From 1d571e10bcd56b6669bd2f4626faa85f1380bfd1 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Wed, 12 Dec 2018 19:27:01 +0000 Subject: [PATCH 001/259] remove deprecated file --- src/versions.json | 5783 --------------------------------------------- 1 file changed, 5783 deletions(-) delete mode 100644 src/versions.json diff --git a/src/versions.json b/src/versions.json deleted file mode 100644 index 81e5264309..0000000000 --- a/src/versions.json +++ /dev/null @@ -1,5783 +0,0 @@ -{ - "name": "alfresco-content-app", - "version": "1.5.0", - "problems": [ - "peer dep missing: @angular/cdk@^6.3.3, required by @mat-datetimepicker/core@2.0.1", - "peer dep missing: @angular/common@^6.0.0, required by @alfresco/adf-extensions@3.0.0-383b74151a47e188020249aea7ec0dfb586bd0b6", - "peer dep missing: @angular/common@^6.0.0, required by @ngrx/router-store@6.1.2", - "peer dep missing: @angular/core@^6.0.0, required by @alfresco/adf-extensions@3.0.0-383b74151a47e188020249aea7ec0dfb586bd0b6", - "peer dep missing: @angular/core@^6.0.7, required by @mat-datetimepicker/core@2.0.1", - "peer dep missing: @angular/core@^6.0.0, required by @ngrx/effects@6.1.2", - "peer dep missing: @angular/core@^6.0.0, required by @ngrx/router-store@6.1.2", - "peer dep missing: @angular/core@^6.0.0, required by @ngrx/store@6.1.2", - "peer dep missing: @angular/flex-layout@>=6.0.0-beta.18, required by @alfresco/adf-content-services@2.6.1", - "peer dep missing: @angular/flex-layout@>=6.0.0-beta.18, required by @alfresco/adf-core@2.6.1", - "peer dep missing: @angular/http@^6.1.4, required by @alfresco/adf-extensions@3.0.0-383b74151a47e188020249aea7ec0dfb586bd0b6", - "peer dep missing: @angular/material@^6.3.3, required by @mat-datetimepicker/core@2.0.1", - "peer dep missing: @angular/material@^6.3.3, required by @mat-datetimepicker/moment@2.0.1", - "peer dep missing: @angular/material-moment-adapter@^6.3.3, required by @mat-datetimepicker/moment@2.0.1", - "peer dep missing: @angular/router@^6.0.0, required by @ngrx/router-store@6.1.2", - "peer dep missing: @mat-datetimepicker/core@2.0.0, required by @mat-datetimepicker/moment@2.0.1", - "peer dep missing: alfresco-js-api@2.7.0-2a84d662e8134ada8923742adad17351a4a2f777, required by @alfresco/adf-extensions@3.0.0-383b74151a47e188020249aea7ec0dfb586bd0b6", - "peer dep missing: core-js@2.4.1, required by @alfresco/adf-core@2.6.1", - "peer dep missing: pdfjs-dist@2.0.303, required by @alfresco/adf-core@2.6.1" - ], - "dependencies": { - "@alfresco/adf-content-services": { - "version": "2.6.1", - "from": "@alfresco/adf-content-services@2.6.1", - "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-2.6.1.tgz" - }, - "@alfresco/adf-core": { - "version": "2.6.1", - "from": "@alfresco/adf-core@2.6.1", - "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-2.6.1.tgz" - }, - "@alfresco/adf-extensions": { - "version": "3.0.0-383b74151a47e188020249aea7ec0dfb586bd0b6", - "from": "@alfresco/adf-extensions@alpha", - "resolved": "https://registry.npmjs.org/@alfresco/adf-extensions/-/adf-extensions-3.0.0-383b74151a47e188020249aea7ec0dfb586bd0b6.tgz" - }, - "@angular/animations": { - "version": "7.0.3", - "from": "@angular/animations@7.0.3", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-7.0.3.tgz" - }, - "@angular/cdk": { - "required": { - "_args": [ - [ - "@angular/cdk@7.0.3", - "/Users/dvuika/github/alfresco-content-app" - ], - [ - "@angular/cdk@7.0.3", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "_from": "@angular/cdk@7.0.3", - "_id": "@angular/cdk@7.0.3", - "_integrity": "sha512-QT7U2tOBVfwn8Q71Nyh0UjlyXfZNKdanq3+b8GJ/+IB/d8mVdMRTXBGQ4PqY7CP+wpkgm+wbbUt3urZF1AqdmQ==", - "_location": "/@angular/cdk", - "_phantomChildren": {}, - "_requested": { - "type": "version", - "registry": true, - "raw": "@angular/cdk@7.0.3", - "name": "@angular/cdk", - "escapedName": "@angular%2fcdk", - "scope": "@angular", - "rawSpec": "7.0.3", - "saveSpec": null, - "fetchSpec": "7.0.3" - }, - "_requiredBy": [ - "/" - ], - "_resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-7.0.3.tgz", - "_spec": "7.0.3", - "_where": "/Users/dvuika/github/alfresco-content-app", - "bugs": { - "url": "https://github.com/angular/material2/issues" - }, - "dependencies": { - "parse5": { - "name": "parse5", - "description": "HTML parser and serializer.", - "version": "5.1.0", - "author": { - "name": "Ivan Nikulin", - "email": "ifaaan@gmail.com", - "url": "https://github.com/inikulin" - }, - "contributors": "https://github.com/inikulin/parse5/graphs/contributors", - "homepage": "https://github.com/inikulin/parse5", - "keywords": [ - "html", - "parser", - "html5", - "WHATWG", - "specification", - "fast", - "html parser", - "html5 parser", - "htmlparser", - "parse5", - "serializer", - "html serializer", - "htmlserializer", - "parse", - "serialize" - ], - "license": "MIT", - "main": "./lib/index.js", - "repository": { - "type": "git", - "url": "git://github.com/inikulin/parse5.git" - }, - "files": [ - "lib" - ], - "_resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", - "_integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==", - "_from": "parse5@5.1.0", - "readme": "

\n \n \"parse5\"\n \n

\n\n
\n

parse5

\nHTML parser and serializer.\n
\n
\n\n
\nnpm install --save parse5\n
\n
\n\n

\n 📖 Documentation 📖\n

\n\n---\n\n

\n List of parse5 toolset packages\n

\n\n

\n GitHub\n

\n\n

\n Online playground\n

\n\n

\n Version history\n

\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/inikulin/parse5/issues" - }, - "_id": "parse5@5.1.0", - "_requested": { - "type": "version", - "registry": true, - "raw": "parse5@5.1.0", - "name": "parse5", - "escapedName": "parse5", - "rawSpec": "5.1.0", - "saveSpec": "[Circular]", - "fetchSpec": "5.1.0" - }, - "_spec": "5.1.0", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_optional": true, - "_args": [ - [ - "parse5@5.1.0", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "dependencies": {}, - "devDependencies": {}, - "optionalDependencies": {}, - "_dependencies": {}, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/@angular/cdk/node_modules/parse5", - "error": "[Circular]", - "extraneous": false - }, - "tslib": { - "name": "tslib", - "author": { - "name": "Microsoft Corp." - }, - "homepage": "http://typescriptlang.org/", - "version": "1.9.3", - "license": "Apache-2.0", - "description": "Runtime library for TypeScript helper functions", - "keywords": [ - "TypeScript", - "Microsoft", - "compiler", - "language", - "javascript", - "tslib", - "runtime" - ], - "bugs": { - "url": "https://github.com/Microsoft/TypeScript/issues" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/Microsoft/tslib.git" - }, - "main": "tslib.js", - "module": "tslib.es6.js", - "jsnext:main": "tslib.es6.js", - "typings": "tslib.d.ts", - "_resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "_integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", - "_from": "tslib@1.9.3", - "readme": "# tslib\r\n\r\nThis is a runtime library for [TypeScript](http://www.typescriptlang.org/) that contains all of the TypeScript helper functions.\r\n\r\nThis library is primarily used by the `--importHelpers` flag in TypeScript.\r\nWhen using `--importHelpers`, a module that uses helper functions like `__extends` and `__assign` in the following emitted file:\r\n\r\n```ts\r\nvar __assign = (this && this.__assign) || Object.assign || function(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))\r\n t[p] = s[p];\r\n }\r\n return t;\r\n};\r\nexports.x = {};\r\nexports.y = __assign({}, exports.x);\r\n\r\n```\r\n\r\nwill instead be emitted as something like the following:\r\n\r\n```ts\r\nvar tslib_1 = require(\"tslib\");\r\nexports.x = {};\r\nexports.y = tslib_1.__assign({}, exports.x);\r\n```\r\n\r\nBecause this can avoid duplicate declarations of things like `__extends`, `__assign`, etc., this means delivering users smaller files on average, as well as less runtime overhead.\r\nFor optimized bundles with TypeScript, you should absolutely consider using `tslib` and `--importHelpers`.\r\n\r\n# Installing\r\n\r\nFor the latest stable version, run:\r\n\r\n## npm\r\n\r\n```sh\r\n# TypeScript 2.3.3 or later\r\nnpm install --save tslib\r\n\r\n# TypeScript 2.3.2 or earlier\r\nnpm install --save tslib@1.6.1\r\n```\r\n\r\n## bower\r\n\r\n```sh\r\n# TypeScript 2.3.3 or later\r\nbower install tslib\r\n\r\n# TypeScript 2.3.2 or earlier\r\nbower install tslib@1.6.1\r\n```\r\n\r\n## JSPM\r\n\r\n```sh\r\n# TypeScript 2.3.3 or later\r\njspm install tslib\r\n\r\n# TypeScript 2.3.2 or earlier\r\njspm install tslib@1.6.1\r\n```\r\n\r\n# Usage\r\n\r\nSet the `importHelpers` compiler option on the command line:\r\n\r\n```\r\ntsc --importHelpers file.ts\r\n```\r\n\r\nor in your tsconfig.json:\r\n\r\n```json\r\n{\r\n \"compilerOptions\": {\r\n \"importHelpers\": true\r\n }\r\n}\r\n```\r\n\r\n#### For bower and JSPM users\r\n\r\nYou will need to add a `paths` mapping for `tslib`, e.g. For Bower users:\r\n\r\n```json\r\n{\r\n \"compilerOptions\": {\r\n \"module\": \"amd\",\r\n \"importHelpers\": true,\r\n \"baseUrl\": \"./\",\r\n \"paths\": {\r\n \"tslib\" : [\"bower_components/tslib/tslib.d.ts\"]\r\n }\r\n }\r\n}\r\n```\r\n\r\nFor JSPM users:\r\n\r\n```json\r\n{\r\n \"compilerOptions\": {\r\n \"module\": \"system\",\r\n \"importHelpers\": true,\r\n \"baseUrl\": \"./\",\r\n \"paths\": {\r\n \"tslib\" : [\"jspm_packages/npm/tslib@1.9.3/tslib.d.ts\"]\r\n }\r\n }\r\n}\r\n```\r\n\r\n\r\n# Contribute\r\n\r\nThere are many ways to [contribute](https://github.com/Microsoft/TypeScript/blob/master/CONTRIBUTING.md) to TypeScript.\r\n\r\n* [Submit bugs](https://github.com/Microsoft/TypeScript/issues) and help us verify fixes as they are checked in.\r\n* Review the [source code changes](https://github.com/Microsoft/TypeScript/pulls).\r\n* Engage with other TypeScript users and developers on [StackOverflow](http://stackoverflow.com/questions/tagged/typescript).\r\n* Join the [#typescript](http://twitter.com/#!/search/realtime/%23typescript) discussion on Twitter.\r\n* [Contribute bug fixes](https://github.com/Microsoft/TypeScript/blob/master/CONTRIBUTING.md).\r\n* Read the language specification ([docx](http://go.microsoft.com/fwlink/?LinkId=267121), [pdf](http://go.microsoft.com/fwlink/?LinkId=267238)).\r\n\r\n# Documentation\r\n\r\n* [Quick tutorial](http://www.typescriptlang.org/Tutorial)\r\n* [Programming handbook](http://www.typescriptlang.org/Handbook)\r\n* [Language specification](https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md)\r\n* [Homepage](http://www.typescriptlang.org/)\r\n", - "readmeFilename": "README.md", - "_id": "tslib@1.9.3", - "_requested": { - "type": "version", - "registry": true, - "raw": "tslib@1.9.3", - "name": "tslib", - "escapedName": "tslib", - "rawSpec": "1.9.3", - "saveSpec": "[Circular]", - "fetchSpec": "1.9.3" - }, - "_spec": "1.9.3", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "tslib@1.9.3", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "dependencies": {}, - "devDependencies": {}, - "optionalDependencies": {}, - "_dependencies": {}, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/tslib", - "error": "[Circular]", - "extraneous": false, - "_deduped": "tslib" - } - }, - "description": "Angular Material Component Development Kit", - "es2015": "./esm2015/cdk.js", - "homepage": "https://github.com/angular/material2#readme", - "keywords": [ - "angular", - "cdk", - "component", - "development", - "kit" - ], - "license": "MIT", - "main": "./bundles/cdk.umd.js", - "module": "./esm5/cdk.es5.js", - "name": "@angular/cdk", - "ng-update": { - "migrations": "./schematics/migration.json" - }, - "optionalDependencies": { - "parse5": "^5.0.0" - }, - "peerDependencies": { - "@angular/core": ">=7.0.0", - "@angular/common": ">=7.0.0" - }, - "releaseGitBranch": "7.0.x", - "releaseGitCommitSha": "44db8860f62bc075e56ec65d784bfe8983a18690", - "releaseGitUser": "Jeremy Elbourn ", - "repository": { - "type": "git", - "url": "git+https://github.com/angular/material2.git" - }, - "schematics": "./schematics/collection.json", - "sideEffects": false, - "typings": "./cdk.d.ts", - "version": "7.0.3", - "readme": "Angular Material\n=======\n\nThe sources for this package are in the main [Angular Material](https://github.com/angular/material2) repo. Please file issues and pull requests against that repo.\n\nLicense: MIT", - "readmeFilename": "README.md", - "devDependencies": {}, - "_dependencies": { - "parse5": "^5.0.0", - "tslib": "^1.7.1" - }, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/@angular/cdk", - "error": "[Circular]", - "extraneous": false, - "peerMissing": [ - { - "requiredBy": "@mat-datetimepicker/core@2.0.1", - "requires": "@angular/cdk@^6.3.3" - } - ] - }, - "peerMissing": true - }, - "@angular/common": { - "required": { - "_args": [ - [ - "@angular/common@7.0.3", - "/Users/dvuika/github/alfresco-content-app" - ], - [ - "@angular/common@7.0.3", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "_from": "@angular/common@7.0.3", - "_id": "@angular/common@7.0.3", - "_integrity": "sha512-aiuQh6+5kWFp34SYEtpnkAJWU3Qn17S/9LjWSZbgfiaYG6MyszepxqLZPBSBPTElxx2u5VoCPh97+TpKoDqx+g==", - "_location": "/@angular/common", - "_phantomChildren": {}, - "_requested": { - "type": "version", - "registry": true, - "raw": "@angular/common@7.0.3", - "name": "@angular/common", - "escapedName": "@angular%2fcommon", - "scope": "@angular", - "rawSpec": "7.0.3", - "saveSpec": "[Circular]", - "fetchSpec": "7.0.3" - }, - "_requiredBy": [ - "/" - ], - "_resolved": "https://registry.npmjs.org/@angular/common/-/common-7.0.3.tgz", - "_spec": "7.0.3", - "_where": "/Users/dvuika/github/alfresco-content-app", - "author": { - "name": "angular" - }, - "bugs": { - "url": "https://github.com/angular/angular/issues" - }, - "dependencies": { - "tslib": { - "name": "tslib", - "author": "[Circular]", - "homepage": "http://typescriptlang.org/", - "version": "1.9.3", - "license": "Apache-2.0", - "description": "Runtime library for TypeScript helper functions", - "keywords": "[Circular]", - "bugs": "[Circular]", - "repository": "[Circular]", - "main": "tslib.js", - "module": "tslib.es6.js", - "jsnext:main": "tslib.es6.js", - "typings": "tslib.d.ts", - "_resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "_integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", - "_from": "tslib@1.9.3", - "readme": "# tslib\r\n\r\nThis is a runtime library for [TypeScript](http://www.typescriptlang.org/) that contains all of the TypeScript helper functions.\r\n\r\nThis library is primarily used by the `--importHelpers` flag in TypeScript.\r\nWhen using `--importHelpers`, a module that uses helper functions like `__extends` and `__assign` in the following emitted file:\r\n\r\n```ts\r\nvar __assign = (this && this.__assign) || Object.assign || function(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))\r\n t[p] = s[p];\r\n }\r\n return t;\r\n};\r\nexports.x = {};\r\nexports.y = __assign({}, exports.x);\r\n\r\n```\r\n\r\nwill instead be emitted as something like the following:\r\n\r\n```ts\r\nvar tslib_1 = require(\"tslib\");\r\nexports.x = {};\r\nexports.y = tslib_1.__assign({}, exports.x);\r\n```\r\n\r\nBecause this can avoid duplicate declarations of things like `__extends`, `__assign`, etc., this means delivering users smaller files on average, as well as less runtime overhead.\r\nFor optimized bundles with TypeScript, you should absolutely consider using `tslib` and `--importHelpers`.\r\n\r\n# Installing\r\n\r\nFor the latest stable version, run:\r\n\r\n## npm\r\n\r\n```sh\r\n# TypeScript 2.3.3 or later\r\nnpm install --save tslib\r\n\r\n# TypeScript 2.3.2 or earlier\r\nnpm install --save tslib@1.6.1\r\n```\r\n\r\n## bower\r\n\r\n```sh\r\n# TypeScript 2.3.3 or later\r\nbower install tslib\r\n\r\n# TypeScript 2.3.2 or earlier\r\nbower install tslib@1.6.1\r\n```\r\n\r\n## JSPM\r\n\r\n```sh\r\n# TypeScript 2.3.3 or later\r\njspm install tslib\r\n\r\n# TypeScript 2.3.2 or earlier\r\njspm install tslib@1.6.1\r\n```\r\n\r\n# Usage\r\n\r\nSet the `importHelpers` compiler option on the command line:\r\n\r\n```\r\ntsc --importHelpers file.ts\r\n```\r\n\r\nor in your tsconfig.json:\r\n\r\n```json\r\n{\r\n \"compilerOptions\": {\r\n \"importHelpers\": true\r\n }\r\n}\r\n```\r\n\r\n#### For bower and JSPM users\r\n\r\nYou will need to add a `paths` mapping for `tslib`, e.g. For Bower users:\r\n\r\n```json\r\n{\r\n \"compilerOptions\": {\r\n \"module\": \"amd\",\r\n \"importHelpers\": true,\r\n \"baseUrl\": \"./\",\r\n \"paths\": {\r\n \"tslib\" : [\"bower_components/tslib/tslib.d.ts\"]\r\n }\r\n }\r\n}\r\n```\r\n\r\nFor JSPM users:\r\n\r\n```json\r\n{\r\n \"compilerOptions\": {\r\n \"module\": \"system\",\r\n \"importHelpers\": true,\r\n \"baseUrl\": \"./\",\r\n \"paths\": {\r\n \"tslib\" : [\"jspm_packages/npm/tslib@1.9.3/tslib.d.ts\"]\r\n }\r\n }\r\n}\r\n```\r\n\r\n\r\n# Contribute\r\n\r\nThere are many ways to [contribute](https://github.com/Microsoft/TypeScript/blob/master/CONTRIBUTING.md) to TypeScript.\r\n\r\n* [Submit bugs](https://github.com/Microsoft/TypeScript/issues) and help us verify fixes as they are checked in.\r\n* Review the [source code changes](https://github.com/Microsoft/TypeScript/pulls).\r\n* Engage with other TypeScript users and developers on [StackOverflow](http://stackoverflow.com/questions/tagged/typescript).\r\n* Join the [#typescript](http://twitter.com/#!/search/realtime/%23typescript) discussion on Twitter.\r\n* [Contribute bug fixes](https://github.com/Microsoft/TypeScript/blob/master/CONTRIBUTING.md).\r\n* Read the language specification ([docx](http://go.microsoft.com/fwlink/?LinkId=267121), [pdf](http://go.microsoft.com/fwlink/?LinkId=267238)).\r\n\r\n# Documentation\r\n\r\n* [Quick tutorial](http://www.typescriptlang.org/Tutorial)\r\n* [Programming handbook](http://www.typescriptlang.org/Handbook)\r\n* [Language specification](https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md)\r\n* [Homepage](http://www.typescriptlang.org/)\r\n", - "readmeFilename": "README.md", - "_id": "tslib@1.9.3", - "_requested": { - "type": "version", - "registry": true, - "raw": "tslib@1.9.3", - "name": "tslib", - "escapedName": "tslib", - "rawSpec": "1.9.3", - "saveSpec": "[Circular]", - "fetchSpec": "1.9.3" - }, - "_spec": "1.9.3", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": "[Circular]", - "dependencies": {}, - "devDependencies": "[Circular]", - "optionalDependencies": "[Circular]", - "_dependencies": "[Circular]", - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/tslib", - "error": "[Circular]", - "extraneous": false, - "_deduped": "tslib" - } - }, - "description": "Angular - commonly needed directives and services", - "es2015": "./fesm2015/common.js", - "esm2015": "./esm2015/common.js", - "esm5": "./esm5/common.js", - "fesm2015": "./fesm2015/common.js", - "fesm5": "./fesm5/common.js", - "homepage": "https://github.com/angular/angular#readme", - "license": "MIT", - "locales": "locales", - "main": "./bundles/common.umd.js", - "module": "./fesm5/common.js", - "name": "@angular/common", - "ng-update": { - "packageGroup": [ - "@angular/core", - "@angular/bazel", - "@angular/common", - "@angular/compiler", - "@angular/compiler-cli", - "@angular/animations", - "@angular/elements", - "@angular/platform-browser", - "@angular/platform-browser-dynamic", - "@angular/forms", - "@angular/http", - "@angular/platform-server", - "@angular/platform-webworker", - "@angular/platform-webworker-dynamic", - "@angular/upgrade", - "@angular/router", - "@angular/language-service", - "@angular/service-worker" - ] - }, - "peerDependencies": { - "rxjs": "^6.0.0", - "@angular/core": "7.0.3" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/angular/angular.git" - }, - "sideEffects": false, - "typings": "./common.d.ts", - "version": "7.0.3", - "readme": "Angular\n=======\n\nThe sources for this package are in the main [Angular](https://github.com/angular/angular) repo. Please file issues and pull requests against that repo.\n\nLicense: MIT\n", - "readmeFilename": "README.md", - "devDependencies": {}, - "optionalDependencies": {}, - "_dependencies": { - "tslib": "^1.9.0" - }, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/@angular/common", - "error": "[Circular]", - "extraneous": false, - "peerMissing": [ - { - "requiredBy": "@alfresco/adf-extensions@3.0.0-383b74151a47e188020249aea7ec0dfb586bd0b6", - "requires": "@angular/common@^6.0.0" - }, - { - "requiredBy": "@ngrx/router-store@6.1.2", - "requires": "@angular/common@^6.0.0" - } - ] - }, - "peerMissing": true - }, - "@angular/compiler": { - "version": "7.0.3", - "from": "@angular/compiler@7.0.3", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-7.0.3.tgz" - }, - "@angular/core": { - "required": { - "_args": [ - [ - "@angular/core@7.0.3", - "/Users/dvuika/github/alfresco-content-app" - ], - [ - "@angular/core@7.0.3", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "_from": "@angular/core@7.0.3", - "_id": "@angular/core@7.0.3", - "_integrity": "sha512-x/OYYykVsi2vrKlYQJ37I8HYAI/s/CtL3Sd9bl87F6AnqLWnnKIxQaofT/ShfAfdP44LQoN5BNp5j+sjs8K4Kg==", - "_location": "/@angular/core", - "_phantomChildren": {}, - "_requested": { - "type": "version", - "registry": true, - "raw": "@angular/core@7.0.3", - "name": "@angular/core", - "escapedName": "@angular%2fcore", - "scope": "@angular", - "rawSpec": "7.0.3", - "saveSpec": "[Circular]", - "fetchSpec": "7.0.3" - }, - "_requiredBy": [ - "/" - ], - "_resolved": "https://registry.npmjs.org/@angular/core/-/core-7.0.3.tgz", - "_spec": "7.0.3", - "_where": "/Users/dvuika/github/alfresco-content-app", - "author": { - "name": "angular" - }, - "bugs": { - "url": "https://github.com/angular/angular/issues" - }, - "dependencies": { - "tslib": { - "name": "tslib", - "author": "[Circular]", - "homepage": "http://typescriptlang.org/", - "version": "1.9.3", - "license": "Apache-2.0", - "description": "Runtime library for TypeScript helper functions", - "keywords": "[Circular]", - "bugs": "[Circular]", - "repository": "[Circular]", - "main": "tslib.js", - "module": "tslib.es6.js", - "jsnext:main": "tslib.es6.js", - "typings": "tslib.d.ts", - "_resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "_integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", - "_from": "tslib@1.9.3", - "readme": "# tslib\r\n\r\nThis is a runtime library for [TypeScript](http://www.typescriptlang.org/) that contains all of the TypeScript helper functions.\r\n\r\nThis library is primarily used by the `--importHelpers` flag in TypeScript.\r\nWhen using `--importHelpers`, a module that uses helper functions like `__extends` and `__assign` in the following emitted file:\r\n\r\n```ts\r\nvar __assign = (this && this.__assign) || Object.assign || function(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))\r\n t[p] = s[p];\r\n }\r\n return t;\r\n};\r\nexports.x = {};\r\nexports.y = __assign({}, exports.x);\r\n\r\n```\r\n\r\nwill instead be emitted as something like the following:\r\n\r\n```ts\r\nvar tslib_1 = require(\"tslib\");\r\nexports.x = {};\r\nexports.y = tslib_1.__assign({}, exports.x);\r\n```\r\n\r\nBecause this can avoid duplicate declarations of things like `__extends`, `__assign`, etc., this means delivering users smaller files on average, as well as less runtime overhead.\r\nFor optimized bundles with TypeScript, you should absolutely consider using `tslib` and `--importHelpers`.\r\n\r\n# Installing\r\n\r\nFor the latest stable version, run:\r\n\r\n## npm\r\n\r\n```sh\r\n# TypeScript 2.3.3 or later\r\nnpm install --save tslib\r\n\r\n# TypeScript 2.3.2 or earlier\r\nnpm install --save tslib@1.6.1\r\n```\r\n\r\n## bower\r\n\r\n```sh\r\n# TypeScript 2.3.3 or later\r\nbower install tslib\r\n\r\n# TypeScript 2.3.2 or earlier\r\nbower install tslib@1.6.1\r\n```\r\n\r\n## JSPM\r\n\r\n```sh\r\n# TypeScript 2.3.3 or later\r\njspm install tslib\r\n\r\n# TypeScript 2.3.2 or earlier\r\njspm install tslib@1.6.1\r\n```\r\n\r\n# Usage\r\n\r\nSet the `importHelpers` compiler option on the command line:\r\n\r\n```\r\ntsc --importHelpers file.ts\r\n```\r\n\r\nor in your tsconfig.json:\r\n\r\n```json\r\n{\r\n \"compilerOptions\": {\r\n \"importHelpers\": true\r\n }\r\n}\r\n```\r\n\r\n#### For bower and JSPM users\r\n\r\nYou will need to add a `paths` mapping for `tslib`, e.g. For Bower users:\r\n\r\n```json\r\n{\r\n \"compilerOptions\": {\r\n \"module\": \"amd\",\r\n \"importHelpers\": true,\r\n \"baseUrl\": \"./\",\r\n \"paths\": {\r\n \"tslib\" : [\"bower_components/tslib/tslib.d.ts\"]\r\n }\r\n }\r\n}\r\n```\r\n\r\nFor JSPM users:\r\n\r\n```json\r\n{\r\n \"compilerOptions\": {\r\n \"module\": \"system\",\r\n \"importHelpers\": true,\r\n \"baseUrl\": \"./\",\r\n \"paths\": {\r\n \"tslib\" : [\"jspm_packages/npm/tslib@1.9.3/tslib.d.ts\"]\r\n }\r\n }\r\n}\r\n```\r\n\r\n\r\n# Contribute\r\n\r\nThere are many ways to [contribute](https://github.com/Microsoft/TypeScript/blob/master/CONTRIBUTING.md) to TypeScript.\r\n\r\n* [Submit bugs](https://github.com/Microsoft/TypeScript/issues) and help us verify fixes as they are checked in.\r\n* Review the [source code changes](https://github.com/Microsoft/TypeScript/pulls).\r\n* Engage with other TypeScript users and developers on [StackOverflow](http://stackoverflow.com/questions/tagged/typescript).\r\n* Join the [#typescript](http://twitter.com/#!/search/realtime/%23typescript) discussion on Twitter.\r\n* [Contribute bug fixes](https://github.com/Microsoft/TypeScript/blob/master/CONTRIBUTING.md).\r\n* Read the language specification ([docx](http://go.microsoft.com/fwlink/?LinkId=267121), [pdf](http://go.microsoft.com/fwlink/?LinkId=267238)).\r\n\r\n# Documentation\r\n\r\n* [Quick tutorial](http://www.typescriptlang.org/Tutorial)\r\n* [Programming handbook](http://www.typescriptlang.org/Handbook)\r\n* [Language specification](https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md)\r\n* [Homepage](http://www.typescriptlang.org/)\r\n", - "readmeFilename": "README.md", - "_id": "tslib@1.9.3", - "_requested": { - "type": "version", - "registry": true, - "raw": "tslib@1.9.3", - "name": "tslib", - "escapedName": "tslib", - "rawSpec": "1.9.3", - "saveSpec": "[Circular]", - "fetchSpec": "1.9.3" - }, - "_spec": "1.9.3", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": "[Circular]", - "dependencies": {}, - "devDependencies": "[Circular]", - "optionalDependencies": "[Circular]", - "_dependencies": "[Circular]", - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/tslib", - "error": "[Circular]", - "extraneous": false, - "_deduped": "tslib" - } - }, - "description": "Angular - the core framework", - "es2015": "./fesm2015/core.js", - "esm2015": "./esm2015/core.js", - "esm5": "./esm5/core.js", - "fesm2015": "./fesm2015/core.js", - "fesm5": "./fesm5/core.js", - "homepage": "https://github.com/angular/angular#readme", - "license": "MIT", - "main": "./bundles/core.umd.js", - "module": "./fesm5/core.js", - "name": "@angular/core", - "ng-update": { - "packageGroup": [ - "@angular/core", - "@angular/bazel", - "@angular/common", - "@angular/compiler", - "@angular/compiler-cli", - "@angular/animations", - "@angular/elements", - "@angular/platform-browser", - "@angular/platform-browser-dynamic", - "@angular/forms", - "@angular/http", - "@angular/platform-server", - "@angular/platform-webworker", - "@angular/platform-webworker-dynamic", - "@angular/upgrade", - "@angular/router", - "@angular/language-service", - "@angular/service-worker" - ] - }, - "peerDependencies": { - "rxjs": "^6.0.0", - "zone.js": "~0.8.26" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/angular/angular.git" - }, - "sideEffects": false, - "typings": "./core.d.ts", - "version": "7.0.3", - "readme": "Angular\n=======\n\nThe sources for this package are in the main [Angular](https://github.com/angular/angular) repo. Please file issues and pull requests against that repo.\n\nLicense: MIT\n", - "readmeFilename": "README.md", - "devDependencies": {}, - "optionalDependencies": {}, - "_dependencies": { - "tslib": "^1.9.0" - }, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/@angular/core", - "error": "[Circular]", - "extraneous": false, - "peerMissing": [ - { - "requiredBy": "@alfresco/adf-extensions@3.0.0-383b74151a47e188020249aea7ec0dfb586bd0b6", - "requires": "@angular/core@^6.0.0" - }, - { - "requiredBy": "@mat-datetimepicker/core@2.0.1", - "requires": "@angular/core@^6.0.7" - }, - { - "requiredBy": "@ngrx/effects@6.1.2", - "requires": "@angular/core@^6.0.0" - }, - { - "requiredBy": "@ngrx/router-store@6.1.2", - "requires": "@angular/core@^6.0.0" - }, - { - "requiredBy": "@ngrx/store@6.1.2", - "requires": "@angular/core@^6.0.0" - } - ] - }, - "peerMissing": true - }, - "@angular/flex-layout": { - "required": { - "name": "@angular/flex-layout", - "version": "7.0.0-beta.19", - "description": "Angular Flex-Layout", - "main": "./bundles/flex-layout.umd.js", - "module": "./esm5/flex-layout.es5.js", - "es2015": "./esm2015/flex-layout.js", - "typings": "./flex-layout.d.ts", - "repository": { - "type": "git", - "url": "git+https://github.com/angular/flex-layout.git" - }, - "keywords": [ - "angular", - "flex-layout", - "flexbox css", - "media query", - "breakpoints" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/angular/flex-layout/issues" - }, - "homepage": "https://github.com/angular/flex-layout#readme", - "peerDependencies": { - "@angular/cdk": "^7.0.0-rc.0", - "@angular/core": ">=7.0.0-rc.0", - "@angular/common": ">=7.0.0-rc.0", - "rxjs": "^6.0.0" - }, - "dependencies": { - "tslib": { - "name": "tslib", - "author": "[Circular]", - "homepage": "http://typescriptlang.org/", - "version": "1.9.3", - "license": "Apache-2.0", - "description": "Runtime library for TypeScript helper functions", - "keywords": "[Circular]", - "bugs": "[Circular]", - "repository": "[Circular]", - "main": "tslib.js", - "module": "tslib.es6.js", - "jsnext:main": "tslib.es6.js", - "typings": "tslib.d.ts", - "_resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "_integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", - "_from": "tslib@1.9.3", - "readme": "# tslib\r\n\r\nThis is a runtime library for [TypeScript](http://www.typescriptlang.org/) that contains all of the TypeScript helper functions.\r\n\r\nThis library is primarily used by the `--importHelpers` flag in TypeScript.\r\nWhen using `--importHelpers`, a module that uses helper functions like `__extends` and `__assign` in the following emitted file:\r\n\r\n```ts\r\nvar __assign = (this && this.__assign) || Object.assign || function(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))\r\n t[p] = s[p];\r\n }\r\n return t;\r\n};\r\nexports.x = {};\r\nexports.y = __assign({}, exports.x);\r\n\r\n```\r\n\r\nwill instead be emitted as something like the following:\r\n\r\n```ts\r\nvar tslib_1 = require(\"tslib\");\r\nexports.x = {};\r\nexports.y = tslib_1.__assign({}, exports.x);\r\n```\r\n\r\nBecause this can avoid duplicate declarations of things like `__extends`, `__assign`, etc., this means delivering users smaller files on average, as well as less runtime overhead.\r\nFor optimized bundles with TypeScript, you should absolutely consider using `tslib` and `--importHelpers`.\r\n\r\n# Installing\r\n\r\nFor the latest stable version, run:\r\n\r\n## npm\r\n\r\n```sh\r\n# TypeScript 2.3.3 or later\r\nnpm install --save tslib\r\n\r\n# TypeScript 2.3.2 or earlier\r\nnpm install --save tslib@1.6.1\r\n```\r\n\r\n## bower\r\n\r\n```sh\r\n# TypeScript 2.3.3 or later\r\nbower install tslib\r\n\r\n# TypeScript 2.3.2 or earlier\r\nbower install tslib@1.6.1\r\n```\r\n\r\n## JSPM\r\n\r\n```sh\r\n# TypeScript 2.3.3 or later\r\njspm install tslib\r\n\r\n# TypeScript 2.3.2 or earlier\r\njspm install tslib@1.6.1\r\n```\r\n\r\n# Usage\r\n\r\nSet the `importHelpers` compiler option on the command line:\r\n\r\n```\r\ntsc --importHelpers file.ts\r\n```\r\n\r\nor in your tsconfig.json:\r\n\r\n```json\r\n{\r\n \"compilerOptions\": {\r\n \"importHelpers\": true\r\n }\r\n}\r\n```\r\n\r\n#### For bower and JSPM users\r\n\r\nYou will need to add a `paths` mapping for `tslib`, e.g. For Bower users:\r\n\r\n```json\r\n{\r\n \"compilerOptions\": {\r\n \"module\": \"amd\",\r\n \"importHelpers\": true,\r\n \"baseUrl\": \"./\",\r\n \"paths\": {\r\n \"tslib\" : [\"bower_components/tslib/tslib.d.ts\"]\r\n }\r\n }\r\n}\r\n```\r\n\r\nFor JSPM users:\r\n\r\n```json\r\n{\r\n \"compilerOptions\": {\r\n \"module\": \"system\",\r\n \"importHelpers\": true,\r\n \"baseUrl\": \"./\",\r\n \"paths\": {\r\n \"tslib\" : [\"jspm_packages/npm/tslib@1.9.3/tslib.d.ts\"]\r\n }\r\n }\r\n}\r\n```\r\n\r\n\r\n# Contribute\r\n\r\nThere are many ways to [contribute](https://github.com/Microsoft/TypeScript/blob/master/CONTRIBUTING.md) to TypeScript.\r\n\r\n* [Submit bugs](https://github.com/Microsoft/TypeScript/issues) and help us verify fixes as they are checked in.\r\n* Review the [source code changes](https://github.com/Microsoft/TypeScript/pulls).\r\n* Engage with other TypeScript users and developers on [StackOverflow](http://stackoverflow.com/questions/tagged/typescript).\r\n* Join the [#typescript](http://twitter.com/#!/search/realtime/%23typescript) discussion on Twitter.\r\n* [Contribute bug fixes](https://github.com/Microsoft/TypeScript/blob/master/CONTRIBUTING.md).\r\n* Read the language specification ([docx](http://go.microsoft.com/fwlink/?LinkId=267121), [pdf](http://go.microsoft.com/fwlink/?LinkId=267238)).\r\n\r\n# Documentation\r\n\r\n* [Quick tutorial](http://www.typescriptlang.org/Tutorial)\r\n* [Programming handbook](http://www.typescriptlang.org/Handbook)\r\n* [Language specification](https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md)\r\n* [Homepage](http://www.typescriptlang.org/)\r\n", - "readmeFilename": "README.md", - "_id": "tslib@1.9.3", - "_requested": { - "type": "version", - "registry": true, - "raw": "tslib@1.9.3", - "name": "tslib", - "escapedName": "tslib", - "rawSpec": "1.9.3", - "saveSpec": "[Circular]", - "fetchSpec": "1.9.3" - }, - "_spec": "1.9.3", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": "[Circular]", - "dependencies": {}, - "devDependencies": "[Circular]", - "optionalDependencies": "[Circular]", - "_dependencies": "[Circular]", - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/tslib", - "error": "[Circular]", - "extraneous": false, - "_deduped": "tslib" - } - }, - "sideEffects": false, - "_resolved": "https://registry.npmjs.org/@angular/flex-layout/-/flex-layout-7.0.0-beta.19.tgz", - "_integrity": "sha512-MXq+zZ6/s5/+GsL9fZ42mKL0LjZ/+L0sVU5FaQuSAJ57soLl5QAGWvdxVmROtqcHd3Htp35R49nKSZBJ0nfAjg==", - "_from": "@angular/flex-layout@7.0.0-beta.19", - "readme": "Angular Flex-Layout\n=======\n\nThe sources for this package are in the main [Angular Flex-Layout](https://github.com/angular/flex-layout) repo. \nPlease file issues and pull requests against that repo.\n\nLicense: MIT\n", - "readmeFilename": "README.md", - "_id": "@angular/flex-layout@7.0.0-beta.19", - "_requested": { - "type": "version", - "registry": true, - "raw": "@angular/flex-layout@7.0.0-beta.19", - "name": "@angular/flex-layout", - "escapedName": "@angular%2fflex-layout", - "scope": "@angular", - "rawSpec": "7.0.0-beta.19", - "saveSpec": "[Circular]", - "fetchSpec": "7.0.0-beta.19" - }, - "_spec": "7.0.0-beta.19", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "@angular/flex-layout@7.0.0-beta.19", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "devDependencies": {}, - "optionalDependencies": {}, - "_dependencies": { - "tslib": "^1.7.1" - }, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/@angular/flex-layout", - "error": "[Circular]", - "extraneous": false, - "peerMissing": [ - { - "requiredBy": "@alfresco/adf-content-services@2.6.1", - "requires": "@angular/flex-layout@>=6.0.0-beta.18" - }, - { - "requiredBy": "@alfresco/adf-core@2.6.1", - "requires": "@angular/flex-layout@>=6.0.0-beta.18" - } - ] - }, - "peerMissing": true - }, - "@angular/forms": { - "version": "7.0.3", - "from": "@angular/forms@7.0.3", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-7.0.3.tgz" - }, - "@angular/http": { - "required": { - "_args": [ - [ - "@angular/http@7.0.3", - "/Users/dvuika/github/alfresco-content-app" - ], - [ - "@angular/http@7.0.3", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "_from": "@angular/http@7.0.3", - "_id": "@angular/http@7.0.3", - "_integrity": "sha512-aL+z1/tbVY8oJw5v46rbMli5vBGDVyJvs95d1l2n3hWnwMTzS9AVetjcL3B3uruAYuXoh4QlSJ+ysBgdmV1+IA==", - "_location": "/@angular/http", - "_phantomChildren": {}, - "_requested": { - "type": "version", - "registry": true, - "raw": "@angular/http@7.0.3", - "name": "@angular/http", - "escapedName": "@angular%2fhttp", - "scope": "@angular", - "rawSpec": "7.0.3", - "saveSpec": "[Circular]", - "fetchSpec": "7.0.3" - }, - "_requiredBy": [ - "/" - ], - "_resolved": "https://registry.npmjs.org/@angular/http/-/http-7.0.3.tgz", - "_spec": "7.0.3", - "_where": "/Users/dvuika/github/alfresco-content-app", - "author": { - "name": "angular" - }, - "bugs": { - "url": "https://github.com/angular/angular/issues" - }, - "dependencies": { - "tslib": { - "name": "tslib", - "author": "[Circular]", - "homepage": "http://typescriptlang.org/", - "version": "1.9.3", - "license": "Apache-2.0", - "description": "Runtime library for TypeScript helper functions", - "keywords": "[Circular]", - "bugs": "[Circular]", - "repository": "[Circular]", - "main": "tslib.js", - "module": "tslib.es6.js", - "jsnext:main": "tslib.es6.js", - "typings": "tslib.d.ts", - "_resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "_integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", - "_from": "tslib@1.9.3", - "readme": "# tslib\r\n\r\nThis is a runtime library for [TypeScript](http://www.typescriptlang.org/) that contains all of the TypeScript helper functions.\r\n\r\nThis library is primarily used by the `--importHelpers` flag in TypeScript.\r\nWhen using `--importHelpers`, a module that uses helper functions like `__extends` and `__assign` in the following emitted file:\r\n\r\n```ts\r\nvar __assign = (this && this.__assign) || Object.assign || function(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))\r\n t[p] = s[p];\r\n }\r\n return t;\r\n};\r\nexports.x = {};\r\nexports.y = __assign({}, exports.x);\r\n\r\n```\r\n\r\nwill instead be emitted as something like the following:\r\n\r\n```ts\r\nvar tslib_1 = require(\"tslib\");\r\nexports.x = {};\r\nexports.y = tslib_1.__assign({}, exports.x);\r\n```\r\n\r\nBecause this can avoid duplicate declarations of things like `__extends`, `__assign`, etc., this means delivering users smaller files on average, as well as less runtime overhead.\r\nFor optimized bundles with TypeScript, you should absolutely consider using `tslib` and `--importHelpers`.\r\n\r\n# Installing\r\n\r\nFor the latest stable version, run:\r\n\r\n## npm\r\n\r\n```sh\r\n# TypeScript 2.3.3 or later\r\nnpm install --save tslib\r\n\r\n# TypeScript 2.3.2 or earlier\r\nnpm install --save tslib@1.6.1\r\n```\r\n\r\n## bower\r\n\r\n```sh\r\n# TypeScript 2.3.3 or later\r\nbower install tslib\r\n\r\n# TypeScript 2.3.2 or earlier\r\nbower install tslib@1.6.1\r\n```\r\n\r\n## JSPM\r\n\r\n```sh\r\n# TypeScript 2.3.3 or later\r\njspm install tslib\r\n\r\n# TypeScript 2.3.2 or earlier\r\njspm install tslib@1.6.1\r\n```\r\n\r\n# Usage\r\n\r\nSet the `importHelpers` compiler option on the command line:\r\n\r\n```\r\ntsc --importHelpers file.ts\r\n```\r\n\r\nor in your tsconfig.json:\r\n\r\n```json\r\n{\r\n \"compilerOptions\": {\r\n \"importHelpers\": true\r\n }\r\n}\r\n```\r\n\r\n#### For bower and JSPM users\r\n\r\nYou will need to add a `paths` mapping for `tslib`, e.g. For Bower users:\r\n\r\n```json\r\n{\r\n \"compilerOptions\": {\r\n \"module\": \"amd\",\r\n \"importHelpers\": true,\r\n \"baseUrl\": \"./\",\r\n \"paths\": {\r\n \"tslib\" : [\"bower_components/tslib/tslib.d.ts\"]\r\n }\r\n }\r\n}\r\n```\r\n\r\nFor JSPM users:\r\n\r\n```json\r\n{\r\n \"compilerOptions\": {\r\n \"module\": \"system\",\r\n \"importHelpers\": true,\r\n \"baseUrl\": \"./\",\r\n \"paths\": {\r\n \"tslib\" : [\"jspm_packages/npm/tslib@1.9.3/tslib.d.ts\"]\r\n }\r\n }\r\n}\r\n```\r\n\r\n\r\n# Contribute\r\n\r\nThere are many ways to [contribute](https://github.com/Microsoft/TypeScript/blob/master/CONTRIBUTING.md) to TypeScript.\r\n\r\n* [Submit bugs](https://github.com/Microsoft/TypeScript/issues) and help us verify fixes as they are checked in.\r\n* Review the [source code changes](https://github.com/Microsoft/TypeScript/pulls).\r\n* Engage with other TypeScript users and developers on [StackOverflow](http://stackoverflow.com/questions/tagged/typescript).\r\n* Join the [#typescript](http://twitter.com/#!/search/realtime/%23typescript) discussion on Twitter.\r\n* [Contribute bug fixes](https://github.com/Microsoft/TypeScript/blob/master/CONTRIBUTING.md).\r\n* Read the language specification ([docx](http://go.microsoft.com/fwlink/?LinkId=267121), [pdf](http://go.microsoft.com/fwlink/?LinkId=267238)).\r\n\r\n# Documentation\r\n\r\n* [Quick tutorial](http://www.typescriptlang.org/Tutorial)\r\n* [Programming handbook](http://www.typescriptlang.org/Handbook)\r\n* [Language specification](https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md)\r\n* [Homepage](http://www.typescriptlang.org/)\r\n", - "readmeFilename": "README.md", - "_id": "tslib@1.9.3", - "_requested": { - "type": "version", - "registry": true, - "raw": "tslib@1.9.3", - "name": "tslib", - "escapedName": "tslib", - "rawSpec": "1.9.3", - "saveSpec": "[Circular]", - "fetchSpec": "1.9.3" - }, - "_spec": "1.9.3", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": "[Circular]", - "dependencies": {}, - "devDependencies": "[Circular]", - "optionalDependencies": "[Circular]", - "_dependencies": "[Circular]", - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/tslib", - "error": "[Circular]", - "extraneous": false, - "_deduped": "tslib" - } - }, - "description": "Angular - the http service", - "es2015": "./fesm2015/http.js", - "esm2015": "./esm2015/http.js", - "esm5": "./esm5/http.js", - "fesm2015": "./fesm2015/http.js", - "fesm5": "./fesm5/http.js", - "homepage": "https://github.com/angular/angular#readme", - "license": "MIT", - "main": "./bundles/http.umd.js", - "module": "./fesm5/http.js", - "name": "@angular/http", - "ng-update": { - "packageGroup": [ - "@angular/core", - "@angular/bazel", - "@angular/common", - "@angular/compiler", - "@angular/compiler-cli", - "@angular/animations", - "@angular/elements", - "@angular/platform-browser", - "@angular/platform-browser-dynamic", - "@angular/forms", - "@angular/http", - "@angular/platform-server", - "@angular/platform-webworker", - "@angular/platform-webworker-dynamic", - "@angular/upgrade", - "@angular/router", - "@angular/language-service", - "@angular/service-worker" - ] - }, - "peerDependencies": { - "rxjs": "^6.0.0", - "@angular/core": "7.0.3", - "@angular/platform-browser": "7.0.3" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/angular/angular.git" - }, - "sideEffects": false, - "typings": "./http.d.ts", - "version": "7.0.3", - "readme": "Angular\n=======\n\nThe sources for this package are in the main [Angular](https://github.com/angular/angular) repo. Please file issues and pull requests against that repo.\n\nLicense: MIT\n", - "readmeFilename": "README.md", - "devDependencies": {}, - "optionalDependencies": {}, - "_dependencies": { - "tslib": "^1.9.0" - }, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/@angular/http", - "error": "[Circular]", - "extraneous": false, - "peerMissing": [ - { - "requiredBy": "@alfresco/adf-extensions@3.0.0-383b74151a47e188020249aea7ec0dfb586bd0b6", - "requires": "@angular/http@^6.1.4" - } - ] - }, - "peerMissing": true - }, - "@angular/material": { - "required": { - "_args": [ - [ - "@angular/material@7.0.3", - "/Users/dvuika/github/alfresco-content-app" - ], - [ - "@angular/material@7.0.3", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "_from": "@angular/material@7.0.3", - "_id": "@angular/material@7.0.3", - "_integrity": "sha512-acJ2zU44k/rsd4OeTdAMVP0R3te8aXwfubDQGc8YI1CdRVW1XqMSvAWkToYDVaGvnZV53zQt/iSi1XWaSXYf1Q==", - "_location": "/@angular/material", - "_phantomChildren": {}, - "_requested": { - "type": "version", - "registry": true, - "raw": "@angular/material@7.0.3", - "name": "@angular/material", - "escapedName": "@angular%2fmaterial", - "scope": "@angular", - "rawSpec": "7.0.3", - "saveSpec": "[Circular]", - "fetchSpec": "7.0.3" - }, - "_requiredBy": [ - "/" - ], - "_resolved": "https://registry.npmjs.org/@angular/material/-/material-7.0.3.tgz", - "_spec": "7.0.3", - "_where": "/Users/dvuika/github/alfresco-content-app", - "bugs": { - "url": "https://github.com/angular/material2/issues" - }, - "dependencies": { - "tslib": { - "name": "tslib", - "author": "[Circular]", - "homepage": "http://typescriptlang.org/", - "version": "1.9.3", - "license": "Apache-2.0", - "description": "Runtime library for TypeScript helper functions", - "keywords": "[Circular]", - "bugs": "[Circular]", - "repository": "[Circular]", - "main": "tslib.js", - "module": "tslib.es6.js", - "jsnext:main": "tslib.es6.js", - "typings": "tslib.d.ts", - "_resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "_integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", - "_from": "tslib@1.9.3", - "readme": "# tslib\r\n\r\nThis is a runtime library for [TypeScript](http://www.typescriptlang.org/) that contains all of the TypeScript helper functions.\r\n\r\nThis library is primarily used by the `--importHelpers` flag in TypeScript.\r\nWhen using `--importHelpers`, a module that uses helper functions like `__extends` and `__assign` in the following emitted file:\r\n\r\n```ts\r\nvar __assign = (this && this.__assign) || Object.assign || function(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))\r\n t[p] = s[p];\r\n }\r\n return t;\r\n};\r\nexports.x = {};\r\nexports.y = __assign({}, exports.x);\r\n\r\n```\r\n\r\nwill instead be emitted as something like the following:\r\n\r\n```ts\r\nvar tslib_1 = require(\"tslib\");\r\nexports.x = {};\r\nexports.y = tslib_1.__assign({}, exports.x);\r\n```\r\n\r\nBecause this can avoid duplicate declarations of things like `__extends`, `__assign`, etc., this means delivering users smaller files on average, as well as less runtime overhead.\r\nFor optimized bundles with TypeScript, you should absolutely consider using `tslib` and `--importHelpers`.\r\n\r\n# Installing\r\n\r\nFor the latest stable version, run:\r\n\r\n## npm\r\n\r\n```sh\r\n# TypeScript 2.3.3 or later\r\nnpm install --save tslib\r\n\r\n# TypeScript 2.3.2 or earlier\r\nnpm install --save tslib@1.6.1\r\n```\r\n\r\n## bower\r\n\r\n```sh\r\n# TypeScript 2.3.3 or later\r\nbower install tslib\r\n\r\n# TypeScript 2.3.2 or earlier\r\nbower install tslib@1.6.1\r\n```\r\n\r\n## JSPM\r\n\r\n```sh\r\n# TypeScript 2.3.3 or later\r\njspm install tslib\r\n\r\n# TypeScript 2.3.2 or earlier\r\njspm install tslib@1.6.1\r\n```\r\n\r\n# Usage\r\n\r\nSet the `importHelpers` compiler option on the command line:\r\n\r\n```\r\ntsc --importHelpers file.ts\r\n```\r\n\r\nor in your tsconfig.json:\r\n\r\n```json\r\n{\r\n \"compilerOptions\": {\r\n \"importHelpers\": true\r\n }\r\n}\r\n```\r\n\r\n#### For bower and JSPM users\r\n\r\nYou will need to add a `paths` mapping for `tslib`, e.g. For Bower users:\r\n\r\n```json\r\n{\r\n \"compilerOptions\": {\r\n \"module\": \"amd\",\r\n \"importHelpers\": true,\r\n \"baseUrl\": \"./\",\r\n \"paths\": {\r\n \"tslib\" : [\"bower_components/tslib/tslib.d.ts\"]\r\n }\r\n }\r\n}\r\n```\r\n\r\nFor JSPM users:\r\n\r\n```json\r\n{\r\n \"compilerOptions\": {\r\n \"module\": \"system\",\r\n \"importHelpers\": true,\r\n \"baseUrl\": \"./\",\r\n \"paths\": {\r\n \"tslib\" : [\"jspm_packages/npm/tslib@1.9.3/tslib.d.ts\"]\r\n }\r\n }\r\n}\r\n```\r\n\r\n\r\n# Contribute\r\n\r\nThere are many ways to [contribute](https://github.com/Microsoft/TypeScript/blob/master/CONTRIBUTING.md) to TypeScript.\r\n\r\n* [Submit bugs](https://github.com/Microsoft/TypeScript/issues) and help us verify fixes as they are checked in.\r\n* Review the [source code changes](https://github.com/Microsoft/TypeScript/pulls).\r\n* Engage with other TypeScript users and developers on [StackOverflow](http://stackoverflow.com/questions/tagged/typescript).\r\n* Join the [#typescript](http://twitter.com/#!/search/realtime/%23typescript) discussion on Twitter.\r\n* [Contribute bug fixes](https://github.com/Microsoft/TypeScript/blob/master/CONTRIBUTING.md).\r\n* Read the language specification ([docx](http://go.microsoft.com/fwlink/?LinkId=267121), [pdf](http://go.microsoft.com/fwlink/?LinkId=267238)).\r\n\r\n# Documentation\r\n\r\n* [Quick tutorial](http://www.typescriptlang.org/Tutorial)\r\n* [Programming handbook](http://www.typescriptlang.org/Handbook)\r\n* [Language specification](https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md)\r\n* [Homepage](http://www.typescriptlang.org/)\r\n", - "readmeFilename": "README.md", - "_id": "tslib@1.9.3", - "_requested": { - "type": "version", - "registry": true, - "raw": "tslib@1.9.3", - "name": "tslib", - "escapedName": "tslib", - "rawSpec": "1.9.3", - "saveSpec": "[Circular]", - "fetchSpec": "1.9.3" - }, - "_spec": "1.9.3", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": "[Circular]", - "dependencies": {}, - "devDependencies": "[Circular]", - "optionalDependencies": "[Circular]", - "_dependencies": "[Circular]", - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/tslib", - "error": "[Circular]", - "extraneous": false, - "_deduped": "tslib" - } - }, - "description": "Angular Material", - "es2015": "./esm2015/material.js", - "homepage": "https://github.com/angular/material2#readme", - "keywords": [ - "angular", - "material", - "material design", - "components" - ], - "license": "MIT", - "main": "./bundles/material.umd.js", - "module": "./esm5/material.es5.js", - "name": "@angular/material", - "ng-update": { - "migrations": "./schematics/migration.json", - "packageGroup": [ - "@angular/material", - "@angular/cdk", - "@angular/material-moment-adapter" - ] - }, - "peerDependencies": { - "@angular/animations": ">=7.0.0", - "@angular/cdk": "7.0.3", - "@angular/core": ">=7.0.0", - "@angular/common": ">=7.0.0" - }, - "releaseGitBranch": "7.0.x", - "releaseGitCommitSha": "44db8860f62bc075e56ec65d784bfe8983a18690", - "releaseGitUser": "Jeremy Elbourn ", - "repository": { - "type": "git", - "url": "git+https://github.com/angular/material2.git" - }, - "schematics": "./schematics/collection.json", - "sideEffects": false, - "typings": "./material.d.ts", - "version": "7.0.3", - "readme": "Angular Material\n=======\n\nThe sources for this package are in the main [Angular Material](https://github.com/angular/material2) repo. Please file issues and pull requests against that repo.\n\nLicense: MIT", - "readmeFilename": "README.md", - "devDependencies": {}, - "optionalDependencies": {}, - "_dependencies": { - "tslib": "^1.7.1" - }, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/@angular/material", - "error": "[Circular]", - "extraneous": false, - "peerMissing": [ - { - "requiredBy": "@mat-datetimepicker/core@2.0.1", - "requires": "@angular/material@^6.3.3" - }, - { - "requiredBy": "@mat-datetimepicker/moment@2.0.1", - "requires": "@angular/material@^6.3.3" - } - ] - }, - "peerMissing": true - }, - "@angular/material-moment-adapter": { - "required": { - "_args": [ - [ - "@angular/material-moment-adapter@7.0.3", - "/Users/dvuika/github/alfresco-content-app" - ], - [ - "@angular/material-moment-adapter@7.0.3", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "_from": "@angular/material-moment-adapter@7.0.3", - "_id": "@angular/material-moment-adapter@7.0.3", - "_integrity": "sha512-vbynHlQYWcgbZKRearq5LpflQp9VPDDNarHL+C4WD6aGLPYmIKotOWcBr083HfN1RnkCa7fh+GhOld/MHglHmg==", - "_location": "/@angular/material-moment-adapter", - "_phantomChildren": {}, - "_requested": { - "type": "version", - "registry": true, - "raw": "@angular/material-moment-adapter@7.0.3", - "name": "@angular/material-moment-adapter", - "escapedName": "@angular%2fmaterial-moment-adapter", - "scope": "@angular", - "rawSpec": "7.0.3", - "saveSpec": "[Circular]", - "fetchSpec": "7.0.3" - }, - "_requiredBy": [ - "/" - ], - "_resolved": "https://registry.npmjs.org/@angular/material-moment-adapter/-/material-moment-adapter-7.0.3.tgz", - "_spec": "7.0.3", - "_where": "/Users/dvuika/github/alfresco-content-app", - "bugs": { - "url": "https://github.com/angular/material2/issues" - }, - "dependencies": { - "tslib": { - "name": "tslib", - "author": "[Circular]", - "homepage": "http://typescriptlang.org/", - "version": "1.9.3", - "license": "Apache-2.0", - "description": "Runtime library for TypeScript helper functions", - "keywords": "[Circular]", - "bugs": "[Circular]", - "repository": "[Circular]", - "main": "tslib.js", - "module": "tslib.es6.js", - "jsnext:main": "tslib.es6.js", - "typings": "tslib.d.ts", - "_resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "_integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", - "_from": "tslib@1.9.3", - "readme": "# tslib\r\n\r\nThis is a runtime library for [TypeScript](http://www.typescriptlang.org/) that contains all of the TypeScript helper functions.\r\n\r\nThis library is primarily used by the `--importHelpers` flag in TypeScript.\r\nWhen using `--importHelpers`, a module that uses helper functions like `__extends` and `__assign` in the following emitted file:\r\n\r\n```ts\r\nvar __assign = (this && this.__assign) || Object.assign || function(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))\r\n t[p] = s[p];\r\n }\r\n return t;\r\n};\r\nexports.x = {};\r\nexports.y = __assign({}, exports.x);\r\n\r\n```\r\n\r\nwill instead be emitted as something like the following:\r\n\r\n```ts\r\nvar tslib_1 = require(\"tslib\");\r\nexports.x = {};\r\nexports.y = tslib_1.__assign({}, exports.x);\r\n```\r\n\r\nBecause this can avoid duplicate declarations of things like `__extends`, `__assign`, etc., this means delivering users smaller files on average, as well as less runtime overhead.\r\nFor optimized bundles with TypeScript, you should absolutely consider using `tslib` and `--importHelpers`.\r\n\r\n# Installing\r\n\r\nFor the latest stable version, run:\r\n\r\n## npm\r\n\r\n```sh\r\n# TypeScript 2.3.3 or later\r\nnpm install --save tslib\r\n\r\n# TypeScript 2.3.2 or earlier\r\nnpm install --save tslib@1.6.1\r\n```\r\n\r\n## bower\r\n\r\n```sh\r\n# TypeScript 2.3.3 or later\r\nbower install tslib\r\n\r\n# TypeScript 2.3.2 or earlier\r\nbower install tslib@1.6.1\r\n```\r\n\r\n## JSPM\r\n\r\n```sh\r\n# TypeScript 2.3.3 or later\r\njspm install tslib\r\n\r\n# TypeScript 2.3.2 or earlier\r\njspm install tslib@1.6.1\r\n```\r\n\r\n# Usage\r\n\r\nSet the `importHelpers` compiler option on the command line:\r\n\r\n```\r\ntsc --importHelpers file.ts\r\n```\r\n\r\nor in your tsconfig.json:\r\n\r\n```json\r\n{\r\n \"compilerOptions\": {\r\n \"importHelpers\": true\r\n }\r\n}\r\n```\r\n\r\n#### For bower and JSPM users\r\n\r\nYou will need to add a `paths` mapping for `tslib`, e.g. For Bower users:\r\n\r\n```json\r\n{\r\n \"compilerOptions\": {\r\n \"module\": \"amd\",\r\n \"importHelpers\": true,\r\n \"baseUrl\": \"./\",\r\n \"paths\": {\r\n \"tslib\" : [\"bower_components/tslib/tslib.d.ts\"]\r\n }\r\n }\r\n}\r\n```\r\n\r\nFor JSPM users:\r\n\r\n```json\r\n{\r\n \"compilerOptions\": {\r\n \"module\": \"system\",\r\n \"importHelpers\": true,\r\n \"baseUrl\": \"./\",\r\n \"paths\": {\r\n \"tslib\" : [\"jspm_packages/npm/tslib@1.9.3/tslib.d.ts\"]\r\n }\r\n }\r\n}\r\n```\r\n\r\n\r\n# Contribute\r\n\r\nThere are many ways to [contribute](https://github.com/Microsoft/TypeScript/blob/master/CONTRIBUTING.md) to TypeScript.\r\n\r\n* [Submit bugs](https://github.com/Microsoft/TypeScript/issues) and help us verify fixes as they are checked in.\r\n* Review the [source code changes](https://github.com/Microsoft/TypeScript/pulls).\r\n* Engage with other TypeScript users and developers on [StackOverflow](http://stackoverflow.com/questions/tagged/typescript).\r\n* Join the [#typescript](http://twitter.com/#!/search/realtime/%23typescript) discussion on Twitter.\r\n* [Contribute bug fixes](https://github.com/Microsoft/TypeScript/blob/master/CONTRIBUTING.md).\r\n* Read the language specification ([docx](http://go.microsoft.com/fwlink/?LinkId=267121), [pdf](http://go.microsoft.com/fwlink/?LinkId=267238)).\r\n\r\n# Documentation\r\n\r\n* [Quick tutorial](http://www.typescriptlang.org/Tutorial)\r\n* [Programming handbook](http://www.typescriptlang.org/Handbook)\r\n* [Language specification](https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md)\r\n* [Homepage](http://www.typescriptlang.org/)\r\n", - "readmeFilename": "README.md", - "_id": "tslib@1.9.3", - "_requested": { - "type": "version", - "registry": true, - "raw": "tslib@1.9.3", - "name": "tslib", - "escapedName": "tslib", - "rawSpec": "1.9.3", - "saveSpec": "[Circular]", - "fetchSpec": "1.9.3" - }, - "_spec": "1.9.3", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": "[Circular]", - "dependencies": {}, - "devDependencies": "[Circular]", - "optionalDependencies": "[Circular]", - "_dependencies": "[Circular]", - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/tslib", - "error": "[Circular]", - "extraneous": false, - "_deduped": "tslib" - } - }, - "description": "Angular Material Moment Adapter", - "es2015": "./esm2015/material-moment-adapter.js", - "homepage": "https://github.com/angular/material2#readme", - "license": "MIT", - "main": "./bundles/material-moment-adapter.umd.js", - "module": "./esm5/material-moment-adapter.es5.js", - "name": "@angular/material-moment-adapter", - "ng-update": { - "packageGroup": [ - "@angular/material", - "@angular/cdk", - "@angular/material-moment-adapter" - ] - }, - "peerDependencies": { - "@angular/material": "7.0.3", - "@angular/core": ">=7.0.0", - "moment": "^2.18.1" - }, - "releaseGitBranch": "7.0.x", - "releaseGitCommitSha": "44db8860f62bc075e56ec65d784bfe8983a18690", - "releaseGitUser": "Jeremy Elbourn ", - "repository": { - "type": "git", - "url": "git+https://github.com/angular/material2.git" - }, - "typings": "./material-moment-adapter.d.ts", - "version": "7.0.3", - "readme": "Angular Material\n=======\n\nThe sources for this package are in the main [Angular Material](https://github.com/angular/material2) repo. Please file issues and pull requests against that repo.\n\nLicense: MIT", - "readmeFilename": "README.md", - "devDependencies": {}, - "optionalDependencies": {}, - "_dependencies": { - "tslib": "^1.7.1" - }, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/@angular/material-moment-adapter", - "error": "[Circular]", - "extraneous": false, - "peerMissing": [ - { - "requiredBy": "@mat-datetimepicker/moment@2.0.1", - "requires": "@angular/material-moment-adapter@^6.3.3" - } - ] - }, - "peerMissing": true - }, - "@angular/platform-browser": { - "version": "7.0.3", - "from": "@angular/platform-browser@7.0.3", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-7.0.3.tgz" - }, - "@angular/platform-browser-dynamic": { - "version": "7.0.3", - "from": "@angular/platform-browser-dynamic@7.0.3", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-7.0.3.tgz" - }, - "@angular/router": { - "required": { - "_args": [ - [ - "@angular/router@7.0.3", - "/Users/dvuika/github/alfresco-content-app" - ], - [ - "@angular/router@7.0.3", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "_from": "@angular/router@7.0.3", - "_id": "@angular/router@7.0.3", - "_integrity": "sha512-885svORDpD9DkaMKjvGwn4g5bf0n3JR8os+gCNhzk0p4TPfpc+vmNo8SyY2jwdLMh2rQzrUQTDkn9SzzgiOfDQ==", - "_location": "/@angular/router", - "_phantomChildren": {}, - "_requested": { - "type": "version", - "registry": true, - "raw": "@angular/router@7.0.3", - "name": "@angular/router", - "escapedName": "@angular%2frouter", - "scope": "@angular", - "rawSpec": "7.0.3", - "saveSpec": "[Circular]", - "fetchSpec": "7.0.3" - }, - "_requiredBy": [ - "/" - ], - "_resolved": "https://registry.npmjs.org/@angular/router/-/router-7.0.3.tgz", - "_spec": "7.0.3", - "_where": "/Users/dvuika/github/alfresco-content-app", - "author": { - "name": "angular" - }, - "bugs": { - "url": "https://github.com/angular/angular/issues" - }, - "dependencies": { - "tslib": { - "name": "tslib", - "author": "[Circular]", - "homepage": "http://typescriptlang.org/", - "version": "1.9.3", - "license": "Apache-2.0", - "description": "Runtime library for TypeScript helper functions", - "keywords": "[Circular]", - "bugs": "[Circular]", - "repository": "[Circular]", - "main": "tslib.js", - "module": "tslib.es6.js", - "jsnext:main": "tslib.es6.js", - "typings": "tslib.d.ts", - "_resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "_integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", - "_from": "tslib@1.9.3", - "readme": "# tslib\r\n\r\nThis is a runtime library for [TypeScript](http://www.typescriptlang.org/) that contains all of the TypeScript helper functions.\r\n\r\nThis library is primarily used by the `--importHelpers` flag in TypeScript.\r\nWhen using `--importHelpers`, a module that uses helper functions like `__extends` and `__assign` in the following emitted file:\r\n\r\n```ts\r\nvar __assign = (this && this.__assign) || Object.assign || function(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))\r\n t[p] = s[p];\r\n }\r\n return t;\r\n};\r\nexports.x = {};\r\nexports.y = __assign({}, exports.x);\r\n\r\n```\r\n\r\nwill instead be emitted as something like the following:\r\n\r\n```ts\r\nvar tslib_1 = require(\"tslib\");\r\nexports.x = {};\r\nexports.y = tslib_1.__assign({}, exports.x);\r\n```\r\n\r\nBecause this can avoid duplicate declarations of things like `__extends`, `__assign`, etc., this means delivering users smaller files on average, as well as less runtime overhead.\r\nFor optimized bundles with TypeScript, you should absolutely consider using `tslib` and `--importHelpers`.\r\n\r\n# Installing\r\n\r\nFor the latest stable version, run:\r\n\r\n## npm\r\n\r\n```sh\r\n# TypeScript 2.3.3 or later\r\nnpm install --save tslib\r\n\r\n# TypeScript 2.3.2 or earlier\r\nnpm install --save tslib@1.6.1\r\n```\r\n\r\n## bower\r\n\r\n```sh\r\n# TypeScript 2.3.3 or later\r\nbower install tslib\r\n\r\n# TypeScript 2.3.2 or earlier\r\nbower install tslib@1.6.1\r\n```\r\n\r\n## JSPM\r\n\r\n```sh\r\n# TypeScript 2.3.3 or later\r\njspm install tslib\r\n\r\n# TypeScript 2.3.2 or earlier\r\njspm install tslib@1.6.1\r\n```\r\n\r\n# Usage\r\n\r\nSet the `importHelpers` compiler option on the command line:\r\n\r\n```\r\ntsc --importHelpers file.ts\r\n```\r\n\r\nor in your tsconfig.json:\r\n\r\n```json\r\n{\r\n \"compilerOptions\": {\r\n \"importHelpers\": true\r\n }\r\n}\r\n```\r\n\r\n#### For bower and JSPM users\r\n\r\nYou will need to add a `paths` mapping for `tslib`, e.g. For Bower users:\r\n\r\n```json\r\n{\r\n \"compilerOptions\": {\r\n \"module\": \"amd\",\r\n \"importHelpers\": true,\r\n \"baseUrl\": \"./\",\r\n \"paths\": {\r\n \"tslib\" : [\"bower_components/tslib/tslib.d.ts\"]\r\n }\r\n }\r\n}\r\n```\r\n\r\nFor JSPM users:\r\n\r\n```json\r\n{\r\n \"compilerOptions\": {\r\n \"module\": \"system\",\r\n \"importHelpers\": true,\r\n \"baseUrl\": \"./\",\r\n \"paths\": {\r\n \"tslib\" : [\"jspm_packages/npm/tslib@1.9.3/tslib.d.ts\"]\r\n }\r\n }\r\n}\r\n```\r\n\r\n\r\n# Contribute\r\n\r\nThere are many ways to [contribute](https://github.com/Microsoft/TypeScript/blob/master/CONTRIBUTING.md) to TypeScript.\r\n\r\n* [Submit bugs](https://github.com/Microsoft/TypeScript/issues) and help us verify fixes as they are checked in.\r\n* Review the [source code changes](https://github.com/Microsoft/TypeScript/pulls).\r\n* Engage with other TypeScript users and developers on [StackOverflow](http://stackoverflow.com/questions/tagged/typescript).\r\n* Join the [#typescript](http://twitter.com/#!/search/realtime/%23typescript) discussion on Twitter.\r\n* [Contribute bug fixes](https://github.com/Microsoft/TypeScript/blob/master/CONTRIBUTING.md).\r\n* Read the language specification ([docx](http://go.microsoft.com/fwlink/?LinkId=267121), [pdf](http://go.microsoft.com/fwlink/?LinkId=267238)).\r\n\r\n# Documentation\r\n\r\n* [Quick tutorial](http://www.typescriptlang.org/Tutorial)\r\n* [Programming handbook](http://www.typescriptlang.org/Handbook)\r\n* [Language specification](https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md)\r\n* [Homepage](http://www.typescriptlang.org/)\r\n", - "readmeFilename": "README.md", - "_id": "tslib@1.9.3", - "_requested": { - "type": "version", - "registry": true, - "raw": "tslib@1.9.3", - "name": "tslib", - "escapedName": "tslib", - "rawSpec": "1.9.3", - "saveSpec": "[Circular]", - "fetchSpec": "1.9.3" - }, - "_spec": "1.9.3", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": "[Circular]", - "dependencies": {}, - "devDependencies": "[Circular]", - "optionalDependencies": "[Circular]", - "_dependencies": "[Circular]", - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/tslib", - "error": "[Circular]", - "extraneous": false, - "_deduped": "tslib" - } - }, - "description": "Angular - the routing library", - "es2015": "./fesm2015/router.js", - "esm2015": "./esm2015/router.js", - "esm5": "./esm5/router.js", - "fesm2015": "./fesm2015/router.js", - "fesm5": "./fesm5/router.js", - "homepage": "https://github.com/angular/angular/tree/master/packages/router", - "keywords": [ - "angular", - "router" - ], - "license": "MIT", - "main": "./bundles/router.umd.js", - "module": "./fesm5/router.js", - "name": "@angular/router", - "ng-update": { - "packageGroup": [ - "@angular/core", - "@angular/bazel", - "@angular/common", - "@angular/compiler", - "@angular/compiler-cli", - "@angular/animations", - "@angular/elements", - "@angular/platform-browser", - "@angular/platform-browser-dynamic", - "@angular/forms", - "@angular/http", - "@angular/platform-server", - "@angular/platform-webworker", - "@angular/platform-webworker-dynamic", - "@angular/upgrade", - "@angular/router", - "@angular/language-service", - "@angular/service-worker" - ] - }, - "peerDependencies": { - "@angular/core": "7.0.3", - "@angular/common": "7.0.3", - "@angular/platform-browser": "7.0.3", - "rxjs": "^6.0.0" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/angular/angular.git" - }, - "sideEffects": false, - "typings": "./router.d.ts", - "version": "7.0.3", - "readme": "Angular\n=======\n\nThe sources for this package are in the main [Angular](https://github.com/angular/angular) repo. Please file issues and pull requests against that repo.\n\nLicense: MIT\n", - "readmeFilename": "README.md", - "devDependencies": {}, - "optionalDependencies": {}, - "_dependencies": { - "tslib": "^1.9.0" - }, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/@angular/router", - "error": "[Circular]", - "extraneous": false, - "peerMissing": [ - { - "requiredBy": "@ngrx/router-store@6.1.2", - "requires": "@angular/router@^6.0.0" - } - ] - }, - "peerMissing": true - }, - "@mat-datetimepicker/core": { - "required": { - "name": "@mat-datetimepicker/core", - "version": "2.0.1", - "repository": { - "type": "git", - "url": "git+https://github.com/kuhnroyal/mat-datetimepicker.git" - }, - "author": { - "name": "PL", - "email": "kuhnroyal@gmail.com" - }, - "license": "MIT", - "peerDependencies": { - "@angular/core": "^6.0.7", - "@angular/material": "^6.3.3", - "@angular/cdk": "^6.3.3" - }, - "main": "bundles/mat-datetimepicker-core.umd.js", - "module": "fesm5/mat-datetimepicker-core.js", - "es2015": "fesm2015/mat-datetimepicker-core.js", - "esm5": "esm5/mat-datetimepicker-core.js", - "esm2015": "esm2015/mat-datetimepicker-core.js", - "fesm5": "fesm5/mat-datetimepicker-core.js", - "fesm2015": "fesm2015/mat-datetimepicker-core.js", - "typings": "mat-datetimepicker-core.d.ts", - "metadata": "mat-datetimepicker-core.metadata.json", - "sideEffects": false, - "dependencies": { - "tslib": { - "name": "tslib", - "author": "[Circular]", - "homepage": "http://typescriptlang.org/", - "version": "1.9.3", - "license": "Apache-2.0", - "description": "Runtime library for TypeScript helper functions", - "keywords": "[Circular]", - "bugs": "[Circular]", - "repository": "[Circular]", - "main": "tslib.js", - "module": "tslib.es6.js", - "jsnext:main": "tslib.es6.js", - "typings": "tslib.d.ts", - "_resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "_integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", - "_from": "tslib@1.9.3", - "readme": "# tslib\r\n\r\nThis is a runtime library for [TypeScript](http://www.typescriptlang.org/) that contains all of the TypeScript helper functions.\r\n\r\nThis library is primarily used by the `--importHelpers` flag in TypeScript.\r\nWhen using `--importHelpers`, a module that uses helper functions like `__extends` and `__assign` in the following emitted file:\r\n\r\n```ts\r\nvar __assign = (this && this.__assign) || Object.assign || function(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))\r\n t[p] = s[p];\r\n }\r\n return t;\r\n};\r\nexports.x = {};\r\nexports.y = __assign({}, exports.x);\r\n\r\n```\r\n\r\nwill instead be emitted as something like the following:\r\n\r\n```ts\r\nvar tslib_1 = require(\"tslib\");\r\nexports.x = {};\r\nexports.y = tslib_1.__assign({}, exports.x);\r\n```\r\n\r\nBecause this can avoid duplicate declarations of things like `__extends`, `__assign`, etc., this means delivering users smaller files on average, as well as less runtime overhead.\r\nFor optimized bundles with TypeScript, you should absolutely consider using `tslib` and `--importHelpers`.\r\n\r\n# Installing\r\n\r\nFor the latest stable version, run:\r\n\r\n## npm\r\n\r\n```sh\r\n# TypeScript 2.3.3 or later\r\nnpm install --save tslib\r\n\r\n# TypeScript 2.3.2 or earlier\r\nnpm install --save tslib@1.6.1\r\n```\r\n\r\n## bower\r\n\r\n```sh\r\n# TypeScript 2.3.3 or later\r\nbower install tslib\r\n\r\n# TypeScript 2.3.2 or earlier\r\nbower install tslib@1.6.1\r\n```\r\n\r\n## JSPM\r\n\r\n```sh\r\n# TypeScript 2.3.3 or later\r\njspm install tslib\r\n\r\n# TypeScript 2.3.2 or earlier\r\njspm install tslib@1.6.1\r\n```\r\n\r\n# Usage\r\n\r\nSet the `importHelpers` compiler option on the command line:\r\n\r\n```\r\ntsc --importHelpers file.ts\r\n```\r\n\r\nor in your tsconfig.json:\r\n\r\n```json\r\n{\r\n \"compilerOptions\": {\r\n \"importHelpers\": true\r\n }\r\n}\r\n```\r\n\r\n#### For bower and JSPM users\r\n\r\nYou will need to add a `paths` mapping for `tslib`, e.g. For Bower users:\r\n\r\n```json\r\n{\r\n \"compilerOptions\": {\r\n \"module\": \"amd\",\r\n \"importHelpers\": true,\r\n \"baseUrl\": \"./\",\r\n \"paths\": {\r\n \"tslib\" : [\"bower_components/tslib/tslib.d.ts\"]\r\n }\r\n }\r\n}\r\n```\r\n\r\nFor JSPM users:\r\n\r\n```json\r\n{\r\n \"compilerOptions\": {\r\n \"module\": \"system\",\r\n \"importHelpers\": true,\r\n \"baseUrl\": \"./\",\r\n \"paths\": {\r\n \"tslib\" : [\"jspm_packages/npm/tslib@1.9.3/tslib.d.ts\"]\r\n }\r\n }\r\n}\r\n```\r\n\r\n\r\n# Contribute\r\n\r\nThere are many ways to [contribute](https://github.com/Microsoft/TypeScript/blob/master/CONTRIBUTING.md) to TypeScript.\r\n\r\n* [Submit bugs](https://github.com/Microsoft/TypeScript/issues) and help us verify fixes as they are checked in.\r\n* Review the [source code changes](https://github.com/Microsoft/TypeScript/pulls).\r\n* Engage with other TypeScript users and developers on [StackOverflow](http://stackoverflow.com/questions/tagged/typescript).\r\n* Join the [#typescript](http://twitter.com/#!/search/realtime/%23typescript) discussion on Twitter.\r\n* [Contribute bug fixes](https://github.com/Microsoft/TypeScript/blob/master/CONTRIBUTING.md).\r\n* Read the language specification ([docx](http://go.microsoft.com/fwlink/?LinkId=267121), [pdf](http://go.microsoft.com/fwlink/?LinkId=267238)).\r\n\r\n# Documentation\r\n\r\n* [Quick tutorial](http://www.typescriptlang.org/Tutorial)\r\n* [Programming handbook](http://www.typescriptlang.org/Handbook)\r\n* [Language specification](https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md)\r\n* [Homepage](http://www.typescriptlang.org/)\r\n", - "readmeFilename": "README.md", - "_id": "tslib@1.9.3", - "_requested": { - "type": "version", - "registry": true, - "raw": "tslib@1.9.3", - "name": "tslib", - "escapedName": "tslib", - "rawSpec": "1.9.3", - "saveSpec": "[Circular]", - "fetchSpec": "1.9.3" - }, - "_spec": "1.9.3", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": "[Circular]", - "dependencies": {}, - "devDependencies": "[Circular]", - "optionalDependencies": "[Circular]", - "_dependencies": "[Circular]", - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/tslib", - "error": "[Circular]", - "extraneous": false, - "_deduped": "tslib" - } - }, - "_resolved": "https://registry.npmjs.org/@mat-datetimepicker/core/-/core-2.0.1.tgz", - "_integrity": "sha1-4NsdtdTPe6Vrck7AQIF8totXdfI=", - "_from": "@mat-datetimepicker/core@2.0.1", - "readme": "# Material Datetimepicker for @angular/material 6.x\n\nThis is the main branch for @angular/material 6.x.\n\nYou can find the Angular 5 version on the `1.x` branch.\n\n### Description\n\nThe datetimepicker is taken from [Promact/md2](https://github.com/Promact/md2) and modified to use @angular/material as base and added theming support.\n\nLike the @angular/material datepicker it contains a native-datetime-adapter as well as a moment-datetime-adapter.\n\n[![Latest Stable Version](https://img.shields.io/npm/v/@mat-datetimepicker/core.svg)](https://www.npmjs.com/package/@mat-datetimepicker/core)\n[![License](https://img.shields.io/npm/l/@mat-datetimepicker/core.svg)](https://www.npmjs.com/package/@mat-datetimepicker/core)\n[![NPM Downloads](https://img.shields.io/npm/dm/@mat-datetimepicker/core.svg)](https://www.npmjs.com/package/@mat-datetimepicker/core)\n\n### Installation\nInstall:\n```\nyarn install @mat-datetimepicker/core\n```\nAnd for the moment adapter:\n```\nyarn install @angular/material-moment-adapter\nyarn install @mat-datetimepicker/moment\n``` \n\n### Performing a local build\n```\nyarn install\nyarn build\n``` \n\n### Using the local build in some project\n```\ncd my-project\n``` \nAdd the dependencies to your `package.json`:\n```\n\"dependencies\": {\n \"@mat-datetimepicker/core\": \"2.0.0\",\n \"@mat-datetimepicker/moment\": \"2.0.0\",\n}\n```\nLink the local built modules:\n```\nyarn link \"@mat-datetimepicker/core\"\nyarn link \"@mat-datetimepicker/moment\"\n``` \n\n### Import & configuration\nBasically the same way the @angular/material datepicker is configured and imported.\n\n```\nimports: [\n ...\n MatDatepickerModule,\n // use this if you want to use native javascript dates and INTL API if available\n // MatNativeDatetimeModule,\n MatMomentDatetimeModule,\n MatDatetimepickerModule\n]\n```\n\n@see [src/app/app.module.ts](src/app/app.module.ts)\n\n### Usage\n```\n
\n \n Start DateTime\n \n \n \n \n
\n```\n### Theming\n```\n@import '~@mat-datetimepicker/core/datetimepicker/datetimepicker-theme.scss';\n\n// Using the $theme variable from the pre-built theme you can call the theming function\n@include mat-datetimepicker-theme($theme);\n```\n@see [src/styles.scss](src/styles.scss)\n\n", - "readmeFilename": "README.md", - "description": "This is the main branch for @angular/material 6.x.", - "bugs": { - "url": "https://github.com/kuhnroyal/mat-datetimepicker/issues" - }, - "homepage": "https://github.com/kuhnroyal/mat-datetimepicker#readme", - "_id": "@mat-datetimepicker/core@2.0.1", - "_requested": { - "type": "version", - "registry": true, - "raw": "@mat-datetimepicker/core@2.0.1", - "name": "@mat-datetimepicker/core", - "escapedName": "@mat-datetimepicker%2fcore", - "scope": "@mat-datetimepicker", - "rawSpec": "2.0.1", - "saveSpec": "[Circular]", - "fetchSpec": "2.0.1" - }, - "_spec": "2.0.1", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "@mat-datetimepicker/core@2.0.1", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "devDependencies": {}, - "optionalDependencies": {}, - "_dependencies": { - "tslib": "^1.9.0" - }, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/@mat-datetimepicker/core", - "error": "[Circular]", - "extraneous": false, - "peerMissing": [ - { - "requiredBy": "@mat-datetimepicker/moment@2.0.1", - "requires": "@mat-datetimepicker/core@2.0.0" - } - ] - }, - "peerMissing": true - }, - "@mat-datetimepicker/moment": { - "version": "2.0.1", - "from": "@mat-datetimepicker/moment@2.0.1", - "resolved": "https://registry.npmjs.org/@mat-datetimepicker/moment/-/moment-2.0.1.tgz" - }, - "@ngrx/effects": { - "version": "6.1.2", - "from": "@ngrx/effects@6.1.2", - "resolved": "https://registry.npmjs.org/@ngrx/effects/-/effects-6.1.2.tgz" - }, - "@ngrx/router-store": { - "version": "6.1.2", - "from": "@ngrx/router-store@6.1.2", - "resolved": "https://registry.npmjs.org/@ngrx/router-store/-/router-store-6.1.2.tgz" - }, - "@ngrx/store": { - "version": "6.1.2", - "from": "@ngrx/store@6.1.2", - "resolved": "https://registry.npmjs.org/@ngrx/store/-/store-6.1.2.tgz" - }, - "@ngrx/store-devtools": { - "version": "6.1.2", - "from": "@ngrx/store-devtools@6.1.2", - "resolved": "https://registry.npmjs.org/@ngrx/store-devtools/-/store-devtools-6.1.2.tgz" - }, - "@ngx-translate/core": { - "version": "10.0.2", - "from": "@ngx-translate/core@10.0.2", - "resolved": "https://registry.npmjs.org/@ngx-translate/core/-/core-10.0.2.tgz" - }, - "alfresco-js-api": { - "required": { - "_args": [ - [ - "alfresco-js-api@2.6.1", - "/Users/dvuika/github/alfresco-content-app" - ], - [ - "alfresco-js-api@2.6.1", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "_from": "alfresco-js-api@2.6.1", - "_id": "alfresco-js-api@2.6.1", - "_integrity": "sha512-E1maHlxlFS3DAmYWG9ueerMWgrcbJSVFO52Bfk2XGx3atEnH3iBFuG0ZczfCJCGIbtv22VliR5qQ90Cufuzhkw==", - "_location": "/alfresco-js-api", - "_phantomChildren": {}, - "_requested": { - "type": "version", - "registry": true, - "raw": "alfresco-js-api@2.6.1", - "name": "alfresco-js-api", - "escapedName": "alfresco-js-api", - "rawSpec": "2.6.1", - "saveSpec": "[Circular]", - "fetchSpec": "2.6.1" - }, - "_requiredBy": [ - "/" - ], - "_resolved": "https://registry.npmjs.org/alfresco-js-api/-/alfresco-js-api-2.6.1.tgz", - "_spec": "2.6.1", - "_where": "/Users/dvuika/github/alfresco-content-app", - "author": { - "name": "Alfresco Software, Ltd." - }, - "bugs": { - "url": "https://github.com/Alfresco/alfresco-js-api/issues" - }, - "contributors": [ - { - "name": "Will Abson", - "email": "will.abson@alfresco.com" - }, - { - "name": "Eugenio Romano", - "email": "eugenio.romano@alfresco.com" - }, - { - "name": "Denys Vuika", - "email": "denys.vuika@gmail.com" - }, - { - "name": "Mario Romano", - "email": "mario.romano83@gmail.com" - } - ], - "dependencies": { - "event-emitter": { - "name": "event-emitter", - "version": "0.3.4", - "description": "Environment agnostic event emitter", - "author": { - "name": "Mariusz Nowak", - "email": "medyk@medikoo.com", - "url": "http://www.medikoo.com/" - }, - "keywords": [ - "event", - "events", - "trigger", - "observer", - "listener", - "emitter", - "pubsub" - ], - "repository": { - "type": "git", - "url": "git://github.com/medikoo/event-emitter.git" - }, - "dependencies": { - "d": { - "name": "d", - "version": "0.1.1", - "description": "Property descriptor factory", - "author": { - "name": "Mariusz Nowak", - "email": "medyk@medikoo.com", - "url": "http://www.medikoo.com/" - }, - "scripts": { - "test": "node node_modules/tad/bin/tad" - }, - "repository": { - "type": "git", - "url": "git://github.com/medikoo/d.git" - }, - "keywords": [ - "descriptor", - "es", - "ecmascript", - "ecma", - "property", - "descriptors", - "meta", - "properties" - ], - "dependencies": { - "es5-ext": { - "name": "es5-ext", - "version": "0.10.45", - "description": "ECMAScript extensions and shims", - "author": { - "name": "Mariusz Nowak", - "email": "medyk@medikoo.com", - "url": "http://www.medikoo.com/" - }, - "keywords": [ - "ecmascript", - "ecmascript5", - "ecmascript6", - "es5", - "es6", - "extensions", - "ext", - "addons", - "extras", - "harmony", - "javascript", - "polyfill", - "shim", - "util", - "utils", - "utilities" - ], - "repository": { - "type": "git", - "url": "git://github.com/medikoo/es5-ext.git" - }, - "dependencies": {}, - "devDependencies": { - "eslint": "^4.15", - "eslint-config-medikoo-es5": "^1.4.8", - "tad": "~0.2.7" - }, - "eslintConfig": { - "extends": "medikoo-es5", - "root": true, - "rules": { - "no-extend-native": "off" - } - }, - "scripts": { - "lint": "eslint --ignore-path=.gitignore .", - "test": "node ./node_modules/tad/bin/tad" - }, - "license": "ISC", - "_resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.45.tgz", - "_integrity": "sha512-FkfM6Vxxfmztilbxxz5UKSD4ICMf5tSpRFtDNtkAhOxZ0EKtX6qwmXNyH/sFyIbX2P/nU5AMiA9jilWsUGJzCQ==", - "_from": "es5-ext@0.10.45", - "readme": "[![Build status][nix-build-image]][nix-build-url]\n[![Windows status][win-build-image]][win-build-url]\n![Transpilation status][transpilation-image]\n[![npm version][npm-image]][npm-url]\n\n# es5-ext\n\n## ECMAScript 5 extensions\n\n### (with respect to ECMAScript 6 standard)\n\nShims for upcoming ES6 standard and other goodies implemented strictly with ECMAScript conventions in mind.\n\nIt's designed to be used in compliant ECMAScript 5 or ECMAScript 6 environments. Older environments are not supported, although most of the features should work with correct ECMAScript 5 shim on board.\n\nWhen used in ECMAScript 6 environment, native implementation (if valid) takes precedence over shims.\n\n### Installation\n\n $ npm install es5-ext\n\nTo port it to Browser or any other (non CJS) environment, use your favorite CJS bundler. No favorite yet? Try: [Browserify](http://browserify.org/), [Webmake](https://github.com/medikoo/modules-webmake) or [Webpack](http://webpack.github.io/)\n\n### Usage\n\n#### ECMAScript 6 features\n\nYou can force ES6 features to be implemented in your environment, e.g. following will assign `from` function to `Array` (only if it's not implemented already).\n\n```javascript\nrequire(\"es5-ext/array/from/implement\");\nArray.from(\"foo\"); // ['f', 'o', 'o']\n```\n\nYou can also access shims directly, without fixing native objects. Following will return native `Array.from` if it's available and fallback to shim if it's not.\n\n```javascript\nvar aFrom = require(\"es5-ext/array/from\");\naFrom(\"foo\"); // ['f', 'o', 'o']\n```\n\nIf you want to use shim unconditionally (even if native implementation exists) do:\n\n```javascript\nvar aFrom = require(\"es5-ext/array/from/shim\");\naFrom(\"foo\"); // ['f', 'o', 'o']\n```\n\n##### List of ES6 shims\n\nIt's about properties introduced with ES6 and those that have been updated in new spec.\n\n* `Array.from` -> `require('es5-ext/array/from')`\n* `Array.of` -> `require('es5-ext/array/of')`\n* `Array.prototype.concat` -> `require('es5-ext/array/#/concat')`\n* `Array.prototype.copyWithin` -> `require('es5-ext/array/#/copy-within')`\n* `Array.prototype.entries` -> `require('es5-ext/array/#/entries')`\n* `Array.prototype.fill` -> `require('es5-ext/array/#/fill')`\n* `Array.prototype.filter` -> `require('es5-ext/array/#/filter')`\n* `Array.prototype.find` -> `require('es5-ext/array/#/find')`\n* `Array.prototype.findIndex` -> `require('es5-ext/array/#/find-index')`\n* `Array.prototype.keys` -> `require('es5-ext/array/#/keys')`\n* `Array.prototype.map` -> `require('es5-ext/array/#/map')`\n* `Array.prototype.slice` -> `require('es5-ext/array/#/slice')`\n* `Array.prototype.splice` -> `require('es5-ext/array/#/splice')`\n* `Array.prototype.values` -> `require('es5-ext/array/#/values')`\n* `Array.prototype[@@iterator]` -> `require('es5-ext/array/#/@@iterator')`\n* `Math.acosh` -> `require('es5-ext/math/acosh')`\n* `Math.asinh` -> `require('es5-ext/math/asinh')`\n* `Math.atanh` -> `require('es5-ext/math/atanh')`\n* `Math.cbrt` -> `require('es5-ext/math/cbrt')`\n* `Math.clz32` -> `require('es5-ext/math/clz32')`\n* `Math.cosh` -> `require('es5-ext/math/cosh')`\n* `Math.exmp1` -> `require('es5-ext/math/expm1')`\n* `Math.fround` -> `require('es5-ext/math/fround')`\n* `Math.hypot` -> `require('es5-ext/math/hypot')`\n* `Math.imul` -> `require('es5-ext/math/imul')`\n* `Math.log1p` -> `require('es5-ext/math/log1p')`\n* `Math.log2` -> `require('es5-ext/math/log2')`\n* `Math.log10` -> `require('es5-ext/math/log10')`\n* `Math.sign` -> `require('es5-ext/math/sign')`\n* `Math.signh` -> `require('es5-ext/math/signh')`\n* `Math.tanh` -> `require('es5-ext/math/tanh')`\n* `Math.trunc` -> `require('es5-ext/math/trunc')`\n* `Number.EPSILON` -> `require('es5-ext/number/epsilon')`\n* `Number.MAX_SAFE_INTEGER` -> `require('es5-ext/number/max-safe-integer')`\n* `Number.MIN_SAFE_INTEGER` -> `require('es5-ext/number/min-safe-integer')`\n* `Number.isFinite` -> `require('es5-ext/number/is-finite')`\n* `Number.isInteger` -> `require('es5-ext/number/is-integer')`\n* `Number.isNaN` -> `require('es5-ext/number/is-nan')`\n* `Number.isSafeInteger` -> `require('es5-ext/number/is-safe-integer')`\n* `Object.assign` -> `require('es5-ext/object/assign')`\n* `Object.keys` -> `require('es5-ext/object/keys')`\n* `Object.setPrototypeOf` -> `require('es5-ext/object/set-prototype-of')`\n* `RegExp.prototype.match` -> `require('es5-ext/reg-exp/#/match')`\n* `RegExp.prototype.replace` -> `require('es5-ext/reg-exp/#/replace')`\n* `RegExp.prototype.search` -> `require('es5-ext/reg-exp/#/search')`\n* `RegExp.prototype.split` -> `require('es5-ext/reg-exp/#/split')`\n* `RegExp.prototype.sticky` -> Implement with `require('es5-ext/reg-exp/#/sticky/implement')`, use as function with `require('es5-ext/reg-exp/#/is-sticky')`\n* `RegExp.prototype.unicode` -> Implement with `require('es5-ext/reg-exp/#/unicode/implement')`, use as function with `require('es5-ext/reg-exp/#/is-unicode')`\n* `String.fromCodePoint` -> `require('es5-ext/string/from-code-point')`\n* `String.raw` -> `require('es5-ext/string/raw')`\n* `String.prototype.codePointAt` -> `require('es5-ext/string/#/code-point-at')`\n* `String.prototype.contains` -> `require('es5-ext/string/#/contains')`\n* `String.prototype.endsWith` -> `require('es5-ext/string/#/ends-with')`\n* `String.prototype.normalize` -> `require('es5-ext/string/#/normalize')`\n* `String.prototype.repeat` -> `require('es5-ext/string/#/repeat')`\n* `String.prototype.startsWith` -> `require('es5-ext/string/#/starts-with')`\n* `String.prototype[@@iterator]` -> `require('es5-ext/string/#/@@iterator')`\n\n#### Non ECMAScript standard features\n\n**es5-ext** provides also other utils, and implements them as if they were proposed for a standard. It mostly offers methods (not functions) which can directly be assigned to native prototypes:\n\n```javascript\nObject.defineProperty(Function.prototype, \"partial\", {\n\tvalue: require(\"es5-ext/function/#/partial\"),\n\tconfigurable: true,\n\tenumerable: false,\n\twritable: true\n});\nObject.defineProperty(Array.prototype, \"flatten\", {\n\tvalue: require(\"es5-ext/array/#/flatten\"),\n\tconfigurable: true,\n\tenumerable: false,\n\twritable: true\n});\nObject.defineProperty(String.prototype, \"capitalize\", {\n\tvalue: require(\"es5-ext/string/#/capitalize\"),\n\tconfigurable: true,\n\tenumerable: false,\n\twritable: true\n});\n```\n\nSee [es5-extend](https://github.com/wookieb/es5-extend#es5-extend), a great utility that automatically will extend natives for you.\n\n**Important:** Remember to **not** extend natives in scope of generic reusable packages (e.g. ones you intend to publish to npm). Extending natives is fine **only** if you're the _owner_ of the global scope, so e.g. in final project you lead development of.\n\nWhen you're in situation when native extensions are not good idea, then you should use methods indirectly:\n\n```javascript\nvar flatten = require(\"es5-ext/array/#/flatten\");\n\nflatten.call([1, [2, [3, 4]]]); // [1, 2, 3, 4]\n```\n\nfor better convenience you can turn methods into functions:\n\n```javascript\nvar call = Function.prototype.call;\nvar flatten = call.bind(require(\"es5-ext/array/#/flatten\"));\n\nflatten([1, [2, [3, 4]]]); // [1, 2, 3, 4]\n```\n\nYou can configure custom toolkit (like [underscorejs](http://underscorejs.org/)), and use it throughout your application\n\n```javascript\nvar util = {};\nutil.partial = call.bind(require(\"es5-ext/function/#/partial\"));\nutil.flatten = call.bind(require(\"es5-ext/array/#/flatten\"));\nutil.startsWith = call.bind(require(\"es5-ext/string/#/starts-with\"));\n\nutil.flatten([1, [2, [3, 4]]]); // [1, 2, 3, 4]\n```\n\nAs with native ones most methods are generic and can be run on any type of object.\n\n## API\n\n### Global extensions\n\n#### global _(es5-ext/global)_\n\nObject that represents global scope\n\n### Array Constructor extensions\n\n#### from(arrayLike[, mapFn[, thisArg]]) _(es5-ext/array/from)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.from). \nReturns array representation of _iterable_ or _arrayLike_. If _arrayLike_ is an instance of array, its copy is returned.\n\n#### generate([length[, …fill]]) _(es5-ext/array/generate)_\n\nGenerate an array of pre-given _length_ built of repeated arguments.\n\n#### isPlainArray(x) _(es5-ext/array/is-plain-array)_\n\nReturns true if object is plain array (not instance of one of the Array's extensions).\n\n#### of([…items]) _(es5-ext/array/of)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.of). \nCreate an array from given arguments.\n\n#### toArray(obj) _(es5-ext/array/to-array)_\n\nReturns array representation of `obj`. If `obj` is already an array, `obj` is returned back.\n\n#### validArray(obj) _(es5-ext/array/valid-array)_\n\nReturns `obj` if it's an array, otherwise throws `TypeError`\n\n### Array Prototype extensions\n\n#### arr.binarySearch(compareFn) _(es5-ext/array/#/binary-search)_\n\nIn **sorted** list search for index of item for which _compareFn_ returns value closest to _0_. \nIt's variant of binary search algorithm\n\n#### arr.clear() _(es5-ext/array/#/clear)_\n\nClears the array\n\n#### arr.compact() _(es5-ext/array/#/compact)_\n\nReturns a copy of the context with all non-values (`null` or `undefined`) removed.\n\n#### arr.concat() _(es5-ext/array/#/concat)_\n\n[_Updated with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype.concat). \nES6's version of `concat`. Supports `isConcatSpreadable` symbol, and returns array of same type as the context.\n\n#### arr.contains(searchElement[, position]) _(es5-ext/array/#/contains)_\n\nWhether list contains the given value.\n\n#### arr.copyWithin(target, start[, end]) _(es5-ext/array/#/copy-within)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.copywithin).\n\n#### arr.diff(other) _(es5-ext/array/#/diff)_\n\nReturns the array of elements that are present in context list but not present in other list.\n\n#### arr.eIndexOf(searchElement[, fromIndex]) _(es5-ext/array/#/e-index-of)_\n\n_egal_ version of `indexOf` method. [_SameValueZero_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) logic is used for comparision\n\n#### arr.eLastIndexOf(searchElement[, fromIndex]) _(es5-ext/array/#/e-last-index-of)_\n\n_egal_ version of `lastIndexOf` method. [_SameValueZero_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) logic is used for comparision\n\n#### arr.entries() _(es5-ext/array/#/entries)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype.entries). \nReturns iterator object, which traverses the array. Each value is represented with an array, where first value is an index and second is corresponding to index value.\n\n#### arr.exclusion([…lists]]) _(es5-ext/array/#/exclusion)_\n\nReturns the array of elements that are found only in one of the lists (either context list or list provided in arguments).\n\n#### arr.fill(value[, start, end]) _(es5-ext/array/#/fill)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.fill).\n\n#### arr.filter(callback[, thisArg]) _(es5-ext/array/#/filter)_\n\n[_Updated with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.filter). \nES6's version of `filter`, returns array of same type as the context.\n\n#### arr.find(predicate[, thisArg]) _(es5-ext/array/#/find)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.find). \nReturn first element for which given function returns true\n\n#### arr.findIndex(predicate[, thisArg]) _(es5-ext/array/#/find-index)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.findindex). \nReturn first index for which given function returns true\n\n#### arr.first() _(es5-ext/array/#/first)_\n\nReturns value for first defined index\n\n#### arr.firstIndex() _(es5-ext/array/#/first-index)_\n\nReturns first declared index of the array\n\n#### arr.flatten() _(es5-ext/array/#/flatten)_\n\nReturns flattened version of the array\n\n#### arr.forEachRight(cb[, thisArg]) _(es5-ext/array/#/for-each-right)_\n\n`forEach` starting from last element\n\n#### arr.group(cb[, thisArg]) _(es5-ext/array/#/group)_\n\nGroup list elements by value returned by _cb_ function\n\n#### arr.indexesOf(searchElement[, fromIndex]) _(es5-ext/array/#/indexes-of)_\n\nReturns array of all indexes of given value\n\n#### arr.intersection([…lists]) _(es5-ext/array/#/intersection)_\n\nComputes the array of values that are the intersection of all lists (context list and lists given in arguments)\n\n#### arr.isCopy(other) _(es5-ext/array/#/is-copy)_\n\nReturns true if both context and _other_ lists have same content\n\n#### arr.isUniq() _(es5-ext/array/#/is-uniq)_\n\nReturns true if all values in array are unique\n\n#### arr.keys() _(es5-ext/array/#/keys)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype.keys). \nReturns iterator object, which traverses all array indexes.\n\n#### arr.last() _(es5-ext/array/#/last)_\n\nReturns value of last defined index\n\n#### arr.lastIndex() _(es5-ext/array/#/last)_\n\nReturns last defined index of the array\n\n#### arr.map(callback[, thisArg]) _(es5-ext/array/#/map)_\n\n[_Updated with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.map). \nES6's version of `map`, returns array of same type as the context.\n\n#### arr.remove(value[, …valuen]) _(es5-ext/array/#/remove)_\n\nRemove values from the array\n\n#### arr.separate(sep) _(es5-ext/array/#/separate)_\n\nReturns array with items separated with `sep` value\n\n#### arr.slice(callback[, thisArg]) _(es5-ext/array/#/slice)_\n\n[_Updated with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.slice). \nES6's version of `slice`, returns array of same type as the context.\n\n#### arr.someRight(cb[, thisArg]) _(es5-ext/array/#/someRight)_\n\n`some` starting from last element\n\n#### arr.splice(callback[, thisArg]) _(es5-ext/array/#/splice)_\n\n[_Updated with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.splice). \nES6's version of `splice`, returns array of same type as the context.\n\n#### arr.uniq() _(es5-ext/array/#/uniq)_\n\nReturns duplicate-free version of the array\n\n#### arr.values() _(es5-ext/array/#/values)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype.values). \nReturns iterator object which traverses all array values.\n\n#### arr[@@iterator] _(es5-ext/array/#/@@iterator)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype-@@iterator). \nReturns iterator object which traverses all array values.\n\n### Boolean Constructor extensions\n\n#### isBoolean(x) _(es5-ext/boolean/is-boolean)_\n\nWhether value is boolean\n\n### Date Constructor extensions\n\n#### isDate(x) _(es5-ext/date/is-date)_\n\nWhether value is date instance\n\n#### validDate(x) _(es5-ext/date/valid-date)_\n\nIf given object is not date throw TypeError in other case return it.\n\n### Date Prototype extensions\n\n#### date.copy(date) _(es5-ext/date/#/copy)_\n\nReturns a copy of the date object\n\n#### date.daysInMonth() _(es5-ext/date/#/days-in-month)_\n\nReturns number of days of date's month\n\n#### date.floorDay() _(es5-ext/date/#/floor-day)_\n\nSets the date time to 00:00:00.000\n\n#### date.floorMonth() _(es5-ext/date/#/floor-month)_\n\nSets date day to 1 and date time to 00:00:00.000\n\n#### date.floorYear() _(es5-ext/date/#/floor-year)_\n\nSets date month to 0, day to 1 and date time to 00:00:00.000\n\n#### date.format(pattern) _(es5-ext/date/#/format)_\n\nFormats date up to given string. Supported patterns:\n\n* `%Y` - Year with century, 1999, 2003\n* `%y` - Year without century, 99, 03\n* `%m` - Month, 01..12\n* `%d` - Day of the month 01..31\n* `%H` - Hour (24-hour clock), 00..23\n* `%M` - Minute, 00..59\n* `%S` - Second, 00..59\n* `%L` - Milliseconds, 000..999\n\n### Error Constructor extensions\n\n#### custom(message/_, code, ext_/) _(es5-ext/error/custom)_\n\nCreates custom error object, optinally extended with `code` and other extension properties (provided with `ext` object)\n\n#### isError(x) _(es5-ext/error/is-error)_\n\nWhether value is an error (instance of `Error`).\n\n#### validError(x) _(es5-ext/error/valid-error)_\n\nIf given object is not error throw TypeError in other case return it.\n\n### Error Prototype extensions\n\n#### err.throw() _(es5-ext/error/#/throw)_\n\nThrows error\n\n### Function Constructor extensions\n\nSome of the functions were inspired by [Functional JavaScript](http://osteele.com/sources/javascript/functional/) project by Olivier Steele\n\n#### constant(x) _(es5-ext/function/constant)_\n\nReturns a constant function that returns pregiven argument\n\n_k(x)(y) =def x_\n\n#### identity(x) _(es5-ext/function/identity)_\n\nIdentity function. Returns first argument\n\n_i(x) =def x_\n\n#### invoke(name[, …args]) _(es5-ext/function/invoke)_\n\nReturns a function that takes an object as an argument, and applies object's\n_name_ method to arguments. \n_name_ can be name of the method or method itself.\n\n_invoke(name, …args)(object, …args2) =def object\\[name\\]\\(…args, …args2\\)_\n\n#### isArguments(x) _(es5-ext/function/is-arguments)_\n\nWhether value is arguments object\n\n#### isFunction(arg) _(es5-ext/function/is-function)_\n\nWhether value is instance of function\n\n#### noop() _(es5-ext/function/noop)_\n\nNo operation function\n\n#### pluck(name) _(es5-ext/function/pluck)_\n\nReturns a function that takes an object, and returns the value of its _name_\nproperty\n\n_pluck(name)(obj) =def obj[name]_\n\n#### validFunction(arg) _(es5-ext/function/valid-function)_\n\nIf given object is not function throw TypeError in other case return it.\n\n### Function Prototype extensions\n\nSome of the methods were inspired by [Functional JavaScript](http://osteele.com/sources/javascript/functional/) project by Olivier Steele\n\n#### fn.compose([…fns]) _(es5-ext/function/#/compose)_\n\nApplies the functions in reverse argument-list order.\n\n_f1.compose(f2, f3, f4)(…args) =def f1(f2(f3(f4(…arg))))_\n\n#### fn.copy() _(es5-ext/function/#/copy)_\n\nProduces copy of given function\n\n#### fn.curry([n]) _(es5-ext/function/#/curry)_\n\nInvoking the function returned by this function only _n_ arguments are passed to the underlying function. If the underlying function is not saturated, the result is a function that passes all its arguments to the underlying function. \nIf _n_ is not provided then it defaults to context function length\n\n_f.curry(4)(arg1, arg2)(arg3)(arg4) =def f(arg1, args2, arg3, arg4)_\n\n#### fn.lock([…args]) _(es5-ext/function/#/lock)_\n\nReturns a function that applies the underlying function to _args_, and ignores its own arguments.\n\n_f.lock(…args)(…args2) =def f(…args)_\n\n_Named after it's counterpart in Google Closure_\n\n#### fn.not() _(es5-ext/function/#/not)_\n\nReturns a function that returns boolean negation of value returned by underlying function.\n\n_f.not()(…args) =def !f(…args)_\n\n#### fn.partial([…args]) _(es5-ext/function/#/partial)_\n\nReturns a function that when called will behave like context function called with initially passed arguments. If more arguments are suplilied, they are appended to initial args.\n\n_f.partial(…args1)(…args2) =def f(…args1, …args2)_\n\n#### fn.spread() _(es5-ext/function/#/spread)_\n\nReturns a function that applies underlying function with first list argument\n\n_f.match()(args) =def f.apply(null, args)_\n\n#### fn.toStringTokens() _(es5-ext/function/#/to-string-tokens)_\n\nSerializes function into two (arguments and body) string tokens. Result is plain object with `args` and `body` properties.\n\n### Math extensions\n\n#### acosh(x) _(es5-ext/math/acosh)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.acosh).\n\n#### asinh(x) _(es5-ext/math/asinh)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.asinh).\n\n#### atanh(x) _(es5-ext/math/atanh)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.atanh).\n\n#### cbrt(x) _(es5-ext/math/cbrt)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.cbrt).\n\n#### clz32(x) _(es5-ext/math/clz32)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.clz32).\n\n#### cosh(x) _(es5-ext/math/cosh)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.cosh).\n\n#### expm1(x) _(es5-ext/math/expm1)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.expm1).\n\n#### fround(x) _(es5-ext/math/fround)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.fround).\n\n#### hypot([…values]) _(es5-ext/math/hypot)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.hypot).\n\n#### imul(x, y) _(es5-ext/math/imul)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.imul).\n\n#### log1p(x) _(es5-ext/math/log1p)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.log1p).\n\n#### log2(x) _(es5-ext/math/log2)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.log2).\n\n#### log10(x) _(es5-ext/math/log10)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.log10).\n\n#### sign(x) _(es5-ext/math/sign)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.sign).\n\n#### sinh(x) _(es5-ext/math/sinh)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.sinh).\n\n#### tanh(x) _(es5-ext/math/tanh)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.tanh).\n\n#### trunc(x) _(es5-ext/math/trunc)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.trunc).\n\n### Number Constructor extensions\n\n#### EPSILON _(es5-ext/number/epsilon)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.epsilon).\n\nThe difference between 1 and the smallest value greater than 1 that is representable as a Number value, which is approximately 2.2204460492503130808472633361816 x 10-16.\n\n#### isFinite(x) _(es5-ext/number/is-finite)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.isfinite). \nWhether value is finite. Differs from global isNaN that it doesn't do type coercion.\n\n#### isInteger(x) _(es5-ext/number/is-integer)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.isinteger). \nWhether value is integer.\n\n#### isNaN(x) _(es5-ext/number/is-nan)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.isnan). \nWhether value is NaN. Differs from global isNaN that it doesn't do type coercion.\n\n#### isNumber(x) _(es5-ext/number/is-number)_\n\nWhether given value is number\n\n#### isSafeInteger(x) _(es5-ext/number/is-safe-integer)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.issafeinteger).\n\n#### MAX*SAFE_INTEGER *(es5-ext/number/max-safe-integer)\\_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.maxsafeinteger). \nThe value of Number.MAX_SAFE_INTEGER is 9007199254740991.\n\n#### MIN*SAFE_INTEGER *(es5-ext/number/min-safe-integer)\\_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.minsafeinteger). \nThe value of Number.MIN_SAFE_INTEGER is -9007199254740991 (253-1).\n\n#### toInteger(x) _(es5-ext/number/to-integer)_\n\nConverts value to integer\n\n#### toPosInteger(x) _(es5-ext/number/to-pos-integer)_\n\nConverts value to positive integer. If provided value is less than 0, then 0 is returned\n\n#### toUint32(x) _(es5-ext/number/to-uint32)_\n\nConverts value to unsigned 32 bit integer. This type is used for array lengths.\nSee: http://www.2ality.com/2012/02/js-integers.html\n\n### Number Prototype extensions\n\n#### num.pad(length[, precision]) _(es5-ext/number/#/pad)_\n\nPad given number with zeros. Returns string\n\n### Object Constructor extensions\n\n#### assign(target, source[, …sourcen]) _(es5-ext/object/assign)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign). \nExtend _target_ by enumerable own properties of other objects. If properties are already set on target object, they will be overwritten.\n\n#### clear(obj) _(es5-ext/object/clear)_\n\nRemove all enumerable own properties of the object\n\n#### compact(obj) _(es5-ext/object/compact)_\n\nReturns copy of the object with all enumerable properties that have no falsy values\n\n#### compare(obj1, obj2) _(es5-ext/object/compare)_\n\nUniversal cross-type compare function. To be used for e.g. array sort.\n\n#### copy(obj) _(es5-ext/object/copy)_\n\nReturns copy of the object with all enumerable properties.\n\n#### copyDeep(obj) _(es5-ext/object/copy-deep)_\n\nReturns deep copy of the object with all enumerable properties.\n\n#### count(obj) _(es5-ext/object/count)_\n\nCounts number of enumerable own properties on object\n\n#### create(obj[, properties]) _(es5-ext/object/create)_\n\n`Object.create` alternative that provides workaround for [V8 issue](http://code.google.com/p/v8/issues/detail?id=2804).\n\nWhen `null` is provided as a prototype, it's substituted with specially prepared object that derives from Object.prototype but has all Object.prototype properties shadowed with undefined.\n\nIt's quirky solution that allows us to have plain objects with no truthy properties but with turnable prototype.\n\nUse only for objects that you plan to switch prototypes of and be aware of limitations of this workaround.\n\n#### eq(x, y) _(es5-ext/object/eq)_\n\nWhether two values are equal, using [_SameValueZero_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) algorithm.\n\n#### every(obj, cb[, thisArg[, compareFn]]) _(es5-ext/object/every)_\n\nAnalogous to Array.prototype.every. Returns true if every key-value pair in this object satisfies the provided testing function. \nOptionally _compareFn_ can be provided which assures that keys are tested in given order. If provided _compareFn_ is equal to `true`, then order is alphabetical (by key).\n\n#### filter(obj, cb[, thisArg]) _(es5-ext/object/filter)_\n\nAnalogous to Array.prototype.filter. Returns new object with properites for which _cb_ function returned truthy value.\n\n#### firstKey(obj) _(es5-ext/object/first-key)_\n\nReturns first enumerable key of the object, as keys are unordered by specification, it can be any key of an object.\n\n#### flatten(obj) _(es5-ext/object/flatten)_\n\nReturns new object, with flatten properties of input object\n\n_flatten({ a: { b: 1 }, c: { d: 1 } }) =def { b: 1, d: 1 }_\n\n#### forEach(obj, cb[, thisArg[, compareFn]]) _(es5-ext/object/for-each)_\n\nAnalogous to Array.prototype.forEach. Calls a function for each key-value pair found in object\nOptionally _compareFn_ can be provided which assures that properties are iterated in given order. If provided _compareFn_ is equal to `true`, then order is alphabetical (by key).\n\n#### getPropertyNames() _(es5-ext/object/get-property-names)_\n\nGet all (not just own) property names of the object\n\n#### is(x, y) _(es5-ext/object/is)_\n\nWhether two values are equal, using [_SameValue_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) algorithm.\n\n#### isArrayLike(x) _(es5-ext/object/is-array-like)_\n\nWhether object is array-like object\n\n#### isCopy(x, y) _(es5-ext/object/is-copy)_\n\nTwo values are considered a copy of same value when all of their own enumerable properties have same values.\n\n#### isCopyDeep(x, y) _(es5-ext/object/is-copy-deep)_\n\nDeep comparision of objects\n\n#### isEmpty(obj) _(es5-ext/object/is-empty)_\n\nTrue if object doesn't have any own enumerable property\n\n#### isObject(arg) _(es5-ext/object/is-object)_\n\nWhether value is not primitive\n\n#### isPlainObject(arg) _(es5-ext/object/is-plain-object)_\n\nWhether object is plain object, its protototype should be Object.prototype and it cannot be host object.\n\n#### keyOf(obj, searchValue) _(es5-ext/object/key-of)_\n\nSearch object for value\n\n#### keys(obj) _(es5-ext/object/keys)_\n\n[_Updated with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.keys). \nES6's version of `keys`, doesn't throw on primitive input\n\n#### map(obj, cb[, thisArg]) _(es5-ext/object/map)_\n\nAnalogous to Array.prototype.map. Creates a new object with properties which values are results of calling a provided function on every key-value pair in this object.\n\n#### mapKeys(obj, cb[, thisArg]) _(es5-ext/object/map-keys)_\n\nCreate new object with same values, but remapped keys\n\n#### mixin(target, source) _(es5-ext/object/mixin)_\n\nExtend _target_ by all own properties of other objects. Properties found in both objects will be overwritten (unless they're not configurable and cannot be overwritten).\n_It was for a moment part of ECMAScript 6 draft._\n\n#### mixinPrototypes(target, …source]) _(es5-ext/object/mixin-prototypes)_\n\nExtends _target_, with all source and source's prototype properties.\nUseful as an alternative for `setPrototypeOf` in environments in which it cannot be shimmed (no `__proto__` support).\n\n#### normalizeOptions(options) _(es5-ext/object/normalize-options)_\n\nNormalizes options object into flat plain object.\n\nUseful for functions in which we either need to keep options object for future reference or need to modify it for internal use.\n\n* It never returns input `options` object back (always a copy is created)\n* `options` can be undefined in such case empty plain object is returned.\n* Copies all enumerable properties found down prototype chain.\n\n#### primitiveSet([…names]) _(es5-ext/object/primitive-set)_\n\nCreates `null` prototype based plain object, and sets on it all property names provided in arguments to true.\n\n#### safeTraverse(obj[, …names]) _(es5-ext/object/safe-traverse)_\n\nSafe navigation of object properties. See http://wiki.ecmascript.org/doku.php?id=strawman:existential_operator\n\n#### serialize(value) _(es5-ext/object/serialize)_\n\nSerialize value into string. Differs from [JSON.stringify](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) that it serializes also dates, functions and regular expresssions.\n\n#### setPrototypeOf(object, proto) _(es5-ext/object/set-prototype-of)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.setprototypeof). \nIf native version is not provided, it depends on existence of `__proto__` functionality, if it's missing, `null` instead of function is exposed.\n\n#### some(obj, cb[, thisArg[, compareFn]]) _(es5-ext/object/some)_\n\nAnalogous to Array.prototype.some Returns true if any key-value pair satisfies the provided\ntesting function. \nOptionally _compareFn_ can be provided which assures that keys are tested in given order. If provided _compareFn_ is equal to `true`, then order is alphabetical (by key).\n\n#### toArray(obj[, cb[, thisArg[, compareFn]]]) _(es5-ext/object/to-array)_\n\nCreates an array of results of calling a provided function on every key-value pair in this object. \nOptionally _compareFn_ can be provided which assures that results are added in given order. If provided _compareFn_ is equal to `true`, then order is alphabetical (by key).\n\n#### unserialize(str) _(es5-ext/object/unserialize)_\n\nUserializes value previously serialized with [serialize](#serializevalue-es5-extobjectserialize)\n\n#### validCallable(x) _(es5-ext/object/valid-callable)_\n\nIf given object is not callable throw TypeError in other case return it.\n\n#### validObject(x) _(es5-ext/object/valid-object)_\n\nThrows error if given value is not an object, otherwise it is returned.\n\n#### validValue(x) _(es5-ext/object/valid-value)_\n\nThrows error if given value is `null` or `undefined`, otherwise returns value.\n\n### RegExp Constructor extensions\n\n#### escape(str) _(es5-ext/reg-exp/escape)_\n\nEscapes string to be used in regular expression\n\n#### isRegExp(x) _(es5-ext/reg-exp/is-reg-exp)_\n\nWhether object is regular expression\n\n#### validRegExp(x) _(es5-ext/reg-exp/valid-reg-exp)_\n\nIf object is regular expression it is returned, otherwise TypeError is thrown.\n\n### RegExp Prototype extensions\n\n#### re.isSticky(x) _(es5-ext/reg-exp/#/is-sticky)_\n\nWhether regular expression has `sticky` flag.\n\nIt's to be used as counterpart to [regExp.sticky](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-get-regexp.prototype.sticky) if it's not implemented.\n\n#### re.isUnicode(x) _(es5-ext/reg-exp/#/is-unicode)_\n\nWhether regular expression has `unicode` flag.\n\nIt's to be used as counterpart to [regExp.unicode](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-get-regexp.prototype.unicode) if it's not implemented.\n\n#### re.match(string) _(es5-ext/reg-exp/#/match)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.match).\n\n#### re.replace(string, replaceValue) _(es5-ext/reg-exp/#/replace)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.replace).\n\n#### re.search(string) _(es5-ext/reg-exp/#/search)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.search).\n\n#### re.split(string) _(es5-ext/reg-exp/#/search)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.split).\n\n#### re.sticky _(es5-ext/reg-exp/#/sticky/implement)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.sticky). \nIt's a getter, so only `implement` and `is-implemented` modules are provided.\n\n#### re.unicode _(es5-ext/reg-exp/#/unicode/implement)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.unicode). \nIt's a getter, so only `implement` and `is-implemented` modules are provided.\n\n### String Constructor extensions\n\n#### formatMethod(fMap) _(es5-ext/string/format-method)_\n\nCreates format method. It's used e.g. to create `Date.prototype.format` method\n\n#### fromCodePoint([…codePoints]) _(es5-ext/string/from-code-point)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.fromcodepoint)\n\n#### isString(x) _(es5-ext/string/is-string)_\n\nWhether object is string\n\n#### randomUniq() _(es5-ext/string/random-uniq)_\n\nReturns randomly generated id, with guarantee of local uniqueness (no same id will be returned twice)\n\n#### raw(callSite[, …substitutions]) _(es5-ext/string/raw)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.raw)\n\n### String Prototype extensions\n\n#### str.at(pos) _(es5-ext/string/#/at)_\n\n_Proposed for ECMAScript 6/7 standard, but not (yet) in a draft_\n\nReturns a string at given position in Unicode-safe manner.\nBased on [implementation by Mathias Bynens](https://github.com/mathiasbynens/String.prototype.at).\n\n#### str.camelToHyphen() _(es5-ext/string/#/camel-to-hyphen)_\n\nConvert camelCase string to hyphen separated, e.g. one-two-three -> oneTwoThree.\nUseful when converting names from js property convention into filename convention.\n\n#### str.capitalize() _(es5-ext/string/#/capitalize)_\n\nCapitalize first character of a string\n\n#### str.caseInsensitiveCompare(str) _(es5-ext/string/#/case-insensitive-compare)_\n\nCase insensitive compare\n\n#### str.codePointAt(pos) _(es5-ext/string/#/code-point-at)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.codepointat)\n\nBased on [implementation by Mathias Bynens](https://github.com/mathiasbynens/String.prototype.codePointAt).\n\n#### str.contains(searchString[, position]) _(es5-ext/string/#/contains)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.contains)\n\nWhether string contains given string.\n\n#### str.endsWith(searchString[, endPosition]) _(es5-ext/string/#/ends-with)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.endswith). \nWhether strings ends with given string\n\n#### str.hyphenToCamel() _(es5-ext/string/#/hyphen-to-camel)_\n\nConvert hyphen separated string to camelCase, e.g. one-two-three -> oneTwoThree.\nUseful when converting names from filename convention to js property name convention.\n\n#### str.indent(str[, count]) _(es5-ext/string/#/indent)_\n\nIndents each line with provided _str_ (if _count_ given then _str_ is repeated _count_ times).\n\n#### str.last() _(es5-ext/string/#/last)_\n\nReturn last character\n\n#### str.normalize([form]) _(es5-ext/string/#/normalize)_\n\n[_Introduced with ECMAScript 6_](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize). \nReturns the Unicode Normalization Form of a given string. \nBased on Matsuza's version. Code used for integrated shim can be found at [github.com/walling/unorm](https://github.com/walling/unorm/blob/master/lib/unorm.js)\n\n#### str.pad(fill[, length]) _(es5-ext/string/#/pad)_\n\nPad string with _fill_.\nIf _length_ si given than _fill_ is reapated _length_ times.\nIf _length_ is negative then pad is applied from right.\n\n#### str.repeat(n) _(es5-ext/string/#/repeat)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.repeat). \nRepeat given string _n_ times\n\n#### str.plainReplace(search, replace) _(es5-ext/string/#/plain-replace)_\n\nSimple `replace` version. Doesn't support regular expressions. Replaces just first occurrence of search string. Doesn't support insert patterns, therefore it is safe to replace text with text obtained programmatically (there's no need for additional _$_ characters escape in such case).\n\n#### str.plainReplaceAll(search, replace) _(es5-ext/string/#/plain-replace-all)_\n\nSimple `replace` version. Doesn't support regular expressions. Replaces all occurrences of search string. Doesn't support insert patterns, therefore it is safe to replace text with text obtained programmatically (there's no need for additional _$_ characters escape in such case).\n\n#### str.startsWith(searchString[, position]) _(es5-ext/string/#/starts-with)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.startswith). \nWhether strings starts with given string\n\n#### str[@@iterator] _(es5-ext/string/#/@@iterator)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype-@@iterator). \nReturns iterator object which traverses all string characters (with respect to unicode symbols)\n\n### Tests\n\n $ npm test\n\n[nix-build-image]: https://semaphoreci.com/api/v1/medikoo-org/es5-ext/branches/master/shields_badge.svg\n[nix-build-url]: https://semaphoreci.com/medikoo-org/es5-ext\n[win-build-image]: https://ci.appveyor.com/api/projects/status/3jox67ksw3p8hkwh?svg=true\n[win-build-url]: https://ci.appveyor.com/project/medikoo/es5-ext\n[transpilation-image]: https://img.shields.io/badge/transpilation-free-brightgreen.svg\n[npm-image]: https://img.shields.io/npm/v/es5-ext.svg\n[npm-url]: https://www.npmjs.com/package/es5-ext\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/medikoo/es5-ext/issues" - }, - "homepage": "https://github.com/medikoo/es5-ext#readme", - "_id": "es5-ext@0.10.45", - "_requested": { - "type": "version", - "registry": true, - "raw": "es5-ext@0.10.45", - "name": "es5-ext", - "escapedName": "es5-ext", - "rawSpec": "0.10.45", - "saveSpec": "[Circular]", - "fetchSpec": "0.10.45" - }, - "_spec": "0.10.45", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "es5-ext@0.10.45", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "optionalDependencies": {}, - "_dependencies": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.1", - "next-tick": "1" - }, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/es5-ext", - "error": "[Circular]", - "extraneous": false, - "_deduped": "es5-ext" - } - }, - "devDependencies": { - "tad": "~0.1.21" - }, - "license": "MIT", - "_resolved": "https://registry.npmjs.org/d/-/d-0.1.1.tgz", - "_integrity": "sha1-2hhMU10Y2O57oqoim5FACfrhEwk=", - "_from": "d@0.1.1", - "readme": "# D - Property descriptor factory\n\n_Originally derived from [es5-ext](https://github.com/medikoo/es5-ext) package._\n\nDefining properties with descriptors is very verbose:\n\n```javascript\nvar Account = function () {};\nObject.defineProperties(Account.prototype, {\n deposit: { value: function () {\n /* ... */\n }, configurable: true, enumerable: false, writable: true },\n whithdraw: { value: function () {\n /* ... */\n }, configurable: true, enumerable: false, writable: true },\n balance: { get: function () {\n /* ... */\n }, configurable: true, enumerable: false }\n});\n```\n\nD cuts that to:\n\n```javascript\nvar d = require('d');\n\nvar Account = function () {};\nObject.defineProperties(Account.prototype, {\n deposit: d(function () {\n /* ... */\n }),\n whithdraw: d(function () {\n /* ... */\n }),\n balance: d.gs(function () {\n /* ... */\n })\n});\n```\n\nBy default, created descriptor follow characteristics of native ES5 properties, and defines values as:\n\n```javascript\n{ configurable: true, enumerable: false, writable: true }\n```\n\nYou can overwrite it by preceding _value_ argument with instruction:\n```javascript\nd('c', value); // { configurable: true, enumerable: false, writable: false }\nd('ce', value); // { configurable: true, enumerable: true, writable: false }\nd('e', value); // { configurable: false, enumerable: true, writable: false }\n\n// Same way for get/set:\nd.gs('e', value); // { configurable: false, enumerable: true }\n```\n\n### Other utilities\n\n#### autoBind(obj, props) _(d/auto-bind)_\n\nDefine methods which will be automatically bound to its instances\n\n```javascript\nvar d = require('d');\nvar autoBind = require('d/auto-bind');\n\nvar Foo = function () { this._count = 0; };\nautoBind(Foo.prototype, {\n increment: d(function () { ++this._count; });\n});\n\nvar foo = new Foo();\n\n// Increment foo counter on each domEl click\ndomEl.addEventListener('click', foo.increment, false);\n```\n\n#### lazy(obj, props) _(d/lazy)_\n\nDefine lazy properties, which will be resolved on first access\n\n```javascript\nvar d = require('d');\nvar lazy = require('d/lazy');\n\nvar Foo = function () {};\nlazy(Foo.prototype, {\n items: d(function () { return []; })\n});\n\nvar foo = new Foo();\nfoo.items.push(1, 2); // foo.items array created\n```\n\n## Installation\n### NPM\n\nIn your project path:\n\n\t$ npm install d\n\n### Browser\n\nYou can easily bundle _D_ for browser with [modules-webmake](https://github.com/medikoo/modules-webmake)\n\n## Tests [![Build Status](https://travis-ci.org/medikoo/d.png)](https://travis-ci.org/medikoo/d)\n\n\t$ npm test\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/medikoo/d/issues" - }, - "homepage": "https://github.com/medikoo/d#readme", - "_id": "d@0.1.1", - "_requested": { - "type": "version", - "registry": true, - "raw": "d@0.1.1", - "name": "d", - "escapedName": "d", - "rawSpec": "0.1.1", - "saveSpec": "[Circular]", - "fetchSpec": "0.1.1" - }, - "_spec": "0.1.1", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "d@0.1.1", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "optionalDependencies": {}, - "_dependencies": { - "es5-ext": "~0.10.2" - }, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/d", - "error": "[Circular]", - "extraneous": false - }, - "es5-ext": { - "name": "es5-ext", - "version": "0.10.45", - "description": "ECMAScript extensions and shims", - "author": "[Circular]", - "keywords": "[Circular]", - "repository": "[Circular]", - "dependencies": { - "es6-iterator": { - "name": "es6-iterator", - "version": "2.0.3", - "description": "Iterator abstraction based on ES6 specification", - "author": { - "name": "Mariusz Nowak", - "email": "medyk@medikoo.com", - "url": "http://www.medikoo.com/" - }, - "keywords": [ - "iterator", - "array", - "list", - "set", - "map", - "generator" - ], - "repository": { - "type": "git", - "url": "git://github.com/medikoo/es6-iterator.git" - }, - "dependencies": { - "es5-ext": { - "name": "es5-ext", - "version": "0.10.45", - "description": "ECMAScript extensions and shims", - "author": "[Circular]", - "keywords": "[Circular]", - "repository": "[Circular]", - "dependencies": {}, - "devDependencies": "[Circular]", - "eslintConfig": "[Circular]", - "scripts": "[Circular]", - "license": "ISC", - "_resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.45.tgz", - "_integrity": "sha512-FkfM6Vxxfmztilbxxz5UKSD4ICMf5tSpRFtDNtkAhOxZ0EKtX6qwmXNyH/sFyIbX2P/nU5AMiA9jilWsUGJzCQ==", - "_from": "es5-ext@0.10.45", - "readme": "[![Build status][nix-build-image]][nix-build-url]\n[![Windows status][win-build-image]][win-build-url]\n![Transpilation status][transpilation-image]\n[![npm version][npm-image]][npm-url]\n\n# es5-ext\n\n## ECMAScript 5 extensions\n\n### (with respect to ECMAScript 6 standard)\n\nShims for upcoming ES6 standard and other goodies implemented strictly with ECMAScript conventions in mind.\n\nIt's designed to be used in compliant ECMAScript 5 or ECMAScript 6 environments. Older environments are not supported, although most of the features should work with correct ECMAScript 5 shim on board.\n\nWhen used in ECMAScript 6 environment, native implementation (if valid) takes precedence over shims.\n\n### Installation\n\n $ npm install es5-ext\n\nTo port it to Browser or any other (non CJS) environment, use your favorite CJS bundler. No favorite yet? Try: [Browserify](http://browserify.org/), [Webmake](https://github.com/medikoo/modules-webmake) or [Webpack](http://webpack.github.io/)\n\n### Usage\n\n#### ECMAScript 6 features\n\nYou can force ES6 features to be implemented in your environment, e.g. following will assign `from` function to `Array` (only if it's not implemented already).\n\n```javascript\nrequire(\"es5-ext/array/from/implement\");\nArray.from(\"foo\"); // ['f', 'o', 'o']\n```\n\nYou can also access shims directly, without fixing native objects. Following will return native `Array.from` if it's available and fallback to shim if it's not.\n\n```javascript\nvar aFrom = require(\"es5-ext/array/from\");\naFrom(\"foo\"); // ['f', 'o', 'o']\n```\n\nIf you want to use shim unconditionally (even if native implementation exists) do:\n\n```javascript\nvar aFrom = require(\"es5-ext/array/from/shim\");\naFrom(\"foo\"); // ['f', 'o', 'o']\n```\n\n##### List of ES6 shims\n\nIt's about properties introduced with ES6 and those that have been updated in new spec.\n\n* `Array.from` -> `require('es5-ext/array/from')`\n* `Array.of` -> `require('es5-ext/array/of')`\n* `Array.prototype.concat` -> `require('es5-ext/array/#/concat')`\n* `Array.prototype.copyWithin` -> `require('es5-ext/array/#/copy-within')`\n* `Array.prototype.entries` -> `require('es5-ext/array/#/entries')`\n* `Array.prototype.fill` -> `require('es5-ext/array/#/fill')`\n* `Array.prototype.filter` -> `require('es5-ext/array/#/filter')`\n* `Array.prototype.find` -> `require('es5-ext/array/#/find')`\n* `Array.prototype.findIndex` -> `require('es5-ext/array/#/find-index')`\n* `Array.prototype.keys` -> `require('es5-ext/array/#/keys')`\n* `Array.prototype.map` -> `require('es5-ext/array/#/map')`\n* `Array.prototype.slice` -> `require('es5-ext/array/#/slice')`\n* `Array.prototype.splice` -> `require('es5-ext/array/#/splice')`\n* `Array.prototype.values` -> `require('es5-ext/array/#/values')`\n* `Array.prototype[@@iterator]` -> `require('es5-ext/array/#/@@iterator')`\n* `Math.acosh` -> `require('es5-ext/math/acosh')`\n* `Math.asinh` -> `require('es5-ext/math/asinh')`\n* `Math.atanh` -> `require('es5-ext/math/atanh')`\n* `Math.cbrt` -> `require('es5-ext/math/cbrt')`\n* `Math.clz32` -> `require('es5-ext/math/clz32')`\n* `Math.cosh` -> `require('es5-ext/math/cosh')`\n* `Math.exmp1` -> `require('es5-ext/math/expm1')`\n* `Math.fround` -> `require('es5-ext/math/fround')`\n* `Math.hypot` -> `require('es5-ext/math/hypot')`\n* `Math.imul` -> `require('es5-ext/math/imul')`\n* `Math.log1p` -> `require('es5-ext/math/log1p')`\n* `Math.log2` -> `require('es5-ext/math/log2')`\n* `Math.log10` -> `require('es5-ext/math/log10')`\n* `Math.sign` -> `require('es5-ext/math/sign')`\n* `Math.signh` -> `require('es5-ext/math/signh')`\n* `Math.tanh` -> `require('es5-ext/math/tanh')`\n* `Math.trunc` -> `require('es5-ext/math/trunc')`\n* `Number.EPSILON` -> `require('es5-ext/number/epsilon')`\n* `Number.MAX_SAFE_INTEGER` -> `require('es5-ext/number/max-safe-integer')`\n* `Number.MIN_SAFE_INTEGER` -> `require('es5-ext/number/min-safe-integer')`\n* `Number.isFinite` -> `require('es5-ext/number/is-finite')`\n* `Number.isInteger` -> `require('es5-ext/number/is-integer')`\n* `Number.isNaN` -> `require('es5-ext/number/is-nan')`\n* `Number.isSafeInteger` -> `require('es5-ext/number/is-safe-integer')`\n* `Object.assign` -> `require('es5-ext/object/assign')`\n* `Object.keys` -> `require('es5-ext/object/keys')`\n* `Object.setPrototypeOf` -> `require('es5-ext/object/set-prototype-of')`\n* `RegExp.prototype.match` -> `require('es5-ext/reg-exp/#/match')`\n* `RegExp.prototype.replace` -> `require('es5-ext/reg-exp/#/replace')`\n* `RegExp.prototype.search` -> `require('es5-ext/reg-exp/#/search')`\n* `RegExp.prototype.split` -> `require('es5-ext/reg-exp/#/split')`\n* `RegExp.prototype.sticky` -> Implement with `require('es5-ext/reg-exp/#/sticky/implement')`, use as function with `require('es5-ext/reg-exp/#/is-sticky')`\n* `RegExp.prototype.unicode` -> Implement with `require('es5-ext/reg-exp/#/unicode/implement')`, use as function with `require('es5-ext/reg-exp/#/is-unicode')`\n* `String.fromCodePoint` -> `require('es5-ext/string/from-code-point')`\n* `String.raw` -> `require('es5-ext/string/raw')`\n* `String.prototype.codePointAt` -> `require('es5-ext/string/#/code-point-at')`\n* `String.prototype.contains` -> `require('es5-ext/string/#/contains')`\n* `String.prototype.endsWith` -> `require('es5-ext/string/#/ends-with')`\n* `String.prototype.normalize` -> `require('es5-ext/string/#/normalize')`\n* `String.prototype.repeat` -> `require('es5-ext/string/#/repeat')`\n* `String.prototype.startsWith` -> `require('es5-ext/string/#/starts-with')`\n* `String.prototype[@@iterator]` -> `require('es5-ext/string/#/@@iterator')`\n\n#### Non ECMAScript standard features\n\n**es5-ext** provides also other utils, and implements them as if they were proposed for a standard. It mostly offers methods (not functions) which can directly be assigned to native prototypes:\n\n```javascript\nObject.defineProperty(Function.prototype, \"partial\", {\n\tvalue: require(\"es5-ext/function/#/partial\"),\n\tconfigurable: true,\n\tenumerable: false,\n\twritable: true\n});\nObject.defineProperty(Array.prototype, \"flatten\", {\n\tvalue: require(\"es5-ext/array/#/flatten\"),\n\tconfigurable: true,\n\tenumerable: false,\n\twritable: true\n});\nObject.defineProperty(String.prototype, \"capitalize\", {\n\tvalue: require(\"es5-ext/string/#/capitalize\"),\n\tconfigurable: true,\n\tenumerable: false,\n\twritable: true\n});\n```\n\nSee [es5-extend](https://github.com/wookieb/es5-extend#es5-extend), a great utility that automatically will extend natives for you.\n\n**Important:** Remember to **not** extend natives in scope of generic reusable packages (e.g. ones you intend to publish to npm). Extending natives is fine **only** if you're the _owner_ of the global scope, so e.g. in final project you lead development of.\n\nWhen you're in situation when native extensions are not good idea, then you should use methods indirectly:\n\n```javascript\nvar flatten = require(\"es5-ext/array/#/flatten\");\n\nflatten.call([1, [2, [3, 4]]]); // [1, 2, 3, 4]\n```\n\nfor better convenience you can turn methods into functions:\n\n```javascript\nvar call = Function.prototype.call;\nvar flatten = call.bind(require(\"es5-ext/array/#/flatten\"));\n\nflatten([1, [2, [3, 4]]]); // [1, 2, 3, 4]\n```\n\nYou can configure custom toolkit (like [underscorejs](http://underscorejs.org/)), and use it throughout your application\n\n```javascript\nvar util = {};\nutil.partial = call.bind(require(\"es5-ext/function/#/partial\"));\nutil.flatten = call.bind(require(\"es5-ext/array/#/flatten\"));\nutil.startsWith = call.bind(require(\"es5-ext/string/#/starts-with\"));\n\nutil.flatten([1, [2, [3, 4]]]); // [1, 2, 3, 4]\n```\n\nAs with native ones most methods are generic and can be run on any type of object.\n\n## API\n\n### Global extensions\n\n#### global _(es5-ext/global)_\n\nObject that represents global scope\n\n### Array Constructor extensions\n\n#### from(arrayLike[, mapFn[, thisArg]]) _(es5-ext/array/from)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.from). \nReturns array representation of _iterable_ or _arrayLike_. If _arrayLike_ is an instance of array, its copy is returned.\n\n#### generate([length[, …fill]]) _(es5-ext/array/generate)_\n\nGenerate an array of pre-given _length_ built of repeated arguments.\n\n#### isPlainArray(x) _(es5-ext/array/is-plain-array)_\n\nReturns true if object is plain array (not instance of one of the Array's extensions).\n\n#### of([…items]) _(es5-ext/array/of)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.of). \nCreate an array from given arguments.\n\n#### toArray(obj) _(es5-ext/array/to-array)_\n\nReturns array representation of `obj`. If `obj` is already an array, `obj` is returned back.\n\n#### validArray(obj) _(es5-ext/array/valid-array)_\n\nReturns `obj` if it's an array, otherwise throws `TypeError`\n\n### Array Prototype extensions\n\n#### arr.binarySearch(compareFn) _(es5-ext/array/#/binary-search)_\n\nIn **sorted** list search for index of item for which _compareFn_ returns value closest to _0_. \nIt's variant of binary search algorithm\n\n#### arr.clear() _(es5-ext/array/#/clear)_\n\nClears the array\n\n#### arr.compact() _(es5-ext/array/#/compact)_\n\nReturns a copy of the context with all non-values (`null` or `undefined`) removed.\n\n#### arr.concat() _(es5-ext/array/#/concat)_\n\n[_Updated with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype.concat). \nES6's version of `concat`. Supports `isConcatSpreadable` symbol, and returns array of same type as the context.\n\n#### arr.contains(searchElement[, position]) _(es5-ext/array/#/contains)_\n\nWhether list contains the given value.\n\n#### arr.copyWithin(target, start[, end]) _(es5-ext/array/#/copy-within)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.copywithin).\n\n#### arr.diff(other) _(es5-ext/array/#/diff)_\n\nReturns the array of elements that are present in context list but not present in other list.\n\n#### arr.eIndexOf(searchElement[, fromIndex]) _(es5-ext/array/#/e-index-of)_\n\n_egal_ version of `indexOf` method. [_SameValueZero_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) logic is used for comparision\n\n#### arr.eLastIndexOf(searchElement[, fromIndex]) _(es5-ext/array/#/e-last-index-of)_\n\n_egal_ version of `lastIndexOf` method. [_SameValueZero_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) logic is used for comparision\n\n#### arr.entries() _(es5-ext/array/#/entries)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype.entries). \nReturns iterator object, which traverses the array. Each value is represented with an array, where first value is an index and second is corresponding to index value.\n\n#### arr.exclusion([…lists]]) _(es5-ext/array/#/exclusion)_\n\nReturns the array of elements that are found only in one of the lists (either context list or list provided in arguments).\n\n#### arr.fill(value[, start, end]) _(es5-ext/array/#/fill)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.fill).\n\n#### arr.filter(callback[, thisArg]) _(es5-ext/array/#/filter)_\n\n[_Updated with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.filter). \nES6's version of `filter`, returns array of same type as the context.\n\n#### arr.find(predicate[, thisArg]) _(es5-ext/array/#/find)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.find). \nReturn first element for which given function returns true\n\n#### arr.findIndex(predicate[, thisArg]) _(es5-ext/array/#/find-index)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.findindex). \nReturn first index for which given function returns true\n\n#### arr.first() _(es5-ext/array/#/first)_\n\nReturns value for first defined index\n\n#### arr.firstIndex() _(es5-ext/array/#/first-index)_\n\nReturns first declared index of the array\n\n#### arr.flatten() _(es5-ext/array/#/flatten)_\n\nReturns flattened version of the array\n\n#### arr.forEachRight(cb[, thisArg]) _(es5-ext/array/#/for-each-right)_\n\n`forEach` starting from last element\n\n#### arr.group(cb[, thisArg]) _(es5-ext/array/#/group)_\n\nGroup list elements by value returned by _cb_ function\n\n#### arr.indexesOf(searchElement[, fromIndex]) _(es5-ext/array/#/indexes-of)_\n\nReturns array of all indexes of given value\n\n#### arr.intersection([…lists]) _(es5-ext/array/#/intersection)_\n\nComputes the array of values that are the intersection of all lists (context list and lists given in arguments)\n\n#### arr.isCopy(other) _(es5-ext/array/#/is-copy)_\n\nReturns true if both context and _other_ lists have same content\n\n#### arr.isUniq() _(es5-ext/array/#/is-uniq)_\n\nReturns true if all values in array are unique\n\n#### arr.keys() _(es5-ext/array/#/keys)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype.keys). \nReturns iterator object, which traverses all array indexes.\n\n#### arr.last() _(es5-ext/array/#/last)_\n\nReturns value of last defined index\n\n#### arr.lastIndex() _(es5-ext/array/#/last)_\n\nReturns last defined index of the array\n\n#### arr.map(callback[, thisArg]) _(es5-ext/array/#/map)_\n\n[_Updated with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.map). \nES6's version of `map`, returns array of same type as the context.\n\n#### arr.remove(value[, …valuen]) _(es5-ext/array/#/remove)_\n\nRemove values from the array\n\n#### arr.separate(sep) _(es5-ext/array/#/separate)_\n\nReturns array with items separated with `sep` value\n\n#### arr.slice(callback[, thisArg]) _(es5-ext/array/#/slice)_\n\n[_Updated with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.slice). \nES6's version of `slice`, returns array of same type as the context.\n\n#### arr.someRight(cb[, thisArg]) _(es5-ext/array/#/someRight)_\n\n`some` starting from last element\n\n#### arr.splice(callback[, thisArg]) _(es5-ext/array/#/splice)_\n\n[_Updated with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.splice). \nES6's version of `splice`, returns array of same type as the context.\n\n#### arr.uniq() _(es5-ext/array/#/uniq)_\n\nReturns duplicate-free version of the array\n\n#### arr.values() _(es5-ext/array/#/values)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype.values). \nReturns iterator object which traverses all array values.\n\n#### arr[@@iterator] _(es5-ext/array/#/@@iterator)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype-@@iterator). \nReturns iterator object which traverses all array values.\n\n### Boolean Constructor extensions\n\n#### isBoolean(x) _(es5-ext/boolean/is-boolean)_\n\nWhether value is boolean\n\n### Date Constructor extensions\n\n#### isDate(x) _(es5-ext/date/is-date)_\n\nWhether value is date instance\n\n#### validDate(x) _(es5-ext/date/valid-date)_\n\nIf given object is not date throw TypeError in other case return it.\n\n### Date Prototype extensions\n\n#### date.copy(date) _(es5-ext/date/#/copy)_\n\nReturns a copy of the date object\n\n#### date.daysInMonth() _(es5-ext/date/#/days-in-month)_\n\nReturns number of days of date's month\n\n#### date.floorDay() _(es5-ext/date/#/floor-day)_\n\nSets the date time to 00:00:00.000\n\n#### date.floorMonth() _(es5-ext/date/#/floor-month)_\n\nSets date day to 1 and date time to 00:00:00.000\n\n#### date.floorYear() _(es5-ext/date/#/floor-year)_\n\nSets date month to 0, day to 1 and date time to 00:00:00.000\n\n#### date.format(pattern) _(es5-ext/date/#/format)_\n\nFormats date up to given string. Supported patterns:\n\n* `%Y` - Year with century, 1999, 2003\n* `%y` - Year without century, 99, 03\n* `%m` - Month, 01..12\n* `%d` - Day of the month 01..31\n* `%H` - Hour (24-hour clock), 00..23\n* `%M` - Minute, 00..59\n* `%S` - Second, 00..59\n* `%L` - Milliseconds, 000..999\n\n### Error Constructor extensions\n\n#### custom(message/_, code, ext_/) _(es5-ext/error/custom)_\n\nCreates custom error object, optinally extended with `code` and other extension properties (provided with `ext` object)\n\n#### isError(x) _(es5-ext/error/is-error)_\n\nWhether value is an error (instance of `Error`).\n\n#### validError(x) _(es5-ext/error/valid-error)_\n\nIf given object is not error throw TypeError in other case return it.\n\n### Error Prototype extensions\n\n#### err.throw() _(es5-ext/error/#/throw)_\n\nThrows error\n\n### Function Constructor extensions\n\nSome of the functions were inspired by [Functional JavaScript](http://osteele.com/sources/javascript/functional/) project by Olivier Steele\n\n#### constant(x) _(es5-ext/function/constant)_\n\nReturns a constant function that returns pregiven argument\n\n_k(x)(y) =def x_\n\n#### identity(x) _(es5-ext/function/identity)_\n\nIdentity function. Returns first argument\n\n_i(x) =def x_\n\n#### invoke(name[, …args]) _(es5-ext/function/invoke)_\n\nReturns a function that takes an object as an argument, and applies object's\n_name_ method to arguments. \n_name_ can be name of the method or method itself.\n\n_invoke(name, …args)(object, …args2) =def object\\[name\\]\\(…args, …args2\\)_\n\n#### isArguments(x) _(es5-ext/function/is-arguments)_\n\nWhether value is arguments object\n\n#### isFunction(arg) _(es5-ext/function/is-function)_\n\nWhether value is instance of function\n\n#### noop() _(es5-ext/function/noop)_\n\nNo operation function\n\n#### pluck(name) _(es5-ext/function/pluck)_\n\nReturns a function that takes an object, and returns the value of its _name_\nproperty\n\n_pluck(name)(obj) =def obj[name]_\n\n#### validFunction(arg) _(es5-ext/function/valid-function)_\n\nIf given object is not function throw TypeError in other case return it.\n\n### Function Prototype extensions\n\nSome of the methods were inspired by [Functional JavaScript](http://osteele.com/sources/javascript/functional/) project by Olivier Steele\n\n#### fn.compose([…fns]) _(es5-ext/function/#/compose)_\n\nApplies the functions in reverse argument-list order.\n\n_f1.compose(f2, f3, f4)(…args) =def f1(f2(f3(f4(…arg))))_\n\n#### fn.copy() _(es5-ext/function/#/copy)_\n\nProduces copy of given function\n\n#### fn.curry([n]) _(es5-ext/function/#/curry)_\n\nInvoking the function returned by this function only _n_ arguments are passed to the underlying function. If the underlying function is not saturated, the result is a function that passes all its arguments to the underlying function. \nIf _n_ is not provided then it defaults to context function length\n\n_f.curry(4)(arg1, arg2)(arg3)(arg4) =def f(arg1, args2, arg3, arg4)_\n\n#### fn.lock([…args]) _(es5-ext/function/#/lock)_\n\nReturns a function that applies the underlying function to _args_, and ignores its own arguments.\n\n_f.lock(…args)(…args2) =def f(…args)_\n\n_Named after it's counterpart in Google Closure_\n\n#### fn.not() _(es5-ext/function/#/not)_\n\nReturns a function that returns boolean negation of value returned by underlying function.\n\n_f.not()(…args) =def !f(…args)_\n\n#### fn.partial([…args]) _(es5-ext/function/#/partial)_\n\nReturns a function that when called will behave like context function called with initially passed arguments. If more arguments are suplilied, they are appended to initial args.\n\n_f.partial(…args1)(…args2) =def f(…args1, …args2)_\n\n#### fn.spread() _(es5-ext/function/#/spread)_\n\nReturns a function that applies underlying function with first list argument\n\n_f.match()(args) =def f.apply(null, args)_\n\n#### fn.toStringTokens() _(es5-ext/function/#/to-string-tokens)_\n\nSerializes function into two (arguments and body) string tokens. Result is plain object with `args` and `body` properties.\n\n### Math extensions\n\n#### acosh(x) _(es5-ext/math/acosh)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.acosh).\n\n#### asinh(x) _(es5-ext/math/asinh)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.asinh).\n\n#### atanh(x) _(es5-ext/math/atanh)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.atanh).\n\n#### cbrt(x) _(es5-ext/math/cbrt)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.cbrt).\n\n#### clz32(x) _(es5-ext/math/clz32)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.clz32).\n\n#### cosh(x) _(es5-ext/math/cosh)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.cosh).\n\n#### expm1(x) _(es5-ext/math/expm1)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.expm1).\n\n#### fround(x) _(es5-ext/math/fround)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.fround).\n\n#### hypot([…values]) _(es5-ext/math/hypot)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.hypot).\n\n#### imul(x, y) _(es5-ext/math/imul)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.imul).\n\n#### log1p(x) _(es5-ext/math/log1p)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.log1p).\n\n#### log2(x) _(es5-ext/math/log2)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.log2).\n\n#### log10(x) _(es5-ext/math/log10)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.log10).\n\n#### sign(x) _(es5-ext/math/sign)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.sign).\n\n#### sinh(x) _(es5-ext/math/sinh)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.sinh).\n\n#### tanh(x) _(es5-ext/math/tanh)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.tanh).\n\n#### trunc(x) _(es5-ext/math/trunc)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.trunc).\n\n### Number Constructor extensions\n\n#### EPSILON _(es5-ext/number/epsilon)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.epsilon).\n\nThe difference between 1 and the smallest value greater than 1 that is representable as a Number value, which is approximately 2.2204460492503130808472633361816 x 10-16.\n\n#### isFinite(x) _(es5-ext/number/is-finite)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.isfinite). \nWhether value is finite. Differs from global isNaN that it doesn't do type coercion.\n\n#### isInteger(x) _(es5-ext/number/is-integer)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.isinteger). \nWhether value is integer.\n\n#### isNaN(x) _(es5-ext/number/is-nan)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.isnan). \nWhether value is NaN. Differs from global isNaN that it doesn't do type coercion.\n\n#### isNumber(x) _(es5-ext/number/is-number)_\n\nWhether given value is number\n\n#### isSafeInteger(x) _(es5-ext/number/is-safe-integer)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.issafeinteger).\n\n#### MAX*SAFE_INTEGER *(es5-ext/number/max-safe-integer)\\_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.maxsafeinteger). \nThe value of Number.MAX_SAFE_INTEGER is 9007199254740991.\n\n#### MIN*SAFE_INTEGER *(es5-ext/number/min-safe-integer)\\_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.minsafeinteger). \nThe value of Number.MIN_SAFE_INTEGER is -9007199254740991 (253-1).\n\n#### toInteger(x) _(es5-ext/number/to-integer)_\n\nConverts value to integer\n\n#### toPosInteger(x) _(es5-ext/number/to-pos-integer)_\n\nConverts value to positive integer. If provided value is less than 0, then 0 is returned\n\n#### toUint32(x) _(es5-ext/number/to-uint32)_\n\nConverts value to unsigned 32 bit integer. This type is used for array lengths.\nSee: http://www.2ality.com/2012/02/js-integers.html\n\n### Number Prototype extensions\n\n#### num.pad(length[, precision]) _(es5-ext/number/#/pad)_\n\nPad given number with zeros. Returns string\n\n### Object Constructor extensions\n\n#### assign(target, source[, …sourcen]) _(es5-ext/object/assign)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign). \nExtend _target_ by enumerable own properties of other objects. If properties are already set on target object, they will be overwritten.\n\n#### clear(obj) _(es5-ext/object/clear)_\n\nRemove all enumerable own properties of the object\n\n#### compact(obj) _(es5-ext/object/compact)_\n\nReturns copy of the object with all enumerable properties that have no falsy values\n\n#### compare(obj1, obj2) _(es5-ext/object/compare)_\n\nUniversal cross-type compare function. To be used for e.g. array sort.\n\n#### copy(obj) _(es5-ext/object/copy)_\n\nReturns copy of the object with all enumerable properties.\n\n#### copyDeep(obj) _(es5-ext/object/copy-deep)_\n\nReturns deep copy of the object with all enumerable properties.\n\n#### count(obj) _(es5-ext/object/count)_\n\nCounts number of enumerable own properties on object\n\n#### create(obj[, properties]) _(es5-ext/object/create)_\n\n`Object.create` alternative that provides workaround for [V8 issue](http://code.google.com/p/v8/issues/detail?id=2804).\n\nWhen `null` is provided as a prototype, it's substituted with specially prepared object that derives from Object.prototype but has all Object.prototype properties shadowed with undefined.\n\nIt's quirky solution that allows us to have plain objects with no truthy properties but with turnable prototype.\n\nUse only for objects that you plan to switch prototypes of and be aware of limitations of this workaround.\n\n#### eq(x, y) _(es5-ext/object/eq)_\n\nWhether two values are equal, using [_SameValueZero_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) algorithm.\n\n#### every(obj, cb[, thisArg[, compareFn]]) _(es5-ext/object/every)_\n\nAnalogous to Array.prototype.every. Returns true if every key-value pair in this object satisfies the provided testing function. \nOptionally _compareFn_ can be provided which assures that keys are tested in given order. If provided _compareFn_ is equal to `true`, then order is alphabetical (by key).\n\n#### filter(obj, cb[, thisArg]) _(es5-ext/object/filter)_\n\nAnalogous to Array.prototype.filter. Returns new object with properites for which _cb_ function returned truthy value.\n\n#### firstKey(obj) _(es5-ext/object/first-key)_\n\nReturns first enumerable key of the object, as keys are unordered by specification, it can be any key of an object.\n\n#### flatten(obj) _(es5-ext/object/flatten)_\n\nReturns new object, with flatten properties of input object\n\n_flatten({ a: { b: 1 }, c: { d: 1 } }) =def { b: 1, d: 1 }_\n\n#### forEach(obj, cb[, thisArg[, compareFn]]) _(es5-ext/object/for-each)_\n\nAnalogous to Array.prototype.forEach. Calls a function for each key-value pair found in object\nOptionally _compareFn_ can be provided which assures that properties are iterated in given order. If provided _compareFn_ is equal to `true`, then order is alphabetical (by key).\n\n#### getPropertyNames() _(es5-ext/object/get-property-names)_\n\nGet all (not just own) property names of the object\n\n#### is(x, y) _(es5-ext/object/is)_\n\nWhether two values are equal, using [_SameValue_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) algorithm.\n\n#### isArrayLike(x) _(es5-ext/object/is-array-like)_\n\nWhether object is array-like object\n\n#### isCopy(x, y) _(es5-ext/object/is-copy)_\n\nTwo values are considered a copy of same value when all of their own enumerable properties have same values.\n\n#### isCopyDeep(x, y) _(es5-ext/object/is-copy-deep)_\n\nDeep comparision of objects\n\n#### isEmpty(obj) _(es5-ext/object/is-empty)_\n\nTrue if object doesn't have any own enumerable property\n\n#### isObject(arg) _(es5-ext/object/is-object)_\n\nWhether value is not primitive\n\n#### isPlainObject(arg) _(es5-ext/object/is-plain-object)_\n\nWhether object is plain object, its protototype should be Object.prototype and it cannot be host object.\n\n#### keyOf(obj, searchValue) _(es5-ext/object/key-of)_\n\nSearch object for value\n\n#### keys(obj) _(es5-ext/object/keys)_\n\n[_Updated with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.keys). \nES6's version of `keys`, doesn't throw on primitive input\n\n#### map(obj, cb[, thisArg]) _(es5-ext/object/map)_\n\nAnalogous to Array.prototype.map. Creates a new object with properties which values are results of calling a provided function on every key-value pair in this object.\n\n#### mapKeys(obj, cb[, thisArg]) _(es5-ext/object/map-keys)_\n\nCreate new object with same values, but remapped keys\n\n#### mixin(target, source) _(es5-ext/object/mixin)_\n\nExtend _target_ by all own properties of other objects. Properties found in both objects will be overwritten (unless they're not configurable and cannot be overwritten).\n_It was for a moment part of ECMAScript 6 draft._\n\n#### mixinPrototypes(target, …source]) _(es5-ext/object/mixin-prototypes)_\n\nExtends _target_, with all source and source's prototype properties.\nUseful as an alternative for `setPrototypeOf` in environments in which it cannot be shimmed (no `__proto__` support).\n\n#### normalizeOptions(options) _(es5-ext/object/normalize-options)_\n\nNormalizes options object into flat plain object.\n\nUseful for functions in which we either need to keep options object for future reference or need to modify it for internal use.\n\n* It never returns input `options` object back (always a copy is created)\n* `options` can be undefined in such case empty plain object is returned.\n* Copies all enumerable properties found down prototype chain.\n\n#### primitiveSet([…names]) _(es5-ext/object/primitive-set)_\n\nCreates `null` prototype based plain object, and sets on it all property names provided in arguments to true.\n\n#### safeTraverse(obj[, …names]) _(es5-ext/object/safe-traverse)_\n\nSafe navigation of object properties. See http://wiki.ecmascript.org/doku.php?id=strawman:existential_operator\n\n#### serialize(value) _(es5-ext/object/serialize)_\n\nSerialize value into string. Differs from [JSON.stringify](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) that it serializes also dates, functions and regular expresssions.\n\n#### setPrototypeOf(object, proto) _(es5-ext/object/set-prototype-of)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.setprototypeof). \nIf native version is not provided, it depends on existence of `__proto__` functionality, if it's missing, `null` instead of function is exposed.\n\n#### some(obj, cb[, thisArg[, compareFn]]) _(es5-ext/object/some)_\n\nAnalogous to Array.prototype.some Returns true if any key-value pair satisfies the provided\ntesting function. \nOptionally _compareFn_ can be provided which assures that keys are tested in given order. If provided _compareFn_ is equal to `true`, then order is alphabetical (by key).\n\n#### toArray(obj[, cb[, thisArg[, compareFn]]]) _(es5-ext/object/to-array)_\n\nCreates an array of results of calling a provided function on every key-value pair in this object. \nOptionally _compareFn_ can be provided which assures that results are added in given order. If provided _compareFn_ is equal to `true`, then order is alphabetical (by key).\n\n#### unserialize(str) _(es5-ext/object/unserialize)_\n\nUserializes value previously serialized with [serialize](#serializevalue-es5-extobjectserialize)\n\n#### validCallable(x) _(es5-ext/object/valid-callable)_\n\nIf given object is not callable throw TypeError in other case return it.\n\n#### validObject(x) _(es5-ext/object/valid-object)_\n\nThrows error if given value is not an object, otherwise it is returned.\n\n#### validValue(x) _(es5-ext/object/valid-value)_\n\nThrows error if given value is `null` or `undefined`, otherwise returns value.\n\n### RegExp Constructor extensions\n\n#### escape(str) _(es5-ext/reg-exp/escape)_\n\nEscapes string to be used in regular expression\n\n#### isRegExp(x) _(es5-ext/reg-exp/is-reg-exp)_\n\nWhether object is regular expression\n\n#### validRegExp(x) _(es5-ext/reg-exp/valid-reg-exp)_\n\nIf object is regular expression it is returned, otherwise TypeError is thrown.\n\n### RegExp Prototype extensions\n\n#### re.isSticky(x) _(es5-ext/reg-exp/#/is-sticky)_\n\nWhether regular expression has `sticky` flag.\n\nIt's to be used as counterpart to [regExp.sticky](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-get-regexp.prototype.sticky) if it's not implemented.\n\n#### re.isUnicode(x) _(es5-ext/reg-exp/#/is-unicode)_\n\nWhether regular expression has `unicode` flag.\n\nIt's to be used as counterpart to [regExp.unicode](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-get-regexp.prototype.unicode) if it's not implemented.\n\n#### re.match(string) _(es5-ext/reg-exp/#/match)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.match).\n\n#### re.replace(string, replaceValue) _(es5-ext/reg-exp/#/replace)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.replace).\n\n#### re.search(string) _(es5-ext/reg-exp/#/search)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.search).\n\n#### re.split(string) _(es5-ext/reg-exp/#/search)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.split).\n\n#### re.sticky _(es5-ext/reg-exp/#/sticky/implement)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.sticky). \nIt's a getter, so only `implement` and `is-implemented` modules are provided.\n\n#### re.unicode _(es5-ext/reg-exp/#/unicode/implement)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.unicode). \nIt's a getter, so only `implement` and `is-implemented` modules are provided.\n\n### String Constructor extensions\n\n#### formatMethod(fMap) _(es5-ext/string/format-method)_\n\nCreates format method. It's used e.g. to create `Date.prototype.format` method\n\n#### fromCodePoint([…codePoints]) _(es5-ext/string/from-code-point)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.fromcodepoint)\n\n#### isString(x) _(es5-ext/string/is-string)_\n\nWhether object is string\n\n#### randomUniq() _(es5-ext/string/random-uniq)_\n\nReturns randomly generated id, with guarantee of local uniqueness (no same id will be returned twice)\n\n#### raw(callSite[, …substitutions]) _(es5-ext/string/raw)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.raw)\n\n### String Prototype extensions\n\n#### str.at(pos) _(es5-ext/string/#/at)_\n\n_Proposed for ECMAScript 6/7 standard, but not (yet) in a draft_\n\nReturns a string at given position in Unicode-safe manner.\nBased on [implementation by Mathias Bynens](https://github.com/mathiasbynens/String.prototype.at).\n\n#### str.camelToHyphen() _(es5-ext/string/#/camel-to-hyphen)_\n\nConvert camelCase string to hyphen separated, e.g. one-two-three -> oneTwoThree.\nUseful when converting names from js property convention into filename convention.\n\n#### str.capitalize() _(es5-ext/string/#/capitalize)_\n\nCapitalize first character of a string\n\n#### str.caseInsensitiveCompare(str) _(es5-ext/string/#/case-insensitive-compare)_\n\nCase insensitive compare\n\n#### str.codePointAt(pos) _(es5-ext/string/#/code-point-at)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.codepointat)\n\nBased on [implementation by Mathias Bynens](https://github.com/mathiasbynens/String.prototype.codePointAt).\n\n#### str.contains(searchString[, position]) _(es5-ext/string/#/contains)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.contains)\n\nWhether string contains given string.\n\n#### str.endsWith(searchString[, endPosition]) _(es5-ext/string/#/ends-with)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.endswith). \nWhether strings ends with given string\n\n#### str.hyphenToCamel() _(es5-ext/string/#/hyphen-to-camel)_\n\nConvert hyphen separated string to camelCase, e.g. one-two-three -> oneTwoThree.\nUseful when converting names from filename convention to js property name convention.\n\n#### str.indent(str[, count]) _(es5-ext/string/#/indent)_\n\nIndents each line with provided _str_ (if _count_ given then _str_ is repeated _count_ times).\n\n#### str.last() _(es5-ext/string/#/last)_\n\nReturn last character\n\n#### str.normalize([form]) _(es5-ext/string/#/normalize)_\n\n[_Introduced with ECMAScript 6_](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize). \nReturns the Unicode Normalization Form of a given string. \nBased on Matsuza's version. Code used for integrated shim can be found at [github.com/walling/unorm](https://github.com/walling/unorm/blob/master/lib/unorm.js)\n\n#### str.pad(fill[, length]) _(es5-ext/string/#/pad)_\n\nPad string with _fill_.\nIf _length_ si given than _fill_ is reapated _length_ times.\nIf _length_ is negative then pad is applied from right.\n\n#### str.repeat(n) _(es5-ext/string/#/repeat)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.repeat). \nRepeat given string _n_ times\n\n#### str.plainReplace(search, replace) _(es5-ext/string/#/plain-replace)_\n\nSimple `replace` version. Doesn't support regular expressions. Replaces just first occurrence of search string. Doesn't support insert patterns, therefore it is safe to replace text with text obtained programmatically (there's no need for additional _$_ characters escape in such case).\n\n#### str.plainReplaceAll(search, replace) _(es5-ext/string/#/plain-replace-all)_\n\nSimple `replace` version. Doesn't support regular expressions. Replaces all occurrences of search string. Doesn't support insert patterns, therefore it is safe to replace text with text obtained programmatically (there's no need for additional _$_ characters escape in such case).\n\n#### str.startsWith(searchString[, position]) _(es5-ext/string/#/starts-with)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.startswith). \nWhether strings starts with given string\n\n#### str[@@iterator] _(es5-ext/string/#/@@iterator)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype-@@iterator). \nReturns iterator object which traverses all string characters (with respect to unicode symbols)\n\n### Tests\n\n $ npm test\n\n[nix-build-image]: https://semaphoreci.com/api/v1/medikoo-org/es5-ext/branches/master/shields_badge.svg\n[nix-build-url]: https://semaphoreci.com/medikoo-org/es5-ext\n[win-build-image]: https://ci.appveyor.com/api/projects/status/3jox67ksw3p8hkwh?svg=true\n[win-build-url]: https://ci.appveyor.com/project/medikoo/es5-ext\n[transpilation-image]: https://img.shields.io/badge/transpilation-free-brightgreen.svg\n[npm-image]: https://img.shields.io/npm/v/es5-ext.svg\n[npm-url]: https://www.npmjs.com/package/es5-ext\n", - "readmeFilename": "README.md", - "bugs": "[Circular]", - "homepage": "https://github.com/medikoo/es5-ext#readme", - "_id": "es5-ext@0.10.45", - "_requested": { - "type": "version", - "registry": true, - "raw": "es5-ext@0.10.45", - "name": "es5-ext", - "escapedName": "es5-ext", - "rawSpec": "0.10.45", - "saveSpec": "[Circular]", - "fetchSpec": "0.10.45" - }, - "_spec": "0.10.45", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": "[Circular]", - "optionalDependencies": "[Circular]", - "_dependencies": "[Circular]", - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/es5-ext", - "error": "[Circular]", - "extraneous": false, - "_deduped": "es5-ext" - }, - "d": { - "name": "d", - "version": "1.0.0", - "description": "Property descriptor factory", - "author": { - "name": "Mariusz Nowak", - "email": "medyk@medikoo.com", - "url": "http://www.medikoo.com/" - }, - "keywords": [ - "descriptor", - "es", - "ecmascript", - "ecma", - "property", - "descriptors", - "meta", - "properties" - ], - "repository": { - "type": "git", - "url": "git://github.com/medikoo/d.git" - }, - "dependencies": { - "es5-ext": { - "name": "es5-ext", - "version": "0.10.45", - "description": "ECMAScript extensions and shims", - "author": "[Circular]", - "keywords": "[Circular]", - "repository": "[Circular]", - "dependencies": {}, - "devDependencies": "[Circular]", - "eslintConfig": "[Circular]", - "scripts": "[Circular]", - "license": "ISC", - "_resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.45.tgz", - "_integrity": "sha512-FkfM6Vxxfmztilbxxz5UKSD4ICMf5tSpRFtDNtkAhOxZ0EKtX6qwmXNyH/sFyIbX2P/nU5AMiA9jilWsUGJzCQ==", - "_from": "es5-ext@0.10.45", - "readme": "[![Build status][nix-build-image]][nix-build-url]\n[![Windows status][win-build-image]][win-build-url]\n![Transpilation status][transpilation-image]\n[![npm version][npm-image]][npm-url]\n\n# es5-ext\n\n## ECMAScript 5 extensions\n\n### (with respect to ECMAScript 6 standard)\n\nShims for upcoming ES6 standard and other goodies implemented strictly with ECMAScript conventions in mind.\n\nIt's designed to be used in compliant ECMAScript 5 or ECMAScript 6 environments. Older environments are not supported, although most of the features should work with correct ECMAScript 5 shim on board.\n\nWhen used in ECMAScript 6 environment, native implementation (if valid) takes precedence over shims.\n\n### Installation\n\n $ npm install es5-ext\n\nTo port it to Browser or any other (non CJS) environment, use your favorite CJS bundler. No favorite yet? Try: [Browserify](http://browserify.org/), [Webmake](https://github.com/medikoo/modules-webmake) or [Webpack](http://webpack.github.io/)\n\n### Usage\n\n#### ECMAScript 6 features\n\nYou can force ES6 features to be implemented in your environment, e.g. following will assign `from` function to `Array` (only if it's not implemented already).\n\n```javascript\nrequire(\"es5-ext/array/from/implement\");\nArray.from(\"foo\"); // ['f', 'o', 'o']\n```\n\nYou can also access shims directly, without fixing native objects. Following will return native `Array.from` if it's available and fallback to shim if it's not.\n\n```javascript\nvar aFrom = require(\"es5-ext/array/from\");\naFrom(\"foo\"); // ['f', 'o', 'o']\n```\n\nIf you want to use shim unconditionally (even if native implementation exists) do:\n\n```javascript\nvar aFrom = require(\"es5-ext/array/from/shim\");\naFrom(\"foo\"); // ['f', 'o', 'o']\n```\n\n##### List of ES6 shims\n\nIt's about properties introduced with ES6 and those that have been updated in new spec.\n\n* `Array.from` -> `require('es5-ext/array/from')`\n* `Array.of` -> `require('es5-ext/array/of')`\n* `Array.prototype.concat` -> `require('es5-ext/array/#/concat')`\n* `Array.prototype.copyWithin` -> `require('es5-ext/array/#/copy-within')`\n* `Array.prototype.entries` -> `require('es5-ext/array/#/entries')`\n* `Array.prototype.fill` -> `require('es5-ext/array/#/fill')`\n* `Array.prototype.filter` -> `require('es5-ext/array/#/filter')`\n* `Array.prototype.find` -> `require('es5-ext/array/#/find')`\n* `Array.prototype.findIndex` -> `require('es5-ext/array/#/find-index')`\n* `Array.prototype.keys` -> `require('es5-ext/array/#/keys')`\n* `Array.prototype.map` -> `require('es5-ext/array/#/map')`\n* `Array.prototype.slice` -> `require('es5-ext/array/#/slice')`\n* `Array.prototype.splice` -> `require('es5-ext/array/#/splice')`\n* `Array.prototype.values` -> `require('es5-ext/array/#/values')`\n* `Array.prototype[@@iterator]` -> `require('es5-ext/array/#/@@iterator')`\n* `Math.acosh` -> `require('es5-ext/math/acosh')`\n* `Math.asinh` -> `require('es5-ext/math/asinh')`\n* `Math.atanh` -> `require('es5-ext/math/atanh')`\n* `Math.cbrt` -> `require('es5-ext/math/cbrt')`\n* `Math.clz32` -> `require('es5-ext/math/clz32')`\n* `Math.cosh` -> `require('es5-ext/math/cosh')`\n* `Math.exmp1` -> `require('es5-ext/math/expm1')`\n* `Math.fround` -> `require('es5-ext/math/fround')`\n* `Math.hypot` -> `require('es5-ext/math/hypot')`\n* `Math.imul` -> `require('es5-ext/math/imul')`\n* `Math.log1p` -> `require('es5-ext/math/log1p')`\n* `Math.log2` -> `require('es5-ext/math/log2')`\n* `Math.log10` -> `require('es5-ext/math/log10')`\n* `Math.sign` -> `require('es5-ext/math/sign')`\n* `Math.signh` -> `require('es5-ext/math/signh')`\n* `Math.tanh` -> `require('es5-ext/math/tanh')`\n* `Math.trunc` -> `require('es5-ext/math/trunc')`\n* `Number.EPSILON` -> `require('es5-ext/number/epsilon')`\n* `Number.MAX_SAFE_INTEGER` -> `require('es5-ext/number/max-safe-integer')`\n* `Number.MIN_SAFE_INTEGER` -> `require('es5-ext/number/min-safe-integer')`\n* `Number.isFinite` -> `require('es5-ext/number/is-finite')`\n* `Number.isInteger` -> `require('es5-ext/number/is-integer')`\n* `Number.isNaN` -> `require('es5-ext/number/is-nan')`\n* `Number.isSafeInteger` -> `require('es5-ext/number/is-safe-integer')`\n* `Object.assign` -> `require('es5-ext/object/assign')`\n* `Object.keys` -> `require('es5-ext/object/keys')`\n* `Object.setPrototypeOf` -> `require('es5-ext/object/set-prototype-of')`\n* `RegExp.prototype.match` -> `require('es5-ext/reg-exp/#/match')`\n* `RegExp.prototype.replace` -> `require('es5-ext/reg-exp/#/replace')`\n* `RegExp.prototype.search` -> `require('es5-ext/reg-exp/#/search')`\n* `RegExp.prototype.split` -> `require('es5-ext/reg-exp/#/split')`\n* `RegExp.prototype.sticky` -> Implement with `require('es5-ext/reg-exp/#/sticky/implement')`, use as function with `require('es5-ext/reg-exp/#/is-sticky')`\n* `RegExp.prototype.unicode` -> Implement with `require('es5-ext/reg-exp/#/unicode/implement')`, use as function with `require('es5-ext/reg-exp/#/is-unicode')`\n* `String.fromCodePoint` -> `require('es5-ext/string/from-code-point')`\n* `String.raw` -> `require('es5-ext/string/raw')`\n* `String.prototype.codePointAt` -> `require('es5-ext/string/#/code-point-at')`\n* `String.prototype.contains` -> `require('es5-ext/string/#/contains')`\n* `String.prototype.endsWith` -> `require('es5-ext/string/#/ends-with')`\n* `String.prototype.normalize` -> `require('es5-ext/string/#/normalize')`\n* `String.prototype.repeat` -> `require('es5-ext/string/#/repeat')`\n* `String.prototype.startsWith` -> `require('es5-ext/string/#/starts-with')`\n* `String.prototype[@@iterator]` -> `require('es5-ext/string/#/@@iterator')`\n\n#### Non ECMAScript standard features\n\n**es5-ext** provides also other utils, and implements them as if they were proposed for a standard. It mostly offers methods (not functions) which can directly be assigned to native prototypes:\n\n```javascript\nObject.defineProperty(Function.prototype, \"partial\", {\n\tvalue: require(\"es5-ext/function/#/partial\"),\n\tconfigurable: true,\n\tenumerable: false,\n\twritable: true\n});\nObject.defineProperty(Array.prototype, \"flatten\", {\n\tvalue: require(\"es5-ext/array/#/flatten\"),\n\tconfigurable: true,\n\tenumerable: false,\n\twritable: true\n});\nObject.defineProperty(String.prototype, \"capitalize\", {\n\tvalue: require(\"es5-ext/string/#/capitalize\"),\n\tconfigurable: true,\n\tenumerable: false,\n\twritable: true\n});\n```\n\nSee [es5-extend](https://github.com/wookieb/es5-extend#es5-extend), a great utility that automatically will extend natives for you.\n\n**Important:** Remember to **not** extend natives in scope of generic reusable packages (e.g. ones you intend to publish to npm). Extending natives is fine **only** if you're the _owner_ of the global scope, so e.g. in final project you lead development of.\n\nWhen you're in situation when native extensions are not good idea, then you should use methods indirectly:\n\n```javascript\nvar flatten = require(\"es5-ext/array/#/flatten\");\n\nflatten.call([1, [2, [3, 4]]]); // [1, 2, 3, 4]\n```\n\nfor better convenience you can turn methods into functions:\n\n```javascript\nvar call = Function.prototype.call;\nvar flatten = call.bind(require(\"es5-ext/array/#/flatten\"));\n\nflatten([1, [2, [3, 4]]]); // [1, 2, 3, 4]\n```\n\nYou can configure custom toolkit (like [underscorejs](http://underscorejs.org/)), and use it throughout your application\n\n```javascript\nvar util = {};\nutil.partial = call.bind(require(\"es5-ext/function/#/partial\"));\nutil.flatten = call.bind(require(\"es5-ext/array/#/flatten\"));\nutil.startsWith = call.bind(require(\"es5-ext/string/#/starts-with\"));\n\nutil.flatten([1, [2, [3, 4]]]); // [1, 2, 3, 4]\n```\n\nAs with native ones most methods are generic and can be run on any type of object.\n\n## API\n\n### Global extensions\n\n#### global _(es5-ext/global)_\n\nObject that represents global scope\n\n### Array Constructor extensions\n\n#### from(arrayLike[, mapFn[, thisArg]]) _(es5-ext/array/from)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.from). \nReturns array representation of _iterable_ or _arrayLike_. If _arrayLike_ is an instance of array, its copy is returned.\n\n#### generate([length[, …fill]]) _(es5-ext/array/generate)_\n\nGenerate an array of pre-given _length_ built of repeated arguments.\n\n#### isPlainArray(x) _(es5-ext/array/is-plain-array)_\n\nReturns true if object is plain array (not instance of one of the Array's extensions).\n\n#### of([…items]) _(es5-ext/array/of)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.of). \nCreate an array from given arguments.\n\n#### toArray(obj) _(es5-ext/array/to-array)_\n\nReturns array representation of `obj`. If `obj` is already an array, `obj` is returned back.\n\n#### validArray(obj) _(es5-ext/array/valid-array)_\n\nReturns `obj` if it's an array, otherwise throws `TypeError`\n\n### Array Prototype extensions\n\n#### arr.binarySearch(compareFn) _(es5-ext/array/#/binary-search)_\n\nIn **sorted** list search for index of item for which _compareFn_ returns value closest to _0_. \nIt's variant of binary search algorithm\n\n#### arr.clear() _(es5-ext/array/#/clear)_\n\nClears the array\n\n#### arr.compact() _(es5-ext/array/#/compact)_\n\nReturns a copy of the context with all non-values (`null` or `undefined`) removed.\n\n#### arr.concat() _(es5-ext/array/#/concat)_\n\n[_Updated with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype.concat). \nES6's version of `concat`. Supports `isConcatSpreadable` symbol, and returns array of same type as the context.\n\n#### arr.contains(searchElement[, position]) _(es5-ext/array/#/contains)_\n\nWhether list contains the given value.\n\n#### arr.copyWithin(target, start[, end]) _(es5-ext/array/#/copy-within)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.copywithin).\n\n#### arr.diff(other) _(es5-ext/array/#/diff)_\n\nReturns the array of elements that are present in context list but not present in other list.\n\n#### arr.eIndexOf(searchElement[, fromIndex]) _(es5-ext/array/#/e-index-of)_\n\n_egal_ version of `indexOf` method. [_SameValueZero_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) logic is used for comparision\n\n#### arr.eLastIndexOf(searchElement[, fromIndex]) _(es5-ext/array/#/e-last-index-of)_\n\n_egal_ version of `lastIndexOf` method. [_SameValueZero_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) logic is used for comparision\n\n#### arr.entries() _(es5-ext/array/#/entries)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype.entries). \nReturns iterator object, which traverses the array. Each value is represented with an array, where first value is an index and second is corresponding to index value.\n\n#### arr.exclusion([…lists]]) _(es5-ext/array/#/exclusion)_\n\nReturns the array of elements that are found only in one of the lists (either context list or list provided in arguments).\n\n#### arr.fill(value[, start, end]) _(es5-ext/array/#/fill)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.fill).\n\n#### arr.filter(callback[, thisArg]) _(es5-ext/array/#/filter)_\n\n[_Updated with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.filter). \nES6's version of `filter`, returns array of same type as the context.\n\n#### arr.find(predicate[, thisArg]) _(es5-ext/array/#/find)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.find). \nReturn first element for which given function returns true\n\n#### arr.findIndex(predicate[, thisArg]) _(es5-ext/array/#/find-index)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.findindex). \nReturn first index for which given function returns true\n\n#### arr.first() _(es5-ext/array/#/first)_\n\nReturns value for first defined index\n\n#### arr.firstIndex() _(es5-ext/array/#/first-index)_\n\nReturns first declared index of the array\n\n#### arr.flatten() _(es5-ext/array/#/flatten)_\n\nReturns flattened version of the array\n\n#### arr.forEachRight(cb[, thisArg]) _(es5-ext/array/#/for-each-right)_\n\n`forEach` starting from last element\n\n#### arr.group(cb[, thisArg]) _(es5-ext/array/#/group)_\n\nGroup list elements by value returned by _cb_ function\n\n#### arr.indexesOf(searchElement[, fromIndex]) _(es5-ext/array/#/indexes-of)_\n\nReturns array of all indexes of given value\n\n#### arr.intersection([…lists]) _(es5-ext/array/#/intersection)_\n\nComputes the array of values that are the intersection of all lists (context list and lists given in arguments)\n\n#### arr.isCopy(other) _(es5-ext/array/#/is-copy)_\n\nReturns true if both context and _other_ lists have same content\n\n#### arr.isUniq() _(es5-ext/array/#/is-uniq)_\n\nReturns true if all values in array are unique\n\n#### arr.keys() _(es5-ext/array/#/keys)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype.keys). \nReturns iterator object, which traverses all array indexes.\n\n#### arr.last() _(es5-ext/array/#/last)_\n\nReturns value of last defined index\n\n#### arr.lastIndex() _(es5-ext/array/#/last)_\n\nReturns last defined index of the array\n\n#### arr.map(callback[, thisArg]) _(es5-ext/array/#/map)_\n\n[_Updated with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.map). \nES6's version of `map`, returns array of same type as the context.\n\n#### arr.remove(value[, …valuen]) _(es5-ext/array/#/remove)_\n\nRemove values from the array\n\n#### arr.separate(sep) _(es5-ext/array/#/separate)_\n\nReturns array with items separated with `sep` value\n\n#### arr.slice(callback[, thisArg]) _(es5-ext/array/#/slice)_\n\n[_Updated with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.slice). \nES6's version of `slice`, returns array of same type as the context.\n\n#### arr.someRight(cb[, thisArg]) _(es5-ext/array/#/someRight)_\n\n`some` starting from last element\n\n#### arr.splice(callback[, thisArg]) _(es5-ext/array/#/splice)_\n\n[_Updated with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.splice). \nES6's version of `splice`, returns array of same type as the context.\n\n#### arr.uniq() _(es5-ext/array/#/uniq)_\n\nReturns duplicate-free version of the array\n\n#### arr.values() _(es5-ext/array/#/values)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype.values). \nReturns iterator object which traverses all array values.\n\n#### arr[@@iterator] _(es5-ext/array/#/@@iterator)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype-@@iterator). \nReturns iterator object which traverses all array values.\n\n### Boolean Constructor extensions\n\n#### isBoolean(x) _(es5-ext/boolean/is-boolean)_\n\nWhether value is boolean\n\n### Date Constructor extensions\n\n#### isDate(x) _(es5-ext/date/is-date)_\n\nWhether value is date instance\n\n#### validDate(x) _(es5-ext/date/valid-date)_\n\nIf given object is not date throw TypeError in other case return it.\n\n### Date Prototype extensions\n\n#### date.copy(date) _(es5-ext/date/#/copy)_\n\nReturns a copy of the date object\n\n#### date.daysInMonth() _(es5-ext/date/#/days-in-month)_\n\nReturns number of days of date's month\n\n#### date.floorDay() _(es5-ext/date/#/floor-day)_\n\nSets the date time to 00:00:00.000\n\n#### date.floorMonth() _(es5-ext/date/#/floor-month)_\n\nSets date day to 1 and date time to 00:00:00.000\n\n#### date.floorYear() _(es5-ext/date/#/floor-year)_\n\nSets date month to 0, day to 1 and date time to 00:00:00.000\n\n#### date.format(pattern) _(es5-ext/date/#/format)_\n\nFormats date up to given string. Supported patterns:\n\n* `%Y` - Year with century, 1999, 2003\n* `%y` - Year without century, 99, 03\n* `%m` - Month, 01..12\n* `%d` - Day of the month 01..31\n* `%H` - Hour (24-hour clock), 00..23\n* `%M` - Minute, 00..59\n* `%S` - Second, 00..59\n* `%L` - Milliseconds, 000..999\n\n### Error Constructor extensions\n\n#### custom(message/_, code, ext_/) _(es5-ext/error/custom)_\n\nCreates custom error object, optinally extended with `code` and other extension properties (provided with `ext` object)\n\n#### isError(x) _(es5-ext/error/is-error)_\n\nWhether value is an error (instance of `Error`).\n\n#### validError(x) _(es5-ext/error/valid-error)_\n\nIf given object is not error throw TypeError in other case return it.\n\n### Error Prototype extensions\n\n#### err.throw() _(es5-ext/error/#/throw)_\n\nThrows error\n\n### Function Constructor extensions\n\nSome of the functions were inspired by [Functional JavaScript](http://osteele.com/sources/javascript/functional/) project by Olivier Steele\n\n#### constant(x) _(es5-ext/function/constant)_\n\nReturns a constant function that returns pregiven argument\n\n_k(x)(y) =def x_\n\n#### identity(x) _(es5-ext/function/identity)_\n\nIdentity function. Returns first argument\n\n_i(x) =def x_\n\n#### invoke(name[, …args]) _(es5-ext/function/invoke)_\n\nReturns a function that takes an object as an argument, and applies object's\n_name_ method to arguments. \n_name_ can be name of the method or method itself.\n\n_invoke(name, …args)(object, …args2) =def object\\[name\\]\\(…args, …args2\\)_\n\n#### isArguments(x) _(es5-ext/function/is-arguments)_\n\nWhether value is arguments object\n\n#### isFunction(arg) _(es5-ext/function/is-function)_\n\nWhether value is instance of function\n\n#### noop() _(es5-ext/function/noop)_\n\nNo operation function\n\n#### pluck(name) _(es5-ext/function/pluck)_\n\nReturns a function that takes an object, and returns the value of its _name_\nproperty\n\n_pluck(name)(obj) =def obj[name]_\n\n#### validFunction(arg) _(es5-ext/function/valid-function)_\n\nIf given object is not function throw TypeError in other case return it.\n\n### Function Prototype extensions\n\nSome of the methods were inspired by [Functional JavaScript](http://osteele.com/sources/javascript/functional/) project by Olivier Steele\n\n#### fn.compose([…fns]) _(es5-ext/function/#/compose)_\n\nApplies the functions in reverse argument-list order.\n\n_f1.compose(f2, f3, f4)(…args) =def f1(f2(f3(f4(…arg))))_\n\n#### fn.copy() _(es5-ext/function/#/copy)_\n\nProduces copy of given function\n\n#### fn.curry([n]) _(es5-ext/function/#/curry)_\n\nInvoking the function returned by this function only _n_ arguments are passed to the underlying function. If the underlying function is not saturated, the result is a function that passes all its arguments to the underlying function. \nIf _n_ is not provided then it defaults to context function length\n\n_f.curry(4)(arg1, arg2)(arg3)(arg4) =def f(arg1, args2, arg3, arg4)_\n\n#### fn.lock([…args]) _(es5-ext/function/#/lock)_\n\nReturns a function that applies the underlying function to _args_, and ignores its own arguments.\n\n_f.lock(…args)(…args2) =def f(…args)_\n\n_Named after it's counterpart in Google Closure_\n\n#### fn.not() _(es5-ext/function/#/not)_\n\nReturns a function that returns boolean negation of value returned by underlying function.\n\n_f.not()(…args) =def !f(…args)_\n\n#### fn.partial([…args]) _(es5-ext/function/#/partial)_\n\nReturns a function that when called will behave like context function called with initially passed arguments. If more arguments are suplilied, they are appended to initial args.\n\n_f.partial(…args1)(…args2) =def f(…args1, …args2)_\n\n#### fn.spread() _(es5-ext/function/#/spread)_\n\nReturns a function that applies underlying function with first list argument\n\n_f.match()(args) =def f.apply(null, args)_\n\n#### fn.toStringTokens() _(es5-ext/function/#/to-string-tokens)_\n\nSerializes function into two (arguments and body) string tokens. Result is plain object with `args` and `body` properties.\n\n### Math extensions\n\n#### acosh(x) _(es5-ext/math/acosh)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.acosh).\n\n#### asinh(x) _(es5-ext/math/asinh)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.asinh).\n\n#### atanh(x) _(es5-ext/math/atanh)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.atanh).\n\n#### cbrt(x) _(es5-ext/math/cbrt)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.cbrt).\n\n#### clz32(x) _(es5-ext/math/clz32)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.clz32).\n\n#### cosh(x) _(es5-ext/math/cosh)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.cosh).\n\n#### expm1(x) _(es5-ext/math/expm1)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.expm1).\n\n#### fround(x) _(es5-ext/math/fround)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.fround).\n\n#### hypot([…values]) _(es5-ext/math/hypot)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.hypot).\n\n#### imul(x, y) _(es5-ext/math/imul)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.imul).\n\n#### log1p(x) _(es5-ext/math/log1p)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.log1p).\n\n#### log2(x) _(es5-ext/math/log2)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.log2).\n\n#### log10(x) _(es5-ext/math/log10)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.log10).\n\n#### sign(x) _(es5-ext/math/sign)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.sign).\n\n#### sinh(x) _(es5-ext/math/sinh)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.sinh).\n\n#### tanh(x) _(es5-ext/math/tanh)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.tanh).\n\n#### trunc(x) _(es5-ext/math/trunc)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.trunc).\n\n### Number Constructor extensions\n\n#### EPSILON _(es5-ext/number/epsilon)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.epsilon).\n\nThe difference between 1 and the smallest value greater than 1 that is representable as a Number value, which is approximately 2.2204460492503130808472633361816 x 10-16.\n\n#### isFinite(x) _(es5-ext/number/is-finite)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.isfinite). \nWhether value is finite. Differs from global isNaN that it doesn't do type coercion.\n\n#### isInteger(x) _(es5-ext/number/is-integer)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.isinteger). \nWhether value is integer.\n\n#### isNaN(x) _(es5-ext/number/is-nan)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.isnan). \nWhether value is NaN. Differs from global isNaN that it doesn't do type coercion.\n\n#### isNumber(x) _(es5-ext/number/is-number)_\n\nWhether given value is number\n\n#### isSafeInteger(x) _(es5-ext/number/is-safe-integer)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.issafeinteger).\n\n#### MAX*SAFE_INTEGER *(es5-ext/number/max-safe-integer)\\_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.maxsafeinteger). \nThe value of Number.MAX_SAFE_INTEGER is 9007199254740991.\n\n#### MIN*SAFE_INTEGER *(es5-ext/number/min-safe-integer)\\_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.minsafeinteger). \nThe value of Number.MIN_SAFE_INTEGER is -9007199254740991 (253-1).\n\n#### toInteger(x) _(es5-ext/number/to-integer)_\n\nConverts value to integer\n\n#### toPosInteger(x) _(es5-ext/number/to-pos-integer)_\n\nConverts value to positive integer. If provided value is less than 0, then 0 is returned\n\n#### toUint32(x) _(es5-ext/number/to-uint32)_\n\nConverts value to unsigned 32 bit integer. This type is used for array lengths.\nSee: http://www.2ality.com/2012/02/js-integers.html\n\n### Number Prototype extensions\n\n#### num.pad(length[, precision]) _(es5-ext/number/#/pad)_\n\nPad given number with zeros. Returns string\n\n### Object Constructor extensions\n\n#### assign(target, source[, …sourcen]) _(es5-ext/object/assign)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign). \nExtend _target_ by enumerable own properties of other objects. If properties are already set on target object, they will be overwritten.\n\n#### clear(obj) _(es5-ext/object/clear)_\n\nRemove all enumerable own properties of the object\n\n#### compact(obj) _(es5-ext/object/compact)_\n\nReturns copy of the object with all enumerable properties that have no falsy values\n\n#### compare(obj1, obj2) _(es5-ext/object/compare)_\n\nUniversal cross-type compare function. To be used for e.g. array sort.\n\n#### copy(obj) _(es5-ext/object/copy)_\n\nReturns copy of the object with all enumerable properties.\n\n#### copyDeep(obj) _(es5-ext/object/copy-deep)_\n\nReturns deep copy of the object with all enumerable properties.\n\n#### count(obj) _(es5-ext/object/count)_\n\nCounts number of enumerable own properties on object\n\n#### create(obj[, properties]) _(es5-ext/object/create)_\n\n`Object.create` alternative that provides workaround for [V8 issue](http://code.google.com/p/v8/issues/detail?id=2804).\n\nWhen `null` is provided as a prototype, it's substituted with specially prepared object that derives from Object.prototype but has all Object.prototype properties shadowed with undefined.\n\nIt's quirky solution that allows us to have plain objects with no truthy properties but with turnable prototype.\n\nUse only for objects that you plan to switch prototypes of and be aware of limitations of this workaround.\n\n#### eq(x, y) _(es5-ext/object/eq)_\n\nWhether two values are equal, using [_SameValueZero_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) algorithm.\n\n#### every(obj, cb[, thisArg[, compareFn]]) _(es5-ext/object/every)_\n\nAnalogous to Array.prototype.every. Returns true if every key-value pair in this object satisfies the provided testing function. \nOptionally _compareFn_ can be provided which assures that keys are tested in given order. If provided _compareFn_ is equal to `true`, then order is alphabetical (by key).\n\n#### filter(obj, cb[, thisArg]) _(es5-ext/object/filter)_\n\nAnalogous to Array.prototype.filter. Returns new object with properites for which _cb_ function returned truthy value.\n\n#### firstKey(obj) _(es5-ext/object/first-key)_\n\nReturns first enumerable key of the object, as keys are unordered by specification, it can be any key of an object.\n\n#### flatten(obj) _(es5-ext/object/flatten)_\n\nReturns new object, with flatten properties of input object\n\n_flatten({ a: { b: 1 }, c: { d: 1 } }) =def { b: 1, d: 1 }_\n\n#### forEach(obj, cb[, thisArg[, compareFn]]) _(es5-ext/object/for-each)_\n\nAnalogous to Array.prototype.forEach. Calls a function for each key-value pair found in object\nOptionally _compareFn_ can be provided which assures that properties are iterated in given order. If provided _compareFn_ is equal to `true`, then order is alphabetical (by key).\n\n#### getPropertyNames() _(es5-ext/object/get-property-names)_\n\nGet all (not just own) property names of the object\n\n#### is(x, y) _(es5-ext/object/is)_\n\nWhether two values are equal, using [_SameValue_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) algorithm.\n\n#### isArrayLike(x) _(es5-ext/object/is-array-like)_\n\nWhether object is array-like object\n\n#### isCopy(x, y) _(es5-ext/object/is-copy)_\n\nTwo values are considered a copy of same value when all of their own enumerable properties have same values.\n\n#### isCopyDeep(x, y) _(es5-ext/object/is-copy-deep)_\n\nDeep comparision of objects\n\n#### isEmpty(obj) _(es5-ext/object/is-empty)_\n\nTrue if object doesn't have any own enumerable property\n\n#### isObject(arg) _(es5-ext/object/is-object)_\n\nWhether value is not primitive\n\n#### isPlainObject(arg) _(es5-ext/object/is-plain-object)_\n\nWhether object is plain object, its protototype should be Object.prototype and it cannot be host object.\n\n#### keyOf(obj, searchValue) _(es5-ext/object/key-of)_\n\nSearch object for value\n\n#### keys(obj) _(es5-ext/object/keys)_\n\n[_Updated with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.keys). \nES6's version of `keys`, doesn't throw on primitive input\n\n#### map(obj, cb[, thisArg]) _(es5-ext/object/map)_\n\nAnalogous to Array.prototype.map. Creates a new object with properties which values are results of calling a provided function on every key-value pair in this object.\n\n#### mapKeys(obj, cb[, thisArg]) _(es5-ext/object/map-keys)_\n\nCreate new object with same values, but remapped keys\n\n#### mixin(target, source) _(es5-ext/object/mixin)_\n\nExtend _target_ by all own properties of other objects. Properties found in both objects will be overwritten (unless they're not configurable and cannot be overwritten).\n_It was for a moment part of ECMAScript 6 draft._\n\n#### mixinPrototypes(target, …source]) _(es5-ext/object/mixin-prototypes)_\n\nExtends _target_, with all source and source's prototype properties.\nUseful as an alternative for `setPrototypeOf` in environments in which it cannot be shimmed (no `__proto__` support).\n\n#### normalizeOptions(options) _(es5-ext/object/normalize-options)_\n\nNormalizes options object into flat plain object.\n\nUseful for functions in which we either need to keep options object for future reference or need to modify it for internal use.\n\n* It never returns input `options` object back (always a copy is created)\n* `options` can be undefined in such case empty plain object is returned.\n* Copies all enumerable properties found down prototype chain.\n\n#### primitiveSet([…names]) _(es5-ext/object/primitive-set)_\n\nCreates `null` prototype based plain object, and sets on it all property names provided in arguments to true.\n\n#### safeTraverse(obj[, …names]) _(es5-ext/object/safe-traverse)_\n\nSafe navigation of object properties. See http://wiki.ecmascript.org/doku.php?id=strawman:existential_operator\n\n#### serialize(value) _(es5-ext/object/serialize)_\n\nSerialize value into string. Differs from [JSON.stringify](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) that it serializes also dates, functions and regular expresssions.\n\n#### setPrototypeOf(object, proto) _(es5-ext/object/set-prototype-of)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.setprototypeof). \nIf native version is not provided, it depends on existence of `__proto__` functionality, if it's missing, `null` instead of function is exposed.\n\n#### some(obj, cb[, thisArg[, compareFn]]) _(es5-ext/object/some)_\n\nAnalogous to Array.prototype.some Returns true if any key-value pair satisfies the provided\ntesting function. \nOptionally _compareFn_ can be provided which assures that keys are tested in given order. If provided _compareFn_ is equal to `true`, then order is alphabetical (by key).\n\n#### toArray(obj[, cb[, thisArg[, compareFn]]]) _(es5-ext/object/to-array)_\n\nCreates an array of results of calling a provided function on every key-value pair in this object. \nOptionally _compareFn_ can be provided which assures that results are added in given order. If provided _compareFn_ is equal to `true`, then order is alphabetical (by key).\n\n#### unserialize(str) _(es5-ext/object/unserialize)_\n\nUserializes value previously serialized with [serialize](#serializevalue-es5-extobjectserialize)\n\n#### validCallable(x) _(es5-ext/object/valid-callable)_\n\nIf given object is not callable throw TypeError in other case return it.\n\n#### validObject(x) _(es5-ext/object/valid-object)_\n\nThrows error if given value is not an object, otherwise it is returned.\n\n#### validValue(x) _(es5-ext/object/valid-value)_\n\nThrows error if given value is `null` or `undefined`, otherwise returns value.\n\n### RegExp Constructor extensions\n\n#### escape(str) _(es5-ext/reg-exp/escape)_\n\nEscapes string to be used in regular expression\n\n#### isRegExp(x) _(es5-ext/reg-exp/is-reg-exp)_\n\nWhether object is regular expression\n\n#### validRegExp(x) _(es5-ext/reg-exp/valid-reg-exp)_\n\nIf object is regular expression it is returned, otherwise TypeError is thrown.\n\n### RegExp Prototype extensions\n\n#### re.isSticky(x) _(es5-ext/reg-exp/#/is-sticky)_\n\nWhether regular expression has `sticky` flag.\n\nIt's to be used as counterpart to [regExp.sticky](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-get-regexp.prototype.sticky) if it's not implemented.\n\n#### re.isUnicode(x) _(es5-ext/reg-exp/#/is-unicode)_\n\nWhether regular expression has `unicode` flag.\n\nIt's to be used as counterpart to [regExp.unicode](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-get-regexp.prototype.unicode) if it's not implemented.\n\n#### re.match(string) _(es5-ext/reg-exp/#/match)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.match).\n\n#### re.replace(string, replaceValue) _(es5-ext/reg-exp/#/replace)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.replace).\n\n#### re.search(string) _(es5-ext/reg-exp/#/search)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.search).\n\n#### re.split(string) _(es5-ext/reg-exp/#/search)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.split).\n\n#### re.sticky _(es5-ext/reg-exp/#/sticky/implement)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.sticky). \nIt's a getter, so only `implement` and `is-implemented` modules are provided.\n\n#### re.unicode _(es5-ext/reg-exp/#/unicode/implement)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.unicode). \nIt's a getter, so only `implement` and `is-implemented` modules are provided.\n\n### String Constructor extensions\n\n#### formatMethod(fMap) _(es5-ext/string/format-method)_\n\nCreates format method. It's used e.g. to create `Date.prototype.format` method\n\n#### fromCodePoint([…codePoints]) _(es5-ext/string/from-code-point)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.fromcodepoint)\n\n#### isString(x) _(es5-ext/string/is-string)_\n\nWhether object is string\n\n#### randomUniq() _(es5-ext/string/random-uniq)_\n\nReturns randomly generated id, with guarantee of local uniqueness (no same id will be returned twice)\n\n#### raw(callSite[, …substitutions]) _(es5-ext/string/raw)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.raw)\n\n### String Prototype extensions\n\n#### str.at(pos) _(es5-ext/string/#/at)_\n\n_Proposed for ECMAScript 6/7 standard, but not (yet) in a draft_\n\nReturns a string at given position in Unicode-safe manner.\nBased on [implementation by Mathias Bynens](https://github.com/mathiasbynens/String.prototype.at).\n\n#### str.camelToHyphen() _(es5-ext/string/#/camel-to-hyphen)_\n\nConvert camelCase string to hyphen separated, e.g. one-two-three -> oneTwoThree.\nUseful when converting names from js property convention into filename convention.\n\n#### str.capitalize() _(es5-ext/string/#/capitalize)_\n\nCapitalize first character of a string\n\n#### str.caseInsensitiveCompare(str) _(es5-ext/string/#/case-insensitive-compare)_\n\nCase insensitive compare\n\n#### str.codePointAt(pos) _(es5-ext/string/#/code-point-at)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.codepointat)\n\nBased on [implementation by Mathias Bynens](https://github.com/mathiasbynens/String.prototype.codePointAt).\n\n#### str.contains(searchString[, position]) _(es5-ext/string/#/contains)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.contains)\n\nWhether string contains given string.\n\n#### str.endsWith(searchString[, endPosition]) _(es5-ext/string/#/ends-with)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.endswith). \nWhether strings ends with given string\n\n#### str.hyphenToCamel() _(es5-ext/string/#/hyphen-to-camel)_\n\nConvert hyphen separated string to camelCase, e.g. one-two-three -> oneTwoThree.\nUseful when converting names from filename convention to js property name convention.\n\n#### str.indent(str[, count]) _(es5-ext/string/#/indent)_\n\nIndents each line with provided _str_ (if _count_ given then _str_ is repeated _count_ times).\n\n#### str.last() _(es5-ext/string/#/last)_\n\nReturn last character\n\n#### str.normalize([form]) _(es5-ext/string/#/normalize)_\n\n[_Introduced with ECMAScript 6_](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize). \nReturns the Unicode Normalization Form of a given string. \nBased on Matsuza's version. Code used for integrated shim can be found at [github.com/walling/unorm](https://github.com/walling/unorm/blob/master/lib/unorm.js)\n\n#### str.pad(fill[, length]) _(es5-ext/string/#/pad)_\n\nPad string with _fill_.\nIf _length_ si given than _fill_ is reapated _length_ times.\nIf _length_ is negative then pad is applied from right.\n\n#### str.repeat(n) _(es5-ext/string/#/repeat)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.repeat). \nRepeat given string _n_ times\n\n#### str.plainReplace(search, replace) _(es5-ext/string/#/plain-replace)_\n\nSimple `replace` version. Doesn't support regular expressions. Replaces just first occurrence of search string. Doesn't support insert patterns, therefore it is safe to replace text with text obtained programmatically (there's no need for additional _$_ characters escape in such case).\n\n#### str.plainReplaceAll(search, replace) _(es5-ext/string/#/plain-replace-all)_\n\nSimple `replace` version. Doesn't support regular expressions. Replaces all occurrences of search string. Doesn't support insert patterns, therefore it is safe to replace text with text obtained programmatically (there's no need for additional _$_ characters escape in such case).\n\n#### str.startsWith(searchString[, position]) _(es5-ext/string/#/starts-with)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.startswith). \nWhether strings starts with given string\n\n#### str[@@iterator] _(es5-ext/string/#/@@iterator)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype-@@iterator). \nReturns iterator object which traverses all string characters (with respect to unicode symbols)\n\n### Tests\n\n $ npm test\n\n[nix-build-image]: https://semaphoreci.com/api/v1/medikoo-org/es5-ext/branches/master/shields_badge.svg\n[nix-build-url]: https://semaphoreci.com/medikoo-org/es5-ext\n[win-build-image]: https://ci.appveyor.com/api/projects/status/3jox67ksw3p8hkwh?svg=true\n[win-build-url]: https://ci.appveyor.com/project/medikoo/es5-ext\n[transpilation-image]: https://img.shields.io/badge/transpilation-free-brightgreen.svg\n[npm-image]: https://img.shields.io/npm/v/es5-ext.svg\n[npm-url]: https://www.npmjs.com/package/es5-ext\n", - "readmeFilename": "README.md", - "bugs": "[Circular]", - "homepage": "https://github.com/medikoo/es5-ext#readme", - "_id": "es5-ext@0.10.45", - "_requested": { - "type": "version", - "registry": true, - "raw": "es5-ext@0.10.45", - "name": "es5-ext", - "escapedName": "es5-ext", - "rawSpec": "0.10.45", - "saveSpec": "[Circular]", - "fetchSpec": "0.10.45" - }, - "_spec": "0.10.45", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": "[Circular]", - "optionalDependencies": "[Circular]", - "_dependencies": "[Circular]", - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/es5-ext", - "error": "[Circular]", - "extraneous": false, - "_deduped": "es5-ext" - } - }, - "devDependencies": { - "tad": "^0.2.4", - "xlint": "^0.2.2", - "xlint-jslint-medikoo": "^0.1.4" - }, - "scripts": { - "lint": "node node_modules/xlint/bin/xlint --linter=node_modules/xlint-jslint-medikoo/index.js --no-cache --no-stream", - "lint-console": "node node_modules/xlint/bin/xlint --linter=node_modules/xlint-jslint-medikoo/index.js --watch", - "test": "node node_modules/tad/bin/tad" - }, - "license": "MIT", - "_resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", - "_integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", - "_from": "d@1.0.0", - "readme": "# D\n## Property descriptor factory\n\n_Originally derived from [es5-ext](https://github.com/medikoo/es5-ext) package._\n\nDefining properties with descriptors is very verbose:\n\n```javascript\nvar Account = function () {};\nObject.defineProperties(Account.prototype, {\n deposit: { value: function () {\n /* ... */\n }, configurable: true, enumerable: false, writable: true },\n withdraw: { value: function () {\n /* ... */\n }, configurable: true, enumerable: false, writable: true },\n balance: { get: function () {\n /* ... */\n }, configurable: true, enumerable: false }\n});\n```\n\nD cuts that to:\n\n```javascript\nvar d = require('d');\n\nvar Account = function () {};\nObject.defineProperties(Account.prototype, {\n deposit: d(function () {\n /* ... */\n }),\n withdraw: d(function () {\n /* ... */\n }),\n balance: d.gs(function () {\n /* ... */\n })\n});\n```\n\nBy default, created descriptor follow characteristics of native ES5 properties, and defines values as:\n\n```javascript\n{ configurable: true, enumerable: false, writable: true }\n```\n\nYou can overwrite it by preceding _value_ argument with instruction:\n```javascript\nd('c', value); // { configurable: true, enumerable: false, writable: false }\nd('ce', value); // { configurable: true, enumerable: true, writable: false }\nd('e', value); // { configurable: false, enumerable: true, writable: false }\n\n// Same way for get/set:\nd.gs('e', value); // { configurable: false, enumerable: true }\n```\n\n### Installation\n\n\t$ npm install d\n\t\nTo port it to Browser or any other (non CJS) environment, use your favorite CJS bundler. No favorite yet? Try: [Browserify](http://browserify.org/), [Webmake](https://github.com/medikoo/modules-webmake) or [Webpack](http://webpack.github.io/)\n\n### Other utilities\n\n#### autoBind(obj, props) _(d/auto-bind)_\n\nDefine methods which will be automatically bound to its instances\n\n```javascript\nvar d = require('d');\nvar autoBind = require('d/auto-bind');\n\nvar Foo = function () { this._count = 0; };\nObject.defineProperties(Foo.prototype, autoBind({\n increment: d(function () { ++this._count; });\n}));\n\nvar foo = new Foo();\n\n// Increment foo counter on each domEl click\ndomEl.addEventListener('click', foo.increment, false);\n```\n\n#### lazy(obj, props) _(d/lazy)_\n\nDefine lazy properties, which will be resolved on first access\n\n```javascript\nvar d = require('d');\nvar lazy = require('d/lazy');\n\nvar Foo = function () {};\nObject.defineProperties(Foo.prototype, lazy({\n items: d(function () { return []; })\n}));\n\nvar foo = new Foo();\nfoo.items.push(1, 2); // foo.items array created and defined directly on foo\n```\n\n## Tests [![Build Status](https://travis-ci.org/medikoo/d.png)](https://travis-ci.org/medikoo/d)\n\n\t$ npm test\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/medikoo/d/issues" - }, - "homepage": "https://github.com/medikoo/d#readme", - "_id": "d@1.0.0", - "_requested": { - "type": "version", - "registry": true, - "raw": "d@1.0.0", - "name": "d", - "escapedName": "d", - "rawSpec": "1.0.0", - "saveSpec": "[Circular]", - "fetchSpec": "1.0.0" - }, - "_spec": "1.0.0", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "d@1.0.0", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "optionalDependencies": {}, - "_dependencies": { - "es5-ext": "^0.10.9" - }, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/es6-iterator/node_modules/d", - "error": "[Circular]", - "extraneous": false - }, - "es6-symbol": { - "name": "es6-symbol", - "version": "3.1.1", - "description": "ECMAScript 6 Symbol polyfill", - "author": { - "name": "Mariusz Nowak", - "email": "medyk@medikoo.com", - "url": "http://www.medikoo.com/" - }, - "keywords": [ - "symbol", - "private", - "property", - "es6", - "ecmascript", - "harmony", - "ponyfill", - "polyfill" - ], - "repository": { - "type": "git", - "url": "git://github.com/medikoo/es6-symbol.git" - }, - "dependencies": {}, - "devDependencies": { - "tad": "~0.2.7", - "xlint": "~0.2.2", - "xlint-jslint-medikoo": "~0.1.4" - }, - "scripts": { - "lint": "node node_modules/xlint/bin/xlint --linter=node_modules/xlint-jslint-medikoo/index.js --no-cache --no-stream", - "lint-console": "node node_modules/xlint/bin/xlint --linter=node_modules/xlint-jslint-medikoo/index.js --watch", - "test": "node ./node_modules/tad/bin/tad" - }, - "license": "MIT", - "_resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", - "_integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", - "_from": "es6-symbol@3.1.1", - "readme": "# es6-symbol\n## ECMAScript 6 Symbol polyfill\n\nFor more information about symbols see following links\n- [Symbols in ECMAScript 6 by Axel Rauschmayer](http://www.2ality.com/2014/12/es6-symbols.html)\n- [MDN Documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol)\n- [Specification](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-symbol-constructor)\n\n### Limitations\n\nUnderneath it uses real string property names which can easily be retrieved, however accidental collision with other property names is unlikely.\n\n### Usage\n\nIf you'd like to use native version when it exists and fallback to [ponyfill](https://ponyfill.com) if it doesn't, use *es6-symbol* as following:\n\n```javascript\nvar Symbol = require('es6-symbol');\n```\n\nIf you want to make sure your environment implements `Symbol` globally, do:\n\n```javascript\nrequire('es6-symbol/implement');\n```\n\nIf you strictly want to use polyfill even if native `Symbol` exists (hard to find a good reason for that), do:\n\n```javascript\nvar Symbol = require('es6-symbol/polyfill');\n```\n\n#### API\n\nBest is to refer to [specification](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-symbol-objects). Still if you want quick look, follow examples:\n\n```javascript\nvar Symbol = require('es6-symbol');\n\nvar symbol = Symbol('My custom symbol');\nvar x = {};\n\nx[symbol] = 'foo';\nconsole.log(x[symbol]); 'foo'\n\n// Detect iterable:\nvar iterator, result;\nif (possiblyIterable[Symbol.iterator]) {\n iterator = possiblyIterable[Symbol.iterator]();\n result = iterator.next();\n while(!result.done) {\n console.log(result.value);\n result = iterator.next();\n }\n}\n```\n\n### Installation\n#### NPM\n\nIn your project path:\n\n\t$ npm install es6-symbol\n\n##### Browser\n\nTo port it to Browser or any other (non CJS) environment, use your favorite CJS bundler. No favorite yet? Try: [Browserify](http://browserify.org/), [Webmake](https://github.com/medikoo/modules-webmake) or [Webpack](http://webpack.github.io/)\n\n## Tests [![Build Status](https://travis-ci.org/medikoo/es6-symbol.png)](https://travis-ci.org/medikoo/es6-symbol)\n\n\t$ npm test\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/medikoo/es6-symbol/issues" - }, - "homepage": "https://github.com/medikoo/es6-symbol#readme", - "_id": "es6-symbol@3.1.1", - "_requested": { - "type": "version", - "registry": true, - "raw": "es6-symbol@3.1.1", - "name": "es6-symbol", - "escapedName": "es6-symbol", - "rawSpec": "3.1.1", - "saveSpec": "[Circular]", - "fetchSpec": "3.1.1" - }, - "_spec": "3.1.1", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "es6-symbol@3.1.1", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "optionalDependencies": {}, - "_dependencies": { - "d": "1", - "es5-ext": "~0.10.14" - }, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/es6-symbol", - "error": "[Circular]", - "extraneous": false, - "_deduped": "es6-symbol" - } - }, - "devDependencies": { - "eslint": "^4.9", - "eslint-config-medikoo-es5": "^1.4.4", - "event-emitter": "^0.3.5", - "tad": "^0.2.7" - }, - "eslintConfig": { - "extends": "medikoo-es5", - "root": true, - "rules": { - "no-extend-native": "off" - } - }, - "scripts": { - "lint": "eslint --ignore-path=.gitignore .", - "test": "node ./node_modules/tad/bin/tad" - }, - "license": "MIT", - "_resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "_integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", - "_from": "es6-iterator@2.0.3", - "readme": "# es6-iterator\n## ECMAScript 6 Iterator interface\n\n### Installation\n\n\t$ npm install es6-iterator\n\t\nTo port it to Browser or any other (non CJS) environment, use your favorite CJS bundler. No favorite yet? Try: [Browserify](http://browserify.org/), [Webmake](https://github.com/medikoo/modules-webmake) or [Webpack](http://webpack.github.io/)\n\n## API\n\n### Constructors\n\n#### Iterator(list) _(es6-iterator)_\n\nAbstract Iterator interface. Meant for extensions and not to be used on its own.\n\nAccepts any _list_ object (technically object with numeric _length_ property).\n\n_Mind it doesn't iterate strings properly, for that use dedicated [StringIterator](#string-iterator)_\n\n```javascript\nvar Iterator = require('es6-iterator')\nvar iterator = new Iterator([1, 2, 3]);\n\niterator.next(); // { value: 1, done: false }\niterator.next(); // { value: 2, done: false }\niterator.next(); // { value: 3, done: false }\niterator.next(); // { value: undefined, done: true }\n```\n\n\n#### ArrayIterator(arrayLike[, kind]) _(es6-iterator/array)_\n\nDedicated for arrays and array-likes. Supports three iteration kinds:\n* __value__ _(default)_ - Iterates values\n* __key__ - Iterates indexes\n* __key+value__ - Iterates keys and indexes, each iteration value is in _[key, value]_ form.\n\n\n```javascript\nvar ArrayIterator = require('es6-iterator/array')\nvar iterator = new ArrayIterator([1, 2, 3], 'key+value');\n\niterator.next(); // { value: [0, 1], done: false }\niterator.next(); // { value: [1, 2], done: false }\niterator.next(); // { value: [2, 3], done: false }\niterator.next(); // { value: undefined, done: true }\n```\n\nMay also be used for _arguments_ objects:\n\n```javascript\n(function () {\n var iterator = new ArrayIterator(arguments);\n\n iterator.next(); // { value: 1, done: false }\n iterator.next(); // { value: 2, done: false }\n iterator.next(); // { value: 3, done: false }\n iterator.next(); // { value: undefined, done: true }\n}(1, 2, 3));\n```\n\n#### StringIterator(str) _(es6-iterator/string)_\n\nAssures proper iteration over unicode symbols. \nSee: http://mathiasbynens.be/notes/javascript-unicode\n\n```javascript\nvar StringIterator = require('es6-iterator/string');\nvar iterator = new StringIterator('f🙈o🙉o🙊');\n\niterator.next(); // { value: 'f', done: false }\niterator.next(); // { value: '🙈', done: false }\niterator.next(); // { value: 'o', done: false }\niterator.next(); // { value: '🙉', done: false }\niterator.next(); // { value: 'o', done: false }\niterator.next(); // { value: '🙊', done: false }\niterator.next(); // { value: undefined, done: true }\n```\n\n### Function utilities\n\n#### forOf(iterable, callback[, thisArg]) _(es6-iterator/for-of)_\n\nPolyfill for ECMAScript 6 [`for...of`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of) statement.\n\n```\nvar forOf = require('es6-iterator/for-of');\nvar result = [];\n\nforOf('🙈🙉🙊', function (monkey) { result.push(monkey); });\nconsole.log(result); // ['🙈', '🙉', '🙊'];\n```\n\nOptionally you can break iteration at any point:\n\n```javascript\nvar result = [];\n\nforOf([1,2,3,4]', function (val, doBreak) {\n result.push(monkey);\n if (val >= 3) doBreak();\n});\nconsole.log(result); // [1, 2, 3];\n```\n\n#### get(obj) _(es6-iterator/get)_\n\nReturn iterator for any iterable object.\n\n```javascript\nvar getIterator = require('es6-iterator/get');\nvar iterator = get([1,2,3]);\n\niterator.next(); // { value: 1, done: false }\niterator.next(); // { value: 2, done: false }\niterator.next(); // { value: 3, done: false }\niterator.next(); // { value: undefined, done: true }\n```\n\n#### isIterable(obj) _(es6-iterator/is-iterable)_\n\nWhether _obj_ is iterable\n\n```javascript\nvar isIterable = require('es6-iterator/is-iterable');\n\nisIterable(null); // false\nisIterable(true); // false\nisIterable('str'); // true\nisIterable(['a', 'r', 'r']); // true\nisIterable(new ArrayIterator([])); // true\n```\n\n#### validIterable(obj) _(es6-iterator/valid-iterable)_\n\nIf _obj_ is an iterable it is returned. Otherwise _TypeError_ is thrown.\n\n### Method extensions\n\n#### iterator.chain(iterator1[, …iteratorn]) _(es6-iterator/#/chain)_\n\nChain multiple iterators into one.\n\n### Tests [![Build Status](https://travis-ci.org/medikoo/es6-iterator.png)](https://travis-ci.org/medikoo/es6-iterator)\n\n\t$ npm test\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/medikoo/es6-iterator/issues" - }, - "homepage": "https://github.com/medikoo/es6-iterator#readme", - "_id": "es6-iterator@2.0.3", - "_requested": { - "type": "version", - "registry": true, - "raw": "es6-iterator@2.0.3", - "name": "es6-iterator", - "escapedName": "es6-iterator", - "rawSpec": "2.0.3", - "saveSpec": "[Circular]", - "fetchSpec": "2.0.3" - }, - "_spec": "2.0.3", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "es6-iterator@2.0.3", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "optionalDependencies": {}, - "_dependencies": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - }, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/es6-iterator", - "error": "[Circular]", - "extraneous": false - }, - "es6-symbol": { - "name": "es6-symbol", - "version": "3.1.1", - "description": "ECMAScript 6 Symbol polyfill", - "author": "[Circular]", - "keywords": "[Circular]", - "repository": "[Circular]", - "dependencies": { - "es5-ext": { - "name": "es5-ext", - "version": "0.10.45", - "description": "ECMAScript extensions and shims", - "author": "[Circular]", - "keywords": "[Circular]", - "repository": "[Circular]", - "dependencies": {}, - "devDependencies": "[Circular]", - "eslintConfig": "[Circular]", - "scripts": "[Circular]", - "license": "ISC", - "_resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.45.tgz", - "_integrity": "sha512-FkfM6Vxxfmztilbxxz5UKSD4ICMf5tSpRFtDNtkAhOxZ0EKtX6qwmXNyH/sFyIbX2P/nU5AMiA9jilWsUGJzCQ==", - "_from": "es5-ext@0.10.45", - "readme": "[![Build status][nix-build-image]][nix-build-url]\n[![Windows status][win-build-image]][win-build-url]\n![Transpilation status][transpilation-image]\n[![npm version][npm-image]][npm-url]\n\n# es5-ext\n\n## ECMAScript 5 extensions\n\n### (with respect to ECMAScript 6 standard)\n\nShims for upcoming ES6 standard and other goodies implemented strictly with ECMAScript conventions in mind.\n\nIt's designed to be used in compliant ECMAScript 5 or ECMAScript 6 environments. Older environments are not supported, although most of the features should work with correct ECMAScript 5 shim on board.\n\nWhen used in ECMAScript 6 environment, native implementation (if valid) takes precedence over shims.\n\n### Installation\n\n $ npm install es5-ext\n\nTo port it to Browser or any other (non CJS) environment, use your favorite CJS bundler. No favorite yet? Try: [Browserify](http://browserify.org/), [Webmake](https://github.com/medikoo/modules-webmake) or [Webpack](http://webpack.github.io/)\n\n### Usage\n\n#### ECMAScript 6 features\n\nYou can force ES6 features to be implemented in your environment, e.g. following will assign `from` function to `Array` (only if it's not implemented already).\n\n```javascript\nrequire(\"es5-ext/array/from/implement\");\nArray.from(\"foo\"); // ['f', 'o', 'o']\n```\n\nYou can also access shims directly, without fixing native objects. Following will return native `Array.from` if it's available and fallback to shim if it's not.\n\n```javascript\nvar aFrom = require(\"es5-ext/array/from\");\naFrom(\"foo\"); // ['f', 'o', 'o']\n```\n\nIf you want to use shim unconditionally (even if native implementation exists) do:\n\n```javascript\nvar aFrom = require(\"es5-ext/array/from/shim\");\naFrom(\"foo\"); // ['f', 'o', 'o']\n```\n\n##### List of ES6 shims\n\nIt's about properties introduced with ES6 and those that have been updated in new spec.\n\n* `Array.from` -> `require('es5-ext/array/from')`\n* `Array.of` -> `require('es5-ext/array/of')`\n* `Array.prototype.concat` -> `require('es5-ext/array/#/concat')`\n* `Array.prototype.copyWithin` -> `require('es5-ext/array/#/copy-within')`\n* `Array.prototype.entries` -> `require('es5-ext/array/#/entries')`\n* `Array.prototype.fill` -> `require('es5-ext/array/#/fill')`\n* `Array.prototype.filter` -> `require('es5-ext/array/#/filter')`\n* `Array.prototype.find` -> `require('es5-ext/array/#/find')`\n* `Array.prototype.findIndex` -> `require('es5-ext/array/#/find-index')`\n* `Array.prototype.keys` -> `require('es5-ext/array/#/keys')`\n* `Array.prototype.map` -> `require('es5-ext/array/#/map')`\n* `Array.prototype.slice` -> `require('es5-ext/array/#/slice')`\n* `Array.prototype.splice` -> `require('es5-ext/array/#/splice')`\n* `Array.prototype.values` -> `require('es5-ext/array/#/values')`\n* `Array.prototype[@@iterator]` -> `require('es5-ext/array/#/@@iterator')`\n* `Math.acosh` -> `require('es5-ext/math/acosh')`\n* `Math.asinh` -> `require('es5-ext/math/asinh')`\n* `Math.atanh` -> `require('es5-ext/math/atanh')`\n* `Math.cbrt` -> `require('es5-ext/math/cbrt')`\n* `Math.clz32` -> `require('es5-ext/math/clz32')`\n* `Math.cosh` -> `require('es5-ext/math/cosh')`\n* `Math.exmp1` -> `require('es5-ext/math/expm1')`\n* `Math.fround` -> `require('es5-ext/math/fround')`\n* `Math.hypot` -> `require('es5-ext/math/hypot')`\n* `Math.imul` -> `require('es5-ext/math/imul')`\n* `Math.log1p` -> `require('es5-ext/math/log1p')`\n* `Math.log2` -> `require('es5-ext/math/log2')`\n* `Math.log10` -> `require('es5-ext/math/log10')`\n* `Math.sign` -> `require('es5-ext/math/sign')`\n* `Math.signh` -> `require('es5-ext/math/signh')`\n* `Math.tanh` -> `require('es5-ext/math/tanh')`\n* `Math.trunc` -> `require('es5-ext/math/trunc')`\n* `Number.EPSILON` -> `require('es5-ext/number/epsilon')`\n* `Number.MAX_SAFE_INTEGER` -> `require('es5-ext/number/max-safe-integer')`\n* `Number.MIN_SAFE_INTEGER` -> `require('es5-ext/number/min-safe-integer')`\n* `Number.isFinite` -> `require('es5-ext/number/is-finite')`\n* `Number.isInteger` -> `require('es5-ext/number/is-integer')`\n* `Number.isNaN` -> `require('es5-ext/number/is-nan')`\n* `Number.isSafeInteger` -> `require('es5-ext/number/is-safe-integer')`\n* `Object.assign` -> `require('es5-ext/object/assign')`\n* `Object.keys` -> `require('es5-ext/object/keys')`\n* `Object.setPrototypeOf` -> `require('es5-ext/object/set-prototype-of')`\n* `RegExp.prototype.match` -> `require('es5-ext/reg-exp/#/match')`\n* `RegExp.prototype.replace` -> `require('es5-ext/reg-exp/#/replace')`\n* `RegExp.prototype.search` -> `require('es5-ext/reg-exp/#/search')`\n* `RegExp.prototype.split` -> `require('es5-ext/reg-exp/#/split')`\n* `RegExp.prototype.sticky` -> Implement with `require('es5-ext/reg-exp/#/sticky/implement')`, use as function with `require('es5-ext/reg-exp/#/is-sticky')`\n* `RegExp.prototype.unicode` -> Implement with `require('es5-ext/reg-exp/#/unicode/implement')`, use as function with `require('es5-ext/reg-exp/#/is-unicode')`\n* `String.fromCodePoint` -> `require('es5-ext/string/from-code-point')`\n* `String.raw` -> `require('es5-ext/string/raw')`\n* `String.prototype.codePointAt` -> `require('es5-ext/string/#/code-point-at')`\n* `String.prototype.contains` -> `require('es5-ext/string/#/contains')`\n* `String.prototype.endsWith` -> `require('es5-ext/string/#/ends-with')`\n* `String.prototype.normalize` -> `require('es5-ext/string/#/normalize')`\n* `String.prototype.repeat` -> `require('es5-ext/string/#/repeat')`\n* `String.prototype.startsWith` -> `require('es5-ext/string/#/starts-with')`\n* `String.prototype[@@iterator]` -> `require('es5-ext/string/#/@@iterator')`\n\n#### Non ECMAScript standard features\n\n**es5-ext** provides also other utils, and implements them as if they were proposed for a standard. It mostly offers methods (not functions) which can directly be assigned to native prototypes:\n\n```javascript\nObject.defineProperty(Function.prototype, \"partial\", {\n\tvalue: require(\"es5-ext/function/#/partial\"),\n\tconfigurable: true,\n\tenumerable: false,\n\twritable: true\n});\nObject.defineProperty(Array.prototype, \"flatten\", {\n\tvalue: require(\"es5-ext/array/#/flatten\"),\n\tconfigurable: true,\n\tenumerable: false,\n\twritable: true\n});\nObject.defineProperty(String.prototype, \"capitalize\", {\n\tvalue: require(\"es5-ext/string/#/capitalize\"),\n\tconfigurable: true,\n\tenumerable: false,\n\twritable: true\n});\n```\n\nSee [es5-extend](https://github.com/wookieb/es5-extend#es5-extend), a great utility that automatically will extend natives for you.\n\n**Important:** Remember to **not** extend natives in scope of generic reusable packages (e.g. ones you intend to publish to npm). Extending natives is fine **only** if you're the _owner_ of the global scope, so e.g. in final project you lead development of.\n\nWhen you're in situation when native extensions are not good idea, then you should use methods indirectly:\n\n```javascript\nvar flatten = require(\"es5-ext/array/#/flatten\");\n\nflatten.call([1, [2, [3, 4]]]); // [1, 2, 3, 4]\n```\n\nfor better convenience you can turn methods into functions:\n\n```javascript\nvar call = Function.prototype.call;\nvar flatten = call.bind(require(\"es5-ext/array/#/flatten\"));\n\nflatten([1, [2, [3, 4]]]); // [1, 2, 3, 4]\n```\n\nYou can configure custom toolkit (like [underscorejs](http://underscorejs.org/)), and use it throughout your application\n\n```javascript\nvar util = {};\nutil.partial = call.bind(require(\"es5-ext/function/#/partial\"));\nutil.flatten = call.bind(require(\"es5-ext/array/#/flatten\"));\nutil.startsWith = call.bind(require(\"es5-ext/string/#/starts-with\"));\n\nutil.flatten([1, [2, [3, 4]]]); // [1, 2, 3, 4]\n```\n\nAs with native ones most methods are generic and can be run on any type of object.\n\n## API\n\n### Global extensions\n\n#### global _(es5-ext/global)_\n\nObject that represents global scope\n\n### Array Constructor extensions\n\n#### from(arrayLike[, mapFn[, thisArg]]) _(es5-ext/array/from)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.from). \nReturns array representation of _iterable_ or _arrayLike_. If _arrayLike_ is an instance of array, its copy is returned.\n\n#### generate([length[, …fill]]) _(es5-ext/array/generate)_\n\nGenerate an array of pre-given _length_ built of repeated arguments.\n\n#### isPlainArray(x) _(es5-ext/array/is-plain-array)_\n\nReturns true if object is plain array (not instance of one of the Array's extensions).\n\n#### of([…items]) _(es5-ext/array/of)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.of). \nCreate an array from given arguments.\n\n#### toArray(obj) _(es5-ext/array/to-array)_\n\nReturns array representation of `obj`. If `obj` is already an array, `obj` is returned back.\n\n#### validArray(obj) _(es5-ext/array/valid-array)_\n\nReturns `obj` if it's an array, otherwise throws `TypeError`\n\n### Array Prototype extensions\n\n#### arr.binarySearch(compareFn) _(es5-ext/array/#/binary-search)_\n\nIn **sorted** list search for index of item for which _compareFn_ returns value closest to _0_. \nIt's variant of binary search algorithm\n\n#### arr.clear() _(es5-ext/array/#/clear)_\n\nClears the array\n\n#### arr.compact() _(es5-ext/array/#/compact)_\n\nReturns a copy of the context with all non-values (`null` or `undefined`) removed.\n\n#### arr.concat() _(es5-ext/array/#/concat)_\n\n[_Updated with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype.concat). \nES6's version of `concat`. Supports `isConcatSpreadable` symbol, and returns array of same type as the context.\n\n#### arr.contains(searchElement[, position]) _(es5-ext/array/#/contains)_\n\nWhether list contains the given value.\n\n#### arr.copyWithin(target, start[, end]) _(es5-ext/array/#/copy-within)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.copywithin).\n\n#### arr.diff(other) _(es5-ext/array/#/diff)_\n\nReturns the array of elements that are present in context list but not present in other list.\n\n#### arr.eIndexOf(searchElement[, fromIndex]) _(es5-ext/array/#/e-index-of)_\n\n_egal_ version of `indexOf` method. [_SameValueZero_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) logic is used for comparision\n\n#### arr.eLastIndexOf(searchElement[, fromIndex]) _(es5-ext/array/#/e-last-index-of)_\n\n_egal_ version of `lastIndexOf` method. [_SameValueZero_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) logic is used for comparision\n\n#### arr.entries() _(es5-ext/array/#/entries)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype.entries). \nReturns iterator object, which traverses the array. Each value is represented with an array, where first value is an index and second is corresponding to index value.\n\n#### arr.exclusion([…lists]]) _(es5-ext/array/#/exclusion)_\n\nReturns the array of elements that are found only in one of the lists (either context list or list provided in arguments).\n\n#### arr.fill(value[, start, end]) _(es5-ext/array/#/fill)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.fill).\n\n#### arr.filter(callback[, thisArg]) _(es5-ext/array/#/filter)_\n\n[_Updated with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.filter). \nES6's version of `filter`, returns array of same type as the context.\n\n#### arr.find(predicate[, thisArg]) _(es5-ext/array/#/find)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.find). \nReturn first element for which given function returns true\n\n#### arr.findIndex(predicate[, thisArg]) _(es5-ext/array/#/find-index)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.findindex). \nReturn first index for which given function returns true\n\n#### arr.first() _(es5-ext/array/#/first)_\n\nReturns value for first defined index\n\n#### arr.firstIndex() _(es5-ext/array/#/first-index)_\n\nReturns first declared index of the array\n\n#### arr.flatten() _(es5-ext/array/#/flatten)_\n\nReturns flattened version of the array\n\n#### arr.forEachRight(cb[, thisArg]) _(es5-ext/array/#/for-each-right)_\n\n`forEach` starting from last element\n\n#### arr.group(cb[, thisArg]) _(es5-ext/array/#/group)_\n\nGroup list elements by value returned by _cb_ function\n\n#### arr.indexesOf(searchElement[, fromIndex]) _(es5-ext/array/#/indexes-of)_\n\nReturns array of all indexes of given value\n\n#### arr.intersection([…lists]) _(es5-ext/array/#/intersection)_\n\nComputes the array of values that are the intersection of all lists (context list and lists given in arguments)\n\n#### arr.isCopy(other) _(es5-ext/array/#/is-copy)_\n\nReturns true if both context and _other_ lists have same content\n\n#### arr.isUniq() _(es5-ext/array/#/is-uniq)_\n\nReturns true if all values in array are unique\n\n#### arr.keys() _(es5-ext/array/#/keys)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype.keys). \nReturns iterator object, which traverses all array indexes.\n\n#### arr.last() _(es5-ext/array/#/last)_\n\nReturns value of last defined index\n\n#### arr.lastIndex() _(es5-ext/array/#/last)_\n\nReturns last defined index of the array\n\n#### arr.map(callback[, thisArg]) _(es5-ext/array/#/map)_\n\n[_Updated with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.map). \nES6's version of `map`, returns array of same type as the context.\n\n#### arr.remove(value[, …valuen]) _(es5-ext/array/#/remove)_\n\nRemove values from the array\n\n#### arr.separate(sep) _(es5-ext/array/#/separate)_\n\nReturns array with items separated with `sep` value\n\n#### arr.slice(callback[, thisArg]) _(es5-ext/array/#/slice)_\n\n[_Updated with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.slice). \nES6's version of `slice`, returns array of same type as the context.\n\n#### arr.someRight(cb[, thisArg]) _(es5-ext/array/#/someRight)_\n\n`some` starting from last element\n\n#### arr.splice(callback[, thisArg]) _(es5-ext/array/#/splice)_\n\n[_Updated with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.splice). \nES6's version of `splice`, returns array of same type as the context.\n\n#### arr.uniq() _(es5-ext/array/#/uniq)_\n\nReturns duplicate-free version of the array\n\n#### arr.values() _(es5-ext/array/#/values)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype.values). \nReturns iterator object which traverses all array values.\n\n#### arr[@@iterator] _(es5-ext/array/#/@@iterator)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype-@@iterator). \nReturns iterator object which traverses all array values.\n\n### Boolean Constructor extensions\n\n#### isBoolean(x) _(es5-ext/boolean/is-boolean)_\n\nWhether value is boolean\n\n### Date Constructor extensions\n\n#### isDate(x) _(es5-ext/date/is-date)_\n\nWhether value is date instance\n\n#### validDate(x) _(es5-ext/date/valid-date)_\n\nIf given object is not date throw TypeError in other case return it.\n\n### Date Prototype extensions\n\n#### date.copy(date) _(es5-ext/date/#/copy)_\n\nReturns a copy of the date object\n\n#### date.daysInMonth() _(es5-ext/date/#/days-in-month)_\n\nReturns number of days of date's month\n\n#### date.floorDay() _(es5-ext/date/#/floor-day)_\n\nSets the date time to 00:00:00.000\n\n#### date.floorMonth() _(es5-ext/date/#/floor-month)_\n\nSets date day to 1 and date time to 00:00:00.000\n\n#### date.floorYear() _(es5-ext/date/#/floor-year)_\n\nSets date month to 0, day to 1 and date time to 00:00:00.000\n\n#### date.format(pattern) _(es5-ext/date/#/format)_\n\nFormats date up to given string. Supported patterns:\n\n* `%Y` - Year with century, 1999, 2003\n* `%y` - Year without century, 99, 03\n* `%m` - Month, 01..12\n* `%d` - Day of the month 01..31\n* `%H` - Hour (24-hour clock), 00..23\n* `%M` - Minute, 00..59\n* `%S` - Second, 00..59\n* `%L` - Milliseconds, 000..999\n\n### Error Constructor extensions\n\n#### custom(message/_, code, ext_/) _(es5-ext/error/custom)_\n\nCreates custom error object, optinally extended with `code` and other extension properties (provided with `ext` object)\n\n#### isError(x) _(es5-ext/error/is-error)_\n\nWhether value is an error (instance of `Error`).\n\n#### validError(x) _(es5-ext/error/valid-error)_\n\nIf given object is not error throw TypeError in other case return it.\n\n### Error Prototype extensions\n\n#### err.throw() _(es5-ext/error/#/throw)_\n\nThrows error\n\n### Function Constructor extensions\n\nSome of the functions were inspired by [Functional JavaScript](http://osteele.com/sources/javascript/functional/) project by Olivier Steele\n\n#### constant(x) _(es5-ext/function/constant)_\n\nReturns a constant function that returns pregiven argument\n\n_k(x)(y) =def x_\n\n#### identity(x) _(es5-ext/function/identity)_\n\nIdentity function. Returns first argument\n\n_i(x) =def x_\n\n#### invoke(name[, …args]) _(es5-ext/function/invoke)_\n\nReturns a function that takes an object as an argument, and applies object's\n_name_ method to arguments. \n_name_ can be name of the method or method itself.\n\n_invoke(name, …args)(object, …args2) =def object\\[name\\]\\(…args, …args2\\)_\n\n#### isArguments(x) _(es5-ext/function/is-arguments)_\n\nWhether value is arguments object\n\n#### isFunction(arg) _(es5-ext/function/is-function)_\n\nWhether value is instance of function\n\n#### noop() _(es5-ext/function/noop)_\n\nNo operation function\n\n#### pluck(name) _(es5-ext/function/pluck)_\n\nReturns a function that takes an object, and returns the value of its _name_\nproperty\n\n_pluck(name)(obj) =def obj[name]_\n\n#### validFunction(arg) _(es5-ext/function/valid-function)_\n\nIf given object is not function throw TypeError in other case return it.\n\n### Function Prototype extensions\n\nSome of the methods were inspired by [Functional JavaScript](http://osteele.com/sources/javascript/functional/) project by Olivier Steele\n\n#### fn.compose([…fns]) _(es5-ext/function/#/compose)_\n\nApplies the functions in reverse argument-list order.\n\n_f1.compose(f2, f3, f4)(…args) =def f1(f2(f3(f4(…arg))))_\n\n#### fn.copy() _(es5-ext/function/#/copy)_\n\nProduces copy of given function\n\n#### fn.curry([n]) _(es5-ext/function/#/curry)_\n\nInvoking the function returned by this function only _n_ arguments are passed to the underlying function. If the underlying function is not saturated, the result is a function that passes all its arguments to the underlying function. \nIf _n_ is not provided then it defaults to context function length\n\n_f.curry(4)(arg1, arg2)(arg3)(arg4) =def f(arg1, args2, arg3, arg4)_\n\n#### fn.lock([…args]) _(es5-ext/function/#/lock)_\n\nReturns a function that applies the underlying function to _args_, and ignores its own arguments.\n\n_f.lock(…args)(…args2) =def f(…args)_\n\n_Named after it's counterpart in Google Closure_\n\n#### fn.not() _(es5-ext/function/#/not)_\n\nReturns a function that returns boolean negation of value returned by underlying function.\n\n_f.not()(…args) =def !f(…args)_\n\n#### fn.partial([…args]) _(es5-ext/function/#/partial)_\n\nReturns a function that when called will behave like context function called with initially passed arguments. If more arguments are suplilied, they are appended to initial args.\n\n_f.partial(…args1)(…args2) =def f(…args1, …args2)_\n\n#### fn.spread() _(es5-ext/function/#/spread)_\n\nReturns a function that applies underlying function with first list argument\n\n_f.match()(args) =def f.apply(null, args)_\n\n#### fn.toStringTokens() _(es5-ext/function/#/to-string-tokens)_\n\nSerializes function into two (arguments and body) string tokens. Result is plain object with `args` and `body` properties.\n\n### Math extensions\n\n#### acosh(x) _(es5-ext/math/acosh)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.acosh).\n\n#### asinh(x) _(es5-ext/math/asinh)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.asinh).\n\n#### atanh(x) _(es5-ext/math/atanh)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.atanh).\n\n#### cbrt(x) _(es5-ext/math/cbrt)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.cbrt).\n\n#### clz32(x) _(es5-ext/math/clz32)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.clz32).\n\n#### cosh(x) _(es5-ext/math/cosh)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.cosh).\n\n#### expm1(x) _(es5-ext/math/expm1)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.expm1).\n\n#### fround(x) _(es5-ext/math/fround)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.fround).\n\n#### hypot([…values]) _(es5-ext/math/hypot)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.hypot).\n\n#### imul(x, y) _(es5-ext/math/imul)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.imul).\n\n#### log1p(x) _(es5-ext/math/log1p)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.log1p).\n\n#### log2(x) _(es5-ext/math/log2)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.log2).\n\n#### log10(x) _(es5-ext/math/log10)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.log10).\n\n#### sign(x) _(es5-ext/math/sign)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.sign).\n\n#### sinh(x) _(es5-ext/math/sinh)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.sinh).\n\n#### tanh(x) _(es5-ext/math/tanh)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.tanh).\n\n#### trunc(x) _(es5-ext/math/trunc)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.trunc).\n\n### Number Constructor extensions\n\n#### EPSILON _(es5-ext/number/epsilon)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.epsilon).\n\nThe difference between 1 and the smallest value greater than 1 that is representable as a Number value, which is approximately 2.2204460492503130808472633361816 x 10-16.\n\n#### isFinite(x) _(es5-ext/number/is-finite)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.isfinite). \nWhether value is finite. Differs from global isNaN that it doesn't do type coercion.\n\n#### isInteger(x) _(es5-ext/number/is-integer)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.isinteger). \nWhether value is integer.\n\n#### isNaN(x) _(es5-ext/number/is-nan)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.isnan). \nWhether value is NaN. Differs from global isNaN that it doesn't do type coercion.\n\n#### isNumber(x) _(es5-ext/number/is-number)_\n\nWhether given value is number\n\n#### isSafeInteger(x) _(es5-ext/number/is-safe-integer)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.issafeinteger).\n\n#### MAX*SAFE_INTEGER *(es5-ext/number/max-safe-integer)\\_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.maxsafeinteger). \nThe value of Number.MAX_SAFE_INTEGER is 9007199254740991.\n\n#### MIN*SAFE_INTEGER *(es5-ext/number/min-safe-integer)\\_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.minsafeinteger). \nThe value of Number.MIN_SAFE_INTEGER is -9007199254740991 (253-1).\n\n#### toInteger(x) _(es5-ext/number/to-integer)_\n\nConverts value to integer\n\n#### toPosInteger(x) _(es5-ext/number/to-pos-integer)_\n\nConverts value to positive integer. If provided value is less than 0, then 0 is returned\n\n#### toUint32(x) _(es5-ext/number/to-uint32)_\n\nConverts value to unsigned 32 bit integer. This type is used for array lengths.\nSee: http://www.2ality.com/2012/02/js-integers.html\n\n### Number Prototype extensions\n\n#### num.pad(length[, precision]) _(es5-ext/number/#/pad)_\n\nPad given number with zeros. Returns string\n\n### Object Constructor extensions\n\n#### assign(target, source[, …sourcen]) _(es5-ext/object/assign)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign). \nExtend _target_ by enumerable own properties of other objects. If properties are already set on target object, they will be overwritten.\n\n#### clear(obj) _(es5-ext/object/clear)_\n\nRemove all enumerable own properties of the object\n\n#### compact(obj) _(es5-ext/object/compact)_\n\nReturns copy of the object with all enumerable properties that have no falsy values\n\n#### compare(obj1, obj2) _(es5-ext/object/compare)_\n\nUniversal cross-type compare function. To be used for e.g. array sort.\n\n#### copy(obj) _(es5-ext/object/copy)_\n\nReturns copy of the object with all enumerable properties.\n\n#### copyDeep(obj) _(es5-ext/object/copy-deep)_\n\nReturns deep copy of the object with all enumerable properties.\n\n#### count(obj) _(es5-ext/object/count)_\n\nCounts number of enumerable own properties on object\n\n#### create(obj[, properties]) _(es5-ext/object/create)_\n\n`Object.create` alternative that provides workaround for [V8 issue](http://code.google.com/p/v8/issues/detail?id=2804).\n\nWhen `null` is provided as a prototype, it's substituted with specially prepared object that derives from Object.prototype but has all Object.prototype properties shadowed with undefined.\n\nIt's quirky solution that allows us to have plain objects with no truthy properties but with turnable prototype.\n\nUse only for objects that you plan to switch prototypes of and be aware of limitations of this workaround.\n\n#### eq(x, y) _(es5-ext/object/eq)_\n\nWhether two values are equal, using [_SameValueZero_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) algorithm.\n\n#### every(obj, cb[, thisArg[, compareFn]]) _(es5-ext/object/every)_\n\nAnalogous to Array.prototype.every. Returns true if every key-value pair in this object satisfies the provided testing function. \nOptionally _compareFn_ can be provided which assures that keys are tested in given order. If provided _compareFn_ is equal to `true`, then order is alphabetical (by key).\n\n#### filter(obj, cb[, thisArg]) _(es5-ext/object/filter)_\n\nAnalogous to Array.prototype.filter. Returns new object with properites for which _cb_ function returned truthy value.\n\n#### firstKey(obj) _(es5-ext/object/first-key)_\n\nReturns first enumerable key of the object, as keys are unordered by specification, it can be any key of an object.\n\n#### flatten(obj) _(es5-ext/object/flatten)_\n\nReturns new object, with flatten properties of input object\n\n_flatten({ a: { b: 1 }, c: { d: 1 } }) =def { b: 1, d: 1 }_\n\n#### forEach(obj, cb[, thisArg[, compareFn]]) _(es5-ext/object/for-each)_\n\nAnalogous to Array.prototype.forEach. Calls a function for each key-value pair found in object\nOptionally _compareFn_ can be provided which assures that properties are iterated in given order. If provided _compareFn_ is equal to `true`, then order is alphabetical (by key).\n\n#### getPropertyNames() _(es5-ext/object/get-property-names)_\n\nGet all (not just own) property names of the object\n\n#### is(x, y) _(es5-ext/object/is)_\n\nWhether two values are equal, using [_SameValue_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) algorithm.\n\n#### isArrayLike(x) _(es5-ext/object/is-array-like)_\n\nWhether object is array-like object\n\n#### isCopy(x, y) _(es5-ext/object/is-copy)_\n\nTwo values are considered a copy of same value when all of their own enumerable properties have same values.\n\n#### isCopyDeep(x, y) _(es5-ext/object/is-copy-deep)_\n\nDeep comparision of objects\n\n#### isEmpty(obj) _(es5-ext/object/is-empty)_\n\nTrue if object doesn't have any own enumerable property\n\n#### isObject(arg) _(es5-ext/object/is-object)_\n\nWhether value is not primitive\n\n#### isPlainObject(arg) _(es5-ext/object/is-plain-object)_\n\nWhether object is plain object, its protototype should be Object.prototype and it cannot be host object.\n\n#### keyOf(obj, searchValue) _(es5-ext/object/key-of)_\n\nSearch object for value\n\n#### keys(obj) _(es5-ext/object/keys)_\n\n[_Updated with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.keys). \nES6's version of `keys`, doesn't throw on primitive input\n\n#### map(obj, cb[, thisArg]) _(es5-ext/object/map)_\n\nAnalogous to Array.prototype.map. Creates a new object with properties which values are results of calling a provided function on every key-value pair in this object.\n\n#### mapKeys(obj, cb[, thisArg]) _(es5-ext/object/map-keys)_\n\nCreate new object with same values, but remapped keys\n\n#### mixin(target, source) _(es5-ext/object/mixin)_\n\nExtend _target_ by all own properties of other objects. Properties found in both objects will be overwritten (unless they're not configurable and cannot be overwritten).\n_It was for a moment part of ECMAScript 6 draft._\n\n#### mixinPrototypes(target, …source]) _(es5-ext/object/mixin-prototypes)_\n\nExtends _target_, with all source and source's prototype properties.\nUseful as an alternative for `setPrototypeOf` in environments in which it cannot be shimmed (no `__proto__` support).\n\n#### normalizeOptions(options) _(es5-ext/object/normalize-options)_\n\nNormalizes options object into flat plain object.\n\nUseful for functions in which we either need to keep options object for future reference or need to modify it for internal use.\n\n* It never returns input `options` object back (always a copy is created)\n* `options` can be undefined in such case empty plain object is returned.\n* Copies all enumerable properties found down prototype chain.\n\n#### primitiveSet([…names]) _(es5-ext/object/primitive-set)_\n\nCreates `null` prototype based plain object, and sets on it all property names provided in arguments to true.\n\n#### safeTraverse(obj[, …names]) _(es5-ext/object/safe-traverse)_\n\nSafe navigation of object properties. See http://wiki.ecmascript.org/doku.php?id=strawman:existential_operator\n\n#### serialize(value) _(es5-ext/object/serialize)_\n\nSerialize value into string. Differs from [JSON.stringify](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) that it serializes also dates, functions and regular expresssions.\n\n#### setPrototypeOf(object, proto) _(es5-ext/object/set-prototype-of)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.setprototypeof). \nIf native version is not provided, it depends on existence of `__proto__` functionality, if it's missing, `null` instead of function is exposed.\n\n#### some(obj, cb[, thisArg[, compareFn]]) _(es5-ext/object/some)_\n\nAnalogous to Array.prototype.some Returns true if any key-value pair satisfies the provided\ntesting function. \nOptionally _compareFn_ can be provided which assures that keys are tested in given order. If provided _compareFn_ is equal to `true`, then order is alphabetical (by key).\n\n#### toArray(obj[, cb[, thisArg[, compareFn]]]) _(es5-ext/object/to-array)_\n\nCreates an array of results of calling a provided function on every key-value pair in this object. \nOptionally _compareFn_ can be provided which assures that results are added in given order. If provided _compareFn_ is equal to `true`, then order is alphabetical (by key).\n\n#### unserialize(str) _(es5-ext/object/unserialize)_\n\nUserializes value previously serialized with [serialize](#serializevalue-es5-extobjectserialize)\n\n#### validCallable(x) _(es5-ext/object/valid-callable)_\n\nIf given object is not callable throw TypeError in other case return it.\n\n#### validObject(x) _(es5-ext/object/valid-object)_\n\nThrows error if given value is not an object, otherwise it is returned.\n\n#### validValue(x) _(es5-ext/object/valid-value)_\n\nThrows error if given value is `null` or `undefined`, otherwise returns value.\n\n### RegExp Constructor extensions\n\n#### escape(str) _(es5-ext/reg-exp/escape)_\n\nEscapes string to be used in regular expression\n\n#### isRegExp(x) _(es5-ext/reg-exp/is-reg-exp)_\n\nWhether object is regular expression\n\n#### validRegExp(x) _(es5-ext/reg-exp/valid-reg-exp)_\n\nIf object is regular expression it is returned, otherwise TypeError is thrown.\n\n### RegExp Prototype extensions\n\n#### re.isSticky(x) _(es5-ext/reg-exp/#/is-sticky)_\n\nWhether regular expression has `sticky` flag.\n\nIt's to be used as counterpart to [regExp.sticky](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-get-regexp.prototype.sticky) if it's not implemented.\n\n#### re.isUnicode(x) _(es5-ext/reg-exp/#/is-unicode)_\n\nWhether regular expression has `unicode` flag.\n\nIt's to be used as counterpart to [regExp.unicode](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-get-regexp.prototype.unicode) if it's not implemented.\n\n#### re.match(string) _(es5-ext/reg-exp/#/match)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.match).\n\n#### re.replace(string, replaceValue) _(es5-ext/reg-exp/#/replace)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.replace).\n\n#### re.search(string) _(es5-ext/reg-exp/#/search)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.search).\n\n#### re.split(string) _(es5-ext/reg-exp/#/search)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.split).\n\n#### re.sticky _(es5-ext/reg-exp/#/sticky/implement)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.sticky). \nIt's a getter, so only `implement` and `is-implemented` modules are provided.\n\n#### re.unicode _(es5-ext/reg-exp/#/unicode/implement)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.unicode). \nIt's a getter, so only `implement` and `is-implemented` modules are provided.\n\n### String Constructor extensions\n\n#### formatMethod(fMap) _(es5-ext/string/format-method)_\n\nCreates format method. It's used e.g. to create `Date.prototype.format` method\n\n#### fromCodePoint([…codePoints]) _(es5-ext/string/from-code-point)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.fromcodepoint)\n\n#### isString(x) _(es5-ext/string/is-string)_\n\nWhether object is string\n\n#### randomUniq() _(es5-ext/string/random-uniq)_\n\nReturns randomly generated id, with guarantee of local uniqueness (no same id will be returned twice)\n\n#### raw(callSite[, …substitutions]) _(es5-ext/string/raw)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.raw)\n\n### String Prototype extensions\n\n#### str.at(pos) _(es5-ext/string/#/at)_\n\n_Proposed for ECMAScript 6/7 standard, but not (yet) in a draft_\n\nReturns a string at given position in Unicode-safe manner.\nBased on [implementation by Mathias Bynens](https://github.com/mathiasbynens/String.prototype.at).\n\n#### str.camelToHyphen() _(es5-ext/string/#/camel-to-hyphen)_\n\nConvert camelCase string to hyphen separated, e.g. one-two-three -> oneTwoThree.\nUseful when converting names from js property convention into filename convention.\n\n#### str.capitalize() _(es5-ext/string/#/capitalize)_\n\nCapitalize first character of a string\n\n#### str.caseInsensitiveCompare(str) _(es5-ext/string/#/case-insensitive-compare)_\n\nCase insensitive compare\n\n#### str.codePointAt(pos) _(es5-ext/string/#/code-point-at)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.codepointat)\n\nBased on [implementation by Mathias Bynens](https://github.com/mathiasbynens/String.prototype.codePointAt).\n\n#### str.contains(searchString[, position]) _(es5-ext/string/#/contains)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.contains)\n\nWhether string contains given string.\n\n#### str.endsWith(searchString[, endPosition]) _(es5-ext/string/#/ends-with)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.endswith). \nWhether strings ends with given string\n\n#### str.hyphenToCamel() _(es5-ext/string/#/hyphen-to-camel)_\n\nConvert hyphen separated string to camelCase, e.g. one-two-three -> oneTwoThree.\nUseful when converting names from filename convention to js property name convention.\n\n#### str.indent(str[, count]) _(es5-ext/string/#/indent)_\n\nIndents each line with provided _str_ (if _count_ given then _str_ is repeated _count_ times).\n\n#### str.last() _(es5-ext/string/#/last)_\n\nReturn last character\n\n#### str.normalize([form]) _(es5-ext/string/#/normalize)_\n\n[_Introduced with ECMAScript 6_](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize). \nReturns the Unicode Normalization Form of a given string. \nBased on Matsuza's version. Code used for integrated shim can be found at [github.com/walling/unorm](https://github.com/walling/unorm/blob/master/lib/unorm.js)\n\n#### str.pad(fill[, length]) _(es5-ext/string/#/pad)_\n\nPad string with _fill_.\nIf _length_ si given than _fill_ is reapated _length_ times.\nIf _length_ is negative then pad is applied from right.\n\n#### str.repeat(n) _(es5-ext/string/#/repeat)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.repeat). \nRepeat given string _n_ times\n\n#### str.plainReplace(search, replace) _(es5-ext/string/#/plain-replace)_\n\nSimple `replace` version. Doesn't support regular expressions. Replaces just first occurrence of search string. Doesn't support insert patterns, therefore it is safe to replace text with text obtained programmatically (there's no need for additional _$_ characters escape in such case).\n\n#### str.plainReplaceAll(search, replace) _(es5-ext/string/#/plain-replace-all)_\n\nSimple `replace` version. Doesn't support regular expressions. Replaces all occurrences of search string. Doesn't support insert patterns, therefore it is safe to replace text with text obtained programmatically (there's no need for additional _$_ characters escape in such case).\n\n#### str.startsWith(searchString[, position]) _(es5-ext/string/#/starts-with)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.startswith). \nWhether strings starts with given string\n\n#### str[@@iterator] _(es5-ext/string/#/@@iterator)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype-@@iterator). \nReturns iterator object which traverses all string characters (with respect to unicode symbols)\n\n### Tests\n\n $ npm test\n\n[nix-build-image]: https://semaphoreci.com/api/v1/medikoo-org/es5-ext/branches/master/shields_badge.svg\n[nix-build-url]: https://semaphoreci.com/medikoo-org/es5-ext\n[win-build-image]: https://ci.appveyor.com/api/projects/status/3jox67ksw3p8hkwh?svg=true\n[win-build-url]: https://ci.appveyor.com/project/medikoo/es5-ext\n[transpilation-image]: https://img.shields.io/badge/transpilation-free-brightgreen.svg\n[npm-image]: https://img.shields.io/npm/v/es5-ext.svg\n[npm-url]: https://www.npmjs.com/package/es5-ext\n", - "readmeFilename": "README.md", - "bugs": "[Circular]", - "homepage": "https://github.com/medikoo/es5-ext#readme", - "_id": "es5-ext@0.10.45", - "_requested": { - "type": "version", - "registry": true, - "raw": "es5-ext@0.10.45", - "name": "es5-ext", - "escapedName": "es5-ext", - "rawSpec": "0.10.45", - "saveSpec": "[Circular]", - "fetchSpec": "0.10.45" - }, - "_spec": "0.10.45", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": "[Circular]", - "optionalDependencies": "[Circular]", - "_dependencies": "[Circular]", - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/es5-ext", - "error": "[Circular]", - "extraneous": false, - "_deduped": "es5-ext" - }, - "d": { - "name": "d", - "version": "1.0.0", - "description": "Property descriptor factory", - "author": { - "name": "Mariusz Nowak", - "email": "medyk@medikoo.com", - "url": "http://www.medikoo.com/" - }, - "keywords": [ - "descriptor", - "es", - "ecmascript", - "ecma", - "property", - "descriptors", - "meta", - "properties" - ], - "repository": { - "type": "git", - "url": "git://github.com/medikoo/d.git" - }, - "dependencies": { - "es5-ext": { - "name": "es5-ext", - "version": "0.10.45", - "description": "ECMAScript extensions and shims", - "author": "[Circular]", - "keywords": "[Circular]", - "repository": "[Circular]", - "dependencies": {}, - "devDependencies": "[Circular]", - "eslintConfig": "[Circular]", - "scripts": "[Circular]", - "license": "ISC", - "_resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.45.tgz", - "_integrity": "sha512-FkfM6Vxxfmztilbxxz5UKSD4ICMf5tSpRFtDNtkAhOxZ0EKtX6qwmXNyH/sFyIbX2P/nU5AMiA9jilWsUGJzCQ==", - "_from": "es5-ext@0.10.45", - "readme": "[![Build status][nix-build-image]][nix-build-url]\n[![Windows status][win-build-image]][win-build-url]\n![Transpilation status][transpilation-image]\n[![npm version][npm-image]][npm-url]\n\n# es5-ext\n\n## ECMAScript 5 extensions\n\n### (with respect to ECMAScript 6 standard)\n\nShims for upcoming ES6 standard and other goodies implemented strictly with ECMAScript conventions in mind.\n\nIt's designed to be used in compliant ECMAScript 5 or ECMAScript 6 environments. Older environments are not supported, although most of the features should work with correct ECMAScript 5 shim on board.\n\nWhen used in ECMAScript 6 environment, native implementation (if valid) takes precedence over shims.\n\n### Installation\n\n $ npm install es5-ext\n\nTo port it to Browser or any other (non CJS) environment, use your favorite CJS bundler. No favorite yet? Try: [Browserify](http://browserify.org/), [Webmake](https://github.com/medikoo/modules-webmake) or [Webpack](http://webpack.github.io/)\n\n### Usage\n\n#### ECMAScript 6 features\n\nYou can force ES6 features to be implemented in your environment, e.g. following will assign `from` function to `Array` (only if it's not implemented already).\n\n```javascript\nrequire(\"es5-ext/array/from/implement\");\nArray.from(\"foo\"); // ['f', 'o', 'o']\n```\n\nYou can also access shims directly, without fixing native objects. Following will return native `Array.from` if it's available and fallback to shim if it's not.\n\n```javascript\nvar aFrom = require(\"es5-ext/array/from\");\naFrom(\"foo\"); // ['f', 'o', 'o']\n```\n\nIf you want to use shim unconditionally (even if native implementation exists) do:\n\n```javascript\nvar aFrom = require(\"es5-ext/array/from/shim\");\naFrom(\"foo\"); // ['f', 'o', 'o']\n```\n\n##### List of ES6 shims\n\nIt's about properties introduced with ES6 and those that have been updated in new spec.\n\n* `Array.from` -> `require('es5-ext/array/from')`\n* `Array.of` -> `require('es5-ext/array/of')`\n* `Array.prototype.concat` -> `require('es5-ext/array/#/concat')`\n* `Array.prototype.copyWithin` -> `require('es5-ext/array/#/copy-within')`\n* `Array.prototype.entries` -> `require('es5-ext/array/#/entries')`\n* `Array.prototype.fill` -> `require('es5-ext/array/#/fill')`\n* `Array.prototype.filter` -> `require('es5-ext/array/#/filter')`\n* `Array.prototype.find` -> `require('es5-ext/array/#/find')`\n* `Array.prototype.findIndex` -> `require('es5-ext/array/#/find-index')`\n* `Array.prototype.keys` -> `require('es5-ext/array/#/keys')`\n* `Array.prototype.map` -> `require('es5-ext/array/#/map')`\n* `Array.prototype.slice` -> `require('es5-ext/array/#/slice')`\n* `Array.prototype.splice` -> `require('es5-ext/array/#/splice')`\n* `Array.prototype.values` -> `require('es5-ext/array/#/values')`\n* `Array.prototype[@@iterator]` -> `require('es5-ext/array/#/@@iterator')`\n* `Math.acosh` -> `require('es5-ext/math/acosh')`\n* `Math.asinh` -> `require('es5-ext/math/asinh')`\n* `Math.atanh` -> `require('es5-ext/math/atanh')`\n* `Math.cbrt` -> `require('es5-ext/math/cbrt')`\n* `Math.clz32` -> `require('es5-ext/math/clz32')`\n* `Math.cosh` -> `require('es5-ext/math/cosh')`\n* `Math.exmp1` -> `require('es5-ext/math/expm1')`\n* `Math.fround` -> `require('es5-ext/math/fround')`\n* `Math.hypot` -> `require('es5-ext/math/hypot')`\n* `Math.imul` -> `require('es5-ext/math/imul')`\n* `Math.log1p` -> `require('es5-ext/math/log1p')`\n* `Math.log2` -> `require('es5-ext/math/log2')`\n* `Math.log10` -> `require('es5-ext/math/log10')`\n* `Math.sign` -> `require('es5-ext/math/sign')`\n* `Math.signh` -> `require('es5-ext/math/signh')`\n* `Math.tanh` -> `require('es5-ext/math/tanh')`\n* `Math.trunc` -> `require('es5-ext/math/trunc')`\n* `Number.EPSILON` -> `require('es5-ext/number/epsilon')`\n* `Number.MAX_SAFE_INTEGER` -> `require('es5-ext/number/max-safe-integer')`\n* `Number.MIN_SAFE_INTEGER` -> `require('es5-ext/number/min-safe-integer')`\n* `Number.isFinite` -> `require('es5-ext/number/is-finite')`\n* `Number.isInteger` -> `require('es5-ext/number/is-integer')`\n* `Number.isNaN` -> `require('es5-ext/number/is-nan')`\n* `Number.isSafeInteger` -> `require('es5-ext/number/is-safe-integer')`\n* `Object.assign` -> `require('es5-ext/object/assign')`\n* `Object.keys` -> `require('es5-ext/object/keys')`\n* `Object.setPrototypeOf` -> `require('es5-ext/object/set-prototype-of')`\n* `RegExp.prototype.match` -> `require('es5-ext/reg-exp/#/match')`\n* `RegExp.prototype.replace` -> `require('es5-ext/reg-exp/#/replace')`\n* `RegExp.prototype.search` -> `require('es5-ext/reg-exp/#/search')`\n* `RegExp.prototype.split` -> `require('es5-ext/reg-exp/#/split')`\n* `RegExp.prototype.sticky` -> Implement with `require('es5-ext/reg-exp/#/sticky/implement')`, use as function with `require('es5-ext/reg-exp/#/is-sticky')`\n* `RegExp.prototype.unicode` -> Implement with `require('es5-ext/reg-exp/#/unicode/implement')`, use as function with `require('es5-ext/reg-exp/#/is-unicode')`\n* `String.fromCodePoint` -> `require('es5-ext/string/from-code-point')`\n* `String.raw` -> `require('es5-ext/string/raw')`\n* `String.prototype.codePointAt` -> `require('es5-ext/string/#/code-point-at')`\n* `String.prototype.contains` -> `require('es5-ext/string/#/contains')`\n* `String.prototype.endsWith` -> `require('es5-ext/string/#/ends-with')`\n* `String.prototype.normalize` -> `require('es5-ext/string/#/normalize')`\n* `String.prototype.repeat` -> `require('es5-ext/string/#/repeat')`\n* `String.prototype.startsWith` -> `require('es5-ext/string/#/starts-with')`\n* `String.prototype[@@iterator]` -> `require('es5-ext/string/#/@@iterator')`\n\n#### Non ECMAScript standard features\n\n**es5-ext** provides also other utils, and implements them as if they were proposed for a standard. It mostly offers methods (not functions) which can directly be assigned to native prototypes:\n\n```javascript\nObject.defineProperty(Function.prototype, \"partial\", {\n\tvalue: require(\"es5-ext/function/#/partial\"),\n\tconfigurable: true,\n\tenumerable: false,\n\twritable: true\n});\nObject.defineProperty(Array.prototype, \"flatten\", {\n\tvalue: require(\"es5-ext/array/#/flatten\"),\n\tconfigurable: true,\n\tenumerable: false,\n\twritable: true\n});\nObject.defineProperty(String.prototype, \"capitalize\", {\n\tvalue: require(\"es5-ext/string/#/capitalize\"),\n\tconfigurable: true,\n\tenumerable: false,\n\twritable: true\n});\n```\n\nSee [es5-extend](https://github.com/wookieb/es5-extend#es5-extend), a great utility that automatically will extend natives for you.\n\n**Important:** Remember to **not** extend natives in scope of generic reusable packages (e.g. ones you intend to publish to npm). Extending natives is fine **only** if you're the _owner_ of the global scope, so e.g. in final project you lead development of.\n\nWhen you're in situation when native extensions are not good idea, then you should use methods indirectly:\n\n```javascript\nvar flatten = require(\"es5-ext/array/#/flatten\");\n\nflatten.call([1, [2, [3, 4]]]); // [1, 2, 3, 4]\n```\n\nfor better convenience you can turn methods into functions:\n\n```javascript\nvar call = Function.prototype.call;\nvar flatten = call.bind(require(\"es5-ext/array/#/flatten\"));\n\nflatten([1, [2, [3, 4]]]); // [1, 2, 3, 4]\n```\n\nYou can configure custom toolkit (like [underscorejs](http://underscorejs.org/)), and use it throughout your application\n\n```javascript\nvar util = {};\nutil.partial = call.bind(require(\"es5-ext/function/#/partial\"));\nutil.flatten = call.bind(require(\"es5-ext/array/#/flatten\"));\nutil.startsWith = call.bind(require(\"es5-ext/string/#/starts-with\"));\n\nutil.flatten([1, [2, [3, 4]]]); // [1, 2, 3, 4]\n```\n\nAs with native ones most methods are generic and can be run on any type of object.\n\n## API\n\n### Global extensions\n\n#### global _(es5-ext/global)_\n\nObject that represents global scope\n\n### Array Constructor extensions\n\n#### from(arrayLike[, mapFn[, thisArg]]) _(es5-ext/array/from)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.from). \nReturns array representation of _iterable_ or _arrayLike_. If _arrayLike_ is an instance of array, its copy is returned.\n\n#### generate([length[, …fill]]) _(es5-ext/array/generate)_\n\nGenerate an array of pre-given _length_ built of repeated arguments.\n\n#### isPlainArray(x) _(es5-ext/array/is-plain-array)_\n\nReturns true if object is plain array (not instance of one of the Array's extensions).\n\n#### of([…items]) _(es5-ext/array/of)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.of). \nCreate an array from given arguments.\n\n#### toArray(obj) _(es5-ext/array/to-array)_\n\nReturns array representation of `obj`. If `obj` is already an array, `obj` is returned back.\n\n#### validArray(obj) _(es5-ext/array/valid-array)_\n\nReturns `obj` if it's an array, otherwise throws `TypeError`\n\n### Array Prototype extensions\n\n#### arr.binarySearch(compareFn) _(es5-ext/array/#/binary-search)_\n\nIn **sorted** list search for index of item for which _compareFn_ returns value closest to _0_. \nIt's variant of binary search algorithm\n\n#### arr.clear() _(es5-ext/array/#/clear)_\n\nClears the array\n\n#### arr.compact() _(es5-ext/array/#/compact)_\n\nReturns a copy of the context with all non-values (`null` or `undefined`) removed.\n\n#### arr.concat() _(es5-ext/array/#/concat)_\n\n[_Updated with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype.concat). \nES6's version of `concat`. Supports `isConcatSpreadable` symbol, and returns array of same type as the context.\n\n#### arr.contains(searchElement[, position]) _(es5-ext/array/#/contains)_\n\nWhether list contains the given value.\n\n#### arr.copyWithin(target, start[, end]) _(es5-ext/array/#/copy-within)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.copywithin).\n\n#### arr.diff(other) _(es5-ext/array/#/diff)_\n\nReturns the array of elements that are present in context list but not present in other list.\n\n#### arr.eIndexOf(searchElement[, fromIndex]) _(es5-ext/array/#/e-index-of)_\n\n_egal_ version of `indexOf` method. [_SameValueZero_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) logic is used for comparision\n\n#### arr.eLastIndexOf(searchElement[, fromIndex]) _(es5-ext/array/#/e-last-index-of)_\n\n_egal_ version of `lastIndexOf` method. [_SameValueZero_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) logic is used for comparision\n\n#### arr.entries() _(es5-ext/array/#/entries)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype.entries). \nReturns iterator object, which traverses the array. Each value is represented with an array, where first value is an index and second is corresponding to index value.\n\n#### arr.exclusion([…lists]]) _(es5-ext/array/#/exclusion)_\n\nReturns the array of elements that are found only in one of the lists (either context list or list provided in arguments).\n\n#### arr.fill(value[, start, end]) _(es5-ext/array/#/fill)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.fill).\n\n#### arr.filter(callback[, thisArg]) _(es5-ext/array/#/filter)_\n\n[_Updated with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.filter). \nES6's version of `filter`, returns array of same type as the context.\n\n#### arr.find(predicate[, thisArg]) _(es5-ext/array/#/find)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.find). \nReturn first element for which given function returns true\n\n#### arr.findIndex(predicate[, thisArg]) _(es5-ext/array/#/find-index)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.findindex). \nReturn first index for which given function returns true\n\n#### arr.first() _(es5-ext/array/#/first)_\n\nReturns value for first defined index\n\n#### arr.firstIndex() _(es5-ext/array/#/first-index)_\n\nReturns first declared index of the array\n\n#### arr.flatten() _(es5-ext/array/#/flatten)_\n\nReturns flattened version of the array\n\n#### arr.forEachRight(cb[, thisArg]) _(es5-ext/array/#/for-each-right)_\n\n`forEach` starting from last element\n\n#### arr.group(cb[, thisArg]) _(es5-ext/array/#/group)_\n\nGroup list elements by value returned by _cb_ function\n\n#### arr.indexesOf(searchElement[, fromIndex]) _(es5-ext/array/#/indexes-of)_\n\nReturns array of all indexes of given value\n\n#### arr.intersection([…lists]) _(es5-ext/array/#/intersection)_\n\nComputes the array of values that are the intersection of all lists (context list and lists given in arguments)\n\n#### arr.isCopy(other) _(es5-ext/array/#/is-copy)_\n\nReturns true if both context and _other_ lists have same content\n\n#### arr.isUniq() _(es5-ext/array/#/is-uniq)_\n\nReturns true if all values in array are unique\n\n#### arr.keys() _(es5-ext/array/#/keys)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype.keys). \nReturns iterator object, which traverses all array indexes.\n\n#### arr.last() _(es5-ext/array/#/last)_\n\nReturns value of last defined index\n\n#### arr.lastIndex() _(es5-ext/array/#/last)_\n\nReturns last defined index of the array\n\n#### arr.map(callback[, thisArg]) _(es5-ext/array/#/map)_\n\n[_Updated with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.map). \nES6's version of `map`, returns array of same type as the context.\n\n#### arr.remove(value[, …valuen]) _(es5-ext/array/#/remove)_\n\nRemove values from the array\n\n#### arr.separate(sep) _(es5-ext/array/#/separate)_\n\nReturns array with items separated with `sep` value\n\n#### arr.slice(callback[, thisArg]) _(es5-ext/array/#/slice)_\n\n[_Updated with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.slice). \nES6's version of `slice`, returns array of same type as the context.\n\n#### arr.someRight(cb[, thisArg]) _(es5-ext/array/#/someRight)_\n\n`some` starting from last element\n\n#### arr.splice(callback[, thisArg]) _(es5-ext/array/#/splice)_\n\n[_Updated with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.splice). \nES6's version of `splice`, returns array of same type as the context.\n\n#### arr.uniq() _(es5-ext/array/#/uniq)_\n\nReturns duplicate-free version of the array\n\n#### arr.values() _(es5-ext/array/#/values)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype.values). \nReturns iterator object which traverses all array values.\n\n#### arr[@@iterator] _(es5-ext/array/#/@@iterator)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype-@@iterator). \nReturns iterator object which traverses all array values.\n\n### Boolean Constructor extensions\n\n#### isBoolean(x) _(es5-ext/boolean/is-boolean)_\n\nWhether value is boolean\n\n### Date Constructor extensions\n\n#### isDate(x) _(es5-ext/date/is-date)_\n\nWhether value is date instance\n\n#### validDate(x) _(es5-ext/date/valid-date)_\n\nIf given object is not date throw TypeError in other case return it.\n\n### Date Prototype extensions\n\n#### date.copy(date) _(es5-ext/date/#/copy)_\n\nReturns a copy of the date object\n\n#### date.daysInMonth() _(es5-ext/date/#/days-in-month)_\n\nReturns number of days of date's month\n\n#### date.floorDay() _(es5-ext/date/#/floor-day)_\n\nSets the date time to 00:00:00.000\n\n#### date.floorMonth() _(es5-ext/date/#/floor-month)_\n\nSets date day to 1 and date time to 00:00:00.000\n\n#### date.floorYear() _(es5-ext/date/#/floor-year)_\n\nSets date month to 0, day to 1 and date time to 00:00:00.000\n\n#### date.format(pattern) _(es5-ext/date/#/format)_\n\nFormats date up to given string. Supported patterns:\n\n* `%Y` - Year with century, 1999, 2003\n* `%y` - Year without century, 99, 03\n* `%m` - Month, 01..12\n* `%d` - Day of the month 01..31\n* `%H` - Hour (24-hour clock), 00..23\n* `%M` - Minute, 00..59\n* `%S` - Second, 00..59\n* `%L` - Milliseconds, 000..999\n\n### Error Constructor extensions\n\n#### custom(message/_, code, ext_/) _(es5-ext/error/custom)_\n\nCreates custom error object, optinally extended with `code` and other extension properties (provided with `ext` object)\n\n#### isError(x) _(es5-ext/error/is-error)_\n\nWhether value is an error (instance of `Error`).\n\n#### validError(x) _(es5-ext/error/valid-error)_\n\nIf given object is not error throw TypeError in other case return it.\n\n### Error Prototype extensions\n\n#### err.throw() _(es5-ext/error/#/throw)_\n\nThrows error\n\n### Function Constructor extensions\n\nSome of the functions were inspired by [Functional JavaScript](http://osteele.com/sources/javascript/functional/) project by Olivier Steele\n\n#### constant(x) _(es5-ext/function/constant)_\n\nReturns a constant function that returns pregiven argument\n\n_k(x)(y) =def x_\n\n#### identity(x) _(es5-ext/function/identity)_\n\nIdentity function. Returns first argument\n\n_i(x) =def x_\n\n#### invoke(name[, …args]) _(es5-ext/function/invoke)_\n\nReturns a function that takes an object as an argument, and applies object's\n_name_ method to arguments. \n_name_ can be name of the method or method itself.\n\n_invoke(name, …args)(object, …args2) =def object\\[name\\]\\(…args, …args2\\)_\n\n#### isArguments(x) _(es5-ext/function/is-arguments)_\n\nWhether value is arguments object\n\n#### isFunction(arg) _(es5-ext/function/is-function)_\n\nWhether value is instance of function\n\n#### noop() _(es5-ext/function/noop)_\n\nNo operation function\n\n#### pluck(name) _(es5-ext/function/pluck)_\n\nReturns a function that takes an object, and returns the value of its _name_\nproperty\n\n_pluck(name)(obj) =def obj[name]_\n\n#### validFunction(arg) _(es5-ext/function/valid-function)_\n\nIf given object is not function throw TypeError in other case return it.\n\n### Function Prototype extensions\n\nSome of the methods were inspired by [Functional JavaScript](http://osteele.com/sources/javascript/functional/) project by Olivier Steele\n\n#### fn.compose([…fns]) _(es5-ext/function/#/compose)_\n\nApplies the functions in reverse argument-list order.\n\n_f1.compose(f2, f3, f4)(…args) =def f1(f2(f3(f4(…arg))))_\n\n#### fn.copy() _(es5-ext/function/#/copy)_\n\nProduces copy of given function\n\n#### fn.curry([n]) _(es5-ext/function/#/curry)_\n\nInvoking the function returned by this function only _n_ arguments are passed to the underlying function. If the underlying function is not saturated, the result is a function that passes all its arguments to the underlying function. \nIf _n_ is not provided then it defaults to context function length\n\n_f.curry(4)(arg1, arg2)(arg3)(arg4) =def f(arg1, args2, arg3, arg4)_\n\n#### fn.lock([…args]) _(es5-ext/function/#/lock)_\n\nReturns a function that applies the underlying function to _args_, and ignores its own arguments.\n\n_f.lock(…args)(…args2) =def f(…args)_\n\n_Named after it's counterpart in Google Closure_\n\n#### fn.not() _(es5-ext/function/#/not)_\n\nReturns a function that returns boolean negation of value returned by underlying function.\n\n_f.not()(…args) =def !f(…args)_\n\n#### fn.partial([…args]) _(es5-ext/function/#/partial)_\n\nReturns a function that when called will behave like context function called with initially passed arguments. If more arguments are suplilied, they are appended to initial args.\n\n_f.partial(…args1)(…args2) =def f(…args1, …args2)_\n\n#### fn.spread() _(es5-ext/function/#/spread)_\n\nReturns a function that applies underlying function with first list argument\n\n_f.match()(args) =def f.apply(null, args)_\n\n#### fn.toStringTokens() _(es5-ext/function/#/to-string-tokens)_\n\nSerializes function into two (arguments and body) string tokens. Result is plain object with `args` and `body` properties.\n\n### Math extensions\n\n#### acosh(x) _(es5-ext/math/acosh)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.acosh).\n\n#### asinh(x) _(es5-ext/math/asinh)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.asinh).\n\n#### atanh(x) _(es5-ext/math/atanh)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.atanh).\n\n#### cbrt(x) _(es5-ext/math/cbrt)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.cbrt).\n\n#### clz32(x) _(es5-ext/math/clz32)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.clz32).\n\n#### cosh(x) _(es5-ext/math/cosh)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.cosh).\n\n#### expm1(x) _(es5-ext/math/expm1)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.expm1).\n\n#### fround(x) _(es5-ext/math/fround)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.fround).\n\n#### hypot([…values]) _(es5-ext/math/hypot)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.hypot).\n\n#### imul(x, y) _(es5-ext/math/imul)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.imul).\n\n#### log1p(x) _(es5-ext/math/log1p)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.log1p).\n\n#### log2(x) _(es5-ext/math/log2)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.log2).\n\n#### log10(x) _(es5-ext/math/log10)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.log10).\n\n#### sign(x) _(es5-ext/math/sign)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.sign).\n\n#### sinh(x) _(es5-ext/math/sinh)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.sinh).\n\n#### tanh(x) _(es5-ext/math/tanh)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.tanh).\n\n#### trunc(x) _(es5-ext/math/trunc)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.trunc).\n\n### Number Constructor extensions\n\n#### EPSILON _(es5-ext/number/epsilon)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.epsilon).\n\nThe difference between 1 and the smallest value greater than 1 that is representable as a Number value, which is approximately 2.2204460492503130808472633361816 x 10-16.\n\n#### isFinite(x) _(es5-ext/number/is-finite)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.isfinite). \nWhether value is finite. Differs from global isNaN that it doesn't do type coercion.\n\n#### isInteger(x) _(es5-ext/number/is-integer)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.isinteger). \nWhether value is integer.\n\n#### isNaN(x) _(es5-ext/number/is-nan)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.isnan). \nWhether value is NaN. Differs from global isNaN that it doesn't do type coercion.\n\n#### isNumber(x) _(es5-ext/number/is-number)_\n\nWhether given value is number\n\n#### isSafeInteger(x) _(es5-ext/number/is-safe-integer)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.issafeinteger).\n\n#### MAX*SAFE_INTEGER *(es5-ext/number/max-safe-integer)\\_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.maxsafeinteger). \nThe value of Number.MAX_SAFE_INTEGER is 9007199254740991.\n\n#### MIN*SAFE_INTEGER *(es5-ext/number/min-safe-integer)\\_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.minsafeinteger). \nThe value of Number.MIN_SAFE_INTEGER is -9007199254740991 (253-1).\n\n#### toInteger(x) _(es5-ext/number/to-integer)_\n\nConverts value to integer\n\n#### toPosInteger(x) _(es5-ext/number/to-pos-integer)_\n\nConverts value to positive integer. If provided value is less than 0, then 0 is returned\n\n#### toUint32(x) _(es5-ext/number/to-uint32)_\n\nConverts value to unsigned 32 bit integer. This type is used for array lengths.\nSee: http://www.2ality.com/2012/02/js-integers.html\n\n### Number Prototype extensions\n\n#### num.pad(length[, precision]) _(es5-ext/number/#/pad)_\n\nPad given number with zeros. Returns string\n\n### Object Constructor extensions\n\n#### assign(target, source[, …sourcen]) _(es5-ext/object/assign)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign). \nExtend _target_ by enumerable own properties of other objects. If properties are already set on target object, they will be overwritten.\n\n#### clear(obj) _(es5-ext/object/clear)_\n\nRemove all enumerable own properties of the object\n\n#### compact(obj) _(es5-ext/object/compact)_\n\nReturns copy of the object with all enumerable properties that have no falsy values\n\n#### compare(obj1, obj2) _(es5-ext/object/compare)_\n\nUniversal cross-type compare function. To be used for e.g. array sort.\n\n#### copy(obj) _(es5-ext/object/copy)_\n\nReturns copy of the object with all enumerable properties.\n\n#### copyDeep(obj) _(es5-ext/object/copy-deep)_\n\nReturns deep copy of the object with all enumerable properties.\n\n#### count(obj) _(es5-ext/object/count)_\n\nCounts number of enumerable own properties on object\n\n#### create(obj[, properties]) _(es5-ext/object/create)_\n\n`Object.create` alternative that provides workaround for [V8 issue](http://code.google.com/p/v8/issues/detail?id=2804).\n\nWhen `null` is provided as a prototype, it's substituted with specially prepared object that derives from Object.prototype but has all Object.prototype properties shadowed with undefined.\n\nIt's quirky solution that allows us to have plain objects with no truthy properties but with turnable prototype.\n\nUse only for objects that you plan to switch prototypes of and be aware of limitations of this workaround.\n\n#### eq(x, y) _(es5-ext/object/eq)_\n\nWhether two values are equal, using [_SameValueZero_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) algorithm.\n\n#### every(obj, cb[, thisArg[, compareFn]]) _(es5-ext/object/every)_\n\nAnalogous to Array.prototype.every. Returns true if every key-value pair in this object satisfies the provided testing function. \nOptionally _compareFn_ can be provided which assures that keys are tested in given order. If provided _compareFn_ is equal to `true`, then order is alphabetical (by key).\n\n#### filter(obj, cb[, thisArg]) _(es5-ext/object/filter)_\n\nAnalogous to Array.prototype.filter. Returns new object with properites for which _cb_ function returned truthy value.\n\n#### firstKey(obj) _(es5-ext/object/first-key)_\n\nReturns first enumerable key of the object, as keys are unordered by specification, it can be any key of an object.\n\n#### flatten(obj) _(es5-ext/object/flatten)_\n\nReturns new object, with flatten properties of input object\n\n_flatten({ a: { b: 1 }, c: { d: 1 } }) =def { b: 1, d: 1 }_\n\n#### forEach(obj, cb[, thisArg[, compareFn]]) _(es5-ext/object/for-each)_\n\nAnalogous to Array.prototype.forEach. Calls a function for each key-value pair found in object\nOptionally _compareFn_ can be provided which assures that properties are iterated in given order. If provided _compareFn_ is equal to `true`, then order is alphabetical (by key).\n\n#### getPropertyNames() _(es5-ext/object/get-property-names)_\n\nGet all (not just own) property names of the object\n\n#### is(x, y) _(es5-ext/object/is)_\n\nWhether two values are equal, using [_SameValue_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) algorithm.\n\n#### isArrayLike(x) _(es5-ext/object/is-array-like)_\n\nWhether object is array-like object\n\n#### isCopy(x, y) _(es5-ext/object/is-copy)_\n\nTwo values are considered a copy of same value when all of their own enumerable properties have same values.\n\n#### isCopyDeep(x, y) _(es5-ext/object/is-copy-deep)_\n\nDeep comparision of objects\n\n#### isEmpty(obj) _(es5-ext/object/is-empty)_\n\nTrue if object doesn't have any own enumerable property\n\n#### isObject(arg) _(es5-ext/object/is-object)_\n\nWhether value is not primitive\n\n#### isPlainObject(arg) _(es5-ext/object/is-plain-object)_\n\nWhether object is plain object, its protototype should be Object.prototype and it cannot be host object.\n\n#### keyOf(obj, searchValue) _(es5-ext/object/key-of)_\n\nSearch object for value\n\n#### keys(obj) _(es5-ext/object/keys)_\n\n[_Updated with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.keys). \nES6's version of `keys`, doesn't throw on primitive input\n\n#### map(obj, cb[, thisArg]) _(es5-ext/object/map)_\n\nAnalogous to Array.prototype.map. Creates a new object with properties which values are results of calling a provided function on every key-value pair in this object.\n\n#### mapKeys(obj, cb[, thisArg]) _(es5-ext/object/map-keys)_\n\nCreate new object with same values, but remapped keys\n\n#### mixin(target, source) _(es5-ext/object/mixin)_\n\nExtend _target_ by all own properties of other objects. Properties found in both objects will be overwritten (unless they're not configurable and cannot be overwritten).\n_It was for a moment part of ECMAScript 6 draft._\n\n#### mixinPrototypes(target, …source]) _(es5-ext/object/mixin-prototypes)_\n\nExtends _target_, with all source and source's prototype properties.\nUseful as an alternative for `setPrototypeOf` in environments in which it cannot be shimmed (no `__proto__` support).\n\n#### normalizeOptions(options) _(es5-ext/object/normalize-options)_\n\nNormalizes options object into flat plain object.\n\nUseful for functions in which we either need to keep options object for future reference or need to modify it for internal use.\n\n* It never returns input `options` object back (always a copy is created)\n* `options` can be undefined in such case empty plain object is returned.\n* Copies all enumerable properties found down prototype chain.\n\n#### primitiveSet([…names]) _(es5-ext/object/primitive-set)_\n\nCreates `null` prototype based plain object, and sets on it all property names provided in arguments to true.\n\n#### safeTraverse(obj[, …names]) _(es5-ext/object/safe-traverse)_\n\nSafe navigation of object properties. See http://wiki.ecmascript.org/doku.php?id=strawman:existential_operator\n\n#### serialize(value) _(es5-ext/object/serialize)_\n\nSerialize value into string. Differs from [JSON.stringify](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) that it serializes also dates, functions and regular expresssions.\n\n#### setPrototypeOf(object, proto) _(es5-ext/object/set-prototype-of)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.setprototypeof). \nIf native version is not provided, it depends on existence of `__proto__` functionality, if it's missing, `null` instead of function is exposed.\n\n#### some(obj, cb[, thisArg[, compareFn]]) _(es5-ext/object/some)_\n\nAnalogous to Array.prototype.some Returns true if any key-value pair satisfies the provided\ntesting function. \nOptionally _compareFn_ can be provided which assures that keys are tested in given order. If provided _compareFn_ is equal to `true`, then order is alphabetical (by key).\n\n#### toArray(obj[, cb[, thisArg[, compareFn]]]) _(es5-ext/object/to-array)_\n\nCreates an array of results of calling a provided function on every key-value pair in this object. \nOptionally _compareFn_ can be provided which assures that results are added in given order. If provided _compareFn_ is equal to `true`, then order is alphabetical (by key).\n\n#### unserialize(str) _(es5-ext/object/unserialize)_\n\nUserializes value previously serialized with [serialize](#serializevalue-es5-extobjectserialize)\n\n#### validCallable(x) _(es5-ext/object/valid-callable)_\n\nIf given object is not callable throw TypeError in other case return it.\n\n#### validObject(x) _(es5-ext/object/valid-object)_\n\nThrows error if given value is not an object, otherwise it is returned.\n\n#### validValue(x) _(es5-ext/object/valid-value)_\n\nThrows error if given value is `null` or `undefined`, otherwise returns value.\n\n### RegExp Constructor extensions\n\n#### escape(str) _(es5-ext/reg-exp/escape)_\n\nEscapes string to be used in regular expression\n\n#### isRegExp(x) _(es5-ext/reg-exp/is-reg-exp)_\n\nWhether object is regular expression\n\n#### validRegExp(x) _(es5-ext/reg-exp/valid-reg-exp)_\n\nIf object is regular expression it is returned, otherwise TypeError is thrown.\n\n### RegExp Prototype extensions\n\n#### re.isSticky(x) _(es5-ext/reg-exp/#/is-sticky)_\n\nWhether regular expression has `sticky` flag.\n\nIt's to be used as counterpart to [regExp.sticky](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-get-regexp.prototype.sticky) if it's not implemented.\n\n#### re.isUnicode(x) _(es5-ext/reg-exp/#/is-unicode)_\n\nWhether regular expression has `unicode` flag.\n\nIt's to be used as counterpart to [regExp.unicode](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-get-regexp.prototype.unicode) if it's not implemented.\n\n#### re.match(string) _(es5-ext/reg-exp/#/match)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.match).\n\n#### re.replace(string, replaceValue) _(es5-ext/reg-exp/#/replace)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.replace).\n\n#### re.search(string) _(es5-ext/reg-exp/#/search)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.search).\n\n#### re.split(string) _(es5-ext/reg-exp/#/search)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.split).\n\n#### re.sticky _(es5-ext/reg-exp/#/sticky/implement)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.sticky). \nIt's a getter, so only `implement` and `is-implemented` modules are provided.\n\n#### re.unicode _(es5-ext/reg-exp/#/unicode/implement)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.unicode). \nIt's a getter, so only `implement` and `is-implemented` modules are provided.\n\n### String Constructor extensions\n\n#### formatMethod(fMap) _(es5-ext/string/format-method)_\n\nCreates format method. It's used e.g. to create `Date.prototype.format` method\n\n#### fromCodePoint([…codePoints]) _(es5-ext/string/from-code-point)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.fromcodepoint)\n\n#### isString(x) _(es5-ext/string/is-string)_\n\nWhether object is string\n\n#### randomUniq() _(es5-ext/string/random-uniq)_\n\nReturns randomly generated id, with guarantee of local uniqueness (no same id will be returned twice)\n\n#### raw(callSite[, …substitutions]) _(es5-ext/string/raw)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.raw)\n\n### String Prototype extensions\n\n#### str.at(pos) _(es5-ext/string/#/at)_\n\n_Proposed for ECMAScript 6/7 standard, but not (yet) in a draft_\n\nReturns a string at given position in Unicode-safe manner.\nBased on [implementation by Mathias Bynens](https://github.com/mathiasbynens/String.prototype.at).\n\n#### str.camelToHyphen() _(es5-ext/string/#/camel-to-hyphen)_\n\nConvert camelCase string to hyphen separated, e.g. one-two-three -> oneTwoThree.\nUseful when converting names from js property convention into filename convention.\n\n#### str.capitalize() _(es5-ext/string/#/capitalize)_\n\nCapitalize first character of a string\n\n#### str.caseInsensitiveCompare(str) _(es5-ext/string/#/case-insensitive-compare)_\n\nCase insensitive compare\n\n#### str.codePointAt(pos) _(es5-ext/string/#/code-point-at)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.codepointat)\n\nBased on [implementation by Mathias Bynens](https://github.com/mathiasbynens/String.prototype.codePointAt).\n\n#### str.contains(searchString[, position]) _(es5-ext/string/#/contains)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.contains)\n\nWhether string contains given string.\n\n#### str.endsWith(searchString[, endPosition]) _(es5-ext/string/#/ends-with)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.endswith). \nWhether strings ends with given string\n\n#### str.hyphenToCamel() _(es5-ext/string/#/hyphen-to-camel)_\n\nConvert hyphen separated string to camelCase, e.g. one-two-three -> oneTwoThree.\nUseful when converting names from filename convention to js property name convention.\n\n#### str.indent(str[, count]) _(es5-ext/string/#/indent)_\n\nIndents each line with provided _str_ (if _count_ given then _str_ is repeated _count_ times).\n\n#### str.last() _(es5-ext/string/#/last)_\n\nReturn last character\n\n#### str.normalize([form]) _(es5-ext/string/#/normalize)_\n\n[_Introduced with ECMAScript 6_](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize). \nReturns the Unicode Normalization Form of a given string. \nBased on Matsuza's version. Code used for integrated shim can be found at [github.com/walling/unorm](https://github.com/walling/unorm/blob/master/lib/unorm.js)\n\n#### str.pad(fill[, length]) _(es5-ext/string/#/pad)_\n\nPad string with _fill_.\nIf _length_ si given than _fill_ is reapated _length_ times.\nIf _length_ is negative then pad is applied from right.\n\n#### str.repeat(n) _(es5-ext/string/#/repeat)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.repeat). \nRepeat given string _n_ times\n\n#### str.plainReplace(search, replace) _(es5-ext/string/#/plain-replace)_\n\nSimple `replace` version. Doesn't support regular expressions. Replaces just first occurrence of search string. Doesn't support insert patterns, therefore it is safe to replace text with text obtained programmatically (there's no need for additional _$_ characters escape in such case).\n\n#### str.plainReplaceAll(search, replace) _(es5-ext/string/#/plain-replace-all)_\n\nSimple `replace` version. Doesn't support regular expressions. Replaces all occurrences of search string. Doesn't support insert patterns, therefore it is safe to replace text with text obtained programmatically (there's no need for additional _$_ characters escape in such case).\n\n#### str.startsWith(searchString[, position]) _(es5-ext/string/#/starts-with)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.startswith). \nWhether strings starts with given string\n\n#### str[@@iterator] _(es5-ext/string/#/@@iterator)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype-@@iterator). \nReturns iterator object which traverses all string characters (with respect to unicode symbols)\n\n### Tests\n\n $ npm test\n\n[nix-build-image]: https://semaphoreci.com/api/v1/medikoo-org/es5-ext/branches/master/shields_badge.svg\n[nix-build-url]: https://semaphoreci.com/medikoo-org/es5-ext\n[win-build-image]: https://ci.appveyor.com/api/projects/status/3jox67ksw3p8hkwh?svg=true\n[win-build-url]: https://ci.appveyor.com/project/medikoo/es5-ext\n[transpilation-image]: https://img.shields.io/badge/transpilation-free-brightgreen.svg\n[npm-image]: https://img.shields.io/npm/v/es5-ext.svg\n[npm-url]: https://www.npmjs.com/package/es5-ext\n", - "readmeFilename": "README.md", - "bugs": "[Circular]", - "homepage": "https://github.com/medikoo/es5-ext#readme", - "_id": "es5-ext@0.10.45", - "_requested": { - "type": "version", - "registry": true, - "raw": "es5-ext@0.10.45", - "name": "es5-ext", - "escapedName": "es5-ext", - "rawSpec": "0.10.45", - "saveSpec": "[Circular]", - "fetchSpec": "0.10.45" - }, - "_spec": "0.10.45", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": "[Circular]", - "optionalDependencies": "[Circular]", - "_dependencies": "[Circular]", - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/es5-ext", - "error": "[Circular]", - "extraneous": false, - "_deduped": "es5-ext" - } - }, - "devDependencies": { - "tad": "^0.2.4", - "xlint": "^0.2.2", - "xlint-jslint-medikoo": "^0.1.4" - }, - "scripts": { - "lint": "node node_modules/xlint/bin/xlint --linter=node_modules/xlint-jslint-medikoo/index.js --no-cache --no-stream", - "lint-console": "node node_modules/xlint/bin/xlint --linter=node_modules/xlint-jslint-medikoo/index.js --watch", - "test": "node node_modules/tad/bin/tad" - }, - "license": "MIT", - "_resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", - "_integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", - "_from": "d@1.0.0", - "readme": "# D\n## Property descriptor factory\n\n_Originally derived from [es5-ext](https://github.com/medikoo/es5-ext) package._\n\nDefining properties with descriptors is very verbose:\n\n```javascript\nvar Account = function () {};\nObject.defineProperties(Account.prototype, {\n deposit: { value: function () {\n /* ... */\n }, configurable: true, enumerable: false, writable: true },\n withdraw: { value: function () {\n /* ... */\n }, configurable: true, enumerable: false, writable: true },\n balance: { get: function () {\n /* ... */\n }, configurable: true, enumerable: false }\n});\n```\n\nD cuts that to:\n\n```javascript\nvar d = require('d');\n\nvar Account = function () {};\nObject.defineProperties(Account.prototype, {\n deposit: d(function () {\n /* ... */\n }),\n withdraw: d(function () {\n /* ... */\n }),\n balance: d.gs(function () {\n /* ... */\n })\n});\n```\n\nBy default, created descriptor follow characteristics of native ES5 properties, and defines values as:\n\n```javascript\n{ configurable: true, enumerable: false, writable: true }\n```\n\nYou can overwrite it by preceding _value_ argument with instruction:\n```javascript\nd('c', value); // { configurable: true, enumerable: false, writable: false }\nd('ce', value); // { configurable: true, enumerable: true, writable: false }\nd('e', value); // { configurable: false, enumerable: true, writable: false }\n\n// Same way for get/set:\nd.gs('e', value); // { configurable: false, enumerable: true }\n```\n\n### Installation\n\n\t$ npm install d\n\t\nTo port it to Browser or any other (non CJS) environment, use your favorite CJS bundler. No favorite yet? Try: [Browserify](http://browserify.org/), [Webmake](https://github.com/medikoo/modules-webmake) or [Webpack](http://webpack.github.io/)\n\n### Other utilities\n\n#### autoBind(obj, props) _(d/auto-bind)_\n\nDefine methods which will be automatically bound to its instances\n\n```javascript\nvar d = require('d');\nvar autoBind = require('d/auto-bind');\n\nvar Foo = function () { this._count = 0; };\nObject.defineProperties(Foo.prototype, autoBind({\n increment: d(function () { ++this._count; });\n}));\n\nvar foo = new Foo();\n\n// Increment foo counter on each domEl click\ndomEl.addEventListener('click', foo.increment, false);\n```\n\n#### lazy(obj, props) _(d/lazy)_\n\nDefine lazy properties, which will be resolved on first access\n\n```javascript\nvar d = require('d');\nvar lazy = require('d/lazy');\n\nvar Foo = function () {};\nObject.defineProperties(Foo.prototype, lazy({\n items: d(function () { return []; })\n}));\n\nvar foo = new Foo();\nfoo.items.push(1, 2); // foo.items array created and defined directly on foo\n```\n\n## Tests [![Build Status](https://travis-ci.org/medikoo/d.png)](https://travis-ci.org/medikoo/d)\n\n\t$ npm test\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/medikoo/d/issues" - }, - "homepage": "https://github.com/medikoo/d#readme", - "_id": "d@1.0.0", - "_requested": { - "type": "version", - "registry": true, - "raw": "d@1.0.0", - "name": "d", - "escapedName": "d", - "rawSpec": "1.0.0", - "saveSpec": "[Circular]", - "fetchSpec": "1.0.0" - }, - "_spec": "1.0.0", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "d@1.0.0", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "optionalDependencies": {}, - "_dependencies": { - "es5-ext": "^0.10.9" - }, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/es6-symbol/node_modules/d", - "error": "[Circular]", - "extraneous": false - } - }, - "devDependencies": "[Circular]", - "scripts": "[Circular]", - "license": "MIT", - "_resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", - "_integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", - "_from": "es6-symbol@3.1.1", - "readme": "# es6-symbol\n## ECMAScript 6 Symbol polyfill\n\nFor more information about symbols see following links\n- [Symbols in ECMAScript 6 by Axel Rauschmayer](http://www.2ality.com/2014/12/es6-symbols.html)\n- [MDN Documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol)\n- [Specification](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-symbol-constructor)\n\n### Limitations\n\nUnderneath it uses real string property names which can easily be retrieved, however accidental collision with other property names is unlikely.\n\n### Usage\n\nIf you'd like to use native version when it exists and fallback to [ponyfill](https://ponyfill.com) if it doesn't, use *es6-symbol* as following:\n\n```javascript\nvar Symbol = require('es6-symbol');\n```\n\nIf you want to make sure your environment implements `Symbol` globally, do:\n\n```javascript\nrequire('es6-symbol/implement');\n```\n\nIf you strictly want to use polyfill even if native `Symbol` exists (hard to find a good reason for that), do:\n\n```javascript\nvar Symbol = require('es6-symbol/polyfill');\n```\n\n#### API\n\nBest is to refer to [specification](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-symbol-objects). Still if you want quick look, follow examples:\n\n```javascript\nvar Symbol = require('es6-symbol');\n\nvar symbol = Symbol('My custom symbol');\nvar x = {};\n\nx[symbol] = 'foo';\nconsole.log(x[symbol]); 'foo'\n\n// Detect iterable:\nvar iterator, result;\nif (possiblyIterable[Symbol.iterator]) {\n iterator = possiblyIterable[Symbol.iterator]();\n result = iterator.next();\n while(!result.done) {\n console.log(result.value);\n result = iterator.next();\n }\n}\n```\n\n### Installation\n#### NPM\n\nIn your project path:\n\n\t$ npm install es6-symbol\n\n##### Browser\n\nTo port it to Browser or any other (non CJS) environment, use your favorite CJS bundler. No favorite yet? Try: [Browserify](http://browserify.org/), [Webmake](https://github.com/medikoo/modules-webmake) or [Webpack](http://webpack.github.io/)\n\n## Tests [![Build Status](https://travis-ci.org/medikoo/es6-symbol.png)](https://travis-ci.org/medikoo/es6-symbol)\n\n\t$ npm test\n", - "readmeFilename": "README.md", - "bugs": "[Circular]", - "homepage": "https://github.com/medikoo/es6-symbol#readme", - "_id": "es6-symbol@3.1.1", - "_requested": { - "type": "version", - "registry": true, - "raw": "es6-symbol@3.1.1", - "name": "es6-symbol", - "escapedName": "es6-symbol", - "rawSpec": "3.1.1", - "saveSpec": "[Circular]", - "fetchSpec": "3.1.1" - }, - "_spec": "3.1.1", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": "[Circular]", - "optionalDependencies": "[Circular]", - "_dependencies": "[Circular]", - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/es6-symbol", - "error": "[Circular]", - "extraneous": false - }, - "next-tick": { - "name": "next-tick", - "version": "1.0.0", - "description": "Environment agnostic nextTick polyfill", - "author": { - "name": "Mariusz Nowak", - "email": "medyk@medikoo.com", - "url": "http://www.medikoo.com/" - }, - "keywords": [ - "nexttick", - "setImmediate", - "setTimeout", - "async" - ], - "repository": { - "type": "git", - "url": "git://github.com/medikoo/next-tick.git" - }, - "devDependencies": { - "tad": "^0.2.4", - "xlint": "^0.2.2", - "xlint-jslint-medikoo": "^0.1.4" - }, - "scripts": { - "lint": "node node_modules/xlint/bin/xlint --linter=node_modules/xlint-jslint-medikoo/index.js --no-cache --no-stream", - "lint-console": "node node_modules/xlint/bin/xlint --linter=node_modules/xlint-jslint-medikoo/index.js --watch", - "test": "node node_modules/tad/bin/tad" - }, - "license": "MIT", - "_resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", - "_integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", - "_from": "next-tick@1.0.0", - "readme": "# next-tick\n## Environment agnostic nextTick polyfill\n\nTo be used in environment agnostic modules that need nextTick functionality.\n\n- When run in Node.js `process.nextTick` is used\n- In modern browsers microtask resolution is guaranteed by `MutationObserver`\n- In other engines `setImmediate` or `setTimeout(fn, 0)` is used as fallback.\n- If none of the above is supported module resolves to `null`\n\n## Installation\n### NPM\n\nIn your project path:\n\n\t$ npm install next-tick\n\n#### Browser\n\nYou can easily bundle `next-tick` for browser with any CJS bundler, e.g. [modules-webmake](https://github.com/medikoo/modules-webmake)\n\n## Tests [![Build Status](https://api.travis-ci.org/medikoo/next-tick.png?branch=master)](https://travis-ci.org/medikoo/next-tick)\n\n\t$ npm test\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/medikoo/next-tick/issues" - }, - "homepage": "https://github.com/medikoo/next-tick#readme", - "_id": "next-tick@1.0.0", - "_requested": { - "type": "version", - "registry": true, - "raw": "next-tick@1.0.0", - "name": "next-tick", - "escapedName": "next-tick", - "rawSpec": "1.0.0", - "saveSpec": "[Circular]", - "fetchSpec": "1.0.0" - }, - "_spec": "1.0.0", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "next-tick@1.0.0", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "dependencies": {}, - "optionalDependencies": {}, - "_dependencies": {}, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/next-tick", - "error": "[Circular]", - "extraneous": false - } - }, - "devDependencies": "[Circular]", - "eslintConfig": "[Circular]", - "scripts": "[Circular]", - "license": "ISC", - "_resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.45.tgz", - "_integrity": "sha512-FkfM6Vxxfmztilbxxz5UKSD4ICMf5tSpRFtDNtkAhOxZ0EKtX6qwmXNyH/sFyIbX2P/nU5AMiA9jilWsUGJzCQ==", - "_from": "es5-ext@0.10.45", - "readme": "[![Build status][nix-build-image]][nix-build-url]\n[![Windows status][win-build-image]][win-build-url]\n![Transpilation status][transpilation-image]\n[![npm version][npm-image]][npm-url]\n\n# es5-ext\n\n## ECMAScript 5 extensions\n\n### (with respect to ECMAScript 6 standard)\n\nShims for upcoming ES6 standard and other goodies implemented strictly with ECMAScript conventions in mind.\n\nIt's designed to be used in compliant ECMAScript 5 or ECMAScript 6 environments. Older environments are not supported, although most of the features should work with correct ECMAScript 5 shim on board.\n\nWhen used in ECMAScript 6 environment, native implementation (if valid) takes precedence over shims.\n\n### Installation\n\n $ npm install es5-ext\n\nTo port it to Browser or any other (non CJS) environment, use your favorite CJS bundler. No favorite yet? Try: [Browserify](http://browserify.org/), [Webmake](https://github.com/medikoo/modules-webmake) or [Webpack](http://webpack.github.io/)\n\n### Usage\n\n#### ECMAScript 6 features\n\nYou can force ES6 features to be implemented in your environment, e.g. following will assign `from` function to `Array` (only if it's not implemented already).\n\n```javascript\nrequire(\"es5-ext/array/from/implement\");\nArray.from(\"foo\"); // ['f', 'o', 'o']\n```\n\nYou can also access shims directly, without fixing native objects. Following will return native `Array.from` if it's available and fallback to shim if it's not.\n\n```javascript\nvar aFrom = require(\"es5-ext/array/from\");\naFrom(\"foo\"); // ['f', 'o', 'o']\n```\n\nIf you want to use shim unconditionally (even if native implementation exists) do:\n\n```javascript\nvar aFrom = require(\"es5-ext/array/from/shim\");\naFrom(\"foo\"); // ['f', 'o', 'o']\n```\n\n##### List of ES6 shims\n\nIt's about properties introduced with ES6 and those that have been updated in new spec.\n\n* `Array.from` -> `require('es5-ext/array/from')`\n* `Array.of` -> `require('es5-ext/array/of')`\n* `Array.prototype.concat` -> `require('es5-ext/array/#/concat')`\n* `Array.prototype.copyWithin` -> `require('es5-ext/array/#/copy-within')`\n* `Array.prototype.entries` -> `require('es5-ext/array/#/entries')`\n* `Array.prototype.fill` -> `require('es5-ext/array/#/fill')`\n* `Array.prototype.filter` -> `require('es5-ext/array/#/filter')`\n* `Array.prototype.find` -> `require('es5-ext/array/#/find')`\n* `Array.prototype.findIndex` -> `require('es5-ext/array/#/find-index')`\n* `Array.prototype.keys` -> `require('es5-ext/array/#/keys')`\n* `Array.prototype.map` -> `require('es5-ext/array/#/map')`\n* `Array.prototype.slice` -> `require('es5-ext/array/#/slice')`\n* `Array.prototype.splice` -> `require('es5-ext/array/#/splice')`\n* `Array.prototype.values` -> `require('es5-ext/array/#/values')`\n* `Array.prototype[@@iterator]` -> `require('es5-ext/array/#/@@iterator')`\n* `Math.acosh` -> `require('es5-ext/math/acosh')`\n* `Math.asinh` -> `require('es5-ext/math/asinh')`\n* `Math.atanh` -> `require('es5-ext/math/atanh')`\n* `Math.cbrt` -> `require('es5-ext/math/cbrt')`\n* `Math.clz32` -> `require('es5-ext/math/clz32')`\n* `Math.cosh` -> `require('es5-ext/math/cosh')`\n* `Math.exmp1` -> `require('es5-ext/math/expm1')`\n* `Math.fround` -> `require('es5-ext/math/fround')`\n* `Math.hypot` -> `require('es5-ext/math/hypot')`\n* `Math.imul` -> `require('es5-ext/math/imul')`\n* `Math.log1p` -> `require('es5-ext/math/log1p')`\n* `Math.log2` -> `require('es5-ext/math/log2')`\n* `Math.log10` -> `require('es5-ext/math/log10')`\n* `Math.sign` -> `require('es5-ext/math/sign')`\n* `Math.signh` -> `require('es5-ext/math/signh')`\n* `Math.tanh` -> `require('es5-ext/math/tanh')`\n* `Math.trunc` -> `require('es5-ext/math/trunc')`\n* `Number.EPSILON` -> `require('es5-ext/number/epsilon')`\n* `Number.MAX_SAFE_INTEGER` -> `require('es5-ext/number/max-safe-integer')`\n* `Number.MIN_SAFE_INTEGER` -> `require('es5-ext/number/min-safe-integer')`\n* `Number.isFinite` -> `require('es5-ext/number/is-finite')`\n* `Number.isInteger` -> `require('es5-ext/number/is-integer')`\n* `Number.isNaN` -> `require('es5-ext/number/is-nan')`\n* `Number.isSafeInteger` -> `require('es5-ext/number/is-safe-integer')`\n* `Object.assign` -> `require('es5-ext/object/assign')`\n* `Object.keys` -> `require('es5-ext/object/keys')`\n* `Object.setPrototypeOf` -> `require('es5-ext/object/set-prototype-of')`\n* `RegExp.prototype.match` -> `require('es5-ext/reg-exp/#/match')`\n* `RegExp.prototype.replace` -> `require('es5-ext/reg-exp/#/replace')`\n* `RegExp.prototype.search` -> `require('es5-ext/reg-exp/#/search')`\n* `RegExp.prototype.split` -> `require('es5-ext/reg-exp/#/split')`\n* `RegExp.prototype.sticky` -> Implement with `require('es5-ext/reg-exp/#/sticky/implement')`, use as function with `require('es5-ext/reg-exp/#/is-sticky')`\n* `RegExp.prototype.unicode` -> Implement with `require('es5-ext/reg-exp/#/unicode/implement')`, use as function with `require('es5-ext/reg-exp/#/is-unicode')`\n* `String.fromCodePoint` -> `require('es5-ext/string/from-code-point')`\n* `String.raw` -> `require('es5-ext/string/raw')`\n* `String.prototype.codePointAt` -> `require('es5-ext/string/#/code-point-at')`\n* `String.prototype.contains` -> `require('es5-ext/string/#/contains')`\n* `String.prototype.endsWith` -> `require('es5-ext/string/#/ends-with')`\n* `String.prototype.normalize` -> `require('es5-ext/string/#/normalize')`\n* `String.prototype.repeat` -> `require('es5-ext/string/#/repeat')`\n* `String.prototype.startsWith` -> `require('es5-ext/string/#/starts-with')`\n* `String.prototype[@@iterator]` -> `require('es5-ext/string/#/@@iterator')`\n\n#### Non ECMAScript standard features\n\n**es5-ext** provides also other utils, and implements them as if they were proposed for a standard. It mostly offers methods (not functions) which can directly be assigned to native prototypes:\n\n```javascript\nObject.defineProperty(Function.prototype, \"partial\", {\n\tvalue: require(\"es5-ext/function/#/partial\"),\n\tconfigurable: true,\n\tenumerable: false,\n\twritable: true\n});\nObject.defineProperty(Array.prototype, \"flatten\", {\n\tvalue: require(\"es5-ext/array/#/flatten\"),\n\tconfigurable: true,\n\tenumerable: false,\n\twritable: true\n});\nObject.defineProperty(String.prototype, \"capitalize\", {\n\tvalue: require(\"es5-ext/string/#/capitalize\"),\n\tconfigurable: true,\n\tenumerable: false,\n\twritable: true\n});\n```\n\nSee [es5-extend](https://github.com/wookieb/es5-extend#es5-extend), a great utility that automatically will extend natives for you.\n\n**Important:** Remember to **not** extend natives in scope of generic reusable packages (e.g. ones you intend to publish to npm). Extending natives is fine **only** if you're the _owner_ of the global scope, so e.g. in final project you lead development of.\n\nWhen you're in situation when native extensions are not good idea, then you should use methods indirectly:\n\n```javascript\nvar flatten = require(\"es5-ext/array/#/flatten\");\n\nflatten.call([1, [2, [3, 4]]]); // [1, 2, 3, 4]\n```\n\nfor better convenience you can turn methods into functions:\n\n```javascript\nvar call = Function.prototype.call;\nvar flatten = call.bind(require(\"es5-ext/array/#/flatten\"));\n\nflatten([1, [2, [3, 4]]]); // [1, 2, 3, 4]\n```\n\nYou can configure custom toolkit (like [underscorejs](http://underscorejs.org/)), and use it throughout your application\n\n```javascript\nvar util = {};\nutil.partial = call.bind(require(\"es5-ext/function/#/partial\"));\nutil.flatten = call.bind(require(\"es5-ext/array/#/flatten\"));\nutil.startsWith = call.bind(require(\"es5-ext/string/#/starts-with\"));\n\nutil.flatten([1, [2, [3, 4]]]); // [1, 2, 3, 4]\n```\n\nAs with native ones most methods are generic and can be run on any type of object.\n\n## API\n\n### Global extensions\n\n#### global _(es5-ext/global)_\n\nObject that represents global scope\n\n### Array Constructor extensions\n\n#### from(arrayLike[, mapFn[, thisArg]]) _(es5-ext/array/from)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.from). \nReturns array representation of _iterable_ or _arrayLike_. If _arrayLike_ is an instance of array, its copy is returned.\n\n#### generate([length[, …fill]]) _(es5-ext/array/generate)_\n\nGenerate an array of pre-given _length_ built of repeated arguments.\n\n#### isPlainArray(x) _(es5-ext/array/is-plain-array)_\n\nReturns true if object is plain array (not instance of one of the Array's extensions).\n\n#### of([…items]) _(es5-ext/array/of)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.of). \nCreate an array from given arguments.\n\n#### toArray(obj) _(es5-ext/array/to-array)_\n\nReturns array representation of `obj`. If `obj` is already an array, `obj` is returned back.\n\n#### validArray(obj) _(es5-ext/array/valid-array)_\n\nReturns `obj` if it's an array, otherwise throws `TypeError`\n\n### Array Prototype extensions\n\n#### arr.binarySearch(compareFn) _(es5-ext/array/#/binary-search)_\n\nIn **sorted** list search for index of item for which _compareFn_ returns value closest to _0_. \nIt's variant of binary search algorithm\n\n#### arr.clear() _(es5-ext/array/#/clear)_\n\nClears the array\n\n#### arr.compact() _(es5-ext/array/#/compact)_\n\nReturns a copy of the context with all non-values (`null` or `undefined`) removed.\n\n#### arr.concat() _(es5-ext/array/#/concat)_\n\n[_Updated with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype.concat). \nES6's version of `concat`. Supports `isConcatSpreadable` symbol, and returns array of same type as the context.\n\n#### arr.contains(searchElement[, position]) _(es5-ext/array/#/contains)_\n\nWhether list contains the given value.\n\n#### arr.copyWithin(target, start[, end]) _(es5-ext/array/#/copy-within)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.copywithin).\n\n#### arr.diff(other) _(es5-ext/array/#/diff)_\n\nReturns the array of elements that are present in context list but not present in other list.\n\n#### arr.eIndexOf(searchElement[, fromIndex]) _(es5-ext/array/#/e-index-of)_\n\n_egal_ version of `indexOf` method. [_SameValueZero_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) logic is used for comparision\n\n#### arr.eLastIndexOf(searchElement[, fromIndex]) _(es5-ext/array/#/e-last-index-of)_\n\n_egal_ version of `lastIndexOf` method. [_SameValueZero_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) logic is used for comparision\n\n#### arr.entries() _(es5-ext/array/#/entries)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype.entries). \nReturns iterator object, which traverses the array. Each value is represented with an array, where first value is an index and second is corresponding to index value.\n\n#### arr.exclusion([…lists]]) _(es5-ext/array/#/exclusion)_\n\nReturns the array of elements that are found only in one of the lists (either context list or list provided in arguments).\n\n#### arr.fill(value[, start, end]) _(es5-ext/array/#/fill)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.fill).\n\n#### arr.filter(callback[, thisArg]) _(es5-ext/array/#/filter)_\n\n[_Updated with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.filter). \nES6's version of `filter`, returns array of same type as the context.\n\n#### arr.find(predicate[, thisArg]) _(es5-ext/array/#/find)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.find). \nReturn first element for which given function returns true\n\n#### arr.findIndex(predicate[, thisArg]) _(es5-ext/array/#/find-index)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.findindex). \nReturn first index for which given function returns true\n\n#### arr.first() _(es5-ext/array/#/first)_\n\nReturns value for first defined index\n\n#### arr.firstIndex() _(es5-ext/array/#/first-index)_\n\nReturns first declared index of the array\n\n#### arr.flatten() _(es5-ext/array/#/flatten)_\n\nReturns flattened version of the array\n\n#### arr.forEachRight(cb[, thisArg]) _(es5-ext/array/#/for-each-right)_\n\n`forEach` starting from last element\n\n#### arr.group(cb[, thisArg]) _(es5-ext/array/#/group)_\n\nGroup list elements by value returned by _cb_ function\n\n#### arr.indexesOf(searchElement[, fromIndex]) _(es5-ext/array/#/indexes-of)_\n\nReturns array of all indexes of given value\n\n#### arr.intersection([…lists]) _(es5-ext/array/#/intersection)_\n\nComputes the array of values that are the intersection of all lists (context list and lists given in arguments)\n\n#### arr.isCopy(other) _(es5-ext/array/#/is-copy)_\n\nReturns true if both context and _other_ lists have same content\n\n#### arr.isUniq() _(es5-ext/array/#/is-uniq)_\n\nReturns true if all values in array are unique\n\n#### arr.keys() _(es5-ext/array/#/keys)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype.keys). \nReturns iterator object, which traverses all array indexes.\n\n#### arr.last() _(es5-ext/array/#/last)_\n\nReturns value of last defined index\n\n#### arr.lastIndex() _(es5-ext/array/#/last)_\n\nReturns last defined index of the array\n\n#### arr.map(callback[, thisArg]) _(es5-ext/array/#/map)_\n\n[_Updated with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.map). \nES6's version of `map`, returns array of same type as the context.\n\n#### arr.remove(value[, …valuen]) _(es5-ext/array/#/remove)_\n\nRemove values from the array\n\n#### arr.separate(sep) _(es5-ext/array/#/separate)_\n\nReturns array with items separated with `sep` value\n\n#### arr.slice(callback[, thisArg]) _(es5-ext/array/#/slice)_\n\n[_Updated with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.slice). \nES6's version of `slice`, returns array of same type as the context.\n\n#### arr.someRight(cb[, thisArg]) _(es5-ext/array/#/someRight)_\n\n`some` starting from last element\n\n#### arr.splice(callback[, thisArg]) _(es5-ext/array/#/splice)_\n\n[_Updated with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.splice). \nES6's version of `splice`, returns array of same type as the context.\n\n#### arr.uniq() _(es5-ext/array/#/uniq)_\n\nReturns duplicate-free version of the array\n\n#### arr.values() _(es5-ext/array/#/values)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype.values). \nReturns iterator object which traverses all array values.\n\n#### arr[@@iterator] _(es5-ext/array/#/@@iterator)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype-@@iterator). \nReturns iterator object which traverses all array values.\n\n### Boolean Constructor extensions\n\n#### isBoolean(x) _(es5-ext/boolean/is-boolean)_\n\nWhether value is boolean\n\n### Date Constructor extensions\n\n#### isDate(x) _(es5-ext/date/is-date)_\n\nWhether value is date instance\n\n#### validDate(x) _(es5-ext/date/valid-date)_\n\nIf given object is not date throw TypeError in other case return it.\n\n### Date Prototype extensions\n\n#### date.copy(date) _(es5-ext/date/#/copy)_\n\nReturns a copy of the date object\n\n#### date.daysInMonth() _(es5-ext/date/#/days-in-month)_\n\nReturns number of days of date's month\n\n#### date.floorDay() _(es5-ext/date/#/floor-day)_\n\nSets the date time to 00:00:00.000\n\n#### date.floorMonth() _(es5-ext/date/#/floor-month)_\n\nSets date day to 1 and date time to 00:00:00.000\n\n#### date.floorYear() _(es5-ext/date/#/floor-year)_\n\nSets date month to 0, day to 1 and date time to 00:00:00.000\n\n#### date.format(pattern) _(es5-ext/date/#/format)_\n\nFormats date up to given string. Supported patterns:\n\n* `%Y` - Year with century, 1999, 2003\n* `%y` - Year without century, 99, 03\n* `%m` - Month, 01..12\n* `%d` - Day of the month 01..31\n* `%H` - Hour (24-hour clock), 00..23\n* `%M` - Minute, 00..59\n* `%S` - Second, 00..59\n* `%L` - Milliseconds, 000..999\n\n### Error Constructor extensions\n\n#### custom(message/_, code, ext_/) _(es5-ext/error/custom)_\n\nCreates custom error object, optinally extended with `code` and other extension properties (provided with `ext` object)\n\n#### isError(x) _(es5-ext/error/is-error)_\n\nWhether value is an error (instance of `Error`).\n\n#### validError(x) _(es5-ext/error/valid-error)_\n\nIf given object is not error throw TypeError in other case return it.\n\n### Error Prototype extensions\n\n#### err.throw() _(es5-ext/error/#/throw)_\n\nThrows error\n\n### Function Constructor extensions\n\nSome of the functions were inspired by [Functional JavaScript](http://osteele.com/sources/javascript/functional/) project by Olivier Steele\n\n#### constant(x) _(es5-ext/function/constant)_\n\nReturns a constant function that returns pregiven argument\n\n_k(x)(y) =def x_\n\n#### identity(x) _(es5-ext/function/identity)_\n\nIdentity function. Returns first argument\n\n_i(x) =def x_\n\n#### invoke(name[, …args]) _(es5-ext/function/invoke)_\n\nReturns a function that takes an object as an argument, and applies object's\n_name_ method to arguments. \n_name_ can be name of the method or method itself.\n\n_invoke(name, …args)(object, …args2) =def object\\[name\\]\\(…args, …args2\\)_\n\n#### isArguments(x) _(es5-ext/function/is-arguments)_\n\nWhether value is arguments object\n\n#### isFunction(arg) _(es5-ext/function/is-function)_\n\nWhether value is instance of function\n\n#### noop() _(es5-ext/function/noop)_\n\nNo operation function\n\n#### pluck(name) _(es5-ext/function/pluck)_\n\nReturns a function that takes an object, and returns the value of its _name_\nproperty\n\n_pluck(name)(obj) =def obj[name]_\n\n#### validFunction(arg) _(es5-ext/function/valid-function)_\n\nIf given object is not function throw TypeError in other case return it.\n\n### Function Prototype extensions\n\nSome of the methods were inspired by [Functional JavaScript](http://osteele.com/sources/javascript/functional/) project by Olivier Steele\n\n#### fn.compose([…fns]) _(es5-ext/function/#/compose)_\n\nApplies the functions in reverse argument-list order.\n\n_f1.compose(f2, f3, f4)(…args) =def f1(f2(f3(f4(…arg))))_\n\n#### fn.copy() _(es5-ext/function/#/copy)_\n\nProduces copy of given function\n\n#### fn.curry([n]) _(es5-ext/function/#/curry)_\n\nInvoking the function returned by this function only _n_ arguments are passed to the underlying function. If the underlying function is not saturated, the result is a function that passes all its arguments to the underlying function. \nIf _n_ is not provided then it defaults to context function length\n\n_f.curry(4)(arg1, arg2)(arg3)(arg4) =def f(arg1, args2, arg3, arg4)_\n\n#### fn.lock([…args]) _(es5-ext/function/#/lock)_\n\nReturns a function that applies the underlying function to _args_, and ignores its own arguments.\n\n_f.lock(…args)(…args2) =def f(…args)_\n\n_Named after it's counterpart in Google Closure_\n\n#### fn.not() _(es5-ext/function/#/not)_\n\nReturns a function that returns boolean negation of value returned by underlying function.\n\n_f.not()(…args) =def !f(…args)_\n\n#### fn.partial([…args]) _(es5-ext/function/#/partial)_\n\nReturns a function that when called will behave like context function called with initially passed arguments. If more arguments are suplilied, they are appended to initial args.\n\n_f.partial(…args1)(…args2) =def f(…args1, …args2)_\n\n#### fn.spread() _(es5-ext/function/#/spread)_\n\nReturns a function that applies underlying function with first list argument\n\n_f.match()(args) =def f.apply(null, args)_\n\n#### fn.toStringTokens() _(es5-ext/function/#/to-string-tokens)_\n\nSerializes function into two (arguments and body) string tokens. Result is plain object with `args` and `body` properties.\n\n### Math extensions\n\n#### acosh(x) _(es5-ext/math/acosh)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.acosh).\n\n#### asinh(x) _(es5-ext/math/asinh)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.asinh).\n\n#### atanh(x) _(es5-ext/math/atanh)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.atanh).\n\n#### cbrt(x) _(es5-ext/math/cbrt)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.cbrt).\n\n#### clz32(x) _(es5-ext/math/clz32)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.clz32).\n\n#### cosh(x) _(es5-ext/math/cosh)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.cosh).\n\n#### expm1(x) _(es5-ext/math/expm1)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.expm1).\n\n#### fround(x) _(es5-ext/math/fround)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.fround).\n\n#### hypot([…values]) _(es5-ext/math/hypot)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.hypot).\n\n#### imul(x, y) _(es5-ext/math/imul)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.imul).\n\n#### log1p(x) _(es5-ext/math/log1p)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.log1p).\n\n#### log2(x) _(es5-ext/math/log2)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.log2).\n\n#### log10(x) _(es5-ext/math/log10)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.log10).\n\n#### sign(x) _(es5-ext/math/sign)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.sign).\n\n#### sinh(x) _(es5-ext/math/sinh)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.sinh).\n\n#### tanh(x) _(es5-ext/math/tanh)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.tanh).\n\n#### trunc(x) _(es5-ext/math/trunc)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.trunc).\n\n### Number Constructor extensions\n\n#### EPSILON _(es5-ext/number/epsilon)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.epsilon).\n\nThe difference between 1 and the smallest value greater than 1 that is representable as a Number value, which is approximately 2.2204460492503130808472633361816 x 10-16.\n\n#### isFinite(x) _(es5-ext/number/is-finite)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.isfinite). \nWhether value is finite. Differs from global isNaN that it doesn't do type coercion.\n\n#### isInteger(x) _(es5-ext/number/is-integer)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.isinteger). \nWhether value is integer.\n\n#### isNaN(x) _(es5-ext/number/is-nan)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.isnan). \nWhether value is NaN. Differs from global isNaN that it doesn't do type coercion.\n\n#### isNumber(x) _(es5-ext/number/is-number)_\n\nWhether given value is number\n\n#### isSafeInteger(x) _(es5-ext/number/is-safe-integer)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.issafeinteger).\n\n#### MAX*SAFE_INTEGER *(es5-ext/number/max-safe-integer)\\_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.maxsafeinteger). \nThe value of Number.MAX_SAFE_INTEGER is 9007199254740991.\n\n#### MIN*SAFE_INTEGER *(es5-ext/number/min-safe-integer)\\_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.minsafeinteger). \nThe value of Number.MIN_SAFE_INTEGER is -9007199254740991 (253-1).\n\n#### toInteger(x) _(es5-ext/number/to-integer)_\n\nConverts value to integer\n\n#### toPosInteger(x) _(es5-ext/number/to-pos-integer)_\n\nConverts value to positive integer. If provided value is less than 0, then 0 is returned\n\n#### toUint32(x) _(es5-ext/number/to-uint32)_\n\nConverts value to unsigned 32 bit integer. This type is used for array lengths.\nSee: http://www.2ality.com/2012/02/js-integers.html\n\n### Number Prototype extensions\n\n#### num.pad(length[, precision]) _(es5-ext/number/#/pad)_\n\nPad given number with zeros. Returns string\n\n### Object Constructor extensions\n\n#### assign(target, source[, …sourcen]) _(es5-ext/object/assign)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign). \nExtend _target_ by enumerable own properties of other objects. If properties are already set on target object, they will be overwritten.\n\n#### clear(obj) _(es5-ext/object/clear)_\n\nRemove all enumerable own properties of the object\n\n#### compact(obj) _(es5-ext/object/compact)_\n\nReturns copy of the object with all enumerable properties that have no falsy values\n\n#### compare(obj1, obj2) _(es5-ext/object/compare)_\n\nUniversal cross-type compare function. To be used for e.g. array sort.\n\n#### copy(obj) _(es5-ext/object/copy)_\n\nReturns copy of the object with all enumerable properties.\n\n#### copyDeep(obj) _(es5-ext/object/copy-deep)_\n\nReturns deep copy of the object with all enumerable properties.\n\n#### count(obj) _(es5-ext/object/count)_\n\nCounts number of enumerable own properties on object\n\n#### create(obj[, properties]) _(es5-ext/object/create)_\n\n`Object.create` alternative that provides workaround for [V8 issue](http://code.google.com/p/v8/issues/detail?id=2804).\n\nWhen `null` is provided as a prototype, it's substituted with specially prepared object that derives from Object.prototype but has all Object.prototype properties shadowed with undefined.\n\nIt's quirky solution that allows us to have plain objects with no truthy properties but with turnable prototype.\n\nUse only for objects that you plan to switch prototypes of and be aware of limitations of this workaround.\n\n#### eq(x, y) _(es5-ext/object/eq)_\n\nWhether two values are equal, using [_SameValueZero_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) algorithm.\n\n#### every(obj, cb[, thisArg[, compareFn]]) _(es5-ext/object/every)_\n\nAnalogous to Array.prototype.every. Returns true if every key-value pair in this object satisfies the provided testing function. \nOptionally _compareFn_ can be provided which assures that keys are tested in given order. If provided _compareFn_ is equal to `true`, then order is alphabetical (by key).\n\n#### filter(obj, cb[, thisArg]) _(es5-ext/object/filter)_\n\nAnalogous to Array.prototype.filter. Returns new object with properites for which _cb_ function returned truthy value.\n\n#### firstKey(obj) _(es5-ext/object/first-key)_\n\nReturns first enumerable key of the object, as keys are unordered by specification, it can be any key of an object.\n\n#### flatten(obj) _(es5-ext/object/flatten)_\n\nReturns new object, with flatten properties of input object\n\n_flatten({ a: { b: 1 }, c: { d: 1 } }) =def { b: 1, d: 1 }_\n\n#### forEach(obj, cb[, thisArg[, compareFn]]) _(es5-ext/object/for-each)_\n\nAnalogous to Array.prototype.forEach. Calls a function for each key-value pair found in object\nOptionally _compareFn_ can be provided which assures that properties are iterated in given order. If provided _compareFn_ is equal to `true`, then order is alphabetical (by key).\n\n#### getPropertyNames() _(es5-ext/object/get-property-names)_\n\nGet all (not just own) property names of the object\n\n#### is(x, y) _(es5-ext/object/is)_\n\nWhether two values are equal, using [_SameValue_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) algorithm.\n\n#### isArrayLike(x) _(es5-ext/object/is-array-like)_\n\nWhether object is array-like object\n\n#### isCopy(x, y) _(es5-ext/object/is-copy)_\n\nTwo values are considered a copy of same value when all of their own enumerable properties have same values.\n\n#### isCopyDeep(x, y) _(es5-ext/object/is-copy-deep)_\n\nDeep comparision of objects\n\n#### isEmpty(obj) _(es5-ext/object/is-empty)_\n\nTrue if object doesn't have any own enumerable property\n\n#### isObject(arg) _(es5-ext/object/is-object)_\n\nWhether value is not primitive\n\n#### isPlainObject(arg) _(es5-ext/object/is-plain-object)_\n\nWhether object is plain object, its protototype should be Object.prototype and it cannot be host object.\n\n#### keyOf(obj, searchValue) _(es5-ext/object/key-of)_\n\nSearch object for value\n\n#### keys(obj) _(es5-ext/object/keys)_\n\n[_Updated with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.keys). \nES6's version of `keys`, doesn't throw on primitive input\n\n#### map(obj, cb[, thisArg]) _(es5-ext/object/map)_\n\nAnalogous to Array.prototype.map. Creates a new object with properties which values are results of calling a provided function on every key-value pair in this object.\n\n#### mapKeys(obj, cb[, thisArg]) _(es5-ext/object/map-keys)_\n\nCreate new object with same values, but remapped keys\n\n#### mixin(target, source) _(es5-ext/object/mixin)_\n\nExtend _target_ by all own properties of other objects. Properties found in both objects will be overwritten (unless they're not configurable and cannot be overwritten).\n_It was for a moment part of ECMAScript 6 draft._\n\n#### mixinPrototypes(target, …source]) _(es5-ext/object/mixin-prototypes)_\n\nExtends _target_, with all source and source's prototype properties.\nUseful as an alternative for `setPrototypeOf` in environments in which it cannot be shimmed (no `__proto__` support).\n\n#### normalizeOptions(options) _(es5-ext/object/normalize-options)_\n\nNormalizes options object into flat plain object.\n\nUseful for functions in which we either need to keep options object for future reference or need to modify it for internal use.\n\n* It never returns input `options` object back (always a copy is created)\n* `options` can be undefined in such case empty plain object is returned.\n* Copies all enumerable properties found down prototype chain.\n\n#### primitiveSet([…names]) _(es5-ext/object/primitive-set)_\n\nCreates `null` prototype based plain object, and sets on it all property names provided in arguments to true.\n\n#### safeTraverse(obj[, …names]) _(es5-ext/object/safe-traverse)_\n\nSafe navigation of object properties. See http://wiki.ecmascript.org/doku.php?id=strawman:existential_operator\n\n#### serialize(value) _(es5-ext/object/serialize)_\n\nSerialize value into string. Differs from [JSON.stringify](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) that it serializes also dates, functions and regular expresssions.\n\n#### setPrototypeOf(object, proto) _(es5-ext/object/set-prototype-of)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.setprototypeof). \nIf native version is not provided, it depends on existence of `__proto__` functionality, if it's missing, `null` instead of function is exposed.\n\n#### some(obj, cb[, thisArg[, compareFn]]) _(es5-ext/object/some)_\n\nAnalogous to Array.prototype.some Returns true if any key-value pair satisfies the provided\ntesting function. \nOptionally _compareFn_ can be provided which assures that keys are tested in given order. If provided _compareFn_ is equal to `true`, then order is alphabetical (by key).\n\n#### toArray(obj[, cb[, thisArg[, compareFn]]]) _(es5-ext/object/to-array)_\n\nCreates an array of results of calling a provided function on every key-value pair in this object. \nOptionally _compareFn_ can be provided which assures that results are added in given order. If provided _compareFn_ is equal to `true`, then order is alphabetical (by key).\n\n#### unserialize(str) _(es5-ext/object/unserialize)_\n\nUserializes value previously serialized with [serialize](#serializevalue-es5-extobjectserialize)\n\n#### validCallable(x) _(es5-ext/object/valid-callable)_\n\nIf given object is not callable throw TypeError in other case return it.\n\n#### validObject(x) _(es5-ext/object/valid-object)_\n\nThrows error if given value is not an object, otherwise it is returned.\n\n#### validValue(x) _(es5-ext/object/valid-value)_\n\nThrows error if given value is `null` or `undefined`, otherwise returns value.\n\n### RegExp Constructor extensions\n\n#### escape(str) _(es5-ext/reg-exp/escape)_\n\nEscapes string to be used in regular expression\n\n#### isRegExp(x) _(es5-ext/reg-exp/is-reg-exp)_\n\nWhether object is regular expression\n\n#### validRegExp(x) _(es5-ext/reg-exp/valid-reg-exp)_\n\nIf object is regular expression it is returned, otherwise TypeError is thrown.\n\n### RegExp Prototype extensions\n\n#### re.isSticky(x) _(es5-ext/reg-exp/#/is-sticky)_\n\nWhether regular expression has `sticky` flag.\n\nIt's to be used as counterpart to [regExp.sticky](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-get-regexp.prototype.sticky) if it's not implemented.\n\n#### re.isUnicode(x) _(es5-ext/reg-exp/#/is-unicode)_\n\nWhether regular expression has `unicode` flag.\n\nIt's to be used as counterpart to [regExp.unicode](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-get-regexp.prototype.unicode) if it's not implemented.\n\n#### re.match(string) _(es5-ext/reg-exp/#/match)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.match).\n\n#### re.replace(string, replaceValue) _(es5-ext/reg-exp/#/replace)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.replace).\n\n#### re.search(string) _(es5-ext/reg-exp/#/search)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.search).\n\n#### re.split(string) _(es5-ext/reg-exp/#/search)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.split).\n\n#### re.sticky _(es5-ext/reg-exp/#/sticky/implement)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.sticky). \nIt's a getter, so only `implement` and `is-implemented` modules are provided.\n\n#### re.unicode _(es5-ext/reg-exp/#/unicode/implement)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.unicode). \nIt's a getter, so only `implement` and `is-implemented` modules are provided.\n\n### String Constructor extensions\n\n#### formatMethod(fMap) _(es5-ext/string/format-method)_\n\nCreates format method. It's used e.g. to create `Date.prototype.format` method\n\n#### fromCodePoint([…codePoints]) _(es5-ext/string/from-code-point)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.fromcodepoint)\n\n#### isString(x) _(es5-ext/string/is-string)_\n\nWhether object is string\n\n#### randomUniq() _(es5-ext/string/random-uniq)_\n\nReturns randomly generated id, with guarantee of local uniqueness (no same id will be returned twice)\n\n#### raw(callSite[, …substitutions]) _(es5-ext/string/raw)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.raw)\n\n### String Prototype extensions\n\n#### str.at(pos) _(es5-ext/string/#/at)_\n\n_Proposed for ECMAScript 6/7 standard, but not (yet) in a draft_\n\nReturns a string at given position in Unicode-safe manner.\nBased on [implementation by Mathias Bynens](https://github.com/mathiasbynens/String.prototype.at).\n\n#### str.camelToHyphen() _(es5-ext/string/#/camel-to-hyphen)_\n\nConvert camelCase string to hyphen separated, e.g. one-two-three -> oneTwoThree.\nUseful when converting names from js property convention into filename convention.\n\n#### str.capitalize() _(es5-ext/string/#/capitalize)_\n\nCapitalize first character of a string\n\n#### str.caseInsensitiveCompare(str) _(es5-ext/string/#/case-insensitive-compare)_\n\nCase insensitive compare\n\n#### str.codePointAt(pos) _(es5-ext/string/#/code-point-at)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.codepointat)\n\nBased on [implementation by Mathias Bynens](https://github.com/mathiasbynens/String.prototype.codePointAt).\n\n#### str.contains(searchString[, position]) _(es5-ext/string/#/contains)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.contains)\n\nWhether string contains given string.\n\n#### str.endsWith(searchString[, endPosition]) _(es5-ext/string/#/ends-with)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.endswith). \nWhether strings ends with given string\n\n#### str.hyphenToCamel() _(es5-ext/string/#/hyphen-to-camel)_\n\nConvert hyphen separated string to camelCase, e.g. one-two-three -> oneTwoThree.\nUseful when converting names from filename convention to js property name convention.\n\n#### str.indent(str[, count]) _(es5-ext/string/#/indent)_\n\nIndents each line with provided _str_ (if _count_ given then _str_ is repeated _count_ times).\n\n#### str.last() _(es5-ext/string/#/last)_\n\nReturn last character\n\n#### str.normalize([form]) _(es5-ext/string/#/normalize)_\n\n[_Introduced with ECMAScript 6_](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize). \nReturns the Unicode Normalization Form of a given string. \nBased on Matsuza's version. Code used for integrated shim can be found at [github.com/walling/unorm](https://github.com/walling/unorm/blob/master/lib/unorm.js)\n\n#### str.pad(fill[, length]) _(es5-ext/string/#/pad)_\n\nPad string with _fill_.\nIf _length_ si given than _fill_ is reapated _length_ times.\nIf _length_ is negative then pad is applied from right.\n\n#### str.repeat(n) _(es5-ext/string/#/repeat)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.repeat). \nRepeat given string _n_ times\n\n#### str.plainReplace(search, replace) _(es5-ext/string/#/plain-replace)_\n\nSimple `replace` version. Doesn't support regular expressions. Replaces just first occurrence of search string. Doesn't support insert patterns, therefore it is safe to replace text with text obtained programmatically (there's no need for additional _$_ characters escape in such case).\n\n#### str.plainReplaceAll(search, replace) _(es5-ext/string/#/plain-replace-all)_\n\nSimple `replace` version. Doesn't support regular expressions. Replaces all occurrences of search string. Doesn't support insert patterns, therefore it is safe to replace text with text obtained programmatically (there's no need for additional _$_ characters escape in such case).\n\n#### str.startsWith(searchString[, position]) _(es5-ext/string/#/starts-with)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.startswith). \nWhether strings starts with given string\n\n#### str[@@iterator] _(es5-ext/string/#/@@iterator)_\n\n[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype-@@iterator). \nReturns iterator object which traverses all string characters (with respect to unicode symbols)\n\n### Tests\n\n $ npm test\n\n[nix-build-image]: https://semaphoreci.com/api/v1/medikoo-org/es5-ext/branches/master/shields_badge.svg\n[nix-build-url]: https://semaphoreci.com/medikoo-org/es5-ext\n[win-build-image]: https://ci.appveyor.com/api/projects/status/3jox67ksw3p8hkwh?svg=true\n[win-build-url]: https://ci.appveyor.com/project/medikoo/es5-ext\n[transpilation-image]: https://img.shields.io/badge/transpilation-free-brightgreen.svg\n[npm-image]: https://img.shields.io/npm/v/es5-ext.svg\n[npm-url]: https://www.npmjs.com/package/es5-ext\n", - "readmeFilename": "README.md", - "bugs": "[Circular]", - "homepage": "https://github.com/medikoo/es5-ext#readme", - "_id": "es5-ext@0.10.45", - "_requested": { - "type": "version", - "registry": true, - "raw": "es5-ext@0.10.45", - "name": "es5-ext", - "escapedName": "es5-ext", - "rawSpec": "0.10.45", - "saveSpec": "[Circular]", - "fetchSpec": "0.10.45" - }, - "_spec": "0.10.45", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": "[Circular]", - "optionalDependencies": "[Circular]", - "_dependencies": "[Circular]", - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/es5-ext", - "error": "[Circular]", - "extraneous": false - } - }, - "devDependencies": { - "tad": "~0.2.3", - "xlint": "~0.2.2", - "xlint-jslint-medikoo": "~0.1.4" - }, - "scripts": { - "lint": "node node_modules/xlint/bin/xlint --linter=node_modules/xlint-jslint-medikoo/index.js --no-cache --no-stream", - "lint-console": "node node_modules/xlint/bin/xlint --linter=node_modules/xlint-jslint-medikoo/index.js --watch", - "test": "node ./node_modules/tad/bin/tad" - }, - "license": "MIT", - "_resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.4.tgz", - "_integrity": "sha1-jWPd+0z+H647MsomXExyAiIIC7U=", - "_from": "event-emitter@0.3.4", - "readme": "# event-emitter\n## Environment agnostic event emitter\n\n### Installation\n\n\t$ npm install event-emitter\n\t\nTo port it to Browser or any other (non CJS) environment, use your favorite CJS bundler. No favorite yet? Try: [Browserify](http://browserify.org/), [Webmake](https://github.com/medikoo/modules-webmake) or [Webpack](http://webpack.github.io/)\n\n### Usage\n\n```javascript\nvar ee = require('event-emitter');\n\nvar emitter = ee({}), listener;\n\nemitter.on('test', listener = function (args) {\n // …emitter logic\n});\n\nemitter.once('test', function (args) {\n // …invoked only once(!)\n});\n\nemitter.emit('test', arg1, arg2/*…args*/); // Two above listeners invoked\nemitter.emit('test', arg1, arg2/*…args*/); // Only first listener invoked\n\nemitter.off('test', listener); // Removed first listener\nemitter.emit('test', arg1, arg2/*…args*/); // No listeners invoked\n```\n### Additional utilities\n\n#### allOff(obj) _(event-emitter/all-off)_\n\nRemoves all listeners from given event emitter object\n\n#### hasListeners(obj[, name]) _(event-emitter/has-listeners)_\n\nWhether object has some listeners attached to the object.\nWhen `name` is provided, it checks listeners for specific event name\n\n```javascript\nvar emitter = ee();\nvar hasListeners = require('event-emitter/has-listeners');\nvar listener = function () {};\n\nhasListeners(emitter); // false\n\nemitter.on('foo', listener);\nhasListeners(emitter); // true\nhasListeners(emitter, 'foo'); // true\nhasListeners(emitter, 'bar'); // false\n\nemitter.off('foo', listener);\nhasListeners(emitter, 'foo'); // false\n```\n\n#### pipe(source, target[, emitMethodName]) _(event-emitter/pipe)_\n\nPipes all events from _source_ emitter onto _target_ emitter (all events from _source_ emitter will be emitted also on _target_ emitter, but not other way). \nReturns _pipe_ object which exposes `pipe.close` function. Invoke it to close configured _pipe_. \nIt works internally by redefinition of `emit` method, if in your interface this method is referenced differently, provide its name (or symbol) with third argument.\n\n#### unify(emitter1, emitter2) _(event-emitter/unify)_\n\nUnifies event handling for two objects. Events emitted on _emitter1_ would be also emitter on _emitter2_, and other way back. \nNon reversible.\n\n```javascript\nvar eeUnify = require('event-emitter/unify');\n\nvar emitter1 = ee(), listener1, listener3;\nvar emitter2 = ee(), listener2, listener4;\n\nemitter1.on('test', listener1 = function () { });\nemitter2.on('test', listener2 = function () { });\n\nemitter1.emit('test'); // Invoked listener1\nemitter2.emit('test'); // Invoked listener2\n\nvar unify = eeUnify(emitter1, emitter2);\n\nemitter1.emit('test'); // Invoked listener1 and listener2\nemitter2.emit('test'); // Invoked listener1 and listener2\n\nemitter1.on('test', listener3 = function () { });\nemitter2.on('test', listener4 = function () { });\n\nemitter1.emit('test'); // Invoked listener1, listener2, listener3 and listener4\nemitter2.emit('test'); // Invoked listener1, listener2, listener3 and listener4\n```\n\n### Tests [![Build Status](https://travis-ci.org/medikoo/event-emitter.png)](https://travis-ci.org/medikoo/event-emitter)\n\n\t$ npm test\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/medikoo/event-emitter/issues" - }, - "homepage": "https://github.com/medikoo/event-emitter#readme", - "_id": "event-emitter@0.3.4", - "_requested": { - "type": "version", - "registry": true, - "raw": "event-emitter@0.3.4", - "name": "event-emitter", - "escapedName": "event-emitter", - "rawSpec": "0.3.4", - "saveSpec": "[Circular]", - "fetchSpec": "0.3.4" - }, - "_spec": "0.3.4", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "event-emitter@0.3.4", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "optionalDependencies": {}, - "_dependencies": { - "es5-ext": "~0.10.7", - "d": "~0.1.1" - }, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/event-emitter", - "error": "[Circular]", - "extraneous": false - }, - "superagent": { - "name": "superagent", - "version": "3.8.2", - "description": "elegant & feature rich browser / node HTTP with a fluent API", - "scripts": { - "prepare": "make all", - "test": "make test" - }, - "keywords": [ - "http", - "ajax", - "request", - "agent" - ], - "license": "MIT", - "author": { - "name": "TJ Holowaychuk", - "email": "tj@vision-media.ca" - }, - "contributors": [ - { - "name": "Kornel Lesiński", - "email": "kornel@geekhood.net" - }, - { - "name": "Peter Lyons", - "email": "pete@peterlyons.com" - }, - { - "name": "Hunter Loftis", - "email": "hunter@hunterloftis.com" - } - ], - "repository": { - "type": "git", - "url": "git://github.com/visionmedia/superagent.git" - }, - "dependencies": { - "component-emitter": { - "name": "component-emitter", - "description": "Event emitter", - "version": "1.2.1", - "license": "MIT", - "devDependencies": { - "mocha": "*", - "should": "*" - }, - "component": { - "scripts": { - "emitter/index.js": "index.js" - } - }, - "main": "index.js", - "repository": { - "type": "git", - "url": "git+https://github.com/component/emitter.git" - }, - "scripts": { - "test": "make test" - }, - "files": [ - "index.js", - "LICENSE" - ], - "_resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "_integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", - "_from": "component-emitter@1.2.1", - "readme": "# Emitter [![Build Status](https://travis-ci.org/component/emitter.png)](https://travis-ci.org/component/emitter)\r\n\r\n Event emitter component.\r\n\r\n## Installation\r\n\r\n```\r\n$ component install component/emitter\r\n```\r\n\r\n## API\r\n\r\n### Emitter(obj)\r\n\r\n The `Emitter` may also be used as a mixin. For example\r\n a \"plain\" object may become an emitter, or you may\r\n extend an existing prototype.\r\n\r\n As an `Emitter` instance:\r\n\r\n```js\r\nvar Emitter = require('emitter');\r\nvar emitter = new Emitter;\r\nemitter.emit('something');\r\n```\r\n\r\n As a mixin:\r\n\r\n```js\r\nvar Emitter = require('emitter');\r\nvar user = { name: 'tobi' };\r\nEmitter(user);\r\n\r\nuser.emit('im a user');\r\n```\r\n\r\n As a prototype mixin:\r\n\r\n```js\r\nvar Emitter = require('emitter');\r\nEmitter(User.prototype);\r\n```\r\n\r\n### Emitter#on(event, fn)\r\n\r\n Register an `event` handler `fn`.\r\n\r\n### Emitter#once(event, fn)\r\n\r\n Register a single-shot `event` handler `fn`,\r\n removed immediately after it is invoked the\r\n first time.\r\n\r\n### Emitter#off(event, fn)\r\n\r\n * Pass `event` and `fn` to remove a listener.\r\n * Pass `event` to remove all listeners on that event.\r\n * Pass nothing to remove all listeners on all events.\r\n\r\n### Emitter#emit(event, ...)\r\n\r\n Emit an `event` with variable option args.\r\n\r\n### Emitter#listeners(event)\r\n\r\n Return an array of callbacks, or an empty array.\r\n\r\n### Emitter#hasListeners(event)\r\n\r\n Check if this emitter has `event` handlers.\r\n\r\n## License\r\n\r\nMIT\r\n", - "readmeFilename": "Readme.md", - "bugs": { - "url": "https://github.com/component/emitter/issues" - }, - "homepage": "https://github.com/component/emitter#readme", - "_id": "component-emitter@1.2.1", - "_requested": { - "type": "version", - "registry": true, - "raw": "component-emitter@1.2.1", - "name": "component-emitter", - "escapedName": "component-emitter", - "rawSpec": "1.2.1", - "saveSpec": "[Circular]", - "fetchSpec": "1.2.1" - }, - "_spec": "1.2.1", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "component-emitter@1.2.1", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "dependencies": {}, - "optionalDependencies": {}, - "_dependencies": {}, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/component-emitter", - "error": "[Circular]", - "extraneous": false - }, - "cookiejar": { - "name": "cookiejar", - "version": "2.1.2", - "author": { - "name": "bradleymeck" - }, - "main": "cookiejar.js", - "description": "simple persistent cookiejar system", - "files": [ - "cookiejar.js" - ], - "license": "MIT", - "jshintConfig": { - "node": true - }, - "scripts": { - "test": "node tests/test.js" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/bmeck/node-cookiejar.git" - }, - "devDependencies": { - "jshint": "^2.9.4" - }, - "_resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", - "_integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==", - "_from": "cookiejar@2.1.2", - "readme": "# CookieJar\n\n[![NPM version](http://img.shields.io/npm/v/cookiejar.svg)](https://www.npmjs.org/package/cookiejar)\n[![devDependency Status](https://david-dm.org/bmeck/node-cookiejar/dev-status.svg)](https://david-dm.org/bmeck/node-cookiejar?type=dev)\n\nSimple robust cookie library\n\n## Exports\n\n### CookieAccessInfo(domain,path,secure,script)\n\nclass to determine matching qualities of a cookie\n\n##### Properties\n\n* String domain - domain to match\n* String path - path to match\n* Boolean secure - access is secure (ssl generally)\n* Boolean script - access is from a script\n\n\n### Cookie(cookiestr_or_cookie, request_domain, request_path)\n\nIt turns input into a Cookie (singleton if given a Cookie),\nthe `request_domain` argument is used to default the domain if it is not explicit in the cookie string,\nthe `request_path` argument is used to set the path if it is not explicit in a cookie String.\n\nExplicit domains/paths will cascade, implied domains/paths must *exactly* match (see http://en.wikipedia.org/wiki/HTTP_cookie#Domain_and_Pat).\n\n##### Properties\n\n* String name - name of the cookie\n* String value - string associated with the cookie\n* String domain - domain to match (on a cookie a '.' at the start means a wildcard matching anything ending in the rest)\n* Boolean explicit_domain - if the domain was explicitly set via the cookie string\n* String path - base path to match (matches any path starting with this '/' is root)\n* Boolean explicit_path - if the path was explicitly set via the cookie string\n* Boolean noscript - if it should be kept from scripts\n* Boolean secure - should it only be transmitted over secure means\n* Number expiration_date - number of millis since 1970 at which this should be removed\n\n##### Methods\n\n* `String toString()` - the __set-cookie:__ string for this cookie\n* `String toValueString()` - the __cookie:__ string for this cookie\n* `Cookie parse(cookiestr, request_domain, request_path)` - parses the string onto this cookie or a new one if called directly\n* `Boolean matches(access_info)` - returns true if the access_info allows retrieval of this cookie\n* `Boolean collidesWith(cookie)` - returns true if the cookies cannot exist in the same space (domain and path match)\n\n\n### CookieJar()\n\nclass to hold numerous cookies from multiple domains correctly\n\n##### Methods\n\n* `Cookie setCookie(cookie, request_domain, request_path)` - modify (or add if not already-existing) a cookie to the jar\n* `Cookie[] setCookies(cookiestr_or_list, request_domain, request_path)` - modify (or add if not already-existing) a large number of cookies to the jar\n* `Cookie getCookie(cookie_name,access_info)` - get a cookie with the name and access_info matching\n* `Cookie[] getCookies(access_info)` - grab all cookies matching this access_info\n", - "readmeFilename": "readme.md", - "bugs": { - "url": "https://github.com/bmeck/node-cookiejar/issues" - }, - "homepage": "https://github.com/bmeck/node-cookiejar#readme", - "_id": "cookiejar@2.1.2", - "_requested": { - "type": "version", - "registry": true, - "raw": "cookiejar@2.1.2", - "name": "cookiejar", - "escapedName": "cookiejar", - "rawSpec": "2.1.2", - "saveSpec": "[Circular]", - "fetchSpec": "2.1.2" - }, - "_spec": "2.1.2", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "cookiejar@2.1.2", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "dependencies": {}, - "optionalDependencies": {}, - "_dependencies": {}, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/cookiejar", - "error": "[Circular]", - "extraneous": false - }, - "debug": { - "name": "debug", - "version": "3.1.0", - "repository": { - "type": "git", - "url": "git://github.com/visionmedia/debug.git" - }, - "description": "small debugging utility", - "keywords": [ - "debug", - "log", - "debugger" - ], - "author": { - "name": "TJ Holowaychuk", - "email": "tj@vision-media.ca" - }, - "contributors": [ - { - "name": "Nathan Rajlich", - "email": "nathan@tootallnate.net", - "url": "http://n8.io" - }, - { - "name": "Andrew Rhyne", - "email": "rhyneandrew@gmail.com" - } - ], - "license": "MIT", - "dependencies": { - "ms": { - "name": "ms", - "version": "2.0.0", - "description": "Tiny milisecond conversion utility", - "repository": { - "type": "git", - "url": "git+https://github.com/zeit/ms.git" - }, - "main": "./index", - "files": [ - "index.js" - ], - "scripts": { - "precommit": "lint-staged", - "lint": "eslint lib/* bin/*", - "test": "mocha tests.js" - }, - "eslintConfig": { - "extends": "eslint:recommended", - "env": { - "node": true, - "es6": true - } - }, - "lint-staged": { - "*.js": [ - "npm run lint", - "prettier --single-quote --write", - "git add" - ] - }, - "license": "MIT", - "devDependencies": { - "eslint": "3.19.0", - "expect.js": "0.3.1", - "husky": "0.13.3", - "lint-staged": "3.4.1", - "mocha": "3.4.1" - }, - "_resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "_integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "_from": "ms@2.0.0", - "readme": "# ms\n\n[![Build Status](https://travis-ci.org/zeit/ms.svg?branch=master)](https://travis-ci.org/zeit/ms)\n[![Slack Channel](http://zeit-slackin.now.sh/badge.svg)](https://zeit.chat/)\n\nUse this package to easily convert various time formats to milliseconds.\n\n## Examples\n\n```js\nms('2 days') // 172800000\nms('1d') // 86400000\nms('10h') // 36000000\nms('2.5 hrs') // 9000000\nms('2h') // 7200000\nms('1m') // 60000\nms('5s') // 5000\nms('1y') // 31557600000\nms('100') // 100\n```\n\n### Convert from milliseconds\n\n```js\nms(60000) // \"1m\"\nms(2 * 60000) // \"2m\"\nms(ms('10 hours')) // \"10h\"\n```\n\n### Time format written-out\n\n```js\nms(60000, { long: true }) // \"1 minute\"\nms(2 * 60000, { long: true }) // \"2 minutes\"\nms(ms('10 hours'), { long: true }) // \"10 hours\"\n```\n\n## Features\n\n- Works both in [node](https://nodejs.org) and in the browser.\n- If a number is supplied to `ms`, a string with a unit is returned.\n- If a string that contains the number is supplied, it returns it as a number (e.g.: it returns `100` for `'100'`).\n- If you pass a string with a number and a valid unit, the number of equivalent ms is returned.\n\n## Caught a bug?\n\n1. [Fork](https://help.github.com/articles/fork-a-repo/) this repository to your own GitHub account and then [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device\n2. Link the package to the global module directory: `npm link`\n3. Within the module you want to test your local development instance of ms, just link it to the dependencies: `npm link ms`. Instead of the default one from npm, node will now use your clone of ms!\n\nAs always, you can run the tests using: `npm test`\n", - "readmeFilename": "readme.md", - "bugs": { - "url": "https://github.com/zeit/ms/issues" - }, - "homepage": "https://github.com/zeit/ms#readme", - "_id": "ms@2.0.0", - "_requested": { - "type": "version", - "registry": true, - "raw": "ms@2.0.0", - "name": "ms", - "escapedName": "ms", - "rawSpec": "2.0.0", - "saveSpec": "[Circular]", - "fetchSpec": "2.0.0" - }, - "_spec": "2.0.0", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "ms@2.0.0", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "dependencies": {}, - "optionalDependencies": {}, - "_dependencies": {}, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/ms", - "error": "[Circular]", - "extraneous": false - } - }, - "devDependencies": { - "browserify": "14.4.0", - "chai": "^3.5.0", - "concurrently": "^3.1.0", - "coveralls": "^2.11.15", - "eslint": "^3.12.1", - "istanbul": "^0.4.5", - "karma": "^1.3.0", - "karma-chai": "^0.1.0", - "karma-mocha": "^1.3.0", - "karma-phantomjs-launcher": "^1.0.2", - "karma-sinon": "^1.0.5", - "mocha": "^3.2.0", - "mocha-lcov-reporter": "^1.2.0", - "rimraf": "^2.5.4", - "sinon": "^1.17.6", - "sinon-chai": "^2.8.0" - }, - "main": "./src/index.js", - "browser": "./src/browser.js", - "_resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "_integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "_from": "debug@3.1.0", - "readme": "# debug\n[![Build Status](https://travis-ci.org/visionmedia/debug.svg?branch=master)](https://travis-ci.org/visionmedia/debug) [![Coverage Status](https://coveralls.io/repos/github/visionmedia/debug/badge.svg?branch=master)](https://coveralls.io/github/visionmedia/debug?branch=master) [![Slack](https://visionmedia-community-slackin.now.sh/badge.svg)](https://visionmedia-community-slackin.now.sh/) [![OpenCollective](https://opencollective.com/debug/backers/badge.svg)](#backers)\n[![OpenCollective](https://opencollective.com/debug/sponsors/badge.svg)](#sponsors)\n\n\n\nA tiny JavaScript debugging utility modelled after Node.js core's debugging\ntechnique. Works in Node.js and web browsers.\n\n## Installation\n\n```bash\n$ npm install debug\n```\n\n## Usage\n\n`debug` exposes a function; simply pass this function the name of your module, and it will return a decorated version of `console.error` for you to pass debug statements to. This will allow you to toggle the debug output for different parts of your module as well as the module as a whole.\n\nExample [_app.js_](./examples/node/app.js):\n\n```js\nvar debug = require('debug')('http')\n , http = require('http')\n , name = 'My App';\n\n// fake app\n\ndebug('booting %o', name);\n\nhttp.createServer(function(req, res){\n debug(req.method + ' ' + req.url);\n res.end('hello\\n');\n}).listen(3000, function(){\n debug('listening');\n});\n\n// fake worker of some kind\n\nrequire('./worker');\n```\n\nExample [_worker.js_](./examples/node/worker.js):\n\n```js\nvar a = require('debug')('worker:a')\n , b = require('debug')('worker:b');\n\nfunction work() {\n a('doing lots of uninteresting work');\n setTimeout(work, Math.random() * 1000);\n}\n\nwork();\n\nfunction workb() {\n b('doing some work');\n setTimeout(workb, Math.random() * 2000);\n}\n\nworkb();\n```\n\nThe `DEBUG` environment variable is then used to enable these based on space or\ncomma-delimited names.\n\nHere are some examples:\n\n\"screen\n\"screen\n\"screen\n\n#### Windows note\n\nOn Windows the environment variable is set using the `set` command.\n\n```cmd\nset DEBUG=*,-not_this\n```\n\nNote that PowerShell uses different syntax to set environment variables.\n\n```cmd\n$env:DEBUG = \"*,-not_this\"\n```\n\nThen, run the program to be debugged as usual.\n\n\n## Namespace Colors\n\nEvery debug instance has a color generated for it based on its namespace name.\nThis helps when visually parsing the debug output to identify which debug instance\na debug line belongs to.\n\n#### Node.js\n\nIn Node.js, colors are enabled when stderr is a TTY. You also _should_ install\nthe [`supports-color`](https://npmjs.org/supports-color) module alongside debug,\notherwise debug will only use a small handful of basic colors.\n\n\n\n#### Web Browser\n\nColors are also enabled on \"Web Inspectors\" that understand the `%c` formatting\noption. These are WebKit web inspectors, Firefox ([since version\n31](https://hacks.mozilla.org/2014/05/editable-box-model-multiple-selection-sublime-text-keys-much-more-firefox-developer-tools-episode-31/))\nand the Firebug plugin for Firefox (any version).\n\n\n\n\n## Millisecond diff\n\nWhen actively developing an application it can be useful to see when the time spent between one `debug()` call and the next. Suppose for example you invoke `debug()` before requesting a resource, and after as well, the \"+NNNms\" will show you how much time was spent between calls.\n\n\n\nWhen stdout is not a TTY, `Date#toISOString()` is used, making it more useful for logging the debug information as shown below:\n\n\n\n\n## Conventions\n\nIf you're using this in one or more of your libraries, you _should_ use the name of your library so that developers may toggle debugging as desired without guessing names. If you have more than one debuggers you _should_ prefix them with your library name and use \":\" to separate features. For example \"bodyParser\" from Connect would then be \"connect:bodyParser\". If you append a \"*\" to the end of your name, it will always be enabled regardless of the setting of the DEBUG environment variable. You can then use it for normal output as well as debug output.\n\n## Wildcards\n\nThe `*` character may be used as a wildcard. Suppose for example your library has\ndebuggers named \"connect:bodyParser\", \"connect:compress\", \"connect:session\",\ninstead of listing all three with\n`DEBUG=connect:bodyParser,connect:compress,connect:session`, you may simply do\n`DEBUG=connect:*`, or to run everything using this module simply use `DEBUG=*`.\n\nYou can also exclude specific debuggers by prefixing them with a \"-\" character.\nFor example, `DEBUG=*,-connect:*` would include all debuggers except those\nstarting with \"connect:\".\n\n## Environment Variables\n\nWhen running through Node.js, you can set a few environment variables that will\nchange the behavior of the debug logging:\n\n| Name | Purpose |\n|-----------|-------------------------------------------------|\n| `DEBUG` | Enables/disables specific debugging namespaces. |\n| `DEBUG_HIDE_DATE` | Hide date from debug output (non-TTY). |\n| `DEBUG_COLORS`| Whether or not to use colors in the debug output. |\n| `DEBUG_DEPTH` | Object inspection depth. |\n| `DEBUG_SHOW_HIDDEN` | Shows hidden properties on inspected objects. |\n\n\n__Note:__ The environment variables beginning with `DEBUG_` end up being\nconverted into an Options object that gets used with `%o`/`%O` formatters.\nSee the Node.js documentation for\n[`util.inspect()`](https://nodejs.org/api/util.html#util_util_inspect_object_options)\nfor the complete list.\n\n## Formatters\n\nDebug uses [printf-style](https://wikipedia.org/wiki/Printf_format_string) formatting.\nBelow are the officially supported formatters:\n\n| Formatter | Representation |\n|-----------|----------------|\n| `%O` | Pretty-print an Object on multiple lines. |\n| `%o` | Pretty-print an Object all on a single line. |\n| `%s` | String. |\n| `%d` | Number (both integer and float). |\n| `%j` | JSON. Replaced with the string '[Circular]' if the argument contains circular references. |\n| `%%` | Single percent sign ('%'). This does not consume an argument. |\n\n\n### Custom formatters\n\nYou can add custom formatters by extending the `debug.formatters` object.\nFor example, if you wanted to add support for rendering a Buffer as hex with\n`%h`, you could do something like:\n\n```js\nconst createDebug = require('debug')\ncreateDebug.formatters.h = (v) => {\n return v.toString('hex')\n}\n\n// …elsewhere\nconst debug = createDebug('foo')\ndebug('this is hex: %h', new Buffer('hello world'))\n// foo this is hex: 68656c6c6f20776f726c6421 +0ms\n```\n\n\n## Browser Support\n\nYou can build a browser-ready script using [browserify](https://github.com/substack/node-browserify),\nor just use the [browserify-as-a-service](https://wzrd.in/) [build](https://wzrd.in/standalone/debug@latest),\nif you don't want to build it yourself.\n\nDebug's enable state is currently persisted by `localStorage`.\nConsider the situation shown below where you have `worker:a` and `worker:b`,\nand wish to debug both. You can enable this using `localStorage.debug`:\n\n```js\nlocalStorage.debug = 'worker:*'\n```\n\nAnd then refresh the page.\n\n```js\na = debug('worker:a');\nb = debug('worker:b');\n\nsetInterval(function(){\n a('doing some work');\n}, 1000);\n\nsetInterval(function(){\n b('doing some work');\n}, 1200);\n```\n\n\n## Output streams\n\n By default `debug` will log to stderr, however this can be configured per-namespace by overriding the `log` method:\n\nExample [_stdout.js_](./examples/node/stdout.js):\n\n```js\nvar debug = require('debug');\nvar error = debug('app:error');\n\n// by default stderr is used\nerror('goes to stderr!');\n\nvar log = debug('app:log');\n// set this namespace to log via console.log\nlog.log = console.log.bind(console); // don't forget to bind to console!\nlog('goes to stdout');\nerror('still goes to stderr!');\n\n// set all output to go via console.info\n// overrides all per-namespace log settings\ndebug.log = console.info.bind(console);\nerror('now goes to stdout via console.info');\nlog('still goes to stdout, but via console.info now');\n```\n\n## Checking whether a debug target is enabled\n\nAfter you've created a debug instance, you can determine whether or not it is\nenabled by checking the `enabled` property:\n\n```javascript\nconst debug = require('debug')('http');\n\nif (debug.enabled) {\n // do stuff...\n}\n```\n\nYou can also manually toggle this property to force the debug instance to be\nenabled or disabled.\n\n\n## Authors\n\n - TJ Holowaychuk\n - Nathan Rajlich\n - Andrew Rhyne\n\n## Backers\n\nSupport us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/debug#backer)]\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n## Sponsors\n\nBecome a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/debug#sponsor)]\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n## License\n\n(The MIT License)\n\nCopyright (c) 2014-2017 TJ Holowaychuk <tj@vision-media.ca>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/visionmedia/debug/issues" - }, - "homepage": "https://github.com/visionmedia/debug#readme", - "_id": "debug@3.1.0", - "_requested": { - "type": "version", - "registry": true, - "raw": "debug@3.1.0", - "name": "debug", - "escapedName": "debug", - "rawSpec": "3.1.0", - "saveSpec": "[Circular]", - "fetchSpec": "3.1.0" - }, - "_spec": "3.1.0", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "debug@3.1.0", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "optionalDependencies": {}, - "_dependencies": { - "ms": "2.0.0" - }, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/debug", - "error": "[Circular]", - "extraneous": false - }, - "extend": { - "name": "extend", - "author": { - "name": "Stefan Thomas", - "email": "justmoon@members.fsf.org", - "url": "http://www.justmoon.net" - }, - "version": "3.0.2", - "description": "Port of jQuery.extend for node.js and the browser", - "main": "index", - "scripts": { - "pretest": "npm run lint", - "test": "npm run tests-only", - "posttest": "npm run coverage-quiet", - "tests-only": "node test", - "coverage": "covert test/index.js", - "coverage-quiet": "covert test/index.js --quiet", - "lint": "npm run jscs && npm run eslint", - "jscs": "jscs *.js */*.js", - "eslint": "eslint *.js */*.js" - }, - "contributors": [ - { - "name": "Jordan Harband", - "url": "https://github.com/ljharb" - } - ], - "keywords": [ - "extend", - "clone", - "merge" - ], - "repository": { - "type": "git", - "url": "git+https://github.com/justmoon/node-extend.git" - }, - "dependencies": {}, - "devDependencies": { - "@ljharb/eslint-config": "^12.2.1", - "covert": "^1.1.0", - "eslint": "^4.19.1", - "jscs": "^3.0.7", - "tape": "^4.9.1" - }, - "license": "MIT", - "_resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "_integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "_from": "extend@3.0.2", - "readme": "[![Build Status][travis-svg]][travis-url]\n[![dependency status][deps-svg]][deps-url]\n[![dev dependency status][dev-deps-svg]][dev-deps-url]\n\n# extend() for Node.js [![Version Badge][npm-version-png]][npm-url]\n\n`node-extend` is a port of the classic extend() method from jQuery. It behaves as you expect. It is simple, tried and true.\n\nNotes:\n\n* Since Node.js >= 4,\n [`Object.assign`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)\n now offers the same functionality natively (but without the \"deep copy\" option).\n See [ECMAScript 2015 (ES6) in Node.js](https://nodejs.org/en/docs/es6).\n* Some native implementations of `Object.assign` in both Node.js and many\n browsers (since NPM modules are for the browser too) may not be fully\n spec-compliant.\n Check [`object.assign`](https://www.npmjs.com/package/object.assign) module for\n a compliant candidate.\n\n## Installation\n\nThis package is available on [npm][npm-url] as: `extend`\n\n``` sh\nnpm install extend\n```\n\n## Usage\n\n**Syntax:** extend **(** [`deep`], `target`, `object1`, [`objectN`] **)**\n\n*Extend one object with one or more others, returning the modified object.*\n\n**Example:**\n\n``` js\nvar extend = require('extend');\nextend(targetObject, object1, object2);\n```\n\nKeep in mind that the target object will be modified, and will be returned from extend().\n\nIf a boolean true is specified as the first argument, extend performs a deep copy, recursively copying any objects it finds. Otherwise, the copy will share structure with the original object(s).\nUndefined properties are not copied. However, properties inherited from the object's prototype will be copied over.\nWarning: passing `false` as the first argument is not supported.\n\n### Arguments\n\n* `deep` *Boolean* (optional)\nIf set, the merge becomes recursive (i.e. deep copy).\n* `target`\t*Object*\nThe object to extend.\n* `object1`\t*Object*\nThe object that will be merged into the first.\n* `objectN` *Object* (Optional)\nMore objects to merge into the first.\n\n## License\n\n`node-extend` is licensed under the [MIT License][mit-license-url].\n\n## Acknowledgements\n\nAll credit to the jQuery authors for perfecting this amazing utility.\n\nPorted to Node.js by [Stefan Thomas][github-justmoon] with contributions by [Jonathan Buchanan][github-insin] and [Jordan Harband][github-ljharb].\n\n[travis-svg]: https://travis-ci.org/justmoon/node-extend.svg\n[travis-url]: https://travis-ci.org/justmoon/node-extend\n[npm-url]: https://npmjs.org/package/extend\n[mit-license-url]: http://opensource.org/licenses/MIT\n[github-justmoon]: https://github.com/justmoon\n[github-insin]: https://github.com/insin\n[github-ljharb]: https://github.com/ljharb\n[npm-version-png]: http://versionbadg.es/justmoon/node-extend.svg\n[deps-svg]: https://david-dm.org/justmoon/node-extend.svg\n[deps-url]: https://david-dm.org/justmoon/node-extend\n[dev-deps-svg]: https://david-dm.org/justmoon/node-extend/dev-status.svg\n[dev-deps-url]: https://david-dm.org/justmoon/node-extend#info=devDependencies\n\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/justmoon/node-extend/issues" - }, - "homepage": "https://github.com/justmoon/node-extend#readme", - "_id": "extend@3.0.2", - "_requested": { - "type": "version", - "registry": true, - "raw": "extend@3.0.2", - "name": "extend", - "escapedName": "extend", - "rawSpec": "3.0.2", - "saveSpec": "[Circular]", - "fetchSpec": "3.0.2" - }, - "_spec": "3.0.2", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "extend@3.0.2", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "optionalDependencies": {}, - "_dependencies": {}, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/extend", - "error": "[Circular]", - "extraneous": false - }, - "form-data": { - "author": { - "name": "Felix Geisendörfer", - "email": "felix@debuggable.com", - "url": "http://debuggable.com/" - }, - "name": "form-data", - "description": "A library to create readable \"multipart/form-data\" streams. Can be used to submit forms and file uploads to other web applications.", - "version": "2.3.2", - "repository": { - "type": "git", - "url": "git://github.com/form-data/form-data.git" - }, - "main": "./lib/form_data", - "browser": "./lib/browser", - "scripts": { - "pretest": "rimraf coverage test/tmp", - "test": "istanbul cover test/run.js", - "posttest": "istanbul report lcov text", - "lint": "eslint lib/*.js test/*.js test/integration/*.js", - "report": "istanbul report lcov text", - "ci-lint": "is-node-modern 6 && npm run lint || is-node-not-modern 6", - "ci-test": "npm run test && npm run browser && npm run report", - "predebug": "rimraf coverage test/tmp", - "debug": "verbose=1 ./test/run.js", - "browser": "browserify -t browserify-istanbul test/run-browser.js | obake --coverage", - "check": "istanbul check-coverage coverage/coverage*.json", - "files": "pkgfiles --sort=name", - "get-version": "node -e \"console.log(require('./package.json').version)\"", - "update-readme": "sed -i.bak 's/\\/master\\.svg/\\/v'$(npm --silent run get-version)'.svg/g' README.md", - "restore-readme": "mv README.md.bak README.md", - "prepublish": "in-publish && npm run update-readme || not-in-publish", - "postpublish": "npm run restore-readme" - }, - "pre-commit": [ - "lint", - "ci-test", - "check" - ], - "engines": { - "node": ">= 0.12" - }, - "dependencies": { - "asynckit": { - "name": "asynckit", - "version": "0.4.0", - "description": "Minimal async jobs utility library, with streams support", - "main": "index.js", - "scripts": { - "clean": "rimraf coverage", - "lint": "eslint *.js lib/*.js test/*.js", - "test": "istanbul cover --reporter=json tape -- 'test/test-*.js' | tap-spec", - "win-test": "tape test/test-*.js", - "browser": "browserify -t browserify-istanbul test/lib/browserify_adjustment.js test/test-*.js | obake --coverage | tap-spec", - "report": "istanbul report", - "size": "browserify index.js | size-table asynckit", - "debug": "tape test/test-*.js" - }, - "pre-commit": [ - "clean", - "lint", - "test", - "browser", - "report", - "size" - ], - "repository": { - "type": "git", - "url": "git+https://github.com/alexindigo/asynckit.git" - }, - "keywords": [ - "async", - "jobs", - "parallel", - "serial", - "iterator", - "array", - "object", - "stream", - "destroy", - "terminate", - "abort" - ], - "author": { - "name": "Alex Indigo", - "email": "iam@alexindigo.com" - }, - "license": "MIT", - "bugs": { - "url": "https://github.com/alexindigo/asynckit/issues" - }, - "homepage": "https://github.com/alexindigo/asynckit#readme", - "devDependencies": { - "browserify": "^13.0.0", - "browserify-istanbul": "^2.0.0", - "coveralls": "^2.11.9", - "eslint": "^2.9.0", - "istanbul": "^0.4.3", - "obake": "^0.1.2", - "phantomjs-prebuilt": "^2.1.7", - "pre-commit": "^1.1.3", - "reamde": "^1.1.0", - "rimraf": "^2.5.2", - "size-table": "^0.2.0", - "tap-spec": "^4.1.1", - "tape": "^4.5.1" - }, - "dependencies": {}, - "_resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "_integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "_from": "asynckit@0.4.0", - "readme": "# asynckit [![NPM Module](https://img.shields.io/npm/v/asynckit.svg?style=flat)](https://www.npmjs.com/package/asynckit)\n\nMinimal async jobs utility library, with streams support.\n\n[![PhantomJS Build](https://img.shields.io/travis/alexindigo/asynckit/v0.4.0.svg?label=browser&style=flat)](https://travis-ci.org/alexindigo/asynckit)\n[![Linux Build](https://img.shields.io/travis/alexindigo/asynckit/v0.4.0.svg?label=linux:0.12-6.x&style=flat)](https://travis-ci.org/alexindigo/asynckit)\n[![Windows Build](https://img.shields.io/appveyor/ci/alexindigo/asynckit/v0.4.0.svg?label=windows:0.12-6.x&style=flat)](https://ci.appveyor.com/project/alexindigo/asynckit)\n\n[![Coverage Status](https://img.shields.io/coveralls/alexindigo/asynckit/v0.4.0.svg?label=code+coverage&style=flat)](https://coveralls.io/github/alexindigo/asynckit?branch=master)\n[![Dependency Status](https://img.shields.io/david/alexindigo/asynckit/v0.4.0.svg?style=flat)](https://david-dm.org/alexindigo/asynckit)\n[![bitHound Overall Score](https://www.bithound.io/github/alexindigo/asynckit/badges/score.svg)](https://www.bithound.io/github/alexindigo/asynckit)\n\n\n\nAsyncKit provides harness for `parallel` and `serial` iterators over list of items represented by arrays or objects.\nOptionally it accepts abort function (should be synchronously return by iterator for each item), and terminates left over jobs upon an error event. For specific iteration order built-in (`ascending` and `descending`) and custom sort helpers also supported, via `asynckit.serialOrdered` method.\n\nIt ensures async operations to keep behavior more stable and prevent `Maximum call stack size exceeded` errors, from sync iterators.\n\n| compression | size |\n| :----------------- | -------: |\n| asynckit.js | 12.34 kB |\n| asynckit.min.js | 4.11 kB |\n| asynckit.min.js.gz | 1.47 kB |\n\n\n## Install\n\n```sh\n$ npm install --save asynckit\n```\n\n## Examples\n\n### Parallel Jobs\n\nRuns iterator over provided array in parallel. Stores output in the `result` array,\non the matching positions. In unlikely event of an error from one of the jobs,\nwill terminate rest of the active jobs (if abort function is provided)\nand return error along with salvaged data to the main callback function.\n\n#### Input Array\n\n```javascript\nvar parallel = require('asynckit').parallel\n , assert = require('assert')\n ;\n\nvar source = [ 1, 1, 4, 16, 64, 32, 8, 2 ]\n , expectedResult = [ 2, 2, 8, 32, 128, 64, 16, 4 ]\n , expectedTarget = [ 1, 1, 2, 4, 8, 16, 32, 64 ]\n , target = []\n ;\n\nparallel(source, asyncJob, function(err, result)\n{\n assert.deepEqual(result, expectedResult);\n assert.deepEqual(target, expectedTarget);\n});\n\n// async job accepts one element from the array\n// and a callback function\nfunction asyncJob(item, cb)\n{\n // different delays (in ms) per item\n var delay = item * 25;\n\n // pretend different jobs take different time to finish\n // and not in consequential order\n var timeoutId = setTimeout(function() {\n target.push(item);\n cb(null, item * 2);\n }, delay);\n\n // allow to cancel \"leftover\" jobs upon error\n // return function, invoking of which will abort this job\n return clearTimeout.bind(null, timeoutId);\n}\n```\n\nMore examples could be found in [test/test-parallel-array.js](test/test-parallel-array.js).\n\n#### Input Object\n\nAlso it supports named jobs, listed via object.\n\n```javascript\nvar parallel = require('asynckit/parallel')\n , assert = require('assert')\n ;\n\nvar source = { first: 1, one: 1, four: 4, sixteen: 16, sixtyFour: 64, thirtyTwo: 32, eight: 8, two: 2 }\n , expectedResult = { first: 2, one: 2, four: 8, sixteen: 32, sixtyFour: 128, thirtyTwo: 64, eight: 16, two: 4 }\n , expectedTarget = [ 1, 1, 2, 4, 8, 16, 32, 64 ]\n , expectedKeys = [ 'first', 'one', 'two', 'four', 'eight', 'sixteen', 'thirtyTwo', 'sixtyFour' ]\n , target = []\n , keys = []\n ;\n\nparallel(source, asyncJob, function(err, result)\n{\n assert.deepEqual(result, expectedResult);\n assert.deepEqual(target, expectedTarget);\n assert.deepEqual(keys, expectedKeys);\n});\n\n// supports full value, key, callback (shortcut) interface\nfunction asyncJob(item, key, cb)\n{\n // different delays (in ms) per item\n var delay = item * 25;\n\n // pretend different jobs take different time to finish\n // and not in consequential order\n var timeoutId = setTimeout(function() {\n keys.push(key);\n target.push(item);\n cb(null, item * 2);\n }, delay);\n\n // allow to cancel \"leftover\" jobs upon error\n // return function, invoking of which will abort this job\n return clearTimeout.bind(null, timeoutId);\n}\n```\n\nMore examples could be found in [test/test-parallel-object.js](test/test-parallel-object.js).\n\n### Serial Jobs\n\nRuns iterator over provided array sequentially. Stores output in the `result` array,\non the matching positions. In unlikely event of an error from one of the jobs,\nwill not proceed to the rest of the items in the list\nand return error along with salvaged data to the main callback function.\n\n#### Input Array\n\n```javascript\nvar serial = require('asynckit/serial')\n , assert = require('assert')\n ;\n\nvar source = [ 1, 1, 4, 16, 64, 32, 8, 2 ]\n , expectedResult = [ 2, 2, 8, 32, 128, 64, 16, 4 ]\n , expectedTarget = [ 0, 1, 2, 3, 4, 5, 6, 7 ]\n , target = []\n ;\n\nserial(source, asyncJob, function(err, result)\n{\n assert.deepEqual(result, expectedResult);\n assert.deepEqual(target, expectedTarget);\n});\n\n// extended interface (item, key, callback)\n// also supported for arrays\nfunction asyncJob(item, key, cb)\n{\n target.push(key);\n\n // it will be automatically made async\n // even it iterator \"returns\" in the same event loop\n cb(null, item * 2);\n}\n```\n\nMore examples could be found in [test/test-serial-array.js](test/test-serial-array.js).\n\n#### Input Object\n\nAlso it supports named jobs, listed via object.\n\n```javascript\nvar serial = require('asynckit').serial\n , assert = require('assert')\n ;\n\nvar source = [ 1, 1, 4, 16, 64, 32, 8, 2 ]\n , expectedResult = [ 2, 2, 8, 32, 128, 64, 16, 4 ]\n , expectedTarget = [ 0, 1, 2, 3, 4, 5, 6, 7 ]\n , target = []\n ;\n\nvar source = { first: 1, one: 1, four: 4, sixteen: 16, sixtyFour: 64, thirtyTwo: 32, eight: 8, two: 2 }\n , expectedResult = { first: 2, one: 2, four: 8, sixteen: 32, sixtyFour: 128, thirtyTwo: 64, eight: 16, two: 4 }\n , expectedTarget = [ 1, 1, 4, 16, 64, 32, 8, 2 ]\n , target = []\n ;\n\n\nserial(source, asyncJob, function(err, result)\n{\n assert.deepEqual(result, expectedResult);\n assert.deepEqual(target, expectedTarget);\n});\n\n// shortcut interface (item, callback)\n// works for object as well as for the arrays\nfunction asyncJob(item, cb)\n{\n target.push(item);\n\n // it will be automatically made async\n // even it iterator \"returns\" in the same event loop\n cb(null, item * 2);\n}\n```\n\nMore examples could be found in [test/test-serial-object.js](test/test-serial-object.js).\n\n_Note: Since _object_ is an _unordered_ collection of properties,\nit may produce unexpected results with sequential iterations.\nWhenever order of the jobs' execution is important please use `serialOrdered` method._\n\n### Ordered Serial Iterations\n\nTBD\n\nFor example [compare-property](compare-property) package.\n\n### Streaming interface\n\nTBD\n\n## Want to Know More?\n\nMore examples can be found in [test folder](test/).\n\nOr open an [issue](https://github.com/alexindigo/asynckit/issues) with questions and/or suggestions.\n\n## License\n\nAsyncKit is licensed under the MIT license.\n", - "readmeFilename": "README.md", - "_id": "asynckit@0.4.0", - "_requested": { - "type": "version", - "registry": true, - "raw": "asynckit@0.4.0", - "name": "asynckit", - "escapedName": "asynckit", - "rawSpec": "0.4.0", - "saveSpec": "[Circular]", - "fetchSpec": "0.4.0" - }, - "_spec": "0.4.0", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "asynckit@0.4.0", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "optionalDependencies": {}, - "_dependencies": {}, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/asynckit", - "error": "[Circular]", - "extraneous": false - }, - "combined-stream": { - "author": { - "name": "Felix Geisendörfer", - "email": "felix@debuggable.com", - "url": "http://debuggable.com/" - }, - "name": "combined-stream", - "description": "A stream that emits multiple other streams one after another.", - "version": "1.0.6", - "homepage": "https://github.com/felixge/node-combined-stream", - "repository": { - "type": "git", - "url": "git://github.com/felixge/node-combined-stream.git" - }, - "main": "./lib/combined_stream", - "scripts": { - "test": "node test/run.js" - }, - "engines": { - "node": ">= 0.8" - }, - "dependencies": { - "delayed-stream": { - "author": { - "name": "Felix Geisendörfer", - "email": "felix@debuggable.com", - "url": "http://debuggable.com/" - }, - "contributors": [ - { - "name": "Mike Atkins", - "email": "apeherder@gmail.com" - } - ], - "name": "delayed-stream", - "description": "Buffers events from a stream until you are ready to handle them.", - "license": "MIT", - "version": "1.0.0", - "homepage": "https://github.com/felixge/node-delayed-stream", - "repository": { - "type": "git", - "url": "git://github.com/felixge/node-delayed-stream.git" - }, - "main": "./lib/delayed_stream", - "engines": { - "node": ">=0.4.0" - }, - "scripts": { - "test": "make test" - }, - "dependencies": {}, - "devDependencies": { - "fake": "0.2.0", - "far": "0.0.1" - }, - "_resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "_integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "_from": "delayed-stream@1.0.0", - "readme": "# delayed-stream\n\nBuffers events from a stream until you are ready to handle them.\n\n## Installation\n\n``` bash\nnpm install delayed-stream\n```\n\n## Usage\n\nThe following example shows how to write a http echo server that delays its\nresponse by 1000 ms.\n\n``` javascript\nvar DelayedStream = require('delayed-stream');\nvar http = require('http');\n\nhttp.createServer(function(req, res) {\n var delayed = DelayedStream.create(req);\n\n setTimeout(function() {\n res.writeHead(200);\n delayed.pipe(res);\n }, 1000);\n});\n```\n\nIf you are not using `Stream#pipe`, you can also manually release the buffered\nevents by calling `delayedStream.resume()`:\n\n``` javascript\nvar delayed = DelayedStream.create(req);\n\nsetTimeout(function() {\n // Emit all buffered events and resume underlaying source\n delayed.resume();\n}, 1000);\n```\n\n## Implementation\n\nIn order to use this meta stream properly, here are a few things you should\nknow about the implementation.\n\n### Event Buffering / Proxying\n\nAll events of the `source` stream are hijacked by overwriting the `source.emit`\nmethod. Until node implements a catch-all event listener, this is the only way.\n\nHowever, delayed-stream still continues to emit all events it captures on the\n`source`, regardless of whether you have released the delayed stream yet or\nnot.\n\nUpon creation, delayed-stream captures all `source` events and stores them in\nan internal event buffer. Once `delayedStream.release()` is called, all\nbuffered events are emitted on the `delayedStream`, and the event buffer is\ncleared. After that, delayed-stream merely acts as a proxy for the underlaying\nsource.\n\n### Error handling\n\nError events on `source` are buffered / proxied just like any other events.\nHowever, `delayedStream.create` attaches a no-op `'error'` listener to the\n`source`. This way you only have to handle errors on the `delayedStream`\nobject, rather than in two places.\n\n### Buffer limits\n\ndelayed-stream provides a `maxDataSize` property that can be used to limit\nthe amount of data being buffered. In order to protect you from bad `source`\nstreams that don't react to `source.pause()`, this feature is enabled by\ndefault.\n\n## API\n\n### DelayedStream.create(source, [options])\n\nReturns a new `delayedStream`. Available options are:\n\n* `pauseStream`\n* `maxDataSize`\n\nThe description for those properties can be found below.\n\n### delayedStream.source\n\nThe `source` stream managed by this object. This is useful if you are\npassing your `delayedStream` around, and you still want to access properties\non the `source` object.\n\n### delayedStream.pauseStream = true\n\nWhether to pause the underlaying `source` when calling\n`DelayedStream.create()`. Modifying this property afterwards has no effect.\n\n### delayedStream.maxDataSize = 1024 * 1024\n\nThe amount of data to buffer before emitting an `error`.\n\nIf the underlaying source is emitting `Buffer` objects, the `maxDataSize`\nrefers to bytes.\n\nIf the underlaying source is emitting JavaScript strings, the size refers to\ncharacters.\n\nIf you know what you are doing, you can set this property to `Infinity` to\ndisable this feature. You can also modify this property during runtime.\n\n### delayedStream.dataSize = 0\n\nThe amount of data buffered so far.\n\n### delayedStream.readable\n\nAn ECMA5 getter that returns the value of `source.readable`.\n\n### delayedStream.resume()\n\nIf the `delayedStream` has not been released so far, `delayedStream.release()`\nis called.\n\nIn either case, `source.resume()` is called.\n\n### delayedStream.pause()\n\nCalls `source.pause()`.\n\n### delayedStream.pipe(dest)\n\nCalls `delayedStream.resume()` and then proxies the arguments to `source.pipe`.\n\n### delayedStream.release()\n\nEmits and clears all events that have been buffered up so far. This does not\nresume the underlaying source, use `delayedStream.resume()` instead.\n\n## License\n\ndelayed-stream is licensed under the MIT license.\n", - "readmeFilename": "Readme.md", - "bugs": { - "url": "https://github.com/felixge/node-delayed-stream/issues" - }, - "_id": "delayed-stream@1.0.0", - "_requested": { - "type": "version", - "registry": true, - "raw": "delayed-stream@1.0.0", - "name": "delayed-stream", - "escapedName": "delayed-stream", - "rawSpec": "1.0.0", - "saveSpec": "[Circular]", - "fetchSpec": "1.0.0" - }, - "_spec": "1.0.0", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "delayed-stream@1.0.0", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "optionalDependencies": {}, - "_dependencies": {}, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/delayed-stream", - "error": "[Circular]", - "extraneous": false - } - }, - "devDependencies": { - "far": "~0.0.7" - }, - "license": "MIT", - "_resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", - "_integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", - "_from": "combined-stream@1.0.6", - "readme": "# combined-stream\n\nA stream that emits multiple other streams one after another.\n\n**NB** Currently `combined-stream` works with streams version 1 only. There is ongoing effort to switch this library to streams version 2. Any help is welcome. :) Meanwhile you can explore other libraries that provide streams2 support with more or less compatibility with `combined-stream`.\n\n- [combined-stream2](https://www.npmjs.com/package/combined-stream2): A drop-in streams2-compatible replacement for the combined-stream module.\n\n- [multistream](https://www.npmjs.com/package/multistream): A stream that emits multiple other streams one after another.\n\n## Installation\n\n``` bash\nnpm install combined-stream\n```\n\n## Usage\n\nHere is a simple example that shows how you can use combined-stream to combine\ntwo files into one:\n\n``` javascript\nvar CombinedStream = require('combined-stream');\nvar fs = require('fs');\n\nvar combinedStream = CombinedStream.create();\ncombinedStream.append(fs.createReadStream('file1.txt'));\ncombinedStream.append(fs.createReadStream('file2.txt'));\n\ncombinedStream.pipe(fs.createWriteStream('combined.txt'));\n```\n\nWhile the example above works great, it will pause all source streams until\nthey are needed. If you don't want that to happen, you can set `pauseStreams`\nto `false`:\n\n``` javascript\nvar CombinedStream = require('combined-stream');\nvar fs = require('fs');\n\nvar combinedStream = CombinedStream.create({pauseStreams: false});\ncombinedStream.append(fs.createReadStream('file1.txt'));\ncombinedStream.append(fs.createReadStream('file2.txt'));\n\ncombinedStream.pipe(fs.createWriteStream('combined.txt'));\n```\n\nHowever, what if you don't have all the source streams yet, or you don't want\nto allocate the resources (file descriptors, memory, etc.) for them right away?\nWell, in that case you can simply provide a callback that supplies the stream\nby calling a `next()` function:\n\n``` javascript\nvar CombinedStream = require('combined-stream');\nvar fs = require('fs');\n\nvar combinedStream = CombinedStream.create();\ncombinedStream.append(function(next) {\n next(fs.createReadStream('file1.txt'));\n});\ncombinedStream.append(function(next) {\n next(fs.createReadStream('file2.txt'));\n});\n\ncombinedStream.pipe(fs.createWriteStream('combined.txt'));\n```\n\n## API\n\n### CombinedStream.create([options])\n\nReturns a new combined stream object. Available options are:\n\n* `maxDataSize`\n* `pauseStreams`\n\nThe effect of those options is described below.\n\n### combinedStream.pauseStreams = `true`\n\nWhether to apply back pressure to the underlaying streams. If set to `false`,\nthe underlaying streams will never be paused. If set to `true`, the\nunderlaying streams will be paused right after being appended, as well as when\n`delayedStream.pipe()` wants to throttle.\n\n### combinedStream.maxDataSize = `2 * 1024 * 1024`\n\nThe maximum amount of bytes (or characters) to buffer for all source streams.\nIf this value is exceeded, `combinedStream` emits an `'error'` event.\n\n### combinedStream.dataSize = `0`\n\nThe amount of bytes (or characters) currently buffered by `combinedStream`.\n\n### combinedStream.append(stream)\n\nAppends the given `stream` to the combinedStream object. If `pauseStreams` is\nset to `true, this stream will also be paused right away.\n\n`streams` can also be a function that takes one parameter called `next`. `next`\nis a function that must be invoked in order to provide the `next` stream, see\nexample above.\n\nRegardless of how the `stream` is appended, combined-stream always attaches an\n`'error'` listener to it, so you don't have to do that manually.\n\nSpecial case: `stream` can also be a String or Buffer.\n\n### combinedStream.write(data)\n\nYou should not call this, `combinedStream` takes care of piping the appended\nstreams into itself for you.\n\n### combinedStream.resume()\n\nCauses `combinedStream` to start drain the streams it manages. The function is\nidempotent, and also emits a `'resume'` event each time which usually goes to\nthe stream that is currently being drained.\n\n### combinedStream.pause();\n\nIf `combinedStream.pauseStreams` is set to `false`, this does nothing.\nOtherwise a `'pause'` event is emitted, this goes to the stream that is\ncurrently being drained, so you can use it to apply back pressure.\n\n### combinedStream.end();\n\nSets `combinedStream.writable` to false, emits an `'end'` event, and removes\nall streams from the queue.\n\n### combinedStream.destroy();\n\nSame as `combinedStream.end()`, except it emits a `'close'` event instead of\n`'end'`.\n\n## License\n\ncombined-stream is licensed under the MIT license.\n", - "readmeFilename": "Readme.md", - "bugs": { - "url": "https://github.com/felixge/node-combined-stream/issues" - }, - "_id": "combined-stream@1.0.6", - "_requested": { - "type": "version", - "registry": true, - "raw": "combined-stream@1.0.6", - "name": "combined-stream", - "escapedName": "combined-stream", - "rawSpec": "1.0.6", - "saveSpec": "[Circular]", - "fetchSpec": "1.0.6" - }, - "_spec": "1.0.6", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "combined-stream@1.0.6", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "optionalDependencies": {}, - "_dependencies": { - "delayed-stream": "~1.0.0" - }, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/combined-stream", - "error": "[Circular]", - "extraneous": false - }, - "mime-types": { - "name": "mime-types", - "description": "The ultimate javascript content-type utility.", - "version": "2.1.19", - "contributors": [ - { - "name": "Douglas Christopher Wilson", - "email": "doug@somethingdoug.com" - }, - { - "name": "Jeremiah Senkpiel", - "email": "fishrock123@rocketmail.com", - "url": "https://searchbeam.jit.su" - }, - { - "name": "Jonathan Ong", - "email": "me@jongleberry.com", - "url": "http://jongleberry.com" - } - ], - "license": "MIT", - "keywords": [ - "mime", - "types" - ], - "repository": { - "type": "git", - "url": "git+https://github.com/jshttp/mime-types.git" - }, - "dependencies": { - "mime-db": { - "name": "mime-db", - "description": "Media Type Database", - "version": "1.35.0", - "contributors": [ - { - "name": "Douglas Christopher Wilson", - "email": "doug@somethingdoug.com" - }, - { - "name": "Jonathan Ong", - "email": "me@jongleberry.com", - "url": "http://jongleberry.com" - }, - { - "name": "Robert Kieffer", - "email": "robert@broofa.com", - "url": "http://github.com/broofa" - } - ], - "license": "MIT", - "keywords": [ - "mime", - "db", - "type", - "types", - "database", - "charset", - "charsets" - ], - "repository": { - "type": "git", - "url": "git+https://github.com/jshttp/mime-db.git" - }, - "devDependencies": { - "bluebird": "3.5.1", - "co": "4.6.0", - "cogent": "1.0.1", - "csv-parse": "2.5.0", - "eslint": "4.19.1", - "eslint-config-standard": "11.0.0", - "eslint-plugin-import": "2.13.0", - "eslint-plugin-node": "6.0.1", - "eslint-plugin-promise": "3.8.0", - "eslint-plugin-standard": "3.1.0", - "gnode": "0.1.2", - "mocha": "1.21.5", - "nyc": "11.8.0", - "raw-body": "2.3.3", - "stream-to-array": "2.3.0" - }, - "files": [ - "HISTORY.md", - "LICENSE", - "README.md", - "db.json", - "index.js" - ], - "engines": { - "node": ">= 0.6" - }, - "scripts": { - "build": "node scripts/build", - "fetch": "node scripts/fetch-apache && gnode scripts/fetch-iana && node scripts/fetch-nginx", - "lint": "eslint .", - "test": "mocha --reporter spec --bail --check-leaks test/", - "test-cov": "nyc --reporter=html --reporter=text npm test", - "test-travis": "nyc --reporter=text npm test", - "update": "npm run fetch && npm run build" - }, - "_resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.35.0.tgz", - "_integrity": "sha512-JWT/IcCTsB0Io3AhWUMjRqucrHSPsSf2xKLaRldJVULioggvkJvggZ3VXNNSRkCddE6D+BUI4HEIZIA2OjwIvg==", - "_from": "mime-db@1.35.0", - "readme": "# mime-db\n\n[![NPM Version][npm-version-image]][npm-url]\n[![NPM Downloads][npm-downloads-image]][npm-url]\n[![Node.js Version][node-image]][node-url]\n[![Build Status][travis-image]][travis-url]\n[![Coverage Status][coveralls-image]][coveralls-url]\n\nThis is a database of all mime types.\nIt consists of a single, public JSON file and does not include any logic,\nallowing it to remain as un-opinionated as possible with an API.\nIt aggregates data from the following sources:\n\n- http://www.iana.org/assignments/media-types/media-types.xhtml\n- http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types\n- http://hg.nginx.org/nginx/raw-file/default/conf/mime.types\n\n## Installation\n\n```bash\nnpm install mime-db\n```\n\n### Database Download\n\nIf you're crazy enough to use this in the browser, you can just grab the\nJSON file using [RawGit](https://rawgit.com/). It is recommended to replace\n`master` with [a release tag](https://github.com/jshttp/mime-db/tags) as the\nJSON format may change in the future.\n\n```\nhttps://cdn.rawgit.com/jshttp/mime-db/master/db.json\n```\n\n## Usage\n\n```js\nvar db = require('mime-db');\n\n// grab data on .js files\nvar data = db['application/javascript'];\n```\n\n## Data Structure\n\nThe JSON file is a map lookup for lowercased mime types.\nEach mime type has the following properties:\n\n- `.source` - where the mime type is defined.\n If not set, it's probably a custom media type.\n - `apache` - [Apache common media types](http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types)\n - `iana` - [IANA-defined media types](http://www.iana.org/assignments/media-types/media-types.xhtml)\n - `nginx` - [nginx media types](http://hg.nginx.org/nginx/raw-file/default/conf/mime.types)\n- `.extensions[]` - known extensions associated with this mime type.\n- `.compressible` - whether a file of this type can be gzipped.\n- `.charset` - the default charset associated with this type, if any.\n\nIf unknown, every property could be `undefined`.\n\n## Contributing\n\nTo edit the database, only make PRs against `src/custom.json` or\n`src/custom-suffix.json`.\n\nThe `src/custom.json` file is a JSON object with the MIME type as the keys\nand the values being an object with the following keys:\n\n- `compressible` - leave out if you don't know, otherwise `true`/`false` to\n indicate whether the data represented by the type is typically compressible.\n- `extensions` - include an array of file extensions that are associated with\n the type.\n- `notes` - human-readable notes about the type, typically what the type is.\n- `sources` - include an array of URLs of where the MIME type and the associated\n extensions are sourced from. This needs to be a [primary source](https://en.wikipedia.org/wiki/Primary_source);\n links to type aggregating sites and Wikipedia are _not acceptable_.\n\nTo update the build, run `npm run build`.\n\n## Adding Custom Media Types\n\nThe best way to get new media types included in this library is to register\nthem with the IANA. The community registration procedure is outlined in\n[RFC 6838 section 5](http://tools.ietf.org/html/rfc6838#section-5). Types\nregistered with the IANA are automatically pulled into this library.\n\n[npm-version-image]: https://img.shields.io/npm/v/mime-db.svg\n[npm-downloads-image]: https://img.shields.io/npm/dm/mime-db.svg\n[npm-url]: https://npmjs.org/package/mime-db\n[travis-image]: https://img.shields.io/travis/jshttp/mime-db/master.svg\n[travis-url]: https://travis-ci.org/jshttp/mime-db\n[coveralls-image]: https://img.shields.io/coveralls/jshttp/mime-db/master.svg\n[coveralls-url]: https://coveralls.io/r/jshttp/mime-db?branch=master\n[node-image]: https://img.shields.io/node/v/mime-db.svg\n[node-url]: https://nodejs.org/en/download/\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/jshttp/mime-db/issues" - }, - "homepage": "https://github.com/jshttp/mime-db#readme", - "_id": "mime-db@1.35.0", - "_requested": { - "type": "version", - "registry": true, - "raw": "mime-db@1.35.0", - "name": "mime-db", - "escapedName": "mime-db", - "rawSpec": "1.35.0", - "saveSpec": "[Circular]", - "fetchSpec": "1.35.0" - }, - "_spec": "1.35.0", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "mime-db@1.35.0", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "dependencies": {}, - "optionalDependencies": {}, - "_dependencies": {}, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/mime-db", - "error": "[Circular]", - "extraneous": false - } - }, - "devDependencies": { - "eslint": "4.19.1", - "eslint-config-standard": "11.0.0", - "eslint-plugin-import": "2.13.0", - "eslint-plugin-node": "6.0.1", - "eslint-plugin-promise": "3.8.0", - "eslint-plugin-standard": "3.1.0", - "istanbul": "0.4.5", - "mocha": "1.21.5" - }, - "files": [ - "HISTORY.md", - "LICENSE", - "index.js" - ], - "engines": { - "node": ">= 0.6" - }, - "scripts": { - "lint": "eslint .", - "test": "mocha --reporter spec test/test.js", - "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot test/test.js", - "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter dot test/test.js" - }, - "_resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.19.tgz", - "_integrity": "sha512-P1tKYHVSZ6uFo26mtnve4HQFE3koh1UWVkp8YUC+ESBHe945xWSoXuHHiGarDqcEZ+whpCDnlNw5LON0kLo+sw==", - "_from": "mime-types@2.1.19", - "readme": "# mime-types\n\n[![NPM Version][npm-image]][npm-url]\n[![NPM Downloads][downloads-image]][downloads-url]\n[![Node.js Version][node-version-image]][node-version-url]\n[![Build Status][travis-image]][travis-url]\n[![Test Coverage][coveralls-image]][coveralls-url]\n\nThe ultimate javascript content-type utility.\n\nSimilar to [the `mime@1.x` module](https://www.npmjs.com/package/mime), except:\n\n- __No fallbacks.__ Instead of naively returning the first available type,\n `mime-types` simply returns `false`, so do\n `var type = mime.lookup('unrecognized') || 'application/octet-stream'`.\n- No `new Mime()` business, so you could do `var lookup = require('mime-types').lookup`.\n- No `.define()` functionality\n- Bug fixes for `.lookup(path)`\n\nOtherwise, the API is compatible with `mime` 1.x.\n\n## Install\n\nThis is a [Node.js](https://nodejs.org/en/) module available through the\n[npm registry](https://www.npmjs.com/). Installation is done using the\n[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):\n\n```sh\n$ npm install mime-types\n```\n\n## Adding Types\n\nAll mime types are based on [mime-db](https://www.npmjs.com/package/mime-db),\nso open a PR there if you'd like to add mime types.\n\n## API\n\n```js\nvar mime = require('mime-types')\n```\n\nAll functions return `false` if input is invalid or not found.\n\n### mime.lookup(path)\n\nLookup the content-type associated with a file.\n\n```js\nmime.lookup('json') // 'application/json'\nmime.lookup('.md') // 'text/markdown'\nmime.lookup('file.html') // 'text/html'\nmime.lookup('folder/file.js') // 'application/javascript'\nmime.lookup('folder/.htaccess') // false\n\nmime.lookup('cats') // false\n```\n\n### mime.contentType(type)\n\nCreate a full content-type header given a content-type or extension.\n\n```js\nmime.contentType('markdown') // 'text/x-markdown; charset=utf-8'\nmime.contentType('file.json') // 'application/json; charset=utf-8'\n\n// from a full path\nmime.contentType(path.extname('/path/to/file.json')) // 'application/json; charset=utf-8'\n```\n\n### mime.extension(type)\n\nGet the default extension for a content-type.\n\n```js\nmime.extension('application/octet-stream') // 'bin'\n```\n\n### mime.charset(type)\n\nLookup the implied default charset of a content-type.\n\n```js\nmime.charset('text/markdown') // 'UTF-8'\n```\n\n### var type = mime.types[extension]\n\nA map of content-types by extension.\n\n### [extensions...] = mime.extensions[type]\n\nA map of extensions by content-type.\n\n## License\n\n[MIT](LICENSE)\n\n[npm-image]: https://img.shields.io/npm/v/mime-types.svg\n[npm-url]: https://npmjs.org/package/mime-types\n[node-version-image]: https://img.shields.io/node/v/mime-types.svg\n[node-version-url]: https://nodejs.org/en/download/\n[travis-image]: https://img.shields.io/travis/jshttp/mime-types/master.svg\n[travis-url]: https://travis-ci.org/jshttp/mime-types\n[coveralls-image]: https://img.shields.io/coveralls/jshttp/mime-types/master.svg\n[coveralls-url]: https://coveralls.io/r/jshttp/mime-types\n[downloads-image]: https://img.shields.io/npm/dm/mime-types.svg\n[downloads-url]: https://npmjs.org/package/mime-types\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/jshttp/mime-types/issues" - }, - "homepage": "https://github.com/jshttp/mime-types#readme", - "_id": "mime-types@2.1.19", - "_requested": { - "type": "version", - "registry": true, - "raw": "mime-types@2.1.19", - "name": "mime-types", - "escapedName": "mime-types", - "rawSpec": "2.1.19", - "saveSpec": "[Circular]", - "fetchSpec": "2.1.19" - }, - "_spec": "2.1.19", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "mime-types@2.1.19", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "optionalDependencies": {}, - "_dependencies": { - "mime-db": "~1.35.0" - }, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/mime-types", - "error": "[Circular]", - "extraneous": false - } - }, - "devDependencies": { - "browserify": "^13.1.1", - "browserify-istanbul": "^2.0.0", - "coveralls": "^2.11.14", - "cross-spawn": "^4.0.2", - "eslint": "^3.9.1", - "fake": "^0.2.2", - "far": "^0.0.7", - "formidable": "^1.0.17", - "in-publish": "^2.0.0", - "is-node-modern": "^1.0.0", - "istanbul": "^0.4.5", - "obake": "^0.1.2", - "phantomjs-prebuilt": "^2.1.13", - "pkgfiles": "^2.3.0", - "pre-commit": "^1.1.3", - "request": "2.76.0", - "rimraf": "^2.5.4", - "tape": "^4.6.2" - }, - "license": "MIT", - "_resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", - "_integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", - "_from": "form-data@2.3.2", - "readme": "# Form-Data [![NPM Module](https://img.shields.io/npm/v/form-data.svg)](https://www.npmjs.com/package/form-data) [![Join the chat at https://gitter.im/form-data/form-data](http://form-data.github.io/images/gitterbadge.svg)](https://gitter.im/form-data/form-data)\n\nA library to create readable ```\"multipart/form-data\"``` streams. Can be used to submit forms and file uploads to other web applications.\n\nThe API of this library is inspired by the [XMLHttpRequest-2 FormData Interface][xhr2-fd].\n\n[xhr2-fd]: http://dev.w3.org/2006/webapi/XMLHttpRequest-2/Overview.html#the-formdata-interface\n\n[![Linux Build](https://img.shields.io/travis/form-data/form-data/v2.3.2.svg?label=linux:4.x-9.x)](https://travis-ci.org/form-data/form-data)\n[![MacOS Build](https://img.shields.io/travis/form-data/form-data/v2.3.2.svg?label=macos:4.x-9.x)](https://travis-ci.org/form-data/form-data)\n[![Windows Build](https://img.shields.io/appveyor/ci/alexindigo/form-data/v2.3.2.svg?label=windows:4.x-9.x)](https://ci.appveyor.com/project/alexindigo/form-data)\n\n[![Coverage Status](https://img.shields.io/coveralls/form-data/form-data/v2.3.2.svg?label=code+coverage)](https://coveralls.io/github/form-data/form-data?branch=master)\n[![Dependency Status](https://img.shields.io/david/form-data/form-data.svg)](https://david-dm.org/form-data/form-data)\n[![bitHound Overall Score](https://www.bithound.io/github/form-data/form-data/badges/score.svg)](https://www.bithound.io/github/form-data/form-data)\n\n## Install\n\n```\nnpm install --save form-data\n```\n\n## Usage\n\nIn this example we are constructing a form with 3 fields that contain a string,\na buffer and a file stream.\n\n``` javascript\nvar FormData = require('form-data');\nvar fs = require('fs');\n\nvar form = new FormData();\nform.append('my_field', 'my value');\nform.append('my_buffer', new Buffer(10));\nform.append('my_file', fs.createReadStream('/foo/bar.jpg'));\n```\n\nAlso you can use http-response stream:\n\n``` javascript\nvar FormData = require('form-data');\nvar http = require('http');\n\nvar form = new FormData();\n\nhttp.request('http://nodejs.org/images/logo.png', function(response) {\n form.append('my_field', 'my value');\n form.append('my_buffer', new Buffer(10));\n form.append('my_logo', response);\n});\n```\n\nOr @mikeal's [request](https://github.com/request/request) stream:\n\n``` javascript\nvar FormData = require('form-data');\nvar request = require('request');\n\nvar form = new FormData();\n\nform.append('my_field', 'my value');\nform.append('my_buffer', new Buffer(10));\nform.append('my_logo', request('http://nodejs.org/images/logo.png'));\n```\n\nIn order to submit this form to a web application, call ```submit(url, [callback])``` method:\n\n``` javascript\nform.submit('http://example.org/', function(err, res) {\n // res – response object (http.IncomingMessage) //\n res.resume();\n});\n\n```\n\nFor more advanced request manipulations ```submit()``` method returns ```http.ClientRequest``` object, or you can choose from one of the alternative submission methods.\n\n### Custom options\n\nYou can provide custom options, such as `maxDataSize`:\n\n``` javascript\nvar FormData = require('form-data');\n\nvar form = new FormData({ maxDataSize: 20971520 });\nform.append('my_field', 'my value');\nform.append('my_buffer', /* something big */);\n```\n\nList of available options could be found in [combined-stream](https://github.com/felixge/node-combined-stream/blob/master/lib/combined_stream.js#L7-L15)\n\n### Alternative submission methods\n\nYou can use node's http client interface:\n\n``` javascript\nvar http = require('http');\n\nvar request = http.request({\n method: 'post',\n host: 'example.org',\n path: '/upload',\n headers: form.getHeaders()\n});\n\nform.pipe(request);\n\nrequest.on('response', function(res) {\n console.log(res.statusCode);\n});\n```\n\nOr if you would prefer the `'Content-Length'` header to be set for you:\n\n``` javascript\nform.submit('example.org/upload', function(err, res) {\n console.log(res.statusCode);\n});\n```\n\nTo use custom headers and pre-known length in parts:\n\n``` javascript\nvar CRLF = '\\r\\n';\nvar form = new FormData();\n\nvar options = {\n header: CRLF + '--' + form.getBoundary() + CRLF + 'X-Custom-Header: 123' + CRLF + CRLF,\n knownLength: 1\n};\n\nform.append('my_buffer', buffer, options);\n\nform.submit('http://example.com/', function(err, res) {\n if (err) throw err;\n console.log('Done');\n});\n```\n\nForm-Data can recognize and fetch all the required information from common types of streams (```fs.readStream```, ```http.response``` and ```mikeal's request```), for some other types of streams you'd need to provide \"file\"-related information manually:\n\n``` javascript\nsomeModule.stream(function(err, stdout, stderr) {\n if (err) throw err;\n\n var form = new FormData();\n\n form.append('file', stdout, {\n filename: 'unicycle.jpg', // ... or:\n filepath: 'photos/toys/unicycle.jpg',\n contentType: 'image/jpeg',\n knownLength: 19806\n });\n\n form.submit('http://example.com/', function(err, res) {\n if (err) throw err;\n console.log('Done');\n });\n});\n```\n\nThe `filepath` property overrides `filename` and may contain a relative path. This is typically used when uploading [multiple files from a directory](https://wicg.github.io/entries-api/#dom-htmlinputelement-webkitdirectory).\n\nFor edge cases, like POST request to URL with query string or to pass HTTP auth credentials, object can be passed to `form.submit()` as first parameter:\n\n``` javascript\nform.submit({\n host: 'example.com',\n path: '/probably.php?extra=params',\n auth: 'username:password'\n}, function(err, res) {\n console.log(res.statusCode);\n});\n```\n\nIn case you need to also send custom HTTP headers with the POST request, you can use the `headers` key in first parameter of `form.submit()`:\n\n``` javascript\nform.submit({\n host: 'example.com',\n path: '/surelynot.php',\n headers: {'x-test-header': 'test-header-value'}\n}, function(err, res) {\n console.log(res.statusCode);\n});\n```\n\n### Integration with other libraries\n\n#### Request\n\nForm submission using [request](https://github.com/request/request):\n\n```javascript\nvar formData = {\n my_field: 'my_value',\n my_file: fs.createReadStream(__dirname + '/unicycle.jpg'),\n};\n\nrequest.post({url:'http://service.com/upload', formData: formData}, function(err, httpResponse, body) {\n if (err) {\n return console.error('upload failed:', err);\n }\n console.log('Upload successful! Server responded with:', body);\n});\n```\n\nFor more details see [request readme](https://github.com/request/request#multipartform-data-multipart-form-uploads).\n\n#### node-fetch\n\nYou can also submit a form using [node-fetch](https://github.com/bitinn/node-fetch):\n\n```javascript\nvar form = new FormData();\n\nform.append('a', 1);\n\nfetch('http://example.com', { method: 'POST', body: form })\n .then(function(res) {\n return res.json();\n }).then(function(json) {\n console.log(json);\n });\n```\n\n## Notes\n\n- ```getLengthSync()``` method DOESN'T calculate length for streams, use ```knownLength``` options as workaround.\n- Starting version `2.x` FormData has dropped support for `node@0.10.x`.\n\n## License\n\nForm-Data is released under the [MIT](License) license.\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/form-data/form-data/issues" - }, - "homepage": "https://github.com/form-data/form-data#readme", - "_id": "form-data@2.3.2", - "_requested": { - "type": "version", - "registry": true, - "raw": "form-data@2.3.2", - "name": "form-data", - "escapedName": "form-data", - "rawSpec": "2.3.2", - "saveSpec": "[Circular]", - "fetchSpec": "2.3.2" - }, - "_spec": "2.3.2", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "form-data@2.3.2", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "optionalDependencies": {}, - "_dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "1.0.6", - "mime-types": "^2.1.12" - }, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/form-data", - "error": "[Circular]", - "extraneous": false - }, - "formidable": { - "name": "formidable", - "description": "A node.js module for parsing form data, especially file uploads.", - "homepage": "https://github.com/felixge/node-formidable", - "license": "MIT", - "version": "1.2.1", - "devDependencies": { - "gently": "^0.8.0", - "findit": "^0.1.2", - "hashish": "^0.0.4", - "urun": "^0.0.6", - "utest": "^0.0.8", - "request": "^2.11.4" - }, - "directories": { - "lib": "./lib" - }, - "main": "./lib/index", - "scripts": { - "test": "node test/run.js", - "clean": "rm test/tmp/*" - }, - "repository": { - "type": "git", - "url": "git://github.com/felixge/node-formidable.git" - }, - "bugs": { - "url": "http://github.com/felixge/node-formidable/issues" - }, - "optionalDependencies": {}, - "_resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.1.tgz", - "_integrity": "sha512-Fs9VRguL0gqGHkXS5GQiMCr1VhZBxz0JnJs4JmMp/2jL18Fmbzvv7vOFRU+U8TBkHEE/CX1qDXzJplVULgsLeg==", - "_from": "formidable@1.2.1", - "readme": "# Formidable\n\n[![Build Status](https://travis-ci.org/felixge/node-formidable.svg?branch=master)](https://travis-ci.org/felixge/node-formidable)\n\n## Purpose\n\nA Node.js module for parsing form data, especially file uploads.\n\n## Current status\n\n**Maintainers Wanted:** Please see https://github.com/felixge/node-formidable/issues/412\n\nThis module was developed for [Transloadit](http://transloadit.com/), a service focused on uploading\nand encoding images and videos. It has been battle-tested against hundreds of GB of file uploads from\na large variety of clients and is considered production-ready.\n\n## Features\n\n* Fast (~500mb/sec), non-buffering multipart parser\n* Automatically writing file uploads to disk\n* Low memory footprint\n* Graceful error handling\n* Very high test coverage\n\n## Installation\n\n```sh\nnpm i -S formidable\n```\n\nThis is a low-level package, and if you're using a high-level framework it may already be included. However, [Express v4](http://expressjs.com) does not include any multipart handling, nor does [body-parser](https://github.com/expressjs/body-parser).\n\nNote: Formidable requires [gently](http://github.com/felixge/node-gently) to run the unit tests, but you won't need it for just using the library.\n\n## Example\n\nParse an incoming file upload.\n```javascript\nvar formidable = require('formidable'),\n http = require('http'),\n util = require('util');\n\nhttp.createServer(function(req, res) {\n if (req.url == '/upload' && req.method.toLowerCase() == 'post') {\n // parse a file upload\n var form = new formidable.IncomingForm();\n\n form.parse(req, function(err, fields, files) {\n res.writeHead(200, {'content-type': 'text/plain'});\n res.write('received upload:\\n\\n');\n res.end(util.inspect({fields: fields, files: files}));\n });\n\n return;\n }\n\n // show a file upload form\n res.writeHead(200, {'content-type': 'text/html'});\n res.end(\n '
'+\n '
'+\n '
'+\n ''+\n '
'\n );\n}).listen(8080);\n```\n## API\n\n### Formidable.IncomingForm\n```javascript\nvar form = new formidable.IncomingForm()\n```\nCreates a new incoming form.\n\n```javascript\nform.encoding = 'utf-8';\n```\nSets encoding for incoming form fields.\n\n```javascript\nform.uploadDir = \"/my/dir\";\n```\nSets the directory for placing file uploads in. You can move them later on using\n`fs.rename()`. The default is `os.tmpdir()`.\n\n```javascript\nform.keepExtensions = false;\n```\nIf you want the files written to `form.uploadDir` to include the extensions of the original files, set this property to `true`.\n\n```javascript\nform.type\n```\nEither 'multipart' or 'urlencoded' depending on the incoming request.\n\n```javascript\nform.maxFieldsSize = 20 * 1024 * 1024;\n```\nLimits the amount of memory all fields together (except files) can allocate in bytes.\nIf this value is exceeded, an `'error'` event is emitted. The default\nsize is 20MB.\n\n```javascript\nform.maxFileSize = 200 * 1024 * 1024;\n```\nLimits the size of uploaded file.\nIf this value is exceeded, an `'error'` event is emitted. The default\nsize is 200MB.\n\n```javascript\nform.maxFields = 1000;\n```\nLimits the number of fields that the querystring parser will decode. Defaults\nto 1000 (0 for unlimited).\n\n```javascript\nform.hash = false;\n```\nIf you want checksums calculated for incoming files, set this to either `'sha1'` or `'md5'`.\n\n```javascript\nform.multiples = false;\n```\nIf this option is enabled, when you call `form.parse`, the `files` argument will contain arrays of files for inputs which submit multiple files using the HTML5 `multiple` attribute.\n\n```javascript\nform.bytesReceived\n```\nThe amount of bytes received for this form so far.\n\n```javascript\nform.bytesExpected\n```\nThe expected number of bytes in this form.\n\n```javascript\nform.parse(request, [cb]);\n```\nParses an incoming node.js `request` containing form data. If `cb` is provided, all fields and files are collected and passed to the callback:\n\n\n```javascript\nform.parse(req, function(err, fields, files) {\n // ...\n});\n\nform.onPart(part);\n```\nYou may overwrite this method if you are interested in directly accessing the multipart stream. Doing so will disable any `'field'` / `'file'` events processing which would occur otherwise, making you fully responsible for handling the processing.\n\n```javascript\nform.onPart = function(part) {\n part.addListener('data', function() {\n // ...\n });\n}\n```\nIf you want to use formidable to only handle certain parts for you, you can do so:\n```javascript\nform.onPart = function(part) {\n if (!part.filename) {\n // let formidable handle all non-file parts\n form.handlePart(part);\n }\n}\n```\nCheck the code in this method for further inspiration.\n\n\n### Formidable.File\n```javascript\nfile.size = 0\n```\nThe size of the uploaded file in bytes. If the file is still being uploaded (see `'fileBegin'` event), this property says how many bytes of the file have been written to disk yet.\n```javascript\nfile.path = null\n```\nThe path this file is being written to. You can modify this in the `'fileBegin'` event in\ncase you are unhappy with the way formidable generates a temporary path for your files.\n```javascript\nfile.name = null\n```\nThe name this file had according to the uploading client.\n```javascript\nfile.type = null\n```\nThe mime type of this file, according to the uploading client.\n```javascript\nfile.lastModifiedDate = null\n```\nA date object (or `null`) containing the time this file was last written to. Mostly\nhere for compatibility with the [W3C File API Draft](http://dev.w3.org/2006/webapi/FileAPI/).\n```javascript\nfile.hash = null\n```\nIf hash calculation was set, you can read the hex digest out of this var.\n\n#### Formidable.File#toJSON()\n\n This method returns a JSON-representation of the file, allowing you to\n `JSON.stringify()` the file which is useful for logging and responding\n to requests.\n\n### Events\n\n\n#### 'progress'\n\nEmitted after each incoming chunk of data that has been parsed. Can be used to roll your own progress bar.\n\n```javascript\nform.on('progress', function(bytesReceived, bytesExpected) {\n});\n```\n\n\n\n#### 'field'\n\nEmitted whenever a field / value pair has been received.\n\n```javascript\nform.on('field', function(name, value) {\n});\n```\n\n#### 'fileBegin'\n\nEmitted whenever a new file is detected in the upload stream. Use this event if\nyou want to stream the file to somewhere else while buffering the upload on\nthe file system.\n\n```javascript\nform.on('fileBegin', function(name, file) {\n});\n```\n\n#### 'file'\n\nEmitted whenever a field / file pair has been received. `file` is an instance of `File`.\n\n```javascript\nform.on('file', function(name, file) {\n});\n```\n\n#### 'error'\n\nEmitted when there is an error processing the incoming form. A request that experiences an error is automatically paused, you will have to manually call `request.resume()` if you want the request to continue firing `'data'` events.\n\n```javascript\nform.on('error', function(err) {\n});\n```\n\n#### 'aborted'\n\n\nEmitted when the request was aborted by the user. Right now this can be due to a 'timeout' or 'close' event on the socket. After this event is emitted, an `error` event will follow. In the future there will be a separate 'timeout' event (needs a change in the node core).\n```javascript\nform.on('aborted', function() {\n});\n```\n\n##### 'end'\n```javascript\nform.on('end', function() {\n});\n```\nEmitted when the entire request has been received, and all contained files have finished flushing to disk. This is a great place for you to send your response.\n\n\n\n## Changelog\n\n### v1.1.1 (2017-01-15)\n\n * Fix DeprecationWarning about os.tmpDir() (Christian)\n * Update `buffer.write` order of arguments for Node 7 (Kornel Lesiński)\n * JSON Parser emits error events to the IncomingForm (alessio.montagnani)\n * Improved Content-Disposition parsing (Sebastien)\n * Access WriteStream of fs during runtime instead of include time (Jonas Amundsen)\n * Use built-in toString to convert buffer to hex (Charmander)\n * Add hash to json if present (Nick Stamas)\n * Add license to package.json (Simen Bekkhus)\n\n### v1.0.14 (2013-05-03)\n\n* Add failing hash tests. (Ben Trask)\n* Enable hash calculation again (Eugene Girshov)\n* Test for immediate data events (Tim Smart)\n* Re-arrange IncomingForm#parse (Tim Smart)\n\n### v1.0.13\n\n* Only update hash if update method exists (Sven Lito)\n* According to travis v0.10 needs to go quoted (Sven Lito)\n* Bumping build node versions (Sven Lito)\n* Additional fix for empty requests (Eugene Girshov)\n* Change the default to 1000, to match the new Node behaviour. (OrangeDog)\n* Add ability to control maxKeys in the querystring parser. (OrangeDog)\n* Adjust test case to work with node 0.9.x (Eugene Girshov)\n* Update package.json (Sven Lito)\n* Path adjustment according to eb4468b (Markus Ast)\n\n### v1.0.12\n\n* Emit error on aborted connections (Eugene Girshov)\n* Add support for empty requests (Eugene Girshov)\n* Fix name/filename handling in Content-Disposition (jesperp)\n* Tolerate malformed closing boundary in multipart (Eugene Girshov)\n* Ignore preamble in multipart messages (Eugene Girshov)\n* Add support for application/json (Mike Frey, Carlos Rodriguez)\n* Add support for Base64 encoding (Elmer Bulthuis)\n* Add File#toJSON (TJ Holowaychuk)\n* Remove support for Node.js 0.4 & 0.6 (Andrew Kelley)\n* Documentation improvements (Sven Lito, Andre Azevedo)\n* Add support for application/octet-stream (Ion Lupascu, Chris Scribner)\n* Use os.tmpdir() to get tmp directory (Andrew Kelley)\n* Improve package.json (Andrew Kelley, Sven Lito)\n* Fix benchmark script (Andrew Kelley)\n* Fix scope issue in incoming_forms (Sven Lito)\n* Fix file handle leak on error (OrangeDog)\n\n## License\n\nFormidable is licensed under the MIT license.\n\n## Ports\n\n* [multipart-parser](http://github.com/FooBarWidget/multipart-parser): a C++ parser based on formidable\n\n## Credits\n\n* [Ryan Dahl](http://twitter.com/ryah) for his work on [http-parser](http://github.com/ry/http-parser) which heavily inspired multipart_parser.js\n", - "readmeFilename": "Readme.md", - "dependencies": {}, - "_id": "formidable@1.2.1", - "_requested": { - "type": "version", - "registry": true, - "raw": "formidable@1.2.1", - "name": "formidable", - "escapedName": "formidable", - "rawSpec": "1.2.1", - "saveSpec": "[Circular]", - "fetchSpec": "1.2.1" - }, - "_spec": "1.2.1", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "formidable@1.2.1", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "_dependencies": {}, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/formidable", - "error": "[Circular]", - "extraneous": false - }, - "methods": { - "name": "methods", - "description": "HTTP methods that node supports", - "version": "1.1.2", - "contributors": [ - { - "name": "Douglas Christopher Wilson", - "email": "doug@somethingdoug.com" - }, - { - "name": "Jonathan Ong", - "email": "me@jongleberry.com", - "url": "http://jongleberry.com" - }, - { - "name": "TJ Holowaychuk", - "email": "tj@vision-media.ca", - "url": "http://tjholowaychuk.com" - } - ], - "license": "MIT", - "repository": { - "type": "git", - "url": "git+https://github.com/jshttp/methods.git" - }, - "devDependencies": { - "istanbul": "0.4.1", - "mocha": "1.21.5" - }, - "files": [ - "index.js", - "HISTORY.md", - "LICENSE" - ], - "engines": { - "node": ">= 0.6" - }, - "scripts": { - "test": "mocha --reporter spec --bail --check-leaks test/", - "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/", - "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/" - }, - "browser": { - "http": false - }, - "keywords": [ - "http", - "methods" - ], - "_resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "_integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", - "_from": "methods@1.1.2", - "readme": "# Methods\n\n[![NPM Version][npm-image]][npm-url]\n[![NPM Downloads][downloads-image]][downloads-url]\n[![Node.js Version][node-version-image]][node-version-url]\n[![Build Status][travis-image]][travis-url]\n[![Test Coverage][coveralls-image]][coveralls-url]\n\nHTTP verbs that Node.js core's HTTP parser supports.\n\nThis module provides an export that is just like `http.METHODS` from Node.js core,\nwith the following differences:\n\n * All method names are lower-cased.\n * Contains a fallback list of methods for Node.js versions that do not have a\n `http.METHODS` export (0.10 and lower).\n * Provides the fallback list when using tools like `browserify` without pulling\n in the `http` shim module.\n\n## Install\n\n```bash\n$ npm install methods\n```\n\n## API\n\n```js\nvar methods = require('methods')\n```\n\n### methods\n\nThis is an array of lower-cased method names that Node.js supports. If Node.js\nprovides the `http.METHODS` export, then this is the same array lower-cased,\notherwise it is a snapshot of the verbs from Node.js 0.10.\n\n## License\n\n[MIT](LICENSE)\n\n[npm-image]: https://img.shields.io/npm/v/methods.svg?style=flat\n[npm-url]: https://npmjs.org/package/methods\n[node-version-image]: https://img.shields.io/node/v/methods.svg?style=flat\n[node-version-url]: https://nodejs.org/en/download/\n[travis-image]: https://img.shields.io/travis/jshttp/methods.svg?style=flat\n[travis-url]: https://travis-ci.org/jshttp/methods\n[coveralls-image]: https://img.shields.io/coveralls/jshttp/methods.svg?style=flat\n[coveralls-url]: https://coveralls.io/r/jshttp/methods?branch=master\n[downloads-image]: https://img.shields.io/npm/dm/methods.svg?style=flat\n[downloads-url]: https://npmjs.org/package/methods\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/jshttp/methods/issues" - }, - "homepage": "https://github.com/jshttp/methods#readme", - "_id": "methods@1.1.2", - "_requested": { - "type": "version", - "registry": true, - "raw": "methods@1.1.2", - "name": "methods", - "escapedName": "methods", - "rawSpec": "1.1.2", - "saveSpec": "[Circular]", - "fetchSpec": "1.1.2" - }, - "_spec": "1.1.2", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "methods@1.1.2", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "dependencies": {}, - "optionalDependencies": {}, - "_dependencies": {}, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/methods", - "error": "[Circular]", - "extraneous": false - }, - "mime": { - "author": { - "name": "Robert Kieffer", - "email": "robert@broofa.com", - "url": "http://github.com/broofa" - }, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - }, - "contributors": [ - { - "name": "Benjamin Thomas", - "email": "benjamin@benjaminthomas.org", - "url": "http://github.com/bentomas" - } - ], - "description": "A comprehensive library for mime-type mapping", - "license": "MIT", - "dependencies": {}, - "devDependencies": { - "github-release-notes": "0.13.1", - "mime-db": "1.31.0", - "mime-score": "1.1.0" - }, - "scripts": { - "prepare": "node src/build.js", - "changelog": "gren changelog --tags=all --generate --override", - "test": "node src/test.js" - }, - "keywords": [ - "util", - "mime" - ], - "main": "mime.js", - "name": "mime", - "repository": { - "url": "git+https://github.com/broofa/node-mime.git", - "type": "git" - }, - "version": "1.6.0", - "_resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "_integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "_from": "mime@1.6.0", - "readme": "# mime\n\nComprehensive MIME type mapping API based on mime-db module.\n\n## Install\n\nInstall with [npm](http://github.com/isaacs/npm):\n\n npm install mime\n\n## Contributing / Testing\n\n npm run test\n\n## Command Line\n\n mime [path_string]\n\nE.g.\n\n > mime scripts/jquery.js\n application/javascript\n\n## API - Queries\n\n### mime.lookup(path)\nGet the mime type associated with a file, if no mime type is found `application/octet-stream` is returned. Performs a case-insensitive lookup using the extension in `path` (the substring after the last '/' or '.'). E.g.\n\n```js\nvar mime = require('mime');\n\nmime.lookup('/path/to/file.txt'); // => 'text/plain'\nmime.lookup('file.txt'); // => 'text/plain'\nmime.lookup('.TXT'); // => 'text/plain'\nmime.lookup('htm'); // => 'text/html'\n```\n\n### mime.default_type\nSets the mime type returned when `mime.lookup` fails to find the extension searched for. (Default is `application/octet-stream`.)\n\n### mime.extension(type)\nGet the default extension for `type`\n\n```js\nmime.extension('text/html'); // => 'html'\nmime.extension('application/octet-stream'); // => 'bin'\n```\n\n### mime.charsets.lookup()\n\nMap mime-type to charset\n\n```js\nmime.charsets.lookup('text/plain'); // => 'UTF-8'\n```\n\n(The logic for charset lookups is pretty rudimentary. Feel free to suggest improvements.)\n\n## API - Defining Custom Types\n\nCustom type mappings can be added on a per-project basis via the following APIs.\n\n### mime.define()\n\nAdd custom mime/extension mappings\n\n```js\nmime.define({\n 'text/x-some-format': ['x-sf', 'x-sft', 'x-sfml'],\n 'application/x-my-type': ['x-mt', 'x-mtt'],\n // etc ...\n});\n\nmime.lookup('x-sft'); // => 'text/x-some-format'\n```\n\nThe first entry in the extensions array is returned by `mime.extension()`. E.g.\n\n```js\nmime.extension('text/x-some-format'); // => 'x-sf'\n```\n\n### mime.load(filepath)\n\nLoad mappings from an Apache \".types\" format file\n\n```js\nmime.load('./my_project.types');\n```\nThe .types file format is simple - See the `types` dir for examples.\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/broofa/node-mime/issues" - }, - "homepage": "https://github.com/broofa/node-mime#readme", - "_id": "mime@1.6.0", - "_requested": { - "type": "version", - "registry": true, - "raw": "mime@1.6.0", - "name": "mime", - "escapedName": "mime", - "rawSpec": "1.6.0", - "saveSpec": "[Circular]", - "fetchSpec": "1.6.0" - }, - "_spec": "1.6.0", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "mime@1.6.0", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "optionalDependencies": {}, - "_dependencies": {}, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/mime", - "error": "[Circular]", - "extraneous": false - }, - "qs": { - "name": "qs", - "description": "A querystring parser that supports nesting and arrays, with a depth limit", - "homepage": "https://github.com/ljharb/qs", - "version": "6.5.2", - "repository": { - "type": "git", - "url": "git+https://github.com/ljharb/qs.git" - }, - "main": "lib/index.js", - "contributors": [ - { - "name": "Jordan Harband", - "email": "ljharb@gmail.com", - "url": "http://ljharb.codes" - } - ], - "keywords": [ - "querystring", - "qs" - ], - "engines": { - "node": ">=0.6" - }, - "dependencies": {}, - "devDependencies": { - "@ljharb/eslint-config": "^12.2.1", - "browserify": "^16.2.0", - "covert": "^1.1.0", - "editorconfig-tools": "^0.1.1", - "eslint": "^4.19.1", - "evalmd": "^0.0.17", - "iconv-lite": "^0.4.21", - "mkdirp": "^0.5.1", - "qs-iconv": "^1.0.4", - "safe-publish-latest": "^1.1.1", - "safer-buffer": "^2.1.2", - "tape": "^4.9.0" - }, - "scripts": { - "prepublish": "safe-publish-latest && npm run dist", - "pretest": "npm run --silent readme && npm run --silent lint", - "test": "npm run --silent coverage", - "tests-only": "node test", - "readme": "evalmd README.md", - "prelint": "editorconfig-tools check * lib/* test/*", - "lint": "eslint lib/*.js test/*.js", - "coverage": "covert test", - "dist": "mkdirp dist && browserify --standalone Qs lib/index.js > dist/qs.js" - }, - "license": "BSD-3-Clause", - "_resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "_integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "_from": "qs@6.5.2", - "readme": "# qs [![Version Badge][2]][1]\n\n[![Build Status][3]][4]\n[![dependency status][5]][6]\n[![dev dependency status][7]][8]\n[![License][license-image]][license-url]\n[![Downloads][downloads-image]][downloads-url]\n\n[![npm badge][11]][1]\n\nA querystring parsing and stringifying library with some added security.\n\nLead Maintainer: [Jordan Harband](https://github.com/ljharb)\n\nThe **qs** module was originally created and maintained by [TJ Holowaychuk](https://github.com/visionmedia/node-querystring).\n\n## Usage\n\n```javascript\nvar qs = require('qs');\nvar assert = require('assert');\n\nvar obj = qs.parse('a=c');\nassert.deepEqual(obj, { a: 'c' });\n\nvar str = qs.stringify(obj);\nassert.equal(str, 'a=c');\n```\n\n### Parsing Objects\n\n[](#preventEval)\n```javascript\nqs.parse(string, [options]);\n```\n\n**qs** allows you to create nested objects within your query strings, by surrounding the name of sub-keys with square brackets `[]`.\nFor example, the string `'foo[bar]=baz'` converts to:\n\n```javascript\nassert.deepEqual(qs.parse('foo[bar]=baz'), {\n foo: {\n bar: 'baz'\n }\n});\n```\n\nWhen using the `plainObjects` option the parsed value is returned as a null object, created via `Object.create(null)` and as such you should be aware that prototype methods will not exist on it and a user may set those names to whatever value they like:\n\n```javascript\nvar nullObject = qs.parse('a[hasOwnProperty]=b', { plainObjects: true });\nassert.deepEqual(nullObject, { a: { hasOwnProperty: 'b' } });\n```\n\nBy default parameters that would overwrite properties on the object prototype are ignored, if you wish to keep the data from those fields either use `plainObjects` as mentioned above, or set `allowPrototypes` to `true` which will allow user input to overwrite those properties. *WARNING* It is generally a bad idea to enable this option as it can cause problems when attempting to use the properties that have been overwritten. Always be careful with this option.\n\n```javascript\nvar protoObject = qs.parse('a[hasOwnProperty]=b', { allowPrototypes: true });\nassert.deepEqual(protoObject, { a: { hasOwnProperty: 'b' } });\n```\n\nURI encoded strings work too:\n\n```javascript\nassert.deepEqual(qs.parse('a%5Bb%5D=c'), {\n a: { b: 'c' }\n});\n```\n\nYou can also nest your objects, like `'foo[bar][baz]=foobarbaz'`:\n\n```javascript\nassert.deepEqual(qs.parse('foo[bar][baz]=foobarbaz'), {\n foo: {\n bar: {\n baz: 'foobarbaz'\n }\n }\n});\n```\n\nBy default, when nesting objects **qs** will only parse up to 5 children deep. This means if you attempt to parse a string like\n`'a[b][c][d][e][f][g][h][i]=j'` your resulting object will be:\n\n```javascript\nvar expected = {\n a: {\n b: {\n c: {\n d: {\n e: {\n f: {\n '[g][h][i]': 'j'\n }\n }\n }\n }\n }\n }\n};\nvar string = 'a[b][c][d][e][f][g][h][i]=j';\nassert.deepEqual(qs.parse(string), expected);\n```\n\nThis depth can be overridden by passing a `depth` option to `qs.parse(string, [options])`:\n\n```javascript\nvar deep = qs.parse('a[b][c][d][e][f][g][h][i]=j', { depth: 1 });\nassert.deepEqual(deep, { a: { b: { '[c][d][e][f][g][h][i]': 'j' } } });\n```\n\nThe depth limit helps mitigate abuse when **qs** is used to parse user input, and it is recommended to keep it a reasonably small number.\n\nFor similar reasons, by default **qs** will only parse up to 1000 parameters. This can be overridden by passing a `parameterLimit` option:\n\n```javascript\nvar limited = qs.parse('a=b&c=d', { parameterLimit: 1 });\nassert.deepEqual(limited, { a: 'b' });\n```\n\nTo bypass the leading question mark, use `ignoreQueryPrefix`:\n\n```javascript\nvar prefixed = qs.parse('?a=b&c=d', { ignoreQueryPrefix: true });\nassert.deepEqual(prefixed, { a: 'b', c: 'd' });\n```\n\nAn optional delimiter can also be passed:\n\n```javascript\nvar delimited = qs.parse('a=b;c=d', { delimiter: ';' });\nassert.deepEqual(delimited, { a: 'b', c: 'd' });\n```\n\nDelimiters can be a regular expression too:\n\n```javascript\nvar regexed = qs.parse('a=b;c=d,e=f', { delimiter: /[;,]/ });\nassert.deepEqual(regexed, { a: 'b', c: 'd', e: 'f' });\n```\n\nOption `allowDots` can be used to enable dot notation:\n\n```javascript\nvar withDots = qs.parse('a.b=c', { allowDots: true });\nassert.deepEqual(withDots, { a: { b: 'c' } });\n```\n\n### Parsing Arrays\n\n**qs** can also parse arrays using a similar `[]` notation:\n\n```javascript\nvar withArray = qs.parse('a[]=b&a[]=c');\nassert.deepEqual(withArray, { a: ['b', 'c'] });\n```\n\nYou may specify an index as well:\n\n```javascript\nvar withIndexes = qs.parse('a[1]=c&a[0]=b');\nassert.deepEqual(withIndexes, { a: ['b', 'c'] });\n```\n\nNote that the only difference between an index in an array and a key in an object is that the value between the brackets must be a number\nto create an array. When creating arrays with specific indices, **qs** will compact a sparse array to only the existing values preserving\ntheir order:\n\n```javascript\nvar noSparse = qs.parse('a[1]=b&a[15]=c');\nassert.deepEqual(noSparse, { a: ['b', 'c'] });\n```\n\nNote that an empty string is also a value, and will be preserved:\n\n```javascript\nvar withEmptyString = qs.parse('a[]=&a[]=b');\nassert.deepEqual(withEmptyString, { a: ['', 'b'] });\n\nvar withIndexedEmptyString = qs.parse('a[0]=b&a[1]=&a[2]=c');\nassert.deepEqual(withIndexedEmptyString, { a: ['b', '', 'c'] });\n```\n\n**qs** will also limit specifying indices in an array to a maximum index of `20`. Any array members with an index of greater than `20` will\ninstead be converted to an object with the index as the key:\n\n```javascript\nvar withMaxIndex = qs.parse('a[100]=b');\nassert.deepEqual(withMaxIndex, { a: { '100': 'b' } });\n```\n\nThis limit can be overridden by passing an `arrayLimit` option:\n\n```javascript\nvar withArrayLimit = qs.parse('a[1]=b', { arrayLimit: 0 });\nassert.deepEqual(withArrayLimit, { a: { '1': 'b' } });\n```\n\nTo disable array parsing entirely, set `parseArrays` to `false`.\n\n```javascript\nvar noParsingArrays = qs.parse('a[]=b', { parseArrays: false });\nassert.deepEqual(noParsingArrays, { a: { '0': 'b' } });\n```\n\nIf you mix notations, **qs** will merge the two items into an object:\n\n```javascript\nvar mixedNotation = qs.parse('a[0]=b&a[b]=c');\nassert.deepEqual(mixedNotation, { a: { '0': 'b', b: 'c' } });\n```\n\nYou can also create arrays of objects:\n\n```javascript\nvar arraysOfObjects = qs.parse('a[][b]=c');\nassert.deepEqual(arraysOfObjects, { a: [{ b: 'c' }] });\n```\n\n### Stringifying\n\n[](#preventEval)\n```javascript\nqs.stringify(object, [options]);\n```\n\nWhen stringifying, **qs** by default URI encodes output. Objects are stringified as you would expect:\n\n```javascript\nassert.equal(qs.stringify({ a: 'b' }), 'a=b');\nassert.equal(qs.stringify({ a: { b: 'c' } }), 'a%5Bb%5D=c');\n```\n\nThis encoding can be disabled by setting the `encode` option to `false`:\n\n```javascript\nvar unencoded = qs.stringify({ a: { b: 'c' } }, { encode: false });\nassert.equal(unencoded, 'a[b]=c');\n```\n\nEncoding can be disabled for keys by setting the `encodeValuesOnly` option to `true`:\n```javascript\nvar encodedValues = qs.stringify(\n { a: 'b', c: ['d', 'e=f'], f: [['g'], ['h']] },\n { encodeValuesOnly: true }\n);\nassert.equal(encodedValues,'a=b&c[0]=d&c[1]=e%3Df&f[0][0]=g&f[1][0]=h');\n```\n\nThis encoding can also be replaced by a custom encoding method set as `encoder` option:\n\n```javascript\nvar encoded = qs.stringify({ a: { b: 'c' } }, { encoder: function (str) {\n // Passed in values `a`, `b`, `c`\n return // Return encoded string\n}})\n```\n\n_(Note: the `encoder` option does not apply if `encode` is `false`)_\n\nAnalogue to the `encoder` there is a `decoder` option for `parse` to override decoding of properties and values:\n\n```javascript\nvar decoded = qs.parse('x=z', { decoder: function (str) {\n // Passed in values `x`, `z`\n return // Return decoded string\n}})\n```\n\nExamples beyond this point will be shown as though the output is not URI encoded for clarity. Please note that the return values in these cases *will* be URI encoded during real usage.\n\nWhen arrays are stringified, by default they are given explicit indices:\n\n```javascript\nqs.stringify({ a: ['b', 'c', 'd'] });\n// 'a[0]=b&a[1]=c&a[2]=d'\n```\n\nYou may override this by setting the `indices` option to `false`:\n\n```javascript\nqs.stringify({ a: ['b', 'c', 'd'] }, { indices: false });\n// 'a=b&a=c&a=d'\n```\n\nYou may use the `arrayFormat` option to specify the format of the output array:\n\n```javascript\nqs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'indices' })\n// 'a[0]=b&a[1]=c'\nqs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'brackets' })\n// 'a[]=b&a[]=c'\nqs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'repeat' })\n// 'a=b&a=c'\n```\n\nWhen objects are stringified, by default they use bracket notation:\n\n```javascript\nqs.stringify({ a: { b: { c: 'd', e: 'f' } } });\n// 'a[b][c]=d&a[b][e]=f'\n```\n\nYou may override this to use dot notation by setting the `allowDots` option to `true`:\n\n```javascript\nqs.stringify({ a: { b: { c: 'd', e: 'f' } } }, { allowDots: true });\n// 'a.b.c=d&a.b.e=f'\n```\n\nEmpty strings and null values will omit the value, but the equals sign (=) remains in place:\n\n```javascript\nassert.equal(qs.stringify({ a: '' }), 'a=');\n```\n\nKey with no values (such as an empty object or array) will return nothing:\n\n```javascript\nassert.equal(qs.stringify({ a: [] }), '');\nassert.equal(qs.stringify({ a: {} }), '');\nassert.equal(qs.stringify({ a: [{}] }), '');\nassert.equal(qs.stringify({ a: { b: []} }), '');\nassert.equal(qs.stringify({ a: { b: {}} }), '');\n```\n\nProperties that are set to `undefined` will be omitted entirely:\n\n```javascript\nassert.equal(qs.stringify({ a: null, b: undefined }), 'a=');\n```\n\nThe query string may optionally be prepended with a question mark:\n\n```javascript\nassert.equal(qs.stringify({ a: 'b', c: 'd' }, { addQueryPrefix: true }), '?a=b&c=d');\n```\n\nThe delimiter may be overridden with stringify as well:\n\n```javascript\nassert.equal(qs.stringify({ a: 'b', c: 'd' }, { delimiter: ';' }), 'a=b;c=d');\n```\n\nIf you only want to override the serialization of `Date` objects, you can provide a `serializeDate` option:\n\n```javascript\nvar date = new Date(7);\nassert.equal(qs.stringify({ a: date }), 'a=1970-01-01T00:00:00.007Z'.replace(/:/g, '%3A'));\nassert.equal(\n qs.stringify({ a: date }, { serializeDate: function (d) { return d.getTime(); } }),\n 'a=7'\n);\n```\n\nYou may use the `sort` option to affect the order of parameter keys:\n\n```javascript\nfunction alphabeticalSort(a, b) {\n return a.localeCompare(b);\n}\nassert.equal(qs.stringify({ a: 'c', z: 'y', b : 'f' }, { sort: alphabeticalSort }), 'a=c&b=f&z=y');\n```\n\nFinally, you can use the `filter` option to restrict which keys will be included in the stringified output.\nIf you pass a function, it will be called for each key to obtain the replacement value. Otherwise, if you\npass an array, it will be used to select properties and array indices for stringification:\n\n```javascript\nfunction filterFunc(prefix, value) {\n if (prefix == 'b') {\n // Return an `undefined` value to omit a property.\n return;\n }\n if (prefix == 'e[f]') {\n return value.getTime();\n }\n if (prefix == 'e[g][0]') {\n return value * 2;\n }\n return value;\n}\nqs.stringify({ a: 'b', c: 'd', e: { f: new Date(123), g: [2] } }, { filter: filterFunc });\n// 'a=b&c=d&e[f]=123&e[g][0]=4'\nqs.stringify({ a: 'b', c: 'd', e: 'f' }, { filter: ['a', 'e'] });\n// 'a=b&e=f'\nqs.stringify({ a: ['b', 'c', 'd'], e: 'f' }, { filter: ['a', 0, 2] });\n// 'a[0]=b&a[2]=d'\n```\n\n### Handling of `null` values\n\nBy default, `null` values are treated like empty strings:\n\n```javascript\nvar withNull = qs.stringify({ a: null, b: '' });\nassert.equal(withNull, 'a=&b=');\n```\n\nParsing does not distinguish between parameters with and without equal signs. Both are converted to empty strings.\n\n```javascript\nvar equalsInsensitive = qs.parse('a&b=');\nassert.deepEqual(equalsInsensitive, { a: '', b: '' });\n```\n\nTo distinguish between `null` values and empty strings use the `strictNullHandling` flag. In the result string the `null`\nvalues have no `=` sign:\n\n```javascript\nvar strictNull = qs.stringify({ a: null, b: '' }, { strictNullHandling: true });\nassert.equal(strictNull, 'a&b=');\n```\n\nTo parse values without `=` back to `null` use the `strictNullHandling` flag:\n\n```javascript\nvar parsedStrictNull = qs.parse('a&b=', { strictNullHandling: true });\nassert.deepEqual(parsedStrictNull, { a: null, b: '' });\n```\n\nTo completely skip rendering keys with `null` values, use the `skipNulls` flag:\n\n```javascript\nvar nullsSkipped = qs.stringify({ a: 'b', c: null}, { skipNulls: true });\nassert.equal(nullsSkipped, 'a=b');\n```\n\n### Dealing with special character sets\n\nBy default the encoding and decoding of characters is done in `utf-8`. If you\nwish to encode querystrings to a different character set (i.e.\n[Shift JIS](https://en.wikipedia.org/wiki/Shift_JIS)) you can use the\n[`qs-iconv`](https://github.com/martinheidegger/qs-iconv) library:\n\n```javascript\nvar encoder = require('qs-iconv/encoder')('shift_jis');\nvar shiftJISEncoded = qs.stringify({ a: 'こんにちは!' }, { encoder: encoder });\nassert.equal(shiftJISEncoded, 'a=%82%B1%82%F1%82%C9%82%BF%82%CD%81I');\n```\n\nThis also works for decoding of query strings:\n\n```javascript\nvar decoder = require('qs-iconv/decoder')('shift_jis');\nvar obj = qs.parse('a=%82%B1%82%F1%82%C9%82%BF%82%CD%81I', { decoder: decoder });\nassert.deepEqual(obj, { a: 'こんにちは!' });\n```\n\n### RFC 3986 and RFC 1738 space encoding\n\nRFC3986 used as default option and encodes ' ' to *%20* which is backward compatible.\nIn the same time, output can be stringified as per RFC1738 with ' ' equal to '+'.\n\n```\nassert.equal(qs.stringify({ a: 'b c' }), 'a=b%20c');\nassert.equal(qs.stringify({ a: 'b c' }, { format : 'RFC3986' }), 'a=b%20c');\nassert.equal(qs.stringify({ a: 'b c' }, { format : 'RFC1738' }), 'a=b+c');\n```\n\n[1]: https://npmjs.org/package/qs\n[2]: http://versionbadg.es/ljharb/qs.svg\n[3]: https://api.travis-ci.org/ljharb/qs.svg\n[4]: https://travis-ci.org/ljharb/qs\n[5]: https://david-dm.org/ljharb/qs.svg\n[6]: https://david-dm.org/ljharb/qs\n[7]: https://david-dm.org/ljharb/qs/dev-status.svg\n[8]: https://david-dm.org/ljharb/qs?type=dev\n[9]: https://ci.testling.com/ljharb/qs.png\n[10]: https://ci.testling.com/ljharb/qs\n[11]: https://nodei.co/npm/qs.png?downloads=true&stars=true\n[license-image]: http://img.shields.io/npm/l/qs.svg\n[license-url]: LICENSE\n[downloads-image]: http://img.shields.io/npm/dm/qs.svg\n[downloads-url]: http://npm-stat.com/charts.html?package=qs\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/ljharb/qs/issues" - }, - "_id": "qs@6.5.2", - "_requested": { - "type": "version", - "registry": true, - "raw": "qs@6.5.2", - "name": "qs", - "escapedName": "qs", - "rawSpec": "6.5.2", - "saveSpec": "[Circular]", - "fetchSpec": "6.5.2" - }, - "_spec": "6.5.2", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "qs@6.5.2", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "optionalDependencies": {}, - "_dependencies": {}, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/qs", - "error": "[Circular]", - "extraneous": false - }, - "readable-stream": { - "name": "readable-stream", - "version": "2.3.6", - "description": "Streams3, a user-land copy of the stream library from Node.js", - "main": "readable.js", - "dependencies": { - "core-util-is": { - "name": "core-util-is", - "version": "1.0.2", - "description": "The `util.is*` functions introduced in Node v0.12.", - "main": "lib/util.js", - "repository": { - "type": "git", - "url": "git://github.com/isaacs/core-util-is.git" - }, - "keywords": [ - "util", - "isBuffer", - "isArray", - "isNumber", - "isString", - "isRegExp", - "isThis", - "isThat", - "polyfill" - ], - "author": { - "name": "Isaac Z. Schlueter", - "email": "i@izs.me", - "url": "http://blog.izs.me/" - }, - "license": "MIT", - "bugs": { - "url": "https://github.com/isaacs/core-util-is/issues" - }, - "scripts": { - "test": "tap test.js" - }, - "devDependencies": { - "tap": "^2.3.0" - }, - "_resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "_integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "_from": "core-util-is@1.0.2", - "readme": "# core-util-is\n\nThe `util.is*` functions introduced in Node v0.12.\n", - "readmeFilename": "README.md", - "homepage": "https://github.com/isaacs/core-util-is#readme", - "_id": "core-util-is@1.0.2", - "_requested": { - "type": "version", - "registry": true, - "raw": "core-util-is@1.0.2", - "name": "core-util-is", - "escapedName": "core-util-is", - "rawSpec": "1.0.2", - "saveSpec": "[Circular]", - "fetchSpec": "1.0.2" - }, - "_spec": "1.0.2", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "core-util-is@1.0.2", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "dependencies": {}, - "optionalDependencies": {}, - "_dependencies": {}, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/core-util-is", - "error": "[Circular]", - "extraneous": false - }, - "inherits": { - "name": "inherits", - "description": "Browser-friendly inheritance fully compatible with standard node.js inherits()", - "version": "2.0.3", - "keywords": [ - "inheritance", - "class", - "klass", - "oop", - "object-oriented", - "inherits", - "browser", - "browserify" - ], - "main": "./inherits.js", - "browser": "./inherits_browser.js", - "repository": { - "type": "git", - "url": "git://github.com/isaacs/inherits.git" - }, - "license": "ISC", - "scripts": { - "test": "node test" - }, - "devDependencies": { - "tap": "^7.1.0" - }, - "files": [ - "inherits.js", - "inherits_browser.js" - ], - "_resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "_integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "_from": "inherits@2.0.3", - "readme": "Browser-friendly inheritance fully compatible with standard node.js\n[inherits](http://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor).\n\nThis package exports standard `inherits` from node.js `util` module in\nnode environment, but also provides alternative browser-friendly\nimplementation through [browser\nfield](https://gist.github.com/shtylman/4339901). Alternative\nimplementation is a literal copy of standard one located in standalone\nmodule to avoid requiring of `util`. It also has a shim for old\nbrowsers with no `Object.create` support.\n\nWhile keeping you sure you are using standard `inherits`\nimplementation in node.js environment, it allows bundlers such as\n[browserify](https://github.com/substack/node-browserify) to not\ninclude full `util` package to your client code if all you need is\njust `inherits` function. It worth, because browser shim for `util`\npackage is large and `inherits` is often the single function you need\nfrom it.\n\nIt's recommended to use this package instead of\n`require('util').inherits` for any code that has chances to be used\nnot only in node.js but in browser too.\n\n## usage\n\n```js\nvar inherits = require('inherits');\n// then use exactly as the standard one\n```\n\n## note on version ~1.0\n\nVersion ~1.0 had completely different motivation and is not compatible\nneither with 2.0 nor with standard node.js `inherits`.\n\nIf you are using version ~1.0 and planning to switch to ~2.0, be\ncareful:\n\n* new version uses `super_` instead of `super` for referencing\n superclass\n* new version overwrites current prototype while old one preserves any\n existing fields on it\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/isaacs/inherits/issues" - }, - "homepage": "https://github.com/isaacs/inherits#readme", - "_id": "inherits@2.0.3", - "_requested": { - "type": "version", - "registry": true, - "raw": "inherits@2.0.3", - "name": "inherits", - "escapedName": "inherits", - "rawSpec": "2.0.3", - "saveSpec": "[Circular]", - "fetchSpec": "2.0.3" - }, - "_spec": "2.0.3", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "inherits@2.0.3", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "dependencies": {}, - "optionalDependencies": {}, - "_dependencies": {}, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/inherits", - "error": "[Circular]", - "extraneous": false - }, - "isarray": { - "name": "isarray", - "description": "Array#isArray for older browsers", - "version": "1.0.0", - "repository": { - "type": "git", - "url": "git://github.com/juliangruber/isarray.git" - }, - "homepage": "https://github.com/juliangruber/isarray", - "main": "index.js", - "dependencies": {}, - "devDependencies": { - "tape": "~2.13.4" - }, - "keywords": [ - "browser", - "isarray", - "array" - ], - "author": { - "name": "Julian Gruber", - "email": "mail@juliangruber.com", - "url": "http://juliangruber.com" - }, - "license": "MIT", - "testling": { - "files": "test.js", - "browsers": [ - "ie/8..latest", - "firefox/17..latest", - "firefox/nightly", - "chrome/22..latest", - "chrome/canary", - "opera/12..latest", - "opera/next", - "safari/5.1..latest", - "ipad/6.0..latest", - "iphone/6.0..latest", - "android-browser/4.2..latest" - ] - }, - "scripts": { - "test": "tape test.js" - }, - "_resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "_integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "_from": "isarray@1.0.0", - "readme": "\n# isarray\n\n`Array#isArray` for older browsers.\n\n[![build status](https://secure.travis-ci.org/juliangruber/isarray.svg)](http://travis-ci.org/juliangruber/isarray)\n[![downloads](https://img.shields.io/npm/dm/isarray.svg)](https://www.npmjs.org/package/isarray)\n\n[![browser support](https://ci.testling.com/juliangruber/isarray.png)\n](https://ci.testling.com/juliangruber/isarray)\n\n## Usage\n\n```js\nvar isArray = require('isarray');\n\nconsole.log(isArray([])); // => true\nconsole.log(isArray({})); // => false\n```\n\n## Installation\n\nWith [npm](http://npmjs.org) do\n\n```bash\n$ npm install isarray\n```\n\nThen bundle for the browser with\n[browserify](https://github.com/substack/browserify).\n\nWith [component](http://component.io) do\n\n```bash\n$ component install juliangruber/isarray\n```\n\n## License\n\n(MIT)\n\nCopyright (c) 2013 Julian Gruber <julian@juliangruber.com>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is furnished to do\nso, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/juliangruber/isarray/issues" - }, - "_id": "isarray@1.0.0", - "_requested": { - "type": "version", - "registry": true, - "raw": "isarray@1.0.0", - "name": "isarray", - "escapedName": "isarray", - "rawSpec": "1.0.0", - "saveSpec": "[Circular]", - "fetchSpec": "1.0.0" - }, - "_spec": "1.0.0", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "isarray@1.0.0", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "optionalDependencies": {}, - "_dependencies": {}, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/isarray", - "error": "[Circular]", - "extraneous": false - }, - "process-nextick-args": { - "name": "process-nextick-args", - "version": "2.0.0", - "description": "process.nextTick but always with args", - "main": "index.js", - "files": [ - "index.js" - ], - "scripts": { - "test": "node test.js" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/calvinmetcalf/process-nextick-args.git" - }, - "author": "", - "license": "MIT", - "bugs": { - "url": "https://github.com/calvinmetcalf/process-nextick-args/issues" - }, - "homepage": "https://github.com/calvinmetcalf/process-nextick-args", - "devDependencies": { - "tap": "~0.2.6" - }, - "_resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "_integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", - "_from": "process-nextick-args@2.0.0", - "readme": "process-nextick-args\n=====\n\n[![Build Status](https://travis-ci.org/calvinmetcalf/process-nextick-args.svg?branch=master)](https://travis-ci.org/calvinmetcalf/process-nextick-args)\n\n```bash\nnpm install --save process-nextick-args\n```\n\nAlways be able to pass arguments to process.nextTick, no matter the platform\n\n```js\nvar pna = require('process-nextick-args');\n\npna.nextTick(function (a, b, c) {\n console.log(a, b, c);\n}, 'step', 3, 'profit');\n```\n", - "readmeFilename": "readme.md", - "_id": "process-nextick-args@2.0.0", - "_requested": { - "type": "version", - "registry": true, - "raw": "process-nextick-args@2.0.0", - "name": "process-nextick-args", - "escapedName": "process-nextick-args", - "rawSpec": "2.0.0", - "saveSpec": "[Circular]", - "fetchSpec": "2.0.0" - }, - "_spec": "2.0.0", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "process-nextick-args@2.0.0", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "dependencies": {}, - "optionalDependencies": {}, - "_dependencies": {}, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/process-nextick-args", - "error": "[Circular]", - "extraneous": false - }, - "safe-buffer": { - "name": "safe-buffer", - "description": "Safer Node.js Buffer API", - "version": "5.1.2", - "author": { - "name": "Feross Aboukhadijeh", - "email": "feross@feross.org", - "url": "http://feross.org" - }, - "bugs": { - "url": "https://github.com/feross/safe-buffer/issues" - }, - "devDependencies": { - "standard": "*", - "tape": "^4.0.0" - }, - "homepage": "https://github.com/feross/safe-buffer", - "keywords": [ - "buffer", - "buffer allocate", - "node security", - "safe", - "safe-buffer", - "security", - "uninitialized" - ], - "license": "MIT", - "main": "index.js", - "types": "index.d.ts", - "repository": { - "type": "git", - "url": "git://github.com/feross/safe-buffer.git" - }, - "scripts": { - "test": "standard && tape test/*.js" - }, - "_resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "_integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "_from": "safe-buffer@5.1.2", - "readme": "# safe-buffer [![travis][travis-image]][travis-url] [![npm][npm-image]][npm-url] [![downloads][downloads-image]][downloads-url] [![javascript style guide][standard-image]][standard-url]\n\n[travis-image]: https://img.shields.io/travis/feross/safe-buffer/master.svg\n[travis-url]: https://travis-ci.org/feross/safe-buffer\n[npm-image]: https://img.shields.io/npm/v/safe-buffer.svg\n[npm-url]: https://npmjs.org/package/safe-buffer\n[downloads-image]: https://img.shields.io/npm/dm/safe-buffer.svg\n[downloads-url]: https://npmjs.org/package/safe-buffer\n[standard-image]: https://img.shields.io/badge/code_style-standard-brightgreen.svg\n[standard-url]: https://standardjs.com\n\n#### Safer Node.js Buffer API\n\n**Use the new Node.js Buffer APIs (`Buffer.from`, `Buffer.alloc`,\n`Buffer.allocUnsafe`, `Buffer.allocUnsafeSlow`) in all versions of Node.js.**\n\n**Uses the built-in implementation when available.**\n\n## install\n\n```\nnpm install safe-buffer\n```\n\n## usage\n\nThe goal of this package is to provide a safe replacement for the node.js `Buffer`.\n\nIt's a drop-in replacement for `Buffer`. You can use it by adding one `require` line to\nthe top of your node.js modules:\n\n```js\nvar Buffer = require('safe-buffer').Buffer\n\n// Existing buffer code will continue to work without issues:\n\nnew Buffer('hey', 'utf8')\nnew Buffer([1, 2, 3], 'utf8')\nnew Buffer(obj)\nnew Buffer(16) // create an uninitialized buffer (potentially unsafe)\n\n// But you can use these new explicit APIs to make clear what you want:\n\nBuffer.from('hey', 'utf8') // convert from many types to a Buffer\nBuffer.alloc(16) // create a zero-filled buffer (safe)\nBuffer.allocUnsafe(16) // create an uninitialized buffer (potentially unsafe)\n```\n\n## api\n\n### Class Method: Buffer.from(array)\n\n\n* `array` {Array}\n\nAllocates a new `Buffer` using an `array` of octets.\n\n```js\nconst buf = Buffer.from([0x62,0x75,0x66,0x66,0x65,0x72]);\n // creates a new Buffer containing ASCII bytes\n // ['b','u','f','f','e','r']\n```\n\nA `TypeError` will be thrown if `array` is not an `Array`.\n\n### Class Method: Buffer.from(arrayBuffer[, byteOffset[, length]])\n\n\n* `arrayBuffer` {ArrayBuffer} The `.buffer` property of a `TypedArray` or\n a `new ArrayBuffer()`\n* `byteOffset` {Number} Default: `0`\n* `length` {Number} Default: `arrayBuffer.length - byteOffset`\n\nWhen passed a reference to the `.buffer` property of a `TypedArray` instance,\nthe newly created `Buffer` will share the same allocated memory as the\nTypedArray.\n\n```js\nconst arr = new Uint16Array(2);\narr[0] = 5000;\narr[1] = 4000;\n\nconst buf = Buffer.from(arr.buffer); // shares the memory with arr;\n\nconsole.log(buf);\n // Prints: \n\n// changing the TypedArray changes the Buffer also\narr[1] = 6000;\n\nconsole.log(buf);\n // Prints: \n```\n\nThe optional `byteOffset` and `length` arguments specify a memory range within\nthe `arrayBuffer` that will be shared by the `Buffer`.\n\n```js\nconst ab = new ArrayBuffer(10);\nconst buf = Buffer.from(ab, 0, 2);\nconsole.log(buf.length);\n // Prints: 2\n```\n\nA `TypeError` will be thrown if `arrayBuffer` is not an `ArrayBuffer`.\n\n### Class Method: Buffer.from(buffer)\n\n\n* `buffer` {Buffer}\n\nCopies the passed `buffer` data onto a new `Buffer` instance.\n\n```js\nconst buf1 = Buffer.from('buffer');\nconst buf2 = Buffer.from(buf1);\n\nbuf1[0] = 0x61;\nconsole.log(buf1.toString());\n // 'auffer'\nconsole.log(buf2.toString());\n // 'buffer' (copy is not changed)\n```\n\nA `TypeError` will be thrown if `buffer` is not a `Buffer`.\n\n### Class Method: Buffer.from(str[, encoding])\n\n\n* `str` {String} String to encode.\n* `encoding` {String} Encoding to use, Default: `'utf8'`\n\nCreates a new `Buffer` containing the given JavaScript string `str`. If\nprovided, the `encoding` parameter identifies the character encoding.\nIf not provided, `encoding` defaults to `'utf8'`.\n\n```js\nconst buf1 = Buffer.from('this is a tést');\nconsole.log(buf1.toString());\n // prints: this is a tést\nconsole.log(buf1.toString('ascii'));\n // prints: this is a tC)st\n\nconst buf2 = Buffer.from('7468697320697320612074c3a97374', 'hex');\nconsole.log(buf2.toString());\n // prints: this is a tést\n```\n\nA `TypeError` will be thrown if `str` is not a string.\n\n### Class Method: Buffer.alloc(size[, fill[, encoding]])\n\n\n* `size` {Number}\n* `fill` {Value} Default: `undefined`\n* `encoding` {String} Default: `utf8`\n\nAllocates a new `Buffer` of `size` bytes. If `fill` is `undefined`, the\n`Buffer` will be *zero-filled*.\n\n```js\nconst buf = Buffer.alloc(5);\nconsole.log(buf);\n // \n```\n\nThe `size` must be less than or equal to the value of\n`require('buffer').kMaxLength` (on 64-bit architectures, `kMaxLength` is\n`(2^31)-1`). Otherwise, a [`RangeError`][] is thrown. A zero-length Buffer will\nbe created if a `size` less than or equal to 0 is specified.\n\nIf `fill` is specified, the allocated `Buffer` will be initialized by calling\n`buf.fill(fill)`. See [`buf.fill()`][] for more information.\n\n```js\nconst buf = Buffer.alloc(5, 'a');\nconsole.log(buf);\n // \n```\n\nIf both `fill` and `encoding` are specified, the allocated `Buffer` will be\ninitialized by calling `buf.fill(fill, encoding)`. For example:\n\n```js\nconst buf = Buffer.alloc(11, 'aGVsbG8gd29ybGQ=', 'base64');\nconsole.log(buf);\n // \n```\n\nCalling `Buffer.alloc(size)` can be significantly slower than the alternative\n`Buffer.allocUnsafe(size)` but ensures that the newly created `Buffer` instance\ncontents will *never contain sensitive data*.\n\nA `TypeError` will be thrown if `size` is not a number.\n\n### Class Method: Buffer.allocUnsafe(size)\n\n\n* `size` {Number}\n\nAllocates a new *non-zero-filled* `Buffer` of `size` bytes. The `size` must\nbe less than or equal to the value of `require('buffer').kMaxLength` (on 64-bit\narchitectures, `kMaxLength` is `(2^31)-1`). Otherwise, a [`RangeError`][] is\nthrown. A zero-length Buffer will be created if a `size` less than or equal to\n0 is specified.\n\nThe underlying memory for `Buffer` instances created in this way is *not\ninitialized*. The contents of the newly created `Buffer` are unknown and\n*may contain sensitive data*. Use [`buf.fill(0)`][] to initialize such\n`Buffer` instances to zeroes.\n\n```js\nconst buf = Buffer.allocUnsafe(5);\nconsole.log(buf);\n // \n // (octets will be different, every time)\nbuf.fill(0);\nconsole.log(buf);\n // \n```\n\nA `TypeError` will be thrown if `size` is not a number.\n\nNote that the `Buffer` module pre-allocates an internal `Buffer` instance of\nsize `Buffer.poolSize` that is used as a pool for the fast allocation of new\n`Buffer` instances created using `Buffer.allocUnsafe(size)` (and the deprecated\n`new Buffer(size)` constructor) only when `size` is less than or equal to\n`Buffer.poolSize >> 1` (floor of `Buffer.poolSize` divided by two). The default\nvalue of `Buffer.poolSize` is `8192` but can be modified.\n\nUse of this pre-allocated internal memory pool is a key difference between\ncalling `Buffer.alloc(size, fill)` vs. `Buffer.allocUnsafe(size).fill(fill)`.\nSpecifically, `Buffer.alloc(size, fill)` will *never* use the internal Buffer\npool, while `Buffer.allocUnsafe(size).fill(fill)` *will* use the internal\nBuffer pool if `size` is less than or equal to half `Buffer.poolSize`. The\ndifference is subtle but can be important when an application requires the\nadditional performance that `Buffer.allocUnsafe(size)` provides.\n\n### Class Method: Buffer.allocUnsafeSlow(size)\n\n\n* `size` {Number}\n\nAllocates a new *non-zero-filled* and non-pooled `Buffer` of `size` bytes. The\n`size` must be less than or equal to the value of\n`require('buffer').kMaxLength` (on 64-bit architectures, `kMaxLength` is\n`(2^31)-1`). Otherwise, a [`RangeError`][] is thrown. A zero-length Buffer will\nbe created if a `size` less than or equal to 0 is specified.\n\nThe underlying memory for `Buffer` instances created in this way is *not\ninitialized*. The contents of the newly created `Buffer` are unknown and\n*may contain sensitive data*. Use [`buf.fill(0)`][] to initialize such\n`Buffer` instances to zeroes.\n\nWhen using `Buffer.allocUnsafe()` to allocate new `Buffer` instances,\nallocations under 4KB are, by default, sliced from a single pre-allocated\n`Buffer`. This allows applications to avoid the garbage collection overhead of\ncreating many individually allocated Buffers. This approach improves both\nperformance and memory usage by eliminating the need to track and cleanup as\nmany `Persistent` objects.\n\nHowever, in the case where a developer may need to retain a small chunk of\nmemory from a pool for an indeterminate amount of time, it may be appropriate\nto create an un-pooled Buffer instance using `Buffer.allocUnsafeSlow()` then\ncopy out the relevant bits.\n\n```js\n// need to keep around a few small chunks of memory\nconst store = [];\n\nsocket.on('readable', () => {\n const data = socket.read();\n // allocate for retained data\n const sb = Buffer.allocUnsafeSlow(10);\n // copy the data into the new allocation\n data.copy(sb, 0, 0, 10);\n store.push(sb);\n});\n```\n\nUse of `Buffer.allocUnsafeSlow()` should be used only as a last resort *after*\na developer has observed undue memory retention in their applications.\n\nA `TypeError` will be thrown if `size` is not a number.\n\n### All the Rest\n\nThe rest of the `Buffer` API is exactly the same as in node.js.\n[See the docs](https://nodejs.org/api/buffer.html).\n\n\n## Related links\n\n- [Node.js issue: Buffer(number) is unsafe](https://github.com/nodejs/node/issues/4660)\n- [Node.js Enhancement Proposal: Buffer.from/Buffer.alloc/Buffer.zalloc/Buffer() soft-deprecate](https://github.com/nodejs/node-eps/pull/4)\n\n## Why is `Buffer` unsafe?\n\nToday, the node.js `Buffer` constructor is overloaded to handle many different argument\ntypes like `String`, `Array`, `Object`, `TypedArrayView` (`Uint8Array`, etc.),\n`ArrayBuffer`, and also `Number`.\n\nThe API is optimized for convenience: you can throw any type at it, and it will try to do\nwhat you want.\n\nBecause the Buffer constructor is so powerful, you often see code like this:\n\n```js\n// Convert UTF-8 strings to hex\nfunction toHex (str) {\n return new Buffer(str).toString('hex')\n}\n```\n\n***But what happens if `toHex` is called with a `Number` argument?***\n\n### Remote Memory Disclosure\n\nIf an attacker can make your program call the `Buffer` constructor with a `Number`\nargument, then they can make it allocate uninitialized memory from the node.js process.\nThis could potentially disclose TLS private keys, user data, or database passwords.\n\nWhen the `Buffer` constructor is passed a `Number` argument, it returns an\n**UNINITIALIZED** block of memory of the specified `size`. When you create a `Buffer` like\nthis, you **MUST** overwrite the contents before returning it to the user.\n\nFrom the [node.js docs](https://nodejs.org/api/buffer.html#buffer_new_buffer_size):\n\n> `new Buffer(size)`\n>\n> - `size` Number\n>\n> The underlying memory for `Buffer` instances created in this way is not initialized.\n> **The contents of a newly created `Buffer` are unknown and could contain sensitive\n> data.** Use `buf.fill(0)` to initialize a Buffer to zeroes.\n\n(Emphasis our own.)\n\nWhenever the programmer intended to create an uninitialized `Buffer` you often see code\nlike this:\n\n```js\nvar buf = new Buffer(16)\n\n// Immediately overwrite the uninitialized buffer with data from another buffer\nfor (var i = 0; i < buf.length; i++) {\n buf[i] = otherBuf[i]\n}\n```\n\n\n### Would this ever be a problem in real code?\n\nYes. It's surprisingly common to forget to check the type of your variables in a\ndynamically-typed language like JavaScript.\n\nUsually the consequences of assuming the wrong type is that your program crashes with an\nuncaught exception. But the failure mode for forgetting to check the type of arguments to\nthe `Buffer` constructor is more catastrophic.\n\nHere's an example of a vulnerable service that takes a JSON payload and converts it to\nhex:\n\n```js\n// Take a JSON payload {str: \"some string\"} and convert it to hex\nvar server = http.createServer(function (req, res) {\n var data = ''\n req.setEncoding('utf8')\n req.on('data', function (chunk) {\n data += chunk\n })\n req.on('end', function () {\n var body = JSON.parse(data)\n res.end(new Buffer(body.str).toString('hex'))\n })\n})\n\nserver.listen(8080)\n```\n\nIn this example, an http client just has to send:\n\n```json\n{\n \"str\": 1000\n}\n```\n\nand it will get back 1,000 bytes of uninitialized memory from the server.\n\nThis is a very serious bug. It's similar in severity to the\n[the Heartbleed bug](http://heartbleed.com/) that allowed disclosure of OpenSSL process\nmemory by remote attackers.\n\n\n### Which real-world packages were vulnerable?\n\n#### [`bittorrent-dht`](https://www.npmjs.com/package/bittorrent-dht)\n\n[Mathias Buus](https://github.com/mafintosh) and I\n([Feross Aboukhadijeh](http://feross.org/)) found this issue in one of our own packages,\n[`bittorrent-dht`](https://www.npmjs.com/package/bittorrent-dht). The bug would allow\nanyone on the internet to send a series of messages to a user of `bittorrent-dht` and get\nthem to reveal 20 bytes at a time of uninitialized memory from the node.js process.\n\nHere's\n[the commit](https://github.com/feross/bittorrent-dht/commit/6c7da04025d5633699800a99ec3fbadf70ad35b8)\nthat fixed it. We released a new fixed version, created a\n[Node Security Project disclosure](https://nodesecurity.io/advisories/68), and deprecated all\nvulnerable versions on npm so users will get a warning to upgrade to a newer version.\n\n#### [`ws`](https://www.npmjs.com/package/ws)\n\nThat got us wondering if there were other vulnerable packages. Sure enough, within a short\nperiod of time, we found the same issue in [`ws`](https://www.npmjs.com/package/ws), the\nmost popular WebSocket implementation in node.js.\n\nIf certain APIs were called with `Number` parameters instead of `String` or `Buffer` as\nexpected, then uninitialized server memory would be disclosed to the remote peer.\n\nThese were the vulnerable methods:\n\n```js\nsocket.send(number)\nsocket.ping(number)\nsocket.pong(number)\n```\n\nHere's a vulnerable socket server with some echo functionality:\n\n```js\nserver.on('connection', function (socket) {\n socket.on('message', function (message) {\n message = JSON.parse(message)\n if (message.type === 'echo') {\n socket.send(message.data) // send back the user's message\n }\n })\n})\n```\n\n`socket.send(number)` called on the server, will disclose server memory.\n\nHere's [the release](https://github.com/websockets/ws/releases/tag/1.0.1) where the issue\nwas fixed, with a more detailed explanation. Props to\n[Arnout Kazemier](https://github.com/3rd-Eden) for the quick fix. Here's the\n[Node Security Project disclosure](https://nodesecurity.io/advisories/67).\n\n\n### What's the solution?\n\nIt's important that node.js offers a fast way to get memory otherwise performance-critical\napplications would needlessly get a lot slower.\n\nBut we need a better way to *signal our intent* as programmers. **When we want\nuninitialized memory, we should request it explicitly.**\n\nSensitive functionality should not be packed into a developer-friendly API that loosely\naccepts many different types. This type of API encourages the lazy practice of passing\nvariables in without checking the type very carefully.\n\n#### A new API: `Buffer.allocUnsafe(number)`\n\nThe functionality of creating buffers with uninitialized memory should be part of another\nAPI. We propose `Buffer.allocUnsafe(number)`. This way, it's not part of an API that\nfrequently gets user input of all sorts of different types passed into it.\n\n```js\nvar buf = Buffer.allocUnsafe(16) // careful, uninitialized memory!\n\n// Immediately overwrite the uninitialized buffer with data from another buffer\nfor (var i = 0; i < buf.length; i++) {\n buf[i] = otherBuf[i]\n}\n```\n\n\n### How do we fix node.js core?\n\nWe sent [a PR to node.js core](https://github.com/nodejs/node/pull/4514) (merged as\n`semver-major`) which defends against one case:\n\n```js\nvar str = 16\nnew Buffer(str, 'utf8')\n```\n\nIn this situation, it's implied that the programmer intended the first argument to be a\nstring, since they passed an encoding as a second argument. Today, node.js will allocate\nuninitialized memory in the case of `new Buffer(number, encoding)`, which is probably not\nwhat the programmer intended.\n\nBut this is only a partial solution, since if the programmer does `new Buffer(variable)`\n(without an `encoding` parameter) there's no way to know what they intended. If `variable`\nis sometimes a number, then uninitialized memory will sometimes be returned.\n\n### What's the real long-term fix?\n\nWe could deprecate and remove `new Buffer(number)` and use `Buffer.allocUnsafe(number)` when\nwe need uninitialized memory. But that would break 1000s of packages.\n\n~~We believe the best solution is to:~~\n\n~~1. Change `new Buffer(number)` to return safe, zeroed-out memory~~\n\n~~2. Create a new API for creating uninitialized Buffers. We propose: `Buffer.allocUnsafe(number)`~~\n\n#### Update\n\nWe now support adding three new APIs:\n\n- `Buffer.from(value)` - convert from any type to a buffer\n- `Buffer.alloc(size)` - create a zero-filled buffer\n- `Buffer.allocUnsafe(size)` - create an uninitialized buffer with given size\n\nThis solves the core problem that affected `ws` and `bittorrent-dht` which is\n`Buffer(variable)` getting tricked into taking a number argument.\n\nThis way, existing code continues working and the impact on the npm ecosystem will be\nminimal. Over time, npm maintainers can migrate performance-critical code to use\n`Buffer.allocUnsafe(number)` instead of `new Buffer(number)`.\n\n\n### Conclusion\n\nWe think there's a serious design issue with the `Buffer` API as it exists today. It\npromotes insecure software by putting high-risk functionality into a convenient API\nwith friendly \"developer ergonomics\".\n\nThis wasn't merely a theoretical exercise because we found the issue in some of the\nmost popular npm packages.\n\nFortunately, there's an easy fix that can be applied today. Use `safe-buffer` in place of\n`buffer`.\n\n```js\nvar Buffer = require('safe-buffer').Buffer\n```\n\nEventually, we hope that node.js core can switch to this new, safer behavior. We believe\nthe impact on the ecosystem would be minimal since it's not a breaking change.\nWell-maintained, popular packages would be updated to use `Buffer.alloc` quickly, while\nolder, insecure packages would magically become safe from this attack vector.\n\n\n## links\n\n- [Node.js PR: buffer: throw if both length and enc are passed](https://github.com/nodejs/node/pull/4514)\n- [Node Security Project disclosure for `ws`](https://nodesecurity.io/advisories/67)\n- [Node Security Project disclosure for`bittorrent-dht`](https://nodesecurity.io/advisories/68)\n\n\n## credit\n\nThe original issues in `bittorrent-dht`\n([disclosure](https://nodesecurity.io/advisories/68)) and\n`ws` ([disclosure](https://nodesecurity.io/advisories/67)) were discovered by\n[Mathias Buus](https://github.com/mafintosh) and\n[Feross Aboukhadijeh](http://feross.org/).\n\nThanks to [Adam Baldwin](https://github.com/evilpacket) for helping disclose these issues\nand for his work running the [Node Security Project](https://nodesecurity.io/).\n\nThanks to [John Hiesey](https://github.com/jhiesey) for proofreading this README and\nauditing the code.\n\n\n## license\n\nMIT. Copyright (C) [Feross Aboukhadijeh](http://feross.org)\n", - "readmeFilename": "README.md", - "_id": "safe-buffer@5.1.2", - "_requested": { - "type": "version", - "registry": true, - "raw": "safe-buffer@5.1.2", - "name": "safe-buffer", - "escapedName": "safe-buffer", - "rawSpec": "5.1.2", - "saveSpec": "[Circular]", - "fetchSpec": "5.1.2" - }, - "_spec": "5.1.2", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "safe-buffer@5.1.2", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "dependencies": {}, - "optionalDependencies": {}, - "_dependencies": {}, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/safe-buffer", - "error": "[Circular]", - "extraneous": false - }, - "string_decoder": { - "name": "string_decoder", - "version": "1.1.1", - "description": "The string_decoder module from Node core", - "main": "lib/string_decoder.js", - "dependencies": { - "safe-buffer": { - "name": "safe-buffer", - "description": "Safer Node.js Buffer API", - "version": "5.1.2", - "author": "[Circular]", - "bugs": "[Circular]", - "devDependencies": "[Circular]", - "homepage": "https://github.com/feross/safe-buffer", - "keywords": "[Circular]", - "license": "MIT", - "main": "index.js", - "types": "index.d.ts", - "repository": "[Circular]", - "scripts": "[Circular]", - "_resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "_integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "_from": "safe-buffer@5.1.2", - "readme": "# safe-buffer [![travis][travis-image]][travis-url] [![npm][npm-image]][npm-url] [![downloads][downloads-image]][downloads-url] [![javascript style guide][standard-image]][standard-url]\n\n[travis-image]: https://img.shields.io/travis/feross/safe-buffer/master.svg\n[travis-url]: https://travis-ci.org/feross/safe-buffer\n[npm-image]: https://img.shields.io/npm/v/safe-buffer.svg\n[npm-url]: https://npmjs.org/package/safe-buffer\n[downloads-image]: https://img.shields.io/npm/dm/safe-buffer.svg\n[downloads-url]: https://npmjs.org/package/safe-buffer\n[standard-image]: https://img.shields.io/badge/code_style-standard-brightgreen.svg\n[standard-url]: https://standardjs.com\n\n#### Safer Node.js Buffer API\n\n**Use the new Node.js Buffer APIs (`Buffer.from`, `Buffer.alloc`,\n`Buffer.allocUnsafe`, `Buffer.allocUnsafeSlow`) in all versions of Node.js.**\n\n**Uses the built-in implementation when available.**\n\n## install\n\n```\nnpm install safe-buffer\n```\n\n## usage\n\nThe goal of this package is to provide a safe replacement for the node.js `Buffer`.\n\nIt's a drop-in replacement for `Buffer`. You can use it by adding one `require` line to\nthe top of your node.js modules:\n\n```js\nvar Buffer = require('safe-buffer').Buffer\n\n// Existing buffer code will continue to work without issues:\n\nnew Buffer('hey', 'utf8')\nnew Buffer([1, 2, 3], 'utf8')\nnew Buffer(obj)\nnew Buffer(16) // create an uninitialized buffer (potentially unsafe)\n\n// But you can use these new explicit APIs to make clear what you want:\n\nBuffer.from('hey', 'utf8') // convert from many types to a Buffer\nBuffer.alloc(16) // create a zero-filled buffer (safe)\nBuffer.allocUnsafe(16) // create an uninitialized buffer (potentially unsafe)\n```\n\n## api\n\n### Class Method: Buffer.from(array)\n\n\n* `array` {Array}\n\nAllocates a new `Buffer` using an `array` of octets.\n\n```js\nconst buf = Buffer.from([0x62,0x75,0x66,0x66,0x65,0x72]);\n // creates a new Buffer containing ASCII bytes\n // ['b','u','f','f','e','r']\n```\n\nA `TypeError` will be thrown if `array` is not an `Array`.\n\n### Class Method: Buffer.from(arrayBuffer[, byteOffset[, length]])\n\n\n* `arrayBuffer` {ArrayBuffer} The `.buffer` property of a `TypedArray` or\n a `new ArrayBuffer()`\n* `byteOffset` {Number} Default: `0`\n* `length` {Number} Default: `arrayBuffer.length - byteOffset`\n\nWhen passed a reference to the `.buffer` property of a `TypedArray` instance,\nthe newly created `Buffer` will share the same allocated memory as the\nTypedArray.\n\n```js\nconst arr = new Uint16Array(2);\narr[0] = 5000;\narr[1] = 4000;\n\nconst buf = Buffer.from(arr.buffer); // shares the memory with arr;\n\nconsole.log(buf);\n // Prints: \n\n// changing the TypedArray changes the Buffer also\narr[1] = 6000;\n\nconsole.log(buf);\n // Prints: \n```\n\nThe optional `byteOffset` and `length` arguments specify a memory range within\nthe `arrayBuffer` that will be shared by the `Buffer`.\n\n```js\nconst ab = new ArrayBuffer(10);\nconst buf = Buffer.from(ab, 0, 2);\nconsole.log(buf.length);\n // Prints: 2\n```\n\nA `TypeError` will be thrown if `arrayBuffer` is not an `ArrayBuffer`.\n\n### Class Method: Buffer.from(buffer)\n\n\n* `buffer` {Buffer}\n\nCopies the passed `buffer` data onto a new `Buffer` instance.\n\n```js\nconst buf1 = Buffer.from('buffer');\nconst buf2 = Buffer.from(buf1);\n\nbuf1[0] = 0x61;\nconsole.log(buf1.toString());\n // 'auffer'\nconsole.log(buf2.toString());\n // 'buffer' (copy is not changed)\n```\n\nA `TypeError` will be thrown if `buffer` is not a `Buffer`.\n\n### Class Method: Buffer.from(str[, encoding])\n\n\n* `str` {String} String to encode.\n* `encoding` {String} Encoding to use, Default: `'utf8'`\n\nCreates a new `Buffer` containing the given JavaScript string `str`. If\nprovided, the `encoding` parameter identifies the character encoding.\nIf not provided, `encoding` defaults to `'utf8'`.\n\n```js\nconst buf1 = Buffer.from('this is a tést');\nconsole.log(buf1.toString());\n // prints: this is a tést\nconsole.log(buf1.toString('ascii'));\n // prints: this is a tC)st\n\nconst buf2 = Buffer.from('7468697320697320612074c3a97374', 'hex');\nconsole.log(buf2.toString());\n // prints: this is a tést\n```\n\nA `TypeError` will be thrown if `str` is not a string.\n\n### Class Method: Buffer.alloc(size[, fill[, encoding]])\n\n\n* `size` {Number}\n* `fill` {Value} Default: `undefined`\n* `encoding` {String} Default: `utf8`\n\nAllocates a new `Buffer` of `size` bytes. If `fill` is `undefined`, the\n`Buffer` will be *zero-filled*.\n\n```js\nconst buf = Buffer.alloc(5);\nconsole.log(buf);\n // \n```\n\nThe `size` must be less than or equal to the value of\n`require('buffer').kMaxLength` (on 64-bit architectures, `kMaxLength` is\n`(2^31)-1`). Otherwise, a [`RangeError`][] is thrown. A zero-length Buffer will\nbe created if a `size` less than or equal to 0 is specified.\n\nIf `fill` is specified, the allocated `Buffer` will be initialized by calling\n`buf.fill(fill)`. See [`buf.fill()`][] for more information.\n\n```js\nconst buf = Buffer.alloc(5, 'a');\nconsole.log(buf);\n // \n```\n\nIf both `fill` and `encoding` are specified, the allocated `Buffer` will be\ninitialized by calling `buf.fill(fill, encoding)`. For example:\n\n```js\nconst buf = Buffer.alloc(11, 'aGVsbG8gd29ybGQ=', 'base64');\nconsole.log(buf);\n // \n```\n\nCalling `Buffer.alloc(size)` can be significantly slower than the alternative\n`Buffer.allocUnsafe(size)` but ensures that the newly created `Buffer` instance\ncontents will *never contain sensitive data*.\n\nA `TypeError` will be thrown if `size` is not a number.\n\n### Class Method: Buffer.allocUnsafe(size)\n\n\n* `size` {Number}\n\nAllocates a new *non-zero-filled* `Buffer` of `size` bytes. The `size` must\nbe less than or equal to the value of `require('buffer').kMaxLength` (on 64-bit\narchitectures, `kMaxLength` is `(2^31)-1`). Otherwise, a [`RangeError`][] is\nthrown. A zero-length Buffer will be created if a `size` less than or equal to\n0 is specified.\n\nThe underlying memory for `Buffer` instances created in this way is *not\ninitialized*. The contents of the newly created `Buffer` are unknown and\n*may contain sensitive data*. Use [`buf.fill(0)`][] to initialize such\n`Buffer` instances to zeroes.\n\n```js\nconst buf = Buffer.allocUnsafe(5);\nconsole.log(buf);\n // \n // (octets will be different, every time)\nbuf.fill(0);\nconsole.log(buf);\n // \n```\n\nA `TypeError` will be thrown if `size` is not a number.\n\nNote that the `Buffer` module pre-allocates an internal `Buffer` instance of\nsize `Buffer.poolSize` that is used as a pool for the fast allocation of new\n`Buffer` instances created using `Buffer.allocUnsafe(size)` (and the deprecated\n`new Buffer(size)` constructor) only when `size` is less than or equal to\n`Buffer.poolSize >> 1` (floor of `Buffer.poolSize` divided by two). The default\nvalue of `Buffer.poolSize` is `8192` but can be modified.\n\nUse of this pre-allocated internal memory pool is a key difference between\ncalling `Buffer.alloc(size, fill)` vs. `Buffer.allocUnsafe(size).fill(fill)`.\nSpecifically, `Buffer.alloc(size, fill)` will *never* use the internal Buffer\npool, while `Buffer.allocUnsafe(size).fill(fill)` *will* use the internal\nBuffer pool if `size` is less than or equal to half `Buffer.poolSize`. The\ndifference is subtle but can be important when an application requires the\nadditional performance that `Buffer.allocUnsafe(size)` provides.\n\n### Class Method: Buffer.allocUnsafeSlow(size)\n\n\n* `size` {Number}\n\nAllocates a new *non-zero-filled* and non-pooled `Buffer` of `size` bytes. The\n`size` must be less than or equal to the value of\n`require('buffer').kMaxLength` (on 64-bit architectures, `kMaxLength` is\n`(2^31)-1`). Otherwise, a [`RangeError`][] is thrown. A zero-length Buffer will\nbe created if a `size` less than or equal to 0 is specified.\n\nThe underlying memory for `Buffer` instances created in this way is *not\ninitialized*. The contents of the newly created `Buffer` are unknown and\n*may contain sensitive data*. Use [`buf.fill(0)`][] to initialize such\n`Buffer` instances to zeroes.\n\nWhen using `Buffer.allocUnsafe()` to allocate new `Buffer` instances,\nallocations under 4KB are, by default, sliced from a single pre-allocated\n`Buffer`. This allows applications to avoid the garbage collection overhead of\ncreating many individually allocated Buffers. This approach improves both\nperformance and memory usage by eliminating the need to track and cleanup as\nmany `Persistent` objects.\n\nHowever, in the case where a developer may need to retain a small chunk of\nmemory from a pool for an indeterminate amount of time, it may be appropriate\nto create an un-pooled Buffer instance using `Buffer.allocUnsafeSlow()` then\ncopy out the relevant bits.\n\n```js\n// need to keep around a few small chunks of memory\nconst store = [];\n\nsocket.on('readable', () => {\n const data = socket.read();\n // allocate for retained data\n const sb = Buffer.allocUnsafeSlow(10);\n // copy the data into the new allocation\n data.copy(sb, 0, 0, 10);\n store.push(sb);\n});\n```\n\nUse of `Buffer.allocUnsafeSlow()` should be used only as a last resort *after*\na developer has observed undue memory retention in their applications.\n\nA `TypeError` will be thrown if `size` is not a number.\n\n### All the Rest\n\nThe rest of the `Buffer` API is exactly the same as in node.js.\n[See the docs](https://nodejs.org/api/buffer.html).\n\n\n## Related links\n\n- [Node.js issue: Buffer(number) is unsafe](https://github.com/nodejs/node/issues/4660)\n- [Node.js Enhancement Proposal: Buffer.from/Buffer.alloc/Buffer.zalloc/Buffer() soft-deprecate](https://github.com/nodejs/node-eps/pull/4)\n\n## Why is `Buffer` unsafe?\n\nToday, the node.js `Buffer` constructor is overloaded to handle many different argument\ntypes like `String`, `Array`, `Object`, `TypedArrayView` (`Uint8Array`, etc.),\n`ArrayBuffer`, and also `Number`.\n\nThe API is optimized for convenience: you can throw any type at it, and it will try to do\nwhat you want.\n\nBecause the Buffer constructor is so powerful, you often see code like this:\n\n```js\n// Convert UTF-8 strings to hex\nfunction toHex (str) {\n return new Buffer(str).toString('hex')\n}\n```\n\n***But what happens if `toHex` is called with a `Number` argument?***\n\n### Remote Memory Disclosure\n\nIf an attacker can make your program call the `Buffer` constructor with a `Number`\nargument, then they can make it allocate uninitialized memory from the node.js process.\nThis could potentially disclose TLS private keys, user data, or database passwords.\n\nWhen the `Buffer` constructor is passed a `Number` argument, it returns an\n**UNINITIALIZED** block of memory of the specified `size`. When you create a `Buffer` like\nthis, you **MUST** overwrite the contents before returning it to the user.\n\nFrom the [node.js docs](https://nodejs.org/api/buffer.html#buffer_new_buffer_size):\n\n> `new Buffer(size)`\n>\n> - `size` Number\n>\n> The underlying memory for `Buffer` instances created in this way is not initialized.\n> **The contents of a newly created `Buffer` are unknown and could contain sensitive\n> data.** Use `buf.fill(0)` to initialize a Buffer to zeroes.\n\n(Emphasis our own.)\n\nWhenever the programmer intended to create an uninitialized `Buffer` you often see code\nlike this:\n\n```js\nvar buf = new Buffer(16)\n\n// Immediately overwrite the uninitialized buffer with data from another buffer\nfor (var i = 0; i < buf.length; i++) {\n buf[i] = otherBuf[i]\n}\n```\n\n\n### Would this ever be a problem in real code?\n\nYes. It's surprisingly common to forget to check the type of your variables in a\ndynamically-typed language like JavaScript.\n\nUsually the consequences of assuming the wrong type is that your program crashes with an\nuncaught exception. But the failure mode for forgetting to check the type of arguments to\nthe `Buffer` constructor is more catastrophic.\n\nHere's an example of a vulnerable service that takes a JSON payload and converts it to\nhex:\n\n```js\n// Take a JSON payload {str: \"some string\"} and convert it to hex\nvar server = http.createServer(function (req, res) {\n var data = ''\n req.setEncoding('utf8')\n req.on('data', function (chunk) {\n data += chunk\n })\n req.on('end', function () {\n var body = JSON.parse(data)\n res.end(new Buffer(body.str).toString('hex'))\n })\n})\n\nserver.listen(8080)\n```\n\nIn this example, an http client just has to send:\n\n```json\n{\n \"str\": 1000\n}\n```\n\nand it will get back 1,000 bytes of uninitialized memory from the server.\n\nThis is a very serious bug. It's similar in severity to the\n[the Heartbleed bug](http://heartbleed.com/) that allowed disclosure of OpenSSL process\nmemory by remote attackers.\n\n\n### Which real-world packages were vulnerable?\n\n#### [`bittorrent-dht`](https://www.npmjs.com/package/bittorrent-dht)\n\n[Mathias Buus](https://github.com/mafintosh) and I\n([Feross Aboukhadijeh](http://feross.org/)) found this issue in one of our own packages,\n[`bittorrent-dht`](https://www.npmjs.com/package/bittorrent-dht). The bug would allow\nanyone on the internet to send a series of messages to a user of `bittorrent-dht` and get\nthem to reveal 20 bytes at a time of uninitialized memory from the node.js process.\n\nHere's\n[the commit](https://github.com/feross/bittorrent-dht/commit/6c7da04025d5633699800a99ec3fbadf70ad35b8)\nthat fixed it. We released a new fixed version, created a\n[Node Security Project disclosure](https://nodesecurity.io/advisories/68), and deprecated all\nvulnerable versions on npm so users will get a warning to upgrade to a newer version.\n\n#### [`ws`](https://www.npmjs.com/package/ws)\n\nThat got us wondering if there were other vulnerable packages. Sure enough, within a short\nperiod of time, we found the same issue in [`ws`](https://www.npmjs.com/package/ws), the\nmost popular WebSocket implementation in node.js.\n\nIf certain APIs were called with `Number` parameters instead of `String` or `Buffer` as\nexpected, then uninitialized server memory would be disclosed to the remote peer.\n\nThese were the vulnerable methods:\n\n```js\nsocket.send(number)\nsocket.ping(number)\nsocket.pong(number)\n```\n\nHere's a vulnerable socket server with some echo functionality:\n\n```js\nserver.on('connection', function (socket) {\n socket.on('message', function (message) {\n message = JSON.parse(message)\n if (message.type === 'echo') {\n socket.send(message.data) // send back the user's message\n }\n })\n})\n```\n\n`socket.send(number)` called on the server, will disclose server memory.\n\nHere's [the release](https://github.com/websockets/ws/releases/tag/1.0.1) where the issue\nwas fixed, with a more detailed explanation. Props to\n[Arnout Kazemier](https://github.com/3rd-Eden) for the quick fix. Here's the\n[Node Security Project disclosure](https://nodesecurity.io/advisories/67).\n\n\n### What's the solution?\n\nIt's important that node.js offers a fast way to get memory otherwise performance-critical\napplications would needlessly get a lot slower.\n\nBut we need a better way to *signal our intent* as programmers. **When we want\nuninitialized memory, we should request it explicitly.**\n\nSensitive functionality should not be packed into a developer-friendly API that loosely\naccepts many different types. This type of API encourages the lazy practice of passing\nvariables in without checking the type very carefully.\n\n#### A new API: `Buffer.allocUnsafe(number)`\n\nThe functionality of creating buffers with uninitialized memory should be part of another\nAPI. We propose `Buffer.allocUnsafe(number)`. This way, it's not part of an API that\nfrequently gets user input of all sorts of different types passed into it.\n\n```js\nvar buf = Buffer.allocUnsafe(16) // careful, uninitialized memory!\n\n// Immediately overwrite the uninitialized buffer with data from another buffer\nfor (var i = 0; i < buf.length; i++) {\n buf[i] = otherBuf[i]\n}\n```\n\n\n### How do we fix node.js core?\n\nWe sent [a PR to node.js core](https://github.com/nodejs/node/pull/4514) (merged as\n`semver-major`) which defends against one case:\n\n```js\nvar str = 16\nnew Buffer(str, 'utf8')\n```\n\nIn this situation, it's implied that the programmer intended the first argument to be a\nstring, since they passed an encoding as a second argument. Today, node.js will allocate\nuninitialized memory in the case of `new Buffer(number, encoding)`, which is probably not\nwhat the programmer intended.\n\nBut this is only a partial solution, since if the programmer does `new Buffer(variable)`\n(without an `encoding` parameter) there's no way to know what they intended. If `variable`\nis sometimes a number, then uninitialized memory will sometimes be returned.\n\n### What's the real long-term fix?\n\nWe could deprecate and remove `new Buffer(number)` and use `Buffer.allocUnsafe(number)` when\nwe need uninitialized memory. But that would break 1000s of packages.\n\n~~We believe the best solution is to:~~\n\n~~1. Change `new Buffer(number)` to return safe, zeroed-out memory~~\n\n~~2. Create a new API for creating uninitialized Buffers. We propose: `Buffer.allocUnsafe(number)`~~\n\n#### Update\n\nWe now support adding three new APIs:\n\n- `Buffer.from(value)` - convert from any type to a buffer\n- `Buffer.alloc(size)` - create a zero-filled buffer\n- `Buffer.allocUnsafe(size)` - create an uninitialized buffer with given size\n\nThis solves the core problem that affected `ws` and `bittorrent-dht` which is\n`Buffer(variable)` getting tricked into taking a number argument.\n\nThis way, existing code continues working and the impact on the npm ecosystem will be\nminimal. Over time, npm maintainers can migrate performance-critical code to use\n`Buffer.allocUnsafe(number)` instead of `new Buffer(number)`.\n\n\n### Conclusion\n\nWe think there's a serious design issue with the `Buffer` API as it exists today. It\npromotes insecure software by putting high-risk functionality into a convenient API\nwith friendly \"developer ergonomics\".\n\nThis wasn't merely a theoretical exercise because we found the issue in some of the\nmost popular npm packages.\n\nFortunately, there's an easy fix that can be applied today. Use `safe-buffer` in place of\n`buffer`.\n\n```js\nvar Buffer = require('safe-buffer').Buffer\n```\n\nEventually, we hope that node.js core can switch to this new, safer behavior. We believe\nthe impact on the ecosystem would be minimal since it's not a breaking change.\nWell-maintained, popular packages would be updated to use `Buffer.alloc` quickly, while\nolder, insecure packages would magically become safe from this attack vector.\n\n\n## links\n\n- [Node.js PR: buffer: throw if both length and enc are passed](https://github.com/nodejs/node/pull/4514)\n- [Node Security Project disclosure for `ws`](https://nodesecurity.io/advisories/67)\n- [Node Security Project disclosure for`bittorrent-dht`](https://nodesecurity.io/advisories/68)\n\n\n## credit\n\nThe original issues in `bittorrent-dht`\n([disclosure](https://nodesecurity.io/advisories/68)) and\n`ws` ([disclosure](https://nodesecurity.io/advisories/67)) were discovered by\n[Mathias Buus](https://github.com/mafintosh) and\n[Feross Aboukhadijeh](http://feross.org/).\n\nThanks to [Adam Baldwin](https://github.com/evilpacket) for helping disclose these issues\nand for his work running the [Node Security Project](https://nodesecurity.io/).\n\nThanks to [John Hiesey](https://github.com/jhiesey) for proofreading this README and\nauditing the code.\n\n\n## license\n\nMIT. Copyright (C) [Feross Aboukhadijeh](http://feross.org)\n", - "readmeFilename": "README.md", - "_id": "safe-buffer@5.1.2", - "_requested": { - "type": "version", - "registry": true, - "raw": "safe-buffer@5.1.2", - "name": "safe-buffer", - "escapedName": "safe-buffer", - "rawSpec": "5.1.2", - "saveSpec": "[Circular]", - "fetchSpec": "5.1.2" - }, - "_spec": "5.1.2", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": "[Circular]", - "dependencies": {}, - "optionalDependencies": "[Circular]", - "_dependencies": "[Circular]", - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/safe-buffer", - "error": "[Circular]", - "extraneous": false, - "_deduped": "safe-buffer" - } - }, - "devDependencies": { - "babel-polyfill": "^6.23.0", - "core-util-is": "^1.0.2", - "inherits": "^2.0.3", - "tap": "~0.4.8" - }, - "scripts": { - "test": "tap test/parallel/*.js && node test/verify-dependencies", - "ci": "tap test/parallel/*.js test/ours/*.js --tap | tee test.tap && node test/verify-dependencies.js" - }, - "repository": { - "type": "git", - "url": "git://github.com/nodejs/string_decoder.git" - }, - "homepage": "https://github.com/nodejs/string_decoder", - "keywords": [ - "string", - "decoder", - "browser", - "browserify" - ], - "license": "MIT", - "_resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "_integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "_from": "string_decoder@1.1.1", - "readme": "# string_decoder\n\n***Node-core v8.9.4 string_decoder for userland***\n\n\n[![NPM](https://nodei.co/npm/string_decoder.png?downloads=true&downloadRank=true)](https://nodei.co/npm/string_decoder/)\n[![NPM](https://nodei.co/npm-dl/string_decoder.png?&months=6&height=3)](https://nodei.co/npm/string_decoder/)\n\n\n```bash\nnpm install --save string_decoder\n```\n\n***Node-core string_decoder for userland***\n\nThis package is a mirror of the string_decoder implementation in Node-core.\n\nFull documentation may be found on the [Node.js website](https://nodejs.org/dist/v8.9.4/docs/api/).\n\nAs of version 1.0.0 **string_decoder** uses semantic versioning.\n\n## Previous versions\n\nPrevious version numbers match the versions found in Node core, e.g. 0.10.24 matches Node 0.10.24, likewise 0.11.10 matches Node 0.11.10.\n\n## Update\n\nThe *build/* directory contains a build script that will scrape the source from the [nodejs/node](https://github.com/nodejs/node) repo given a specific Node version.\n\n## Streams Working Group\n\n`string_decoder` is maintained by the Streams Working Group, which\noversees the development and maintenance of the Streams API within\nNode.js. The responsibilities of the Streams Working Group include:\n\n* Addressing stream issues on the Node.js issue tracker.\n* Authoring and editing stream documentation within the Node.js project.\n* Reviewing changes to stream subclasses within the Node.js project.\n* Redirecting changes to streams from the Node.js project to this\n project.\n* Assisting in the implementation of stream providers within Node.js.\n* Recommending versions of `readable-stream` to be included in Node.js.\n* Messaging about the future of streams to give the community advance\n notice of changes.\n\nSee [readable-stream](https://github.com/nodejs/readable-stream) for\nmore details.\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/nodejs/string_decoder/issues" - }, - "_id": "string_decoder@1.1.1", - "_requested": { - "type": "version", - "registry": true, - "raw": "string_decoder@1.1.1", - "name": "string_decoder", - "escapedName": "string_decoder", - "rawSpec": "1.1.1", - "saveSpec": "[Circular]", - "fetchSpec": "1.1.1" - }, - "_spec": "1.1.1", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "string_decoder@1.1.1", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "optionalDependencies": {}, - "_dependencies": { - "safe-buffer": "~5.1.0" - }, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/string_decoder", - "error": "[Circular]", - "extraneous": false - }, - "util-deprecate": { - "name": "util-deprecate", - "version": "1.0.2", - "description": "The Node.js `util.deprecate()` function with browser support", - "main": "node.js", - "browser": "browser.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "repository": { - "type": "git", - "url": "git://github.com/TooTallNate/util-deprecate.git" - }, - "keywords": [ - "util", - "deprecate", - "browserify", - "browser", - "node" - ], - "author": { - "name": "Nathan Rajlich", - "email": "nathan@tootallnate.net", - "url": "http://n8.io/" - }, - "license": "MIT", - "bugs": { - "url": "https://github.com/TooTallNate/util-deprecate/issues" - }, - "homepage": "https://github.com/TooTallNate/util-deprecate", - "_resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "_integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "_from": "util-deprecate@1.0.2", - "readme": "util-deprecate\n==============\n### The Node.js `util.deprecate()` function with browser support\n\nIn Node.js, this module simply re-exports the `util.deprecate()` function.\n\nIn the web browser (i.e. via browserify), a browser-specific implementation\nof the `util.deprecate()` function is used.\n\n\n## API\n\nA `deprecate()` function is the only thing exposed by this module.\n\n``` javascript\n// setup:\nexports.foo = deprecate(foo, 'foo() is deprecated, use bar() instead');\n\n\n// users see:\nfoo();\n// foo() is deprecated, use bar() instead\nfoo();\nfoo();\n```\n\n\n## License\n\n(The MIT License)\n\nCopyright (c) 2014 Nathan Rajlich \n\nPermission is hereby granted, free of charge, to any person\nobtaining a copy of this software and associated documentation\nfiles (the \"Software\"), to deal in the Software without\nrestriction, including without limitation the rights to use,\ncopy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the\nSoftware is furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\nOF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\nHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\nOTHER DEALINGS IN THE SOFTWARE.\n", - "readmeFilename": "README.md", - "_id": "util-deprecate@1.0.2", - "_requested": { - "type": "version", - "registry": true, - "raw": "util-deprecate@1.0.2", - "name": "util-deprecate", - "escapedName": "util-deprecate", - "rawSpec": "1.0.2", - "saveSpec": "[Circular]", - "fetchSpec": "1.0.2" - }, - "_spec": "1.0.2", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "util-deprecate@1.0.2", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "dependencies": {}, - "devDependencies": {}, - "optionalDependencies": {}, - "_dependencies": {}, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/util-deprecate", - "error": "[Circular]", - "extraneous": false - } - }, - "devDependencies": { - "assert": "^1.4.0", - "babel-polyfill": "^6.9.1", - "buffer": "^4.9.0", - "lolex": "^2.3.2", - "nyc": "^6.4.0", - "tap": "^0.7.0", - "tape": "^4.8.0" - }, - "scripts": { - "test": "tap test/parallel/*.js test/ours/*.js && node test/verify-dependencies.js", - "ci": "tap test/parallel/*.js test/ours/*.js --tap | tee test.tap && node test/verify-dependencies.js", - "cover": "nyc npm test", - "report": "nyc report --reporter=lcov" - }, - "repository": { - "type": "git", - "url": "git://github.com/nodejs/readable-stream.git" - }, - "keywords": [ - "readable", - "stream", - "pipe" - ], - "browser": { - "util": false, - "./readable.js": "./readable-browser.js", - "./writable.js": "./writable-browser.js", - "./duplex.js": "./duplex-browser.js", - "./lib/internal/streams/stream.js": "./lib/internal/streams/stream-browser.js" - }, - "nyc": { - "include": [ - "lib/**.js" - ] - }, - "license": "MIT", - "_resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "_integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "_from": "readable-stream@2.3.6", - "readme": "# readable-stream\n\n***Node-core v8.11.1 streams for userland*** [![Build Status](https://travis-ci.org/nodejs/readable-stream.svg?branch=master)](https://travis-ci.org/nodejs/readable-stream)\n\n\n[![NPM](https://nodei.co/npm/readable-stream.png?downloads=true&downloadRank=true)](https://nodei.co/npm/readable-stream/)\n[![NPM](https://nodei.co/npm-dl/readable-stream.png?&months=6&height=3)](https://nodei.co/npm/readable-stream/)\n\n\n[![Sauce Test Status](https://saucelabs.com/browser-matrix/readable-stream.svg)](https://saucelabs.com/u/readable-stream)\n\n```bash\nnpm install --save readable-stream\n```\n\n***Node-core streams for userland***\n\nThis package is a mirror of the Streams2 and Streams3 implementations in\nNode-core.\n\nFull documentation may be found on the [Node.js website](https://nodejs.org/dist/v8.11.1/docs/api/stream.html).\n\nIf you want to guarantee a stable streams base, regardless of what version of\nNode you, or the users of your libraries are using, use **readable-stream** *only* and avoid the *\"stream\"* module in Node-core, for background see [this blogpost](http://r.va.gg/2014/06/why-i-dont-use-nodes-core-stream-module.html).\n\nAs of version 2.0.0 **readable-stream** uses semantic versioning.\n\n# Streams Working Group\n\n`readable-stream` is maintained by the Streams Working Group, which\noversees the development and maintenance of the Streams API within\nNode.js. The responsibilities of the Streams Working Group include:\n\n* Addressing stream issues on the Node.js issue tracker.\n* Authoring and editing stream documentation within the Node.js project.\n* Reviewing changes to stream subclasses within the Node.js project.\n* Redirecting changes to streams from the Node.js project to this\n project.\n* Assisting in the implementation of stream providers within Node.js.\n* Recommending versions of `readable-stream` to be included in Node.js.\n* Messaging about the future of streams to give the community advance\n notice of changes.\n\n\n## Team Members\n\n* **Chris Dickinson** ([@chrisdickinson](https://github.com/chrisdickinson)) <christopher.s.dickinson@gmail.com>\n - Release GPG key: 9554F04D7259F04124DE6B476D5A82AC7E37093B\n* **Calvin Metcalf** ([@calvinmetcalf](https://github.com/calvinmetcalf)) <calvin.metcalf@gmail.com>\n - Release GPG key: F3EF5F62A87FC27A22E643F714CE4FF5015AA242\n* **Rod Vagg** ([@rvagg](https://github.com/rvagg)) <rod@vagg.org>\n - Release GPG key: DD8F2338BAE7501E3DD5AC78C273792F7D83545D\n* **Sam Newman** ([@sonewman](https://github.com/sonewman)) <newmansam@outlook.com>\n* **Mathias Buus** ([@mafintosh](https://github.com/mafintosh)) <mathiasbuus@gmail.com>\n* **Domenic Denicola** ([@domenic](https://github.com/domenic)) <d@domenic.me>\n* **Matteo Collina** ([@mcollina](https://github.com/mcollina)) <matteo.collina@gmail.com>\n - Release GPG key: 3ABC01543F22DD2239285CDD818674489FBC127E\n* **Irina Shestak** ([@lrlna](https://github.com/lrlna)) <shestak.irina@gmail.com>\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/nodejs/readable-stream/issues" - }, - "homepage": "https://github.com/nodejs/readable-stream#readme", - "_id": "readable-stream@2.3.6", - "_requested": { - "type": "version", - "registry": true, - "raw": "readable-stream@2.3.6", - "name": "readable-stream", - "escapedName": "readable-stream", - "rawSpec": "2.3.6", - "saveSpec": "[Circular]", - "fetchSpec": "2.3.6" - }, - "_spec": "2.3.6", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "readable-stream@2.3.6", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "optionalDependencies": {}, - "_dependencies": { - "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" - }, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/readable-stream", - "error": "[Circular]", - "extraneous": false - } - }, - "devDependencies": { - "Base64": "^1.0.1", - "basic-auth-connect": "^1.0.0", - "body-parser": "^1.18.2", - "browserify": "^14.1.0", - "cookie-parser": "^1.4.3", - "express": "^4.16.0", - "express-session": "^1.15.6", - "marked": "^0.3.6", - "mocha": "^3.5.3", - "multer": "^1.3.0", - "should": "^11.2.0", - "should-http": "^0.1.1", - "zuul": "^3.11.1" - }, - "browser": { - "./lib/node/index.js": "./lib/client.js", - "./test/support/server.js": "./test/support/blank.js" - }, - "component": { - "scripts": { - "superagent": "lib/client.js" - } - }, - "main": "./lib/node/index.js", - "engines": { - "node": ">= 4.0" - }, - "_resolved": "https://registry.npmjs.org/superagent/-/superagent-3.8.2.tgz", - "_integrity": "sha512-gVH4QfYHcY3P0f/BZzavLreHW3T1v7hG9B+hpMQotGQqurOvhv87GcMCd6LWySmBuf+BDR44TQd0aISjVHLeNQ==", - "_from": "superagent@3.8.2", - "readme": "# SuperAgent [![Build Status](https://travis-ci.org/visionmedia/superagent.svg?branch=master)](https://travis-ci.org/visionmedia/superagent)\n\n[![Sauce Test Status](https://saucelabs.com/browser-matrix/shtylman-superagent.svg)](https://saucelabs.com/u/shtylman-superagent)\n\nSuperAgent is a small progressive __client-side__ HTTP request library, and __Node.js__ module with the same API, sporting many high-level HTTP client features. View the [docs](http://visionmedia.github.io/superagent/).\n\n![super agent](http://f.cl.ly/items/3d282n3A0h0Z0K2w0q2a/Screenshot.png)\n\n## Installation\n\nnode:\n\n```\n$ npm install superagent\n```\n\nWorks with [browserify](https://github.com/substack/node-browserify) and [webpack](https://github.com/visionmedia/superagent/wiki/SuperAgent-for-Webpack).\n\n```js\nrequest\n .post('/api/pet')\n .send({ name: 'Manny', species: 'cat' }) // sends a JSON post body\n .set('X-API-Key', 'foobar')\n .set('accept', 'json')\n .end((err, res) => {\n // Calling the end function will send the request\n });\n```\n\n## Supported browsers and Node versions\n\nTested browsers:\n\n- Latest Firefox, Chrome, Safari\n- Latest Android, iPhone\n- IE10 through latest. IE9 with polyfills. Even though IE9 is supported, a polyfill for `window.FormData` is required for `.field()`.\n\nNode 4 or later is required.\n\n## Plugins\n\nSuperAgent is easily extended via plugins.\n\n```js\nconst nocache = require('superagent-no-cache');\nconst request = require('superagent');\nconst prefix = require('superagent-prefix')('/static');\n\nrequest\n .get('/some-url')\n .query({ action: 'edit', city: 'London' }) // query string\n .use(prefix) // Prefixes *only* this request\n .use(nocache) // Prevents caching of *only* this request\n .end((err, res) => {\n // Do something\n });\n```\n\nExisting plugins:\n * [superagent-no-cache](https://github.com/johntron/superagent-no-cache) - prevents caching by including Cache-Control header\n * [superagent-prefix](https://github.com/johntron/superagent-prefix) - prefixes absolute URLs (useful in test environment)\n * [superagent-suffix](https://github.com/timneutkens1/superagent-suffix) - suffix URLs with a given path\n * [superagent-mock](https://github.com/M6Web/superagent-mock) - simulate HTTP calls by returning data fixtures based on the requested URL\n * [superagent-mocker](https://github.com/shuvalov-anton/superagent-mocker) — simulate REST API\n * [superagent-cache](https://github.com/jpodwys/superagent-cache) - A global SuperAgent patch with built-in, flexible caching\n * [superagent-cache-plugin](https://github.com/jpodwys/superagent-cache-plugin) - A SuperAgent plugin with built-in, flexible caching\n * [superagent-jsonapify](https://github.com/alex94puchades/superagent-jsonapify) - A lightweight [json-api](http://jsonapi.org/format/) client addon for superagent\n * [superagent-serializer](https://github.com/zzarcon/superagent-serializer) - Converts server payload into different cases\n * [superagent-use](https://github.com/koenpunt/superagent-use) - A client addon to apply plugins to all requests.\n * [superagent-httpbackend](https://www.npmjs.com/package/superagent-httpbackend) - stub out requests using AngularJS' $httpBackend syntax\n * [superagent-throttle](https://github.com/leviwheatcroft/superagent-throttle) - queues and intelligently throttles requests\n * [superagent-charset](https://github.com/magicdawn/superagent-charset) - add charset support for node's SuperAgent\n\nPlease prefix your plugin with `superagent-*` so that it can easily be found by others.\n\nFor SuperAgent extensions such as couchdb and oauth visit the [wiki](https://github.com/visionmedia/superagent/wiki).\n\n## Upgrading from previous versions:\n\nOur breaking changes are mostly in rarely used functionality and from stricter error handling.\n\n* [2.x to 3.x](https://github.com/visionmedia/superagent/releases/tag/v3.0.0):\n - Ensure you're running Node 4 or later. We dropped support for Node 0.x.\n - Test code that calls `.send()` multiple times. Invalid calls to `.send()` will now throw instead of sending garbage.\n* [1.x to 2.x](https://github.com/visionmedia/superagent/releases/tag/v2.0.0):\n - If you use `.parse()` in the *browser* version, rename it to `.serialize()`.\n - If you rely on `undefined` in query-string values being sent literally as the text \"undefined\", switch to checking for missing value instead. `?key=undefined` is now `?key` (without a value).\n - If you use `.then()` in Internet Explorer, ensure that you have a polyfill that adds a global `Promise` object.\n* 0.x to 1.x:\n - Use `.end(function(err, res){})`. 1-argument version is no longer supported.\n\n## Running node tests\n\nInstall dependencies:\n\n```shell\n$ npm install\n```\nRun em!\n\n```shell\n$ make test\n```\n\n## Running browser tests\n\nInstall dependencies:\n\n```shell\n$ npm install\n```\n\nStart the test runner:\n\n```shell\n$ make test-browser-local\n```\n\nVisit `http://localhost:4000/__zuul` in your browser.\n\nEdit tests and refresh your browser. You do not have to restart the test runner.\n\n\n## Packaging Notes for Developers\n\n**npm (for node)** is configured via the `package.json` file and the `.npmignore` file. Key metadata in the `package.json` file is the `version` field which should be changed according to semantic versioning and have a 1-1 correspondence with git tags. So for example, if you were to `git show v1.5.0:package.json | grep version`, you should see `\"version\": \"1.5.0\",` and this should hold true for every release. This can be handled via the `npm version` command. Be aware that when publishing, npm will presume the version being published should also be tagged in npm as `latest`, which is OK for normal incremental releases. For betas and minor/patch releases to older versions, be sure to include `--tag` appropriately to avoid an older release getting tagged as `latest`.\n\n**npm (for browser standalone)** When we publish versions to npm, we run `make superagent.js` which generates the standalone `superagent.js` file via `browserify`, and this file is included in the package published to npm (but this file is never checked into the git repository). If users want to install via npm but serve a single `.js` file directly to the browser, the `node_modules/superagent/superagent.js` is a standalone browserified file ready to go for that purpose. It is not minified.\n\n**npm (for browserify)** is handled via the `package.json` `browser` field which allows users to install SuperAgent via npm, reference it from their browser code with `require('superagent')`, and then build their own application bundle via `browserify`, which will use `lib/client.js` as the SuperAgent entrypoint.\n\n**bower** is configured via the `bower.json` file. Bower installs files directly from git/github without any transformation, so you *must* use Browserify or Webpack (or use npm).\n\n## License\n\nMIT\n", - "readmeFilename": "Readme.md", - "bugs": { - "url": "https://github.com/visionmedia/superagent/issues" - }, - "homepage": "https://github.com/visionmedia/superagent#readme", - "_id": "superagent@3.8.2", - "_requested": { - "type": "version", - "registry": true, - "raw": "superagent@3.8.2", - "name": "superagent", - "escapedName": "superagent", - "rawSpec": "3.8.2", - "saveSpec": "[Circular]", - "fetchSpec": "3.8.2" - }, - "_spec": "3.8.2", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "superagent@3.8.2", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "optionalDependencies": {}, - "_dependencies": { - "component-emitter": "^1.2.0", - "cookiejar": "^2.1.0", - "debug": "^3.1.0", - "extend": "^3.0.0", - "form-data": "^2.3.1", - "formidable": "^1.1.1", - "methods": "^1.1.1", - "mime": "^1.4.1", - "qs": "^6.5.1", - "readable-stream": "^2.0.5" - }, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/superagent", - "error": "[Circular]", - "extraneous": false - } - }, - "description": "JavaScript client library for the Alfresco REST API", - "devDependencies": { - "babel-loader": "^7.0.0", - "babel-plugin-transform-proto-to-assign": "^6.9.0", - "babel-preset-es2015": "^6.24.1", - "babel-preset-es2015-loose": "^8.0.0", - "babel-preset-es2015-rollup": "^3.0.0", - "babelify": "^7.3.0", - "chai": "^3.5.0", - "chai-datetime": "^1.4.1", - "expect.js": "~0.3.1", - "grunt": "~0.4.0", - "grunt-cli": "^1.1.0", - "grunt-contrib-jshint": "^1.0.0", - "grunt-coveralls": "^1.0.0", - "grunt-istanbul": "^0.7.0", - "grunt-jscs": "^2.8.0", - "grunt-mocha-istanbul": "^3.0.1", - "grunt-mocha-test": "0.13.3", - "grunt-open": "^0.2.3", - "load-grunt-tasks": "^3.4.1", - "markdown-toc": "^0.12.14", - "mocha": "5.2.0", - "mocha-lcov-reporter": "^1.2.0", - "nock": "8.1.0", - "remove-comments-loader": "0.1.2", - "rimraf": "^2.5.2", - "sinon": "^1.17.3", - "sinon-chai": "^2.8.0", - "tsd-jsdoc": "^2.0.0-beta.3", - "tslint": "5.7.0", - "typescript": "^2.4.0", - "uglifyjs-webpack-plugin": "^1.2.3", - "watchify": "^3.7.0", - "webpack": "4.1.1", - "webpack-cli": "2.0.12" - }, - "homepage": "https://github.com/Alfresco/alfresco-js-api#readme", - "keywords": [ - "alfresco" - ], - "license": "Apache-2.0", - "main": "dist/alfresco-js-api.js", - "name": "alfresco-js-api", - "repository": { - "type": "git", - "url": "git+https://github.com/Alfresco/alfresco-js-api.git" - }, - "scripts": { - "build": "npm run clean-build && grunt && npm run tslint && npm run test && npm run webpack && npm run toc", - "clean": "rimraf node_modules && npm run clean-build", - "clean-build": "rimraf dist", - "coverage": "grunt coverage", - "generate": "mvn clean generate-sources", - "generate-api": "mvn install", - "generate-ts": "jsdoc -c config.json .", - "prepublish": "npm run webpack", - "test": "grunt test", - "toc": "markdown-toc -i README.md && markdown-toc -i test/mockObjects/README.md", - "tslint": "tslint --type-check -c tslint.json index.d.ts --project tsconfig.json ", - "watchify": "watchify -s AlfrescoApi main.js -o dist/alfresco-js-api.js", - "webpack": "webpack" - }, - "sideEffects": false, - "typings": "index.d.ts", - "version": "2.6.1", - "readme": "# Alfresco JavaScript API Client\n\n\n

\n \n Gitter chat\n \n \n travis Status\n \n \n Coverage Status\n \n \n license\n \n\n

\n\n

\n alfresco\n

\n\nThis project provides a JavaScript client API into the Alfresco REST API and Activiti REST API.\n\n\n\n\n\n- [Full documentation of all the methods of each API](#full-documentation-of-all-the-methods-of-each-api)\n- [Prerequisites](#prerequisites)\n- [Node](#node)\n- [Api Modules complete methods list](#api-modules-complete-methods-list)\n- [Install](#install)\n- [Use](#use)\n + [Import library for node projects](#import-library-for-node-projects)\n + [Import library for browser projects](#import-library-for-browser-projects)\n- [Authentication JS-API](#authentication-js-api)\n * [Login](#login)\n + [Login with Username and Password BPM and ECM](#login-with-username-and-password-bpm-and-ecm)\n - [Example](#example)\n + [Login with Username and Password ECM](#login-with-username-and-password-ecm)\n - [Example](#example-1)\n + [Login with ticket](#login-with-ticket)\n - [Login with ticket ECM](#login-with-ticket-ecm)\n - [Example](#example-2)\n - [Login with ticket ECM/BPM as parameter in the constructor](#login-with-ticket-ecmbpm-as-parameter-in-the-constructor)\n * [Example](#example-3)\n + [Login with Username and Password BPM](#login-with-username-and-password-bpm)\n + [Example](#example-4)\n + [Login with OAUTH2 Alfresco authorization server](#login-with-oauth2-alfresco-authorization-server)\n * [Implicit Flow](#implicit-flow)\n - [oauth2 properties](#oauth2-properties)\n - [Events](#events)\n + [Example](#example-5)\n + [Example skip login form](#example-skip-login-form)\n * [Password Flow](#password-flow)\n + [Example](#example-6)\n + [Example](#example-7)\n * [Logout](#logout)\n + [Example](#example-8)\n * [isLoggedIn](#isloggedin)\n + [Example](#example-9)\n * [Get tickets](#get-tickets)\n * [Events login/logout](#events-loginlogout)\n + [Example](#example-10)\n- [Custom Endpoint](#custom-endpoint)\n * [Example](#example-11)\n- [ECM](#ecm)\n * [Get Node content](#get-node--content)\n + [Example](#example-12)\n * [Get File or Folder Info](#get-file-or-folder-info)\n + [Example](#example-13)\n * [Get Folder Children Info](#get-folder-children-info)\n + [Example](#example-14)\n * [Create Folder](#create-folder)\n + [Example](#example-15)\n + [Example](#example-16)\n * [Upload File](#upload-file)\n + [Example](#example-17)\n * [Events Upload File](#events-upload-file)\n + [Example](#example-18)\n * [Delete File or Folder](#delete-file-or-folder)\n + [Example](#example-19)\n * [Delete File or Folder Permanent](#delete-file-or-folder-permanent)\n + [Example](#example-20)\n * [Get thumbnail Url](#get-thumbnail-url)\n + [Example](#example-21)\n * [Get preview Url](#get-preview-url)\n + [Example](#example-22)\n * [Get content Url](#get-content-url)\n + [Example](#example-23)\n * [Custom web scripts call](#custom-web-scripts-call)\n + [Parameters](#parameters)\n- [BPM](#bpm)\n * [Task Api](#task-api)\n + [List Task](#list-task)\n - [Parameters](#parameters-1)\n - [Example](#example-24)\n + [Get Task](#get-task)\n - [Parameters](#parameters-2)\n - [Example](#example-25)\n + [Filter Task](#filter-task)\n - [Parameters](#parameters-3)\n - [Example](#example-26)\n + [Complete Task](#complete-task)\n - [Parameters](#parameters-4)\n - [Example](#example-27)\n + [Get Task Form](#get-task-form)\n - [Parameters](#parameters-5)\n - [Example](#example-28)\n + [Complete Task Form](#complete-task-form)\n - [Parameters](#parameters-6)\n - [Example](#example-29)\n * [Process Api](#process-api)\n + [Get Process Instances](#get-process-instances)\n - [Parameters](#parameters-7)\n - [Example](#example-30)\n * [Models Api](#models-api)\n + [Get Model](#get-model)\n - [Parameters](#parameters-8)\n - [Example](#example-31)\n * [Report Api](#report-api)\n + [Create default Reports](#create-default-reports)\n - [Parameters](#parameters-9)\n - [Example](#example-32)\n + [Get Reports](#get-reports)\n - [Parameters](#parameters-10)\n - [Example](#example-33)\n + [Report Params](#report-params)\n - [Parameters](#parameters-11)\n - [Example](#example-34)\n * [Report Process Definitions](#report-process-definitions)\n - [Parameters](#parameters-12)\n - [Example](#example-35)\n * [Tasks of process definition](#tasks-of-process-definition)\n - [Parameters](#parameters-13)\n - [Example](#example-36)\n * [Generate reports](#generate-reports)\n - [Parameters](#parameters-14)\n - [Example](#example-37)\n * [Update report details](#update-report-details)\n - [Parameters](#parameters-15)\n - [Example](#example-38)\n * [Export to csv](#export-to-csv)\n - [Parameters](#parameters-16)\n - [Example](#example-39)\n * [Save Report](#save-report)\n - [Parameters](#parameters-17)\n - [Example](#example-40)\n * [Delete report](#delete-report)\n - [Parameters](#parameters-18)\n - [Example](#example-41)\n- [Error Events](#error-events)\n * [Example](#example-42)\n- [Development](#development)\n- [Release History](#release-history)\n\n\n\n\n\n# Full documentation of all the methods of each API\n\n- [Authentication Services](/src/alfresco-auth-rest-api)\n- [Content Services](/src/alfresco-core-rest-api)\n- [Process Services](/src/alfresco-activiti-rest-api)\n- [ContentCMN](/src/alfresco-private-rest-api)\n- [Content Search](/src/alfresco-search-rest-api)\n\n# Prerequisites\n\nTo correctly use the alfresco js api the minimal supported version are:\n\n- 5.2.a-EA Alfresco Platform Repository (version [5.2.a-EA](https://wiki.alfresco.com/wiki/Community_file_list_201606-EA) or newer)\n- 1.5 Activiti\n\n# Node\nTo correctly use the alfresco-js-api in node check that on your machine is running Node version 5.0.0 or higher.\n\n# Api Modules complete methods list\n\n- [Authentication API](/src/alfresco-auth-rest-api)\n- [Core API](/src/alfresco-core-rest-api)\n- [Governance core API](/src/alfresco-gs-core-rest-api)\n- [Governance classification API](/src/alfresco-gs-classification-rest-api)\n- [Discovery API](/src/alfresco-discovery-rest-api)\n- [Search API](/src/alfresco-search-rest-api)\n- [Activiti API](/src/alfresco-activiti-rest-api)\n- [Mock API](/test/mockObjects)\n\n# Install\n\n\nInstaller for browser versions:\n\n```sh\nnpm install --save alfresco-js-api\n```\n\nInstaller for node versions:\n\n```sh\nnpm install --save alfresco-js-api-node\n```\n\n\n# Use\n\n### Import library for node projects\n\n```javascript\nvar AlfrescoApi = require('alfresco-js-api-node');\n```\n\n### Import library for browser projects\n\n```html\n \n\n or for not minify version\n\n \n```\n\n\n# Authentication JS-API\n\n## Login\n\nAlfrescoApi({alfrescoHost, activitiHost, contextRoot, ticket});\n\nProperty | Description | default value|\n------------- | ------------- | -------------|\nhostEcm| (Optional value The Ip or Name of the host where your Alfresco instance is running )|http://127.0.0.1:8080 |\nhostBpm| (Optional value The Ip or Name of the host where your Activiti instance is running )|http://127.0.0.1:9999 |\nauthType| (Optional value can be 'BASIC' or 'OAUTH') | 'BASIC'|\noauth2| (Optional configuration for SSO) ||\ncontextRoot| (Optional value that define the context Root of the Alfresco ECM API default value is alfresco )|alfresco |\ncontextRootBpm| (Optional value that define the context Root of the Activiti API default value is activiti-app )|alfresco |\nprovider| (Optional value default value is ECM. This parameter can accept as value ECM BPM or ALL to use the API and Login in the ECM, Activiti BPM or Both )|alfresco |\nticket| (Optional only if you want login with the ticket see example below)| |\ndisableCsrf| To disable CSRF Token to be submitted. Only for Activiti call.| false |\n\n### Login with Username and Password BPM and ECM\n\n#### Example\n```javascript\nthis.alfrescoJsApi = new AlfrescoApi({ provider:'ALL' });\n\nthis.alfrescoJsApi.login('admin', 'admin').then(function (data) {\n console.log('API called successfully Login in BPM and ECM performed ');\n}, function (error) {\n console.error(error);\n});\n```\n\n\n### Login with Username and Password ECM\n\n#### Example\n```javascript\nthis.alfrescoJsApi = new AlfrescoApi();\n\nthis.alfrescoJsApi.login('admin', 'admin').then(function (data) {\n console.log('API called successfully Login ticket:' + data);\n}, function (error) {\n console.error(error);\n});\n\n//The output will be: API called successfully Login ticket: TICKET_4479f4d3bb155195879bfbb8d5206f433488a1b1\n\n```\n\n### Login with ticket\n\nIf you already know thw ticket when you invoke the constructor you can pass it as parameter in the constructor otherwise you can call the login with ticket that will validate the ticket against the server\n\n\n#### Login with ticket ECM\n\nThis authentication validate also the ticket against the server\n\n#### Example\n```javascript\nvar ticket = 'TICKET_4479f4d3bb155195879bfbb8d5206f433488a1b1';\n\nthis.alfrescoJsApi.loginTicket(ticket).then(function (data) {\n console.log('valid ticket you are logged in');\n }, function (error) {\n console.error(error);\n });\n```\n\n#### Login with ticket ECM/BPM as parameter in the constructor\n\nWith this authentication the ticket is not validated against the server\n\n##### Example\n```javascript\n\n//Login ticket ECM\nthis.alfrescoJsApi = new AlfrescoApi({ ticketEcm:'TICKET_4479f4d3bb155195879bfbb8d5206f433488a1b1', hostEcm:'http://127.0.0.1:8080'});\n\n//Login ticket BPM\nthis.alfrescoJsApi = new AlfrescoApi({ ticketBpm: 'Basic YWRtaW46YWRtaW4=', hostBpm:'http://127.0.0.1:9999'});\n\n//Login ticket ECM and BPM\nthis.alfrescoJsApi = new AlfrescoApi({ ticketEcm:'TICKET_4479f4d3bb155195879bfbb8d5206f433488a1b1', ticketBpm: 'Basic YWRtaW46YWRtaW4=', hostEcm:'http://127.0.0.1:8080', hostBpm:'http://127.0.0.1:9999'});\n```\n\n### Login with Username and Password BPM\n\n### Example\n```javascript\nthis.alfrescoJsApi = new AlfrescoApi({ provider:'BPM' });\n\nthis.alfrescoJsApi.login('admin', 'admin').then(function (data) {\n console.log('API called successfully Login in Activiti BPM performed ');\n}, function (error) {\n console.error(error);\n});\n\n```\n### Login with OAUTH2 Alfresco authorization server\n\n## Implicit Flow\n\nIf your want to be redirect to the authorization server and login there you can use the implicit flow to login\n\n#### oauth2 properties\n\nProperty | Description | default value|\n------------- | ------------- | -------------|\nhost| Your oauth2 server URL| null |\nclientId| Your clientId oauth2 | null |\nsecret| Your secret oauth2| null |\nscope| Your scope | null |\nimplicitFlow| true/false | false |\nredirectUri| url to be redirect after login| null|\nredirectLogout| url to be redirect after logout optional, if is nor present the redirectUri will be used| null|\nrefreshTokenTimeout| millisecond value, after how many millisecond youw ant refresh the token| 40000|\nredirectSilentIframeUri| url to be redirect after silent refresh login| /assets/silent-refresh.html |\nsilentLogin| direct execute the implicit login without the need od call this.alfrescoJsApi.implicitLogin() method| false|\n\n\nThe alfresco-js-api will automatically redirect you to the login page anf refresh the token if necessary\n\n#### Events\n\nProperty | Description | default value|\n------------- | ------------- | -------------|\nimplicit_redirect| triggered when the user is redirect to the auth server return url parameter of the redirect | |\ndiscovery| triggered when all the openId discovery url phase is terminated returnl an object with all the discovered url | |\ntoken_issued| triggered when a new token is issued| |\n\nThe alfresco-js-api will automatically redirect you to the login page anf refresh the token if necessary\n\n\n### Example\n\n```javascript\nthis.alfrescoJsApi = new AlfrescoApi({\n oauth2: {\n host: 'HOST_OAUTH2_SERVER',\n clientId: 'YOUR_CLIENT_ID',\n secret: 'SECRET',\n scope: 'openid',\n implicitFlow: true,\n redirectUri: 'YOUR_HOME_APP_URL',\n silentRefreshTimeout: '600000' //Optional parameter 10 minutes default value\n },\n authType: 'OAUTH',\n provider: 'ALL'\n});\n\nthis.alfrescoJsApi.implicitLogin();\n\n```\n\n### Example skip login form\n\n```javascript\nthis.alfrescoJsApi = new AlfrescoApi({\n oauth2: {\n host: 'HOST_OAUTH2_SERVER',\n clientId: 'YOUR_CLIENT_ID',\n secret: 'SECRET',\n scope: 'openid',\n implicitFlow: true,\n redirectUri: 'YOUR_HOME_APP_URL',\n silentRefreshTimeout: '600000' //Optional parameter 10 minutes default value,\n silentLogin: true\n },\n authType: 'OAUTH',\n provider: 'ALL'\n});\n\n```\n\n\n## Password Flow\n\nIf your auth endpoint is different from the standard one \"/oauth/token\" you can override it through the property authPath\n\n### Example\n```javascript\nthis.alfrescoJsApi = new AlfrescoApi({\n oauth2: {\n host: 'HOST_OAUTH2_SERVER',\n clientId: 'YOUR_CLIENT_ID',\n secret: 'SECRET',\n authPath:'my-custom-auth-endpoint/token'\n },\n authType: 'OAUTH',\n provider: 'ALL'\n });\n\nthis.alfrescoJsApi.login('admin', 'admin').then(function (data) {\n console.log('API called successfully Login in with authorization server performed ');\n}, function (error) {\n console.error(error);\n});\n\n```\n\nAfter the login if you want refresh your token you can use this call\n\n### Example\n\n```javascript\nthis.alfrescoJsApi.refreshToken()then(function (data) {\n console.log('Your token has been refreshed');\n }, function (error) {\n console.error(error);\n });\n```\n\n## Logout\n\nlogout()\n\n### Example\n\n```javascript\n\nthis.alfrescoJsApi.logout().then(function (data) {\n console.log('Successfully Logout');\n}, function (error) {\n console.error('Possible ticket already expired');\n});\n\n```\n\n## isLoggedIn\n\nisLoggedIn()\n\n> return true if you are logged in false if you are not.\n\n### Example\n\n```javascript\n\nvar isLoggedIn = this.alfrescoJsApi.isLoggedIn();\n\nif (isLoggedIn) {\n console.log('You are logged in');\n} else {\n console.log('You are not logged in');\n}\n\n```\n## Get tickets\n\ngetTicketEcm()\n\n>After the log in you can retrieve you ECM ticket\n\n```javascript\n var ecmTicket = this.alfrescoJsApi.getTicketEcm() ;\n console.log('This is your ECM ticket ' + ecmTicket);\n\n```\n\ngetTicketBpm()\n\n>After the log in you can retrieve you BPM ticket\n\n```javascript\n\n var bpmTicket = this.alfrescoJsApi.getTicketBpm();\n console.log('This is your BPM ticket ' + bpmTicket);\n```\n\n## Events login/logout\n\n> The login/logout are also an EventEmitter which you can register to listen to any of the following event types:\n* unauthorized (If this event is triggered a call to the Api was unauthorized)\n* success (If this event is triggered the login was success you can use this event instead the login promise)\n* logout (If this event is triggered the client is successfully logout)\n\n### Example\n\n```javascript\n\nthis.alfrescoJsApi.login('admin', 'admin').on('unauthorized', function(){\n console.log('You are unauthorized you can use this event to redirect to login');\n});\n\nthis.alfrescoJsApi.login('admin', 'admin').on('success', function(){\n console.log('Success Login');\n});\n\nthis.alfrescoJsApi.logout().on('logout', function(){\n console.log('Successfully Logout');\n});\n```\n\n# Custom Endpoint\n\nContent service and process service has two different clients:\n\n- this.alfrescoJsApi.bpmClient\n- this.alfrescoJsApi.ecmClient\n\nBoth client expose a method ***callApi**\n\n\n```javascript\n callApi(path: string, httpMethod: string, pathParams?: any, queryParams?: any, headerParams?: any, formParams?: any, bodyParam?: any, authNames?: string[], contentTypes?: string[], accepts?: string[], returnType?: any, contextRoot?: string, responseType?: string): Promise;\n```\n\nIf you want call your custom rest point in one of those two service use the corrispondin client. \n\n## Example\n\n```javascript\n\n this.alfrescoJsApi.bpmClient.callApi(\n '/api/enterprise/app-version', 'GET',\n {}, {}, {}, {}, {},\n [], ['application/json'], ['application/json'], {'String': 'String'}\n )\n\n ```\n \n\n# ECM\n\nA complete list of all the ECM methods is available here : [Core API](/src/alfresco-core-rest-api).\nBelow you can find some common examples.\n\n## Get Node content\n\ngetFileContent(nodeId, opts)\n\n>Returns the file content of the node with identifier **nodeId**.\n\n ### Example\n```javascript\n\nvar nodeId = '80a94ac8-3ece-47ad-864e-5d939424c47c';\n\nthis.alfrescoJsApi.core.nodesApi.getFileContent(nodeId).then(function(data) {\n fs.writeFile('./test/grass.jpg', data, function(error) {\n if (error) {\n console.error(error);\n return;\n }\n console.log('The file was saved!');\n });\n}, function(error) {\n console.error(error);\n});\n```\n\n## Get File or Folder Info\n\ngetNodeInfo(fileOrFolderId, opts)\n\n>Get information for the File/Folder with the identifier nodeId. The identifier of a node. You can also use one of these well-known aliases: -my- , -shared- or -root- as NodeId\n\n### Example\n\n```javascript\n\nvar fileOrFolderId = '80a94ac8-3ece-47ad-864e-5d939424c47c';\n\nthis.alfrescoJsApi.nodes.getNodeInfo(fileOrFolderId).then(function (data) {\n console.log('This is the name' + data.name );\n}, function (error) {\n console.log('This node does not exist');\n});\n\n```\n## Get Folder Children Info\n\ngetNodeChildren(fileOrFolderId, opts)\n\n>Minimal information for each child is returned by default.\nYou can use the include parameter to return additional information.\nreturns a promise with the Info about the children of the node if resolved and {error} if rejected.\nYou can also use one of these well-known aliases: -my- , -shared- or -root- as NodeId\n\n### Example\n\n```javascript\n\nvar folderNodeId = '80a94ac8-3ece-47ad-864e-5d939424c47c';\n\nthis.alfrescoJsApi.nodes.getNodeChildren(folderNodeId).then(function (data) {\n console.log('The number of children in this folder are ' + data.list.pagination.count );\n}, function (error) {\n console.log('This node does not exist');\n});\n\n```\n## Create Folder\n\ncreateFolder(name, relativePath, nodeIdParentFolder, opts)\n\n>createFolder return a promise that is resolved if the folder is created and {error} if rejected.\nYou can also use one of these well-known aliases: -my- , -shared- or -root- as nodeIdParentFolder\n\n### Example\n\n```javascript\n\nthis.alfrescoJsApi.nodes.createFolder('newFolderName').then(function (data) {\n console.log('The folder is created in root');\n}, function (error) {\n console.log('Error in creation of this folder or folder already exist' + error);\n});\n\n\nthis.alfrescoJsApi.nodes.createFolder('newFolderName', 'folderA/folderB').then(function (data) {\n console.log('The folder is created in folderA/folderB from root');\n}, function (error) {\n console.log('Error in creation of this folder or folder already exist' + error);\n});\n\n\nvar parentFolder = '80a94ac8-3ece-47ad-864e-5d939424c47c'\n\nthis.alfrescoJsApi.nodes.createFolder('newFolderName', 'folderA/folderB', parentFolder).then(function (data) {\n console.log('The folder is created in folderA/folderB from parentFolder:' + parentFolder);\n}, function (error) {\n console.log('Error in creation of this folder or folder already exist' + error);\n});\n\n```\n\n**CreateFolder With Auto Rename**\n\ncreateFolderAutoRename(name, relativePath, nodeIdParentFolder, opts)\n>is the same of createFolder(name, relativePath, nodeId, {autoRename: true}) is just syntactic sugar\n You can also use one of these well-known aliases: -my- , -shared- or -root- as nodeIdParentFolder\n\n### Example\n\n```javascript\n\nthis.alfrescoJsApi.nodes.createFolderAutoRename('newFolderName').then(function (data) {\n console.log('The folder is created in root');\n}, function (error) {\n console.log('Error in creation of this folder' + error);\n});\n```\n\n## Upload File\n\nuploadFile(fileDefinition, relativePath, nodeId, nodeBody, opts)\n>uploadFile return a promise that is resolved if the file is successful uploaded and {error} if rejected.\n\nThe fileDefinition provides information about files and allows JavaScript to access their content.\n\n*Web File Definition\nFile Definition are generally retrieved from a FileList object returned as a result of a user selecting files using the element\n\n*Node File Definition\nFile Definition are generally retrieved from a read Stram\n\n### Example\n\n```javascript\n\nvar fs = require('fs');\n\nvar fileToUpload = fs.createReadStream('./folderA/folderB/newFile.txt');\n\nthis.alfrescoJsApi.upload.uploadFile(fileToUpload)\n .then(function () {\n console.log('File Uploaded in the root');\n }, function (error) {\n console.log('Error during the upload' + error);\n });\n\n\nthis.alfrescoJsApi.upload.uploadFile(fileToUpload, null, null, null, {autoRename: true})\n .then(function () {\n console.log('File Uploaded in the root');\n }, function (error) {\n console.log('Error during the upload' + error);\n });\n\n\nthis.alfrescoJsApi.upload.uploadFile(fileToUpload, 'folderX/folderY/folderZ')\n .then(function () {\n console.log('File Uploaded in the from root folderX/folderY/folderZ');\n }, function (error) {\n console.log('Error during the upload' + error);\n });\n\n\nvar parentFolder = '80a94ac8-3ece-47ad-864e-5d939424c47c';\n\nthis.alfrescoJsApi.upload.uploadFile(fileToUpload, 'folderX/folderY/folderZ', parentFolder )\n .then(function () {\n console.log('File Uploaded in the from parentFolder ' + parentFolder + ' n folderX/folderY/folderZ');\n }, function (error) {\n console.log('Error during the upload' + error);\n });\n\n```\n\nThe default behaviour of the Upload API will not create any thumbnail.\nIn order to create a thumbnail you have to perform to pass the parameter ```javascript{renditions: 'doclib'}``` as in the example below.\nThis parameter will basically perform also a call to the Rendition API.\nFor more information about the Rendition API :\n* [Rendition API](/src/alfresco-core-rest-api/docs/Rendition.md)\n* [Rendition service Wiki](https://wiki.alfresco.com/wiki/Rendition_Service)\n\n```javascript\n\nvar fs = require('fs');\n\nvar fileToUpload = fs.createReadStream('./folderA/folderB/newFile.txt');\n\nthis.alfrescoJsApi.upload.uploadFile(fileToUpload, null, null, null, {renditions: 'doclib'})\n .then(function () {\n console.log('File Uploaded in the root');\n }, function (error) {\n console.log('Error during the upload' + error);\n });\n\n```\n\n* To abort a file uploading\n\n\n```javascript\n\nvar fs = require('fs');\n\nvar fileToUpload = fs.createReadStream('./folderA/folderB/newFile.txt');\n\nvar promiseUpload = this.alfrescoJsApi.upload.uploadFile(fileToUpload)\n .once('abort', function () {\n console.log('File Uploaded aborted');\n });\n\npromiseUpload.abort();\n```\n\n\n## Events Upload File\n\n> The uploadFile is also an EventEmitter which you can register to listen to any of the following event types:\n* progress\n* success\n* abort\n* error\n* unauthorized\n\n### Example\n\n```javascript\nvar fs = require('fs');\n\nvar fileToUpload = fs.createReadStream('./folderA/folderB/newFile.txt');\n\nthis.alfrescoJsApi.upload.uploadFile(fileToUpload)\n .on('progress', (progress) => {\n console.log( 'Total :' + progress.total );\n console.log( 'Loaded :' + progress.loaded );\n console.log( 'Percent :' + progress.percent );\n })\n .on('success', () => {\n console.log( 'Your File is uploaded');\n });\n .on('abort', () => {\n console.log( 'Upload Aborted');\n })\n .on('error', () => {\n console.log( 'Error during the upload');\n })\n .on('unauthorized', () => {\n console.log('You are unauthorized');\n })\n```\n\n## Delete File or Folder\n\ndeleteNode(fileOrFolderId)\n\n>Delete File/Folder with the identifier nodeId, if the nodeId is a folder, then its children are also deleted\nDeleted nodes move to the trash bin is still possible to recover it\n\n### Example\n\n```javascript\n\nvar fileOrFolderId = '80a94ac8-3ece-47ad-864e-5d939424c47c';\n\nthis.alfrescoJsApi.nodes.deleteNode(fileOrFolderId).then(function (data) {\n console.log('The file/folder is deleted');\n}, function (error) {\n console.log('This node does not exist');\n});\n\n```\n\n## Delete File or Folder Permanent\n\ndeleteNodePermanent(fileOrFolderId)\n\n>Delete File/Folder with the identifier nodeId, if the nodeId is a folder, then its children are also deleted\nIf Deleted Permanent is used will not be possible recover the files\n\n### Example\n\n```javascript\n\nvar fileOrFolderId = '80a94ac8-3ece-47ad-864e-5d939424c47c';\n\nthis.alfrescoJsApi.nodes.deleteNodePermanent(fileOrFolderId).then(function (data) {\n console.log('The file/folder is deleted');\n}, function (error) {\n console.log('This node does not exist');\n});\n\n```\n\n## Get thumbnail Url\n\ngetDocumentThumbnailUrl(documentId)\n\n### Example\n\n```javascript\n\nvar thumbnailUrl = this.alfrescoJsApi.content.getDocumentThumbnailUrl('1a0b110f-1e09-4ca2-b367-fe25e4964a4');\n\n```\n\n## Get preview Url\n\ngetDocumentPreviewUrl(documentId)\n\n### Example\n\n```javascript\n\nvar previewUrl = this.alfrescoJsApi.content.getDocumentPreviewUrl('1a0b110f-1e09-4ca2-b367-fe25e4964a4');\n\n```\n\n## Get content Url\n\ngetContentUrl(documentId)\n\n### Example\n\n```javascript\n\nvar contentUrl = this.alfrescoJsApi.content.getContentUrl('1a0b110f-1e09-4ca2-b367-fe25e4964a4');\n\n```\n\n## Custom web scripts call\n\nFor mor information about web scripts read the [Wiki](https://wiki.alfresco.com/wiki/Web_Scripts) and the [Wiki with Web ScriptsExamples](https://wiki.alfresco.com/wiki/Web_Scripts_Examples)\n\nexecuteWebScript(httpMethod, scriptPath, scriptArgs, contextRoot, servicePath)\n\n> Anatomy of a Web Script URI **http(s)://(host):(port)/(contextPath)/(servicePath)/(scriptPath)?(scriptArgs)**\nA Web Script is simply a service bound to a URI which responds to HTTP methods such as GET, POST, PUT and DELETE. While using the same underlying code, there are broadly two kinds of Web Scripts.\n\n### Parameters\nName | Description\n------------- | -------------\n**httpMethod** | possible value GET, POST, PUT and DELETE\n**scriptPath** |path to Web Script (as defined by Web Script)\n**scriptArgs** |arguments to pass to Web Script\n**contextRoot** |path where application is deployed default value 'alfresco'\n**servicePath** |path where Web Script service is mapped default value 'service'\n**postBody** | post body\n\n```javascript\n\n//Call a GET on a Web Scripts available at the following URIs: http://127.0.01:8080/alfresco/service/mytasks\n\nthis.alfrescoJsApi.core.webscriptApi.executeWebScript('GET', 'mytasks').then(function (data) {\n console.log('Data received form http://127.0.01:8080/alfresco/service/mytasks' + data);\n}, function (error) {\n console.log('Error' + error);\n});\n\n//Call a GET on a Web Scripts available at the following URIs: http://127.0.01:8080/share/service/mytasks\n\nthis.alfrescoJsApi.core.webscriptApi.executeWebScript('GET', 'mytasks', null, 'share').then(function (data) {\n console.log('Data received form http://127.0.01:8080/share/service/mytasks' + data);\n}, function (error) {\n console.log('Error' + error);\n});\n\n//Call a GET on a Web Scripts available at the following URIs: http://127.0.01:8080/share/differentServiceSlug/mytasks\n\nthis.alfrescoJsApi.core.webscriptApi.executeWebScript('GET', 'mytasks', null, 'share', 'differentServiceSlug').then(function (data) {\n console.log('Data received form http://127.0.01:8080/share/differentServiceSlug/mytasks' + data);\n}, function (error) {\n console.log('Error' + error);\n});\n\n```\n\n# BPM\n\nA complete list of all the BPM methods is available her[Activiti API](/src/alfresco-activiti-rest-api).\nBelow you can find some common examples.\n\n## Task Api\n\nBelow you can find some example relative to the Activiti process api for all the possible method go to [Task Api documentation](/src/alfresco-activiti-rest-api/docs/TaskApi.md)\n\n### List Task\n\nlistTasks(requestNode)\n\n>return a list of task based on the requestNode query\n\n#### Parameters\n\nName | Type | Description\n------------- | ------------- | -------------\n **requestNode** | [**Representation**](/src/alfresco-activiti-rest-api/docs/TaskQueryRequestRepresentation.md)| requestNode\n\n#### Example\n\n```javascript\nvar requestTasks = new this.alfrescoJsApi.activiti.TaskQueryRequestRepresentation();\n\nthis.alfrescoJsApi.activiti.taskApi.listTasks(requestTasks).then(function (data) {\n console.log('listTasks ' + data);\n}, function (error) {\n console.log('Error' + error);\n});\n```\n\n### Get Task\n\ngetTask(taskId)\n\n>return the [**TaskRepresentation**](/src/alfresco-activiti-rest-api/docs/TaskRepresentation.md) of single task by id\n\n#### Parameters\n\nName | Type | Description\n------------- | ------------- | -------------\n **taskId** | **String**| taskId\n\n#### Example\n\n```javascript\n\nvar taskId = '10'; // String | taskId\n\nthis.alfrescoJsApi.activiti.taskApi.getTask(taskId).then(function (data) {\n console.log('Task representation ' + data);\n}, function (error) {\n console.log('Error' + error);\n});\n```\n\n### Filter Task\n\nfilterTasks(requestTasks)\n\n>return the [**ResultListDataRepresentation**](/src/alfresco-activiti-rest-api/docs/ResultListDataRepresentation.md) that is a list of all the task filered\n\n#### Parameters\n\nName | Type | Description\n------------- | ------------- | -------------\n **requestTasks** | [**TaskFilterRequestRepresentation**](/src/alfresco-activiti-rest-api/docs/TaskFilterRequestRepresentation.md)| requestTasks\n\n\n#### Example\n\n```javascript\n\nvar requestTasks = new this.alfrescoJsApi.activiti.TaskFilterRequestRepresentation();\nrequestTasks.appDefinitionId = 1;\n\nthis.alfrescoJsApi.activiti.taskApi.filterTasks(requestTasks).then(function (data) {\n console.log('Task filter list ' + data);\n}, function (error) {\n console.log('Error' + error);\n});\n```\n\n### Complete Task\n\ncompleteTask(taskId)\n\n>To complete a task (standalone or without a task form) :\n\n#### Parameters\n\nName | Type | Description\n------------- | ------------- | -------------\n **taskId** | **String**| taskId\n\n#### Example\n\n```javascript\n\nvar taskId = '10'; // String | taskId\n\nthis.alfrescoJsApi.activiti.taskApi.completeTask(taskId).then(function () {\n console.log('Task completed');\n}, function (error) {\n console.log('Error' + error);\n});\n```\n### Get Task Form\n\ngetTaskForm(taskId)\n\n>Retrieve the Task Form representation. [**FormDefinitionRepresentation**](/src/alfresco-activiti-rest-api/docs/FormDefinitionRepresentation.md)\n\n#### Parameters\n\nName | Type | Description\n------------- | ------------- | -------------\n **taskId** | **String**| taskId\n\n#### Example\n\n```javascript\n\nvar taskId = '10'; // String | taskId\n\nthis.alfrescoJsApi.activiti.taskApi.getTaskForm(taskId).then(function (data) {\n console.log('Task form representation' + data);\n}, function (error) {\n console.log('Error' + error);\n});\n```\n\n### Complete Task Form\n\ncompleteTaskForm(taskId, completeTaskFormRepresentation)\n\n>Complete a Task Form\n\n#### Parameters\n\nName | Type | Description\n------------- | ------------- | -------------\n **taskId** | **String**| taskId\n **completeTaskFormRepresentation** | [**CompleteFormRepresentation**](/src/alfresco-activiti-rest-api/docs/CompleteFormRepresentation.md)| completeTaskFormRepresentation\n\n#### Example\n\n```javascript\n\nvar taskId = '10'; // String | taskId\n\nthis.alfrescoJsApi.activiti.taskApi.completeTaskForm(taskId, completeTaskFormRepresentation).then(function () {\n console.log('Task completed');\n}, function (error) {\n console.log('Error' + error);\n});\n```\n\n## Process Api\n\nBelow you can find some example relative to the Activiti process api for all the possible method go to [Process Api documentation](/src/alfresco-activiti-rest-api/docs/ProcessApi.md)\n\n\n### Get Process Instances\n\ngetProcessInstances(requestNode)\n\n>Retrieve a list of process instances [**ResultListDataRepresentation**](/src/alfresco-activiti-rest-api/docs/ResultListDataRepresentation.md)\n\n#### Parameters\n\nName | Type | Description\n------------- | ------------- | -------------\n **requestNode** | [**ProcessFilterRequestRepresentation**](/src/alfresco-activiti-rest-api/docs/ProcessFilterRequestRepresentation.md)| requestNode\n\n#### Example\n\n```javascript\nvar requestNode = new this.alfrescoJsApi.activiti.ProcessFilterRequestRepresentation();\n\nthis.alfrescoJsApi.activiti.processApi.getProcessInstances(requestNode).then(function (data) {\n console.log('All processes' + data);\n}, function (error) {\n console.log('Error' + error);\n});\n```\n\nFiltered process:\n\n```javascript\n var requestNode = new this.alfrescoJsApi.activiti.ProcessFilterRequestRepresentation();\n\nrequestNode.page = 0;\nrequestNode.sort = 'created-desc';\nrequestNode.state = 'completed';\n\nthis.alfrescoJsApi.activiti.processApi.getProcessInstances(requestNode).then(function (data) {\n console.log('All processes completed' + data);\n}, function (error) {\n console.log('Error' + error);\n});\n```\n\n## Models Api\n\nBelow you can find some example relative to the Activiti process api for all the possible method go to [Task Api documentation](/src/alfresco-activiti-rest-api/docs/ModelsApi.md)\n\n### Get Model\n\ngetModel(modelId, opts)\n\n>To retrieve details about a particular model (process, form, decision rule or app) return a [**ModelRepresentation**](ModelRepresentation.md)\n\n#### Parameters\n\nName | Type | Description | Notes\n------------- | ------------- | ------------- | -------------\n **modelId** | **Integer**| modelId |\n **includePermissions** | **Boolean**| includePermissions | [optional]\n\n#### Example\n```javascript\n\nvar opts = {\n 'filter': 'myReusableForms',\n 'modelType': 2\n};\n\nthis.alfrescoJsApi.activiti.modelsApi.getModels(opts).then(function (data) {\n console.log('All your reusable forms' + data);\n }, function (error) {\n console.log('Error' + error);\n });\n```\n\n## Report Api\n\nBelow you can find some example relative to the Activiti report api for all the possible method go to [Report Api documentation](/src/alfresco-activiti-rest-api/docs/ReportApi.md)\n\n### Create default Reports\n\ncreateDefaultReports()\n\n>Create the default reports\n\n#### Parameters\n\nNo parameters required.\n\n#### Example\n\n```javascript\n\nthis.alfrescoJsApi.activiti.reportApi.createDefaultReports();\n```\n\n### Get Reports\n\ngetReportList()\n\n> Retrieve the available report list\n\n#### Parameters\n\nNo parameters required.\n\n#### Example\n\n```javascript\n\nthis.alfrescoJsApi.activiti.reportApi.getReportList();\n```\n\n### Report Params\n\ngetReportParams(reportId)\n\n> Retrieve the parameters referring to the reportId.\n\n#### Parameters\n\nName | Type | Description | Notes|\n------------- | ------------- | ------------- | -------------|\n **reportId** | **String**| reportId ||\n\n#### Example\n\n```javascript\n\nvar reportId = \"1\"; // String | reportId\n\nthis.alfrescoJsApi.activiti.reportApi.getReportParams(reportId);\n```\n\n## Report Process Definitions\n\ngetProcessDefinitions()\n\n> Retrieve the process definition list for all the apps.\n\n#### Parameters\n\nNo parameters required.\n\n#### Example\n\n```javascript\n\nthis.alfrescoJsApi.activiti.reportApi.getProcessDefinitions();\n```\n\n## Tasks of process definition\n\ngetTasksByProcessDefinitionId(reportId, processDefinitionId)\n\n> Retrieves all tasks that refer to the processDefinitionId\n\n#### Parameters\nName | Type | Description | Notes|\n------------- | ------------- | ------------- | -------------|\n **reportId** | **String**| reportId ||\n **processDefinitionId** | **String**| process definition id ||\n\n#### Example\n\n```javascript\n\nvar reportId = \"1\"; // String | reportId\nvar processDefinitionId = \"1\"; // String | processDefinitionId\n\nthis.alfrescoJsApi.activiti.reportApi.getTasksByProcessDefinitionId(reportId, processDefinitionId);\n```\n\n## Generate reports\n\ngetReportsByParams(reportId, paramsQuery)\n\n> Generate the reports based on the input parameters\n\n#### Parameters\nName | Type | Description | Notes|\n------------- | ------------- | ------------- | -------------|\n **reportId** | **String**| reportId ||\n **paramsQuery** | **Object**| Query parameters ||\n\n#### Example\n\n```javascript\n\nvar reportId = \"1\"; // String | reportId\nvar paramsQuery = {status: 'ALL'}; // Object | paramsQuery\n\nthis.alfrescoJsApi.activiti.reportApi.getReportsByParams(reportId, paramsQuery);\n```\n## Update report details\n\nupdateReport(reportId, name)\n\n> Update the report details\n\n#### Parameters\nName | Type | Description | Notes\n------------- | ------------- | ------------- | -------------|\n **reportId** | **String**| reportId ||\n **name** | **String**| The report name ||\n\n#### Example\n\n```javascript\n\nvar reportId = \"1\"; // String | reportId\nvar name = \"new Fake name\"; // String | reportId\n\nthis.alfrescoJsApi.activiti.reportApi.updateReport(reportId, name);\n```\n\n## Export to csv\nexportToCsv(reportId, queryParms)\n\n> Export a report as csv\n\n#### Parameters\nName | Type | Description | Notes\n------------- | ------------- | ------------- | -------------|\n **reportId** | **String**| reportId ||\n **queryParms** | **Object**| Query parameters ||\n\n#### Example\n```javascript\n\nvar reportId = \"1\"; // String | reportId\nvar queryParms = {\n 'processDefinitionId': 'TEST:99:999',\n 'dateRange': {\n 'startDate': '2017-01-01T00:00:00.000Z',\n 'endDate': '2017-01-24T23:59:59.999Z',\n 'rangeId': 'currentYear'\n },\n 'slowProcessInstanceInteger': 10,\n 'status': 'All',\n '__reportName': 'FAKE_REPORT_NAME'\n };\n\nthis.alfrescoJsApi.activiti.reportApi.exportToCsv(reportId, queryParms);\n```\n\n## Save Report\n\nsaveReport(reportId, queryParams)\n\n> Save a report\n\n#### Parameters\nName | Type | Description | Notes\n------------- | ------------- | ------------- | -------------|\n **reportId** | **String**| reportId ||\n **queryParms** | **Object**| Query parameters ||\n\n#### Example\n```javascript\n\nvar reportId = \"1\"; // String | reportId\nvar queryParms = {\n 'processDefinitionId': 'TEST:99:999',\n 'dateRange': {\n 'startDate': '2017-01-01T00:00:00.000Z',\n 'endDate': '2017-01-24T23:59:59.999Z',\n 'rangeId': 'currentYear'\n },\n 'slowProcessInstanceInteger': 10,\n 'status': 'All',\n '__reportName': 'FAKE_REPORT_NAME'\n };\n\nthis.alfrescoJsApi.activiti.reportApi.saveReport(reportId, queryParms);\n```\n\n## Delete report\ndeleteReport(reportId)\n\n> Delete a report\n\n#### Parameters\nName | Type | Description | Notes |\n------------- | ------------- | ------------- | ------------- |\n **reportId** | **String**| reportId | |\n\n#### Example\n```javascript\n\nvar reportId = \"1\"; // String | reportId\n\nthis.alfrescoJsApi.activiti.reportApi.deleteReport(reportId);\n```\n\n# Error Events\n\nThe alfresco-js-api has an error handler event where you can subscribe\n\n## Example\n```javascript\n this.alfrescoJsApi.on('error', (error) => {\n console.log(error)\n })\n```\n\n# Development\n\n* To run the build\n\n ```$ npm run build```\n\n* To run the build in watch mode\n\n ```$ npm run watchify```\n\n* To run the test\n\n ```$ npm run test```\n\n* To run the test coverage\n\n ```$ npm run coverage```\n\n\n# Release History\n\nRead the [Changelog] (./CHANGELOG.md)\n\n", - "readmeFilename": "README.md", - "optionalDependencies": {}, - "_dependencies": { - "event-emitter": "0.3.4", - "superagent": "3.8.2" - }, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/alfresco-js-api", - "error": "[Circular]", - "extraneous": false, - "peerMissing": [ - { - "requiredBy": "@alfresco/adf-extensions@3.0.0-383b74151a47e188020249aea7ec0dfb586bd0b6", - "requires": "alfresco-js-api@2.7.0-2a84d662e8134ada8923742adad17351a4a2f777" - } - ] - }, - "peerMissing": true - }, - "core-js": { - "required": { - "name": "core-js", - "description": "Standard library", - "version": "2.5.7", - "repository": { - "type": "git", - "url": "git+https://github.com/zloirock/core-js.git" - }, - "main": "index.js", - "devDependencies": { - "LiveScript": "1.3.x", - "es-observable-tests": "0.2.x", - "eslint": "4.19.x", - "eslint-plugin-import": "2.12.x", - "grunt": "^1.0.2", - "grunt-cli": "^1.2.0", - "grunt-contrib-clean": "^1.1.0", - "grunt-contrib-copy": "^1.0.0", - "grunt-contrib-uglify": "3.3.x", - "grunt-contrib-watch": "^1.0.0", - "grunt-karma": "^2.0.0", - "grunt-livescript": "0.6.x", - "karma": "^2.0.0", - "karma-qunit": "^2.1.0", - "karma-chrome-launcher": "^2.2.0", - "karma-firefox-launcher": "^1.0.1", - "karma-ie-launcher": "^1.0.0", - "karma-phantomjs-launcher": "1.0.x", - "phantomjs-prebuilt": "2.1.x", - "promises-aplus-tests": "^2.1.2", - "qunit": "2.6.x", - "temp": "^0.8.3", - "webpack": "^3.11.0" - }, - "scripts": { - "grunt": "grunt", - "lint": "eslint ./", - "promises-tests": "promises-aplus-tests tests/promises-aplus/adapter", - "observables-tests": "node tests/observables/adapter && node tests/observables/adapter-library", - "test": "npm run grunt clean copy && npm run lint && npm run grunt livescript client karma:default && npm run grunt library karma:library && npm run promises-tests && npm run observables-tests && lsc tests/commonjs" - }, - "license": "MIT", - "keywords": [ - "ES3", - "ES5", - "ES6", - "ES7", - "ES2015", - "ES2016", - "ES2017", - "ECMAScript 3", - "ECMAScript 5", - "ECMAScript 6", - "ECMAScript 7", - "ECMAScript 2015", - "ECMAScript 2016", - "ECMAScript 2017", - "Harmony", - "Strawman", - "Map", - "Set", - "WeakMap", - "WeakSet", - "Promise", - "Symbol", - "TypedArray", - "setImmediate", - "Dict", - "polyfill", - "shim" - ], - "_resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", - "_integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==", - "_from": "core-js@2.5.7", - "readme": "# core-js\n\n[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/zloirock/core-js?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![version](https://img.shields.io/npm/v/core-js.svg)](https://www.npmjs.com/package/core-js) [![npm downloads](https://img.shields.io/npm/dm/core-js.svg)](http://npm-stat.com/charts.html?package=core-js&author=&from=2014-11-18) [![Build Status](https://travis-ci.org/zloirock/core-js.svg)](https://travis-ci.org/zloirock/core-js) [![devDependency status](https://david-dm.org/zloirock/core-js/dev-status.svg)](https://david-dm.org/zloirock/core-js?type=dev)\n#### As advertising: the author is looking for a good job :)\n\nModular standard library for JavaScript. Includes polyfills for [ECMAScript 5](#ecmascript-5), [ECMAScript 6](#ecmascript-6): [promises](#ecmascript-6-promise), [symbols](#ecmascript-6-symbol), [collections](#ecmascript-6-collections), iterators, [typed arrays](#ecmascript-6-typed-arrays), [ECMAScript 7+ proposals](#ecmascript-7-proposals), [setImmediate](#setimmediate), etc. Some additional features such as [dictionaries](#dict) or [extended partial application](#partial-application). You can require only needed features or use it without global namespace pollution.\n\n[*Example*](http://goo.gl/a2xexl):\n```js\nArray.from(new Set([1, 2, 3, 2, 1])); // => [1, 2, 3]\n'*'.repeat(10); // => '**********'\nPromise.resolve(32).then(x => console.log(x)); // => 32\nsetImmediate(x => console.log(x), 42); // => 42\n```\n\n[*Without global namespace pollution*](http://goo.gl/paOHb0):\n```js\nvar core = require('core-js/library'); // With a modular system, otherwise use global `core`\ncore.Array.from(new core.Set([1, 2, 3, 2, 1])); // => [1, 2, 3]\ncore.String.repeat('*', 10); // => '**********'\ncore.Promise.resolve(32).then(x => console.log(x)); // => 32\ncore.setImmediate(x => console.log(x), 42); // => 42\n```\n\n### Index\n- [Usage](#usage)\n - [Basic](#basic)\n - [CommonJS](#commonjs)\n - [Custom build](#custom-build-from-the-command-line)\n- [Supported engines](#supported-engines)\n- [Features](#features)\n - [ECMAScript 5](#ecmascript-5)\n - [ECMAScript 6](#ecmascript-6)\n - [ECMAScript 6: Object](#ecmascript-6-object)\n - [ECMAScript 6: Function](#ecmascript-6-function)\n - [ECMAScript 6: Array](#ecmascript-6-array)\n - [ECMAScript 6: String](#ecmascript-6-string)\n - [ECMAScript 6: RegExp](#ecmascript-6-regexp)\n - [ECMAScript 6: Number](#ecmascript-6-number)\n - [ECMAScript 6: Math](#ecmascript-6-math)\n - [ECMAScript 6: Date](#ecmascript-6-date)\n - [ECMAScript 6: Promise](#ecmascript-6-promise)\n - [ECMAScript 6: Symbol](#ecmascript-6-symbol)\n - [ECMAScript 6: Collections](#ecmascript-6-collections)\n - [ECMAScript 6: Typed Arrays](#ecmascript-6-typed-arrays)\n - [ECMAScript 6: Reflect](#ecmascript-6-reflect)\n - [ECMAScript 7+ proposals](#ecmascript-7-proposals)\n - [stage 4 proposals](#stage-4-proposals)\n - [stage 3 proposals](#stage-3-proposals)\n - [stage 2 proposals](#stage-2-proposals)\n - [stage 1 proposals](#stage-1-proposals)\n - [stage 0 proposals](#stage-0-proposals)\n - [pre-stage 0 proposals](#pre-stage-0-proposals)\n - [Web standards](#web-standards)\n - [setTimeout / setInterval](#settimeout--setinterval)\n - [setImmediate](#setimmediate)\n - [iterable DOM collections](#iterable-dom-collections)\n - [Non-standard](#non-standard)\n - [Object](#object)\n - [Dict](#dict)\n - [partial application](#partial-application)\n - [Number Iterator](#number-iterator)\n - [escaping strings](#escaping-strings)\n - [delay](#delay)\n - [helpers for iterators](#helpers-for-iterators)\n- [Missing polyfills](#missing-polyfills)\n- [Changelog](./CHANGELOG.md)\n\n## Usage\n### Basic\n```\nnpm i core-js\nbower install core.js\n```\n\n```js\n// Default\nrequire('core-js');\n// Without global namespace pollution\nvar core = require('core-js/library');\n// Shim only\nrequire('core-js/shim');\n```\nIf you need complete build for browser, use builds from `core-js/client` path: \n\n* [default](https://raw.githack.com/zloirock/core-js/v2.5.7/client/core.min.js): Includes all features, standard and non-standard.\n* [as a library](https://raw.githack.com/zloirock/core-js/v2.5.7/client/library.min.js): Like \"default\", but does not pollute the global namespace (see [2nd example at the top](#core-js)).\n* [shim only](https://raw.githack.com/zloirock/core-js/v2.5.7/client/shim.min.js): Only includes the standard methods.\n\nWarning: if you use `core-js` with the extension of native objects, require all needed `core-js` modules at the beginning of entry point of your application, otherwise, conflicts may occur.\n\n### CommonJS\nYou can require only needed modules.\n\n```js\nrequire('core-js/fn/set');\nrequire('core-js/fn/array/from');\nrequire('core-js/fn/array/find-index');\nArray.from(new Set([1, 2, 3, 2, 1])); // => [1, 2, 3]\n[1, 2, NaN, 3, 4].findIndex(isNaN); // => 2\n\n// or, w/o global namespace pollution:\n\nvar Set = require('core-js/library/fn/set');\nvar from = require('core-js/library/fn/array/from');\nvar findIndex = require('core-js/library/fn/array/find-index');\nfrom(new Set([1, 2, 3, 2, 1])); // => [1, 2, 3]\nfindIndex([1, 2, NaN, 3, 4], isNaN); // => 2\n```\nAvailable entry points for methods / constructors, as above examples, and namespaces: for example, `core-js/es6/array` (`core-js/library/es6/array`) contains all [ES6 `Array` features](#ecmascript-6-array), `core-js/es6` (`core-js/library/es6`) contains all ES6 features.\n\n##### Caveats when using CommonJS API:\n\n* `modules` path is internal API, does not inject all required dependencies and can be changed in minor or patch releases. Use it only for a custom build and / or if you know what are you doing.\n* `core-js` is extremely modular and uses a lot of very tiny modules, because of that for usage in browsers bundle up `core-js` instead of usage loader for each file, otherwise, you will have hundreds of requests.\n\n#### CommonJS and prototype methods without global namespace pollution\nIn the `library` version, we can't pollute prototypes of native constructors. Because of that, prototype methods transformed to static methods like in examples above. `babel` `runtime` transformer also can't transform them. But with transpilers we can use one more trick - [bind operator and virtual methods](https://github.com/zenparsing/es-function-bind). Special for that, available `/virtual/` entry points. Example:\n```js\nimport fill from 'core-js/library/fn/array/virtual/fill';\nimport findIndex from 'core-js/library/fn/array/virtual/find-index';\n\nArray(10)::fill(0).map((a, b) => b * b)::findIndex(it => it && !(it % 8)); // => 4\n\n// or\n\nimport {fill, findIndex} from 'core-js/library/fn/array/virtual';\n\nArray(10)::fill(0).map((a, b) => b * b)::findIndex(it => it && !(it % 8)); // => 4\n\n```\n\n### Custom build (from the command-line)\n```\nnpm i core-js && cd node_modules/core-js && npm i\nnpm run grunt build:core.dict,es6 -- --blacklist=es6.promise,es6.math --library=on --path=custom uglify\n```\nWhere `core.dict` and `es6` are modules (namespaces) names, which will be added to the build, `es6.promise` and `es6.math` are modules (namespaces) names, which will be excluded from the build, `--library=on` is flag for build without global namespace pollution and `custom` is target file name.\n\nAvailable namespaces: for example, `es6.array` contains [ES6 `Array` features](#ecmascript-6-array), `es6` contains all modules whose names start with `es6`.\n\n### Custom build (from external scripts)\n\n[`core-js-builder`](https://www.npmjs.com/package/core-js-builder) package exports a function that takes the same parameters as the `build` target from the previous section. This will conditionally include or exclude certain parts of `core-js`:\n\n```js\nrequire('core-js-builder')({\n modules: ['es6', 'core.dict'], // modules / namespaces\n blacklist: ['es6.reflect'], // blacklist of modules / namespaces, by default - empty list\n library: false, // flag for build without global namespace pollution, by default - false\n umd: true // use UMD wrapper for export `core` object, by default - true\n}).then(code => {\n // ...\n}).catch(error => {\n // ...\n});\n```\n## Supported engines\n**Tested in:**\n- Chrome 26+\n- Firefox 4+\n- Safari 5+\n- Opera 12+\n- Internet Explorer 6+ (sure, IE8- with ES3 limitations)\n- Edge\n- Android Browser 2.3+\n- iOS Safari 5.1+\n- PhantomJS 1.9 / 2.1\n- NodeJS 0.8+\n\n...and it doesn't mean `core-js` will not work in other engines, they just have not been tested.\n\n## Features:\n[*CommonJS entry points:*](#commonjs)\n```\ncore-js(/library) <- all features\ncore-js(/library)/shim <- only polyfills\n```\n### ECMAScript 5\nAll features moved to the [`es6` namespace](#ecmascript-6), here just a list of features:\n```js\nObject\n .create(proto | null, descriptors?) -> object\n .getPrototypeOf(object) -> proto | null\n .defineProperty(target, key, desc) -> target, cap for ie8-\n .defineProperties(target, descriptors) -> target, cap for ie8-\n .getOwnPropertyDescriptor(object, key) -> desc\n .getOwnPropertyNames(object) -> array\n .keys(object) -> array\n .seal(object) -> object, cap for ie8-\n .freeze(object) -> object, cap for ie8-\n .preventExtensions(object) -> object, cap for ie8-\n .isSealed(object) -> bool, cap for ie8-\n .isFrozen(object) -> bool, cap for ie8-\n .isExtensible(object) -> bool, cap for ie8-\nArray\n .isArray(var) -> bool\n #slice(start?, end?) -> array, fix for ie7-\n #join(string = ',') -> string, fix for ie7-\n #indexOf(var, from?) -> int\n #lastIndexOf(var, from?) -> int\n #every(fn(val, index, @), that) -> bool\n #some(fn(val, index, @), that) -> bool\n #forEach(fn(val, index, @), that) -> void\n #map(fn(val, index, @), that) -> array\n #filter(fn(val, index, @), that) -> array\n #reduce(fn(memo, val, index, @), memo?) -> var\n #reduceRight(fn(memo, val, index, @), memo?) -> var\n #sort(fn?) -> @, fixes for some engines\nFunction\n #bind(object, ...args) -> boundFn(...args)\nString\n #split(separator, limit) -> array\n #trim() -> str\nRegExp\n #toString() -> str\nNumber\n #toFixed(digits) -> string\n #toPrecision(precision) -> string\nparseInt(str, radix) -> int\nparseFloat(str) -> num\nDate\n .now() -> int\n #toISOString() -> string\n #toJSON() -> string\n```\n[*CommonJS entry points:*](#commonjs)\n```\ncore-js(/library)/es5\n```\n\n### ECMAScript 6\n[*CommonJS entry points:*](#commonjs)\n```\ncore-js(/library)/es6\n```\n#### ECMAScript 6: Object\nModules [`es6.object.assign`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.object.assign.js), [`es6.object.is`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.object.is.js), [`es6.object.set-prototype-of`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.object.set-prototype-of.js) and [`es6.object.to-string`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.object.to-string.js).\n\nIn ES6 most `Object` static methods should work with primitives. Modules [`es6.object.freeze`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.object.freeze.js), [`es6.object.seal`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.object.seal.js), [`es6.object.prevent-extensions`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.object.prevent-extensions.js), [`es6.object.is-frozen`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.object.is-frozen.js), [`es6.object.is-sealed`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.object.is-sealed.js), [`es6.object.is-extensible`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.object.is-extensible.js), [`es6.object.get-own-property-descriptor`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.object.get-own-property-descriptor.js), [`es6.object.get-prototype-of`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.object.get-prototype-of.js), [`es6.object.keys`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.object.keys.js) and [`es6.object.get-own-property-names`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.object.get-own-property-names.js).\n\nJust ES5 features: [`es6.object.create`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.object.create.js), [`es6.object.define-property`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.object.define-property.js) and [`es6.object.define-properties`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.object.es6.object.define-properties.js).\n```js\nObject\n .assign(target, ...src) -> target\n .is(a, b) -> bool\n .setPrototypeOf(target, proto | null) -> target (required __proto__ - IE11+)\n .create(object | null, descriptors?) -> object\n .getPrototypeOf(var) -> object | null\n .defineProperty(object, key, desc) -> target\n .defineProperties(object, descriptors) -> target\n .getOwnPropertyDescriptor(var, key) -> desc | undefined\n .keys(var) -> array\n .getOwnPropertyNames(var) -> array\n .freeze(var) -> var\n .seal(var) -> var\n .preventExtensions(var) -> var\n .isFrozen(var) -> bool\n .isSealed(var) -> bool\n .isExtensible(var) -> bool\n #toString() -> string, ES6 fix: @@toStringTag support\n```\n[*CommonJS entry points:*](#commonjs)\n```\ncore-js(/library)/es6/object\ncore-js(/library)/fn/object/assign\ncore-js(/library)/fn/object/is\ncore-js(/library)/fn/object/set-prototype-of\ncore-js(/library)/fn/object/get-prototype-of\ncore-js(/library)/fn/object/create\ncore-js(/library)/fn/object/define-property\ncore-js(/library)/fn/object/define-properties\ncore-js(/library)/fn/object/get-own-property-descriptor\ncore-js(/library)/fn/object/keys\ncore-js(/library)/fn/object/get-own-property-names\ncore-js(/library)/fn/object/freeze\ncore-js(/library)/fn/object/seal\ncore-js(/library)/fn/object/prevent-extensions\ncore-js(/library)/fn/object/is-frozen\ncore-js(/library)/fn/object/is-sealed\ncore-js(/library)/fn/object/is-extensible\ncore-js/fn/object/to-string\n```\n[*Examples*](http://goo.gl/ywdwPz):\n```js\nvar foo = {q: 1, w: 2}\n , bar = {e: 3, r: 4}\n , baz = {t: 5, y: 6};\nObject.assign(foo, bar, baz); // => foo = {q: 1, w: 2, e: 3, r: 4, t: 5, y: 6}\n\nObject.is(NaN, NaN); // => true\nObject.is(0, -0); // => false\nObject.is(42, 42); // => true\nObject.is(42, '42'); // => false\n\nfunction Parent(){}\nfunction Child(){}\nObject.setPrototypeOf(Child.prototype, Parent.prototype);\nnew Child instanceof Child; // => true\nnew Child instanceof Parent; // => true\n\nvar O = {};\nO[Symbol.toStringTag] = 'Foo';\n'' + O; // => '[object Foo]'\n\nObject.keys('qwe'); // => ['0', '1', '2']\nObject.getPrototypeOf('qwe') === String.prototype; // => true\n```\n#### ECMAScript 6: Function\nModules [`es6.function.name`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.function.name.js), [`es6.function.has-instance`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.function.has-instance.js). Just ES5: [`es6.function.bind`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.function.bind.js).\n```js\nFunction\n #bind(object, ...args) -> boundFn(...args)\n #name -> string (IE9+)\n #@@hasInstance(var) -> bool\n```\n[*CommonJS entry points:*](#commonjs)\n```\ncore-js/es6/function\ncore-js/fn/function/name\ncore-js/fn/function/has-instance\ncore-js/fn/function/bind\ncore-js/fn/function/virtual/bind\n```\n[*Example*](http://goo.gl/zqu3Wp):\n```js\n(function foo(){}).name // => 'foo'\n\nconsole.log.bind(console, 42)(43); // => 42 43\n```\n#### ECMAScript 6: Array\nModules [`es6.array.from`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.array.from.js), [`es6.array.of`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.array.of.js), [`es6.array.copy-within`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.array.copy-within.js), [`es6.array.fill`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.array.fill.js), [`es6.array.find`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.array.find.js), [`es6.array.find-index`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.array.find-index.js), [`es6.array.iterator`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.array.iterator.js). ES5 features with fixes: [`es6.array.is-array`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.array.is-array.js), [`es6.array.slice`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.array.slice.js), [`es6.array.join`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.array.join.js), [`es6.array.index-of`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.array.index-of.js), [`es6.array.last-index-of`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.array.last-index-of.js), [`es6.array.every`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.array.every.js), [`es6.array.some`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.array.some.js), [`es6.array.for-each`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.array.for-each.js), [`es6.array.map`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.array.map.js), [`es6.array.filter`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.array.filter.js), [`es6.array.reduce`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.array.reduce.js), [`es6.array.reduce-right`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.array.reduce-right.js), [`es6.array.sort`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.array.sort.js).\n```js\nArray\n .from(iterable | array-like, mapFn(val, index)?, that) -> array\n .of(...args) -> array\n .isArray(var) -> bool\n #copyWithin(target = 0, start = 0, end = @length) -> @\n #fill(val, start = 0, end = @length) -> @\n #find(fn(val, index, @), that) -> val\n #findIndex(fn(val, index, @), that) -> index | -1\n #values() -> iterator\n #keys() -> iterator\n #entries() -> iterator\n #join(string = ',') -> string, fix for ie7-\n #slice(start?, end?) -> array, fix for ie7-\n #indexOf(var, from?) -> index | -1\n #lastIndexOf(var, from?) -> index | -1\n #every(fn(val, index, @), that) -> bool\n #some(fn(val, index, @), that) -> bool\n #forEach(fn(val, index, @), that) -> void\n #map(fn(val, index, @), that) -> array\n #filter(fn(val, index, @), that) -> array\n #reduce(fn(memo, val, index, @), memo?) -> var\n #reduceRight(fn(memo, val, index, @), memo?) -> var\n #sort(fn?) -> @, invalid arguments fix\n #@@iterator() -> iterator (values)\n #@@unscopables -> object (cap)\nArguments\n #@@iterator() -> iterator (values, available only in core-js methods)\n```\n[*CommonJS entry points:*](#commonjs)\n```\ncore-js(/library)/es6/array\ncore-js(/library)/fn/array/from\ncore-js(/library)/fn/array/of\ncore-js(/library)/fn/array/is-array\ncore-js(/library)/fn/array/iterator\ncore-js(/library)/fn/array/copy-within\ncore-js(/library)/fn/array/fill\ncore-js(/library)/fn/array/find\ncore-js(/library)/fn/array/find-index\ncore-js(/library)/fn/array/values\ncore-js(/library)/fn/array/keys\ncore-js(/library)/fn/array/entries\ncore-js(/library)/fn/array/slice\ncore-js(/library)/fn/array/join\ncore-js(/library)/fn/array/index-of\ncore-js(/library)/fn/array/last-index-of\ncore-js(/library)/fn/array/every\ncore-js(/library)/fn/array/some\ncore-js(/library)/fn/array/for-each\ncore-js(/library)/fn/array/map\ncore-js(/library)/fn/array/filter\ncore-js(/library)/fn/array/reduce\ncore-js(/library)/fn/array/reduce-right\ncore-js(/library)/fn/array/sort\ncore-js(/library)/fn/array/virtual/iterator\ncore-js(/library)/fn/array/virtual/copy-within\ncore-js(/library)/fn/array/virtual/fill\ncore-js(/library)/fn/array/virtual/find\ncore-js(/library)/fn/array/virtual/find-index\ncore-js(/library)/fn/array/virtual/values\ncore-js(/library)/fn/array/virtual/keys\ncore-js(/library)/fn/array/virtual/entries\ncore-js(/library)/fn/array/virtual/slice\ncore-js(/library)/fn/array/virtual/join\ncore-js(/library)/fn/array/virtual/index-of\ncore-js(/library)/fn/array/virtual/last-index-of\ncore-js(/library)/fn/array/virtual/every\ncore-js(/library)/fn/array/virtual/some\ncore-js(/library)/fn/array/virtual/for-each\ncore-js(/library)/fn/array/virtual/map\ncore-js(/library)/fn/array/virtual/filter\ncore-js(/library)/fn/array/virtual/reduce\ncore-js(/library)/fn/array/virtual/reduce-right\ncore-js(/library)/fn/array/virtual/sort\n```\n[*Examples*](http://goo.gl/oaUFUf):\n```js\nArray.from(new Set([1, 2, 3, 2, 1])); // => [1, 2, 3]\nArray.from({0: 1, 1: 2, 2: 3, length: 3}); // => [1, 2, 3]\nArray.from('123', Number); // => [1, 2, 3]\nArray.from('123', function(it){\n return it * it;\n}); // => [1, 4, 9]\n\nArray.of(1); // => [1]\nArray.of(1, 2, 3); // => [1, 2, 3]\n\nvar array = ['a', 'b', 'c'];\n\nfor(var val of array)console.log(val); // => 'a', 'b', 'c'\nfor(var val of array.values())console.log(val); // => 'a', 'b', 'c'\nfor(var key of array.keys())console.log(key); // => 0, 1, 2\nfor(var [key, val] of array.entries()){\n console.log(key); // => 0, 1, 2\n console.log(val); // => 'a', 'b', 'c'\n}\n\nfunction isOdd(val){\n return val % 2;\n}\n[4, 8, 15, 16, 23, 42].find(isOdd); // => 15\n[4, 8, 15, 16, 23, 42].findIndex(isOdd); // => 2\n[4, 8, 15, 16, 23, 42].find(isNaN); // => undefined\n[4, 8, 15, 16, 23, 42].findIndex(isNaN); // => -1\n\nArray(5).fill(42); // => [42, 42, 42, 42, 42]\n\n[1, 2, 3, 4, 5].copyWithin(0, 3); // => [4, 5, 3, 4, 5]\n```\n#### ECMAScript 6: String\nModules [`es6.string.from-code-point`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.string.from-code-point.js), [`es6.string.raw`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.string.raw.js), [`es6.string.iterator`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.string.iterator.js), [`es6.string.code-point-at`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.string.code-point-at.js), [`es6.string.ends-with`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.string.ends-with.js), [`es6.string.includes`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.string.includes.js), [`es6.string.repeat`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.string.repeat.js), [`es6.string.starts-with`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.string.starts-with.js) and [`es6.string.trim`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.string.trim.js).\n\nAnnex B HTML methods. Ugly, but it's also the part of the spec. Modules [`es6.string.anchor`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.string.anchor.js), [`es6.string.big`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.string.big.js), [`es6.string.blink`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.string.blink.js), [`es6.string.bold`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.string.bold.js), [`es6.string.fixed`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.string.fixed.js), [`es6.string.fontcolor`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.string.fontcolor.js), [`es6.string.fontsize`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.string.fontsize.js), [`es6.string.italics`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.string.italics.js), [`es6.string.link`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.string.link.js), [`es6.string.small`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.string.small.js), [`es6.string.strike`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.string.strike.js), [`es6.string.sub`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.string.sub.js) and [`es6.string.sup`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.string.sup.js).\n```js\nString\n .fromCodePoint(...codePoints) -> str\n .raw({raw}, ...substitutions) -> str\n #includes(str, from?) -> bool\n #startsWith(str, from?) -> bool\n #endsWith(str, from?) -> bool\n #repeat(num) -> str\n #codePointAt(pos) -> uint\n #trim() -> str, ES6 fix\n #anchor(name) -> str\n #big() -> str\n #blink() -> str\n #bold() -> str\n #fixed() -> str\n #fontcolor(color) -> str\n #fontsize(size) -> str\n #italics() -> str\n #link(url) -> str\n #small() -> str\n #strike() -> str\n #sub() -> str\n #sup() -> str\n #@@iterator() -> iterator (code points)\n```\n[*CommonJS entry points:*](#commonjs)\n```\ncore-js(/library)/es6/string\ncore-js(/library)/fn/string/from-code-point\ncore-js(/library)/fn/string/raw\ncore-js(/library)/fn/string/includes\ncore-js(/library)/fn/string/starts-with\ncore-js(/library)/fn/string/ends-with\ncore-js(/library)/fn/string/repeat\ncore-js(/library)/fn/string/code-point-at\ncore-js(/library)/fn/string/trim\ncore-js(/library)/fn/string/anchor\ncore-js(/library)/fn/string/big\ncore-js(/library)/fn/string/blink\ncore-js(/library)/fn/string/bold\ncore-js(/library)/fn/string/fixed\ncore-js(/library)/fn/string/fontcolor\ncore-js(/library)/fn/string/fontsize\ncore-js(/library)/fn/string/italics\ncore-js(/library)/fn/string/link\ncore-js(/library)/fn/string/small\ncore-js(/library)/fn/string/strike\ncore-js(/library)/fn/string/sub\ncore-js(/library)/fn/string/sup\ncore-js(/library)/fn/string/iterator\ncore-js(/library)/fn/string/virtual/includes\ncore-js(/library)/fn/string/virtual/starts-with\ncore-js(/library)/fn/string/virtual/ends-with\ncore-js(/library)/fn/string/virtual/repeat\ncore-js(/library)/fn/string/virtual/code-point-at\ncore-js(/library)/fn/string/virtual/trim\ncore-js(/library)/fn/string/virtual/anchor\ncore-js(/library)/fn/string/virtual/big\ncore-js(/library)/fn/string/virtual/blink\ncore-js(/library)/fn/string/virtual/bold\ncore-js(/library)/fn/string/virtual/fixed\ncore-js(/library)/fn/string/virtual/fontcolor\ncore-js(/library)/fn/string/virtual/fontsize\ncore-js(/library)/fn/string/virtual/italics\ncore-js(/library)/fn/string/virtual/link\ncore-js(/library)/fn/string/virtual/small\ncore-js(/library)/fn/string/virtual/strike\ncore-js(/library)/fn/string/virtual/sub\ncore-js(/library)/fn/string/virtual/sup\ncore-js(/library)/fn/string/virtual/iterator\n```\n[*Examples*](http://goo.gl/3UaQ93):\n```js\nfor(var val of 'a𠮷b'){\n console.log(val); // => 'a', '𠮷', 'b'\n}\n\n'foobarbaz'.includes('bar'); // => true\n'foobarbaz'.includes('bar', 4); // => false\n'foobarbaz'.startsWith('foo'); // => true\n'foobarbaz'.startsWith('bar', 3); // => true\n'foobarbaz'.endsWith('baz'); // => true\n'foobarbaz'.endsWith('bar', 6); // => true\n\n'string'.repeat(3); // => 'stringstringstring'\n\n'𠮷'.codePointAt(0); // => 134071\nString.fromCodePoint(97, 134071, 98); // => 'a𠮷b'\n\nvar name = 'Bob';\nString.raw`Hi\\n${name}!`; // => 'Hi\\\\nBob!' (ES6 template string syntax)\nString.raw({raw: 'test'}, 0, 1, 2); // => 't0e1s2t'\n\n'foo'.bold(); // => 'foo'\n'bar'.anchor('a\"b'); // => 'bar'\n'baz'.link('http://example.com'); // => 'baz'\n```\n#### ECMAScript 6: RegExp\nModules [`es6.regexp.constructor`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.regexp.constructor.js) and [`es6.regexp.flags`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.regexp.flags.js).\n\nSupport well-known [symbols](#ecmascript-6-symbol) `@@match`, `@@replace`, `@@search` and `@@split`, modules [`es6.regexp.match`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.regexp.match.js), [`es6.regexp.replace`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.regexp.replace.js), [`es6.regexp.search`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.regexp.search.js) and [`es6.regexp.split`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.regexp.split.js).\n```\n[new] RegExp(pattern, flags?) -> regexp, ES6 fix: can alter flags (IE9+)\n #flags -> str (IE9+)\n #toString() -> str, ES6 fixes\n #@@match(str) -> array | null\n #@@replace(str, replacer) -> string\n #@@search(str) -> index\n #@@split(str, limit) -> array\nString\n #match(tpl) -> var, ES6 fix for support @@match\n #replace(tpl, replacer) -> var, ES6 fix for support @@replace\n #search(tpl) -> var, ES6 fix for support @@search\n #split(tpl, limit) -> var, ES6 fix for support @@split, some fixes for old engines\n```\n[*CommonJS entry points:*](#commonjs)\n```\ncore-js/es6/regexp\ncore-js/fn/regexp/constructor\ncore-js(/library)/fn/regexp/flags\ncore-js/fn/regexp/to-string\ncore-js/fn/regexp/match\ncore-js/fn/regexp/replace\ncore-js/fn/regexp/search\ncore-js/fn/regexp/split\n```\n[*Examples*](http://goo.gl/PiJxBD):\n```js\nRegExp(/./g, 'm'); // => /./m\n\n/foo/.flags; // => ''\n/foo/gim.flags; // => 'gim'\n\n'foo'.match({[Symbol.match]: _ => 1}); // => 1\n'foo'.replace({[Symbol.replace]: _ => 2}); // => 2\n'foo'.search({[Symbol.search]: _ => 3}); // => 3\n'foo'.split({[Symbol.split]: _ => 4}); // => 4\n\nRegExp.prototype.toString.call({source: 'foo', flags: 'bar'}); // => '/foo/bar'\n```\n#### ECMAScript 6: Number\nModule [`es6.number.constructor`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.number.constructor.js). `Number` constructor support binary and octal literals, [*example*](http://goo.gl/jRd6b3):\n```js\nNumber('0b1010101'); // => 85\nNumber('0o7654321'); // => 2054353\n```\nModules [`es6.number.epsilon`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.number.epsilon.js), [`es6.number.is-finite`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.number.is-finite.js), [`es6.number.is-integer`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.number.is-integer.js), [`es6.number.is-nan`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.number.is-nan.js), [`es6.number.is-safe-integer`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.number.is-safe-integer.js), [`es6.number.max-safe-integer`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.number.max-safe-integer.js), [`es6.number.min-safe-integer`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.number.min-safe-integer.js), [`es6.number.parse-float`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.number.parse-float.js), [`es6.number.parse-int`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.number.parse-int.js), [`es6.number.to-fixed`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.number.to-fixed.js), [`es6.number.to-precision`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.number.to-precision.js), [`es6.parse-int`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.parse-int.js), [`es6.parse-float`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.parse-float.js).\n```js\n[new] Number(var) -> number | number object\n .isFinite(num) -> bool\n .isNaN(num) -> bool\n .isInteger(num) -> bool\n .isSafeInteger(num) -> bool\n .parseFloat(str) -> num\n .parseInt(str) -> int\n .EPSILON -> num\n .MAX_SAFE_INTEGER -> int\n .MIN_SAFE_INTEGER -> int\n #toFixed(digits) -> string, fixes\n #toPrecision(precision) -> string, fixes\nparseFloat(str) -> num, fixes\nparseInt(str) -> int, fixes\n```\n[*CommonJS entry points:*](#commonjs)\n```\ncore-js(/library)/es6/number\ncore-js/es6/number/constructor\ncore-js(/library)/fn/number/is-finite\ncore-js(/library)/fn/number/is-nan\ncore-js(/library)/fn/number/is-integer\ncore-js(/library)/fn/number/is-safe-integer\ncore-js(/library)/fn/number/parse-float\ncore-js(/library)/fn/number/parse-int\ncore-js(/library)/fn/number/epsilon\ncore-js(/library)/fn/number/max-safe-integer\ncore-js(/library)/fn/number/min-safe-integer\ncore-js(/library)/fn/number/to-fixed\ncore-js(/library)/fn/number/to-precision\ncore-js(/library)/fn/parse-float\ncore-js(/library)/fn/parse-int\n```\n#### ECMAScript 6: Math\nModules [`es6.math.acosh`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.math.acosh.js), [`es6.math.asinh`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.math.asinh.js), [`es6.math.atanh`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.math.atanh.js), [`es6.math.cbrt`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.math.cbrt.js), [`es6.math.clz32`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.math.clz32.js), [`es6.math.cosh`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.math.cosh.js), [`es6.math.expm1`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.math.expm1.js), [`es6.math.fround`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.math.fround.js), [`es6.math.hypot`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.math.hypot.js), [`es6.math.imul`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.math.imul.js), [`es6.math.log10`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.math.log10.js), [`es6.math.log1p`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.math.log1p.js), [`es6.math.log2`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.math.log2.js), [`es6.math.sign`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.math.sign.js), [`es6.math.sinh`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.math.sinh.js), [`es6.math.tanh`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.math.tanh.js), [`es6.math.trunc`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.math.trunc.js).\n```js\nMath\n .acosh(num) -> num\n .asinh(num) -> num\n .atanh(num) -> num\n .cbrt(num) -> num\n .clz32(num) -> uint\n .cosh(num) -> num\n .expm1(num) -> num\n .fround(num) -> num\n .hypot(...args) -> num\n .imul(num, num) -> int\n .log1p(num) -> num\n .log10(num) -> num\n .log2(num) -> num\n .sign(num) -> 1 | -1 | 0 | -0 | NaN\n .sinh(num) -> num\n .tanh(num) -> num\n .trunc(num) -> num\n```\n[*CommonJS entry points:*](#commonjs)\n```\ncore-js(/library)/es6/math\ncore-js(/library)/fn/math/acosh\ncore-js(/library)/fn/math/asinh\ncore-js(/library)/fn/math/atanh\ncore-js(/library)/fn/math/cbrt\ncore-js(/library)/fn/math/clz32\ncore-js(/library)/fn/math/cosh\ncore-js(/library)/fn/math/expm1\ncore-js(/library)/fn/math/fround\ncore-js(/library)/fn/math/hypot\ncore-js(/library)/fn/math/imul\ncore-js(/library)/fn/math/log1p\ncore-js(/library)/fn/math/log10\ncore-js(/library)/fn/math/log2\ncore-js(/library)/fn/math/sign\ncore-js(/library)/fn/math/sinh\ncore-js(/library)/fn/math/tanh\ncore-js(/library)/fn/math/trunc\n```\n#### ECMAScript 6: Date\nModules [`es6.date.to-string`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.date.to-string.js), ES5 features with fixes: [`es6.date.now`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.date.now.js), [`es6.date.to-iso-string`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.date.to-iso-string.js), [`es6.date.to-json`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.date.to-json.js) and [`es6.date.to-primitive`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.date.to-primitive.js).\n```js\nDate\n .now() -> int\n #toISOString() -> string\n #toJSON() -> string\n #toString() -> string\n #@@toPrimitive(hint) -> primitive\n```\n[*CommonJS entry points:*](#commonjs)\n```\ncore-js/es6/date\ncore-js/fn/date/to-string\ncore-js(/library)/fn/date/now\ncore-js(/library)/fn/date/to-iso-string\ncore-js(/library)/fn/date/to-json\ncore-js(/library)/fn/date/to-primitive\n```\n[*Example*](http://goo.gl/haeHLR):\n```js\nnew Date(NaN).toString(); // => 'Invalid Date'\n```\n\n#### ECMAScript 6: Promise\nModule [`es6.promise`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.promise.js).\n```js\nnew Promise(executor(resolve(var), reject(var))) -> promise\n #then(resolved(var), rejected(var)) -> promise\n #catch(rejected(var)) -> promise\n .resolve(promise | var) -> promise\n .reject(var) -> promise\n .all(iterable) -> promise\n .race(iterable) -> promise\n```\n[*CommonJS entry points:*](#commonjs)\n```\ncore-js(/library)/es6/promise\ncore-js(/library)/fn/promise\n```\nBasic [*example*](http://goo.gl/vGrtUC):\n```js\nfunction sleepRandom(time){\n return new Promise(function(resolve, reject){\n setTimeout(resolve, time * 1e3, 0 | Math.random() * 1e3);\n });\n}\n\nconsole.log('Run'); // => Run\nsleepRandom(5).then(function(result){\n console.log(result); // => 869, after 5 sec.\n return sleepRandom(10);\n}).then(function(result){\n console.log(result); // => 202, after 10 sec.\n}).then(function(){\n console.log('immediately after'); // => immediately after\n throw Error('Irror!');\n}).then(function(){\n console.log('will not be displayed');\n}).catch(x => console.log(x)); // => => Error: Irror!\n```\n`Promise.resolve` and `Promise.reject` [*example*](http://goo.gl/vr8TN3):\n```js\nPromise.resolve(42).then(x => console.log(x)); // => 42\nPromise.reject(42).catch(x => console.log(x)); // => 42\n\nPromise.resolve($.getJSON('/data.json')); // => ES6 promise\n```\n`Promise.all` [*example*](http://goo.gl/RdoDBZ):\n```js\nPromise.all([\n 'foo',\n sleepRandom(5),\n sleepRandom(15),\n sleepRandom(10) // after 15 sec:\n]).then(x => console.log(x)); // => ['foo', 956, 85, 382]\n```\n`Promise.race` [*example*](http://goo.gl/L8ovkJ):\n```js\nfunction timeLimit(promise, time){\n return Promise.race([promise, new Promise(function(resolve, reject){\n setTimeout(reject, time * 1e3, Error('Await > ' + time + ' sec'));\n })]);\n}\n\ntimeLimit(sleepRandom(5), 10).then(x => console.log(x)); // => 853, after 5 sec.\ntimeLimit(sleepRandom(15), 10).catch(x => console.log(x)); // Error: Await > 10 sec\n```\nECMAScript 7 [async functions](https://tc39.github.io/ecmascript-asyncawait) [example](http://goo.gl/wnQS4j):\n```js\nvar delay = time => new Promise(resolve => setTimeout(resolve, time))\n\nasync function sleepRandom(time){\n await delay(time * 1e3);\n return 0 | Math.random() * 1e3;\n};\nasync function sleepError(time, msg){\n await delay(time * 1e3);\n throw Error(msg);\n};\n\n(async () => {\n try {\n console.log('Run'); // => Run\n console.log(await sleepRandom(5)); // => 936, after 5 sec.\n var [a, b, c] = await Promise.all([\n sleepRandom(5),\n sleepRandom(15),\n sleepRandom(10)\n ]);\n console.log(a, b, c); // => 210 445 71, after 15 sec.\n await sleepError(5, 'Irror!');\n console.log('Will not be displayed');\n } catch(e){\n console.log(e); // => Error: 'Irror!', after 5 sec.\n }\n})();\n```\n\n##### Unhandled rejection tracking\n\nIn Node.js, like in native implementation, available events [`unhandledRejection`](https://nodejs.org/api/process.html#process_event_unhandledrejection) and [`rejectionHandled`](https://nodejs.org/api/process.html#process_event_rejectionhandled):\n```js\nprocess.on('unhandledRejection', (reason, promise) => console.log('unhandled', reason, promise));\nprocess.on('rejectionHandled', (promise) => console.log('handled', promise));\n\nvar p = Promise.reject(42);\n// unhandled 42 [object Promise]\n\nsetTimeout(() => p.catch(_ => _), 1e3);\n// handled [object Promise]\n```\nIn a browser on rejection, by default, you will see notify in the console, or you can add a custom handler and a handler on handling unhandled, [*example*](http://goo.gl/Wozskl):\n```js\nwindow.onunhandledrejection = e => console.log('unhandled', e.reason, e.promise);\nwindow.onrejectionhandled = e => console.log('handled', e.reason, e.promise);\n\nvar p = Promise.reject(42);\n// unhandled 42 [object Promise]\n\nsetTimeout(() => p.catch(_ => _), 1e3);\n// handled 42 [object Promise]\n```\n\n#### ECMAScript 6: Symbol\nModule [`es6.symbol`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.symbol.js).\n```js\nSymbol(description?) -> symbol\n .hasInstance -> @@hasInstance\n .isConcatSpreadable -> @@isConcatSpreadable\n .iterator -> @@iterator\n .match -> @@match\n .replace -> @@replace\n .search -> @@search\n .species -> @@species\n .split -> @@split\n .toPrimitive -> @@toPrimitive\n .toStringTag -> @@toStringTag\n .unscopables -> @@unscopables\n .for(key) -> symbol\n .keyFor(symbol) -> key\n .useSimple() -> void\n .useSetter() -> void\nObject\n .getOwnPropertySymbols(object) -> array\n```\nAlso wrapped some methods for correct work with `Symbol` polyfill.\n```js\nObject\n .create(proto | null, descriptors?) -> object\n .defineProperty(target, key, desc) -> target\n .defineProperties(target, descriptors) -> target\n .getOwnPropertyDescriptor(var, key) -> desc | undefined\n .getOwnPropertyNames(var) -> array\n #propertyIsEnumerable(key) -> bool\nJSON\n .stringify(target, replacer?, space?) -> string | undefined\n```\n[*CommonJS entry points:*](#commonjs)\n```\ncore-js(/library)/es6/symbol\ncore-js(/library)/fn/symbol\ncore-js(/library)/fn/symbol/has-instance\ncore-js(/library)/fn/symbol/is-concat-spreadable\ncore-js(/library)/fn/symbol/iterator\ncore-js(/library)/fn/symbol/match\ncore-js(/library)/fn/symbol/replace\ncore-js(/library)/fn/symbol/search\ncore-js(/library)/fn/symbol/species\ncore-js(/library)/fn/symbol/split\ncore-js(/library)/fn/symbol/to-primitive\ncore-js(/library)/fn/symbol/to-string-tag\ncore-js(/library)/fn/symbol/unscopables\ncore-js(/library)/fn/symbol/for\ncore-js(/library)/fn/symbol/key-for\n```\n[*Basic example*](http://goo.gl/BbvWFc):\n```js\nvar Person = (function(){\n var NAME = Symbol('name');\n function Person(name){\n this[NAME] = name;\n }\n Person.prototype.getName = function(){\n return this[NAME];\n };\n return Person;\n})();\n\nvar person = new Person('Vasya');\nconsole.log(person.getName()); // => 'Vasya'\nconsole.log(person['name']); // => undefined\nconsole.log(person[Symbol('name')]); // => undefined, symbols are uniq\nfor(var key in person)console.log(key); // => only 'getName', symbols are not enumerable\n```\n`Symbol.for` & `Symbol.keyFor` [*example*](http://goo.gl/0pdJjX):\n```js\nvar symbol = Symbol.for('key');\nsymbol === Symbol.for('key'); // true\nSymbol.keyFor(symbol); // 'key'\n```\n[*Example*](http://goo.gl/mKVOQJ) with methods for getting own object keys:\n```js\nvar O = {a: 1};\nObject.defineProperty(O, 'b', {value: 2});\nO[Symbol('c')] = 3;\nObject.keys(O); // => ['a']\nObject.getOwnPropertyNames(O); // => ['a', 'b']\nObject.getOwnPropertySymbols(O); // => [Symbol(c)]\nReflect.ownKeys(O); // => ['a', 'b', Symbol(c)]\n```\n##### Caveats when using `Symbol` polyfill:\n\n* We can't add new primitive type, `Symbol` returns object.\n* `Symbol.for` and `Symbol.keyFor` can't be shimmed cross-realm.\n* By default, to hide the keys, `Symbol` polyfill defines setter in `Object.prototype`. For this reason, uncontrolled creation of symbols can cause memory leak and the `in` operator is not working correctly with `Symbol` polyfill: `Symbol() in {} // => true`.\n\nYou can disable defining setters in `Object.prototype`. [Example](http://goo.gl/N5UD7J):\n```js\nSymbol.useSimple();\nvar s1 = Symbol('s1')\n , o1 = {};\no1[s1] = true;\nfor(var key in o1)console.log(key); // => 'Symbol(s1)_t.qamkg9f3q', w/o native Symbol\n\nSymbol.useSetter();\nvar s2 = Symbol('s2')\n , o2 = {};\no2[s2] = true;\nfor(var key in o2)console.log(key); // nothing\n```\n* Currently, `core-js` not adds setters to `Object.prototype` for well-known symbols for correct work something like `Symbol.iterator in foo`. It can cause problems with their enumerability.\n* Some problems possible with environment exotic objects (for example, IE `localStorage`).\n\n#### ECMAScript 6: Collections\n`core-js` uses native collections in most case, just fixes methods / constructor, if it's required, and in old environment uses fast polyfill (O(1) lookup).\n#### Map\nModule [`es6.map`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.map.js).\n```js\nnew Map(iterable (entries) ?) -> map\n #clear() -> void\n #delete(key) -> bool\n #forEach(fn(val, key, @), that) -> void\n #get(key) -> val\n #has(key) -> bool\n #set(key, val) -> @\n #size -> uint\n #values() -> iterator\n #keys() -> iterator\n #entries() -> iterator\n #@@iterator() -> iterator (entries)\n```\n[*CommonJS entry points:*](#commonjs)\n```\ncore-js(/library)/es6/map\ncore-js(/library)/fn/map\n```\n[*Examples*](http://goo.gl/GWR7NI):\n```js\nvar a = [1];\n\nvar map = new Map([['a', 1], [42, 2]]);\nmap.set(a, 3).set(true, 4);\n\nconsole.log(map.size); // => 4\nconsole.log(map.has(a)); // => true\nconsole.log(map.has([1])); // => false\nconsole.log(map.get(a)); // => 3\nmap.forEach(function(val, key){\n console.log(val); // => 1, 2, 3, 4\n console.log(key); // => 'a', 42, [1], true\n});\nmap.delete(a);\nconsole.log(map.size); // => 3\nconsole.log(map.get(a)); // => undefined\nconsole.log(Array.from(map)); // => [['a', 1], [42, 2], [true, 4]]\n\nvar map = new Map([['a', 1], ['b', 2], ['c', 3]]);\n\nfor(var [key, val] of map){\n console.log(key); // => 'a', 'b', 'c'\n console.log(val); // => 1, 2, 3\n}\nfor(var val of map.values())console.log(val); // => 1, 2, 3\nfor(var key of map.keys())console.log(key); // => 'a', 'b', 'c'\nfor(var [key, val] of map.entries()){\n console.log(key); // => 'a', 'b', 'c'\n console.log(val); // => 1, 2, 3\n}\n```\n#### Set\nModule [`es6.set`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.set.js).\n```js\nnew Set(iterable?) -> set\n #add(key) -> @\n #clear() -> void\n #delete(key) -> bool\n #forEach(fn(el, el, @), that) -> void\n #has(key) -> bool\n #size -> uint\n #values() -> iterator\n #keys() -> iterator\n #entries() -> iterator\n #@@iterator() -> iterator (values)\n```\n[*CommonJS entry points:*](#commonjs)\n```\ncore-js(/library)/es6/set\ncore-js(/library)/fn/set\n```\n[*Examples*](http://goo.gl/bmhLwg):\n```js\nvar set = new Set(['a', 'b', 'a', 'c']);\nset.add('d').add('b').add('e');\nconsole.log(set.size); // => 5\nconsole.log(set.has('b')); // => true\nset.forEach(function(it){\n console.log(it); // => 'a', 'b', 'c', 'd', 'e'\n});\nset.delete('b');\nconsole.log(set.size); // => 4\nconsole.log(set.has('b')); // => false\nconsole.log(Array.from(set)); // => ['a', 'c', 'd', 'e']\n\nvar set = new Set([1, 2, 3, 2, 1]);\n\nfor(var val of set)console.log(val); // => 1, 2, 3\nfor(var val of set.values())console.log(val); // => 1, 2, 3\nfor(var key of set.keys())console.log(key); // => 1, 2, 3\nfor(var [key, val] of set.entries()){\n console.log(key); // => 1, 2, 3\n console.log(val); // => 1, 2, 3\n}\n```\n#### WeakMap\nModule [`es6.weak-map`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.weak-map.js).\n```js\nnew WeakMap(iterable (entries) ?) -> weakmap\n #delete(key) -> bool\n #get(key) -> val\n #has(key) -> bool\n #set(key, val) -> @\n```\n[*CommonJS entry points:*](#commonjs)\n```\ncore-js(/library)/es6/weak-map\ncore-js(/library)/fn/weak-map\n```\n[*Examples*](http://goo.gl/SILXyw):\n```js\nvar a = [1]\n , b = [2]\n , c = [3];\n\nvar wmap = new WeakMap([[a, 1], [b, 2]]);\nwmap.set(c, 3).set(b, 4);\nconsole.log(wmap.has(a)); // => true\nconsole.log(wmap.has([1])); // => false\nconsole.log(wmap.get(a)); // => 1\nwmap.delete(a);\nconsole.log(wmap.get(a)); // => undefined\n\n// Private properties store:\nvar Person = (function(){\n var names = new WeakMap;\n function Person(name){\n names.set(this, name);\n }\n Person.prototype.getName = function(){\n return names.get(this);\n };\n return Person;\n})();\n\nvar person = new Person('Vasya');\nconsole.log(person.getName()); // => 'Vasya'\nfor(var key in person)console.log(key); // => only 'getName'\n```\n#### WeakSet\nModule [`es6.weak-set`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.weak-set.js).\n```js\nnew WeakSet(iterable?) -> weakset\n #add(key) -> @\n #delete(key) -> bool\n #has(key) -> bool\n```\n[*CommonJS entry points:*](#commonjs)\n```\ncore-js(/library)/es6/weak-set\ncore-js(/library)/fn/weak-set\n```\n[*Examples*](http://goo.gl/TdFbEx):\n```js\nvar a = [1]\n , b = [2]\n , c = [3];\n\nvar wset = new WeakSet([a, b, a]);\nwset.add(c).add(b).add(c);\nconsole.log(wset.has(b)); // => true\nconsole.log(wset.has([2])); // => false\nwset.delete(b);\nconsole.log(wset.has(b)); // => false\n```\n##### Caveats when using collections polyfill:\n\n* Weak-collections polyfill stores values as hidden properties of keys. It works correct and not leak in most cases. However, it is desirable to store a collection longer than its keys.\n\n#### ECMAScript 6: Typed Arrays\nImplementations and fixes `ArrayBuffer`, `DataView`, typed arrays constructors, static and prototype methods. Typed Arrays work only in environments with support descriptors (IE9+), `ArrayBuffer` and `DataView` should work anywhere.\n\nModules [`es6.typed.array-buffer`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.typed.array-buffer.js), [`es6.typed.data-view`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.typed.data-view.js), [`es6.typed.int8-array`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.typed.int8-array.js), [`es6.typed.uint8-array`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.typed.uint8-array.js), [`es6.typed.uint8-clamped-array`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.typed.uint8-clamped-array.js), [`es6.typed.int16-array`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.typed.int16-array.js), [`es6.typed.uint16-array`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.typed.uint16-array.js), [`es6.typed.int32-array`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.typed.int32-array.js), [`es6.typed.uint32-array`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.typed.uint32-array.js), [`es6.typed.float32-array`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.typed.float32-array.js) and [`es6.typed.float64-array`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.typed.float64-array.js).\n```js\nnew ArrayBuffer(length) -> buffer\n .isView(var) -> bool\n #slice(start = 0, end = @length) -> buffer\n #byteLength -> uint\n\nnew DataView(buffer, byteOffset = 0, byteLength = buffer.byteLength - byteOffset) -> view\n #getInt8(offset) -> int8\n #getUint8(offset) -> uint8\n #getInt16(offset, littleEndian = false) -> int16\n #getUint16(offset, littleEndian = false) -> uint16\n #getInt32(offset, littleEndian = false) -> int32\n #getUint32(offset, littleEndian = false) -> uint32\n #getFloat32(offset, littleEndian = false) -> float32\n #getFloat64(offset, littleEndian = false) -> float64\n #setInt8(offset, value) -> void\n #setUint8(offset, value) -> void\n #setInt16(offset, value, littleEndian = false) -> void\n #setUint16(offset, value, littleEndian = false) -> void\n #setInt32(offset, value, littleEndian = false) -> void\n #setUint32(offset, value, littleEndian = false) -> void\n #setFloat32(offset, value, littleEndian = false) -> void\n #setFloat64(offset, value, littleEndian = false) -> void\n #buffer -> buffer\n #byteLength -> uint\n #byteOffset -> uint\n\n{\n Int8Array,\n Uint8Array,\n Uint8ClampedArray,\n Int16Array,\n Uint16Array,\n Int32Array,\n Uint32Array,\n Float32Array,\n Float64Array\n}\n new %TypedArray%(length) -> typed\n new %TypedArray%(typed) -> typed\n new %TypedArray%(arrayLike) -> typed\n new %TypedArray%(iterable) -> typed\n new %TypedArray%(buffer, byteOffset = 0, length = (buffer.byteLength - byteOffset) / @BYTES_PER_ELEMENT) -> typed\n .BYTES_PER_ELEMENT -> uint\n .from(arrayLike | iterable, mapFn(val, index)?, that) -> typed\n .of(...args) -> typed\n #BYTES_PER_ELEMENT -> uint\n #copyWithin(target = 0, start = 0, end = @length) -> @\n #every(fn(val, index, @), that) -> bool\n #fill(val, start = 0, end = @length) -> @\n #filter(fn(val, index, @), that) -> typed\n #find(fn(val, index, @), that) -> val\n #findIndex(fn(val, index, @), that) -> index\n #forEach(fn(val, index, @), that) -> void\n #indexOf(var, from?) -> int\n #join(string = ',') -> string\n #lastIndexOf(var, from?) -> int\n #map(fn(val, index, @), that) -> typed\n #reduce(fn(memo, val, index, @), memo?) -> var\n #reduceRight(fn(memo, val, index, @), memo?) -> var\n #reverse() -> @\n #set(arrayLike, offset = 0) -> void\n #slice(start = 0, end = @length) -> typed\n #some(fn(val, index, @), that) -> bool\n #sort(fn(a, b)?) -> @\n #subarray(start = 0, end = @length) -> typed\n #toString() -> string\n #toLocaleString() -> string\n #values() -> iterator\n #keys() -> iterator\n #entries() -> iterator\n #@@iterator() -> iterator (values)\n #buffer -> buffer\n #byteLength -> uint\n #byteOffset -> uint\n #length -> uint\n```\n[*CommonJS entry points:*](#commonjs)\n```\ncore-js(/library)/es6/typed\ncore-js(/library)/fn/typed\ncore-js(/library)/fn/typed/array-buffer\ncore-js(/library)/fn/typed/data-view\ncore-js(/library)/fn/typed/int8-array\ncore-js(/library)/fn/typed/uint8-array\ncore-js(/library)/fn/typed/uint8-clamped-array\ncore-js(/library)/fn/typed/int16-array\ncore-js(/library)/fn/typed/uint16-array\ncore-js(/library)/fn/typed/int32-array\ncore-js(/library)/fn/typed/uint32-array\ncore-js(/library)/fn/typed/float32-array\ncore-js(/library)/fn/typed/float64-array\n```\n[*Examples*](http://goo.gl/yla75z):\n```js\nnew Int32Array(4); // => [0, 0, 0, 0]\nnew Uint8ClampedArray([1, 2, 3, 666]); // => [1, 2, 3, 255]\nnew Float32Array(new Set([1, 2, 3, 2, 1])); // => [1, 2, 3]\n\nvar buffer = new ArrayBuffer(8);\nvar view = new DataView(buffer);\nview.setFloat64(0, 123.456, true);\nnew Uint8Array(buffer.slice(4)); // => [47, 221, 94, 64]\n\nInt8Array.of(1, 1.5, 5.7, 745); // => [1, 1, 5, -23]\nUint8Array.from([1, 1.5, 5.7, 745]); // => [1, 1, 5, 233]\n\nvar typed = new Uint8Array([1, 2, 3]);\n\nvar a = typed.slice(1); // => [2, 3]\ntyped.buffer === a.buffer; // => false\nvar b = typed.subarray(1); // => [2, 3]\ntyped.buffer === b.buffer; // => true\n\ntyped.filter(it => it % 2); // => [1, 3]\ntyped.map(it => it * 1.5); // => [1, 3, 4]\n\nfor(var val of typed)console.log(val); // => 1, 2, 3\nfor(var val of typed.values())console.log(val); // => 1, 2, 3\nfor(var key of typed.keys())console.log(key); // => 0, 1, 2\nfor(var [key, val] of typed.entries()){\n console.log(key); // => 0, 1, 2\n console.log(val); // => 1, 2, 3\n}\n```\n##### Caveats when using typed arrays:\n\n* Typed Arrays polyfills works completely how should work by the spec, but because of internal use getter / setters on each instance, is slow and consumes significant memory. However, typed arrays polyfills required mainly for IE9 (and for `Uint8ClampedArray` in IE10 and early IE11), all modern engines have native typed arrays and requires only constructors fixes and methods.\n* The current version hasn't special entry points for methods, they can be added only with constructors. It can be added in the future.\n* In the `library` version we can't pollute native prototypes, so prototype methods available as constructors static.\n\n#### ECMAScript 6: Reflect\nModules [`es6.reflect.apply`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.reflect.apply.js), [`es6.reflect.construct`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.reflect.construct.js), [`es6.reflect.define-property`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.reflect.define-property.js), [`es6.reflect.delete-property`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.reflect.delete-property.js), [`es6.reflect.enumerate`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.reflect.enumerate.js), [`es6.reflect.get`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.reflect.get.js), [`es6.reflect.get-own-property-descriptor`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.reflect.get-own-property-descriptor.js), [`es6.reflect.get-prototype-of`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.reflect.get-prototype-of.js), [`es6.reflect.has`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.reflect.has.js), [`es6.reflect.is-extensible`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.reflect.is-extensible.js), [`es6.reflect.own-keys`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.reflect.own-keys.js), [`es6.reflect.prevent-extensions`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.reflect.prevent-extensions.js), [`es6.reflect.set`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.reflect.set.js), [`es6.reflect.set-prototype-of`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es6.reflect.set-prototype-of.js).\n```js\nReflect\n .apply(target, thisArgument, argumentsList) -> var\n .construct(target, argumentsList, newTarget?) -> object\n .defineProperty(target, propertyKey, attributes) -> bool\n .deleteProperty(target, propertyKey) -> bool\n .enumerate(target) -> iterator (removed from the spec and will be removed from core-js@3)\n .get(target, propertyKey, receiver?) -> var\n .getOwnPropertyDescriptor(target, propertyKey) -> desc\n .getPrototypeOf(target) -> object | null\n .has(target, propertyKey) -> bool\n .isExtensible(target) -> bool\n .ownKeys(target) -> array\n .preventExtensions(target) -> bool\n .set(target, propertyKey, V, receiver?) -> bool\n .setPrototypeOf(target, proto) -> bool (required __proto__ - IE11+)\n```\n[*CommonJS entry points:*](#commonjs)\n```\ncore-js(/library)/es6/reflect\ncore-js(/library)/fn/reflect\ncore-js(/library)/fn/reflect/apply\ncore-js(/library)/fn/reflect/construct\ncore-js(/library)/fn/reflect/define-property\ncore-js(/library)/fn/reflect/delete-property\ncore-js(/library)/fn/reflect/enumerate (deprecated and will be removed from the next major release)\ncore-js(/library)/fn/reflect/get\ncore-js(/library)/fn/reflect/get-own-property-descriptor\ncore-js(/library)/fn/reflect/get-prototype-of\ncore-js(/library)/fn/reflect/has\ncore-js(/library)/fn/reflect/is-extensible\ncore-js(/library)/fn/reflect/own-keys\ncore-js(/library)/fn/reflect/prevent-extensions\ncore-js(/library)/fn/reflect/set\ncore-js(/library)/fn/reflect/set-prototype-of\n```\n[*Examples*](http://goo.gl/gVT0cH):\n```js\nvar O = {a: 1};\nObject.defineProperty(O, 'b', {value: 2});\nO[Symbol('c')] = 3;\nReflect.ownKeys(O); // => ['a', 'b', Symbol(c)]\n\nfunction C(a, b){\n this.c = a + b;\n}\n\nvar instance = Reflect.construct(C, [20, 22]);\ninstance.c; // => 42\n```\n\n### ECMAScript 7+ proposals\n[The TC39 process.](https://tc39.github.io/process-document/)\n\n[*CommonJS entry points:*](#commonjs)\n```\ncore-js(/library)/es7\ncore-js(/library)/es7/array\ncore-js(/library)/es7/global\ncore-js(/library)/es7/string\ncore-js(/library)/es7/map\ncore-js(/library)/es7/set\ncore-js(/library)/es7/error\ncore-js(/library)/es7/math\ncore-js(/library)/es7/system\ncore-js(/library)/es7/symbol\ncore-js(/library)/es7/reflect\ncore-js(/library)/es7/observable\n```\n`core-js/stage/4` entry point contains only stage 4 proposals, `core-js/stage/3` - stage 3 and stage 4, etc.\n#### Stage 4 proposals\n\n[*CommonJS entry points:*](#commonjs)\n```js\ncore-js(/library)/stage/4\n```\n* `{Array, %TypedArray%}#includes` [proposal](https://github.com/tc39/Array.prototype.includes) - module [`es7.array.includes`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.array.includes.js), `%TypedArray%` version in modules from [this section](#ecmascript-6-typed-arrays).\n```js\nArray\n #includes(var, from?) -> bool\n{\n Int8Array,\n Uint8Array,\n Uint8ClampedArray,\n Int16Array,\n Uint16Array,\n Int32Array,\n Uint32Array,\n Float32Array,\n Float64Array\n}\n #includes(var, from?) -> bool\n```\n[*CommonJS entry points:*](#commonjs)\n```js\ncore-js(/library)/fn/array/includes\n```\n[*Examples*](http://goo.gl/2Gq4ma):\n```js\n[1, 2, 3].includes(2); // => true\n[1, 2, 3].includes(4); // => false\n[1, 2, 3].includes(2, 2); // => false\n\n[NaN].indexOf(NaN); // => -1\n[NaN].includes(NaN); // => true\nArray(1).indexOf(undefined); // => -1\nArray(1).includes(undefined); // => true\n```\n* `Object.values`, `Object.entries` [proposal](https://github.com/tc39/proposal-object-values-entries) - modules [`es7.object.values`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.object.values.js), [`es7.object.entries`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.object.entries.js)\n```js\nObject\n .values(object) -> array\n .entries(object) -> array\n```\n[*CommonJS entry points:*](#commonjs)\n```js\ncore-js(/library)/fn/object/values\ncore-js(/library)/fn/object/entries\n```\n[*Examples*](http://goo.gl/6kuGOn):\n```js\nObject.values({a: 1, b: 2, c: 3}); // => [1, 2, 3]\nObject.entries({a: 1, b: 2, c: 3}); // => [['a', 1], ['b', 2], ['c', 3]]\n\nfor(let [key, value] of Object.entries({a: 1, b: 2, c: 3})){\n console.log(key); // => 'a', 'b', 'c'\n console.log(value); // => 1, 2, 3\n}\n```\n* `Object.getOwnPropertyDescriptors` [proposal](https://github.com/tc39/proposal-object-getownpropertydescriptors) - module [`es7.object.get-own-property-descriptors`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.object.get-own-property-descriptors.js)\n```js\nObject\n .getOwnPropertyDescriptors(object) -> object\n```\n[*CommonJS entry points:*](#commonjs)\n```js\ncore-js(/library)/fn/object/get-own-property-descriptors\n```\n*Examples*:\n```js\n// Shallow object cloning with prototype and descriptors:\nvar copy = Object.create(Object.getPrototypeOf(O), Object.getOwnPropertyDescriptors(O));\n// Mixin:\nObject.defineProperties(target, Object.getOwnPropertyDescriptors(source));\n```\n* `String#padStart`, `String#padEnd` [proposal](https://github.com/tc39/proposal-string-pad-start-end) - modules [`es7.string.pad-start`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.string.pad-start.js), [`es7.string.pad-end`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.string.pad-end.js)\n```js\nString\n #padStart(length, fillStr = ' ') -> string\n #padEnd(length, fillStr = ' ') -> string\n```\n[*CommonJS entry points:*](#commonjs)\n```js\ncore-js(/library)/fn/string/pad-start\ncore-js(/library)/fn/string/pad-end\ncore-js(/library)/fn/string/virtual/pad-start\ncore-js(/library)/fn/string/virtual/pad-end\n```\n[*Examples*](http://goo.gl/hK5ccv):\n```js\n'hello'.padStart(10); // => ' hello'\n'hello'.padStart(10, '1234'); // => '12341hello'\n'hello'.padEnd(10); // => 'hello '\n'hello'.padEnd(10, '1234'); // => 'hello12341'\n```\n* `Object#__(define|lookup)[GS]etter__`, [annex B ES2017](https://github.com/tc39/ecma262/pull/381), but we haven't special namespace for that - modules [`es7.object.define-setter`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.object.define-setter.js), [`es7.object.define-getter`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.object.define-getter.js), [`es7.object.lookup-setter`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.object.lookup-setter.js) and [`es7.object.lookup-getter`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.object.lookup-getter.js).\n```js\nObject\n #__defineSetter__(key, fn) -> void\n #__defineGetter__(key, fn) -> void\n #__lookupSetter__(key) -> fn | void\n #__lookupGetter__(key) -> fn | void\n```\n[*CommonJS entry points:*](#commonjs)\n```js\ncore-js(/library)/fn/object/define-getter\ncore-js(/library)/fn/object/define-setter\ncore-js(/library)/fn/object/lookup-getter\ncore-js(/library)/fn/object/lookup-setter\n```\n\n#### Stage 3 proposals\n[*CommonJS entry points:*](#commonjs)\n```js\ncore-js(/library)/stage/3\n```\n* `global` [proposal](https://github.com/tc39/proposal-global) - modules [`es7.global`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.global.js) and [`es7.system.global`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.system.global.js) (obsolete)\n```js\nglobal -> object\nSystem\n .global -> object (obsolete)\n```\n[*CommonJS entry points:*](#commonjs)\n```js\ncore-js(/library)/fn/global\ncore-js(/library)/fn/system/global (obsolete)\n```\n[*Examples*](http://goo.gl/gEqMl7):\n```js\nglobal.Array === Array; // => true\n```\n* `Promise#finally` [proposal](https://github.com/tc39/proposal-promise-finally) - module [`es7.promise.finally`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.promise.finally.js)\n```js\nPromise\n #finally(onFinally()) -> promise\n```\n[*CommonJS entry points:*](#commonjs)\n```js\ncore-js(/library)/fn/promise/finally\n```\n[*Examples*](https://goo.gl/AhyBbJ):\n```js\nPromise.resolve(42).finally(() => console.log('You will see it anyway'));\n\nPromise.reject(42).finally(() => console.log('You will see it anyway'));\n\n#### Stage 2 proposals\n[*CommonJS entry points:*](#commonjs)\n```js\ncore-js(/library)/stage/2\n```\n* `String#trimLeft`, `String#trimRight` / `String#trimStart`, `String#trimEnd` [proposal](https://github.com/sebmarkbage/ecmascript-string-left-right-trim) - modules [`es7.string.trim-left`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.string.trim-right.js), [`es7.string.trim-right`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.string.trim-right.js)\n```js\nString\n #trimLeft() -> string\n #trimRight() -> string\n #trimStart() -> string\n #trimEnd() -> string\n```\n[*CommonJS entry points:*](#commonjs)\n```js\ncore-js(/library)/fn/string/trim-start\ncore-js(/library)/fn/string/trim-end\ncore-js(/library)/fn/string/trim-left\ncore-js(/library)/fn/string/trim-right\ncore-js(/library)/fn/string/virtual/trim-start\ncore-js(/library)/fn/string/virtual/trim-end\ncore-js(/library)/fn/string/virtual/trim-left\ncore-js(/library)/fn/string/virtual/trim-right\n```\n[*Examples*](http://goo.gl/Er5lMJ):\n```js\n' hello '.trimLeft(); // => 'hello '\n' hello '.trimRight(); // => ' hello'\n```\n```\n* `Symbol.asyncIterator` for [async iteration proposal](https://github.com/tc39/proposal-async-iteration) - module [`es7.symbol.async-iterator`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.symbol.async-iterator.js)\n```js\nSymbol\n .asyncIterator -> @@asyncIterator\n```\n[*CommonJS entry points:*](#commonjs)\n```js\ncore-js(/library)/fn/symbol/async-iterator\n```\n\n#### Stage 1 proposals\n[*CommonJS entry points:*](#commonjs)\n```js\ncore-js(/library)/stage/1\n```\n* `Promise.try` [proposal](https://github.com/tc39/proposal-promise-try) - module [`es7.promise.try`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.promise.try.js)\n```js\nPromise\n .try(function()) -> promise\n```\n[*CommonJS entry points:*](#commonjs)\n```js\ncore-js(/library)/fn/promise/try\n```\n[*Examples*](https://goo.gl/k5GGRo):\n```js\nPromise.try(() => 42).then(it => console.log(`Promise, resolved as ${it}`));\n\nPromise.try(() => { throw 42; }).catch(it => console.log(`Promise, rejected as ${it}`));\n```\n* `Array#flatten` and `Array#flatMap` [proposal](https://tc39.github.io/proposal-flatMap) - modules [`es7.array.flatten`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.array.flatten.js) and [`es7.array.flat-map`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.array.flat-map.js)\n```js\nArray\n #flatten(depthArg = 1) -> array\n #flatMap(fn(val, key, @), that) -> array\n```\n[*CommonJS entry points:*](#commonjs)\n```js\ncore-js(/library)/fn/array/flatten\ncore-js(/library)/fn/array/flat-map\ncore-js(/library)/fn/array/virtual/flatten\ncore-js(/library)/fn/array/virtual/flat-map\n```\n[*Examples*](https://goo.gl/jTXsZi):\n```js\n[1, [2, 3], [4, 5]].flatten(); // => [1, 2, 3, 4, 5]\n[1, [2, [3, [4]]], 5].flatten(); // => [1, 2, [3, [4]], 5]\n[1, [2, [3, [4]]], 5].flatten(3); // => [1, 2, 3, 4, 5]\n\n[{a: 1, b: 2}, {a: 3, b: 4}, {a: 5, b: 6}].flatMap(it => [it.a, it.b]); // => [1, 2, 3, 4, 5, 6]\n```\n* `.of` and `.from` methods on collection constructors [proposal](https://github.com/tc39/proposal-setmap-offrom) - modules [`es7.set.of`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.set.of.js), [`es7.set.from`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.set.from.js), [`es7.map.of`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.map.of.js), [`es7.map.from`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.map.from.js), [`es7.weak-set.of`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.weak-set.of.js), [`es7.weak-set.from`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.weak-set.from.js), [`es7.weak-map.of`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.weak-map.of.js), [`es7.weak-map.from`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.weak-map.from.js)\n```js\nSet\n .of(...args) -> set\n .from(iterable, mapFn(val, index)?, that?) -> set\nMap\n .of(...args) -> map\n .from(iterable, mapFn(val, index)?, that?) -> map\nWeakSet\n .of(...args) -> weakset\n .from(iterable, mapFn(val, index)?, that?) -> weakset\nWeakMap\n .of(...args) -> weakmap\n .from(iterable, mapFn(val, index)?, that?) -> weakmap\n```\n[*CommonJS entry points:*](#commonjs)\n```js\ncore-js(/library)/fn/set/of\ncore-js(/library)/fn/set/from\ncore-js(/library)/fn/map/of\ncore-js(/library)/fn/map/from\ncore-js(/library)/fn/weak-set/of\ncore-js(/library)/fn/weak-set/from\ncore-js(/library)/fn/weak-map/of\ncore-js(/library)/fn/weak-map/from\n```\n[*Examples*](https://goo.gl/mSC7eU):\n```js\nSet.of(1, 2, 3, 2, 1); // => Set {1, 2, 3}\n\nMap.from([[1, 2], [3, 4]], ([key, val]) => [key ** 2, val ** 2]); // => Map {1: 4, 9: 16}\n```\n* `String#matchAll` [proposal](https://github.com/tc39/String.prototype.matchAll) - module [`es7.string.match-all`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.string.match-all.js)\n```js\nString\n #matchAll(regexp) -> iterator\n```\n[*CommonJS entry points:*](#commonjs)\n```js\ncore-js(/library)/fn/string/match-all\ncore-js(/library)/fn/string/virtual/match-all\n```\n[*Examples*](http://goo.gl/6kp9EB):\n```js\nfor(let [_, d, D] of '1111a2b3cccc'.matchAll(/(\\d)(\\D)/)){\n console.log(d, D); // => 1 a, 2 b, 3 c\n}\n```\n* `Observable` [proposal](https://github.com/zenparsing/es-observable) - modules [`es7.observable`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.observable.js) and [`es7.symbol.observable`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.symbol.observable.js)\n```js\nnew Observable(fn) -> observable\n #subscribe(observer) -> subscription\n #forEach(fn) -> promise\n #@@observable() -> @\n .of(...items) -> observable\n .from(observable | iterable) -> observable\n .@@species -> @\nSymbol\n .observable -> @@observable\n```\n[*CommonJS entry points:*](#commonjs)\n```js\ncore-js(/library)/fn/observable\ncore-js(/library)/fn/symbol/observable\n```\n[*Examples*](http://goo.gl/1LDywi):\n```js\nnew Observable(observer => {\n observer.next('hello');\n observer.next('world');\n observer.complete();\n}).forEach(it => console.log(it))\n .then(_ => console.log('!'));\n```\n* `Math.{clamp, DEG_PER_RAD, degrees, fscale, rad-per-deg, radians, scale}` \n [proposal](https://github.com/rwaldron/proposal-math-extensions) - modules \n [`es7.math.clamp`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.math.clamp.js), \n [`es7.math.DEG_PER_RAD`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.math.DEG_PER_RAD.js), \n [`es7.math.degrees`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.math.degrees.js),\n [`es7.math.fscale`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.math.fscale.js), \n [`es7.math.RAD_PER_DEG`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.math.RAD_PER_DEG.js), \n [`es7.math.radians`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.math.radians.js) and\n [`es7.math.scale`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.math.scale.js)\n```js\nMath\n .DEG_PER_RAD -> number\n .RAD_PER_DEG -> number\n .clamp(x, lower, upper) -> number\n .degrees(radians) -> number\n .fscale(x, inLow, inHigh, outLow, outHigh) -> number\n .radians(degrees) -> number\n .scale(x, inLow, inHigh, outLow, outHigh) -> number\n```\n[*CommonJS entry points:*](#commonjs)\n```js\ncore-js(/library)/fn/math/clamp\ncore-js(/library)/fn/math/deg-per-rad\ncore-js(/library)/fn/math/degrees\ncore-js(/library)/fn/math/fscale\ncore-js(/library)/fn/math/rad-per-deg\ncore-js(/library)/fn/math/radians\ncore-js(/library)/fn/math/scale\n```\n* `Math.signbit` [proposal](http://jfbastien.github.io/papers/Math.signbit.html) - module [`es7.math.signbit`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.math.signbit.js)\n```js\nMath\n .signbit(x) -> bool\n```\n[*CommonJS entry points:*](#commonjs)\n```js\ncore-js(/library)/fn/math/signbit\n```\n[*Examples*](http://es6.zloirock.ru/):\n```js\nMath.signbit(NaN); // => NaN\nMath.signbit(1); // => true\nMath.signbit(-1); // => false\nMath.signbit(0); // => true\nMath.signbit(-0); // => false\n```\n\n#### Stage 0 proposals\n[*CommonJS entry points:*](#commonjs)\n```js\ncore-js(/library)/stage/0\n```\n* `String#at` [proposal](https://github.com/mathiasbynens/String.prototype.at) - module [`es7.string.at`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.string.at.js)\n```js\nString\n #at(index) -> string\n```\n[*CommonJS entry points:*](#commonjs)\n```js\ncore-js(/library)/fn/string/at\ncore-js(/library)/fn/string/virtual/at\n```\n[*Examples*](http://goo.gl/XluXI8):\n```js\n'a𠮷b'.at(1); // => '𠮷'\n'a𠮷b'.at(1).length; // => 2\n```\n* `Map#toJSON`, `Set#toJSON` [proposal](https://github.com/DavidBruant/Map-Set.prototype.toJSON) - modules [`es7.map.to-json`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.map.to-json.js), [`es7.set.to-json`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.set.to-json.js) (rejected and will be removed from `core-js@3`)\n```js\nMap\n #toJSON() -> array (rejected and will be removed from core-js@3)\nSet\n #toJSON() -> array (rejected and will be removed from core-js@3)\n```\n[*CommonJS entry points:*](#commonjs)\n```js\ncore-js(/library)/fn/map\ncore-js(/library)/fn/set\n```\n* `Error.isError` [proposal](https://github.com/ljharb/proposal-is-error) - module [`es7.error.is-error`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.error.is-error.js) (withdrawn and will be removed from `core-js@3`)\n```js\nError\n .isError(it) -> bool (withdrawn and will be removed from core-js@3)\n```\n[*CommonJS entry points:*](#commonjs)\n```js\ncore-js(/library)/fn/error/is-error\n```\n* `Math.{iaddh, isubh, imulh, umulh}` [proposal](https://gist.github.com/BrendanEich/4294d5c212a6d2254703) - modules [`es7.math.iaddh`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.math.iaddh.js), [`es7.math.isubh`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.math.isubh.js), [`es7.math.imulh`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.math.imulh.js) and [`es7.math.umulh`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.math.umulh.js)\n```js\nMath\n .iaddh(lo0, hi0, lo1, hi1) -> int32\n .isubh(lo0, hi0, lo1, hi1) -> int32\n .imulh(a, b) -> int32\n .umulh(a, b) -> uint32\n```\n[*CommonJS entry points:*](#commonjs)\n```js\ncore-js(/library)/fn/math/iaddh\ncore-js(/library)/fn/math/isubh\ncore-js(/library)/fn/math/imulh\ncore-js(/library)/fn/math/umulh\n```\n* `global.asap`, [TC39 discussion](https://github.com/rwaldron/tc39-notes/blob/master/es6/2014-09/sept-25.md#510-globalasap-for-enqueuing-a-microtask), module [`es7.asap`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.asap.js)\n```js\nasap(fn) -> void\n```\n[*CommonJS entry points:*](#commonjs)\n```js\ncore-js(/library)/fn/asap\n```\n[*Examples*](http://goo.gl/tx3SRK):\n```js\nasap(() => console.log('called as microtask'));\n```\n\n#### Pre-stage 0 proposals\n[*CommonJS entry points:*](#commonjs)\n```js\ncore-js(/library)/stage/pre\n```\n* `Reflect` metadata [proposal](https://github.com/jonathandturner/decorators/blob/master/specs/metadata.md) - modules [`es7.reflect.define-metadata`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.reflect.define-metadata.js), [`es7.reflect.delete-metadata`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.reflect.delete-metadata.js), [`es7.reflect.get-metadata`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.reflect.get-metadata.js), [`es7.reflect.get-metadata-keys`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.reflect.get-metadata-keys.js), [`es7.reflect.get-own-metadata`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.reflect.get-own-metadata.js), [`es7.reflect.get-own-metadata-keys`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.reflect.get-own-metadata-keys.js), [`es7.reflect.has-metadata`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.reflect.has-metadata.js), [`es7.reflect.has-own-metadata`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.reflect.has-own-metadata.js) and [`es7.reflect.metadata`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/es7.reflect.metadata.js).\n```js\nReflect\n .defineMetadata(metadataKey, metadataValue, target, propertyKey?) -> void\n .getMetadata(metadataKey, target, propertyKey?) -> var\n .getOwnMetadata(metadataKey, target, propertyKey?) -> var\n .hasMetadata(metadataKey, target, propertyKey?) -> bool\n .hasOwnMetadata(metadataKey, target, propertyKey?) -> bool\n .deleteMetadata(metadataKey, target, propertyKey?) -> bool\n .getMetadataKeys(target, propertyKey?) -> array\n .getOwnMetadataKeys(target, propertyKey?) -> array\n .metadata(metadataKey, metadataValue) -> decorator(target, targetKey?) -> void\n```\n[*CommonJS entry points:*](#commonjs)\n```js\ncore-js(/library)/fn/reflect/define-metadata\ncore-js(/library)/fn/reflect/delete-metadata\ncore-js(/library)/fn/reflect/get-metadata\ncore-js(/library)/fn/reflect/get-metadata-keys\ncore-js(/library)/fn/reflect/get-own-metadata\ncore-js(/library)/fn/reflect/get-own-metadata-keys\ncore-js(/library)/fn/reflect/has-metadata\ncore-js(/library)/fn/reflect/has-own-metadata\ncore-js(/library)/fn/reflect/metadata\n```\n[*Examples*](http://goo.gl/KCo3PS):\n```js\nvar O = {};\nReflect.defineMetadata('foo', 'bar', O);\nReflect.ownKeys(O); // => []\nReflect.getOwnMetadataKeys(O); // => ['foo']\nReflect.getOwnMetadata('foo', O); // => 'bar'\n```\n\n### Web standards\n[*CommonJS entry points:*](#commonjs)\n```js\ncore-js(/library)/web\n```\n#### setTimeout / setInterval\nModule [`web.timers`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/web.timers.js). Additional arguments fix for IE9-.\n```js\nsetTimeout(fn(...args), time, ...args) -> id\nsetInterval(fn(...args), time, ...args) -> id\n```\n[*CommonJS entry points:*](#commonjs)\n```js\ncore-js(/library)/web/timers\ncore-js(/library)/fn/set-timeout\ncore-js(/library)/fn/set-interval\n```\n```js\n// Before:\nsetTimeout(log.bind(null, 42), 1000);\n// After:\nsetTimeout(log, 1000, 42);\n```\n#### setImmediate\nModule [`web.immediate`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/web.immediate.js). [`setImmediate` proposal](https://developer.mozilla.org/en-US/docs/Web/API/Window.setImmediate) polyfill.\n```js\nsetImmediate(fn(...args), ...args) -> id\nclearImmediate(id) -> void\n```\n[*CommonJS entry points:*](#commonjs)\n```js\ncore-js(/library)/web/immediate\ncore-js(/library)/fn/set-immediate\ncore-js(/library)/fn/clear-immediate\n```\n[*Examples*](http://goo.gl/6nXGrx):\n```js\nsetImmediate(function(arg1, arg2){\n console.log(arg1, arg2); // => Message will be displayed with minimum delay\n}, 'Message will be displayed', 'with minimum delay');\n\nclearImmediate(setImmediate(function(){\n console.log('Message will not be displayed');\n}));\n```\n#### Iterable DOM collections\nSome DOM collections should have [iterable interface](https://heycam.github.io/webidl/#idl-iterable) or should be [inherited from `Array`](https://heycam.github.io/webidl/#LegacyArrayClass). That mean they should have `keys`, `values`, `entries` and `@@iterator` methods for iteration. So add them. Module [`web.dom.iterable`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/web.dom.iterable.js):\n```js\n{\n CSSRuleList,\n CSSStyleDeclaration,\n CSSValueList,\n ClientRectList,\n DOMRectList,\n DOMStringList,\n DOMTokenList,\n DataTransferItemList,\n FileList,\n HTMLAllCollection,\n HTMLCollection,\n HTMLFormElement,\n HTMLSelectElement,\n MediaList,\n MimeTypeArray,\n NamedNodeMap,\n NodeList,\n PaintRequestList,\n Plugin,\n PluginArray,\n SVGLengthList,\n SVGNumberList,\n SVGPathSegList,\n SVGPointList,\n SVGStringList,\n SVGTransformList,\n SourceBufferList,\n StyleSheetList,\n TextTrackCueList,\n TextTrackList,\n TouchList\n}\n #@@iterator() -> iterator (values)\n\n{\n DOMTokenList,\n NodeList\n}\n #values() -> iterator\n #keys() -> iterator\n #entries() -> iterator\n```\n[*CommonJS entry points:*](#commonjs)\n```js\ncore-js(/library)/web/dom-collections\ncore-js(/library)/fn/dom-collections/iterator\n```\n[*Examples*](http://goo.gl/lfXVFl):\n```js\nfor(var {id} of document.querySelectorAll('*')){\n if(id)console.log(id);\n}\n\nfor(var [index, {id}] of document.querySelectorAll('*').entries()){\n if(id)console.log(index, id);\n}\n```\n### Non-standard\n[*CommonJS entry points:*](#commonjs)\n```js\ncore-js(/library)/core\n```\n#### Object\nModules [`core.object.is-object`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/core.object.is-object.js), [`core.object.classof`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/core.object.classof.js), [`core.object.define`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/core.object.define.js), [`core.object.make`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/core.object.make.js).\n```js\nObject\n .isObject(var) -> bool\n .classof(var) -> string\n .define(target, mixin) -> target\n .make(proto | null, mixin?) -> object\n```\n\n[*CommonJS entry points:*](#commonjs)\n```js\ncore-js(/library)/core/object\ncore-js(/library)/fn/object/is-object\ncore-js(/library)/fn/object/define\ncore-js(/library)/fn/object/make\n```\nObject classify [*examples*](http://goo.gl/YZQmGo):\n```js\nObject.isObject({}); // => true\nObject.isObject(isNaN); // => true\nObject.isObject(null); // => false\n\nvar classof = Object.classof;\n\nclassof(null); // => 'Null'\nclassof(undefined); // => 'Undefined'\nclassof(1); // => 'Number'\nclassof(true); // => 'Boolean'\nclassof('string'); // => 'String'\nclassof(Symbol()); // => 'Symbol'\n\nclassof(new Number(1)); // => 'Number'\nclassof(new Boolean(true)); // => 'Boolean'\nclassof(new String('string')); // => 'String'\n\nvar fn = function(){}\n , list = (function(){return arguments})(1, 2, 3);\n\nclassof({}); // => 'Object'\nclassof(fn); // => 'Function'\nclassof([]); // => 'Array'\nclassof(list); // => 'Arguments'\nclassof(/./); // => 'RegExp'\nclassof(new TypeError); // => 'Error'\n\nclassof(new Set); // => 'Set'\nclassof(new Map); // => 'Map'\nclassof(new WeakSet); // => 'WeakSet'\nclassof(new WeakMap); // => 'WeakMap'\nclassof(new Promise(fn)); // => 'Promise'\n\nclassof([].values()); // => 'Array Iterator'\nclassof(new Set().values()); // => 'Set Iterator'\nclassof(new Map().values()); // => 'Map Iterator'\n\nclassof(Math); // => 'Math'\nclassof(JSON); // => 'JSON'\n\nfunction Example(){}\nExample.prototype[Symbol.toStringTag] = 'Example';\n\nclassof(new Example); // => 'Example'\n```\n`Object.define` and `Object.make` [*examples*](http://goo.gl/rtpD5Z):\n```js\n// Before:\nObject.defineProperty(target, 'c', {\n enumerable: true,\n configurable: true,\n get: function(){\n return this.a + this.b;\n }\n});\n\n// After:\nObject.define(target, {\n get c(){\n return this.a + this.b;\n }\n});\n\n// Shallow object cloning with prototype and descriptors:\nvar copy = Object.make(Object.getPrototypeOf(src), src);\n\n// Simple inheritance:\nfunction Vector2D(x, y){\n this.x = x;\n this.y = y;\n}\nObject.define(Vector2D.prototype, {\n get xy(){\n return Math.hypot(this.x, this.y);\n }\n});\nfunction Vector3D(x, y, z){\n Vector2D.apply(this, arguments);\n this.z = z;\n}\nVector3D.prototype = Object.make(Vector2D.prototype, {\n constructor: Vector3D,\n get xyz(){\n return Math.hypot(this.x, this.y, this.z);\n }\n});\n\nvar vector = new Vector3D(9, 12, 20);\nconsole.log(vector.xy); // => 15\nconsole.log(vector.xyz); // => 25\nvector.y++;\nconsole.log(vector.xy); // => 15.811388300841896\nconsole.log(vector.xyz); // => 25.495097567963924\n```\n#### Dict\nModule [`core.dict`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/core.dict.js). Based on [TC39 discuss](https://github.com/rwaldron/tc39-notes/blob/master/es6/2012-11/nov-29.md#collection-apis-review) / [strawman](http://wiki.ecmascript.org/doku.php?id=harmony:modules_standard#dictionaries).\n```js\n[new] Dict(iterable (entries) | object ?) -> dict\n .isDict(var) -> bool\n .values(object) -> iterator\n .keys(object) -> iterator\n .entries(object) -> iterator (entries)\n .has(object, key) -> bool\n .get(object, key) -> val\n .set(object, key, value) -> object\n .forEach(object, fn(val, key, @), that) -> void\n .map(object, fn(val, key, @), that) -> new @\n .mapPairs(object, fn(val, key, @), that) -> new @\n .filter(object, fn(val, key, @), that) -> new @\n .some(object, fn(val, key, @), that) -> bool\n .every(object, fn(val, key, @), that) -> bool\n .find(object, fn(val, key, @), that) -> val\n .findKey(object, fn(val, key, @), that) -> key\n .keyOf(object, var) -> key\n .includes(object, var) -> bool\n .reduce(object, fn(memo, val, key, @), memo?) -> var\n```\n\n[*CommonJS entry points:*](#commonjs)\n```js\ncore-js(/library)/core/dict\ncore-js(/library)/fn/dict\n```\n`Dict` create object without prototype from iterable or simple object.\n\n[*Examples*](http://goo.gl/pnp8Vr):\n```js\nvar map = new Map([['a', 1], ['b', 2], ['c', 3]]);\n\nDict(); // => {__proto__: null}\nDict({a: 1, b: 2, c: 3}); // => {__proto__: null, a: 1, b: 2, c: 3}\nDict(map); // => {__proto__: null, a: 1, b: 2, c: 3}\nDict([1, 2, 3].entries()); // => {__proto__: null, 0: 1, 1: 2, 2: 3}\n\nvar dict = Dict({a: 42});\ndict instanceof Object; // => false\ndict.a; // => 42\ndict.toString; // => undefined\n'a' in dict; // => true\n'hasOwnProperty' in dict; // => false\n\nDict.isDict({}); // => false\nDict.isDict(Dict()); // => true\n```\n`Dict.keys`, `Dict.values` and `Dict.entries` returns iterators for objects.\n\n[*Examples*](http://goo.gl/xAvECH):\n```js\nvar dict = {a: 1, b: 2, c: 3};\n\nfor(var key of Dict.keys(dict))console.log(key); // => 'a', 'b', 'c'\n\nfor(var val of Dict.values(dict))console.log(val); // => 1, 2, 3\n\nfor(var [key, val] of Dict.entries(dict)){\n console.log(key); // => 'a', 'b', 'c'\n console.log(val); // => 1, 2, 3\n}\n\nnew Map(Dict.entries(dict)); // => Map {a: 1, b: 2, c: 3}\n```\nBasic dict operations for objects with prototype [*examples*](http://goo.gl/B28UnG):\n```js\n'q' in {q: 1}; // => true\n'toString' in {}; // => true\n\nDict.has({q: 1}, 'q'); // => true\nDict.has({}, 'toString'); // => false\n\n({q: 1})['q']; // => 1\n({}).toString; // => function toString(){ [native code] }\n\nDict.get({q: 1}, 'q'); // => 1\nDict.get({}, 'toString'); // => undefined\n\nvar O = {};\nO['q'] = 1;\nO['q']; // => 1\nO['__proto__'] = {w: 2};\nO['__proto__']; // => {w: 2}\nO['w']; // => 2\n\nvar O = {};\nDict.set(O, 'q', 1);\nO['q']; // => 1\nDict.set(O, '__proto__', {w: 2});\nO['__proto__']; // => {w: 2}\nO['w']; // => undefined\n```\nOther methods of `Dict` module are static equivalents of `Array.prototype` methods for dictionaries.\n\n[*Examples*](http://goo.gl/xFi1RH):\n```js\nvar dict = {a: 1, b: 2, c: 3};\n\nDict.forEach(dict, console.log, console);\n// => 1, 'a', {a: 1, b: 2, c: 3}\n// => 2, 'b', {a: 1, b: 2, c: 3}\n// => 3, 'c', {a: 1, b: 2, c: 3}\n\nDict.map(dict, function(it){\n return it * it;\n}); // => {a: 1, b: 4, c: 9}\n\nDict.mapPairs(dict, function(val, key){\n if(key != 'b')return [key + key, val * val];\n}); // => {aa: 1, cc: 9}\n\nDict.filter(dict, function(it){\n return it % 2;\n}); // => {a: 1, c: 3}\n\nDict.some(dict, function(it){\n return it === 2;\n}); // => true\n\nDict.every(dict, function(it){\n return it === 2;\n}); // => false\n\nDict.find(dict, function(it){\n return it > 2;\n}); // => 3\nDict.find(dict, function(it){\n return it > 4;\n}); // => undefined\n\nDict.findKey(dict, function(it){\n return it > 2;\n}); // => 'c'\nDict.findKey(dict, function(it){\n return it > 4;\n}); // => undefined\n\nDict.keyOf(dict, 2); // => 'b'\nDict.keyOf(dict, 4); // => undefined\n\nDict.includes(dict, 2); // => true\nDict.includes(dict, 4); // => false\n\nDict.reduce(dict, function(memo, it){\n return memo + it;\n}); // => 6\nDict.reduce(dict, function(memo, it){\n return memo + it;\n}, ''); // => '123'\n```\n#### Partial application\nModule [`core.function.part`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/core.function.part.js).\n```js\nFunction\n #part(...args | _) -> fn(...args)\n```\n\n[*CommonJS entry points:*](#commonjs)\n```js\ncore-js/core/function\ncore-js(/library)/fn/function/part\ncore-js(/library)/fn/function/virtual/part\ncore-js(/library)/fn/_\n```\n`Function#part` partial apply function without `this` binding. Uses global variable `_` (`core._` for builds without global namespace pollution) as placeholder and not conflict with `Underscore` / `LoDash`.\n\n[*Examples*](http://goo.gl/p9ZJ8K):\n```js\nvar fn1 = log.part(1, 2);\nfn1(3, 4); // => 1, 2, 3, 4\n\nvar fn2 = log.part(_, 2, _, 4);\nfn2(1, 3); // => 1, 2, 3, 4\n\nvar fn3 = log.part(1, _, _, 4);\nfn3(2, 3); // => 1, 2, 3, 4\n\nfn2(1, 3, 5); // => 1, 2, 3, 4, 5\nfn2(1); // => 1, 2, undefined, 4\n```\n#### Number Iterator\nModule [`core.number.iterator`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/core.number.iterator.js).\n```js\nNumber\n #@@iterator() -> iterator\n```\n\n[*CommonJS entry points:*](#commonjs)\n```js\ncore-js(/library)/core/number\ncore-js(/library)/fn/number/iterator\ncore-js(/library)/fn/number/virtual/iterator\n```\n[*Examples*](http://goo.gl/o45pCN):\n```js\nfor(var i of 3)console.log(i); // => 0, 1, 2\n\n[...10]; // => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n\nArray.from(10, Math.random); // => [0.9817775336559862, 0.02720663254149258, ...]\n\nArray.from(10, function(it){\n return this + it * it;\n}, .42); // => [0.42, 1.42, 4.42, 9.42, 16.42, 25.42, 36.42, 49.42, 64.42, 81.42]\n```\n#### Escaping strings\nModules [`core.regexp.escape`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/core.regexp.escape.js), [`core.string.escape-html`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/core.string.escape-html.js) and [`core.string.unescape-html`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/core.string.unescape-html.js).\n```js\nRegExp\n .escape(str) -> str\nString\n #escapeHTML() -> str\n #unescapeHTML() -> str\n```\n[*CommonJS entry points:*](#commonjs)\n```js\ncore-js(/library)/core/regexp\ncore-js(/library)/core/string\ncore-js(/library)/fn/regexp/escape\ncore-js(/library)/fn/string/escape-html\ncore-js(/library)/fn/string/unescape-html\ncore-js(/library)/fn/string/virtual/escape-html\ncore-js(/library)/fn/string/virtual/unescape-html\n```\n[*Examples*](http://goo.gl/6bOvsQ):\n```js\nRegExp.escape('Hello, []{}()*+?.\\\\^$|!'); // => 'Hello, \\[\\]\\{\\}\\(\\)\\*\\+\\?\\.\\\\\\^\\$\\|!'\n\n''.escapeHTML(); // => '<script>doSomething();</script>'\n'<script>doSomething();</script>'.unescapeHTML(); // => ''\n```\n#### delay\nModule [`core.delay`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/core.delay.js). [Promise](#ecmascript-6-promise)-returning delay function, [esdiscuss](https://esdiscuss.org/topic/promise-returning-delay-function).\n```js\ndelay(ms) -> promise\n```\n[*CommonJS entry points:*](#commonjs)\n```js\ncore-js(/library)/core/delay\ncore-js(/library)/fn/delay\n```\n[*Examples*](http://goo.gl/lbucba):\n```js\ndelay(1e3).then(() => console.log('after 1 sec'));\n\n(async () => {\n await delay(3e3);\n console.log('after 3 sec');\n\n while(await delay(3e3))console.log('each 3 sec');\n})();\n```\n#### Helpers for iterators\nModules [`core.is-iterable`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/core.is-iterable.js), [`core.get-iterator`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/core.get-iterator.js), [`core.get-iterator-method`](https://github.com/zloirock/core-js/blob/v2.5.7/modules/core.get-iterator-method.js) - helpers for check iterability / get iterator in the `library` version or, for example, for `arguments` object:\n```js\ncore\n .isIterable(var) -> bool\n .getIterator(iterable) -> iterator\n .getIteratorMethod(var) -> function | undefined\n```\n[*CommonJS entry points:*](#commonjs)\n```js\ncore-js(/library)/fn/is-iterable\ncore-js(/library)/fn/get-iterator\ncore-js(/library)/fn/get-iterator-method\n```\n[*Examples*](http://goo.gl/SXsM6D):\n```js\nvar list = (function(){\n return arguments;\n})(1, 2, 3);\n\nconsole.log(core.isIterable(list)); // true;\n\nvar iter = core.getIterator(list);\nconsole.log(iter.next().value); // 1\nconsole.log(iter.next().value); // 2\nconsole.log(iter.next().value); // 3\nconsole.log(iter.next().value); // undefined\n\ncore.getIterator({}); // TypeError: [object Object] is not iterable!\n\nvar iterFn = core.getIteratorMethod(list);\nconsole.log(typeof iterFn); // 'function'\nvar iter = iterFn.call(list);\nconsole.log(iter.next().value); // 1\nconsole.log(iter.next().value); // 2\nconsole.log(iter.next().value); // 3\nconsole.log(iter.next().value); // undefined\n\nconsole.log(core.getIteratorMethod({})); // undefined\n```\n\n## Missing polyfills\n- ES5 `JSON` is missing now only in IE7- and never will it be added to `core-js`, if you need it in these old browsers, many implementations are available, for example, [json3](https://github.com/bestiejs/json3).\n- ES6 `String#normalize` is not a very useful feature, but this polyfill will be very large. If you need it, you can use [unorm](https://github.com/walling/unorm/).\n- ES6 `Proxy` can't be polyfilled, but for Node.js / Chromium with additional flags you can try [harmony-reflect](https://github.com/tvcutsem/harmony-reflect) for adapt old style `Proxy` API to final ES6 version.\n- ES6 logic for `@@isConcatSpreadable` and `@@species` (in most places) can be polyfilled without problems, but it will cause a serious slowdown in popular cases in some engines. It will be polyfilled when it will be implemented in modern engines.\n- ES7 `SIMD`. `core-js` doesn't add polyfill of this feature because of large size and some other reasons. You can use [this polyfill](https://github.com/tc39/ecmascript_simd/blob/master/src/ecmascript_simd.js).\n- `window.fetch` is not a cross-platform feature, in some environments it makes no sense. For this reason, I don't think it should be in `core-js`. Looking at a large number of requests it *may be* added in the future. Now you can use, for example, [this polyfill](https://github.com/github/fetch).\n- ECMA-402 `Intl` is missed because of size. You can use [this polyfill](https://github.com/andyearnshaw/Intl.js/).\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/zloirock/core-js/issues" - }, - "homepage": "https://github.com/zloirock/core-js#readme", - "_id": "core-js@2.5.7", - "_requested": { - "type": "version", - "registry": true, - "raw": "core-js@2.5.7", - "name": "core-js", - "escapedName": "core-js", - "rawSpec": "2.5.7", - "saveSpec": "[Circular]", - "fetchSpec": "2.5.7" - }, - "_spec": "2.5.7", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "core-js@2.5.7", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "dependencies": {}, - "optionalDependencies": {}, - "_dependencies": {}, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/core-js", - "error": "[Circular]", - "extraneous": false, - "peerMissing": [ - { - "requiredBy": "@alfresco/adf-core@2.6.1", - "requires": "core-js@2.4.1" - } - ] - }, - "peerMissing": true - }, - "hammerjs": { - "version": "2.0.8", - "from": "hammerjs@2.0.8", - "resolved": "https://registry.npmjs.org/hammerjs/-/hammerjs-2.0.8.tgz" - }, - "minimatch-browser": { - "version": "1.0.0", - "from": "minimatch-browser@1.0.0", - "resolved": "https://registry.npmjs.org/minimatch-browser/-/minimatch-browser-1.0.0.tgz" - }, - "moment": { - "version": "2.22.2", - "from": "moment@2.22.2", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz" - }, - "moment-es6": { - "version": "1.0.0", - "from": "moment-es6@1.0.0", - "resolved": "https://registry.npmjs.org/moment-es6/-/moment-es6-1.0.0.tgz" - }, - "pdfjs-dist": { - "required": { - "name": "pdfjs-dist", - "version": "2.0.489", - "main": "build/pdf.js", - "description": "Generic build of Mozilla's PDF.js library.", - "keywords": [ - "Mozilla", - "pdf", - "pdf.js" - ], - "homepage": "http://mozilla.github.io/pdf.js/", - "bugs": { - "url": "https://github.com/mozilla/pdf.js/issues" - }, - "license": "Apache-2.0", - "dependencies": { - "node-ensure": { - "name": "node-ensure", - "version": "0.0.0", - "description": "Async module-loading library and protocol for bundlers/loaders targeting isomorphic apps and Node.js.", - "main": "index.js", - "browser": { - "./index.js": "./browser.js" - }, - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "keywords": [ - "require", - "ensure", - "dynamic", - "module", - "loader", - "bundler", - "async" - ], - "author": { - "name": "Carl A. Bauer" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/bauerca/node-ensure.git" - }, - "bugs": { - "url": "https://github.com/bauerca/node-ensure/issues" - }, - "homepage": "https://github.com/bauerca/node-ensure", - "license": "MIT", - "_resolved": "https://registry.npmjs.org/node-ensure/-/node-ensure-0.0.0.tgz", - "_integrity": "sha1-7K52QVDemYYexcgQ/V0Jaxg5Mqc=", - "_from": "node-ensure@0.0.0", - "readme": "# node-ensure\n\nA simple library that shims asynchronous module loading into Node.js to help\nwith building module bundlers and client-side loaders for isomorphic apps.\nThis library is super slim (read the source) and mainly represents an agreement\nbetween developers and users of a particular bundler/loader.\n\nNOTE: This module is *not* compatible with Browserify. It is for developers that\nwant to split their bundles for the client. For example, see\n[dynapack](https://github.com/bauerca/dynapack).\n\n*Syntax is inspired by the CommonJS\n[Modules/Async/A](http://wiki.commonjs.org/wiki/Modules/Async/A) proposal.*\n\n\n## Installation\n\n```\nnpm install node-ensure\n```\n\n## Example\n\n```js\nvar ensure = require('node-ensure');\n\nensure(['superagent', 'react'], function(err) {\n var request = require('superagent');\n var React = require('react');\n\n // Do the coolest of things.\n});\n```\n\nIf your bundler needs `require.ensure`, do this instead:\n\n```js\nrequire.ensure = require('node-ensure');\n\nrequire.ensure(['superagent', 'react'], function(err) {\n var request = require('superagent');\n var React = require('react');\n\n // Do the coolest of things.\n});\n```\n\n## Usage\n\nThe returned function takes an array of strings and a callback, in that\norder (see the example above). The callback takes a single error argument, which\nusually indicates a network problem or other client-side loader-specific runtime\nerror (it should never receive an error when used in Node.js).\n\nWithin the ensure callback, load modules with standard require calls.\n\n## Bundlers/Loaders\n\nThis library primarily constitutes an agreement between users and developers of\nmodule bundlers and (client-side) loaders. The users agree to the usage instructions\nsupplied above.\n\nBundlers and/or loaders must adhere to the following:\n\n- The bundler/loader uses the package.json `\"browser\"` property for replacing\n server-only modules with browser-ready counterparts (a la Browserify).\n- The `require` function passed to a module must have a `require.ensure`\n function.\n- Each `require.ensure` must accept the same arguments as described in [Usage](#usage).\n- Each `require.ensure` must not access variables via closure unless those variables\n are shared by **all** `require.ensure` functions.\n- Each `require.ensure` may access properties\n on `this`. However, this assumes users have attached node-ensure to `require` via\n `require.ensure = require('node-ensure')`.\n\nHappy loading!\n\n# License\n\nMIT\n", - "readmeFilename": "README.md", - "_id": "node-ensure@0.0.0", - "_requested": { - "type": "version", - "registry": true, - "raw": "node-ensure@0.0.0", - "name": "node-ensure", - "escapedName": "node-ensure", - "rawSpec": "0.0.0", - "saveSpec": "[Circular]", - "fetchSpec": "0.0.0" - }, - "_spec": "0.0.0", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "node-ensure@0.0.0", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "dependencies": {}, - "devDependencies": {}, - "optionalDependencies": {}, - "_dependencies": {}, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/node-ensure", - "error": "[Circular]", - "extraneous": false - }, - "worker-loader": { - "name": "worker-loader", - "version": "1.1.1", - "author": { - "name": "Tobias Koppers @sokra" - }, - "description": "worker loader module for webpack", - "main": "dist/cjs.js", - "files": [ - "dist" - ], - "engines": { - "node": ">= 4.8 < 5.0.0 || >= 5.10" - }, - "scripts": { - "start": "npm run build -- -w", - "build": "cross-env NODE_ENV=production babel src -d dist --ignore 'src/**/*.test.js' --copy-files", - "clean": "del-cli dist", - "lint": "eslint --cache src test", - "lint-staged": "lint-staged", - "prebuild": "npm run clean", - "prepare": "npm run build", - "release": "standard-version", - "security": "nsp check", - "test": "jest", - "test:watch": "jest --watch", - "test:coverage": "jest --collectCoverageFrom='src/**/*.js' --coverage", - "travis:lint": "npm run lint && npm run security", - "travis:test": "npm run test -- --runInBand", - "travis:coverage": "npm run test:coverage -- --runInBand", - "appveyor:test": "npm run test", - "defaults": "webpack-defaults" - }, - "peerDependencies": { - "webpack": "^2.0.0 || ^3.0.0 || ^4.0.0" - }, - "dependencies": { - "loader-utils": { - "name": "loader-utils", - "version": "1.1.0", - "author": { - "name": "Tobias Koppers @sokra" - }, - "description": "utils for webpack loaders", - "dependencies": { - "big.js": { - "name": "big.js", - "description": "A small, fast, easy-to-use library for arbitrary-precision decimal arithmetic", - "version": "3.2.0", - "keywords": [ - "arbitrary", - "precision", - "arithmetic", - "big", - "number", - "decimal", - "float", - "biginteger", - "bigdecimal", - "bignumber", - "bigint", - "bignum" - ], - "repository": { - "type": "git", - "url": "git+https://github.com/MikeMcl/big.js.git" - }, - "main": "big.js", - "author": { - "name": "Michael Mclaughlin", - "email": "M8ch88l@gmail.com" - }, - "bugs": { - "url": "https://github.com/MikeMcl/big.js/issues" - }, - "engines": { - "node": "*" - }, - "license": "MIT", - "scripts": { - "test": "node ./test/every-test.js", - "build": "uglifyjs big.js --source-map doc/big.js.map -c -m -o big.min.js --preamble \"/* big.js v3.2.0 https://github.com/MikeMcl/big.js/LICENCE */\"" - }, - "files": [ - "big.js", - "big.min.js" - ], - "_resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", - "_integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", - "_from": "big.js@3.2.0", - "readme": "\r\n# big.js #\r\n\r\nA small, fast JavaScript library for arbitrary-precision decimal arithmetic.\r\n\r\nThe little sister to [bignumber.js](https://github.com/MikeMcl/bignumber.js/).\r\nSee also [decimal.js](https://github.com/MikeMcl/decimal.js/), and [here](https://github.com/MikeMcl/big.js/wiki) for the difference between them.\r\n\r\n## Features\r\n\r\n - Faster, smaller and easier-to-use than JavaScript versions of Java's BigDecimal\r\n - Only 2.7 KB minified and gzipped\r\n - Simple API\r\n - Replicates the `toExponential`, `toFixed` and `toPrecision` methods of JavaScript's Number type\r\n - Includes a `sqrt` method\r\n - Stores values in an accessible decimal floating point format\r\n - No dependencies\r\n - Comprehensive [documentation](http://mikemcl.github.io/big.js/) and test set\r\n\r\n## Load\r\n\r\nThe library is the single JavaScript file *big.js* (or *big.min.js*, which is *big.js* minified).\r\n\r\nIt can be loaded via a script tag in an HTML document for the browser\r\n\r\n \r\n\r\nor as a CommonJS, [Node.js](http://nodejs.org) or AMD module using `require`.\r\n\r\n var Big = require('big.js');\r\n\r\nFor Node.js, the library is available from the npm registry:\r\n\r\n $ npm install big.js\r\n\r\n\r\n\r\n## Use\r\n\r\n*In all examples below, `var`, semicolons and `toString` calls are not shown.\r\nIf a commented-out value is in quotes it means `toString` has been called on the preceding expression.*\r\n\r\nThe library exports a single function: Big, the constructor of Big number instances.\r\nIt accepts a value of type Number, String or Big number Object.\r\n\r\n x = new Big(123.4567)\r\n y = Big('123456.7e-3') // 'new' is optional\r\n z = new Big(x)\r\n x.eq(y) && x.eq(z) && y.eq(z) // true\r\n\r\nA Big number is immutable in the sense that it is not changed by its methods.\r\n\r\n 0.3 - 0.1 // 0.19999999999999998\r\n x = new Big(0.3)\r\n x.minus(0.1) // \"0.2\"\r\n x // \"0.3\"\r\n\r\nThe methods that return a Big number can be chained.\r\n\r\n x.div(y).plus(z).times(9).minus('1.234567801234567e+8').plus(976.54321).div('2598.11772')\r\n x.sqrt().div(y).pow(3).gt(y.mod(z)) // true\r\n\r\nLike JavaScript's Number type, there are `toExponential`, `toFixed` and `toPrecision` methods.\r\n\r\n x = new Big(255.5)\r\n x.toExponential(5) // \"2.55500e+2\"\r\n x.toFixed(5) // \"255.50000\"\r\n x.toPrecision(5) // \"255.50\"\r\n\r\nThe maximum number of decimal places and the rounding mode used to round the results of the `div`, `sqrt` and `pow`\r\n(with negative exponent) methods is determined by the value of the `DP` and `RM` properties of the `Big` number constructor. \r\n\r\nThe other methods always give the exact result. \r\n\r\n(From *v3.0.0*, multiple Big number constructors can be created, see Change Log below.)\r\n\r\n Big.DP = 10\r\n Big.RM = 1\r\n\r\n x = new Big(2);\r\n y = new Big(3);\r\n z = x.div(y) // \"0.6666666667\"\r\n z.sqrt() // \"0.8164965809\"\r\n z.pow(-3) // \"3.3749999995\"\r\n z.times(z) // \"0.44444444448888888889\"\r\n z.times(z).round(10) // \"0.4444444445\"\r\n\r\n\r\nThe value of a Big number is stored in a decimal floating point format in terms of a coefficient, exponent and sign.\r\n\r\n x = new Big(-123.456);\r\n x.c // [1,2,3,4,5,6] coefficient (i.e. significand)\r\n x.e // 2 exponent\r\n x.s // -1 sign\r\n\r\nFor further information see the [API](http://mikemcl.github.io/big.js/) reference from the *doc* folder.\r\n\r\n## Test\r\n\r\nThe *test* directory contains the test scripts for each Big number method.\r\n\r\nThe tests can be run with Node or a browser.\r\n\r\nTo test a single method, from a command-line shell at the *test* directory, use e.g.\r\n\r\n $ node toFixed\r\n\r\nTo test all the methods\r\n\r\n $ node every-test\r\n\r\nFor the browser, see *single-test.html* and *every-test.html* in the *test/browser* directory.\r\n\r\n*big-vs-number.html* enables some of the methods of big.js to be compared with those of JavaScript's Number type.\r\n\r\n## Performance\r\n\r\nThe *perf* directory contains two applications and a *lib* directory containing the BigDecimal libraries used by both.\r\n\r\n*big-vs-bigdecimal.html* tests the performance of big.js against the JavaScript translations of two versions of BigDecimal, its use should be more or less self-explanatory.\r\n(The GWT version doesn't work in IE 6.)\r\n\r\n* GWT: java.math.BigDecimal\r\n\r\n* ICU4J: com.ibm.icu.math.BigDecimal\r\n\r\n\r\nThe BigDecimal in Node's npm registry is the GWT version. Despite its seeming popularity I have found it to have some serious bugs, see the Node script *perf/lib/bigdecimal_GWT/bugs.js* for examples of flaws in its *remainder*, *divide* and *compareTo* methods.\r\n\r\n*bigtime.js* is a Node command-line application which tests the performance of big.js against the GWT version of\r\nBigDecimal from the npm registry.\r\n\r\nFor example, to compare the time taken by the big.js `plus` method and the BigDecimal `add` method:\r\n\r\n $ node bigtime plus 10000 40\r\n\r\nThis will time 10000 calls to each, using operands of up to 40 random digits and will check that the results match.\r\n\r\nFor help:\r\n\r\n $ node bigtime -h\r\n\r\n## Build\r\n\r\nI.e. minify.\r\n\r\nFor Node, if uglify-js is installed globally ( `npm install uglify-js -g` ) then\r\n\r\n uglifyjs -o ./big.min.js ./big.js\r\n\r\nwill create *big.min.js*.\r\n\r\nThe *big.min.js* already present was created with *Microsoft Ajax Minifier 5.11*.\r\n\r\n## TypeScript\r\n\r\nThe [DefinitelyTyped](https://github.com/borisyankov/DefinitelyTyped) project has a TypeScript [definitions file](https://github.com/borisyankov/DefinitelyTyped/blob/master/big.js/big.js.d.ts) for big.js.\r\n\r\nThe definitions file can be added to your project via the [big.js.TypeScript.DefinitelyTyped](https://www.nuget.org/packages/big.js.TypeScript.DefinitelyTyped/0.0.1) NuGet package or via [tsd](http://definitelytyped.org/tsd/).\r\n\r\n tsd query big.js --action install\r\n\r\nAny questions about the TypeScript definitions file should be addressed to the DefinitelyTyped project.\r\n\r\n## Feedback\r\n\r\nFeedback is welcome.\r\n\r\nBugs/comments/questions?\r\nOpen an issue, or email\r\n\r\nMichael\r\nM8ch88l@gmail.com\r\n\r\nBitcoin donation to:\r\n**1DppGRQSjVSMgGxuygDEHQuWEdTiVEzJYG**\r\nThank you\r\n\r\n## Licence\r\n\r\nSee LICENCE.\r\n\r\n## Change Log\r\n\r\n####3.2.0\r\n\r\n* 14/09/17 Aid ES6 import.\r\n\r\n####3.1.3\r\n\r\n* Minor documentation updates.\r\n\r\n####3.1.2\r\n\r\n* README typo.\r\n\r\n####3.1.1\r\n\r\n* API documentation update, including FAQ additions.\r\n\r\n####3.1.0\r\n\r\n* Renamed and exposed `TO_EXP_NEG` and `TO_EXP_POS` as `Big.E_NEG` and\r\n `Big.E_POS`.\r\n\r\n####3.0.2\r\n\r\n* Remove *.npmignore*, use `files` field in *package.json* instead.\r\n\r\n####3.0.1\r\n\r\n* Added `sub`, `add` and `mul` aliases.\r\n* Clean-up after lint.\r\n\r\n####3.0.0\r\n\r\n* 10/12/14 Added [multiple constructor functionality](http://mikemcl.github.io/big.js/#faq).\r\n* No breaking changes or other additions, but a major code reorganisation,\r\n so *v3* seemed appropriate.\r\n\r\n####2.5.2\r\n\r\n* 1/11/14 Added bower.json.\r\n\r\n####2.5.1\r\n\r\n* 8/06/14 Amend README requires.\r\n\r\n####2.5.0\r\n\r\n* 26/01/14 Added `toJSON` method so serialization uses `toString`.\r\n\r\n####2.4.1\r\n\r\n* 17/10/13 Conform signed zero to IEEEE 754 (2008).\r\n\r\n####2.4.0\r\n\r\n* 19/09/13 Throw instances of `Error`.\r\n\r\n####2.3.0\r\n\r\n* 16/09/13 Added `cmp` method.\r\n\r\n####2.2.0\r\n\r\n* 11/07/13 Added 'round up' mode.\r\n\r\n####2.1.0\r\n\r\n* 26/06/13 Allow e.g. `.1` and `2.`.\r\n\r\n####2.0.0\r\n\r\n* 12/05/13 Added `abs` method and replaced `cmp` with `eq`, `gt`, `gte`, `lt`, and `lte` methods.\r\n\r\n####1.0.1\r\n\r\n* Changed default value of MAX_DP to 1E6\r\n\r\n####1.0.0\r\n\r\n* 7/11/2012 Initial release\r\n", - "readmeFilename": "README.md", - "homepage": "https://github.com/MikeMcl/big.js#readme", - "_id": "big.js@3.2.0", - "_requested": { - "type": "version", - "registry": true, - "raw": "big.js@3.2.0", - "name": "big.js", - "escapedName": "big.js", - "rawSpec": "3.2.0", - "saveSpec": "[Circular]", - "fetchSpec": "3.2.0" - }, - "_spec": "3.2.0", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "big.js@3.2.0", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "dependencies": {}, - "devDependencies": {}, - "optionalDependencies": {}, - "_dependencies": {}, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/big.js", - "error": "[Circular]", - "extraneous": false - }, - "emojis-list": { - "name": "emojis-list", - "description": "Complete list of standard emojis.", - "homepage": "https://github.com/Kikobeats/emojis-list", - "version": "2.1.0", - "main": "./index.js", - "author": { - "name": "Kiko Beats", - "email": "josefrancisco.verdu@gmail.com", - "url": "https://github.com/Kikobeats" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/kikobeats/emojis-list.git" - }, - "bugs": { - "url": "https://github.com/Kikobeats/emojis-list/issues" - }, - "keywords": [ - "archive", - "complete", - "emoji", - "list", - "standard" - ], - "devDependencies": { - "acho": "latest", - "browserify": "latest", - "cheerio": "latest", - "got": ">=5 <6", - "gulp": "latest", - "gulp-header": "latest", - "gulp-uglify": "latest", - "gulp-util": "latest", - "standard": "latest", - "vinyl-buffer": "latest", - "vinyl-source-stream": "latest" - }, - "engines": { - "node": ">= 0.10" - }, - "files": [ - "index.js" - ], - "scripts": { - "pretest": "standard update.js", - "test": "echo 'YOLO'", - "update": "node update" - }, - "license": "MIT", - "_resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", - "_integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", - "_from": "emojis-list@2.1.0", - "readme": "# emojis-list\n\n[![Dependency status](http://img.shields.io/david/Kikobeats/emojis-list.svg?style=flat-square)](https://david-dm.org/Kikobeats/emojis-list)\n[![Dev Dependencies Status](http://img.shields.io/david/dev/Kikobeats/emojis-list.svg?style=flat-square)](https://david-dm.org/Kikobeats/emojis-list#info=devDependencies)\n[![NPM Status](http://img.shields.io/npm/dm/emojis-list.svg?style=flat-square)](https://www.npmjs.org/package/emojis-list)\n[![Donate](https://img.shields.io/badge/donate-paypal-blue.svg?style=flat-square)](https://paypal.me/kikobeats)\n\n> Complete list of standard Unicode Hex Character Code that represent emojis.\n\n**NOTE**: The lists is related with the Unicode Hex Character Code. The representation of the emoji depend of the system. Will be possible that the system don't have all the representations.\n\n## Install\n\n```bash\nnpm install emojis-list --save\n```\n\nIf you want to use in the browser (powered by [Browserify](http://browserify.org/)):\n\n```bash\nbower install emojis-list --save\n```\n\nand later link in your HTML:\n\n```html\n\n```\n\n## Usage\n\n```\nvar emojis = require('emojis-list');\nconsole.log(emojis[0]);\n// => 🀄\n```\n\n## Related\n\n* [emojis-unicode](https://github.com/Kikobeats/emojis-unicode) – Complete list of standard Unicode codes that represent emojis.\n* [emojis-keywords](https://github.com/Kikobeats/emojis-keywords) – Complete list of am emoji shortcuts.\n* [is-emoji-keyword](https://github.com/Kikobeats/is-emoji-keyword) – Check if a word is a emoji shortcut.\n* [is-standard-emoji](https://github.com/kikobeats/is-standard-emoji) – Simply way to check if a emoji is a standard emoji.\n* [trim-emoji](https://github.com/Kikobeats/trim-emoji) – Deletes ':' from the begin and the end of an emoji shortcut.\n\n## License\n\nMIT © [Kiko Beats](http://www.kikobeats.com)\n", - "readmeFilename": "README.md", - "_id": "emojis-list@2.1.0", - "_requested": { - "type": "version", - "registry": true, - "raw": "emojis-list@2.1.0", - "name": "emojis-list", - "escapedName": "emojis-list", - "rawSpec": "2.1.0", - "saveSpec": "[Circular]", - "fetchSpec": "2.1.0" - }, - "_spec": "2.1.0", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "emojis-list@2.1.0", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "dependencies": {}, - "optionalDependencies": {}, - "_dependencies": {}, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/emojis-list", - "error": "[Circular]", - "extraneous": false - }, - "json5": { - "name": "json5", - "version": "0.5.1", - "description": "JSON for the ES5 era.", - "keywords": [ - "json", - "es5" - ], - "author": { - "name": "Aseem Kishore", - "email": "aseem.kishore@gmail.com" - }, - "contributors": [ - { - "name": "Max Nanasy", - "email": "max.nanasy@gmail.com" - }, - { - "name": "Andrew Eisenberg", - "email": "andrew@eisenberg.as" - }, - { - "name": "Jordan Tucker", - "email": "jordanbtucker@gmail.com" - } - ], - "main": "lib/json5.js", - "bin": { - "json5": "lib/cli.js" - }, - "files": [ - "lib/" - ], - "dependencies": {}, - "devDependencies": { - "gulp": "^3.9.1", - "gulp-jshint": "^2.0.1", - "jshint": "^2.9.3", - "jshint-stylish": "^2.2.1", - "mocha": "^3.1.0" - }, - "scripts": { - "build": "node ./lib/cli.js -c package.json5", - "test": "mocha --ui exports --reporter spec" - }, - "homepage": "http://json5.org/", - "license": "MIT", - "repository": { - "type": "git", - "url": "git+https://github.com/aseemk/json5.git" - }, - "_resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "_integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", - "_from": "json5@0.5.1", - "readme": "# JSON5 – Modern JSON\n\n[![Build Status](https://travis-ci.org/json5/json5.svg)](https://travis-ci.org/json5/json5)\n\nJSON is an excellent data format, but we think it can be better.\n\n**JSON5 is a proposed extension to JSON** that aims to make it easier for\n*humans to write and maintain* by hand. It does this by adding some minimal\nsyntax features directly from ECMAScript 5.\n\nJSON5 remains a **strict subset of JavaScript**, adds **no new data types**,\nand **works with all existing JSON content**.\n\nJSON5 is *not* an official successor to JSON, and JSON5 content may *not*\nwork with existing JSON parsers. For this reason, JSON5 files use a new .json5\nextension. *(TODO: new MIME type needed too.)*\n\nThe code here is a **reference JavaScript implementation** for both Node.js\nand all browsers. It’s based directly off of Douglas Crockford’s own [JSON\nimplementation][json_parse.js], and it’s both robust and secure.\n\n\n## Why\n\nJSON isn’t the friendliest to *write*. Keys need to be quoted, objects and\narrays can’t have trailing commas, and comments aren’t allowed — even though\nnone of these are the case with regular JavaScript today.\n\nThat was fine when JSON’s goal was to be a great data format, but JSON’s usage\nhas expanded beyond *machines*. JSON is now used for writing [configs][ex1],\n[manifests][ex2], even [tests][ex3] — all by *humans*.\n\n[ex1]: http://plovr.com/docs.html\n[ex2]: https://www.npmjs.org/doc/files/package.json.html\n[ex3]: http://code.google.com/p/fuzztester/wiki/JSONFileFormat\n\nThere are other formats that are human-friendlier, like YAML, but changing\nfrom JSON to a completely different format is undesirable in many cases.\nJSON5’s aim is to remain close to JSON and JavaScript.\n\n\n## Features\n\nThe following is the exact list of additions to JSON’s syntax introduced by\nJSON5. **All of these are optional**, and **all of these come from ES5**.\n\n### Objects\n\n- Object keys can be unquoted if they’re valid [identifiers][mdn_variables].\n Yes, even reserved keywords (like `default`) are valid unquoted keys in ES5\n [[§11.1.5](http://es5.github.com/#x11.1.5), [§7.6](http://es5.github.com/#x7.6)].\n ([More info](https://mathiasbynens.be/notes/javascript-identifiers))\n\n *(TODO: Unicode characters and escape sequences aren’t yet supported in this\n implementation.)*\n \n- Object keys can also be single-quoted.\n\n- Objects can have trailing commas.\n\n[mdn_variables]: https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Core_Language_Features#Variables\n\n### Arrays\n\n- Arrays can have trailing commas.\n\n### Strings\n\n- Strings can be single-quoted.\n\n- Strings can be split across multiple lines; just prefix each newline with a\n backslash. [ES5 [§7.8.4](http://es5.github.com/#x7.8.4)]\n\n### Numbers\n\n- Numbers can be hexadecimal (base 16).\n\n- Numbers can begin or end with a (leading or trailing) decimal point.\n\n- Numbers can include `Infinity`, `-Infinity`, `NaN`, and `-NaN`.\n\n- Numbers can begin with an explicit plus sign.\n\n### Comments\n\n- Both inline (single-line) and block (multi-line) comments are allowed.\n\n\n## Example\n\nThe following is a contrived example, but it illustrates most of the features:\n\n```js\n{\n foo: 'bar',\n while: true,\n\n this: 'is a \\\nmulti-line string',\n\n // this is an inline comment\n here: 'is another', // inline comment\n\n /* this is a block comment\n that continues on another line */\n\n hex: 0xDEADbeef,\n half: .5,\n delta: +10,\n to: Infinity, // and beyond!\n\n finally: 'a trailing comma',\n oh: [\n \"we shouldn't forget\",\n 'arrays can have',\n 'trailing commas too',\n ],\n}\n```\n\nThis implementation’s own [package.json5](package.json5) is more realistic:\n\n```js\n// This file is written in JSON5 syntax, naturally, but npm needs a regular\n// JSON file, so compile via `npm run build`. Be sure to keep both in sync!\n\n{\n name: 'json5',\n version: '0.5.0',\n description: 'JSON for the ES5 era.',\n keywords: ['json', 'es5'],\n author: 'Aseem Kishore ',\n contributors: [\n // TODO: Should we remove this section in favor of GitHub's list?\n // https://github.com/aseemk/json5/contributors\n 'Max Nanasy ',\n 'Andrew Eisenberg ',\n 'Jordan Tucker ',\n ],\n main: 'lib/json5.js',\n bin: 'lib/cli.js',\n files: [\"lib/\"],\n dependencies: {},\n devDependencies: {\n gulp: \"^3.9.1\",\n 'gulp-jshint': \"^2.0.0\",\n jshint: \"^2.9.1\",\n 'jshint-stylish': \"^2.1.0\",\n mocha: \"^2.4.5\"\n },\n scripts: {\n build: 'node ./lib/cli.js -c package.json5',\n test: 'mocha --ui exports --reporter spec',\n // TODO: Would it be better to define these in a mocha.opts file?\n },\n homepage: 'http://json5.org/',\n license: 'MIT',\n repository: {\n type: 'git',\n url: 'https://github.com/aseemk/json5.git',\n },\n}\n```\n\n\n## Community\n\nJoin the [Google Group](http://groups.google.com/group/json5) if you’re\ninterested in JSON5 news, updates, and general discussion.\nDon’t worry, it’s very low-traffic.\n\nThe [GitHub wiki](https://github.com/aseemk/json5/wiki) is a good place to track\nJSON5 support and usage. Contribute freely there!\n\n[GitHub Issues](https://github.com/aseemk/json5/issues) is the place to\nformally propose feature requests and report bugs. Questions and general\nfeedback are better directed at the Google Group.\n\n\n## Usage\n\nThis JavaScript implementation of JSON5 simply provides a `JSON5` object just\nlike the native ES5 `JSON` object.\n\nTo use from Node:\n\n```sh\nnpm install json5\n```\n\n```js\nvar JSON5 = require('json5');\n```\n\nTo use in the browser (adds the `JSON5` object to the global namespace):\n\n```html\n\n```\n\nThen in both cases, you can simply replace native `JSON` calls with `JSON5`:\n\n```js\nvar obj = JSON5.parse('{unquoted:\"key\",trailing:\"comma\",}');\nvar str = JSON5.stringify(obj);\n```\n\n`JSON5.parse` supports all of the JSON5 features listed above (*TODO: except\nUnicode*), as well as the native [`reviver` argument][json-parse].\n\n[json-parse]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse\n\n`JSON5.stringify` mainly avoids quoting keys where possible, but we hope to\nkeep expanding it in the future (e.g. to also output trailing commas).\nIt supports the native [`replacer` and `space` arguments][json-stringify],\nas well. *(TODO: Any implemented `toJSON` methods aren’t used today.)*\n\n[json-stringify]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify\n\n\n### Extras\n\nIf you’re running this on Node, you can also register a JSON5 `require()` hook\nto let you `require()` `.json5` files just like you can `.json` files:\n\n```js\nrequire('json5/lib/require');\nrequire('./path/to/foo'); // tries foo.json5 after foo.js, foo.json, etc.\nrequire('./path/to/bar.json5');\n```\n\nThis module also provides a `json5` executable (requires Node) for converting\nJSON5 files to JSON:\n\n```sh\njson5 -c path/to/foo.json5 # generates path/to/foo.json\n```\n\n\n## Development\n\n```sh\ngit clone git://github.com/aseemk/json5.git\ncd json5\nnpm install\nnpm test\n```\n\nAs the `package.json5` file states, be sure to run `npm run build` on changes\nto `package.json5`, since npm requires `package.json`.\n\nFeel free to [file issues](https://github.com/aseemk/json5/issues) and submit\n[pull requests](https://github.com/aseemk/json5/pulls) — contributions are\nwelcome. If you do submit a pull request, please be sure to add or update the\ntests, and ensure that `npm test` continues to pass.\n\n\n## License\n\nMIT. See [LICENSE.md](./LICENSE.md) for details.\n\n\n## Credits\n\n[Michael Bolin](http://bolinfest.com/) independently arrived at and published\nsome of these same ideas with awesome explanations and detail.\nRecommended reading:\n[Suggested Improvements to JSON](http://bolinfest.com/essays/json.html)\n\n[Douglas Crockford](http://www.crockford.com/) of course designed and built\nJSON, but his state machine diagrams on the [JSON website](http://json.org/),\nas cheesy as it may sound, gave me motivation and confidence that building a\nnew parser to implement these ideas this was within my reach!\nThis code is also modeled directly off of Doug’s open-source [json_parse.js][]\nparser. I’m super grateful for that clean and well-documented code.\n\n[json_parse.js]: https://github.com/douglascrockford/JSON-js/blob/master/json_parse.js\n\n[Max Nanasy](https://github.com/MaxNanasy) has been an early and prolific\nsupporter, contributing multiple patches and ideas. Thanks Max!\n\n[Andrew Eisenberg](https://github.com/aeisenberg) has contributed the\n`stringify` method.\n\n[Jordan Tucker](https://github.com/jordanbtucker) has aligned JSON5 more closely\nwith ES5 and is actively maintaining this project.\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/aseemk/json5/issues" - }, - "_id": "json5@0.5.1", - "_requested": { - "type": "version", - "registry": true, - "raw": "json5@0.5.1", - "name": "json5", - "escapedName": "json5", - "rawSpec": "0.5.1", - "saveSpec": "[Circular]", - "fetchSpec": "0.5.1" - }, - "_spec": "0.5.1", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "json5@0.5.1", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "optionalDependencies": {}, - "_dependencies": {}, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/json5", - "error": "[Circular]", - "extraneous": false - } - }, - "scripts": { - "test": "mocha", - "posttest": "npm run lint", - "lint": "eslint lib test", - "travis": "npm run cover -- --report lcovonly", - "cover": "istanbul cover -x *.runtime.js node_modules/mocha/bin/_mocha", - "release": "npm test && standard-version" - }, - "license": "MIT", - "repository": { - "type": "git", - "url": "git+https://github.com/webpack/loader-utils.git" - }, - "engines": { - "node": ">=4.0.0" - }, - "devDependencies": { - "coveralls": "^2.11.2", - "eslint": "^3.15.0", - "eslint-plugin-node": "^4.0.1", - "istanbul": "^0.3.14", - "mocha": "^1.21.4", - "standard-version": "^4.0.0" - }, - "main": "lib/index.js", - "files": [ - "lib" - ], - "_resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz", - "_integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=", - "_from": "loader-utils@1.1.0", - "readme": "# loader-utils\n\n## Methods\n\n### `getOptions`\n\nRecommended way to retrieve the options of a loader invocation:\n\n```javascript\n// inside your loader\nconst options = loaderUtils.getOptions(this);\n```\n\n1. If `this.query` is a string:\n\t- Tries to parse the query string and returns a new object\n\t- Throws if it's not a valid query string\n2. If `this.query` is object-like, it just returns `this.query`\n3. In any other case, it just returns `null`\n\n**Please note:** The returned `options` object is *read-only*. It may be re-used across multiple invocations.\nIf you pass it on to another library, make sure to make a *deep copy* of it:\n\n```javascript\nconst options = Object.assign(\n\t{},\n\tloaderUtils.getOptions(this), // it is safe to pass null to Object.assign()\n\tdefaultOptions\n);\n// don't forget nested objects or arrays\noptions.obj = Object.assign({}, options.obj); \noptions.arr = options.arr.slice();\nsomeLibrary(options);\n```\n\n[clone-deep](https://www.npmjs.com/package/clone-deep) is a good library to make a deep copy of the options.\n\n#### Options as query strings\n\nIf the loader options have been passed as loader query string (`loader?some¶ms`), the string is parsed by using [`parseQuery`](#parsequery).\n\n### `parseQuery`\n\nParses a passed string (e.g. `loaderContext.resourceQuery`) as a query string, and returns an object.\n\n``` javascript\nconst params = loaderUtils.parseQuery(this.resourceQuery); // resource: `file?param1=foo`\nif (params.param1 === \"foo\") {\n\t// do something\n}\n```\n\nThe string is parsed like this:\n\n``` text\n -> Error\n? -> {}\n?flag -> { flag: true }\n?+flag -> { flag: true }\n?-flag -> { flag: false }\n?xyz=test -> { xyz: \"test\" }\n?xyz=1 -> { xyz: \"1\" } // numbers are NOT parsed\n?xyz[]=a -> { xyz: [\"a\"] }\n?flag1&flag2 -> { flag1: true, flag2: true }\n?+flag1,-flag2 -> { flag1: true, flag2: false }\n?xyz[]=a,xyz[]=b -> { xyz: [\"a\", \"b\"] }\n?a%2C%26b=c%2C%26d -> { \"a,&b\": \"c,&d\" }\n?{data:{a:1},isJSON5:true} -> { data: { a: 1 }, isJSON5: true }\n```\n\n### `stringifyRequest`\n\nTurns a request into a string that can be used inside `require()` or `import` while avoiding absolute paths.\nUse it instead of `JSON.stringify(...)` if you're generating code inside a loader.\n\n**Why is this necessary?** Since webpack calculates the hash before module paths are translated into module ids, we must avoid absolute paths to ensure\nconsistent hashes across different compilations.\n\nThis function:\n\n- resolves absolute requests into relative requests if the request and the module are on the same hard drive\n- replaces `\\` with `/` if the request and the module are on the same hard drive\n- won't change the path at all if the request and the module are on different hard drives\n- applies `JSON.stringify` to the result\n\n```javascript\nloaderUtils.stringifyRequest(this, \"./test.js\");\n// \"\\\"./test.js\\\"\"\n\nloaderUtils.stringifyRequest(this, \".\\\\test.js\");\n// \"\\\"./test.js\\\"\"\n\nloaderUtils.stringifyRequest(this, \"test\");\n// \"\\\"test\\\"\"\n\nloaderUtils.stringifyRequest(this, \"test/lib/index.js\");\n// \"\\\"test/lib/index.js\\\"\"\n\nloaderUtils.stringifyRequest(this, \"otherLoader?andConfig!test?someConfig\");\n// \"\\\"otherLoader?andConfig!test?someConfig\\\"\"\n\nloaderUtils.stringifyRequest(this, require.resolve(\"test\"));\n// \"\\\"../node_modules/some-loader/lib/test.js\\\"\"\n\nloaderUtils.stringifyRequest(this, \"C:\\\\module\\\\test.js\");\n// \"\\\"../../test.js\\\"\" (on Windows, in case the module and the request are on the same drive)\n\nloaderUtils.stringifyRequest(this, \"C:\\\\module\\\\test.js\");\n// \"\\\"C:\\\\module\\\\test.js\\\"\" (on Windows, in case the module and the request are on different drives)\n\nloaderUtils.stringifyRequest(this, \"\\\\\\\\network-drive\\\\test.js\");\n// \"\\\"\\\\\\\\network-drive\\\\\\\\test.js\\\"\" (on Windows, in case the module and the request are on different drives)\n```\n\n### `urlToRequest`\n\nConverts some resource URL to a webpack module request.\n\n```javascript\nconst url = \"path/to/module.js\";\nconst request = loaderUtils.urlToRequest(url); // \"./path/to/module.js\"\n```\n\n#### Module URLs\n\nAny URL containing a `~` will be interpreted as a module request. Anything after the `~` will be considered the request path.\n\n```javascript\nconst url = \"~path/to/module.js\";\nconst request = loaderUtils.urlToRequest(url); // \"path/to/module.js\"\n```\n\n#### Root-relative URLs\n\nURLs that are root-relative (start with `/`) can be resolved relative to some arbitrary path by using the `root` parameter:\n\n```javascript\nconst url = \"/path/to/module.js\";\nconst root = \"./root\";\nconst request = loaderUtils.urlToRequest(url, root); // \"./root/path/to/module.js\"\n```\n\nTo convert a root-relative URL into a module URL, specify a `root` value that starts with `~`:\n\n```javascript\nconst url = \"/path/to/module.js\";\nconst root = \"~\";\nconst request = loaderUtils.urlToRequest(url, root); // \"path/to/module.js\"\n```\n\n### `interpolateName`\n\nInterpolates a filename template using multiple placeholders and/or a regular expression.\nThe template and regular expression are set as query params called `name` and `regExp` on the current loader's context.\n\n```javascript\nconst interpolatedName = loaderUtils.interpolateName(loaderContext, name, options);\n```\n\nThe following tokens are replaced in the `name` parameter:\n\n* `[ext]` the extension of the resource\n* `[name]` the basename of the resource\n* `[path]` the path of the resource relative to the `context` query parameter or option.\n* `[folder]` the folder of the resource is in.\n* `[emoji]` a random emoji representation of `options.content`\n* `[emoji:]` same as above, but with a customizable number of emojis\n* `[hash]` the hash of `options.content` (Buffer) (by default it's the hex digest of the md5 hash)\n* `[:hash::]` optionally one can configure\n * other `hashType`s, i. e. `sha1`, `md5`, `sha256`, `sha512`\n * other `digestType`s, i. e. `hex`, `base26`, `base32`, `base36`, `base49`, `base52`, `base58`, `base62`, `base64`\n * and `length` the length in chars\n* `[N]` the N-th match obtained from matching the current file name against `options.regExp`\n\nExamples\n\n``` javascript\n// loaderContext.resourcePath = \"/app/js/javascript.js\"\nloaderUtils.interpolateName(loaderContext, \"js/[hash].script.[ext]\", { content: ... });\n// => js/9473fdd0d880a43c21b7778d34872157.script.js\n\n// loaderContext.resourcePath = \"/app/page.html\"\nloaderUtils.interpolateName(loaderContext, \"html-[hash:6].html\", { content: ... });\n// => html-9473fd.html\n\n// loaderContext.resourcePath = \"/app/flash.txt\"\nloaderUtils.interpolateName(loaderContext, \"[hash]\", { content: ... });\n// => c31e9820c001c9c4a86bce33ce43b679\n\n// loaderContext.resourcePath = \"/app/img/image.gif\"\nloaderUtils.interpolateName(loaderContext, \"[emoji]\", { content: ... });\n// => 👍\n\n// loaderContext.resourcePath = \"/app/img/image.gif\"\nloaderUtils.interpolateName(loaderContext, \"[emoji:4]\", { content: ... });\n// => 🙍🏢📤🐝\n\n// loaderContext.resourcePath = \"/app/img/image.png\"\nloaderUtils.interpolateName(loaderContext, \"[sha512:hash:base64:7].[ext]\", { content: ... });\n// => 2BKDTjl.png\n// use sha512 hash instead of md5 and with only 7 chars of base64\n\n// loaderContext.resourcePath = \"/app/img/myself.png\"\n// loaderContext.query.name =\nloaderUtils.interpolateName(loaderContext, \"picture.png\");\n// => picture.png\n\n// loaderContext.resourcePath = \"/app/dir/file.png\"\nloaderUtils.interpolateName(loaderContext, \"[path][name].[ext]?[hash]\", { content: ... });\n// => /app/dir/file.png?9473fdd0d880a43c21b7778d34872157\n\n// loaderContext.resourcePath = \"/app/js/page-home.js\"\nloaderUtils.interpolateName(loaderContext, \"script-[1].[ext]\", { regExp: \"page-(.*)\\\\.js\", content: ... });\n// => script-home.js\n```\n\n### `getHashDigest`\n\n``` javascript\nconst digestString = loaderUtils.getHashDigest(buffer, hashType, digestType, maxLength);\n```\n\n* `buffer` the content that should be hashed\n* `hashType` one of `sha1`, `md5`, `sha256`, `sha512` or any other node.js supported hash type\n* `digestType` one of `hex`, `base26`, `base32`, `base36`, `base49`, `base52`, `base58`, `base62`, `base64`\n* `maxLength` the maximum length in chars\n\n## License\n\nMIT (http://www.opensource.org/licenses/mit-license.php)\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/webpack/loader-utils/issues" - }, - "homepage": "https://github.com/webpack/loader-utils#readme", - "_id": "loader-utils@1.1.0", - "_requested": { - "type": "version", - "registry": true, - "raw": "loader-utils@1.1.0", - "name": "loader-utils", - "escapedName": "loader-utils", - "rawSpec": "1.1.0", - "saveSpec": "[Circular]", - "fetchSpec": "1.1.0" - }, - "_spec": "1.1.0", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "loader-utils@1.1.0", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "optionalDependencies": {}, - "_dependencies": { - "big.js": "^3.1.3", - "emojis-list": "^2.0.0", - "json5": "^0.5.0" - }, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/loader-utils", - "error": "[Circular]", - "extraneous": false - }, - "schema-utils": { - "name": "schema-utils", - "version": "0.4.5", - "author": { - "name": "Webpack Contrib", - "url": "https://github.com/webpack-contrib" - }, - "description": "Webpack Schema Validation Utilities", - "license": "MIT", - "main": "dist/cjs.js", - "files": [ - "dist" - ], - "scripts": { - "start": "npm run build -- -w", - "build": "cross-env NODE_ENV=production babel src -d dist --ignore 'src/**/*.test.js' --copy-files", - "clean": "del-cli dist", - "commitlint": "commitlint", - "commitmsg": "commitlint -e $GIT_PARAMS", - "lint": "eslint --cache src test", - "ci:lint:commits": "commitlint --from=${CIRCLE_BRANCH} --to=${CIRCLE_SHA1}", - "lint-staged": "lint-staged", - "prebuild": "npm run clean", - "prepare": "npm run build", - "release": "standard-version", - "release:ci": "conventional-github-releaser -p angular", - "release:validate": "commitlint --from=$(git describe --tags --abbrev=0) --to=$(git rev-parse HEAD)", - "security": "nsp check", - "test": "jest", - "test:watch": "jest --watch", - "test:coverage": "jest --collectCoverageFrom='src/**/*.js' --coverage", - "ci:lint": "npm run lint && npm run security", - "ci:test": "npm run test -- --runInBand", - "ci:coverage": "npm run test:coverage -- --runInBand", - "defaults": "webpack-defaults" - }, - "dependencies": { - "ajv": { - "name": "ajv", - "version": "6.5.2", - "description": "Another JSON Schema Validator", - "main": "lib/ajv.js", - "typings": "lib/ajv.d.ts", - "files": [ - "lib/", - "dist/", - "scripts/", - "LICENSE", - ".tonic_example.js" - ], - "scripts": { - "eslint": "eslint lib/*.js lib/compile/*.js spec/*.js scripts", - "jshint": "jshint lib/*.js lib/**/*.js --exclude lib/dotjs/**/*", - "test-spec": "mocha spec/*.spec.js -R spec", - "test-fast": "AJV_FAST_TEST=true npm run test-spec", - "test-debug": "mocha spec/*.spec.js --debug-brk -R spec", - "test-cov": "nyc npm run test-spec", - "test-ts": "tsc --target ES5 --noImplicitAny lib/ajv.d.ts", - "bundle": "del-cli dist && node ./scripts/bundle.js . Ajv pure_getters", - "bundle-beautify": "node ./scripts/bundle.js js-beautify", - "build": "del-cli lib/dotjs/*.js '!lib/dotjs/index.js' && node scripts/compile-dots.js", - "test-karma": "karma start --single-run --browsers PhantomJS", - "test-browser": "del-cli .browser && npm run bundle && scripts/prepare-tests && npm run test-karma", - "test": "npm run jshint && npm run eslint && npm run test-ts && npm run build && npm run test-cov && if-node-version 8 npm run test-browser", - "prepublish": "npm run build && npm run bundle", - "watch": "watch 'npm run build' ./lib/dot" - }, - "nyc": { - "exclude": [ - "**/spec/**", - "node_modules" - ], - "reporter": [ - "lcov", - "text-summary" - ] - }, - "repository": { - "type": "git", - "url": "git+https://github.com/epoberezkin/ajv.git" - }, - "keywords": [ - "JSON", - "schema", - "validator", - "validation", - "jsonschema", - "json-schema", - "json-schema-validator", - "json-schema-validation" - ], - "author": { - "name": "Evgeny Poberezkin" - }, - "license": "MIT", - "bugs": { - "url": "https://github.com/epoberezkin/ajv/issues" - }, - "homepage": "https://github.com/epoberezkin/ajv", - "tonicExampleFilename": ".tonic_example.js", - "dependencies": { - "fast-deep-equal": { - "name": "fast-deep-equal", - "version": "2.0.1", - "description": "Fast deep equal", - "main": "index.js", - "scripts": { - "eslint": "eslint *.js benchmark spec", - "test-spec": "mocha spec/*.spec.js -R spec", - "test-cov": "nyc npm run test-spec", - "test-ts": "tsc --target ES5 --noImplicitAny index.d.ts", - "test": "npm run eslint && npm run test-ts && npm run test-cov" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/epoberezkin/fast-deep-equal.git" - }, - "keywords": [ - "fast", - "equal", - "deep-equal" - ], - "author": { - "name": "Evgeny Poberezkin" - }, - "license": "MIT", - "bugs": { - "url": "https://github.com/epoberezkin/fast-deep-equal/issues" - }, - "homepage": "https://github.com/epoberezkin/fast-deep-equal#readme", - "devDependencies": { - "benchmark": "^2.1.4", - "coveralls": "^2.13.1", - "deep-eql": "latest", - "deep-equal": "latest", - "eslint": "^4.0.0", - "lodash": "latest", - "mocha": "^3.4.2", - "nano-equal": "latest", - "nyc": "^11.0.2", - "pre-commit": "^1.2.2", - "ramda": "latest", - "shallow-equal-fuzzy": "latest", - "typescript": "^2.6.1", - "underscore": "latest" - }, - "nyc": { - "exclude": [ - "**/spec/**", - "node_modules" - ], - "reporter": [ - "lcov", - "text-summary" - ] - }, - "files": [ - "index.js", - "index.d.ts" - ], - "types": "index.d.ts", - "_resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "_integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", - "_from": "fast-deep-equal@2.0.1", - "readme": "# fast-deep-equal\nThe fastest deep equal\n\n[![Build Status](https://travis-ci.org/epoberezkin/fast-deep-equal.svg?branch=master)](https://travis-ci.org/epoberezkin/fast-deep-equal)\n[![npm version](https://badge.fury.io/js/fast-deep-equal.svg)](http://badge.fury.io/js/fast-deep-equal)\n[![Coverage Status](https://coveralls.io/repos/github/epoberezkin/fast-deep-equal/badge.svg?branch=master)](https://coveralls.io/github/epoberezkin/fast-deep-equal?branch=master)\n\n\n## Install\n\n```bash\nnpm install fast-deep-equal\n```\n\n\n## Features\n\n- ES5 compatible\n- works in node.js (0.10+) and browsers (IE9+)\n- checks equality of Date and RegExp objects by value.\n\n\n## Usage\n\n```javascript\nvar equal = require('fast-deep-equal');\nconsole.log(equal({foo: 'bar'}, {foo: 'bar'})); // true\n```\n\n\n## Performance benchmark\n\nNode.js v9.11.1:\n\n```\nfast-deep-equal x 226,960 ops/sec ±1.55% (86 runs sampled)\nnano-equal x 218,210 ops/sec ±0.79% (89 runs sampled)\nshallow-equal-fuzzy x 206,762 ops/sec ±0.84% (88 runs sampled)\nunderscore.isEqual x 128,668 ops/sec ±0.75% (91 runs sampled)\nlodash.isEqual x 44,895 ops/sec ±0.67% (85 runs sampled)\ndeep-equal x 51,616 ops/sec ±0.96% (90 runs sampled)\ndeep-eql x 28,218 ops/sec ±0.42% (85 runs sampled)\nassert.deepStrictEqual x 1,777 ops/sec ±1.05% (86 runs sampled)\nramda.equals x 13,466 ops/sec ±0.82% (86 runs sampled)\nThe fastest is fast-deep-equal\n```\n\nTo run benchmark (requires node.js 6+):\n\n```bash\nnpm install\nnode benchmark\n```\n\n\n## License\n\n[MIT](https://github.com/epoberezkin/fast-deep-equal/blob/master/LICENSE)\n", - "readmeFilename": "README.md", - "_id": "fast-deep-equal@2.0.1", - "_requested": { - "type": "version", - "registry": true, - "raw": "fast-deep-equal@2.0.1", - "name": "fast-deep-equal", - "escapedName": "fast-deep-equal", - "rawSpec": "2.0.1", - "saveSpec": "[Circular]", - "fetchSpec": "2.0.1" - }, - "_spec": "2.0.1", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "fast-deep-equal@2.0.1", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "dependencies": {}, - "optionalDependencies": {}, - "_dependencies": {}, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/fast-deep-equal", - "error": "[Circular]", - "extraneous": false - }, - "fast-json-stable-stringify": { - "name": "fast-json-stable-stringify", - "version": "2.0.0", - "description": "deterministic `JSON.stringify()` - a faster version of substack's json-stable-strigify without jsonify", - "main": "index.js", - "devDependencies": { - "benchmark": "^2.1.4", - "coveralls": "^3.0.0", - "eslint": "^4.9.0", - "fast-stable-stringify": "latest", - "faster-stable-stringify": "latest", - "json-stable-stringify": "latest", - "nyc": "^11.2.1", - "pre-commit": "^1.2.2", - "tape": "~1.0.4" - }, - "scripts": { - "eslint": "eslint index.js test", - "test-spec": "tape test/*.js", - "test": "npm run eslint && nyc npm run test-spec" - }, - "repository": { - "type": "git", - "url": "git://github.com/epoberezkin/fast-json-stable-stringify.git" - }, - "homepage": "https://github.com/epoberezkin/fast-json-stable-stringify", - "keywords": [ - "json", - "stringify", - "deterministic", - "hash", - "stable" - ], - "author": { - "name": "James Halliday", - "email": "mail@substack.net", - "url": "http://substack.net" - }, - "license": "MIT", - "nyc": { - "exclude": [ - "test", - "node_modules" - ], - "reporter": [ - "lcov", - "text-summary" - ] - }, - "_resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "_integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", - "_from": "fast-json-stable-stringify@2.0.0", - "readme": "# fast-json-stable-stringify\n\nDeterministic `JSON.stringify()` - a faster version of [@substack](https://github.com/substack)'s json-stable-strigify without [jsonify](https://github.com/substack/jsonify).\n\nYou can also pass in a custom comparison function.\n\n[![Build Status](https://travis-ci.org/epoberezkin/fast-json-stable-stringify.svg?branch=master)](https://travis-ci.org/epoberezkin/fast-json-stable-stringify)\n[![Coverage Status](https://coveralls.io/repos/github/epoberezkin/fast-json-stable-stringify/badge.svg?branch=master)](https://coveralls.io/github/epoberezkin/fast-json-stable-stringify?branch=master)\n\n# example\n\n``` js\nvar stringify = require('fast-json-stable-stringify');\nvar obj = { c: 8, b: [{z:6,y:5,x:4},7], a: 3 };\nconsole.log(stringify(obj));\n```\n\noutput:\n\n```\n{\"a\":3,\"b\":[{\"x\":4,\"y\":5,\"z\":6},7],\"c\":8}\n```\n\n\n# methods\n\n``` js\nvar stringify = require('fast-json-stable-stringify')\n```\n\n## var str = stringify(obj, opts)\n\nReturn a deterministic stringified string `str` from the object `obj`.\n\n\n## options\n\n### cmp\n\nIf `opts` is given, you can supply an `opts.cmp` to have a custom comparison\nfunction for object keys. Your function `opts.cmp` is called with these\nparameters:\n\n``` js\nopts.cmp({ key: akey, value: avalue }, { key: bkey, value: bvalue })\n```\n\nFor example, to sort on the object key names in reverse order you could write:\n\n``` js\nvar stringify = require('fast-json-stable-stringify');\n\nvar obj = { c: 8, b: [{z:6,y:5,x:4},7], a: 3 };\nvar s = stringify(obj, function (a, b) {\n return a.key < b.key ? 1 : -1;\n});\nconsole.log(s);\n```\n\nwhich results in the output string:\n\n```\n{\"c\":8,\"b\":[{\"z\":6,\"y\":5,\"x\":4},7],\"a\":3}\n```\n\nOr if you wanted to sort on the object values in reverse order, you could write:\n\n```\nvar stringify = require('fast-json-stable-stringify');\n\nvar obj = { d: 6, c: 5, b: [{z:3,y:2,x:1},9], a: 10 };\nvar s = stringify(obj, function (a, b) {\n return a.value < b.value ? 1 : -1;\n});\nconsole.log(s);\n```\n\nwhich outputs:\n\n```\n{\"d\":6,\"c\":5,\"b\":[{\"z\":3,\"y\":2,\"x\":1},9],\"a\":10}\n```\n\n### cycles\n\nPass `true` in `opts.cycles` to stringify circular property as `__cycle__` - the result will not be a valid JSON string in this case.\n\nTypeError will be thrown in case of circular object without this option.\n\n\n# install\n\nWith [npm](https://npmjs.org) do:\n\n```\nnpm install fast-json-stable-stringify\n```\n\n\n# benchmark\n\nTo run benchmark (requires Node.js 6+):\n```\nnode benchmark\n```\n\nResults:\n```\nfast-json-stable-stringify x 17,189 ops/sec ±1.43% (83 runs sampled)\njson-stable-stringify x 13,634 ops/sec ±1.39% (85 runs sampled)\nfast-stable-stringify x 20,212 ops/sec ±1.20% (84 runs sampled)\nfaster-stable-stringify x 15,549 ops/sec ±1.12% (84 runs sampled)\nThe fastest is fast-stable-stringify\n```\n\n\n# license\n\n[MIT](https://github.com/epoberezkin/fast-json-stable-stringify/blob/master/LICENSE)\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/epoberezkin/fast-json-stable-stringify/issues" - }, - "_id": "fast-json-stable-stringify@2.0.0", - "_requested": { - "type": "version", - "registry": true, - "raw": "fast-json-stable-stringify@2.0.0", - "name": "fast-json-stable-stringify", - "escapedName": "fast-json-stable-stringify", - "rawSpec": "2.0.0", - "saveSpec": "[Circular]", - "fetchSpec": "2.0.0" - }, - "_spec": "2.0.0", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "fast-json-stable-stringify@2.0.0", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "dependencies": {}, - "optionalDependencies": {}, - "_dependencies": {}, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/fast-json-stable-stringify", - "error": "[Circular]", - "extraneous": false - }, - "json-schema-traverse": { - "name": "json-schema-traverse", - "version": "0.4.1", - "description": "Traverse JSON Schema passing each schema object to callback", - "main": "index.js", - "scripts": { - "eslint": "eslint index.js spec", - "test-spec": "mocha spec -R spec", - "test": "npm run eslint && nyc npm run test-spec" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/epoberezkin/json-schema-traverse.git" - }, - "keywords": [ - "JSON-Schema", - "traverse", - "iterate" - ], - "author": { - "name": "Evgeny Poberezkin" - }, - "license": "MIT", - "bugs": { - "url": "https://github.com/epoberezkin/json-schema-traverse/issues" - }, - "homepage": "https://github.com/epoberezkin/json-schema-traverse#readme", - "devDependencies": { - "coveralls": "^2.13.1", - "eslint": "^3.19.0", - "mocha": "^3.4.2", - "nyc": "^11.0.2", - "pre-commit": "^1.2.2" - }, - "nyc": { - "exclude": [ - "**/spec/**", - "node_modules" - ], - "reporter": [ - "lcov", - "text-summary" - ] - }, - "_resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "_integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "_from": "json-schema-traverse@0.4.1", - "readme": "# json-schema-traverse\nTraverse JSON Schema passing each schema object to callback\n\n[![Build Status](https://travis-ci.org/epoberezkin/json-schema-traverse.svg?branch=master)](https://travis-ci.org/epoberezkin/json-schema-traverse)\n[![npm version](https://badge.fury.io/js/json-schema-traverse.svg)](https://www.npmjs.com/package/json-schema-traverse)\n[![Coverage Status](https://coveralls.io/repos/github/epoberezkin/json-schema-traverse/badge.svg?branch=master)](https://coveralls.io/github/epoberezkin/json-schema-traverse?branch=master)\n\n\n## Install\n\n```\nnpm install json-schema-traverse\n```\n\n\n## Usage\n\n```javascript\nconst traverse = require('json-schema-traverse');\nconst schema = {\n properties: {\n foo: {type: 'string'},\n bar: {type: 'integer'}\n }\n};\n\ntraverse(schema, {cb});\n// cb is called 3 times with:\n// 1. root schema\n// 2. {type: 'string'}\n// 3. {type: 'integer'}\n\n// Or:\n\ntraverse(schema, {cb: {pre, post}});\n// pre is called 3 times with:\n// 1. root schema\n// 2. {type: 'string'}\n// 3. {type: 'integer'}\n//\n// post is called 3 times with:\n// 1. {type: 'string'}\n// 2. {type: 'integer'}\n// 3. root schema\n\n```\n\nCallback function `cb` is called for each schema object (not including draft-06 boolean schemas), including the root schema, in pre-order traversal. Schema references ($ref) are not resolved, they are passed as is. Alternatively, you can pass a `{pre, post}` object as `cb`, and then `pre` will be called before traversing child elements, and `post` will be called after all child elements have been traversed.\n\nCallback is passed these parameters:\n\n- _schema_: the current schema object\n- _JSON pointer_: from the root schema to the current schema object\n- _root schema_: the schema passed to `traverse` object\n- _parent JSON pointer_: from the root schema to the parent schema object (see below)\n- _parent keyword_: the keyword inside which this schema appears (e.g. `properties`, `anyOf`, etc.)\n- _parent schema_: not necessarily parent object/array; in the example above the parent schema for `{type: 'string'}` is the root schema\n- _index/property_: index or property name in the array/object containing multiple schemas; in the example above for `{type: 'string'}` the property name is `'foo'`\n\n\n## Traverse objects in all unknown keywords\n\n```javascript\nconst traverse = require('json-schema-traverse');\nconst schema = {\n mySchema: {\n minimum: 1,\n maximum: 2\n }\n};\n\ntraverse(schema, {allKeys: true, cb});\n// cb is called 2 times with:\n// 1. root schema\n// 2. mySchema\n```\n\nWithout option `allKeys: true` callback will be called only with root schema.\n\n\n## License\n\n[MIT](https://github.com/epoberezkin/json-schema-traverse/blob/master/LICENSE)\n", - "readmeFilename": "README.md", - "_id": "json-schema-traverse@0.4.1", - "_requested": { - "type": "version", - "registry": true, - "raw": "json-schema-traverse@0.4.1", - "name": "json-schema-traverse", - "escapedName": "json-schema-traverse", - "rawSpec": "0.4.1", - "saveSpec": "[Circular]", - "fetchSpec": "0.4.1" - }, - "_spec": "0.4.1", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "json-schema-traverse@0.4.1", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "dependencies": {}, - "optionalDependencies": {}, - "_dependencies": {}, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/json-schema-traverse", - "error": "[Circular]", - "extraneous": false - }, - "uri-js": { - "name": "uri-js", - "version": "4.2.2", - "description": "An RFC 3986/3987 compliant, scheme extendable URI/IRI parsing/validating/resolving library for JavaScript.", - "main": "dist/es5/uri.all.js", - "types": "dist/es5/uri.all.d.ts", - "directories": { - "test": "tests" - }, - "scripts": { - "build:esnext": "tsc", - "build:es5": "rollup -c && cp dist/esnext/uri.d.ts dist/es5/uri.all.d.ts && npm run build:es5:fix-sourcemap", - "build:es5:fix-sourcemap": "sorcery -i dist/es5/uri.all.js", - "build:es5:min": "uglifyjs dist/es5/uri.all.js --support-ie8 --output dist/es5/uri.all.min.js --in-source-map dist/es5/uri.all.js.map --source-map uri.all.min.js.map --comments --compress --mangle --pure-funcs merge subexp && mv uri.all.min.js.map dist/es5/ && cp dist/es5/uri.all.d.ts dist/es5/uri.all.min.d.ts", - "build": "npm run build:esnext && npm run build:es5 && npm run build:es5:min", - "test": "mocha -u mocha-qunit-ui dist/es5/uri.all.js tests/tests.js" - }, - "repository": { - "type": "git", - "url": "git+ssh://git@github.com/garycourt/uri-js.git" - }, - "keywords": [ - "URI", - "IRI", - "IDN", - "URN", - "UUID", - "HTTP", - "HTTPS", - "MAILTO", - "RFC3986", - "RFC3987", - "RFC5891", - "RFC2616", - "RFC2818", - "RFC2141", - "RFC4122", - "RFC4291", - "RFC5952", - "RFC6068", - "RFC6874" - ], - "author": { - "name": "Gary Court", - "email": "gary.court@gmail.com" - }, - "license": "BSD-2-Clause", - "bugs": { - "url": "https://github.com/garycourt/uri-js/issues" - }, - "homepage": "https://github.com/garycourt/uri-js", - "devDependencies": { - "babel-cli": "^6.26.0", - "babel-plugin-external-helpers": "^6.22.0", - "babel-preset-latest": "^6.24.1", - "mocha": "^3.2.0", - "mocha-qunit-ui": "^0.1.3", - "rollup": "^0.41.6", - "rollup-plugin-babel": "^2.7.1", - "rollup-plugin-node-resolve": "^2.0.0", - "sorcery": "^0.10.0", - "typescript": "^2.8.1", - "uglify-js": "^2.8.14" - }, - "dependencies": { - "punycode": { - "name": "punycode", - "version": "2.1.1", - "description": "A robust Punycode converter that fully complies to RFC 3492 and RFC 5891, and works on nearly all JavaScript platforms.", - "homepage": "https://mths.be/punycode", - "main": "punycode.js", - "jsnext:main": "punycode.es6.js", - "module": "punycode.es6.js", - "engines": { - "node": ">=6" - }, - "keywords": [ - "punycode", - "unicode", - "idn", - "idna", - "dns", - "url", - "domain" - ], - "license": "MIT", - "author": { - "name": "Mathias Bynens", - "url": "https://mathiasbynens.be/" - }, - "contributors": [ - { - "name": "Mathias Bynens", - "url": "https://mathiasbynens.be/" - } - ], - "repository": { - "type": "git", - "url": "git+https://github.com/bestiejs/punycode.js.git" - }, - "bugs": { - "url": "https://github.com/bestiejs/punycode.js/issues" - }, - "files": [ - "LICENSE-MIT.txt", - "punycode.js", - "punycode.es6.js" - ], - "scripts": { - "test": "mocha tests", - "prepublish": "node scripts/prepublish.js" - }, - "devDependencies": { - "codecov": "^1.0.1", - "istanbul": "^0.4.1", - "mocha": "^2.5.3" - }, - "jspm": { - "map": { - "./punycode.js": { - "node": "@node/punycode" - } - } - }, - "_resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "_integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "_from": "punycode@2.1.1", - "readme": "# Punycode.js [![Build status](https://travis-ci.org/bestiejs/punycode.js.svg?branch=master)](https://travis-ci.org/bestiejs/punycode.js) [![Code coverage status](http://img.shields.io/codecov/c/github/bestiejs/punycode.js.svg)](https://codecov.io/gh/bestiejs/punycode.js) [![Dependency status](https://gemnasium.com/bestiejs/punycode.js.svg)](https://gemnasium.com/bestiejs/punycode.js)\n\nPunycode.js is a robust Punycode converter that fully complies to [RFC 3492](https://tools.ietf.org/html/rfc3492) and [RFC 5891](https://tools.ietf.org/html/rfc5891).\n\nThis JavaScript library is the result of comparing, optimizing and documenting different open-source implementations of the Punycode algorithm:\n\n* [The C example code from RFC 3492](https://tools.ietf.org/html/rfc3492#appendix-C)\n* [`punycode.c` by _Markus W. Scherer_ (IBM)](http://opensource.apple.com/source/ICU/ICU-400.42/icuSources/common/punycode.c)\n* [`punycode.c` by _Ben Noordhuis_](https://github.com/bnoordhuis/punycode/blob/master/punycode.c)\n* [JavaScript implementation by _some_](http://stackoverflow.com/questions/183485/can-anyone-recommend-a-good-free-javascript-for-punycode-to-unicode-conversion/301287#301287)\n* [`punycode.js` by _Ben Noordhuis_](https://github.com/joyent/node/blob/426298c8c1c0d5b5224ac3658c41e7c2a3fe9377/lib/punycode.js) (note: [not fully compliant](https://github.com/joyent/node/issues/2072))\n\nThis project was [bundled](https://github.com/joyent/node/blob/master/lib/punycode.js) with Node.js from [v0.6.2+](https://github.com/joyent/node/compare/975f1930b1...61e796decc) until [v7](https://github.com/nodejs/node/pull/7941) (soft-deprecated).\n\nThe current version supports recent versions of Node.js only. It provides a CommonJS module and an ES6 module. For the old version that offers the same functionality with broader support, including Rhino, Ringo, Narwhal, and web browsers, see [v1.4.1](https://github.com/bestiejs/punycode.js/releases/tag/v1.4.1).\n\n## Installation\n\nVia [npm](https://www.npmjs.com/):\n\n```bash\nnpm install punycode --save\n```\n\nIn [Node.js](https://nodejs.org/):\n\n```js\nconst punycode = require('punycode');\n```\n\n## API\n\n### `punycode.decode(string)`\n\nConverts a Punycode string of ASCII symbols to a string of Unicode symbols.\n\n```js\n// decode domain name parts\npunycode.decode('maana-pta'); // 'mañana'\npunycode.decode('--dqo34k'); // '☃-⌘'\n```\n\n### `punycode.encode(string)`\n\nConverts a string of Unicode symbols to a Punycode string of ASCII symbols.\n\n```js\n// encode domain name parts\npunycode.encode('mañana'); // 'maana-pta'\npunycode.encode('☃-⌘'); // '--dqo34k'\n```\n\n### `punycode.toUnicode(input)`\n\nConverts a Punycode string representing a domain name or an email address to Unicode. Only the Punycoded parts of the input will be converted, i.e. it doesn’t matter if you call it on a string that has already been converted to Unicode.\n\n```js\n// decode domain names\npunycode.toUnicode('xn--maana-pta.com');\n// → 'mañana.com'\npunycode.toUnicode('xn----dqo34k.com');\n// → '☃-⌘.com'\n\n// decode email addresses\npunycode.toUnicode('джумла@xn--p-8sbkgc5ag7bhce.xn--ba-lmcq');\n// → 'джумла@джpумлатест.bрфa'\n```\n\n### `punycode.toASCII(input)`\n\nConverts a lowercased Unicode string representing a domain name or an email address to Punycode. Only the non-ASCII parts of the input will be converted, i.e. it doesn’t matter if you call it with a domain that’s already in ASCII.\n\n```js\n// encode domain names\npunycode.toASCII('mañana.com');\n// → 'xn--maana-pta.com'\npunycode.toASCII('☃-⌘.com');\n// → 'xn----dqo34k.com'\n\n// encode email addresses\npunycode.toASCII('джумла@джpумлатест.bрфa');\n// → 'джумла@xn--p-8sbkgc5ag7bhce.xn--ba-lmcq'\n```\n\n### `punycode.ucs2`\n\n#### `punycode.ucs2.decode(string)`\n\nCreates an array containing the numeric code point values of each Unicode symbol in the string. While [JavaScript uses UCS-2 internally](https://mathiasbynens.be/notes/javascript-encoding), this function will convert a pair of surrogate halves (each of which UCS-2 exposes as separate characters) into a single code point, matching UTF-16.\n\n```js\npunycode.ucs2.decode('abc');\n// → [0x61, 0x62, 0x63]\n// surrogate pair for U+1D306 TETRAGRAM FOR CENTRE:\npunycode.ucs2.decode('\\uD834\\uDF06');\n// → [0x1D306]\n```\n\n#### `punycode.ucs2.encode(codePoints)`\n\nCreates a string based on an array of numeric code point values.\n\n```js\npunycode.ucs2.encode([0x61, 0x62, 0x63]);\n// → 'abc'\npunycode.ucs2.encode([0x1D306]);\n// → '\\uD834\\uDF06'\n```\n\n### `punycode.version`\n\nA string representing the current Punycode.js version number.\n\n## Author\n\n| [![twitter/mathias](https://gravatar.com/avatar/24e08a9ea84deb17ae121074d0f17125?s=70)](https://twitter.com/mathias \"Follow @mathias on Twitter\") |\n|---|\n| [Mathias Bynens](https://mathiasbynens.be/) |\n\n## License\n\nPunycode.js is available under the [MIT](https://mths.be/mit) license.\n", - "readmeFilename": "README.md", - "_id": "punycode@2.1.1", - "_requested": { - "type": "version", - "registry": true, - "raw": "punycode@2.1.1", - "name": "punycode", - "escapedName": "punycode", - "rawSpec": "2.1.1", - "saveSpec": "[Circular]", - "fetchSpec": "2.1.1" - }, - "_spec": "2.1.1", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "punycode@2.1.1", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "dependencies": {}, - "optionalDependencies": {}, - "_dependencies": {}, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/punycode", - "error": "[Circular]", - "extraneous": false - } - }, - "_resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "_integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "_from": "uri-js@4.2.2", - "readme": "# URI.js\n\nURI.js is an [RFC 3986](http://www.ietf.org/rfc/rfc3986.txt) compliant, scheme extendable URI parsing/validating/resolving library for all JavaScript environments (browsers, Node.js, etc).\nIt is also compliant with the IRI ([RFC 3987](http://www.ietf.org/rfc/rfc3987.txt)), IDNA ([RFC 5890](http://www.ietf.org/rfc/rfc5890.txt)), IPv6 Address ([RFC 5952](http://www.ietf.org/rfc/rfc5952.txt)), IPv6 Zone Identifier ([RFC 6874](http://www.ietf.org/rfc/rfc6874.txt)) specifications.\n\nURI.js has an extensive test suite, and works in all (Node.js, web) environments. It weighs in at 6.2kb (gzipped, 16kb deflated).\n\n## API\n\n### Parsing\n\n\tURI.parse(\"uri://user:pass@example.com:123/one/two.three?q1=a1&q2=a2#body\");\n\t//returns:\n\t//{\n\t// scheme : \"uri\",\n\t// userinfo : \"user:pass\",\n\t// host : \"example.com\",\n\t// port : 123,\n\t// path : \"/one/two.three\",\n\t// query : \"q1=a1&q2=a2\",\n\t// fragment : \"body\"\n\t//}\n\n### Serializing\n\n\tURI.serialize({scheme : \"http\", host : \"example.com\", fragment : \"footer\"}) === \"http://example.com/#footer\"\n\n### Resolving\n\n\tURI.resolve(\"uri://a/b/c/d?q\", \"../../g\") === \"uri://a/g\"\n\n### Normalizing\n\n\tURI.normalize(\"HTTP://ABC.com:80/%7Esmith/home.html\") === \"http://abc.com/~smith/home.html\"\n\n### Comparison\n\n\tURI.equal(\"example://a/b/c/%7Bfoo%7D\", \"eXAMPLE://a/./b/../b/%63/%7bfoo%7d\") === true\n\n### IP Support\n\n\t//IPv4 normalization\n\tURI.normalize(\"//192.068.001.000\") === \"//192.68.1.0\"\n\n\t//IPv6 normalization\n\tURI.normalize(\"//[2001:0:0DB8::0:0001]\") === \"//[2001:0:db8::1]\"\n\n\t//IPv6 zone identifier support\n\tURI.parse(\"//[2001:db8::7%25en1]\");\n\t//returns:\n\t//{\n\t// host : \"2001:db8::7%en1\"\n\t//}\n\n### IRI Support\n\n\t//convert IRI to URI\n\tURI.serialize(URI.parse(\"http://examplé.org/rosé\")) === \"http://xn--exampl-gva.org/ros%C3%A9\"\n\t//convert URI to IRI\n\tURI.serialize(URI.parse(\"http://xn--exampl-gva.org/ros%C3%A9\"), {iri:true}) === \"http://examplé.org/rosé\"\n\n### Options\n\nAll of the above functions can accept an additional options argument that is an object that can contain one or more of the following properties:\n\n*\t`scheme` (string)\n\n\tIndicates the scheme that the URI should be treated as, overriding the URI's normal scheme parsing behavior.\n\n*\t`reference` (string)\n\n\tIf set to `\"suffix\"`, it indicates that the URI is in the suffix format, and the validator will use the option's `scheme` property to determine the URI's scheme.\n\n*\t`tolerant` (boolean, false)\n\n\tIf set to `true`, the parser will relax URI resolving rules.\n\n*\t`absolutePath` (boolean, false)\n\n\tIf set to `true`, the serializer will not resolve a relative `path` component.\n\n*\t`iri` (boolean, false)\n\n\tIf set to `true`, the serializer will unescape non-ASCII characters as per [RFC 3987](http://www.ietf.org/rfc/rfc3987.txt).\n\n*\t`unicodeSupport` (boolean, false)\n\n\tIf set to `true`, the parser will unescape non-ASCII characters in the parsed output as per [RFC 3987](http://www.ietf.org/rfc/rfc3987.txt).\n\n*\t`domainHost` (boolean, false)\n\n\tIf set to `true`, the library will treat the `host` component as a domain name, and convert IDNs (International Domain Names) as per [RFC 5891](http://www.ietf.org/rfc/rfc5891.txt).\n\n## Scheme Extendable\n\nURI.js supports inserting custom [scheme](http://en.wikipedia.org/wiki/URI_scheme) dependent processing rules. Currently, URI.js has built in support for the following schemes:\n\n*\thttp \\[[RFC 2616](http://www.ietf.org/rfc/rfc2616.txt)\\]\n*\thttps \\[[RFC 2818](http://www.ietf.org/rfc/rfc2818.txt)\\]\n*\tmailto \\[[RFC 6068](http://www.ietf.org/rfc/rfc6068.txt)\\]\n*\turn \\[[RFC 2141](http://www.ietf.org/rfc/rfc2141.txt)\\]\n*\turn:uuid \\[[RFC 4122](http://www.ietf.org/rfc/rfc4122.txt)\\]\n\n### HTTP Support\n\n\tURI.equal(\"HTTP://ABC.COM:80\", \"http://abc.com/\") === true\n\n### Mailto Support\n\n\tURI.parse(\"mailto:alpha@example.com,bravo@example.com?subject=SUBSCRIBE&body=Sign%20me%20up!\");\n\t//returns:\n\t//{\n\t//\tscheme : \"mailto\",\n\t//\tto : [\"alpha@example.com\", \"bravo@example.com\"],\n\t//\tsubject : \"SUBSCRIBE\",\n\t//\tbody : \"Sign me up!\"\n\t//}\n\n\tURI.serialize({\n\t\tscheme : \"mailto\",\n\t\tto : [\"alpha@example.com\"],\n\t\tsubject : \"REMOVE\",\n\t\tbody : \"Please remove me\",\n\t\theaders : {\n\t\t\tcc : \"charlie@example.com\"\n\t\t}\n\t}) === \"mailto:alpha@example.com?cc=charlie@example.com&subject=REMOVE&body=Please%20remove%20me\"\n\n### URN Support\n\n\tURI.parse(\"urn:example:foo\");\n\t//returns:\n\t//{\n\t//\tscheme : \"urn\",\n\t//\tnid : \"example\",\n\t//\tnss : \"foo\",\n\t//}\n\n#### URN UUID Support\n\n\tURI.parse(\"urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6\");\n\t//returns:\n\t//{\n\t//\tscheme : \"urn\",\n\t//\tnid : \"example\",\n\t//\tuuid : \"f81d4fae-7dec-11d0-a765-00a0c91e6bf6\",\n\t//}\n\n## Usage\n\nTo load in a browser, use the following tag:\n\n\t\n\nTo load in a CommonJS (Node.js) environment, first install with npm by running on the command line:\n\n\tnpm install uri-js\n\nThen, in your code, load it using:\n\n\tconst URI = require(\"uri-js\");\n\nIf you are writing your code in ES6+ (ESNEXT) or TypeScript, you would load it using:\n\n\timport * as URI from \"uri-js\";\n\nOr you can load just what you need using named exports:\n\n\timport { parse, serialize, resolve, resolveComponents, normalize, equal, removeDotSegments, pctEncChar, pctDecChars, escapeComponent, unescapeComponent } from \"uri-js\";\n\n## Breaking changes\n\n### Breaking changes from 3.x\n\nURN parsing has been completely changed to better align with the specification. Scheme is now always `urn`, but has two new properties: `nid` which contains the Namspace Identifier, and `nss` which contains the Namespace Specific String. The `nss` property will be removed by higher order scheme handlers, such as the UUID URN scheme handler.\n\nThe UUID of a URN can now be found in the `uuid` property.\n\n### Breaking changes from 2.x\n\nURI validation has been removed as it was slow, exposed a vulnerabilty, and was generally not useful.\n\n### Breaking changes from 1.x\n\nThe `errors` array on parsed components is now an `error` string.\n\n## License ([Simplified BSD](http://en.wikipedia.org/wiki/BSD_licenses#2-clause))\n\nCopyright 2011 Gary Court. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\n\n1.\tRedistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\n\n2.\tRedistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY GARY COURT \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GARY COURT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\nThe views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of Gary Court.\n", - "readmeFilename": "README.md", - "_id": "uri-js@4.2.2", - "_requested": { - "type": "version", - "registry": true, - "raw": "uri-js@4.2.2", - "name": "uri-js", - "escapedName": "uri-js", - "rawSpec": "4.2.2", - "saveSpec": "[Circular]", - "fetchSpec": "4.2.2" - }, - "_spec": "4.2.2", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "uri-js@4.2.2", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "optionalDependencies": {}, - "_dependencies": { - "punycode": "^2.1.0" - }, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/uri-js", - "error": "[Circular]", - "extraneous": false - } - }, - "devDependencies": { - "ajv-async": "^1.0.0", - "bluebird": "^3.1.5", - "brfs": "^2.0.0", - "browserify": "^16.2.0", - "chai": "^4.0.1", - "coveralls": "^3.0.1", - "del-cli": "^1.1.0", - "dot": "^1.0.3", - "eslint": "^5.0.0", - "gh-pages-generator": "^0.2.3", - "glob": "^7.0.0", - "if-node-version": "^1.0.0", - "js-beautify": "^1.7.3", - "jshint": "^2.9.4", - "json-schema-test": "^2.0.0", - "karma": "^2.0.2", - "karma-chrome-launcher": "^2.0.0", - "karma-mocha": "^1.1.1", - "karma-phantomjs-launcher": "^1.0.0", - "karma-sauce-launcher": "^1.1.0", - "mocha": "^5.1.1", - "nyc": "^12.0.1", - "phantomjs-prebuilt": "^2.1.4", - "pre-commit": "^1.1.1", - "require-globify": "^1.3.0", - "typescript": "^2.8.3", - "uglify-js": "^3.3.24", - "watch": "^1.0.0" - }, - "_resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.2.tgz", - "_integrity": "sha512-hOs7GfvI6tUI1LfZddH82ky6mOMyTuY0mk7kE2pWpmhhUSkumzaTO5vbVwij39MdwPQWCV4Zv57Eo06NtL/GVA==", - "_from": "ajv@6.5.2", - "readme": "\"Ajv\n\n# Ajv: Another JSON Schema Validator\n\nThe fastest JSON Schema validator for Node.js and browser. Supports draft-04/06/07.\n\n\n[![Build Status](https://travis-ci.org/epoberezkin/ajv.svg?branch=master)](https://travis-ci.org/epoberezkin/ajv)\n[![npm](https://img.shields.io/npm/v/ajv.svg)](https://www.npmjs.com/package/ajv)\n[![npm downloads](https://img.shields.io/npm/dm/ajv.svg)](https://www.npmjs.com/package/ajv)\n[![Coverage Status](https://coveralls.io/repos/epoberezkin/ajv/badge.svg?branch=master&service=github)](https://coveralls.io/github/epoberezkin/ajv?branch=master)\n[![Greenkeeper badge](https://badges.greenkeeper.io/epoberezkin/ajv.svg)](https://greenkeeper.io/)\n[![Gitter](https://img.shields.io/gitter/room/ajv-validator/ajv.svg)](https://gitter.im/ajv-validator/ajv)\n\n\n## Using version 6\n\n[JSON Schema draft-07](http://json-schema.org/latest/json-schema-validation.html) is published.\n\n[Ajv version 6.0.0](https://github.com/epoberezkin/ajv/releases/tag/v6.0.0) that supports draft-07 is released. It may require either migrating your schemas or updating your code (to continue using draft-04 and v5 schemas, draft-06 schemas will be supported without changes).\n\n__Please note__: To use Ajv with draft-06 schemas you need to explicitly add the meta-schema to the validator instance:\n\n```javascript\najv.addMetaSchema(require('ajv/lib/refs/json-schema-draft-06.json'));\n```\n\nTo use Ajv with draft-04 schemas in addition to explicitly adding meta-schema you also need to use option schemaId:\n\n```javascript\nvar ajv = new Ajv({schemaId: 'id'});\n// If you want to use both draft-04 and draft-06/07 schemas:\n// var ajv = new Ajv({schemaId: 'auto'});\najv.addMetaSchema(require('ajv/lib/refs/json-schema-draft-04.json'));\n```\n\n\n## Contents\n\n- [Performance](#performance)\n- [Features](#features)\n- [Getting started](#getting-started)\n- [Frequently Asked Questions](https://github.com/epoberezkin/ajv/blob/master/FAQ.md)\n- [Using in browser](#using-in-browser)\n- [Command line interface](#command-line-interface)\n- Validation\n - [Keywords](#validation-keywords)\n - [Annotation keywords](#annotation-keywords)\n - [Formats](#formats)\n - [Combining schemas with $ref](#ref)\n - [$data reference](#data-reference)\n - NEW: [$merge and $patch keywords](#merge-and-patch-keywords)\n - [Defining custom keywords](#defining-custom-keywords)\n - [Asynchronous schema compilation](#asynchronous-schema-compilation)\n - [Asynchronous validation](#asynchronous-validation)\n- Modifying data during validation\n - [Filtering data](#filtering-data)\n - [Assigning defaults](#assigning-defaults)\n - [Coercing data types](#coercing-data-types)\n- API\n - [Methods](#api)\n - [Options](#options)\n - [Validation errors](#validation-errors)\n- [Plugins](#plugins)\n- [Related packages](#related-packages)\n- [Packages using Ajv](#some-packages-using-ajv)\n- [Tests, Contributing, History, License](#tests)\n\n\n## Performance\n\nAjv generates code using [doT templates](https://github.com/olado/doT) to turn JSON Schemas into super-fast validation functions that are efficient for v8 optimization.\n\nCurrently Ajv is the fastest and the most standard compliant validator according to these benchmarks:\n\n- [json-schema-benchmark](https://github.com/ebdrup/json-schema-benchmark) - 50% faster than the second place\n- [jsck benchmark](https://github.com/pandastrike/jsck#benchmarks) - 20-190% faster\n- [z-schema benchmark](https://rawgit.com/zaggino/z-schema/master/benchmark/results.html)\n- [themis benchmark](https://cdn.rawgit.com/playlyfe/themis/master/benchmark/results.html)\n\n\nPerformance of different validators by [json-schema-benchmark](https://github.com/ebdrup/json-schema-benchmark):\n\n[![performance](https://chart.googleapis.com/chart?chxt=x,y&cht=bhs&chco=76A4FB&chls=2.0&chbh=32,4,1&chs=600x416&chxl=-1:|djv|ajv|json-schema-validator-generator|jsen|is-my-json-valid|themis|z-schema|jsck|skeemas|json-schema-library|tv4&chd=t:100,98,72.1,66.8,50.1,15.1,6.1,3.8,1.2,0.7,0.2)](https://github.com/ebdrup/json-schema-benchmark/blob/master/README.md#performance)\n\n\n## Features\n\n- Ajv implements full JSON Schema [draft-06/07](http://json-schema.org/) and draft-04 standards:\n - all validation keywords (see [JSON Schema validation keywords](https://github.com/epoberezkin/ajv/blob/master/KEYWORDS.md))\n - full support of remote refs (remote schemas have to be added with `addSchema` or compiled to be available)\n - support of circular references between schemas\n - correct string lengths for strings with unicode pairs (can be turned off)\n - [formats](#formats) defined by JSON Schema draft-07 standard and custom formats (can be turned off)\n - [validates schemas against meta-schema](#api-validateschema)\n- supports [browsers](#using-in-browser) and Node.js 0.10-8.x\n- [asynchronous loading](#asynchronous-schema-compilation) of referenced schemas during compilation\n- \"All errors\" validation mode with [option allErrors](#options)\n- [error messages with parameters](#validation-errors) describing error reasons to allow creating custom error messages\n- i18n error messages support with [ajv-i18n](https://github.com/epoberezkin/ajv-i18n) package\n- [filtering data](#filtering-data) from additional properties\n- [assigning defaults](#assigning-defaults) to missing properties and items\n- [coercing data](#coercing-data-types) to the types specified in `type` keywords\n- [custom keywords](#defining-custom-keywords)\n- draft-06/07 keywords `const`, `contains`, `propertyNames` and `if/then/else`\n- draft-06 boolean schemas (`true`/`false` as a schema to always pass/fail).\n- keywords `switch`, `patternRequired`, `formatMaximum` / `formatMinimum` and `formatExclusiveMaximum` / `formatExclusiveMinimum` from [JSON Schema extension proposals](https://github.com/json-schema/json-schema/wiki/v5-Proposals) with [ajv-keywords](https://github.com/epoberezkin/ajv-keywords) package\n- [$data reference](#data-reference) to use values from the validated data as values for the schema keywords\n- [asynchronous validation](#asynchronous-validation) of custom formats and keywords\n\nCurrently Ajv is the only validator that passes all the tests from [JSON Schema Test Suite](https://github.com/json-schema/JSON-Schema-Test-Suite) (according to [json-schema-benchmark](https://github.com/ebdrup/json-schema-benchmark), apart from the test that requires that `1.0` is not an integer that is impossible to satisfy in JavaScript).\n\n\n## Install\n\n```\nnpm install ajv\n```\n\n\n## Getting started\n\nTry it in the Node.js REPL: https://tonicdev.com/npm/ajv\n\n\nThe fastest validation call:\n\n```javascript\nvar Ajv = require('ajv');\nvar ajv = new Ajv(); // options can be passed, e.g. {allErrors: true}\nvar validate = ajv.compile(schema);\nvar valid = validate(data);\nif (!valid) console.log(validate.errors);\n```\n\nor with less code\n\n```javascript\n// ...\nvar valid = ajv.validate(schema, data);\nif (!valid) console.log(ajv.errors);\n// ...\n```\n\nor\n\n```javascript\n// ...\nvar valid = ajv.addSchema(schema, 'mySchema')\n .validate('mySchema', data);\nif (!valid) console.log(ajv.errorsText());\n// ...\n```\n\nSee [API](#api) and [Options](#options) for more details.\n\nAjv compiles schemas to functions and caches them in all cases (using schema serialized with [fast-json-stable-stringify](https://github.com/epoberezkin/fast-json-stable-stringify) or a custom function as a key), so that the next time the same schema is used (not necessarily the same object instance) it won't be compiled again.\n\nThe best performance is achieved when using compiled functions returned by `compile` or `getSchema` methods (there is no additional function call).\n\n__Please note__: every time a validation function or `ajv.validate` are called `errors` property is overwritten. You need to copy `errors` array reference to another variable if you want to use it later (e.g., in the callback). See [Validation errors](#validation-errors)\n\n\n## Using in browser\n\nYou can require Ajv directly from the code you browserify - in this case Ajv will be a part of your bundle.\n\nIf you need to use Ajv in several bundles you can create a separate UMD bundle using `npm run bundle` script (thanks to [siddo420](https://github.com/siddo420)).\n\nThen you need to load Ajv in the browser:\n```html\n\n```\n\nThis bundle can be used with different module systems; it creates global `Ajv` if no module system is found.\n\nThe browser bundle is available on [cdnjs](https://cdnjs.com/libraries/ajv).\n\nAjv is tested with these browsers:\n\n[![Sauce Test Status](https://saucelabs.com/browser-matrix/epoberezkin.svg)](https://saucelabs.com/u/epoberezkin)\n\n__Please note__: some frameworks, e.g. Dojo, may redefine global require in such way that is not compatible with CommonJS module format. In such case Ajv bundle has to be loaded before the framework and then you can use global Ajv (see issue [#234](https://github.com/epoberezkin/ajv/issues/234)).\n\n\n## Command line interface\n\nCLI is available as a separate npm package [ajv-cli](https://github.com/jessedc/ajv-cli). It supports:\n\n- compiling JSON Schemas to test their validity\n- BETA: generating standalone module exporting a validation function to be used without Ajv (using [ajv-pack](https://github.com/epoberezkin/ajv-pack))\n- migrate schemas to draft-07 (using [json-schema-migrate](https://github.com/epoberezkin/json-schema-migrate))\n- validating data file(s) against JSON Schema\n- testing expected validity of data against JSON Schema\n- referenced schemas\n- custom meta-schemas\n- files in JSON and JavaScript format\n- all Ajv options\n- reporting changes in data after validation in [JSON-patch](https://tools.ietf.org/html/rfc6902) format\n\n\n## Validation keywords\n\nAjv supports all validation keywords from draft-07 of JSON Schema standard:\n\n- [type](https://github.com/epoberezkin/ajv/blob/master/KEYWORDS.md#type)\n- [for numbers](https://github.com/epoberezkin/ajv/blob/master/KEYWORDS.md#keywords-for-numbers) - maximum, minimum, exclusiveMaximum, exclusiveMinimum, multipleOf\n- [for strings](https://github.com/epoberezkin/ajv/blob/master/KEYWORDS.md#keywords-for-strings) - maxLength, minLength, pattern, format\n- [for arrays](https://github.com/epoberezkin/ajv/blob/master/KEYWORDS.md#keywords-for-arrays) - maxItems, minItems, uniqueItems, items, additionalItems, [contains](https://github.com/epoberezkin/ajv/blob/master/KEYWORDS.md#contains)\n- [for objects](https://github.com/epoberezkin/ajv/blob/master/KEYWORDS.md#keywords-for-objects) - maxProperties, minProperties, required, properties, patternProperties, additionalProperties, dependencies, [propertyNames](https://github.com/epoberezkin/ajv/blob/master/KEYWORDS.md#propertynames)\n- [for all types](https://github.com/epoberezkin/ajv/blob/master/KEYWORDS.md#keywords-for-all-types) - enum, [const](https://github.com/epoberezkin/ajv/blob/master/KEYWORDS.md#const)\n- [compound keywords](https://github.com/epoberezkin/ajv/blob/master/KEYWORDS.md#compound-keywords) - not, oneOf, anyOf, allOf, [if/then/else](https://github.com/epoberezkin/ajv/blob/master/KEYWORDS.md#ifthenelse)\n\nWith [ajv-keywords](https://github.com/epoberezkin/ajv-keywords) package Ajv also supports validation keywords from [JSON Schema extension proposals](https://github.com/json-schema/json-schema/wiki/v5-Proposals) for JSON Schema standard:\n\n- [patternRequired](https://github.com/epoberezkin/ajv/blob/master/KEYWORDS.md#patternrequired-proposed) - like `required` but with patterns that some property should match.\n- [formatMaximum, formatMinimum, formatExclusiveMaximum, formatExclusiveMinimum](https://github.com/epoberezkin/ajv/blob/master/KEYWORDS.md#formatmaximum--formatminimum-and-exclusiveformatmaximum--exclusiveformatminimum-proposed) - setting limits for date, time, etc.\n\nSee [JSON Schema validation keywords](https://github.com/epoberezkin/ajv/blob/master/KEYWORDS.md) for more details.\n\n\n## Annotation keywords\n\nJSON Schema specification defines several annotation keywords that describe schema itself but do not perform any validation.\n\n- `title` and `description`: information about the data represented by that schema\n- `$comment` (NEW in draft-07): information for developers. With option `$comment` Ajv logs or passes the comment string to the user-supplied function. See [Options](#options).\n- `default`: a default value of the data instance, see [Assigning defaults](#assigning-defaults).\n- `examples` (NEW in draft-07): an array of data instances. Ajv does not check the validity of these instances against the schema.\n- `readOnly` and `writeOnly` (NEW in draft-07): marks data-instance as read-only or write-only in relation to the source of the data (database, api, etc.).\n- `contentEncoding`: [RFC 2045](https://tools.ietf.org/html/rfc2045#section-6.1 ), e.g., \"base64\".\n- `contentMediaType`: [RFC 2046](https://tools.ietf.org/html/rfc2046), e.g., \"image/png\".\n\n__Please note__: Ajv does not implement validation of the keywords `examples`, `contentEncoding` and `contentMediaType` but it reserves them. If you want to create a plugin that implements some of them, it should remove these keywords from the instance.\n\n\n## Formats\n\nThe following formats are supported for string validation with \"format\" keyword:\n\n- _date_: full-date according to [RFC3339](http://tools.ietf.org/html/rfc3339#section-5.6).\n- _time_: time with optional time-zone.\n- _date-time_: date-time from the same source (time-zone is mandatory). `date`, `time` and `date-time` validate ranges in `full` mode and only regexp in `fast` mode (see [options](#options)).\n- _uri_: full URI.\n- _uri-reference_: URI reference, including full and relative URIs.\n- _uri-template_: URI template according to [RFC6570](https://tools.ietf.org/html/rfc6570)\n- _url_: [URL record](https://url.spec.whatwg.org/#concept-url).\n- _email_: email address.\n- _hostname_: host name according to [RFC1034](http://tools.ietf.org/html/rfc1034#section-3.5).\n- _ipv4_: IP address v4.\n- _ipv6_: IP address v6.\n- _regex_: tests whether a string is a valid regular expression by passing it to RegExp constructor.\n- _uuid_: Universally Unique IDentifier according to [RFC4122](http://tools.ietf.org/html/rfc4122).\n- _json-pointer_: JSON-pointer according to [RFC6901](https://tools.ietf.org/html/rfc6901).\n- _relative-json-pointer_: relative JSON-pointer according to [this draft](http://tools.ietf.org/html/draft-luff-relative-json-pointer-00).\n\n__Please note__: JSON Schema draft-07 also defines formats `iri`, `iri-reference`, `idn-hostname` and `idn-email` for URLs, hostnames and emails with international characters. Ajv does not implement these formats. If you create Ajv plugin that implements them please make a PR to mention this plugin here.\n\nThere are two modes of format validation: `fast` and `full`. This mode affects formats `date`, `time`, `date-time`, `uri`, `uri-reference`, `email`, and `hostname`. See [Options](#options) for details.\n\nYou can add additional formats and replace any of the formats above using [addFormat](#api-addformat) method.\n\nThe option `unknownFormats` allows changing the default behaviour when an unknown format is encountered. In this case Ajv can either fail schema compilation (default) or ignore it (default in versions before 5.0.0). You also can whitelist specific format(s) to be ignored. See [Options](#options) for details.\n\nYou can find patterns used for format validation and the sources that were used in [formats.js](https://github.com/epoberezkin/ajv/blob/master/lib/compile/formats.js).\n\n\n## Combining schemas with $ref\n\nYou can structure your validation logic across multiple schema files and have schemas reference each other using `$ref` keyword.\n\nExample:\n\n```javascript\nvar schema = {\n \"$id\": \"http://example.com/schemas/schema.json\",\n \"type\": \"object\",\n \"properties\": {\n \"foo\": { \"$ref\": \"defs.json#/definitions/int\" },\n \"bar\": { \"$ref\": \"defs.json#/definitions/str\" }\n }\n};\n\nvar defsSchema = {\n \"$id\": \"http://example.com/schemas/defs.json\",\n \"definitions\": {\n \"int\": { \"type\": \"integer\" },\n \"str\": { \"type\": \"string\" }\n }\n};\n```\n\nNow to compile your schema you can either pass all schemas to Ajv instance:\n\n```javascript\nvar ajv = new Ajv({schemas: [schema, defsSchema]});\nvar validate = ajv.getSchema('http://example.com/schemas/schema.json');\n```\n\nor use `addSchema` method:\n\n```javascript\nvar ajv = new Ajv;\nvar validate = ajv.addSchema(defsSchema)\n .compile(schema);\n```\n\nSee [Options](#options) and [addSchema](#api) method.\n\n__Please note__:\n- `$ref` is resolved as the uri-reference using schema $id as the base URI (see the example).\n- References can be recursive (and mutually recursive) to implement the schemas for different data structures (such as linked lists, trees, graphs, etc.).\n- You don't have to host your schema files at the URIs that you use as schema $id. These URIs are only used to identify the schemas, and according to JSON Schema specification validators should not expect to be able to download the schemas from these URIs.\n- The actual location of the schema file in the file system is not used.\n- You can pass the identifier of the schema as the second parameter of `addSchema` method or as a property name in `schemas` option. This identifier can be used instead of (or in addition to) schema $id.\n- You cannot have the same $id (or the schema identifier) used for more than one schema - the exception will be thrown.\n- You can implement dynamic resolution of the referenced schemas using `compileAsync` method. In this way you can store schemas in any system (files, web, database, etc.) and reference them without explicitly adding to Ajv instance. See [Asynchronous schema compilation](#asynchronous-schema-compilation).\n\n\n## $data reference\n\nWith `$data` option you can use values from the validated data as the values for the schema keywords. See [proposal](https://github.com/json-schema/json-schema/wiki/$data-(v5-proposal)) for more information about how it works.\n\n`$data` reference is supported in the keywords: const, enum, format, maximum/minimum, exclusiveMaximum / exclusiveMinimum, maxLength / minLength, maxItems / minItems, maxProperties / minProperties, formatMaximum / formatMinimum, formatExclusiveMaximum / formatExclusiveMinimum, multipleOf, pattern, required, uniqueItems.\n\nThe value of \"$data\" should be a [JSON-pointer](https://tools.ietf.org/html/rfc6901) to the data (the root is always the top level data object, even if the $data reference is inside a referenced subschema) or a [relative JSON-pointer](http://tools.ietf.org/html/draft-luff-relative-json-pointer-00) (it is relative to the current point in data; if the $data reference is inside a referenced subschema it cannot point to the data outside of the root level for this subschema).\n\nExamples.\n\nThis schema requires that the value in property `smaller` is less or equal than the value in the property larger:\n\n```javascript\nvar ajv = new Ajv({$data: true});\n\nvar schema = {\n \"properties\": {\n \"smaller\": {\n \"type\": \"number\",\n \"maximum\": { \"$data\": \"1/larger\" }\n },\n \"larger\": { \"type\": \"number\" }\n }\n};\n\nvar validData = {\n smaller: 5,\n larger: 7\n};\n\najv.validate(schema, validData); // true\n```\n\nThis schema requires that the properties have the same format as their field names:\n\n```javascript\nvar schema = {\n \"additionalProperties\": {\n \"type\": \"string\",\n \"format\": { \"$data\": \"0#\" }\n }\n};\n\nvar validData = {\n 'date-time': '1963-06-19T08:30:06.283185Z',\n email: 'joe.bloggs@example.com'\n}\n```\n\n`$data` reference is resolved safely - it won't throw even if some property is undefined. If `$data` resolves to `undefined` the validation succeeds (with the exclusion of `const` keyword). If `$data` resolves to incorrect type (e.g. not \"number\" for maximum keyword) the validation fails.\n\n\n## $merge and $patch keywords\n\nWith the package [ajv-merge-patch](https://github.com/epoberezkin/ajv-merge-patch) you can use the keywords `$merge` and `$patch` that allow extending JSON Schemas with patches using formats [JSON Merge Patch (RFC 7396)](https://tools.ietf.org/html/rfc7396) and [JSON Patch (RFC 6902)](https://tools.ietf.org/html/rfc6902).\n\nTo add keywords `$merge` and `$patch` to Ajv instance use this code:\n\n```javascript\nrequire('ajv-merge-patch')(ajv);\n```\n\nExamples.\n\nUsing `$merge`:\n\n```json\n{\n \"$merge\": {\n \"source\": {\n \"type\": \"object\",\n \"properties\": { \"p\": { \"type\": \"string\" } },\n \"additionalProperties\": false\n },\n \"with\": {\n \"properties\": { \"q\": { \"type\": \"number\" } }\n }\n }\n}\n```\n\nUsing `$patch`:\n\n```json\n{\n \"$patch\": {\n \"source\": {\n \"type\": \"object\",\n \"properties\": { \"p\": { \"type\": \"string\" } },\n \"additionalProperties\": false\n },\n \"with\": [\n { \"op\": \"add\", \"path\": \"/properties/q\", \"value\": { \"type\": \"number\" } }\n ]\n }\n}\n```\n\nThe schemas above are equivalent to this schema:\n\n```json\n{\n \"type\": \"object\",\n \"properties\": {\n \"p\": { \"type\": \"string\" },\n \"q\": { \"type\": \"number\" }\n },\n \"additionalProperties\": false\n}\n```\n\nThe properties `source` and `with` in the keywords `$merge` and `$patch` can use absolute or relative `$ref` to point to other schemas previously added to the Ajv instance or to the fragments of the current schema.\n\nSee the package [ajv-merge-patch](https://github.com/epoberezkin/ajv-merge-patch) for more information.\n\n\n## Defining custom keywords\n\nThe advantages of using custom keywords are:\n\n- allow creating validation scenarios that cannot be expressed using JSON Schema\n- simplify your schemas\n- help bringing a bigger part of the validation logic to your schemas\n- make your schemas more expressive, less verbose and closer to your application domain\n- implement custom data processors that modify your data (`modifying` option MUST be used in keyword definition) and/or create side effects while the data is being validated\n\nIf a keyword is used only for side-effects and its validation result is pre-defined, use option `valid: true/false` in keyword definition to simplify both generated code (no error handling in case of `valid: true`) and your keyword functions (no need to return any validation result).\n\nThe concerns you have to be aware of when extending JSON Schema standard with custom keywords are the portability and understanding of your schemas. You will have to support these custom keywords on other platforms and to properly document these keywords so that everybody can understand them in your schemas.\n\nYou can define custom keywords with [addKeyword](#api-addkeyword) method. Keywords are defined on the `ajv` instance level - new instances will not have previously defined keywords.\n\nAjv allows defining keywords with:\n- validation function\n- compilation function\n- macro function\n- inline compilation function that should return code (as string) that will be inlined in the currently compiled schema.\n\nExample. `range` and `exclusiveRange` keywords using compiled schema:\n\n```javascript\najv.addKeyword('range', {\n type: 'number',\n compile: function (sch, parentSchema) {\n var min = sch[0];\n var max = sch[1];\n\n return parentSchema.exclusiveRange === true\n ? function (data) { return data > min && data < max; }\n : function (data) { return data >= min && data <= max; }\n }\n});\n\nvar schema = { \"range\": [2, 4], \"exclusiveRange\": true };\nvar validate = ajv.compile(schema);\nconsole.log(validate(2.01)); // true\nconsole.log(validate(3.99)); // true\nconsole.log(validate(2)); // false\nconsole.log(validate(4)); // false\n```\n\nSeveral custom keywords (typeof, instanceof, range and propertyNames) are defined in [ajv-keywords](https://github.com/epoberezkin/ajv-keywords) package - they can be used for your schemas and as a starting point for your own custom keywords.\n\nSee [Defining custom keywords](https://github.com/epoberezkin/ajv/blob/master/CUSTOM.md) for more details.\n\n\n## Asynchronous schema compilation\n\nDuring asynchronous compilation remote references are loaded using supplied function. See `compileAsync` [method](#api-compileAsync) and `loadSchema` [option](#options).\n\nExample:\n\n```javascript\nvar ajv = new Ajv({ loadSchema: loadSchema });\n\najv.compileAsync(schema).then(function (validate) {\n var valid = validate(data);\n // ...\n});\n\nfunction loadSchema(uri) {\n return request.json(uri).then(function (res) {\n if (res.statusCode >= 400)\n throw new Error('Loading error: ' + res.statusCode);\n return res.body;\n });\n}\n```\n\n__Please note__: [Option](#options) `missingRefs` should NOT be set to `\"ignore\"` or `\"fail\"` for asynchronous compilation to work.\n\n\n## Asynchronous validation\n\nExample in Node.js REPL: https://tonicdev.com/esp/ajv-asynchronous-validation\n\nYou can define custom formats and keywords that perform validation asynchronously by accessing database or some other service. You should add `async: true` in the keyword or format definition (see [addFormat](#api-addformat), [addKeyword](#api-addkeyword) and [Defining custom keywords](#defining-custom-keywords)).\n\nIf your schema uses asynchronous formats/keywords or refers to some schema that contains them it should have `\"$async\": true` keyword so that Ajv can compile it correctly. If asynchronous format/keyword or reference to asynchronous schema is used in the schema without `$async` keyword Ajv will throw an exception during schema compilation.\n\n__Please note__: all asynchronous subschemas that are referenced from the current or other schemas should have `\"$async\": true` keyword as well, otherwise the schema compilation will fail.\n\nValidation function for an asynchronous custom format/keyword should return a promise that resolves with `true` or `false` (or rejects with `new Ajv.ValidationError(errors)` if you want to return custom errors from the keyword function).\n\nAjv compiles asynchronous schemas to [es7 async functions](http://tc39.github.io/ecmascript-asyncawait/) that can optionally be transpiled with [nodent](https://github.com/MatAtBread/nodent). Async functions are supported in Node.js 7+ and all modern browsers. You can also supply any other transpiler as a function via `processCode` option. See [Options](#options).\n\nThe compiled validation function has `$async: true` property (if the schema is asynchronous), so you can differentiate these functions if you are using both synchronous and asynchronous schemas.\n\nValidation result will be a promise that resolves with validated data or rejects with an exception `Ajv.ValidationError` that contains the array of validation errors in `errors` property.\n\n\nExample:\n\n```javascript\nvar ajv = new Ajv;\n// require('ajv-async')(ajv);\n\najv.addKeyword('idExists', {\n async: true,\n type: 'number',\n validate: checkIdExists\n});\n\n\nfunction checkIdExists(schema, data) {\n return knex(schema.table)\n .select('id')\n .where('id', data)\n .then(function (rows) {\n return !!rows.length; // true if record is found\n });\n}\n\nvar schema = {\n \"$async\": true,\n \"properties\": {\n \"userId\": {\n \"type\": \"integer\",\n \"idExists\": { \"table\": \"users\" }\n },\n \"postId\": {\n \"type\": \"integer\",\n \"idExists\": { \"table\": \"posts\" }\n }\n }\n};\n\nvar validate = ajv.compile(schema);\n\nvalidate({ userId: 1, postId: 19 })\n.then(function (data) {\n console.log('Data is valid', data); // { userId: 1, postId: 19 }\n})\n.catch(function (err) {\n if (!(err instanceof Ajv.ValidationError)) throw err;\n // data is invalid\n console.log('Validation errors:', err.errors);\n});\n```\n\n### Using transpilers with asynchronous validation functions.\n\n[ajv-async](https://github.com/epoberezkin/ajv-async) uses [nodent](https://github.com/MatAtBread/nodent) to transpile async functions. To use another transpiler you should separately install it (or load its bundle in the browser).\n\n\n#### Using nodent\n\n```javascript\nvar ajv = new Ajv;\nrequire('ajv-async')(ajv);\n// in the browser if you want to load ajv-async bundle separately you can:\n// window.ajvAsync(ajv);\nvar validate = ajv.compile(schema); // transpiled es7 async function\nvalidate(data).then(successFunc).catch(errorFunc);\n```\n\n\n#### Using other transpilers\n\n```javascript\nvar ajv = new Ajv({ processCode: transpileFunc });\nvar validate = ajv.compile(schema); // transpiled es7 async function\nvalidate(data).then(successFunc).catch(errorFunc);\n```\n\nSee [Options](#options).\n\n\n## Filtering data\n\nWith [option `removeAdditional`](#options) (added by [andyscott](https://github.com/andyscott)) you can filter data during the validation.\n\nThis option modifies original data.\n\nExample:\n\n```javascript\nvar ajv = new Ajv({ removeAdditional: true });\nvar schema = {\n \"additionalProperties\": false,\n \"properties\": {\n \"foo\": { \"type\": \"number\" },\n \"bar\": {\n \"additionalProperties\": { \"type\": \"number\" },\n \"properties\": {\n \"baz\": { \"type\": \"string\" }\n }\n }\n }\n}\n\nvar data = {\n \"foo\": 0,\n \"additional1\": 1, // will be removed; `additionalProperties` == false\n \"bar\": {\n \"baz\": \"abc\",\n \"additional2\": 2 // will NOT be removed; `additionalProperties` != false\n },\n}\n\nvar validate = ajv.compile(schema);\n\nconsole.log(validate(data)); // true\nconsole.log(data); // { \"foo\": 0, \"bar\": { \"baz\": \"abc\", \"additional2\": 2 }\n```\n\nIf `removeAdditional` option in the example above were `\"all\"` then both `additional1` and `additional2` properties would have been removed.\n\nIf the option were `\"failing\"` then property `additional1` would have been removed regardless of its value and property `additional2` would have been removed only if its value were failing the schema in the inner `additionalProperties` (so in the example above it would have stayed because it passes the schema, but any non-number would have been removed).\n\n__Please note__: If you use `removeAdditional` option with `additionalProperties` keyword inside `anyOf`/`oneOf` keywords your validation can fail with this schema, for example:\n\n```json\n{\n \"type\": \"object\",\n \"oneOf\": [\n {\n \"properties\": {\n \"foo\": { \"type\": \"string\" }\n },\n \"required\": [ \"foo\" ],\n \"additionalProperties\": false\n },\n {\n \"properties\": {\n \"bar\": { \"type\": \"integer\" }\n },\n \"required\": [ \"bar\" ],\n \"additionalProperties\": false\n }\n ]\n}\n```\n\nThe intention of the schema above is to allow objects with either the string property \"foo\" or the integer property \"bar\", but not with both and not with any other properties.\n\nWith the option `removeAdditional: true` the validation will pass for the object `{ \"foo\": \"abc\"}` but will fail for the object `{\"bar\": 1}`. It happens because while the first subschema in `oneOf` is validated, the property `bar` is removed because it is an additional property according to the standard (because it is not included in `properties` keyword in the same schema).\n\nWhile this behaviour is unexpected (issues [#129](https://github.com/epoberezkin/ajv/issues/129), [#134](https://github.com/epoberezkin/ajv/issues/134)), it is correct. To have the expected behaviour (both objects are allowed and additional properties are removed) the schema has to be refactored in this way:\n\n```json\n{\n \"type\": \"object\",\n \"properties\": {\n \"foo\": { \"type\": \"string\" },\n \"bar\": { \"type\": \"integer\" }\n },\n \"additionalProperties\": false,\n \"oneOf\": [\n { \"required\": [ \"foo\" ] },\n { \"required\": [ \"bar\" ] }\n ]\n}\n```\n\nThe schema above is also more efficient - it will compile into a faster function.\n\n\n## Assigning defaults\n\nWith [option `useDefaults`](#options) Ajv will assign values from `default` keyword in the schemas of `properties` and `items` (when it is the array of schemas) to the missing properties and items.\n\nThis option modifies original data.\n\n__Please note__: by default the default value is inserted in the generated validation code as a literal (starting from v4.0), so the value inserted in the data will be the deep clone of the default in the schema.\n\nIf you need to insert the default value in the data by reference pass the option `useDefaults: \"shared\"`.\n\nInserting defaults by reference can be faster (in case you have an object in `default`) and it allows to have dynamic values in defaults, e.g. timestamp, without recompiling the schema. The side effect is that modifying the default value in any validated data instance will change the default in the schema and in other validated data instances. See example 3 below.\n\n\nExample 1 (`default` in `properties`):\n\n```javascript\nvar ajv = new Ajv({ useDefaults: true });\nvar schema = {\n \"type\": \"object\",\n \"properties\": {\n \"foo\": { \"type\": \"number\" },\n \"bar\": { \"type\": \"string\", \"default\": \"baz\" }\n },\n \"required\": [ \"foo\", \"bar\" ]\n};\n\nvar data = { \"foo\": 1 };\n\nvar validate = ajv.compile(schema);\n\nconsole.log(validate(data)); // true\nconsole.log(data); // { \"foo\": 1, \"bar\": \"baz\" }\n```\n\nExample 2 (`default` in `items`):\n\n```javascript\nvar schema = {\n \"type\": \"array\",\n \"items\": [\n { \"type\": \"number\" },\n { \"type\": \"string\", \"default\": \"foo\" }\n ]\n}\n\nvar data = [ 1 ];\n\nvar validate = ajv.compile(schema);\n\nconsole.log(validate(data)); // true\nconsole.log(data); // [ 1, \"foo\" ]\n```\n\nExample 3 (inserting \"defaults\" by reference):\n\n```javascript\nvar ajv = new Ajv({ useDefaults: 'shared' });\n\nvar schema = {\n properties: {\n foo: {\n default: { bar: 1 }\n }\n }\n}\n\nvar validate = ajv.compile(schema);\n\nvar data = {};\nconsole.log(validate(data)); // true\nconsole.log(data); // { foo: { bar: 1 } }\n\ndata.foo.bar = 2;\n\nvar data2 = {};\nconsole.log(validate(data2)); // true\nconsole.log(data2); // { foo: { bar: 2 } }\n```\n\n`default` keywords in other cases are ignored:\n\n- not in `properties` or `items` subschemas\n- in schemas inside `anyOf`, `oneOf` and `not` (see [#42](https://github.com/epoberezkin/ajv/issues/42))\n- in `if` subschema of `switch` keyword\n- in schemas generated by custom macro keywords\n\n\n## Coercing data types\n\nWhen you are validating user inputs all your data properties are usually strings. The option `coerceTypes` allows you to have your data types coerced to the types specified in your schema `type` keywords, both to pass the validation and to use the correctly typed data afterwards.\n\nThis option modifies original data.\n\n__Please note__: if you pass a scalar value to the validating function its type will be coerced and it will pass the validation, but the value of the variable you pass won't be updated because scalars are passed by value.\n\n\nExample 1:\n\n```javascript\nvar ajv = new Ajv({ coerceTypes: true });\nvar schema = {\n \"type\": \"object\",\n \"properties\": {\n \"foo\": { \"type\": \"number\" },\n \"bar\": { \"type\": \"boolean\" }\n },\n \"required\": [ \"foo\", \"bar\" ]\n};\n\nvar data = { \"foo\": \"1\", \"bar\": \"false\" };\n\nvar validate = ajv.compile(schema);\n\nconsole.log(validate(data)); // true\nconsole.log(data); // { \"foo\": 1, \"bar\": false }\n```\n\nExample 2 (array coercions):\n\n```javascript\nvar ajv = new Ajv({ coerceTypes: 'array' });\nvar schema = {\n \"properties\": {\n \"foo\": { \"type\": \"array\", \"items\": { \"type\": \"number\" } },\n \"bar\": { \"type\": \"boolean\" }\n }\n};\n\nvar data = { \"foo\": \"1\", \"bar\": [\"false\"] };\n\nvar validate = ajv.compile(schema);\n\nconsole.log(validate(data)); // true\nconsole.log(data); // { \"foo\": [1], \"bar\": false }\n```\n\nThe coercion rules, as you can see from the example, are different from JavaScript both to validate user input as expected and to have the coercion reversible (to correctly validate cases where different types are defined in subschemas of \"anyOf\" and other compound keywords).\n\nSee [Coercion rules](https://github.com/epoberezkin/ajv/blob/master/COERCION.md) for details.\n\n\n## API\n\n##### new Ajv(Object options) -> Object\n\nCreate Ajv instance.\n\n\n##### .compile(Object schema) -> Function<Object data>\n\nGenerate validating function and cache the compiled schema for future use.\n\nValidating function returns a boolean value. This function has properties `errors` and `schema`. Errors encountered during the last validation are assigned to `errors` property (it is assigned `null` if there was no errors). `schema` property contains the reference to the original schema.\n\nThe schema passed to this method will be validated against meta-schema unless `validateSchema` option is false. If schema is invalid, an error will be thrown. See [options](#options).\n\n\n##### .compileAsync(Object schema [, Boolean meta] [, Function callback]) -> Promise\n\nAsynchronous version of `compile` method that loads missing remote schemas using asynchronous function in `options.loadSchema`. This function returns a Promise that resolves to a validation function. An optional callback passed to `compileAsync` will be called with 2 parameters: error (or null) and validating function. The returned promise will reject (and the callback will be called with an error) when:\n\n- missing schema can't be loaded (`loadSchema` returns a Promise that rejects).\n- a schema containing a missing reference is loaded, but the reference cannot be resolved.\n- schema (or some loaded/referenced schema) is invalid.\n\nThe function compiles schema and loads the first missing schema (or meta-schema) until all missing schemas are loaded.\n\nYou can asynchronously compile meta-schema by passing `true` as the second parameter.\n\nSee example in [Asynchronous compilation](#asynchronous-schema-compilation).\n\n\n##### .validate(Object schema|String key|String ref, data) -> Boolean\n\nValidate data using passed schema (it will be compiled and cached).\n\nInstead of the schema you can use the key that was previously passed to `addSchema`, the schema id if it was present in the schema or any previously resolved reference.\n\nValidation errors will be available in the `errors` property of Ajv instance (`null` if there were no errors).\n\n__Please note__: every time this method is called the errors are overwritten so you need to copy them to another variable if you want to use them later.\n\nIf the schema is asynchronous (has `$async` keyword on the top level) this method returns a Promise. See [Asynchronous validation](#asynchronous-validation).\n\n\n##### .addSchema(Array<Object>|Object schema [, String key]) -> Ajv\n\nAdd schema(s) to validator instance. This method does not compile schemas (but it still validates them). Because of that dependencies can be added in any order and circular dependencies are supported. It also prevents unnecessary compilation of schemas that are containers for other schemas but not used as a whole.\n\nArray of schemas can be passed (schemas should have ids), the second parameter will be ignored.\n\nKey can be passed that can be used to reference the schema and will be used as the schema id if there is no id inside the schema. If the key is not passed, the schema id will be used as the key.\n\n\nOnce the schema is added, it (and all the references inside it) can be referenced in other schemas and used to validate data.\n\nAlthough `addSchema` does not compile schemas, explicit compilation is not required - the schema will be compiled when it is used first time.\n\nBy default the schema is validated against meta-schema before it is added, and if the schema does not pass validation the exception is thrown. This behaviour is controlled by `validateSchema` option.\n\n__Please note__: Ajv uses the [method chaining syntax](https://en.wikipedia.org/wiki/Method_chaining) for all methods with the prefix `add*` and `remove*`.\nThis allows you to do nice things like the following.\n\n```javascript\nvar validate = new Ajv().addSchema(schema).addFormat(name, regex).getSchema(uri);\n```\n\n##### .addMetaSchema(Array<Object>|Object schema [, String key]) -> Ajv\n\nAdds meta schema(s) that can be used to validate other schemas. That function should be used instead of `addSchema` because there may be instance options that would compile a meta schema incorrectly (at the moment it is `removeAdditional` option).\n\nThere is no need to explicitly add draft-07 meta schema (http://json-schema.org/draft-07/schema) - it is added by default, unless option `meta` is set to `false`. You only need to use it if you have a changed meta-schema that you want to use to validate your schemas. See `validateSchema`.\n\n\n##### .validateSchema(Object schema) -> Boolean\n\nValidates schema. This method should be used to validate schemas rather than `validate` due to the inconsistency of `uri` format in JSON Schema standard.\n\nBy default this method is called automatically when the schema is added, so you rarely need to use it directly.\n\nIf schema doesn't have `$schema` property, it is validated against draft 6 meta-schema (option `meta` should not be false).\n\nIf schema has `$schema` property, then the schema with this id (that should be previously added) is used to validate passed schema.\n\nErrors will be available at `ajv.errors`.\n\n\n##### .getSchema(String key) -> Function<Object data>\n\nRetrieve compiled schema previously added with `addSchema` by the key passed to `addSchema` or by its full reference (id). The returned validating function has `schema` property with the reference to the original schema.\n\n\n##### .removeSchema([Object schema|String key|String ref|RegExp pattern]) -> Ajv\n\nRemove added/cached schema. Even if schema is referenced by other schemas it can be safely removed as dependent schemas have local references.\n\nSchema can be removed using:\n- key passed to `addSchema`\n- it's full reference (id)\n- RegExp that should match schema id or key (meta-schemas won't be removed)\n- actual schema object that will be stable-stringified to remove schema from cache\n\nIf no parameter is passed all schemas but meta-schemas will be removed and the cache will be cleared.\n\n\n##### .addFormat(String name, String|RegExp|Function|Object format) -> Ajv\n\nAdd custom format to validate strings or numbers. It can also be used to replace pre-defined formats for Ajv instance.\n\nStrings are converted to RegExp.\n\nFunction should return validation result as `true` or `false`.\n\nIf object is passed it should have properties `validate`, `compare` and `async`:\n\n- _validate_: a string, RegExp or a function as described above.\n- _compare_: an optional comparison function that accepts two strings and compares them according to the format meaning. This function is used with keywords `formatMaximum`/`formatMinimum` (defined in [ajv-keywords](https://github.com/epoberezkin/ajv-keywords) package). It should return `1` if the first value is bigger than the second value, `-1` if it is smaller and `0` if it is equal.\n- _async_: an optional `true` value if `validate` is an asynchronous function; in this case it should return a promise that resolves with a value `true` or `false`.\n- _type_: an optional type of data that the format applies to. It can be `\"string\"` (default) or `\"number\"` (see https://github.com/epoberezkin/ajv/issues/291#issuecomment-259923858). If the type of data is different, the validation will pass.\n\nCustom formats can be also added via `formats` option.\n\n\n##### .addKeyword(String keyword, Object definition) -> Ajv\n\nAdd custom validation keyword to Ajv instance.\n\nKeyword should be different from all standard JSON Schema keywords and different from previously defined keywords. There is no way to redefine keywords or to remove keyword definition from the instance.\n\nKeyword must start with a letter, `_` or `$`, and may continue with letters, numbers, `_`, `$`, or `-`.\nIt is recommended to use an application-specific prefix for keywords to avoid current and future name collisions.\n\nExample Keywords:\n- `\"xyz-example\"`: valid, and uses prefix for the xyz project to avoid name collisions.\n- `\"example\"`: valid, but not recommended as it could collide with future versions of JSON Schema etc.\n- `\"3-example\"`: invalid as numbers are not allowed to be the first character in a keyword\n\nKeyword definition is an object with the following properties:\n\n- _type_: optional string or array of strings with data type(s) that the keyword applies to. If not present, the keyword will apply to all types.\n- _validate_: validating function\n- _compile_: compiling function\n- _macro_: macro function\n- _inline_: compiling function that returns code (as string)\n- _schema_: an optional `false` value used with \"validate\" keyword to not pass schema\n- _metaSchema_: an optional meta-schema for keyword schema\n- _modifying_: `true` MUST be passed if keyword modifies data\n- _valid_: pass `true`/`false` to pre-define validation result, the result returned from validation function will be ignored. This option cannot be used with macro keywords.\n- _$data_: an optional `true` value to support [$data reference](#data-reference) as the value of custom keyword. The reference will be resolved at validation time. If the keyword has meta-schema it would be extended to allow $data and it will be used to validate the resolved value. Supporting $data reference requires that keyword has validating function (as the only option or in addition to compile, macro or inline function).\n- _async_: an optional `true` value if the validation function is asynchronous (whether it is compiled or passed in _validate_ property); in this case it should return a promise that resolves with a value `true` or `false`. This option is ignored in case of \"macro\" and \"inline\" keywords.\n- _errors_: an optional boolean indicating whether keyword returns errors. If this property is not set Ajv will determine if the errors were set in case of failed validation.\n\n_compile_, _macro_ and _inline_ are mutually exclusive, only one should be used at a time. _validate_ can be used separately or in addition to them to support $data reference.\n\n__Please note__: If the keyword is validating data type that is different from the type(s) in its definition, the validation function will not be called (and expanded macro will not be used), so there is no need to check for data type inside validation function or inside schema returned by macro function (unless you want to enforce a specific type and for some reason do not want to use a separate `type` keyword for that). In the same way as standard keywords work, if the keyword does not apply to the data type being validated, the validation of this keyword will succeed.\n\nSee [Defining custom keywords](#defining-custom-keywords) for more details.\n\n\n##### .getKeyword(String keyword) -> Object|Boolean\n\nReturns custom keyword definition, `true` for pre-defined keywords and `false` if the keyword is unknown.\n\n\n##### .removeKeyword(String keyword) -> Ajv\n\nRemoves custom or pre-defined keyword so you can redefine them.\n\nWhile this method can be used to extend pre-defined keywords, it can also be used to completely change their meaning - it may lead to unexpected results.\n\n__Please note__: schemas compiled before the keyword is removed will continue to work without changes. To recompile schemas use `removeSchema` method and compile them again.\n\n\n##### .errorsText([Array<Object> errors [, Object options]]) -> String\n\nReturns the text with all errors in a String.\n\nOptions can have properties `separator` (string used to separate errors, \", \" by default) and `dataVar` (the variable name that dataPaths are prefixed with, \"data\" by default).\n\n\n## Options\n\nDefaults:\n\n```javascript\n{\n // validation and reporting options:\n $data: false,\n allErrors: false,\n verbose: false,\n $comment: false, // NEW in Ajv version 6.0\n jsonPointers: false,\n uniqueItems: true,\n unicode: true,\n format: 'fast',\n formats: {},\n unknownFormats: true,\n schemas: {},\n logger: undefined,\n // referenced schema options:\n schemaId: '$id',\n missingRefs: true,\n extendRefs: 'ignore', // recommended 'fail'\n loadSchema: undefined, // function(uri: string): Promise {}\n // options to modify validated data:\n removeAdditional: false,\n useDefaults: false,\n coerceTypes: false,\n // asynchronous validation options:\n transpile: undefined, // requires ajv-async package\n // advanced options:\n meta: true,\n validateSchema: true,\n addUsedSchema: true,\n inlineRefs: true,\n passContext: false,\n loopRequired: Infinity,\n ownProperties: false,\n multipleOfPrecision: false,\n errorDataPath: 'object', // deprecated\n messages: true,\n sourceCode: false,\n processCode: undefined, // function (str: string): string {}\n cache: new Cache,\n serialize: undefined\n}\n```\n\n##### Validation and reporting options\n\n- _$data_: support [$data references](#data-reference). Draft 6 meta-schema that is added by default will be extended to allow them. If you want to use another meta-schema you need to use $dataMetaSchema method to add support for $data reference. See [API](#api).\n- _allErrors_: check all rules collecting all errors. Default is to return after the first error.\n- _verbose_: include the reference to the part of the schema (`schema` and `parentSchema`) and validated data in errors (false by default).\n- _$comment_ (NEW in Ajv version 6.0): log or pass the value of `$comment` keyword to a function. Option values:\n - `false` (default): ignore $comment keyword.\n - `true`: log the keyword value to console.\n - function: pass the keyword value, its schema path and root schema to the specified function\n- _jsonPointers_: set `dataPath` property of errors using [JSON Pointers](https://tools.ietf.org/html/rfc6901) instead of JavaScript property access notation.\n- _uniqueItems_: validate `uniqueItems` keyword (true by default).\n- _unicode_: calculate correct length of strings with unicode pairs (true by default). Pass `false` to use `.length` of strings that is faster, but gives \"incorrect\" lengths of strings with unicode pairs - each unicode pair is counted as two characters.\n- _format_: formats validation mode ('fast' by default). Pass 'full' for more correct and slow validation or `false` not to validate formats at all. E.g., 25:00:00 and 2015/14/33 will be invalid time and date in 'full' mode but it will be valid in 'fast' mode.\n- _formats_: an object with custom formats. Keys and values will be passed to `addFormat` method.\n- _unknownFormats_: handling of unknown formats. Option values:\n - `true` (default) - if an unknown format is encountered the exception is thrown during schema compilation. If `format` keyword value is [$data reference](#data-reference) and it is unknown the validation will fail.\n - `[String]` - an array of unknown format names that will be ignored. This option can be used to allow usage of third party schemas with format(s) for which you don't have definitions, but still fail if another unknown format is used. If `format` keyword value is [$data reference](#data-reference) and it is not in this array the validation will fail.\n - `\"ignore\"` - to log warning during schema compilation and always pass validation (the default behaviour in versions before 5.0.0). This option is not recommended, as it allows to mistype format name and it won't be validated without any error message. This behaviour is required by JSON Schema specification.\n- _schemas_: an array or object of schemas that will be added to the instance. In case you pass the array the schemas must have IDs in them. When the object is passed the method `addSchema(value, key)` will be called for each schema in this object.\n- _logger_: sets the logging method. Default is the global `console` object that should have methods `log`, `warn` and `error`. Option values:\n - custom logger - it should have methods `log`, `warn` and `error`. If any of these methods is missing an exception will be thrown.\n - `false` - logging is disabled.\n\n\n##### Referenced schema options\n\n- _schemaId_: this option defines which keywords are used as schema URI. Option value:\n - `\"$id\"` (default) - only use `$id` keyword as schema URI (as specified in JSON Schema draft-06/07), ignore `id` keyword (if it is present a warning will be logged).\n - `\"id\"` - only use `id` keyword as schema URI (as specified in JSON Schema draft-04), ignore `$id` keyword (if it is present a warning will be logged).\n - `\"auto\"` - use both `$id` and `id` keywords as schema URI. If both are present (in the same schema object) and different the exception will be thrown during schema compilation.\n- _missingRefs_: handling of missing referenced schemas. Option values:\n - `true` (default) - if the reference cannot be resolved during compilation the exception is thrown. The thrown error has properties `missingRef` (with hash fragment) and `missingSchema` (without it). Both properties are resolved relative to the current base id (usually schema id, unless it was substituted).\n - `\"ignore\"` - to log error during compilation and always pass validation.\n - `\"fail\"` - to log error and successfully compile schema but fail validation if this rule is checked.\n- _extendRefs_: validation of other keywords when `$ref` is present in the schema. Option values:\n - `\"ignore\"` (default) - when `$ref` is used other keywords are ignored (as per [JSON Reference](https://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03#section-3) standard). A warning will be logged during the schema compilation.\n - `\"fail\"` (recommended) - if other validation keywords are used together with `$ref` the exception will be thrown when the schema is compiled. This option is recommended to make sure schema has no keywords that are ignored, which can be confusing.\n - `true` - validate all keywords in the schemas with `$ref` (the default behaviour in versions before 5.0.0).\n- _loadSchema_: asynchronous function that will be used to load remote schemas when `compileAsync` [method](#api-compileAsync) is used and some reference is missing (option `missingRefs` should NOT be 'fail' or 'ignore'). This function should accept remote schema uri as a parameter and return a Promise that resolves to a schema. See example in [Asynchronous compilation](#asynchronous-schema-compilation).\n\n\n##### Options to modify validated data\n\n- _removeAdditional_: remove additional properties - see example in [Filtering data](#filtering-data). This option is not used if schema is added with `addMetaSchema` method. Option values:\n - `false` (default) - not to remove additional properties\n - `\"all\"` - all additional properties are removed, regardless of `additionalProperties` keyword in schema (and no validation is made for them).\n - `true` - only additional properties with `additionalProperties` keyword equal to `false` are removed.\n - `\"failing\"` - additional properties that fail schema validation will be removed (where `additionalProperties` keyword is `false` or schema).\n- _useDefaults_: replace missing properties and items with the values from corresponding `default` keywords. Default behaviour is to ignore `default` keywords. This option is not used if schema is added with `addMetaSchema` method. See examples in [Assigning defaults](#assigning-defaults). Option values:\n - `false` (default) - do not use defaults\n - `true` - insert defaults by value (safer and slower, object literal is used).\n - `\"shared\"` - insert defaults by reference (faster). If the default is an object, it will be shared by all instances of validated data. If you modify the inserted default in the validated data, it will be modified in the schema as well.\n- _coerceTypes_: change data type of data to match `type` keyword. See the example in [Coercing data types](#coercing-data-types) and [coercion rules](https://github.com/epoberezkin/ajv/blob/master/COERCION.md). Option values:\n - `false` (default) - no type coercion.\n - `true` - coerce scalar data types.\n - `\"array\"` - in addition to coercions between scalar types, coerce scalar data to an array with one element and vice versa (as required by the schema).\n\n\n##### Asynchronous validation options\n\n- _transpile_: Requires [ajv-async](https://github.com/epoberezkin/ajv-async) package. It determines whether Ajv transpiles compiled asynchronous validation function. Option values:\n - `undefined` (default) - transpile with [nodent](https://github.com/MatAtBread/nodent) if async functions are not supported.\n - `true` - always transpile with nodent.\n - `false` - do not transpile; if async functions are not supported an exception will be thrown.\n\n\n##### Advanced options\n\n- _meta_: add [meta-schema](http://json-schema.org/documentation.html) so it can be used by other schemas (true by default). If an object is passed, it will be used as the default meta-schema for schemas that have no `$schema` keyword. This default meta-schema MUST have `$schema` keyword.\n- _validateSchema_: validate added/compiled schemas against meta-schema (true by default). `$schema` property in the schema can be http://json-schema.org/draft-07/schema or absent (draft-07 meta-schema will be used) or can be a reference to the schema previously added with `addMetaSchema` method. Option values:\n - `true` (default) - if the validation fails, throw the exception.\n - `\"log\"` - if the validation fails, log error.\n - `false` - skip schema validation.\n- _addUsedSchema_: by default methods `compile` and `validate` add schemas to the instance if they have `$id` (or `id`) property that doesn't start with \"#\". If `$id` is present and it is not unique the exception will be thrown. Set this option to `false` to skip adding schemas to the instance and the `$id` uniqueness check when these methods are used. This option does not affect `addSchema` method.\n- _inlineRefs_: Affects compilation of referenced schemas. Option values:\n - `true` (default) - the referenced schemas that don't have refs in them are inlined, regardless of their size - that substantially improves performance at the cost of the bigger size of compiled schema functions.\n - `false` - to not inline referenced schemas (they will be compiled as separate functions).\n - integer number - to limit the maximum number of keywords of the schema that will be inlined.\n- _passContext_: pass validation context to custom keyword functions. If this option is `true` and you pass some context to the compiled validation function with `validate.call(context, data)`, the `context` will be available as `this` in your custom keywords. By default `this` is Ajv instance.\n- _loopRequired_: by default `required` keyword is compiled into a single expression (or a sequence of statements in `allErrors` mode). In case of a very large number of properties in this keyword it may result in a very big validation function. Pass integer to set the number of properties above which `required` keyword will be validated in a loop - smaller validation function size but also worse performance.\n- _ownProperties_: by default Ajv iterates over all enumerable object properties; when this option is `true` only own enumerable object properties (i.e. found directly on the object rather than on its prototype) are iterated. Contributed by @mbroadst.\n- _multipleOfPrecision_: by default `multipleOf` keyword is validated by comparing the result of division with parseInt() of that result. It works for dividers that are bigger than 1. For small dividers such as 0.01 the result of the division is usually not integer (even when it should be integer, see issue [#84](https://github.com/epoberezkin/ajv/issues/84)). If you need to use fractional dividers set this option to some positive integer N to have `multipleOf` validated using this formula: `Math.abs(Math.round(division) - division) < 1e-N` (it is slower but allows for float arithmetics deviations).\n- _errorDataPath_ (deprecated): set `dataPath` to point to 'object' (default) or to 'property' when validating keywords `required`, `additionalProperties` and `dependencies`.\n- _messages_: Include human-readable messages in errors. `true` by default. `false` can be passed when custom messages are used (e.g. with [ajv-i18n](https://github.com/epoberezkin/ajv-i18n)).\n- _sourceCode_: add `sourceCode` property to validating function (for debugging; this code can be different from the result of toString call).\n- _processCode_: an optional function to process generated code before it is passed to Function constructor. It can be used to either beautify (the validating function is generated without line-breaks) or to transpile code. Starting from version 5.0.0 this option replaced options:\n - `beautify` that formatted the generated function using [js-beautify](https://github.com/beautify-web/js-beautify). If you want to beautify the generated code pass `require('js-beautify').js_beautify`.\n - `transpile` that transpiled asynchronous validation function. You can still use `transpile` option with [ajv-async](https://github.com/epoberezkin/ajv-async) package. See [Asynchronous validation](#asynchronous-validation) for more information.\n- _cache_: an optional instance of cache to store compiled schemas using stable-stringified schema as a key. For example, set-associative cache [sacjs](https://github.com/epoberezkin/sacjs) can be used. If not passed then a simple hash is used which is good enough for the common use case (a limited number of statically defined schemas). Cache should have methods `put(key, value)`, `get(key)`, `del(key)` and `clear()`.\n- _serialize_: an optional function to serialize schema to cache key. Pass `false` to use schema itself as a key (e.g., if WeakMap used as a cache). By default [fast-json-stable-stringify](https://github.com/epoberezkin/fast-json-stable-stringify) is used.\n\n\n## Validation errors\n\nIn case of validation failure, Ajv assigns the array of errors to `errors` property of validation function (or to `errors` property of Ajv instance when `validate` or `validateSchema` methods were called). In case of [asynchronous validation](#asynchronous-validation), the returned promise is rejected with exception `Ajv.ValidationError` that has `errors` property.\n\n\n### Error objects\n\nEach error is an object with the following properties:\n\n- _keyword_: validation keyword.\n- _dataPath_: the path to the part of the data that was validated. By default `dataPath` uses JavaScript property access notation (e.g., `\".prop[1].subProp\"`). When the option `jsonPointers` is true (see [Options](#options)) `dataPath` will be set using JSON pointer standard (e.g., `\"/prop/1/subProp\"`).\n- _schemaPath_: the path (JSON-pointer as a URI fragment) to the schema of the keyword that failed validation.\n- _params_: the object with the additional information about error that can be used to create custom error messages (e.g., using [ajv-i18n](https://github.com/epoberezkin/ajv-i18n) package). See below for parameters set by all keywords.\n- _message_: the standard error message (can be excluded with option `messages` set to false).\n- _schema_: the schema of the keyword (added with `verbose` option).\n- _parentSchema_: the schema containing the keyword (added with `verbose` option)\n- _data_: the data validated by the keyword (added with `verbose` option).\n\n__Please note__: `propertyNames` keyword schema validation errors have an additional property `propertyName`, `dataPath` points to the object. After schema validation for each property name, if it is invalid an additional error is added with the property `keyword` equal to `\"propertyNames\"`.\n\n\n### Error parameters\n\nProperties of `params` object in errors depend on the keyword that failed validation.\n\n- `maxItems`, `minItems`, `maxLength`, `minLength`, `maxProperties`, `minProperties` - property `limit` (number, the schema of the keyword).\n- `additionalItems` - property `limit` (the maximum number of allowed items in case when `items` keyword is an array of schemas and `additionalItems` is false).\n- `additionalProperties` - property `additionalProperty` (the property not used in `properties` and `patternProperties` keywords).\n- `dependencies` - properties:\n - `property` (dependent property),\n - `missingProperty` (required missing dependency - only the first one is reported currently)\n - `deps` (required dependencies, comma separated list as a string),\n - `depsCount` (the number of required dependencies).\n- `format` - property `format` (the schema of the keyword).\n- `maximum`, `minimum` - properties:\n - `limit` (number, the schema of the keyword),\n - `exclusive` (boolean, the schema of `exclusiveMaximum` or `exclusiveMinimum`),\n - `comparison` (string, comparison operation to compare the data to the limit, with the data on the left and the limit on the right; can be \"<\", \"<=\", \">\", \">=\")\n- `multipleOf` - property `multipleOf` (the schema of the keyword)\n- `pattern` - property `pattern` (the schema of the keyword)\n- `required` - property `missingProperty` (required property that is missing).\n- `propertyNames` - property `propertyName` (an invalid property name).\n- `patternRequired` (in ajv-keywords) - property `missingPattern` (required pattern that did not match any property).\n- `type` - property `type` (required type(s), a string, can be a comma-separated list)\n- `uniqueItems` - properties `i` and `j` (indices of duplicate items).\n- `const` - property `allowedValue` pointing to the value (the schema of the keyword).\n- `enum` - property `allowedValues` pointing to the array of values (the schema of the keyword).\n- `$ref` - property `ref` with the referenced schema URI.\n- `oneOf` - property `passingSchemas` (array of indices of passing schemas, null if no schema passes).\n- custom keywords (in case keyword definition doesn't create errors) - property `keyword` (the keyword name).\n\n\n## Plugins\n\nAjv can be extended with plugins that add custom keywords, formats or functions to process generated code. When such plugin is published as npm package it is recommended that it follows these conventions:\n\n- it exports a function\n- this function accepts ajv instance as the first parameter and returns the same instance to allow chaining\n- this function can accept an optional configuration as the second parameter\n\nIf you have published a useful plugin please submit a PR to add it to the next section.\n\n\n## Related packages\n\n- [ajv-async](https://github.com/epoberezkin/ajv-async) - plugin to configure async validation mode\n- [ajv-cli](https://github.com/jessedc/ajv-cli) - command line interface\n- [ajv-errors](https://github.com/epoberezkin/ajv-errors) - plugin for custom error messages\n- [ajv-i18n](https://github.com/epoberezkin/ajv-i18n) - internationalised error messages\n- [ajv-istanbul](https://github.com/epoberezkin/ajv-istanbul) - plugin to instrument generated validation code to measure test coverage of your schemas\n- [ajv-keywords](https://github.com/epoberezkin/ajv-keywords) - plugin with custom validation keywords (if/then/else, select, typeof, etc.)\n- [ajv-merge-patch](https://github.com/epoberezkin/ajv-merge-patch) - plugin with keywords $merge and $patch\n- [ajv-pack](https://github.com/epoberezkin/ajv-pack) - produces a compact module exporting validation functions\n\n\n## Some packages using Ajv\n\n- [webpack](https://github.com/webpack/webpack) - a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser\n- [jsonscript-js](https://github.com/JSONScript/jsonscript-js) - the interpreter for [JSONScript](http://www.jsonscript.org) - scripted processing of existing endpoints and services\n- [osprey-method-handler](https://github.com/mulesoft-labs/osprey-method-handler) - Express middleware for validating requests and responses based on a RAML method object, used in [osprey](https://github.com/mulesoft/osprey) - validating API proxy generated from a RAML definition\n- [har-validator](https://github.com/ahmadnassri/har-validator) - HTTP Archive (HAR) validator\n- [jsoneditor](https://github.com/josdejong/jsoneditor) - a web-based tool to view, edit, format, and validate JSON http://jsoneditoronline.org\n- [JSON Schema Lint](https://github.com/nickcmaynard/jsonschemalint) - a web tool to validate JSON/YAML document against a single JSON Schema http://jsonschemalint.com\n- [objection](https://github.com/vincit/objection.js) - SQL-friendly ORM for Node.js\n- [table](https://github.com/gajus/table) - formats data into a string table\n- [ripple-lib](https://github.com/ripple/ripple-lib) - a JavaScript API for interacting with [Ripple](https://ripple.com) in Node.js and the browser\n- [restbase](https://github.com/wikimedia/restbase) - distributed storage with REST API & dispatcher for backend services built to provide a low-latency & high-throughput API for Wikipedia / Wikimedia content\n- [hippie-swagger](https://github.com/CacheControl/hippie-swagger) - [Hippie](https://github.com/vesln/hippie) wrapper that provides end to end API testing with swagger validation\n- [react-form-controlled](https://github.com/seeden/react-form-controlled) - React controlled form components with validation\n- [rabbitmq-schema](https://github.com/tjmehta/rabbitmq-schema) - a schema definition module for RabbitMQ graphs and messages\n- [@query/schema](https://www.npmjs.com/package/@query/schema) - stream filtering with a URI-safe query syntax parsing to JSON Schema\n- [chai-ajv-json-schema](https://github.com/peon374/chai-ajv-json-schema) - chai plugin to us JSON Schema with expect in mocha tests\n- [grunt-jsonschema-ajv](https://github.com/SignpostMarv/grunt-jsonschema-ajv) - Grunt plugin for validating files against JSON Schema\n- [extract-text-webpack-plugin](https://github.com/webpack-contrib/extract-text-webpack-plugin) - extract text from bundle into a file\n- [electron-builder](https://github.com/electron-userland/electron-builder) - a solution to package and build a ready for distribution Electron app\n- [addons-linter](https://github.com/mozilla/addons-linter) - Mozilla Add-ons Linter\n- [gh-pages-generator](https://github.com/epoberezkin/gh-pages-generator) - multi-page site generator converting markdown files to GitHub pages\n- [ESLint](https://github.com/eslint/eslint) - the pluggable linting utility for JavaScript and JSX\n\n\n## Tests\n\n```\nnpm install\ngit submodule update --init\nnpm test\n```\n\n## Contributing\n\nAll validation functions are generated using doT templates in [dot](https://github.com/epoberezkin/ajv/tree/master/lib/dot) folder. Templates are precompiled so doT is not a run-time dependency.\n\n`npm run build` - compiles templates to [dotjs](https://github.com/epoberezkin/ajv/tree/master/lib/dotjs) folder.\n\n`npm run watch` - automatically compiles templates when files in dot folder change\n\nPlease see [Contributing guidelines](https://github.com/epoberezkin/ajv/blob/master/CONTRIBUTING.md)\n\n\n## Changes history\n\nSee https://github.com/epoberezkin/ajv/releases\n\n__Please note__: [Changes in version 6.0.0](https://github.com/epoberezkin/ajv/releases/tag/v6.0.0).\n\n[Version 5.0.0](https://github.com/epoberezkin/ajv/releases/tag/5.0.0).\n\n[Version 4.0.0](https://github.com/epoberezkin/ajv/releases/tag/4.0.0).\n\n[Version 3.0.0](https://github.com/epoberezkin/ajv/releases/tag/3.0.0).\n\n[Version 2.0.0](https://github.com/epoberezkin/ajv/releases/tag/2.0.0).\n\n\n## License\n\n[MIT](https://github.com/epoberezkin/ajv/blob/master/LICENSE)\n", - "readmeFilename": "README.md", - "_id": "ajv@6.5.2", - "_requested": { - "type": "version", - "registry": true, - "raw": "ajv@6.5.2", - "name": "ajv", - "escapedName": "ajv", - "rawSpec": "6.5.2", - "saveSpec": "[Circular]", - "fetchSpec": "6.5.2" - }, - "_spec": "6.5.2", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "ajv@6.5.2", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "optionalDependencies": {}, - "_dependencies": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.1" - }, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/ajv", - "error": "[Circular]", - "extraneous": false - }, - "ajv-keywords": { - "name": "ajv-keywords", - "version": "3.2.0", - "description": "Custom JSON-Schema keywords for Ajv validator", - "main": "index.js", - "scripts": { - "build": "node node_modules/ajv/scripts/compile-dots.js node_modules/ajv/lib keywords", - "prepublish": "npm run build", - "test": "npm run build && npm run eslint && npm run test-cov", - "eslint": "eslint index.js keywords/*.js", - "test-spec": "mocha spec/*.spec.js -R spec", - "test-cov": "istanbul cover -x 'spec/**' node_modules/mocha/bin/_mocha -- spec/*.spec.js -R spec" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/epoberezkin/ajv-keywords.git" - }, - "keywords": [ - "JSON-Schema", - "ajv", - "keywords" - ], - "files": [ - "index.js", - "keywords" - ], - "author": { - "name": "Evgeny Poberezkin" - }, - "license": "MIT", - "bugs": { - "url": "https://github.com/epoberezkin/ajv-keywords/issues" - }, - "homepage": "https://github.com/epoberezkin/ajv-keywords#readme", - "peerDependencies": { - "ajv": "^6.0.0" - }, - "devDependencies": { - "ajv": "^6.0.0", - "ajv-pack": "^0.3.0", - "chai": "^4.0.2", - "coveralls": "^3.0.0", - "dot": "^1.1.1", - "eslint": "^4.9.0", - "glob": "^7.1.1", - "istanbul": "^0.4.3", - "js-beautify": "^1.7.4", - "json-schema-test": "^2.0.0", - "mocha": "^5.0.0", - "pre-commit": "^1.1.3", - "uuid": "^3.0.1" - }, - "_resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz", - "_integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=", - "_from": "ajv-keywords@3.2.0", - "readme": "# ajv-keywords\n\nCustom JSON-Schema keywords for [Ajv](https://github.com/epoberezkin/ajv) validator\n\n[![Build Status](https://travis-ci.org/epoberezkin/ajv-keywords.svg?branch=master)](https://travis-ci.org/epoberezkin/ajv-keywords)\n[![npm](https://img.shields.io/npm/v/ajv-keywords.svg)](https://www.npmjs.com/package/ajv-keywords)\n[![npm downloads](https://img.shields.io/npm/dm/ajv-keywords.svg)](https://www.npmjs.com/package/ajv-keywords)\n[![Coverage Status](https://coveralls.io/repos/github/epoberezkin/ajv-keywords/badge.svg?branch=master)](https://coveralls.io/github/epoberezkin/ajv-keywords?branch=master)\n[![Greenkeeper badge](https://badges.greenkeeper.io/epoberezkin/ajv-keywords.svg)](https://greenkeeper.io/)\n[![Gitter](https://img.shields.io/gitter/room/ajv-validator/ajv.svg)](https://gitter.im/ajv-validator/ajv)\n\n\n## Contents\n\n- [Install](#install)\n- [Usage](#usage)\n- [Keywords](#keywords)\n - [typeof](#typeof)\n - [instanceof](#instanceof)\n - [range and exclusiveRange](#range-and-exclusiverange)\n - [switch](#switch)\n - [select/selectCases/selectDefault](#selectselectcasesselectdefault) (BETA)\n - [patternRequired](#patternrequired)\n - [prohibited](#prohibited)\n - [deepProperties](#deepproperties)\n - [deepRequired](#deeprequired)\n - [uniqueItemProperties](#uniqueitemproperties)\n - [regexp](#regexp)\n - [formatMaximum / formatMinimum and formatExclusiveMaximum / formatExclusiveMinimum](#formatmaximum--formatminimum-and-formatexclusivemaximum--formatexclusiveminimum)\n - [dynamicDefaults](#dynamicdefaults)\n - [transform](#transform)\n- [License](#license)\n\n\n## Install\n\n```\nnpm install ajv-keywords\n```\n\n\n## Usage\n\nTo add all available keywords:\n\n```javascript\nvar Ajv = require('ajv');\nvar ajv = new Ajv;\nrequire('ajv-keywords')(ajv);\n\najv.validate({ instanceof: 'RegExp' }, /.*/); // true\najv.validate({ instanceof: 'RegExp' }, '.*'); // false\n```\n\nTo add a single keyword:\n\n```javascript\nrequire('ajv-keywords')(ajv, 'instanceof');\n```\n\nTo add multiple keywords:\n\n```javascript\nrequire('ajv-keywords')(ajv, ['typeof', 'instanceof']);\n```\n\nTo add a single keyword in browser (to avoid adding unused code):\n\n```javascript\nrequire('ajv-keywords/keywords/instanceof')(ajv);\n```\n\n\n## Keywords\n\n### `typeof`\n\nBased on JavaScript `typeof` operation.\n\nThe value of the keyword should be a string (`\"undefined\"`, `\"string\"`, `\"number\"`, `\"object\"`, `\"function\"`, `\"boolean\"` or `\"symbol\"`) or array of strings.\n\nTo pass validation the result of `typeof` operation on the value should be equal to the string (or one of the strings in the array).\n\n```\najv.validate({ typeof: 'undefined' }, undefined); // true\najv.validate({ typeof: 'undefined' }, null); // false\najv.validate({ typeof: ['undefined', 'object'] }, null); // true\n```\n\n\n### `instanceof`\n\nBased on JavaScript `instanceof` operation.\n\nThe value of the keyword should be a string (`\"Object\"`, `\"Array\"`, `\"Function\"`, `\"Number\"`, `\"String\"`, `\"Date\"`, `\"RegExp\"`, `\"Promise\"` or `\"Buffer\"`) or array of strings.\n\nTo pass validation the result of `data instanceof ...` operation on the value should be true:\n\n```\najv.validate({ instanceof: 'Array' }, []); // true\najv.validate({ instanceof: 'Array' }, {}); // false\najv.validate({ instanceof: ['Array', 'Function'] }, function(){}); // true\n```\n\nYou can add your own constructor function to be recognised by this keyword:\n\n```javascript\nfunction MyClass() {}\nvar instanceofDefinition = require('ajv-keywords').get('instanceof').definition;\n// or require('ajv-keywords/keywords/instanceof').definition;\ninstanceofDefinition.CONSTRUCTORS.MyClass = MyClass;\n\najv.validate({ instanceof: 'MyClass' }, new MyClass); // true\n```\n\n\n### `range` and `exclusiveRange`\n\nSyntax sugar for the combination of minimum and maximum keywords, also fails schema compilation if there are no numbers in the range.\n\nThe value of this keyword must be the array consisting of two numbers, the second must be greater or equal than the first one.\n\nIf the validated value is not a number the validation passes, otherwise to pass validation the value should be greater (or equal) than the first number and smaller (or equal) than the second number in the array. If `exclusiveRange` keyword is present in the same schema and its value is true, the validated value must not be equal to the range boundaries.\n\n```javascript\nvar schema = { range: [1, 3] };\najv.validate(schema, 1); // true\najv.validate(schema, 2); // true\najv.validate(schema, 3); // true\najv.validate(schema, 0.99); // false\najv.validate(schema, 3.01); // false\n\nvar schema = { range: [1, 3], exclusiveRange: true };\najv.validate(schema, 1.01); // true\najv.validate(schema, 2); // true\najv.validate(schema, 2.99); // true\najv.validate(schema, 1); // false\najv.validate(schema, 3); // false\n```\n\n\n### `switch`\n\nThis keyword allows to perform advanced conditional validation.\n\nThe value of the keyword is the array of if/then clauses. Each clause is the object with the following properties:\n\n- `if` (optional) - the value is JSON-schema\n- `then` (required) - the value is JSON-schema or boolean\n- `continue` (optional) - the value is boolean\n\nThe validation process is dynamic; all clauses are executed sequentially in the following way:\n\n1. `if`:\n 1. `if` property is JSON-schema according to which the data is:\n 1. valid => go to step 2.\n 2. invalid => go to the NEXT clause, if this was the last clause the validation of `switch` SUCCEEDS.\n 2. `if` property is absent => go to step 2.\n2. `then`:\n 1. `then` property is `true` or it is JSON-schema according to which the data is valid => go to step 3.\n 2. `then` property is `false` or it is JSON-schema according to which the data is invalid => the validation of `switch` FAILS.\n3. `continue`:\n 1. `continue` property is `true` => go to the NEXT clause, if this was the last clause the validation of `switch` SUCCEEDS.\n 2. `continue` property is `false` or absent => validation of `switch` SUCCEEDS.\n\n```javascript\nrequire('ajv-keywords')(ajv, 'switch');\n\nvar schema = {\n type: 'array',\n items: {\n type: 'integer',\n 'switch': [\n { if: { not: { minimum: 1 } }, then: false },\n { if: { maximum: 10 }, then: true },\n { if: { maximum: 100 }, then: { multipleOf: 10 } },\n { if: { maximum: 1000 }, then: { multipleOf: 100 } },\n { then: false }\n ]\n }\n};\n\nvar validItems = [1, 5, 10, 20, 50, 100, 200, 500, 1000];\n\nvar invalidItems = [1, 0, 2000, 11, 57, 123, 'foo'];\n```\n\n__Please note__: this keyword is moved here from Ajv, mainly to preserve backward compatibility. It is unlikely to become a standard. It's preferable to use `if`/`then`/`else` keywords if possible, as they are likely to be added to the standard. The above schema is equivalent to (for example):\n\n```javascript\n{\n type: 'array',\n items: {\n type: 'integer',\n if: { minimum: 1, maximum: 10 },\n then: true,\n else: {\n if: { maximum: 100 },\n then: { multipleOf: 10 },\n else: {\n if: { maximum: 1000 },\n then: { multipleOf: 100 },\n else: false\n }\n }\n }\n}\n```\n\n\n### `select`/`selectCases`/`selectDefault`\n\nThese keywords allow to choose the schema to validate the data based on the value of some property in the validated data.\n\nThese keywords must be present in the same schema object (`selectDefault` is optional).\n\nThe value of `select` keyword should be a [$data reference](https://github.com/epoberezkin/ajv/tree/5.0.2-beta.0#data-reference) that points to any primitive JSON type (string, number, boolean or null) in the data that is validated. You can also use a constant of primitive type as the value of this keyword (e.g., for debugging purposes).\n\nThe value of `selectCases` keyword must be an object where each property name is a possible string representation of the value of `select` keyword and each property value is a corresponding schema (from draft-06 it can be boolean) that must be used to validate the data.\n\nThe value of `selectDefault` keyword is a schema (from draft-06 it can be boolean) that must be used to validate the data in case `selectCases` has no key equal to the stringified value of `select` keyword.\n\nThe validation succeeds in one of the following cases:\n- the validation of data using selected schema succeeds,\n- none of the schemas is selected for validation,\n- the value of select is undefined (no property in the data that the data reference points to).\n\nIf `select` value (in data) is not a primitive type the validation fails.\n\n__Please note__: these keywords require Ajv `$data` option to support [$data reference](https://github.com/epoberezkin/ajv/tree/5.0.2-beta.0#data-reference).\n\n\n```javascript\nrequire('ajv-keywords')(ajv, 'select');\n\nvar schema = {\n type: object,\n required: ['kind'],\n properties: {\n kind: { type: 'string' }\n },\n select: { $data: '0/kind' },\n selectCases: {\n foo: {\n required: ['foo'],\n properties: {\n kind: {},\n foo: { type: 'string' }\n },\n additionalProperties: false\n },\n bar: {\n required: ['bar'],\n properties: {\n kind: {},\n bar: { type: 'number' }\n },\n additionalProperties: false\n }\n },\n selectDefault: {\n propertyNames: {\n not: { enum: ['foo', 'bar'] }\n }\n }\n};\n\nvar validDataList = [\n { kind: 'foo', foo: 'any' },\n { kind: 'bar', bar: 1 },\n { kind: 'anything_else', not_bar_or_foo: 'any value' }\n];\n\nvar invalidDataList = [\n { kind: 'foo' }, // no propery foo\n { kind: 'bar' }, // no propery bar\n { kind: 'foo', foo: 'any', another: 'any value' }, // additional property\n { kind: 'bar', bar: 1, another: 'any value' }, // additional property\n { kind: 'anything_else', foo: 'any' } // property foo not allowed\n { kind: 'anything_else', bar: 1 } // property bar not allowed\n];\n```\n\n__Please note__: the current implementation is BETA. It does not allow using relative URIs in $ref keywords in schemas in `selectCases` and `selectDefault` that point outside of these schemas. The workaround is to use absolute URIs (that can point to any (sub-)schema added to Ajv, including those inside the current root schema where `select` is used). See [tests](https://github.com/epoberezkin/ajv-keywords/blob/v2.0.0/spec/tests/select.json#L314).\n\n\n### `patternRequired`\n\nThis keyword allows to require the presence of properties that match some pattern(s).\n\nThis keyword applies only to objects. If the data is not an object, the validation succeeds.\n\nThe value of this keyword should be an array of strings, each string being a regular expression. For data object to be valid each regular expression in this array should match at least one property name in the data object.\n\nIf the array contains multiple regular expressions, more than one expression can match the same property name.\n\n```javascript\nvar schema = { patternRequired: [ 'f.*o', 'b.*r' ] };\n\nvar validData = { foo: 1, bar: 2 };\nvar alsoValidData = { foobar: 3 };\n\nvar invalidDataList = [ {}, { foo: 1 }, { bar: 2 } ];\n```\n\n\n### `prohibited`\n\nThis keyword allows to prohibit that any of the properties in the list is present in the object.\n\nThis keyword applies only to objects. If the data is not an object, the validation succeeds.\n\nThe value of this keyword should be an array of strings, each string being a property name. For data object to be valid none of the properties in this array should be present in the object.\n\n```\nvar schema = { prohibited: ['foo', 'bar']};\n\nvar validData = { baz: 1 };\nvar alsoValidData = {};\n\nvar invalidDataList = [\n { foo: 1 },\n { bar: 2 },\n { foo: 1, bar: 2}\n];\n```\n\n\n### `deepProperties`\n\nThis keyword allows to validate deep properties (identified by JSON pointers).\n\nThis keyword applies only to objects. If the data is not an object, the validation succeeds.\n\nThe value should be an object, where keys are JSON pointers to the data, starting from the current position in data, and the values are JSON schemas. For data object to be valid the value of each JSON pointer should be valid according to the corresponding schema.\n\n```javascript\nvar schema = {\n type: 'object',\n deepProperties: {\n \"/users/1/role\": { \"enum\": [\"admin\"] }\n }\n};\n\nvar validData = {\n users: [\n {},\n {\n id: 123,\n role: 'admin'\n }\n ]\n};\n\nvar alsoValidData = {\n users: {\n \"1\": {\n id: 123,\n role: 'admin'\n }\n }\n};\n\nvar invalidData = {\n users: [\n {},\n {\n id: 123,\n role: 'user'\n }\n ]\n};\n\nvar alsoInvalidData = {\n users: {\n \"1\": {\n id: 123,\n role: 'user'\n }\n }\n};\n```\n\n\n### `deepRequired`\n\nThis keyword allows to check that some deep properties (identified by JSON pointers) are available.\n\nThis keyword applies only to objects. If the data is not an object, the validation succeeds.\n\nThe value should be an array of JSON pointers to the data, starting from the current position in data. For data object to be valid each JSON pointer should be some existing part of the data.\n\n```javascript\nvar schema = {\n type: 'object',\n deepRequired: [\"/users/1/role\"]\n};\n\nvar validData = {\n users: [\n {},\n {\n id: 123,\n role: 'admin'\n }\n ]\n};\n\nvar invalidData = {\n users: [\n {},\n {\n id: 123\n }\n ]\n};\n```\n\nSee [json-schema-org/json-schema-spec#203](https://github.com/json-schema-org/json-schema-spec/issues/203#issue-197211916) for an example of the equivalent schema without `deepRequired` keyword.\n\n\n### `uniqueItemProperties`\n\nThe keyword allows to check that some properties in array items are unique.\n\nThis keyword applies only to arrays. If the data is not an array, the validation succeeds.\n\nThe value of this keyword must be an array of strings - property names that should have unique values across all items.\n\n```javascript\nvar schema = { uniqueItemProperties: [ \"id\", \"name\" ] };\n\nvar validData = [\n { id: 1 },\n { id: 2 },\n { id: 3 }\n];\n\nvar invalidData1 = [\n { id: 1 },\n { id: 1 },\n { id: 3 }\n];\n\nvar invalidData2 = [\n { id: 1, name: \"taco\" },\n { id: 2, name: \"taco\" }, // duplicate \"name\"\n { id: 3, name: \"salsa\" }\n];\n```\n\nThis keyword is contributed by [@blainesch](https://github.com/blainesch).\n\n\n### `regexp`\n\nThis keyword allows to use regular expressions with flags in schemas (the standard `pattern` keyword does not support flags).\n\nThis keyword applies only to strings. If the data is not a string, the validation succeeds.\n\nThe value of this keyword can be either a string (the result of `regexp.toString()`) or an object with the properties `pattern` and `flags` (the same strings that should be passed to RegExp constructor).\n\n```javascript\nvar schema = {\n type: 'object',\n properties: {\n foo: { regexp: '/foo/i' },\n bar: { regexp: { pattern: 'bar', flags: 'i' } }\n }\n};\n\nvar validData = {\n foo: 'Food',\n bar: 'Barmen'\n};\n\nvar invalidData = {\n foo: 'fog',\n bar: 'bad'\n};\n```\n\n\n### `formatMaximum` / `formatMinimum` and `formatExclusiveMaximum` / `formatExclusiveMinimum`\n\nThese keywords allow to define minimum/maximum constraints when the format keyword defines ordering.\n\nThese keywords apply only to strings. If the data is not a string, the validation succeeds.\n\nThe value of keyword `formatMaximum` (`formatMinimum`) should be a string. This value is the maximum (minimum) allowed value for the data to be valid as determined by `format` keyword.\n\nWhen this keyword is added, it defines comparison rules for formats `\"date\"`, `\"time\"` and `\"date-time\". Custom formats also can have comparison rules. See [addFormat](https://github.com/epoberezkin/ajv#api-addformat) method.\n\nThe value of keyword `formatExclusiveMaximum` (`formatExclusiveMinimum`) should be a boolean value. These keyword cannot be used without `formatMaximum` (`formatMinimum`). If this keyword value is equal to `true`, the data to be valid should not be equal to the value in `formatMaximum` (`formatMinimum`) keyword.\n\n```javascript\nrequire('ajv-keywords')(ajv, ['formatMinimum', 'formatMaximum']);\n\nvar schema = {\n format: 'date',\n formatMinimum: '2016-02-06',\n formatMaximum: '2016-12-27',\n formatExclusiveMaximum: true\n}\n\nvar validDataList = ['2016-02-06', '2016-12-26', 1];\n\nvar invalidDataList = ['2016-02-05', '2016-12-27', 'abc'];\n```\n\n\n### `dynamicDefaults`\n\nThis keyword allows to assign dynamic defaults to properties, such as timestamps, unique IDs etc.\n\nThis keyword only works if `useDefaults` options is used and not inside `anyOf` keywrods etc., in the same way as [default keyword treated by Ajv](https://github.com/epoberezkin/ajv#assigning-defaults).\n\nThe keyword should be added on the object level. Its value should be an object with each property corresponding to a property name, in the same way as in standard `properties` keyword. The value of each property can be:\n\n- an identifier of default function (a string)\n- an object with properties `func` (an identifier) and `args` (an object with parameters that will be passed to this function during schema compilation - see examples).\n\nThe properties used in `dynamicDefaults` should not be added to `required` keyword (or validation will fail), because unlike `default` this keyword is processed after validation.\n\nThere are several predefined dynamic default functions:\n\n- `\"timestamp\"` - current timestamp in milliseconds\n- `\"datetime\"` - current date and time as string (ISO, valid according to `date-time` format)\n- `\"date\"` - current date as string (ISO, valid according to `date` format)\n- `\"time\"` - current time as string (ISO, valid according to `time` format)\n- `\"random\"` - pseudo-random number in [0, 1) interval\n- `\"randomint\"` - pseudo-random integer number. If string is used as a property value, the function will randomly return 0 or 1. If object `{func: 'randomint', max: N}` is used then the default will be an integer number in [0, N) interval.\n- `\"seq\"` - sequential integer number starting from 0. If string is used as a property value, the default sequence will be used. If object `{func: 'seq', name: 'foo'}` is used then the sequence with name `\"foo\"` will be used. Sequences are global, even if different ajv instances are used.\n\n```javascript\nvar schema = {\n type: 'object',\n dynamicDefaults: {\n ts: 'datetime',\n r: { func: 'randomint', max: 100 },\n id: { func: 'seq', name: 'id' }\n },\n properties: {\n ts: {\n type: 'string',\n format: 'datetime'\n },\n r: {\n type: 'integer',\n minimum: 0,\n maximum: 100,\n exclusiveMaximum: true\n },\n id: {\n type: 'integer',\n minimum: 0\n }\n }\n};\n\nvar data = {};\najv.validate(data); // true\ndata; // { ts: '2016-12-01T22:07:28.829Z', r: 25, id: 0 }\n\nvar data1 = {};\najv.validate(data1); // true\ndata1; // { ts: '2016-12-01T22:07:29.832Z', r: 68, id: 1 }\n\najv.validate(data1); // true\ndata1; // didn't change, as all properties were defined\n```\n\nYou can add your own dynamic default function to be recognised by this keyword:\n\n```javascript\nvar uuid = require('uuid');\n\nfunction uuidV4() { return uuid.v4(); }\n\nvar definition = require('ajv-keywords').get('dynamicDefaults').definition;\n// or require('ajv-keywords/keywords/dynamicDefaults').definition;\ndefinition.DEFAULTS.uuid = uuidV4;\n\nvar schema = {\n dynamicDefaults: { id: 'uuid' },\n properties: { id: { type: 'string', format: 'uuid' } }\n};\n\nvar data = {};\najv.validate(schema, data); // true\ndata; // { id: 'a1183fbe-697b-4030-9bcc-cfeb282a9150' };\n\nvar data1 = {};\najv.validate(schema, data1); // true\ndata1; // { id: '5b008de7-1669-467a-a5c6-70fa244d7209' }\n```\n\nYou also can define dynamic default that accepts parameters, e.g. version of uuid:\n\n```javascript\nvar uuid = require('uuid');\n\nfunction getUuid(args) {\n var version = 'v' + (arvs && args.v || 4);\n return function() {\n return uuid[version]();\n };\n}\n\nvar definition = require('ajv-keywords').get('dynamicDefaults').definition;\ndefinition.DEFAULTS.uuid = getUuid;\n\nvar schema = {\n dynamicDefaults: {\n id1: 'uuid', // v4\n id2: { func: 'uuid', v: 4 }, // v4\n id3: { func: 'uuid', v: 1 } // v1\n }\n};\n```\n\n### `transform`\n\nThis keyword allows a string to be modified before validation. \n\nThese keywords apply only to strings. If the data is not a string, the transform is skipped.\n\nThere are limitation due to how ajv is written:\n- a stand alone string cannot be transformed. ie `data = 'a'; ajv.validate(schema, data);`\n- currently cannot work with `ajv-pack`\n\n**Supported options:**\n- `trim`: remove whitespace from start and end\n- `trimLeft`: remove whitespace from start\n- `trimRight`: remove whitespace from end\n- `toLowerCase`: case string to all lower case\n- `toUpperCase`: case string to all upper case\n- `toEnumCase`: case string to match case in schema\n\nOptions are applied in the order they are listed.\n\nNote: `toEnumCase` requires that all allowed values are unique when case insensitive.\n\n**Example: multiple options**\n```javascript\nrequire('ajv-keywords')(ajv, ['transform']);\n\nvar schema = {\n type: 'array',\n items: {\n type:'string',\n transform:['trim','lowercase']\n }\n};\n\nvar data = [' MixCase '];\navj.validate(schema, data);\nconsole.log(data); // ['mixcase']\n\n```\n\n**Example: `enumcase`**\n```javascript\nrequire('ajv-keywords')(ajv, ['transform']);\n\nvar schema = {\n type: 'array',\n items: {\n type:'string',\n transform:['trim','enumcase'],\n enum:['pH']\n }\n};\n\nvar data = ['ph',' Ph','PH','pH '];\navj.validate(schema, data);\nconsole.log(data); // ['pH','pH','pH','pH']\n```\n\n\n## License\n\n[MIT](https://github.com/epoberezkin/ajv-keywords/blob/master/LICENSE)\n", - "readmeFilename": "README.md", - "_id": "ajv-keywords@3.2.0", - "_requested": { - "type": "version", - "registry": true, - "raw": "ajv-keywords@3.2.0", - "name": "ajv-keywords", - "escapedName": "ajv-keywords", - "rawSpec": "3.2.0", - "saveSpec": "[Circular]", - "fetchSpec": "3.2.0" - }, - "_spec": "3.2.0", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "ajv-keywords@3.2.0", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "dependencies": {}, - "optionalDependencies": {}, - "_dependencies": {}, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/ajv-keywords", - "error": "[Circular]", - "extraneous": false - } - }, - "devDependencies": { - "@commitlint/cli": "^5.2.8", - "@commitlint/config-angular": "^5.1.1", - "@webpack-contrib/eslint-config-webpack": "^2.0.2", - "babel-cli": "^6.26.0", - "babel-jest": "^22.2.2", - "babel-plugin-transform-object-rest-spread": "^6.26.0", - "babel-polyfill": "^6.26.0", - "babel-preset-env": "^1.6.1", - "conventional-github-releaser": "^2.0.0", - "cross-env": "^5.1.3", - "del": "^3.0.0", - "del-cli": "^1.1.0", - "eslint": "^4.17.0", - "eslint-plugin-import": "^2.8.0", - "eslint-plugin-prettier": "^2.6.0", - "husky": "^0.14.3", - "jest": "^22.2.2", - "lint-staged": "^6.1.0", - "memory-fs": "^0.4.1", - "nsp": "^3.1.0", - "pre-commit": "^1.2.2", - "prettier": "^1.10.2", - "standard-version": "^4.3.0", - "webpack": "^3.11.0", - "webpack-defaults": "^2.0.0-rc.4" - }, - "engines": { - "node": ">= 4.8.0 || >= 6.9.0 || >= 8.9.0" - }, - "peerDependencies": { - "webpack": "^2.0.0 || ^3.0.0 || ^4.0.0" - }, - "homepage": "https://github.com/webpack-contrib/schema-utils", - "repository": { - "type": "git", - "url": "git+https://github.com/webpack-contrib/schema-utils.git" - }, - "bugs": { - "url": "https://github.com/webpack-contrib/schema-utils/issues" - }, - "pre-commit": "lint-staged", - "lint-staged": { - "*.js": [ - "eslint --fix", - "git add" - ] - }, - "_resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.5.tgz", - "_integrity": "sha512-yYrjb9TX2k/J1Y5UNy3KYdZq10xhYcF8nMpAW6o3hy6Q8WSIEf9lJHG/ePnOBfziPM3fvQwfOwa13U/Fh8qTfA==", - "_from": "schema-utils@0.4.5", - "readme": "[![npm][npm]][npm-url]\n[![node][node]][node-url]\n[![deps][deps]][deps-url]\n[![test][test]][test-url]\n[![coverage][cover]][cover-url]\n[![chat][chat]][chat-url]\n\n
\n \n \n \n \n \n \n

Schema Utils

\n
\n\n

Install

\n\n```bash\nnpm i schema-utils\n```\n\n

Usage

\n\n### `validateOptions`\n\n**schema.json**\n```js\n{\n \"type\": \"object\",\n \"properties\": {\n // Options...\n },\n \"additionalProperties\": false\n}\n```\n\n```js\nimport schema from 'path/to/schema.json'\nimport validateOptions from 'schema-utils'\n\nvalidateOptions(schema, options, 'Loader/Plugin Name')\n```\n\n

Examples

\n\n**schema.json**\n```json\n{\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"type\": \"string\"\n },\n \"test\": {\n \"anyOf\": [\n { \"type\": \"array\" },\n { \"type\": \"string\" },\n { \"instanceof\": \"RegExp\" }\n ]\n },\n \"transform\": {\n \"instanceof\": \"Function\"\n },\n \"sourceMap\": {\n \"type\": \"boolean\"\n }\n },\n \"additionalProperties\": false\n}\n```\n\n### `Loader`\n\n```js\nimport { getOptions } from 'loader-utils'\nimport validateOptions from 'schema-utils'\n\nimport schema from 'path/to/schema.json'\n\nfunction loader (src, map) {\n const options = getOptions(this) || {}\n\n validateOptions(schema, options, 'Loader Name')\n\n // Code...\n}\n```\n\n### `Plugin`\n\n```js\nimport validateOptions from 'schema-utils'\n\nimport schema from 'path/to/schema.json'\n\nclass Plugin {\n constructor (options) {\n validateOptions(schema, options, 'Plugin Name')\n\n this.options = options\n }\n\n apply (compiler) {\n // Code...\n }\n}\n```\n\n

Maintainers

\n\n\n \n \n \n \n \n \n \n
\n \n
\n Juho Vepsäläinen\n
\n \n
\n Joshua Wiens\n
\n \n
\n Michael Ciniawsky\n
\n\n\n[npm]: https://img.shields.io/npm/v/schema-utils.svg\n[npm-url]: https://npmjs.com/package/schema-utils\n\n[node]: https://img.shields.io/node/v/schema-utils.svg\n[node-url]: https://nodejs.org\n\n[deps]: https://david-dm.org/webpack-contrib/schema-utils.svg\n[deps-url]: https://david-dm.org/webpack-contrib/schema-utils\n\n[test]: http://img.shields.io/travis/webpack-contrib/schema-utils.svg\n[test-url]: https://travis-ci.org/webpack-contrib/schema-utils\n\n[cover]: https://codecov.io/gh/webpack-contrib/schema-utils/branch/master/graph/badge.svg\n[cover-url]: https://codecov.io/gh/webpack-contrib/schema-utils\n\n[chat]: https://img.shields.io/badge/gitter-webpack%2Fwebpack-brightgreen.svg\n[chat-url]: https://gitter.im/webpack/webpack\n", - "readmeFilename": "README.md", - "_id": "schema-utils@0.4.5", - "_requested": { - "type": "version", - "registry": true, - "raw": "schema-utils@0.4.5", - "name": "schema-utils", - "escapedName": "schema-utils", - "rawSpec": "0.4.5", - "saveSpec": "[Circular]", - "fetchSpec": "0.4.5" - }, - "_spec": "0.4.5", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "schema-utils@0.4.5", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "optionalDependencies": {}, - "_dependencies": { - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0" - }, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/schema-utils", - "error": "[Circular]", - "extraneous": false - } - }, - "devDependencies": { - "babel-cli": "^6.0.0", - "babel-jest": "^21.0.0", - "babel-plugin-transform-object-rest-spread": "^6.0.0", - "babel-polyfill": "^6.0.0", - "babel-preset-env": "^1.0.0", - "cross-env": "^5.0.0", - "del": "^3.0.0", - "del-cli": "^1.0.0", - "eslint": "^4.0.0", - "eslint-config-webpack": "^1.0.0", - "eslint-plugin-import": "^2.2.0", - "jest": "^21.0.0", - "lint-staged": "^4.0.0", - "nsp": "^2.6.0", - "pre-commit": "^1.0.0", - "standard-version": "^4.0.0", - "webpack": "^3.0.0", - "webpack-defaults": "^1.6.0" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/webpack-contrib/worker-loader.git" - }, - "bugs": { - "url": "https://github.com/webpack-contrib/worker-loader/issues" - }, - "homepage": "https://github.com/webpack-contrib/html-loader", - "license": "MIT", - "pre-commit": "lint-staged", - "lint-staged": { - "*.js": [ - "eslint --fix", - "git add" - ] - }, - "_resolved": "https://registry.npmjs.org/worker-loader/-/worker-loader-1.1.1.tgz", - "_integrity": "sha512-qJZLVS/jMCBITDzPo/RuweYSIG8VJP5P67mP/71alGyTZRe1LYJFdwLjLalY3T5ifx0bMDRD3OB6P2p1escvlg==", - "_from": "worker-loader@1.1.1", - "readme": "[![npm][npm]][npm-url]\r\n[![node][node]][node-url]\r\n[![deps][deps]][deps-url]\r\n[![test][test]][test-url]\r\n[![coverage][cover]][cover-url]\r\n[![chat][chat]][chat-url]\r\n\r\n
\r\n \r\n \r\n \r\n

Worker Loader

\r\n

This loader registers the script as Web Worker

\r\n

\r\n\r\n\r\n

Install

\r\n\r\n```bash\r\nnpm i -D worker-loader\r\n```\r\n\r\n

Usage

\r\n\r\n### `Inlined`\r\n\r\n**App.js**\r\n```js\r\nimport Worker from 'worker-loader!./Worker.js';\r\n```\r\n\r\n### `Config`\r\n\r\n**webpack.config.js**\r\n```js\r\n{\r\n module: {\r\n rules: [\r\n {\r\n test: /\\.worker\\.js$/,\r\n use: { loader: 'worker-loader' }\r\n }\r\n ]\r\n }\r\n}\r\n```\r\n\r\n**App.js**\r\n```js\r\nimport Worker from './file.worker.js';\r\n\r\nconst worker = new Worker();\r\n\r\nworker.postMessage({ a: 1 });\r\nworker.onmessage = function (event) {};\r\n\r\nworker.addEventListener(\"message\", function (event) {});\r\n```\r\n\r\n

Options

\r\n\r\n|Name|Type|Default|Description|\r\n|:--:|:--:|:-----:|:----------|\r\n|[**`name`**](#name)|`{String}`|`[hash].worker.js`|Set a custom name for the output script|\r\n|[**`inline`**](#inline)|`{Boolean}`|`false`|Inline the worker as a BLOB|\r\n|[**`fallback`**](#fallback)|`{Boolean}`|`false`|Require a fallback for non-worker supporting environments|\r\n|[**`publicPath`**](#publicPath)|`{String}`|`null`|Override the path from which worker scripts are downloaded|\r\n\r\n### `name`\r\n\r\nTo set a custom name for the output script, use the `name` parameter. The name may contain the string `[hash]`, which will be replaced with a content dependent hash for caching purposes\r\n\r\n*webpack.config.js**\r\n```js\r\n{\r\n loader: 'worker-loader',\r\n options: { name: 'WorkerName.[hash].js' }\r\n}\r\n```\r\n\r\n### `inline`\r\n\r\nYou can also inline the worker as a BLOB with the `inline` parameter\r\n\r\n**webpack.config.js**\r\n```js\r\n{\r\n loader: 'worker-loader',\r\n options: { inline: true }\r\n}\r\n```\r\n\r\n> ℹ️ Inline mode will also create chunks for browsers without support for inline workers, to disable this behavior just set `fallback` parameter as `false`\r\n\r\n**webpack.config.js**\r\n```js\r\n{\r\n loader: 'worker-loader'\r\n options: { inline: true, fallback: false }\r\n}\r\n```\r\n\r\n### `fallback`\r\n\r\nRequire a fallback for non-worker supporting environments\r\n\r\n**webpack.config.js**\r\n```js\r\n{\r\n loader: 'worker-loader'\r\n options: { fallback: false }\r\n}\r\n```\r\n\r\n### `publicPath`\r\n\r\nOverrides the path from which worker scripts are downloaded. If not specified, the same public path used for other\r\nwebpack assets is used\r\n\r\n**webpack.config.js**\r\n```js\r\n{\r\n loader: 'worker-loader'\r\n options: { publicPath: '/scripts/workers/' }\r\n}\r\n```\r\n\r\n

Examples

\r\n\r\nThe worker file can import dependencies just like any other file\r\n\r\n**Worker.js**\r\n```js\r\nconst _ = require('lodash')\r\n\r\nconst obj = { foo: 'foo' }\r\n\r\n_.has(obj, 'foo')\r\n\r\n// Post data to parent thread\r\nself.postMessage({ foo: 'foo' })\r\n\r\n// Respond to message from parent thread\r\nself.addEventListener('message', (event) => console.log(event)) \r\n```\r\n\r\n### `Integrating with ES2015 Modules`\r\n\r\n> ℹ️ You can even use ES2015 Modules if you have the [`babel-loader`](https://github.com/babel/babel-loader) configured.\r\n\r\n**Worker.js**\r\n```js\r\nimport _ from 'lodash'\r\n\r\nconst obj = { foo: 'foo' }\r\n\r\n_.has(obj, 'foo')\r\n\r\n// Post data to parent thread\r\nself.postMessage({ foo: 'foo' })\r\n\r\n// Respond to message from parent thread\r\nself.addEventListener('message', (event) => console.log(event))\r\n```\r\n\r\n### `Integrating with TypeScript`\r\n\r\nTo integrate with TypeScript, you will need to define a custom module for the exports of your worker\r\n\r\n**typings/custom.d.ts**\r\n```typescript\r\ndeclare module \"worker-loader!*\" {\r\n class WebpackWorker extends Worker {\r\n constructor();\r\n }\r\n\r\n export = WebpackWorker;\r\n}\r\n```\r\n\r\n**Worker.ts**\r\n```typescript\r\nconst ctx: Worker = self as any;\r\n\r\n// Post data to parent thread\r\nctx.postMessage({ foo: \"foo\" });\r\n\r\n// Respond to message from parent thread\r\nctx.addEventListener(\"message\", (event) => console.log(event));\r\n```\r\n\r\n**App.ts**\r\n```typescript\r\nimport Worker = require(\"worker-loader!./Worker\");\r\n\r\nconst worker = new Worker();\r\n\r\nworker.postMessage({ a: 1 });\r\nworker.onmessage = (event) => {};\r\n\r\nworker.addEventListener(\"message\", (event) => {});\r\n```\r\n\r\n### `Cross-Origin Policy`\r\n\r\n[`WebWorkers`](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) are restricted by a [same-origin policy](https://en.wikipedia.org/wiki/Same-origin_policy), so if your `webpack` assets are not being served from the same origin as your application, their download may be blocked by your browser. This scenario can commonly occur if you are hosting your assets under a CDN domain. Even downloads from the `webpack-dev-server` could be blocked. There are two workarounds\r\n\r\nFirstly, you can inline the worker as a blob instead of downloading it as an external script via the [`inline`](#inline) parameter\r\n\r\n**App.js**\r\n```js\r\nimport Worker from './file.worker.js';\r\n```\r\n\r\n**webpack.config.js**\r\n```js\r\n{\r\n loader: 'worker-loader'\r\n options: { inline: true }\r\n}\r\n```\r\n\r\nSecondly, you may override the base download URL for your worker script via the [`publicPath`](#publicpath) option\r\n\r\n**App.js**\r\n```js\r\n// This will cause the worker to be downloaded from `/workers/file.worker.js`\r\nimport Worker from './file.worker.js';\r\n```\r\n\r\n**webpack.config.js**\r\n```js\r\n{\r\n loader: 'worker-loader'\r\n options: { publicPath: '/workers/' }\r\n}\r\n```\r\n\r\n

Maintainers

\r\n\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n \r\n \r\n \r\n
\r\n Bogdan Chadkin\r\n
\r\n \r\n \r\n
\r\n Juho Vepsäläinen\r\n
\r\n
\r\n \r\n \r\n
\r\n Joshua Wiens\r\n
\r\n
\r\n \r\n \r\n
\r\n Michael Ciniawsky\r\n
\r\n
\r\n \r\n \r\n
\r\n Alexander Krasnoyarov\r\n
\r\n
\r\n\r\n\r\n[npm]: https://img.shields.io/npm/v/worker-loader.svg\r\n[npm-url]: https://npmjs.com/package/worker-loader\r\n\r\n[node]: https://img.shields.io/node/v/cache-loader.svg\r\n[node-url]: https://nodejs.org\r\n\r\n[deps]: https://david-dm.org/webpack-contrib/worker-loader.svg\r\n[deps-url]: https://david-dm.org/webpack-contrib/worker-loader\r\n\r\n[test]: http://img.shields.io/travis/webpack-contrib/worker-loader.svg\r\n[test-url]: https://travis-ci.org/webpack-contrib/worker-loader\r\n\r\n[cover]: https://codecov.io/gh/webpack-contrib/cache-loader/branch/master/graph/badge.svg\r\n[cover-url]: https://codecov.io/gh/webpack-contrib/cache-loader\r\n\r\n[chat]: https://img.shields.io/badge/gitter-webpack%2Fwebpack-brightgreen.svg\r\n[chat-url]: https://gitter.im/webpack/webpack\r\n", - "readmeFilename": "README.md", - "_id": "worker-loader@1.1.1", - "_requested": { - "type": "version", - "registry": true, - "raw": "worker-loader@1.1.1", - "name": "worker-loader", - "escapedName": "worker-loader", - "rawSpec": "1.1.1", - "saveSpec": "[Circular]", - "fetchSpec": "1.1.1" - }, - "_spec": "1.1.1", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "worker-loader@1.1.1", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "optionalDependencies": {}, - "_dependencies": { - "loader-utils": "^1.0.0", - "schema-utils": "^0.4.0" - }, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/worker-loader", - "error": "[Circular]", - "extraneous": false - } - }, - "peerDependencies": { - "webpack": "^2.0.0 || ^3.0.0" - }, - "browser": { - "fs": false, - "http": false, - "https": false, - "node-ensure": false - }, - "format": "amd", - "repository": { - "type": "git", - "url": "git+https://github.com/mozilla/pdfjs-dist.git" - }, - "_resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-2.0.489.tgz", - "_integrity": "sha1-Y+VLKSqGeQpFRpfrRNQ0e4+/rSc=", - "_from": "pdfjs-dist@2.0.489", - "readme": "# PDF.js\n\nPDF.js is a Portable Document Format (PDF) library that is built with HTML5.\nOur goal is to create a general-purpose, web standards-based platform for\nparsing and rendering PDFs.\n\nThis is a pre-built version of the PDF.js source code. It is automatically\ngenerated by the build scripts.\n\nSee https://github.com/mozilla/pdf.js for learning and contributing.\n", - "readmeFilename": "README.md", - "_id": "pdfjs-dist@2.0.489", - "_requested": { - "type": "version", - "registry": true, - "raw": "pdfjs-dist@2.0.489", - "name": "pdfjs-dist", - "escapedName": "pdfjs-dist", - "rawSpec": "2.0.489", - "saveSpec": "[Circular]", - "fetchSpec": "2.0.489" - }, - "_spec": "2.0.489", - "_where": "/Users/dvuika/github/alfresco-content-app", - "_args": [ - [ - "pdfjs-dist@2.0.489", - "/Users/dvuika/github/alfresco-content-app" - ] - ], - "devDependencies": {}, - "optionalDependencies": {}, - "_dependencies": { - "node-ensure": "^0.0.0", - "worker-loader": "^1.1.1" - }, - "path": "/Users/dvuika/github/alfresco-content-app/node_modules/pdfjs-dist", - "error": "[Circular]", - "extraneous": false, - "peerMissing": [ - { - "requiredBy": "@alfresco/adf-core@2.6.1", - "requires": "pdfjs-dist@2.0.303" - } - ] - }, - "peerMissing": true - }, - "rxjs": { - "version": "6.3.3", - "from": "rxjs@6.3.3", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz" - }, - "zone.js": { - "version": "0.8.26", - "from": "zone.js@0.8.26", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.8.26.tgz" - } - } -} From d7db57a76a981d8c4449ac81d9df59c4b92807e0 Mon Sep 17 00:00:00 2001 From: Suzana Dirla Date: Fri, 14 Dec 2018 14:14:12 +0200 Subject: [PATCH 002/259] [ACA-1904] Language labels (#879) --- src/app.config.json | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/app.config.json b/src/app.config.json index 0b6d1f9335..7870fd57be 100644 --- a/src/app.config.json +++ b/src/app.config.json @@ -43,7 +43,7 @@ "languages": [ { "key": "de", - "label": "German" + "label": "Deutsch" }, { "key": "en", @@ -51,39 +51,39 @@ }, { "key": "es", - "label": "Spanish" + "label": "Español" }, { "key": "fr", - "label": "French" + "label": "Français" }, { "key": "it", - "label": "Italian" + "label": "Italiano" }, { "key": "ja", - "label": "Japanese" + "label": "日本語" }, { "key": "nb", - "label": "Norwegian" + "label": "Bokmål" }, { "key": "nl", - "label": "Dutch" + "label": "Nederlands" }, { "key": "pt-BR", - "label": "Brazilian Portuguese" + "label": "Português (Brasil)" }, { "key": "ru", - "label": "Russian" + "label": "Русский" }, { "key": "zh-CN", - "label": "Simplified Chinese" + "label": "中文简体" } ], "content-metadata": { From 465646e87e726d16fc74876a8ee8d361262b7cfc Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Fri, 14 Dec 2018 13:24:37 +0000 Subject: [PATCH 003/259] [ACA-2083] reset router cache on login/logout (#867) * reset router cache on login/logout * Update src/app/app.routes.strategy.ts Co-Authored-By: DenysVuika * merge suggestion * [ACA-2083] reset content filters on logout * [ACA-2083] unit tests --- src/app/app.routes.strategy.spec.ts | 88 +++++++++++++++++++ src/app/app.routes.strategy.ts | 18 ++++ .../search-input/search-input.component.ts | 1 + src/app/services/app.service.spec.ts | 79 +++++++++++++++++ src/app/services/app.service.ts | 16 +++- 5 files changed, 199 insertions(+), 3 deletions(-) create mode 100644 src/app/app.routes.strategy.spec.ts create mode 100644 src/app/services/app.service.spec.ts diff --git a/src/app/app.routes.strategy.spec.ts b/src/app/app.routes.strategy.spec.ts new file mode 100644 index 0000000000..d8b79ea3c2 --- /dev/null +++ b/src/app/app.routes.strategy.spec.ts @@ -0,0 +1,88 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2018 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { AppRouteReuseStrategy } from './app.routes.strategy'; +import { TestBed } from '@angular/core/testing'; +import { AppTestingModule } from './testing/app-testing.module'; + +describe('AppRouteReuseStrategy', () => { + let appRouteReuse: AppRouteReuseStrategy; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [AppTestingModule], + providers: [AppRouteReuseStrategy] + }); + + appRouteReuse = TestBed.get(AppRouteReuseStrategy); + }); + + it('should allow detach if route is configured to be reused', () => { + const route = { + routeConfig: { + data: { + reuse: true + }, + path: 'tested-path' + } + }; + expect(appRouteReuse.shouldDetach(route)).toBe(true); + }); + + it('should store on routeCache', () => { + const route = { + url: [], + routeConfig: { + data: { + reuse: true + }, + path: 'tested-path', + component: {} + }, + firstChild: null, + children: [] + }; + appRouteReuse.store(route, { route: {} }); + expect(appRouteReuse.shouldAttach(route)).toBe(true); + }); + + it('should clear routeCache on resetCache', () => { + const route = { + url: [], + routeConfig: { + data: { + reuse: true + }, + path: 'tested-path', + component: {} + }, + firstChild: null, + children: [] + }; + appRouteReuse.store(route, { route: {} }); + appRouteReuse.resetCache(); + expect(appRouteReuse.shouldAttach(route)).toBe(false); + }); +}); diff --git a/src/app/app.routes.strategy.ts b/src/app/app.routes.strategy.ts index ff5c8e58d1..13415bed20 100644 --- a/src/app/app.routes.strategy.ts +++ b/src/app/app.routes.strategy.ts @@ -28,6 +28,7 @@ import { DetachedRouteHandle, ActivatedRouteSnapshot } from '@angular/router'; +import { ComponentRef } from '@angular/core'; interface RouteData { reuse: boolean; @@ -41,6 +42,23 @@ interface RouteInfo { export class AppRouteReuseStrategy implements RouteReuseStrategy { private routeCache = new Map(); + resetCache() { + this.routeCache.forEach(value => { + this.deactivateComponent(value.handle); + }); + this.routeCache.clear(); + } + + private deactivateComponent(handle: DetachedRouteHandle): void { + if (!handle) { + return; + } + const componentRef: ComponentRef = handle['componentRef']; + if (componentRef) { + componentRef.destroy(); + } + } + shouldReuseRoute( future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot diff --git a/src/app/components/search/search-input/search-input.component.ts b/src/app/components/search/search-input/search-input.component.ts index 1bf5121305..e2c4f4a70d 100644 --- a/src/app/components/search/search-input/search-input.component.ts +++ b/src/app/components/search/search-input/search-input.component.ts @@ -143,6 +143,7 @@ export class SearchInputComponent implements OnInit, OnDestroy { ngOnDestroy(): void { this.onDestroy$.next(true); this.onDestroy$.complete(); + this.removeContentFilters(); } onMenuOpened() { diff --git a/src/app/services/app.service.spec.ts b/src/app/services/app.service.spec.ts new file mode 100644 index 0000000000..442b9bfdc1 --- /dev/null +++ b/src/app/services/app.service.spec.ts @@ -0,0 +1,79 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2018 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { AppService } from './app.service'; +import { TestBed } from '@angular/core/testing'; +import { AppTestingModule } from '../testing/app-testing.module'; +import { AuthenticationService } from '@alfresco/adf-core'; +import { AppRouteReuseStrategy } from '../app.routes.strategy'; +import { Subject } from 'rxjs'; + +describe('AppService', () => { + let service: AppService; + let auth: AuthenticationService; + let routeReuse: AppRouteReuseStrategy; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [AppTestingModule], + providers: [ + AppRouteReuseStrategy, + { + provide: AuthenticationService, + useValue: { + onLogin: new Subject(), + onLogout: new Subject(), + isLoggedIn: () => false + } + } + ] + }); + + routeReuse = TestBed.get(AppRouteReuseStrategy); + auth = TestBed.get(AuthenticationService); + spyOn(routeReuse, 'resetCache').and.stub(); + + service = new AppService(auth, routeReuse); + }); + + it('should reset route cache on login', async () => { + auth.onLogin.next(); + await expect(routeReuse.resetCache).toHaveBeenCalled(); + }); + + it('should reset route cache on logout', async () => { + auth.onLogout.next(); + await expect(routeReuse.resetCache).toHaveBeenCalled(); + }); + + it('should be ready after login', async () => { + let isReady = false; + service.ready$.subscribe(value => { + isReady = value; + }); + auth.onLogin.next(); + await expect(isReady).toEqual(true); + }); +}); diff --git a/src/app/services/app.service.ts b/src/app/services/app.service.ts index 24b7f86e0b..259f972b13 100644 --- a/src/app/services/app.service.ts +++ b/src/app/services/app.service.ts @@ -23,9 +23,11 @@ * along with Alfresco. If not, see . */ -import { Injectable } from '@angular/core'; +import { Injectable, Inject } from '@angular/core'; import { AuthenticationService } from '@alfresco/adf-core'; import { Observable, BehaviorSubject } from 'rxjs'; +import { AppRouteReuseStrategy } from '../app.routes.strategy'; +import { RouteReuseStrategy } from '@angular/router'; @Injectable({ providedIn: 'root' @@ -34,12 +36,20 @@ export class AppService { private ready: BehaviorSubject; ready$: Observable; - constructor(auth: AuthenticationService) { + constructor( + auth: AuthenticationService, + @Inject(RouteReuseStrategy) routeStrategy: AppRouteReuseStrategy + ) { this.ready = new BehaviorSubject(auth.isLoggedIn()); this.ready$ = this.ready.asObservable(); - auth.onLogin.subscribe(e => { + auth.onLogin.subscribe(() => { + routeStrategy.resetCache(); this.ready.next(true); }); + + auth.onLogout.subscribe(() => { + routeStrategy.resetCache(); + }); } } From f68200a633c9c175ad1796002d41a75c75dc58a8 Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Mon, 17 Dec 2018 08:54:53 +0200 Subject: [PATCH 004/259] [ACA-2067] Side navigation - highlight element with children only when not expanded (#880) * highlight parent element condition * update test * e2e --- e2e/suites/navigation/sidebar.test.ts | 6 +-- .../components/sidenav/sidenav.component.html | 16 +++++--- .../sidenav/sidenav.component.spec.ts | 40 +++++++++++++++---- .../sidenav/sidenav.component.theme.scss | 4 ++ 4 files changed, 49 insertions(+), 17 deletions(-) diff --git a/e2e/suites/navigation/sidebar.test.ts b/e2e/suites/navigation/sidebar.test.ts index 0c9700206c..ed61a3dffc 100755 --- a/e2e/suites/navigation/sidebar.test.ts +++ b/e2e/suites/navigation/sidebar.test.ts @@ -53,21 +53,21 @@ describe('Sidebar', () => { it('My Libraries is automatically selected on expanding File Libraries - [C289900]', async () => { await page.clickFileLibraries(); expect(await browser.getCurrentUrl()).toContain(APP_ROUTES.MY_LIBRARIES); - expect(await sidenav.isActive(SIDEBAR_LABELS.FILE_LIBRARIES)).toBe(true, 'File Libraries link not active'); + expect(await sidenav.isActive(SIDEBAR_LABELS.FILE_LIBRARIES)).toBe(false, 'File Libraries link is active'); expect(await sidenav.childIsActive(SIDEBAR_LABELS.MY_LIBRARIES)).toBe(true, 'My Libraries link not active'); }); it('navigate to Favorite Libraries - [C289902]', async () => { await page.goToFavoriteLibraries(); expect(await browser.getCurrentUrl()).toContain(APP_ROUTES.FAVORITE_LIBRARIES); - expect(await sidenav.isActive(SIDEBAR_LABELS.FILE_LIBRARIES)).toBe(true, 'File Libraries link not active'); + expect(await sidenav.isActive(SIDEBAR_LABELS.FILE_LIBRARIES)).toBe(false, 'File Libraries link is active'); expect(await sidenav.childIsActive(SIDEBAR_LABELS.FAVORITE_LIBRARIES)).toBe(true, 'Favorite Libraries link not active'); }); it('navigate to My Libraries - [C289901]', async () => { await page.goToMyLibraries(); expect(await browser.getCurrentUrl()).toContain(APP_ROUTES.MY_LIBRARIES); - expect(await sidenav.isActive(SIDEBAR_LABELS.FILE_LIBRARIES)).toBe(true, 'File Libraries link not active'); + expect(await sidenav.isActive(SIDEBAR_LABELS.FILE_LIBRARIES)).toBe(false, 'File Libraries link is active'); expect(await sidenav.childIsActive(SIDEBAR_LABELS.MY_LIBRARIES)).toBe(true, 'My Libraries link not active'); }); diff --git a/src/app/components/sidenav/sidenav.component.html b/src/app/components/sidenav/sidenav.component.html index b0b9bef5c0..6315e13890 100644 --- a/src/app/components/sidenav/sidenav.component.html +++ b/src/app/components/sidenav/sidenav.component.html @@ -40,18 +40,22 @@ - {{ item.icon }} - + {{ item.icon }} + + - {{ item.title | translate }} + 'item--default': !routerLink.isActive && expansionPanel.expanded, + 'item--active': routerLink.isActive && !expansionPanel.expanded + }" + >{{ item.title | translate }} diff --git a/src/app/components/sidenav/sidenav.component.spec.ts b/src/app/components/sidenav/sidenav.component.spec.ts index 78a09728aa..16b374b4e0 100644 --- a/src/app/components/sidenav/sidenav.component.spec.ts +++ b/src/app/components/sidenav/sidenav.component.spec.ts @@ -26,29 +26,53 @@ import { NO_ERRORS_SCHEMA } from '@angular/core'; import { TestBed, async, ComponentFixture } from '@angular/core/testing'; import { SidenavComponent } from './sidenav.component'; -import { EffectsModule } from '@ngrx/effects'; -import { NodeEffects } from '../../store/effects/node.effects'; import { AppTestingModule } from '../../testing/app-testing.module'; -import { ExperimentalDirective } from '../../directives/experimental.directive'; +import { MatExpansionModule } from '@angular/material/expansion'; +import { AppExtensionService } from '../../extensions/extension.service'; describe('SidenavComponent', () => { let fixture: ComponentFixture; let component: SidenavComponent; + let extensionService: AppExtensionService; + const navbarMock = [ + { + items: [ + { + route: 'route' + } + ] + } + ]; beforeEach(async(() => { TestBed.configureTestingModule({ - imports: [AppTestingModule, EffectsModule.forRoot([NodeEffects])], - declarations: [SidenavComponent, ExperimentalDirective], + imports: [MatExpansionModule, AppTestingModule], + providers: [AppExtensionService], + declarations: [SidenavComponent], schemas: [NO_ERRORS_SCHEMA] }) .compileComponents() .then(() => { fixture = TestBed.createComponent(SidenavComponent); component = fixture.componentInstance; + extensionService = TestBed.get(AppExtensionService); + + extensionService.navbar = navbarMock; + + fixture.detectChanges(); }); })); - it('should be created', () => { - expect(component).toBeTruthy(); - }); + it('should set the sidenav data', async(() => { + expect(component.groups).toEqual([ + { + items: [ + { + route: 'route', + url: '/route' + } + ] + } + ]); + })); }); diff --git a/src/app/components/sidenav/sidenav.component.theme.scss b/src/app/components/sidenav/sidenav.component.theme.scss index 85ff9c878d..65e3c86fe6 100644 --- a/src/app/components/sidenav/sidenav.component.theme.scss +++ b/src/app/components/sidenav/sidenav.component.theme.scss @@ -41,6 +41,10 @@ color: mat-color($foreground, text); } + .item--label { + color: mat-color($primary, 0.87); + } + .item--active { color: mat-color($accent); } From af3af845aa0c1f43af36be1cdb7fd95f36dc3c13 Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Mon, 17 Dec 2018 16:43:27 +0200 Subject: [PATCH 005/259] add context menu (#881) --- .../search/search-results/search-results.component.html | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app/components/search/search-results/search-results.component.html b/src/app/components/search/search-results/search-results.component.html index a3795886f8..01ba634f67 100644 --- a/src/app/components/search/search-results/search-results.component.html +++ b/src/app/components/search/search-results/search-results.component.html @@ -40,6 +40,7 @@ Date: Thu, 20 Dec 2018 10:13:56 +0200 Subject: [PATCH 006/259] [ACA-2107] upgrade to ADF latest beta (#882) * [ACA-2107] upgrade ADF to latest beta * fix adf sidenav class name * [ACA-2107] update is-selected to adf-is-selected * [ACA-2107] add 'adf' prefix to classes name * [ACA-2107] remove ADF duplicate css style * [ACA-2107] use 'adf-full-width' class * [ACA-2107] add 'adf' prefix --- e2e/components/data-table/data-table.ts | 2 +- e2e/components/dialog/copy-move-dialog.ts | 2 +- e2e/components/dialog/share-dialog.ts | 2 +- e2e/components/login/login.ts | 4 +- .../context-submenus-ext.json | 12 +- .../document-presets-ext.json | 12 +- package-lock.json | 244 +++++++++--------- package.json | 10 +- src/app/app.module.ts | 9 +- .../context-menu/context-menu.directive.ts | 2 +- .../content-node-share.dialog.html | 6 +- .../content-node-share.dialog.scss | 6 +- .../content-node-share.dialog.spec.ts | 2 +- .../file-uploading-dialog.component.html | 34 +-- src/app/store/effects/download.effects.ts | 2 +- .../adf-content-node-selector.theme.scss | 7 - .../ui/overrides/adf-document-list.theme.scss | 8 +- .../overrides/adf-sidenav-layout.theme.scss | 2 +- .../ui/overrides/adf-upload-dialog.theme.scss | 2 +- src/assets/app.extensions.json | 16 +- 20 files changed, 189 insertions(+), 195 deletions(-) diff --git a/e2e/components/data-table/data-table.ts b/e2e/components/data-table/data-table.ts index 645e7273b9..4f57cb105e 100755 --- a/e2e/components/data-table/data-table.ts +++ b/e2e/components/data-table/data-table.ts @@ -42,7 +42,7 @@ export class DataTable extends Component { body: '.adf-datatable-body', row: '.adf-datatable-row[role]', - selectedRow: '.adf-datatable-row.is-selected', + selectedRow: '.adf-datatable-row.adf-is-selected', cell: '.adf-data-table-cell', locationLink: '.aca-location-link', nameLink: '.dl-link', diff --git a/e2e/components/dialog/copy-move-dialog.ts b/e2e/components/dialog/copy-move-dialog.ts index aa2e5211d8..e7dd9ebc91 100755 --- a/e2e/components/dialog/copy-move-dialog.ts +++ b/e2e/components/dialog/copy-move-dialog.ts @@ -39,7 +39,7 @@ export class CopyMoveDialog extends Component { dataTable: '.adf-datatable-body', row: '.adf-datatable-row[role]', - selectedRow: '.is-selected', + selectedRow: '.adf-is-selected', button: '.mat-dialog-actions button' }; diff --git a/e2e/components/dialog/share-dialog.ts b/e2e/components/dialog/share-dialog.ts index 827fae15a4..dc668850e8 100755 --- a/e2e/components/dialog/share-dialog.ts +++ b/e2e/components/dialog/share-dialog.ts @@ -37,7 +37,7 @@ export class ShareDialog extends Component { label: '.adf-share-link__label', shareToggle: `[data-automation-id='adf-share-toggle']`, linkUrl: `[data-automation-id='adf-share-link']`, - inputAction: '.input-action', + inputAction: '.adf-input-action', expireToggle: `[data-automation-id='adf-expire-toggle']`, datetimePickerButton: '.mat-datetimepicker-toggle', expirationInput: 'input[formcontrolname="time"]', diff --git a/e2e/components/login/login.ts b/e2e/components/login/login.ts index 0001e10c62..543cd4f2f1 100755 --- a/e2e/components/login/login.ts +++ b/e2e/components/login/login.ts @@ -34,8 +34,8 @@ export class LoginComponent extends Component { passwordInput: by.css('input#password'), passwordVisibility: by.css('.adf-login-password-icon'), submitButton: by.css('button#login-button'), - errorMessage: by.css('.login-error-message'), - copyright: by.css('.copyright') + errorMessage: by.css('.adf-login-error-message'), + copyright: by.css('.adf-copyright') }; usernameInput: ElementFinder = this.component.element(this.locators.usernameInput); diff --git a/e2e/resources/extensibility-configs/context-submenus-ext.json b/e2e/resources/extensibility-configs/context-submenus-ext.json index cfb41c8e95..5f86b51fda 100644 --- a/e2e/resources/extensibility-configs/context-submenus-ext.json +++ b/e2e/resources/extensibility-configs/context-submenus-ext.json @@ -939,7 +939,7 @@ "id": "app.files.thumbnail", "key": "$thumbnail", "type": "image", - "class": "image-table-cell", + "class": "adf-image-table-cell", "sortable": false, "desktopOnly": false }, @@ -985,7 +985,7 @@ "id": "app.libraries.thumbnail", "key": "$thumbnail", "type": "image", - "class": "image-table-cell", + "class": "adf-image-table-cell", "sortable": false, "desktopOnly": false }, @@ -1014,7 +1014,7 @@ "id": "app.shared.thumbnail", "key": "$thumbnail", "type": "image", - "class": "image-table-cell", + "class": "adf-image-table-cell", "sortable": false, "desktopOnly": false }, @@ -1078,7 +1078,7 @@ "id": "app.recent.thumbnail", "key": "$thumbnail", "type": "image", - "class": "image-table-cell", + "class": "adf-image-table-cell", "sortable": false, "desktopOnly": false }, @@ -1124,7 +1124,7 @@ "id": "app.favorites.thumbnail", "key": "$thumbnail", "type": "image", - "class": "image-table-cell", + "class": "adf-image-table-cell", "sortable": false, "desktopOnly": false }, @@ -1179,7 +1179,7 @@ "id": "app.trashcan.thumbnail", "key": "$thumbnail", "type": "image", - "class": "image-table-cell", + "class": "adf-image-table-cell", "sortable": false, "desktopOnly": false }, diff --git a/e2e/resources/extensibility-configs/document-presets-ext.json b/e2e/resources/extensibility-configs/document-presets-ext.json index 64dd837849..5797cc32d2 100644 --- a/e2e/resources/extensibility-configs/document-presets-ext.json +++ b/e2e/resources/extensibility-configs/document-presets-ext.json @@ -882,7 +882,7 @@ "id": "app.files.thumbnail", "key": "$thumbnail", "type": "image", - "class": "image-table-cell", + "class": "adf-image-table-cell", "sortable": false, "desktopOnly": false }, @@ -919,7 +919,7 @@ "id": "app.libraries.thumbnail", "key": "$thumbnail", "type": "image", - "class": "image-table-cell", + "class": "adf-image-table-cell", "sortable": false, "desktopOnly": false }, @@ -948,7 +948,7 @@ "id": "app.shared.thumbnail", "key": "$thumbnail", "type": "image", - "class": "image-table-cell", + "class": "adf-image-table-cell", "sortable": false, "desktopOnly": false }, @@ -1012,7 +1012,7 @@ "id": "app.recent.thumbnail", "key": "$thumbnail", "type": "image", - "class": "image-table-cell", + "class": "adf-image-table-cell", "sortable": false, "desktopOnly": false }, @@ -1058,7 +1058,7 @@ "id": "app.favorites.thumbnail", "key": "$thumbnail", "type": "image", - "class": "image-table-cell", + "class": "adf-image-table-cell", "sortable": false, "desktopOnly": false }, @@ -1113,7 +1113,7 @@ "id": "app.trashcan.thumbnail", "key": "$thumbnail", "type": "image", - "class": "image-table-cell", + "class": "adf-image-table-cell", "sortable": false, "desktopOnly": false }, diff --git a/package-lock.json b/package-lock.json index e25bbfd101..51aacc52b0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,25 +5,25 @@ "requires": true, "dependencies": { "@alfresco/adf-content-services": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-2.6.1.tgz", - "integrity": "sha512-mQkACzwpY4Go4MIwAMnuYp8yaQ+baiHOPfX6nJ4i+CIVnViocw8uq/lgDmSSmM4vQRr7KITh1ZOsat6rgePg6g==", + "version": "3.0.0-beta5", + "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-3.0.0-beta5.tgz", + "integrity": "sha512-1U7/E0gt6RWPprqsFfQefmRtdSc1uS6WBnKbtUgNWmL0Gt2Vg22RnK2qYnUd+kWwmPnJ3XmLOniV4WK40AAaNA==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/adf-core": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-2.6.1.tgz", - "integrity": "sha512-ehNQ6VNHWgj9CKrIKVuS5/7N/zqblImtXol9qZtOtHcPNvybBqdKfcbxpaedmi9eh9h4A9uEmtMJ1PvWCmfPQg==", + "version": "3.0.0-beta5", + "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-3.0.0-beta5.tgz", + "integrity": "sha512-Cfk7ItQ68cRrti/p5HdGMlpEYlf78NrQrZTb9Wa5ZR8tvoWPZ5xrFPXPlYCVrKnDJjafB8AHwTFaJW+Y1Pl2kg==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/adf-extensions": { - "version": "3.0.0-383b74151a47e188020249aea7ec0dfb586bd0b6", - "resolved": "https://registry.npmjs.org/@alfresco/adf-extensions/-/adf-extensions-3.0.0-383b74151a47e188020249aea7ec0dfb586bd0b6.tgz", - "integrity": "sha512-pAI4DoDMqek2G1sEFeHpgZ0OkUhSTmp95XWC+b3OoUroztwOC0y2a/PqLUvDgm5aTe4hVsA+r6IRMkp7aA1KAA==", + "version": "3.0.0-beta5", + "resolved": "https://registry.npmjs.org/@alfresco/adf-extensions/-/adf-extensions-3.0.0-beta5.tgz", + "integrity": "sha512-gPZ/ztqTKQIk0phLuH+6lMc2TROBAPcM5G0HHXeT442Cv/aqH79amDv3GqJlnIkPEOu+TKmA0awbUjB8QuE16w==", "requires": { "tslib": "^1.9.0" } @@ -259,7 +259,7 @@ "dependencies": { "source-map": { "version": "0.5.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "resolved": "http://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=", "dev": true }, @@ -2694,7 +2694,7 @@ }, "@types/q": { "version": "0.0.32", - "resolved": "https://registry.npmjs.org/@types/q/-/q-0.0.32.tgz", + "resolved": "http://registry.npmjs.org/@types/q/-/q-0.0.32.tgz", "integrity": "sha1-vShOV8hPEyXacCur/IKlMoGQwMU=", "dev": true }, @@ -2706,7 +2706,7 @@ }, "@types/strip-bom": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/strip-bom/-/strip-bom-3.0.0.tgz", + "resolved": "http://registry.npmjs.org/@types/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha1-FKjsOVbC6B7bdSB5CuzyHCkK69I=", "dev": true }, @@ -3000,18 +3000,18 @@ "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=" }, "alfresco-js-api": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/alfresco-js-api/-/alfresco-js-api-2.6.1.tgz", - "integrity": "sha512-E1maHlxlFS3DAmYWG9ueerMWgrcbJSVFO52Bfk2XGx3atEnH3iBFuG0ZczfCJCGIbtv22VliR5qQ90Cufuzhkw==", + "version": "3.0.0-beta6", + "resolved": "https://registry.npmjs.org/alfresco-js-api/-/alfresco-js-api-3.0.0-beta6.tgz", + "integrity": "sha512-VADSYFmF+5d9tBRN6ZCEDOp2I29LdTI0AqDpKEoukcnwABsQUqUusGOA9tAi7QkGgHq2yDFV5OGTMxVdeeqRVw==", "requires": { "event-emitter": "0.3.4", "superagent": "3.8.2" } }, "alfresco-js-api-node": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/alfresco-js-api-node/-/alfresco-js-api-node-2.6.0.tgz", - "integrity": "sha512-ETZKZzWBsZ2ztR4b4vKOne97jQrsrfsoNvVPQRxNV+Tc3zzR42OJIpIg0t48g1jdaaHmjzim8NUtafs07GhzPg==", + "version": "3.0.0-beta6", + "resolved": "https://registry.npmjs.org/alfresco-js-api-node/-/alfresco-js-api-node-3.0.0-beta6.tgz", + "integrity": "sha512-tKy+D4feKvtsKb6X/g1SRFmVMBKcJenWCZ6ejPwaQLw1t+jn+iBTnRsrGWJ2bGowhDUIIvB1D+X+Wt/ZbU0R6g==", "dev": true, "requires": { "event-emitter": "0.3.4", @@ -3085,7 +3085,7 @@ }, "ansi-escapes": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", + "resolved": "http://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==", "dev": true }, @@ -3292,7 +3292,7 @@ }, "util": { "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "resolved": "http://registry.npmjs.org/util/-/util-0.10.3.tgz", "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", "dev": true, "requires": { @@ -3396,7 +3396,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -3667,7 +3667,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true } @@ -3816,7 +3816,7 @@ }, "browserify-aes": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", "dev": true, "requires": { @@ -3853,7 +3853,7 @@ }, "browserify-rsa": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "resolved": "http://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", "dev": true, "requires": { @@ -3930,7 +3930,7 @@ }, "buffer": { "version": "4.9.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", + "resolved": "http://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", "dev": true, "requires": { @@ -4005,7 +4005,7 @@ }, "cacache": { "version": "10.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-10.0.4.tgz", + "resolved": "http://registry.npmjs.org/cacache/-/cacache-10.0.4.tgz", "integrity": "sha512-Dph0MzuH+rTQzGPNT9fAnrPmMmjKfST6trxJeK7NQuHRaVw24VzPRWTmg9MpcwOVQZO0E1FBICUlFeNaKPIfHA==", "dev": true, "requires": { @@ -4063,7 +4063,7 @@ }, "camelcase-keys": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "resolved": "http://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", "dev": true, "requires": { @@ -4368,7 +4368,7 @@ }, "colors": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", + "resolved": "http://registry.npmjs.org/colors/-/colors-1.1.2.tgz", "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", "dev": true }, @@ -4738,7 +4738,7 @@ }, "create-hash": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", "dev": true, "requires": { @@ -4751,7 +4751,7 @@ }, "create-hmac": { "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", "dev": true, "requires": { @@ -5035,7 +5035,7 @@ }, "d": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/d/-/d-0.1.1.tgz", + "resolved": "http://registry.npmjs.org/d/-/d-0.1.1.tgz", "integrity": "sha1-2hhMU10Y2O57oqoim5FACfrhEwk=", "requires": { "es5-ext": "~0.10.2" @@ -5234,7 +5234,7 @@ "dependencies": { "globby": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "resolved": "http://registry.npmjs.org/globby/-/globby-6.1.0.tgz", "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", "dev": true, "requires": { @@ -5247,7 +5247,7 @@ "dependencies": { "pify": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true } @@ -5323,7 +5323,7 @@ }, "diffie-hellman": { "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "resolved": "http://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", "dev": true, "requires": { @@ -5489,7 +5489,7 @@ }, "engine.io-client": { "version": "3.2.1", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.2.1.tgz", + "resolved": "http://registry.npmjs.org/engine.io-client/-/engine.io-client-3.2.1.tgz", "integrity": "sha512-y5AbkytWeM4jQr7m/koQLc5AxpRKC1hEVUb/s1FUAWEJq5AzJJ4NLvzuKPuxtDi5Mq755WuDvZ6Iv2rXj4PTzw==", "dev": true, "requires": { @@ -5561,9 +5561,9 @@ } }, "es5-ext": { - "version": "0.10.45", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.45.tgz", - "integrity": "sha512-FkfM6Vxxfmztilbxxz5UKSD4ICMf5tSpRFtDNtkAhOxZ0EKtX6qwmXNyH/sFyIbX2P/nU5AMiA9jilWsUGJzCQ==", + "version": "0.10.46", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.46.tgz", + "integrity": "sha512-24XxRvJXNFwEMpJb3nOkiRJKRoupmjYmOPVlI65Qy2SrtxwOTB+g6ODjBKOtwEHbYrhWRty9xxOWLNdClT2djw==", "requires": { "es6-iterator": "~2.0.3", "es6-symbol": "~3.1.1", @@ -5582,7 +5582,7 @@ "dependencies": { "d": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "resolved": "http://registry.npmjs.org/d/-/d-1.0.0.tgz", "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", "requires": { "es5-ext": "^0.10.9" @@ -5598,7 +5598,7 @@ }, "es6-promisify": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "resolved": "http://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", "dev": true, "requires": { @@ -5616,7 +5616,7 @@ "dependencies": { "d": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "resolved": "http://registry.npmjs.org/d/-/d-1.0.0.tgz", "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", "requires": { "es5-ext": "^0.10.9" @@ -5651,7 +5651,7 @@ "dependencies": { "source-map": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", + "resolved": "http://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", "dev": true, "optional": true, @@ -5760,7 +5760,7 @@ }, "events": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "resolved": "http://registry.npmjs.org/events/-/events-1.1.1.tgz", "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", "dev": true }, @@ -5839,7 +5839,7 @@ }, "expand-range": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-0.1.1.tgz", + "resolved": "http://registry.npmjs.org/expand-range/-/expand-range-0.1.1.tgz", "integrity": "sha1-TLjtoJk8pW+k9B/ELzy7TMrf8EQ=", "dev": true, "requires": { @@ -5872,7 +5872,7 @@ }, "expand-range": { "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "resolved": "http://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", "dev": true, "requires": { @@ -5919,7 +5919,7 @@ "dependencies": { "array-flatten": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "resolved": "http://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", "dev": true }, @@ -6127,7 +6127,7 @@ }, "finalhandler": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", + "resolved": "http://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", "dev": true, "requires": { @@ -6265,7 +6265,7 @@ }, "fs-access": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz", + "resolved": "http://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz", "integrity": "sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o=", "dev": true, "requires": { @@ -6968,7 +6968,7 @@ }, "get-stream": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "resolved": "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", "dev": true }, @@ -7070,7 +7070,7 @@ }, "got": { "version": "6.7.1", - "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", + "resolved": "http://registry.npmjs.org/got/-/got-6.7.1.tgz", "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", "dev": true, "requires": { @@ -7100,7 +7100,7 @@ }, "handle-thing": { "version": "1.2.5", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-1.2.5.tgz", + "resolved": "http://registry.npmjs.org/handle-thing/-/handle-thing-1.2.5.tgz", "integrity": "sha1-/Xqtcmvxpf0W38KbL3pmAdJxOcQ=", "dev": true }, @@ -7416,7 +7416,7 @@ }, "http-errors": { "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", "dev": true, "requires": { @@ -7455,7 +7455,7 @@ }, "http-proxy-middleware": { "version": "0.18.0", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.18.0.tgz", + "resolved": "http://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.18.0.tgz", "integrity": "sha512-Fs25KVMPAIIcgjMZkVHJoKg9VcXcC1C8yb9JUgeDvVXY0S/zgVIhMb+qVswDIgtJe2DfckMSY2d6TuTEutlk6Q==", "dev": true, "requires": { @@ -8111,7 +8111,7 @@ }, "is-accessor-descriptor": { "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "resolved": "http://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "requires": { @@ -8141,7 +8141,7 @@ }, "is-builtin-module": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "resolved": "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", "dev": true, "requires": { @@ -8159,7 +8159,7 @@ }, "is-data-descriptor": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "resolved": "http://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "requires": { @@ -8278,7 +8278,7 @@ }, "is-obj": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "resolved": "http://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", "dev": true }, @@ -8543,7 +8543,7 @@ }, "fast-deep-equal": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", + "resolved": "http://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", "dev": true }, @@ -8694,7 +8694,7 @@ "dependencies": { "fs-extra": { "version": "0.26.7", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.26.7.tgz", + "resolved": "http://registry.npmjs.org/fs-extra/-/fs-extra-0.26.7.tgz", "integrity": "sha1-muH92UiXeY7at20JGM9C0MMYT6k=", "dev": true, "requires": { @@ -8707,7 +8707,7 @@ }, "jsonfile": { "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "resolved": "http://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", "dev": true, "requires": { @@ -8772,7 +8772,7 @@ }, "jsesc": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", + "resolved": "http://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", "dev": true }, @@ -8816,7 +8816,7 @@ }, "json5": { "version": "0.5.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "resolved": "http://registry.npmjs.org/json5/-/json5-0.5.1.tgz", "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=" }, "jsonfile": { @@ -8869,13 +8869,13 @@ "dependencies": { "core-js": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.3.0.tgz", + "resolved": "http://registry.npmjs.org/core-js/-/core-js-2.3.0.tgz", "integrity": "sha1-+rg/uwstjchfpjbEudNMdUIMbWU=", "dev": true }, "es6-promise": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.0.2.tgz", + "resolved": "http://registry.npmjs.org/es6-promise/-/es6-promise-3.0.2.tgz", "integrity": "sha1-AQ1YWEI6XxGJeWZfRkhqlcbuK7Y=", "dev": true }, @@ -8887,7 +8887,7 @@ }, "readable-stream": { "version": "2.0.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", "dev": true, "requires": { @@ -8901,7 +8901,7 @@ }, "string_decoder": { "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true } @@ -9318,7 +9318,7 @@ }, "karma-cli": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/karma-cli/-/karma-cli-1.0.1.tgz", + "resolved": "http://registry.npmjs.org/karma-cli/-/karma-cli-1.0.1.tgz", "integrity": "sha1-rmw8WKMTodALRRZMRVubhs4X+WA=", "dev": true, "requires": { @@ -9343,7 +9343,7 @@ }, "karma-jasmine-html-reporter": { "version": "0.2.2", - "resolved": "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-0.2.2.tgz", + "resolved": "http://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-0.2.2.tgz", "integrity": "sha1-SKjl7xiAdhfuK14zwRlMNbQ5Ukw=", "dev": true, "requires": { @@ -9475,7 +9475,7 @@ "dependencies": { "promise": { "version": "7.0.4", - "resolved": "https://registry.npmjs.org/promise/-/promise-7.0.4.tgz", + "resolved": "http://registry.npmjs.org/promise/-/promise-7.0.4.tgz", "integrity": "sha1-Nj6EpMNsg1a4kP7WLJHOhdAu1Tk=", "dev": true, "requires": { @@ -9520,7 +9520,7 @@ }, "load-json-file": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "dev": true, "requires": { @@ -9533,7 +9533,7 @@ "dependencies": { "pify": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true } @@ -9814,7 +9814,7 @@ }, "media-typer": { "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", "dev": true }, @@ -9839,7 +9839,7 @@ }, "meow": { "version": "3.7.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "resolved": "http://registry.npmjs.org/meow/-/meow-3.7.0.tgz", "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", "dev": true, "requires": { @@ -9857,7 +9857,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true } @@ -9984,7 +9984,7 @@ }, "minimist": { "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", "dev": true }, @@ -10074,7 +10074,7 @@ }, "mkdirp": { "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "dev": true, "requires": { @@ -10194,7 +10194,7 @@ }, "next-tick": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "resolved": "http://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" }, "ng-packagr": { @@ -10737,7 +10737,7 @@ "dependencies": { "semver": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "resolved": "http://registry.npmjs.org/semver/-/semver-5.3.0.tgz", "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", "dev": true } @@ -10817,7 +10817,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -11126,7 +11126,7 @@ }, "opn": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-5.3.0.tgz", + "resolved": "http://registry.npmjs.org/opn/-/opn-5.3.0.tgz", "integrity": "sha512-bYJHo/LOmoTd+pfiYhfZDnf9zekVJrY+cnS2a5F2x+w5ppvTqObojTP7WiFG+kVZs9Inw+qQ/lw7TroWwhdd2g==", "dev": true, "requires": { @@ -11182,13 +11182,13 @@ }, "os-homedir": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "resolved": "http://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "dev": true }, "os-locale": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "resolved": "http://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", "dev": true, "requires": { @@ -11197,7 +11197,7 @@ }, "os-tmpdir": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true }, @@ -11225,7 +11225,7 @@ }, "p-is-promise": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz", + "resolved": "http://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz", "integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=", "dev": true }, @@ -11442,7 +11442,7 @@ }, "parse-asn1": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz", + "resolved": "http://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz", "integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==", "dev": true, "requires": { @@ -11518,7 +11518,7 @@ }, "path-browserify": { "version": "0.0.0", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", + "resolved": "http://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", "dev": true }, @@ -11536,7 +11536,7 @@ }, "path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, @@ -11875,7 +11875,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -11903,7 +11903,7 @@ }, "globby": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", + "resolved": "http://registry.npmjs.org/globby/-/globby-5.0.0.tgz", "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", "dev": true, "requires": { @@ -11917,13 +11917,13 @@ }, "minimist": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, "pify": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true }, @@ -12180,7 +12180,7 @@ }, "raw-loader": { "version": "0.5.1", - "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-0.5.1.tgz", + "resolved": "http://registry.npmjs.org/raw-loader/-/raw-loader-0.5.1.tgz", "integrity": "sha1-DD0L6u2KAclm2Xh793goElKpeao=", "dev": true }, @@ -12198,7 +12198,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true } @@ -12215,7 +12215,7 @@ "dependencies": { "pify": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true } @@ -12245,7 +12245,7 @@ }, "pify": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true } @@ -12284,7 +12284,7 @@ }, "readable-stream": { "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "requires": { "core-util-is": "~1.0.0", @@ -12366,7 +12366,7 @@ }, "regexpu-core": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz", + "resolved": "http://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz", "integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=", "dev": true, "requires": { @@ -12396,13 +12396,13 @@ }, "regjsgen": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", + "resolved": "http://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", "dev": true }, "regjsparser": { "version": "0.1.5", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", + "resolved": "http://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", "dev": true, "requires": { @@ -12411,7 +12411,7 @@ "dependencies": { "jsesc": { "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "resolved": "http://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", "dev": true } @@ -12836,7 +12836,7 @@ }, "safe-regex": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "dev": true, "requires": { @@ -12886,7 +12886,7 @@ }, "sax": { "version": "0.5.8", - "resolved": "https://registry.npmjs.org/sax/-/sax-0.5.8.tgz", + "resolved": "http://registry.npmjs.org/sax/-/sax-0.5.8.tgz", "integrity": "sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE=", "dev": true }, @@ -12911,7 +12911,7 @@ "dependencies": { "source-map": { "version": "0.4.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "resolved": "http://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", "dev": true, "requires": { @@ -13122,7 +13122,7 @@ }, "sha.js": { "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", "dev": true, "requires": { @@ -13354,7 +13354,7 @@ }, "socket.io-parser": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.2.0.tgz", + "resolved": "http://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.2.0.tgz", "integrity": "sha512-FYiBx7rc/KORMJlgsXysflWx/RIvtqZbyGLlHZvjfmPTPeuD/I8MaW7cfFrj5tRltICJdgwflhfZ3NVVbVLFQA==", "dev": true, "requires": { @@ -13600,7 +13600,7 @@ }, "sprintf-js": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "resolved": "http://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, @@ -13685,7 +13685,7 @@ }, "stream-browserify": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", + "resolved": "http://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", "dev": true, "requires": { @@ -13736,7 +13736,7 @@ }, "string-width": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "resolved": "http://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "requires": { @@ -13747,7 +13747,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "requires": { "safe-buffer": "~5.1.0" @@ -13755,7 +13755,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -13773,7 +13773,7 @@ }, "strip-eof": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "resolved": "http://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", "dev": true }, @@ -13845,7 +13845,7 @@ }, "source-map": { "version": "0.1.43", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", + "resolved": "http://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", "dev": true, "requires": { @@ -13905,7 +13905,7 @@ }, "tar": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", + "resolved": "http://registry.npmjs.org/tar/-/tar-2.2.1.tgz", "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", "dev": true, "requires": { @@ -14117,7 +14117,7 @@ }, "through": { "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", "dev": true }, @@ -14309,7 +14309,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, @@ -14364,7 +14364,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, @@ -14412,7 +14412,7 @@ }, "tty-browserify": { "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "resolved": "http://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", "dev": true }, @@ -14846,7 +14846,7 @@ }, "vm-browserify": { "version": "0.0.4", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", + "resolved": "http://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", "dev": true, "requires": { @@ -14880,7 +14880,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true } @@ -15626,7 +15626,7 @@ }, "source-map": { "version": "0.4.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "resolved": "http://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", "dev": true, "requires": { @@ -16425,7 +16425,7 @@ }, "wrap-ansi": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", "dev": true, "requires": { @@ -16487,7 +16487,7 @@ }, "xmlbuilder": { "version": "9.0.7", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", + "resolved": "http://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", "dev": true }, diff --git a/package.json b/package.json index aa8f6abdd7..a02b365e99 100644 --- a/package.json +++ b/package.json @@ -30,9 +30,9 @@ }, "private": true, "dependencies": { - "@alfresco/adf-content-services": "2.6.1", - "@alfresco/adf-core": "2.6.1", - "@alfresco/adf-extensions": "3.0.0-383b74151a47e188020249aea7ec0dfb586bd0b6", + "@alfresco/adf-content-services": "3.0.0-beta5", + "@alfresco/adf-core": "3.0.0-beta5", + "@alfresco/adf-extensions": "3.0.0-beta5", "@angular/animations": "7.1.1", "@angular/cdk": "^7.1.0", "@angular/common": "7.1.1", @@ -53,7 +53,7 @@ "@ngrx/store": "^6.1.2", "@ngrx/store-devtools": "^6.1.2", "@ngx-translate/core": "^10.0.2", - "alfresco-js-api": "2.6.1", + "alfresco-js-api": "3.0.0-beta6", "core-js": "^2.5.7", "hammerjs": "2.0.8", "minimatch-browser": "^1.0.0", @@ -73,7 +73,7 @@ "@types/jasminewd2": "^2.0.2", "@types/node": "9.3.0", "@types/selenium-webdriver": "^3.0.8", - "alfresco-js-api-node": "^2.6.0", + "alfresco-js-api-node": "3.0.0-beta6", "chrome-remote-interface": "^0.26.1", "codelyzer": "^4.5.0", "cspell": "^3.1.3", diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 89fdb98643..2de688991f 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -35,7 +35,8 @@ import { TRANSLATION_PROVIDER, CoreModule, AppConfigService, - DebugAppConfigService + DebugAppConfigService, + TranslateLoaderService } from '@alfresco/adf-core'; import { ContentModule, @@ -74,6 +75,7 @@ import { AppLoginModule } from './components/login/login.module'; import { AppHeaderModule } from './components/header/header.module'; import { environment } from '../environments/environment'; import { AppDataService } from './services/data.service'; +import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; @NgModule({ imports: [ @@ -106,7 +108,10 @@ import { AppDataService } from './services/data.service'; AppPermissionsModule, AppSearchInputModule, AppSearchResultsModule, - AppHeaderModule + AppHeaderModule, + TranslateModule.forRoot({ + loader: { provide: TranslateLoader, useClass: TranslateLoaderService } + }) ], declarations: [ AppComponent, diff --git a/src/app/components/context-menu/context-menu.directive.ts b/src/app/components/context-menu/context-menu.directive.ts index 5fb5af91cf..c93abbbad0 100644 --- a/src/app/components/context-menu/context-menu.directive.ts +++ b/src/app/components/context-menu/context-menu.directive.ts @@ -109,7 +109,7 @@ export class ContextActionsDirective implements OnInit, OnDestroy { } return this.findAncestor(target, 'adf-datatable-row').classList.contains( - 'is-selected' + 'adf-is-selected' ); } diff --git a/src/app/components/shared/content-node-share/content-node-share.dialog.html b/src/app/components/shared/content-node-share/content-node-share.dialog.html index a922dc8be1..048a0760ed 100644 --- a/src/app/components/shared/content-node-share/content-node-share.dialog.html +++ b/src/app/components/shared/content-node-share/content-node-share.dialog.html @@ -20,7 +20,7 @@

{{ 'SHARE.TITLE' | translate }}

- + {{ 'SHARE.TITLE' | translate }} placeholder="{{ 'SHARE.PUBLIC-LINK' | translate }}" formControlName="sharedUrl" readonly="readonly"> - link @@ -48,7 +48,7 @@

{{ 'SHARE.EXPIRES' | translate }}

- + { fixture.detectChanges(); fixture.nativeElement - .querySelector('.input-action') + .querySelector('.adf-input-action') .dispatchEvent(new MouseEvent('click')); fixture.detectChanges(); diff --git a/src/app/components/upload-dialog/file-uploading-dialog.component.html b/src/app/components/upload-dialog/file-uploading-dialog.component.html index c4f2460795..50a214fae2 100644 --- a/src/app/components/upload-dialog/file-uploading-dialog.component.html +++ b/src/app/components/upload-dialog/file-uploading-dialog.component.html @@ -1,10 +1,10 @@
-
+ [class.adf-upload-dialog--minimized]="isDialogMinimized" + [class.adf-upload-dialog--position-left]="position === 'left'" + [class.adf-upload-dialog--position-right]="position === 'right'"> +
-
{{ (totalErrors > 1 @@ -45,10 +45,10 @@ }}
-
+
@@ -62,19 +62,19 @@
-

+ class="adf-upload-dialog__confirmation" + [class.adf-upload-dialog--hide]="!isConfirmation"> +

{{ 'ADF_FILE_UPLOAD.CONFIRMATION.MESSAGE.TITLE' | translate }}

-

+

{{ 'ADF_FILE_UPLOAD.CONFIRMATION.MESSAGE.TEXT' | translate }}

-
-
@@ -17,12 +22,22 @@ data-automation-id="create-button" [matMenuTriggerFor]="rootMenu" #createMenu="matMenuTrigger" - title="{{ 'APP.NEW_MENU.TOOLTIP' | translate }}"> - queue + title="{{ 'APP.NEW_MENU.TOOLTIP' | translate }}" + > + queue - + diff --git a/src/app/components/current-user/current-user.component.html b/src/app/components/current-user/current-user.component.html index 1c566f2dae..0d14487b6d 100644 --- a/src/app/components/current-user/current-user.component.html +++ b/src/app/components/current-user/current-user.component.html @@ -1,23 +1,24 @@
-
{{ (profile$ | async)?.userName }}
-
- {{ (profile$ | async)?.initials }} -
+
{{ (profile$ | async)?.userName }}
+
+ {{ (profile$ | async)?.initials }} +
- + - + - + diff --git a/src/app/components/info-drawer/info-drawer.component.html b/src/app/components/info-drawer/info-drawer.component.html index 1d1b085944..14230ca9dd 100644 --- a/src/app/components/info-drawer/info-drawer.component.html +++ b/src/app/components/info-drawer/info-drawer.component.html @@ -1,14 +1,19 @@
- +
- - - - - - + + + + + + diff --git a/src/app/components/info-drawer/library-metadata-tab/library-metadata-form.component.html b/src/app/components/info-drawer/library-metadata-tab/library-metadata-form.component.html index ac0b0a38bf..0d49a135cb 100644 --- a/src/app/components/info-drawer/library-metadata-tab/library-metadata-form.component.html +++ b/src/app/components/info-drawer/library-metadata-tab/library-metadata-form.component.html @@ -1,125 +1,158 @@ - -
-
-
-
- - - {{ 'LIBRARY.DIALOG.FORM.NAME' | translate }} - - + +
+
+
+
+ + + {{ 'LIBRARY.DIALOG.FORM.NAME' | translate }} + + - - {{ form.controls.title.value }} - -
-
-
+ + {{ form.controls.title.value }} + +
+
+
-
-
-
-
- - - {{ 'LIBRARY.DIALOG.FORM.SITE_ID' | translate }} - - +
+
+
+
+ + + {{ 'LIBRARY.DIALOG.FORM.SITE_ID' | translate }} + + - - {{ form.controls.id.value }} - -
-
-
+ + {{ form.controls.id.value }} + +
+
+
-
-
-
-
- - - {{ 'LIBRARY.DIALOG.FORM.VISIBILITY' | translate }} - - +
+
+
+
+ + + {{ 'LIBRARY.DIALOG.FORM.VISIBILITY' | translate }} + + - - {{ (getVisibilityLabel(form.controls.visibility.value)) | translate }} - -
-
-
+ + {{ + getVisibilityLabel(form.controls.visibility.value) | translate + }} + +
+
+
-
-
-
-
- - - {{ 'LIBRARY.DIALOG.FORM.DESCRIPTION' | translate }} - - +
+
+
+
+ + + {{ 'LIBRARY.DIALOG.FORM.DESCRIPTION' | translate }} + + - - {{ form.controls.description?.value }} - -
-
-
+ + {{ form.controls.description?.value }} + +
- +
+
+ - - - + + + - - - - + + + + - {{ 'LIBRARY.HINTS.SITE_TITLE_EXISTS' | translate }} - - {{ 'LIBRARY.ERRORS.TITLE_TOO_LONG' | translate }} - - + {{ + 'LIBRARY.HINTS.SITE_TITLE_EXISTS' | translate + }} + + {{ 'LIBRARY.ERRORS.TITLE_TOO_LONG' | translate }} + + - - - + + + - - - - {{ type.label | translate }} - - - + + + + {{ type.label | translate }} + + + - - + + - - {{ 'LIBRARY.ERRORS.DESCRIPTION_TOO_LONG' | translate }} - - - - + + {{ 'LIBRARY.ERRORS.DESCRIPTION_TOO_LONG' | translate }} + + + + - - - - - \ No newline at end of file + + + + + diff --git a/src/app/components/layout/app-layout/app-layout.component.html b/src/app/components/layout/app-layout/app-layout.component.html index 63b169c002..59e88dcdbd 100644 --- a/src/app/components/layout/app-layout/app-layout.component.html +++ b/src/app/components/layout/app-layout/app-layout.component.html @@ -1,38 +1,33 @@ - + + + + + + + + - + + + + + - - - - - - + + + + - - - - - - - - - - - - - - - + diff --git a/src/app/components/login/login.component.html b/src/app/components/login/login.component.html index 2d043c35cc..841261a95b 100644 --- a/src/app/components/login/login.component.html +++ b/src/app/components/login/login.component.html @@ -1,8 +1,9 @@ + [copyrightText]="'application.copyright' | adfAppConfig" + providers="ECM" + successRoute="/personal-files" + [logoImageUrl]="'./assets/images/alfresco-logo.svg'" + [showRememberMe]="false" + [showLoginActions]="false" +> diff --git a/src/app/components/permissions/permission-dialog/node-permissions.dialog.html b/src/app/components/permissions/permission-dialog/node-permissions.dialog.html index 8a42b71040..dcd7a180c7 100644 --- a/src/app/components/permissions/permission-dialog/node-permissions.dialog.html +++ b/src/app/components/permissions/permission-dialog/node-permissions.dialog.html @@ -1,7 +1,9 @@
{{'PERMISSIONS.DIALOG.TITLE' | translate}}
- +
- +
diff --git a/src/app/components/permissions/permission-manager/permission-manager.component.html b/src/app/components/permissions/permission-manager/permission-manager.component.html index 3ef3989e11..48a5f43e54 100644 --- a/src/app/components/permissions/permission-manager/permission-manager.component.html +++ b/src/app/components/permissions/permission-manager/permission-manager.component.html @@ -1,21 +1,27 @@
- - + +
+ (update)="onUpdate()" +> diff --git a/src/app/components/preview/preview.component.html b/src/app/components/preview/preview.component.html index 4e9ade2958..1bb50988b3 100644 --- a/src/app/components/preview/preview.component.html +++ b/src/app/components/preview/preview.component.html @@ -1,55 +1,61 @@ + + + + - + + + + + - - - + + + + + - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + diff --git a/src/app/components/search/search-input-control/search-input-control.component.html b/src/app/components/search/search-input-control/search-input-control.component.html index 69aaaccd03..4ca3201b22 100644 --- a/src/app/components/search/search-input-control/search-input-control.component.html +++ b/src/app/components/search/search-input-control/search-input-control.component.html @@ -1,21 +1,33 @@
- - - -
- clear -
-
+ + + +
+ clear +
+
diff --git a/src/app/components/search/search-input/search-input.component.html b/src/app/components/search/search-input/search-input.component.html index d349860ffc..92c3f5e424 100644 --- a/src/app/components/search/search-input/search-input.component.html +++ b/src/app/components/search/search-input/search-input.component.html @@ -1,40 +1,59 @@ -
- - - +
+ + + -
- arrow_drop_down -
-
+
+ arrow_drop_down +
+
- - - - {{ 'SEARCH.INPUT.HINT' | translate }} + + + + {{ + 'SEARCH.INPUT.HINT' | translate + }} -
- - {{ option.key | translate }} - -
+
+ + {{ option.key | translate }} + +
diff --git a/src/app/components/search/search-results-row/search-results-row.component.html b/src/app/components/search/search-results-row/search-results-row.component.html index b81e3b48ac..c2a15dca74 100644 --- a/src/app/components/search/search-results-row/search-results-row.component.html +++ b/src/app/components/search/search-results-row/search-results-row.component.html @@ -1,17 +1,26 @@
- {{ name }} - {{ name }} - ( {{ title }} ) + {{ name }} + + {{ name }} + + ( {{ title }} )
-
{{ description }}
+
{{ description }}
- {{ 'APP.BROWSE.SEARCH.CUSTOM_ROW.MODIFIED' | translate }}: {{ modifiedAt | date:'medium' }} + {{ 'APP.BROWSE.SEARCH.CUSTOM_ROW.MODIFIED' | translate }}: + {{ modifiedAt | date: 'medium' }} - by {{ user }} + by {{ user }} - | {{ 'APP.BROWSE.SEARCH.CUSTOM_ROW.SIZE' | translate }}: {{ size | adfFileSize }} + | {{ 'APP.BROWSE.SEARCH.CUSTOM_ROW.SIZE' | translate }}: + {{ size | adfFileSize }} +
-
{{ 'APP.BROWSE.SEARCH.CUSTOM_ROW.LOCATION' | translate }}:
+
+ {{ 'APP.BROWSE.SEARCH.CUSTOM_ROW.LOCATION' | translate }}: + +
diff --git a/src/app/components/search/search-results/search-results.component.html b/src/app/components/search/search-results/search-results.component.html index 01ba634f67..6a1478ca44 100644 --- a/src/app/components/search/search-results/search-results.component.html +++ b/src/app/components/search/search-results/search-results.component.html @@ -1,8 +1,6 @@ - - - + @@ -13,83 +11,107 @@
- -
- - -
-
-
{{ 'APP.BROWSE.SEARCH.FOUND_RESULTS' | translate: { number: totalResults } }}
-
{{ 'APP.BROWSE.SEARCH.FOUND_ONE_RESULT' | translate: { number: totalResults } }}
- -
- -
-
- - + +
+ + +
+
+
+ {{ + 'APP.BROWSE.SEARCH.FOUND_RESULTS' + | translate: { number: totalResults } + }} +
+
+ {{ + 'APP.BROWSE.SEARCH.FOUND_ONE_RESULT' + | translate: { number: totalResults } + }}
- +
+ +
+
- - - + +
- - - - - + + + + - + + + + + + - - - -
-

- {{ 'APP.BROWSE.SEARCH.NO_RESULTS' | translate }} -

-
-
-
-
-
+ + + +
+

+ {{ 'APP.BROWSE.SEARCH.NO_RESULTS' | translate }} +

+
+
+
+
+ - - -
+ + +
-
-
- +
+ - -
+ +
-
- +
+ - -
+ +
diff --git a/src/app/components/upload-dialog/file-uploading-list-row.component.html b/src/app/components/upload-dialog/file-uploading-list-row.component.html index 57cba25fde..578129cf8b 100644 --- a/src/app/components/upload-dialog/file-uploading-list-row.component.html +++ b/src/app/components/upload-dialog/file-uploading-list-row.component.html @@ -1,81 +1,94 @@
- - insert_drive_file - + + insert_drive_file + - - {{ file.name }} - + + {{ file.name }} + -
- - {{ file.progress.loaded | adfFileSize }} / {{ file.progress.total | adfFileSize }} - +
+ + {{ file.progress.loaded | adfFileSize }} / + {{ file.progress.total | adfFileSize }} + - - clear - -
+ + clear + +
-
- - check_circle - +
+ + check_circle + - - remove_circle - -
+ + remove_circle + +
-
- - schedule - +
+ + schedule + - - remove_circle - -
+ + remove_circle + +
- -
- - report_problem - -
+ +
+ + report_problem + +
-
- {{ 'ADF_FILE_UPLOAD.STATUS.FILE_CANCELED_STATUS' | translate }} -
-
+
+ {{ 'ADF_FILE_UPLOAD.STATUS.FILE_CANCELED_STATUS' | translate }} +
+
+
diff --git a/src/app/components/upload-dialog/file-uploading-list.component.html b/src/app/components/upload-dialog/file-uploading-list.component.html index 91a4d358d8..475b084b12 100644 --- a/src/app/components/upload-dialog/file-uploading-list.component.html +++ b/src/app/components/upload-dialog/file-uploading-list.component.html @@ -1,7 +1,4 @@
- - + +
diff --git a/src/app/dialogs/library/library.dialog.html b/src/app/dialogs/library/library.dialog.html index 2314c585b3..20437bcd7d 100644 --- a/src/app/dialogs/library/library.dialog.html +++ b/src/app/dialogs/library/library.dialog.html @@ -11,18 +11,17 @@

{{ createTitle | translate }}

autocomplete="off" /> - {{ - 'LIBRARY.HINTS.SITE_TITLE_EXISTS' | translate - }} + {{ 'LIBRARY.HINTS.SITE_TITLE_EXISTS' | translate }} {{ 'LIBRARY.ERRORS.TITLE_TOO_LONG' | translate }} - {{ form.controls['title'].errors?.message | translate }} + {{ form.controls['title'].errors?.message | translate }} - diff --git a/src/app/dialogs/node-versions/node-versions.dialog.html b/src/app/dialogs/node-versions/node-versions.dialog.html index 829ea13b13..10beef5b98 100644 --- a/src/app/dialogs/node-versions/node-versions.dialog.html +++ b/src/app/dialogs/node-versions/node-versions.dialog.html @@ -1,12 +1,15 @@
{{'VERSION.DIALOG.TITLE' | translate}}
- - + +
- +
From a1789e45aab5bc22f27a97c98feba6d1e60dc467 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Fri, 4 Jan 2019 18:47:19 +0000 Subject: [PATCH 015/259] [ACA-2120] update library toolbar (#891) --- src/assets/app.extensions.json | 44 +++++++++++++++++----------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/assets/app.extensions.json b/src/assets/app.extensions.json index b84cc1d137..c7475d70d0 100644 --- a/src/assets/app.extensions.json +++ b/src/assets/app.extensions.json @@ -452,6 +452,27 @@ "visible": "app.trashcan.hasSelection" } }, + { + "id": "app.toolbar.joinLibrary", + "type": "custom", + "order": 600, + "component": "app.toolbar.toggleJoinLibrary", + "rules": { + "visible": "app.libraries.toolbar.canToggleJoin" + } + }, + { + "id": "app.toolbar.leaveLibrary", + "order": 650, + "title": "APP.ACTIONS.LEAVE", + "icon": "exit_to_app", + "actions": { + "click": "LEAVE_LIBRARY" + }, + "rules": { + "visible": "app.libraries.toolbar.canLeaveLibrary" + } + }, { "id": "app.create.separator.2", "type": "separator", @@ -469,33 +490,12 @@ { "id": "app.libraries.toolbar.infoDrawer", "type": "custom", - "order": 701, + "order": 800, "component": "app.toolbar.toggleInfoDrawer", "rules": { "visible": "app.libraries.toolbar" } }, - { - "id": "app.toolbar.joinLibrary", - "type": "custom", - "order": 704, - "component": "app.toolbar.toggleJoinLibrary", - "rules": { - "visible": "app.libraries.toolbar.canToggleJoin" - } - }, - { - "id": "app.toolbar.leaveLibrary", - "order": 705, - "title": "APP.ACTIONS.LEAVE", - "icon": "not_interested", - "actions": { - "click": "LEAVE_LIBRARY" - }, - "rules": { - "visible": "app.libraries.toolbar.canLeaveLibrary" - } - }, { "id": "app.toolbar.more", "type": "menu", From 46d593c72b171dd3f0d210cbba88d7c85e9098ea Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Mon, 7 Jan 2019 12:32:41 +0000 Subject: [PATCH 016/259] [ACA-2131] fix leave library icon for context menu --- src/assets/app.extensions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/assets/app.extensions.json b/src/assets/app.extensions.json index c7475d70d0..4c3cc36349 100644 --- a/src/assets/app.extensions.json +++ b/src/assets/app.extensions.json @@ -733,7 +733,7 @@ "id": "app.context.menu.leaveLibrary", "order": 703, "title": "APP.ACTIONS.LEAVE", - "icon": "not_interested", + "icon": "exit_to_app", "actions": { "click": "LEAVE_LIBRARY" }, From 299516a4108881181519d69f62274355f10676bf Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Mon, 7 Jan 2019 19:43:32 +0000 Subject: [PATCH 017/259] remove moment-es6 usage (#892) --- .../shared/content-node-share/content-node-share.dialog.spec.ts | 2 +- .../shared/content-node-share/content-node-share.dialog.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/components/shared/content-node-share/content-node-share.dialog.spec.ts b/src/app/components/shared/content-node-share/content-node-share.dialog.spec.ts index d4f6b8319c..3a062f7984 100644 --- a/src/app/components/shared/content-node-share/content-node-share.dialog.spec.ts +++ b/src/app/components/shared/content-node-share/content-node-share.dialog.spec.ts @@ -28,7 +28,7 @@ import { } from '@alfresco/adf-core'; import { ContentNodeShareModule } from './content-node-share.module'; import { ShareDialogComponent } from './content-node-share.dialog'; -import moment from 'moment-es6'; +import * as moment from 'moment'; import { Store } from '@ngrx/store'; describe('ShareDialogComponent', () => { diff --git a/src/app/components/shared/content-node-share/content-node-share.dialog.ts b/src/app/components/shared/content-node-share/content-node-share.dialog.ts index c737a495ec..b6382a2495 100644 --- a/src/app/components/shared/content-node-share/content-node-share.dialog.ts +++ b/src/app/components/shared/content-node-share/content-node-share.dialog.ts @@ -38,7 +38,7 @@ import { import { SharedLinksApiService, NodesApiService } from '@alfresco/adf-core'; import { SharedLinkEntry, MinimalNodeEntryEntity } from 'alfresco-js-api'; import { ConfirmDialogComponent } from '@alfresco/adf-content-services'; -import moment from 'moment-es6'; +import * as moment from 'moment'; @Component({ selector: 'aca-share-dialog', From 71074b2bf1f69ba44b8493ac47cc9ca885ab0fed Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Wed, 9 Jan 2019 10:19:09 +0200 Subject: [PATCH 018/259] [ACA] Create Library - switch to ADF component (#893) * use adf component * fix component name locator --- .../dialog/create-library-dialog.ts | 2 +- src/app/app.module.ts | 5 +- src/app/dialogs/library/library.dialog.html | 89 ------ src/app/dialogs/library/library.dialog.scss | 29 -- .../dialogs/library/library.dialog.spec.ts | 248 ----------------- src/app/dialogs/library/library.dialog.ts | 262 ------------------ .../services/content-management.service.ts | 4 +- 7 files changed, 5 insertions(+), 634 deletions(-) delete mode 100644 src/app/dialogs/library/library.dialog.html delete mode 100644 src/app/dialogs/library/library.dialog.scss delete mode 100644 src/app/dialogs/library/library.dialog.spec.ts delete mode 100644 src/app/dialogs/library/library.dialog.ts diff --git a/e2e/components/dialog/create-library-dialog.ts b/e2e/components/dialog/create-library-dialog.ts index 074d5beeba..305ccdf709 100755 --- a/e2e/components/dialog/create-library-dialog.ts +++ b/e2e/components/dialog/create-library-dialog.ts @@ -30,7 +30,7 @@ import { Utils } from '../../utilities/utils'; export class CreateLibraryDialog extends Component { private static selectors = { - root: 'app-library-dialog', + root: 'adf-library-dialog', title: '.mat-dialog-title', nameInput: 'input[placeholder="Name" i]', diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 2de688991f..98391279c7 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -39,6 +39,7 @@ import { TranslateLoaderService } from '@alfresco/adf-core'; import { + LibraryDialogComponent, ContentModule, CustomResourcesService } from '@alfresco/adf-content-services'; @@ -50,7 +51,6 @@ import { FilesComponent } from './components/files/files.component'; import { LibrariesComponent } from './components/libraries/libraries.component'; import { FavoriteLibrariesComponent } from './components/favorite-libraries/favorite-libraries.component'; import { NodeVersionsDialogComponent } from './dialogs/node-versions/node-versions.dialog'; -import { LibraryDialogComponent } from './dialogs/library/library.dialog'; import { AppStoreModule } from './store/app-store.module'; import { MaterialModule } from './material.module'; @@ -118,8 +118,7 @@ import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; FilesComponent, LibrariesComponent, FavoriteLibrariesComponent, - NodeVersionsDialogComponent, - LibraryDialogComponent + NodeVersionsDialogComponent ], providers: [ { provide: RouteReuseStrategy, useClass: AppRouteReuseStrategy }, diff --git a/src/app/dialogs/library/library.dialog.html b/src/app/dialogs/library/library.dialog.html deleted file mode 100644 index 20437bcd7d..0000000000 --- a/src/app/dialogs/library/library.dialog.html +++ /dev/null @@ -1,89 +0,0 @@ -

{{ createTitle | translate }}

- - -
- - - - {{ 'LIBRARY.HINTS.SITE_TITLE_EXISTS' | translate }} - - - {{ 'LIBRARY.ERRORS.TITLE_TOO_LONG' | translate }} - - - - {{ form.controls['title'].errors?.message | translate }} - - - - - - - - {{ form.controls['id'].errors?.message | translate }} - - - - {{ 'LIBRARY.ERRORS.ID_TOO_LONG' | translate }} - - - - - - - - {{ 'LIBRARY.ERRORS.DESCRIPTION_TOO_LONG' | translate }} - - - - - - {{ option.label | translate }} - - -
-
- - - - - - diff --git a/src/app/dialogs/library/library.dialog.scss b/src/app/dialogs/library/library.dialog.scss deleted file mode 100644 index 5c8abdba9c..0000000000 --- a/src/app/dialogs/library/library.dialog.scss +++ /dev/null @@ -1,29 +0,0 @@ -.app-library-dialog { - .mat-radio-group { - display: flex; - flex-direction: column; - margin: 0 0 20px 0; - } - - .mat-radio-group .mat-radio-button { - margin: 10px 0; - } - - .mat-form-field { - width: 100%; - } - - mat-form-field { - padding-top: 20px; - } - - .actions-buttons { - display: flex; - flex-direction: row; - justify-content: flex-end; - - .mat-button { - text-transform: uppercase; - } - } -} diff --git a/src/app/dialogs/library/library.dialog.spec.ts b/src/app/dialogs/library/library.dialog.spec.ts deleted file mode 100644 index 01808c1452..0000000000 --- a/src/app/dialogs/library/library.dialog.spec.ts +++ /dev/null @@ -1,248 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2018 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { ReactiveFormsModule } from '@angular/forms'; -import { CoreModule } from '@alfresco/adf-core'; -import { LibraryDialogComponent } from './library.dialog'; -import { TestBed, fakeAsync, tick, flush } from '@angular/core/testing'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; -import { MatDialogRef } from '@angular/material'; -import { - AlfrescoApiService, - AlfrescoApiServiceMock, - setupTestBed -} from '@alfresco/adf-core'; - -describe('LibraryDialogComponent', () => { - let fixture; - let component; - let alfrescoApi; - const dialogRef = { - close: jasmine.createSpy('close') - }; - - setupTestBed({ - imports: [NoopAnimationsModule, CoreModule, ReactiveFormsModule], - declarations: [LibraryDialogComponent], - providers: [ - { - provide: AlfrescoApiService, - useClass: AlfrescoApiServiceMock - }, - { provide: MatDialogRef, useValue: dialogRef } - ], - schemas: [NO_ERRORS_SCHEMA] - }); - - beforeEach(() => { - fixture = TestBed.createComponent(LibraryDialogComponent); - component = fixture.componentInstance; - alfrescoApi = TestBed.get(AlfrescoApiService); - - spyOn( - alfrescoApi.getInstance().core.queriesApi, - 'findSites' - ).and.returnValue( - Promise.resolve({ - list: { entries: [] } - }) - ); - }); - - it('should set library id automatically on title input', fakeAsync(() => { - spyOn(alfrescoApi.sitesApi, 'getSite').and.callFake(() => { - return new Promise((resolve, reject) => reject()); - }); - - fixture.detectChanges(); - component.form.controls.title.setValue('libraryTitle'); - tick(500); - flush(); - fixture.detectChanges(); - - expect(component.form.controls.id.value).toBe('libraryTitle'); - })); - - it('should translate library title space character to dash for library id', fakeAsync(() => { - spyOn(alfrescoApi.sitesApi, 'getSite').and.callFake(() => { - return new Promise((resolve, reject) => reject()); - }); - - fixture.detectChanges(); - component.form.controls.title.setValue('library title'); - tick(500); - flush(); - fixture.detectChanges(); - - expect(component.form.controls.id.value).toBe('library-title'); - })); - - it('should not translate library title if value is not a valid id', fakeAsync(() => { - spyOn(alfrescoApi.sitesApi, 'getSite').and.callFake(() => { - return new Promise((resolve, reject) => reject()); - }); - - fixture.detectChanges(); - component.form.controls.title.setValue('@@@####'); - tick(500); - flush(); - fixture.detectChanges(); - - expect(component.form.controls.id.value).toBe(null); - })); - - it('should translate library title partially for library id', fakeAsync(() => { - spyOn(alfrescoApi.sitesApi, 'getSite').and.callFake(() => { - return new Promise((resolve, reject) => reject()); - }); - - fixture.detectChanges(); - component.form.controls.title.setValue('@@@####library'); - tick(500); - flush(); - fixture.detectChanges(); - - expect(component.form.controls.id.value).toBe('library'); - })); - - it('should translate library title multiple space character to one dash for library id', fakeAsync(() => { - spyOn(alfrescoApi.sitesApi, 'getSite').and.callFake(() => { - return new Promise((resolve, reject) => reject()); - }); - - fixture.detectChanges(); - component.form.controls.title.setValue('library title'); - tick(500); - flush(); - fixture.detectChanges(); - - expect(component.form.controls.id.value).toBe('library-title'); - })); - - it('should not change custom library id on title input', fakeAsync(() => { - spyOn(alfrescoApi.sitesApi, 'getSite').and.callFake(() => { - return new Promise((resolve, reject) => reject()); - }); - - fixture.detectChanges(); - component.form.controls.id.setValue('custom-id'); - component.form.controls.id.markAsDirty(); - tick(500); - flush(); - fixture.detectChanges(); - - component.form.controls.title.setValue('library title'); - tick(500); - flush(); - fixture.detectChanges(); - - expect(component.form.controls.id.value).toBe('custom-id'); - })); - - it('should invalidate form when library id already exists', fakeAsync(() => { - spyOn(alfrescoApi.sitesApi, 'getSite').and.returnValue(Promise.resolve()); - - fixture.detectChanges(); - component.form.controls.id.setValue('existingLibrary'); - tick(500); - flush(); - fixture.detectChanges(); - - expect(component.form.controls.id.errors).toEqual({ - message: 'LIBRARY.ERRORS.EXISTENT_SITE' - }); - expect(component.form.valid).toBe(false); - })); - - it('should create site when form is valid', fakeAsync(() => { - spyOn(alfrescoApi.sitesApi, 'createSite').and.returnValue( - Promise.resolve() - ); - spyOn(alfrescoApi.sitesApi, 'getSite').and.callFake(() => { - return new Promise((resolve, reject) => reject()); - }); - - fixture.detectChanges(); - component.form.controls.title.setValue('library title'); - tick(500); - flush(); - fixture.detectChanges(); - - component.submit(); - fixture.detectChanges(); - flush(); - - expect(alfrescoApi.sitesApi.createSite).toHaveBeenCalledWith({ - id: 'library-title', - title: 'library title', - description: '', - visibility: 'PUBLIC' - }); - })); - - it('should not create site when form is invalid', fakeAsync(() => { - spyOn(alfrescoApi.sitesApi, 'createSite').and.returnValue( - Promise.resolve({}) - ); - spyOn(alfrescoApi.sitesApi, 'getSite').and.returnValue(Promise.resolve()); - - fixture.detectChanges(); - component.form.controls.title.setValue('existingLibrary'); - tick(500); - flush(); - fixture.detectChanges(); - - component.submit(); - fixture.detectChanges(); - flush(); - - expect(alfrescoApi.sitesApi.createSite).not.toHaveBeenCalled(); - })); - - it('should notify on 409 conflict error (might be in trash)', fakeAsync(() => { - const error = { message: '{ "error": { "statusCode": 409 } }' }; - spyOn(alfrescoApi.sitesApi, 'createSite').and.callFake(() => { - return new Promise((resolve, reject) => reject(error)); - }); - spyOn(alfrescoApi.sitesApi, 'getSite').and.callFake(() => { - return new Promise((resolve, reject) => reject()); - }); - - fixture.detectChanges(); - component.form.controls.title.setValue('test'); - tick(500); - flush(); - fixture.detectChanges(); - - component.submit(); - fixture.detectChanges(); - flush(); - - expect(component.form.controls.id.errors).toEqual({ - message: 'LIBRARY.ERRORS.CONFLICT' - }); - })); -}); diff --git a/src/app/dialogs/library/library.dialog.ts b/src/app/dialogs/library/library.dialog.ts deleted file mode 100644 index 7bfcbf8e98..0000000000 --- a/src/app/dialogs/library/library.dialog.ts +++ /dev/null @@ -1,262 +0,0 @@ -/*! - * @license - * Copyright 2016 Alfresco Software, Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Observable, Subject, from } from 'rxjs'; -import { - Component, - OnInit, - Output, - EventEmitter, - OnDestroy, - ViewEncapsulation -} from '@angular/core'; -import { - FormBuilder, - FormGroup, - Validators, - FormControl, - AbstractControl -} from '@angular/forms'; -import { MatDialogRef } from '@angular/material'; -import { SiteBody, SiteEntry, SitePaging } from 'alfresco-js-api'; -import { AlfrescoApiService } from '@alfresco/adf-core'; -import { debounceTime, mergeMap, takeUntil } from 'rxjs/operators'; - -@Component({ - selector: 'app-library-dialog', - styleUrls: ['./library.dialog.scss'], - templateUrl: './library.dialog.html', - encapsulation: ViewEncapsulation.None, - host: { class: 'app-library-dialog' } -}) -export class LibraryDialogComponent implements OnInit, OnDestroy { - @Output() - error: EventEmitter = new EventEmitter(); - - @Output() - success: EventEmitter = new EventEmitter(); - - onDestroy$: Subject = new Subject(); - - createTitle = 'LIBRARY.DIALOG.CREATE_TITLE'; - libraryTitleExists = false; - form: FormGroup; - visibilityOption: any; - visibilityOptions = [ - { value: 'PUBLIC', label: 'LIBRARY.VISIBILITY.PUBLIC', disabled: false }, - { value: 'PRIVATE', label: 'LIBRARY.VISIBILITY.PRIVATE', disabled: false }, - { - value: 'MODERATED', - label: 'LIBRARY.VISIBILITY.MODERATED', - disabled: false - } - ]; - - constructor( - private alfrescoApiService: AlfrescoApiService, - private formBuilder: FormBuilder, - private dialog: MatDialogRef - ) {} - - ngOnInit() { - const validators = { - id: [ - Validators.required, - Validators.maxLength(72), - this.forbidSpecialCharacters - ], - title: [ - Validators.required, - this.forbidOnlySpaces, - Validators.maxLength(256) - ], - description: [Validators.maxLength(512)] - }; - - this.form = this.formBuilder.group({ - title: [null, validators.title], - id: [null, validators.id, this.createSiteIdValidator()], - description: ['', validators.description] - }); - - this.visibilityOption = this.visibilityOptions[0].value; - - this.form.controls['title'].valueChanges - .pipe( - debounceTime(300), - mergeMap(title => this.checkLibraryNameExists(title), title => title), - takeUntil(this.onDestroy$) - ) - .subscribe((title: string) => { - if (!this.form.controls['id'].dirty && this.canGenerateId(title)) { - this.form.patchValue({ id: this.sanitize(title.trim()) }); - this.form.controls['id'].markAsTouched(); - } - }); - } - - ngOnDestroy() { - this.onDestroy$.next(true); - this.onDestroy$.complete(); - } - - get title(): string { - const { title } = this.form.value; - - return (title || '').trim(); - } - - get id(): string { - const { id } = this.form.value; - - return (id || '').trim(); - } - - get description(): string { - const { description } = this.form.value; - - return (description || '').trim(); - } - - get visibility(): string { - return this.visibilityOption || ''; - } - - submit() { - const { form, dialog } = this; - - if (!form.valid) { - return; - } - - this.create().subscribe( - (node: SiteEntry) => { - this.success.emit(node); - dialog.close(node); - }, - error => this.handleError(error) - ); - } - - visibilityChangeHandler(event) { - this.visibilityOption = event.value; - } - - private create(): Observable { - const { title, id, description, visibility } = this; - const siteBody = { - id, - title, - description, - visibility - }; - - return from(this.alfrescoApiService.sitesApi.createSite(siteBody)); - } - - private sanitize(input: string) { - return input.replace(/[\s\s]+/g, '-').replace(/[^A-Za-z0-9-]/g, ''); - } - - private canGenerateId(title) { - return Boolean(title.replace(/[^A-Za-z0-9-]/g, '').length); - } - - private handleError(error: any): any { - const { - error: { statusCode } - } = JSON.parse(error.message); - - if (statusCode === 409) { - this.form.controls['id'].setErrors({ - message: 'LIBRARY.ERRORS.CONFLICT' - }); - } - - return error; - } - - private async checkLibraryNameExists(libraryTitle: string) { - const { entries } = (await this.findLibraryByTitle(libraryTitle)).list; - - if (entries.length) { - this.libraryTitleExists = entries[0].entry.title === libraryTitle; - } else { - this.libraryTitleExists = false; - } - } - - private findLibraryByTitle(libraryTitle: string): Promise { - return this.alfrescoApiService - .getInstance() - .core.queriesApi.findSites(libraryTitle, { - maxItems: 1, - fields: ['title'] - }) - .catch(() => ({ list: { entries: [] } })); - } - - private forbidSpecialCharacters({ value }: FormControl) { - if (value === null || value.length === 0) { - return null; - } - - const validCharacters: RegExp = /[^A-Za-z0-9-]/; - const isValid: boolean = !validCharacters.test(value); - - return isValid - ? null - : { - message: 'LIBRARY.ERRORS.ILLEGAL_CHARACTERS' - }; - } - - private forbidOnlySpaces({ value }: FormControl) { - if (value === null || value.length === 0) { - return null; - } - - const isValid: boolean = !!(value || '').trim(); - - return isValid - ? null - : { - message: 'LIBRARY.ERRORS.ONLY_SPACES' - }; - } - - private createSiteIdValidator() { - let timer; - - return (control: AbstractControl) => { - if (timer) { - clearTimeout(timer); - } - - return new Promise(resolve => { - timer = setTimeout(() => { - return from( - this.alfrescoApiService.sitesApi.getSite(control.value) - ).subscribe( - () => resolve({ message: 'LIBRARY.ERRORS.EXISTENT_SITE' }), - () => resolve(null) - ); - }, 300); - }); - }; - } -} diff --git a/src/app/services/content-management.service.ts b/src/app/services/content-management.service.ts index 31c02520c0..f8aa5a146e 100644 --- a/src/app/services/content-management.service.ts +++ b/src/app/services/content-management.service.ts @@ -28,9 +28,9 @@ import { Injectable } from '@angular/core'; import { MatDialog, MatSnackBar } from '@angular/material'; import { FolderDialogComponent, - ConfirmDialogComponent + ConfirmDialogComponent, + LibraryDialogComponent } from '@alfresco/adf-content-services'; -import { LibraryDialogComponent } from '../dialogs/library/library.dialog'; import { SnackbarErrorAction, SnackbarInfoAction, From 0163c3e6e4d2dd86b25ea8905121506b0cd3e6a4 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Wed, 9 Jan 2019 13:36:54 +0000 Subject: [PATCH 019/259] update extension registration docs --- docs/extending/registration.md | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/docs/extending/registration.md b/docs/extending/registration.md index 285ffa419b..d0afcecf48 100644 --- a/docs/extending/registration.md +++ b/docs/extending/registration.md @@ -1,6 +1,3 @@ ---- ---- - # Registration You can use `ExtensionService` to register custom components, authentication guards, @@ -16,7 +13,7 @@ and use the following snippet to register custom content: import { ExtensionsModule, ExtensionService } from '@alfresco/adf-extensions'; @NgModule({ - imports: [ ExtensionsModule.forChild() ] + imports: [ ExtensionsModule ] declarations: [ MyComponent1, MyLayout ], entryComponents: [ MyComponent1, MyLayout ] }) @@ -41,9 +38,6 @@ export class MyExtensionModule { } ``` -Use `ExtensionsModule.forChild()` when importing into the child modules, -and `ExtensionsModule.forRoot()` for the main application module. -

According to Angular rules, all components that are created dynamically at runtime need to be registered within the `entryComponents` section of the NgModule. From b50d7bd5e3301f017dbc1ed4317691b01140246d Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Mon, 14 Jan 2019 09:33:47 +0000 Subject: [PATCH 020/259] fix SSO defaults --- src/app.config.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app.config.json b/src/app.config.json index 7870fd57be..3205c49636 100644 --- a/src/app.config.json +++ b/src/app.config.json @@ -4,13 +4,13 @@ "providers": "ECM", "authType": "BASIC", "oauth2": { - "host": "http://localhost:30081/auth/realms/myrealm", + "host": "http://localhost:8081/auth/realms/alfresco", "clientId": "alfresco", "scope": "openid", "secret": "", "implicitFlow": true, "silentLogin": true, - "redirectSilentIframeUri": "/assets/silent-refresh.html", + "redirectSilentIframeUri": "./assets/silent-refresh.html", "redirectUri": "/", "redirectUriLogout": "/logout" }, From 0471b783a47bc69fffd00cac46887d7c15661fd2 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Mon, 14 Jan 2019 20:32:38 +0000 Subject: [PATCH 021/259] fix pre-commit issue with partial commits --- package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index 0f5ff84847..e332e49fd9 100644 --- a/package.json +++ b/package.json @@ -107,8 +107,7 @@ }, "lint-staged": { "*.{ts,js,css,scss,html}": [ - "prettier --single-quote --write", - "git add" + "prettier --single-quote --write" ] }, "pre-commit": "lint:staged" From d2e0f688e8e13d5a0ed1e09f80dc1a21b6dcacbd Mon Sep 17 00:00:00 2001 From: Adina Parpalita Date: Sat, 19 Jan 2019 18:47:12 +0200 Subject: [PATCH 022/259] [ACA-2116] search results available actions (#895) * add item.id to File Libraries * add method to wait for node to be indexed * create separate methods in queries API to wait for sites or wait for nodes * improvements, renaming * renaming * fix * add tests for actions on search results * add wait and use new method * fix * another fix * use correct method * more fixes * create method for clickView button * fixes * no message --- cspell.json | 3 +- e2e/components/data-table/data-table.ts | 16 +- .../dialog/create-edit-folder-dialog.ts | 2 +- e2e/components/search/search-input.ts | 30 ++- e2e/components/sidenav/sidenav.ts | 43 +++- e2e/components/toolbar/toolbar.ts | 9 +- e2e/configs.ts | 11 +- e2e/pages/browsing-page.ts | 69 ++--- e2e/pages/page.ts | 24 +- .../context-menu-multiple-selection.test.ts | 84 ++++++- .../context-menu-single-selection.test.ts | 139 +++++++++-- e2e/suites/actions/create-folder.test.ts | 2 +- e2e/suites/actions/create-library.test.ts | 10 +- e2e/suites/actions/edit-folder.test.ts | 2 +- e2e/suites/actions/library-actions.test.ts | 16 +- e2e/suites/actions/mark-favorite.test.ts | 8 +- e2e/suites/actions/new-menu.test.ts | 14 +- e2e/suites/actions/share-file.test.ts | 18 +- ...cial-permissions-available-actions.test.ts | 236 +++++++++++++++++- .../toolbar-multiple-selection.test.ts | 130 +++++++--- .../actions/toolbar-single-selection.test.ts | 153 +++++++++--- e2e/suites/actions/unshare-file.test.ts | 6 +- e2e/suites/application/page-titles.test.ts | 33 +-- .../info-drawer/library-properties.test.ts | 2 +- e2e/suites/list-views/file-libraries.test.ts | 4 +- e2e/suites/navigation/breadcrumb.test.ts | 6 +- e2e/suites/navigation/sidebar.test.ts | 2 +- .../pagination/pag-file-libraries.test.ts | 2 +- e2e/suites/search/search-input.test.ts | 1 + .../search/search-results-libraries.test.ts | 2 +- e2e/suites/search/search-results.test.ts | 2 +- e2e/suites/viewer/viewer-actions.test.ts | 2 +- e2e/suites/viewer/viewer-general.test.ts | 7 +- .../repo-client/apis/queries/queries-api.ts | 29 ++- .../repo-client/apis/search/search-api.ts | 46 ++++ .../components/sidenav/sidenav.component.html | 1 + 36 files changed, 913 insertions(+), 251 deletions(-) diff --git a/cspell.json b/cspell.json index b63c3393aa..ecc4c0ed8f 100644 --- a/cspell.json +++ b/cspell.json @@ -56,8 +56,7 @@ "keycodes", "denysvuika", "submenu", - "submenus", - "simpletask" + "submenus" ], "dictionaries": ["html", "en-gb", "en_US"] } diff --git a/e2e/components/data-table/data-table.ts b/e2e/components/data-table/data-table.ts index 6907c0fb08..c78cdca493 100755 --- a/e2e/components/data-table/data-table.ts +++ b/e2e/components/data-table/data-table.ts @@ -191,10 +191,14 @@ export class DataTable extends Component { // Navigation/selection methods async doubleClickOnRowByName(name: string) { - const item = this.getRowFirstCell(name); - await Utils.waitUntilElementClickable(item); - await browser.actions().mouseMove(item).perform(); - await browser.actions().click().click().perform(); + try { + const item = this.getRowFirstCell(name); + await Utils.waitUntilElementClickable(item); + await browser.actions().mouseMove(item).perform(); + await browser.actions().click().click().perform(); + } catch (error) { + console.log('--- catch: doubleClickOnRowByName', error); + } } async selectItem(name: string) { @@ -225,7 +229,7 @@ export class DataTable extends Component { const count = await this.countSelectedRows(); if (count !== 0) { await browser.refresh(); - await this.waitForHeader(); + await this.wait(); } } catch (error) { console.log('------ clearSelection catch : ', error); @@ -238,7 +242,7 @@ export class DataTable extends Component { } async rightClickOnMultipleSelection() { - await this.waitForHeader(); + await this.wait(); const itemFromSelection = this.getSelectedRows().get(0); await browser.actions().click(itemFromSelection, protractor.Button.RIGHT).perform(); } diff --git a/e2e/components/dialog/create-edit-folder-dialog.ts b/e2e/components/dialog/create-edit-folder-dialog.ts index c2a29c2a00..28095d859b 100755 --- a/e2e/components/dialog/create-edit-folder-dialog.ts +++ b/e2e/components/dialog/create-edit-folder-dialog.ts @@ -23,7 +23,7 @@ * along with Alfresco. If not, see . */ -import { ElementFinder, by, browser, protractor, ExpectedConditions as EC, promise } from 'protractor'; +import { ElementFinder, by, browser, protractor, ExpectedConditions as EC } from 'protractor'; import { BROWSER_WAIT_TIMEOUT } from '../../configs'; import { Component } from '../component'; import { Utils } from '../../utilities/utils'; diff --git a/e2e/components/search/search-input.ts b/e2e/components/search/search-input.ts index 5bf99c1650..0698fa11ae 100755 --- a/e2e/components/search/search-input.ts +++ b/e2e/components/search/search-input.ts @@ -23,9 +23,10 @@ * along with Alfresco. If not, see . */ -import { ElementFinder, browser, by, until, protractor } from 'protractor'; +import { ElementFinder, browser, by, until, protractor, ExpectedConditions as EC } from 'protractor'; import { BROWSER_WAIT_TIMEOUT } from '../../configs'; import { Component } from '../component'; +import { Utils } from '../../utilities/utils'; export class SearchInput extends Component { private static selectors = { @@ -35,27 +36,36 @@ export class SearchInput extends Component { searchControl: '.app-search-control', searchInput: 'app-control-input', searchOptionsArea: 'search-options', - optionCheckbox: '.mat-checkbox' + optionCheckbox: '.mat-checkbox', + clearButton: '.app-clear-icon' }; searchButton: ElementFinder = this.component.element(by.css(SearchInput.selectors.searchButton)); searchContainer: ElementFinder = browser.element(by.css(SearchInput.selectors.searchContainer)); + searchControl: ElementFinder = browser.element(by.css(SearchInput.selectors.searchControl)); searchBar: ElementFinder = browser.element(by.id(SearchInput.selectors.searchInput)); searchOptionsArea: ElementFinder = browser.element(by.id(SearchInput.selectors.searchOptionsArea)); searchFilesOption: ElementFinder = this.searchOptionsArea.element(by.cssContainingText(SearchInput.selectors.optionCheckbox, 'Files')); searchFoldersOption: ElementFinder = this.searchOptionsArea.element(by.cssContainingText(SearchInput.selectors.optionCheckbox, 'Folders')); searchLibrariesOption: ElementFinder = this.searchOptionsArea.element(by.cssContainingText(SearchInput.selectors.optionCheckbox, 'Libraries')); + clearSearchButton: ElementFinder = this.searchContainer.$(SearchInput.selectors.clearButton); constructor(ancestor?: ElementFinder) { super(SearchInput.selectors.root, ancestor); } + async waitForSearchControl() { + return await browser.wait(EC.presenceOf(this.searchControl), BROWSER_WAIT_TIMEOUT, '--- timeout waitForSearchControl ---'); + } + async isSearchContainerDisplayed() { return (await this.searchContainer.isDisplayed()) && (await this.searchButton.isDisplayed()); } async clickSearchButton() { + await Utils.waitUntilElementClickable(this.searchButton); await this.searchButton.click(); + await this.waitForSearchControl(); } async isOptionsAreaDisplayed() { @@ -117,6 +127,16 @@ export class SearchInput extends Component { } } + async isClearSearchButtonPresent() { + return await browser.isElementPresent(this.clearSearchButton); + } + + async clickClearSearchButton() { + if (await this.isClearSearchButtonPresent()) { + return await this.clearSearchButton.click(); + } + } + async checkOnlyFiles() { await this.clearOptions(); await this.clickFilesOption(); @@ -139,8 +159,14 @@ export class SearchInput extends Component { } async searchFor(text: string) { + await browser.wait(EC.elementToBeClickable(this.searchBar), BROWSER_WAIT_TIMEOUT, '---- timeout waiting for searchBar to be clickable'); await this.searchBar.clear(); await this.searchBar.sendKeys(text); await this.searchBar.sendKeys(protractor.Key.ENTER); } + + async searchForTextAndCloseSearchOptions(text: string) { + await this.searchFor(text); + await Utils.pressEscape(); + } } diff --git a/e2e/components/sidenav/sidenav.ts b/e2e/components/sidenav/sidenav.ts index 145c772e4b..c363c47fba 100755 --- a/e2e/components/sidenav/sidenav.ts +++ b/e2e/components/sidenav/sidenav.ts @@ -36,15 +36,34 @@ export class Sidenav extends Component { label: '.item--label', expansion_panel: ".mat-expansion-panel-header", expansion_panel_content: ".mat-expansion-panel-body", - active: 'item--active', - activeLink: '.item--active', - newButton: '[data-automation-id="create-button"]' + active: 'mat-accent', + activeLink: '.mat-accent', + activeChild: 'item--active', + newButton: '[data-automation-id="create-button"]', + + personalFiles: `[id='app.navbar.personalFiles']`, + fileLibraries: `[id='app.navbar.libraries.menu']`, + myLibraries: `[id='app.navbar.libraries.files']`, + favoriteLibraries: `[id='app.navbar.libraries.favorite']`, + shared: `[id='app.navbar.shared']`, + recentFiles: `[id='app.navbar.recentFiles']`, + favorites: `[id='app.navbar.favorites']`, + trash: `[id='app.navbar.trashcan']` }; links: ElementArrayFinder = this.component.all(by.css(Sidenav.selectors.link)); activeLink: ElementFinder = this.component.element(by.css(Sidenav.selectors.activeLink)); newButton: ElementArrayFinder = this.component.all(by.css(Sidenav.selectors.newButton)); + personalFiles: ElementFinder = this.component.element(by.css(Sidenav.selectors.personalFiles)); + fileLibraries: ElementFinder = this.component.element(by.css(Sidenav.selectors.fileLibraries)); + myLibraries: ElementFinder = this.component.element(by.css(Sidenav.selectors.myLibraries)); + favoriteLibraries: ElementFinder = this.component.element(by.css(Sidenav.selectors.favoriteLibraries)); + shared: ElementFinder = this.component.element(by.css(Sidenav.selectors.shared)); + recentFiles: ElementFinder = this.component.element(by.css(Sidenav.selectors.recentFiles)); + favorites: ElementFinder = this.component.element(by.css(Sidenav.selectors.favorites)); + trash: ElementFinder = this.component.element(by.css(Sidenav.selectors.trash)); + menu: Menu = new Menu(); constructor(ancestor?: ElementFinder) { @@ -92,7 +111,7 @@ export class Sidenav extends Component { async childIsActive(name: string) { const childClass = await this.getLinkLabel(name).element(by.css('span')).getAttribute('class'); - return childClass.includes(Sidenav.selectors.active); + return childClass.includes(Sidenav.selectors.activeChild); } getLink(name: string) { @@ -100,7 +119,17 @@ export class Sidenav extends Component { } getLinkLabel(name: string) { - return this.component.element(by.cssContainingText(Sidenav.selectors.label, name)); + switch (name) { + case 'Personal Files': return this.personalFiles; + case 'File Libraries': return this.fileLibraries; + case 'My Libraries': return this.myLibraries; + case 'Favorite Libraries': return this.favoriteLibraries; + case 'Shared': return this.shared; + case 'Recent Files': return this.recentFiles; + case 'Favorites': return this.favorites; + case 'Trash': return this.trash; + default: return this.personalFiles; + } } getActiveLink() { @@ -111,14 +140,14 @@ export class Sidenav extends Component { return await this.getLink(name).getAttribute('title'); } - async navigateToLink(name: string) { + async clickLink(name: string) { try{ const link = this.getLinkLabel(name); await Utils.waitUntilElementClickable(link); return await link.click(); } catch (e){ - console.log('---- sidebar navigation catch navigateToLink: ', e); + console.log('---- sidebar navigation catch clickLink: ', e); } } diff --git a/e2e/components/toolbar/toolbar.ts b/e2e/components/toolbar/toolbar.ts index db0e975f88..44a6699626 100755 --- a/e2e/components/toolbar/toolbar.ts +++ b/e2e/components/toolbar/toolbar.ts @@ -23,9 +23,10 @@ * along with Alfresco. If not, see . */ -import { ElementFinder, ElementArrayFinder, by, protractor, browser } from 'protractor'; +import { ElementFinder, ElementArrayFinder, by, browser } from 'protractor'; import { Menu } from '../menu/menu'; import { Component } from '../component'; +import { Utils } from '../../utilities/utils'; export class Toolbar extends Component { private static selectors = { @@ -95,7 +96,7 @@ export class Toolbar extends Component { } async closeMoreMenu() { - await browser.actions().sendKeys(protractor.Key.ESCAPE).perform(); + await Utils.pressEscape(); } async getButtonTooltip(button: ElementFinder) { @@ -150,6 +151,10 @@ export class Toolbar extends Component { } + async clickView() { + return await this.viewButton.click(); + } + async clickEdit() { return await this.editButton.click(); } diff --git a/e2e/configs.ts b/e2e/configs.ts index 18f23a8859..30a79b28f2 100755 --- a/e2e/configs.ts +++ b/e2e/configs.ts @@ -69,10 +69,15 @@ export const SIDEBAR_LABELS = { // Page titles export const PAGE_TITLES = { - VIEWER: 'Preview', - SEARCH: 'Search Results', + PERSONAL_FILES: 'Personal Files', MY_LIBRARIES: 'My Libraries', - FAVORITE_LIBRARIES: 'Favorite Libraries' + FAVORITE_LIBRARIES: 'Favorite Libraries', + SHARED_FILES: 'Shared', + RECENT_FILES: 'Recent Files', + FAVORITES: 'Favorites', + TRASH: 'Trash', + VIEWER: 'Preview', + SEARCH: 'Search Results' }; // Site visibility diff --git a/e2e/pages/browsing-page.ts b/e2e/pages/browsing-page.ts index 41267da436..69f4bddbbe 100755 --- a/e2e/pages/browsing-page.ts +++ b/e2e/pages/browsing-page.ts @@ -45,76 +45,89 @@ export class BrowsingPage extends Page { // helper methods + async clickPersonalFiles() { + await this.sidenav.clickLink(SIDEBAR_LABELS.PERSONAL_FILES); + } + async clickPersonalFilesAndWait() { - await this.sidenav.navigateToLink(SIDEBAR_LABELS.PERSONAL_FILES); + await this.clickPersonalFiles(); await this.dataTable.waitForHeader(); } - async clickPersonalFiles() { - await this.sidenav.navigateToLink(SIDEBAR_LABELS.PERSONAL_FILES); - } + async clickFileLibraries() { + await this.sidenav.clickLink(SIDEBAR_LABELS.FILE_LIBRARIES); + } async clickFileLibrariesAndWait() { - await this.sidenav.expandFileLibraries(); - await this.sidenav.navigateToLink(SIDEBAR_LABELS.MY_LIBRARIES); + await this.clickFileLibraries(); await this.dataTable.waitForHeader(); } - async clickFileLibraries() { - await this.sidenav.expandFileLibraries(); - await this.sidenav.navigateToLink(SIDEBAR_LABELS.MY_LIBRARIES); - } async goToFavoriteLibraries() { - await this.sidenav.expandFileLibraries(); - await this.sidenav.navigateToLink(SIDEBAR_LABELS.FAVORITE_LIBRARIES); + if ( !(await this.sidenav.isFileLibrariesMenuExpanded()) ) { + await this.sidenav.expandFileLibraries(); + } + await this.sidenav.clickLink(SIDEBAR_LABELS.FAVORITE_LIBRARIES); + } + + async goToFavoriteLibrariesAndWait() { + await this.goToFavoriteLibraries(); + await this.dataTable.waitForHeader(); } + async goToMyLibraries() { if ( !(await this.sidenav.isFileLibrariesMenuExpanded()) ) { await this.sidenav.expandFileLibraries(); } - await this.sidenav.navigateToLink(SIDEBAR_LABELS.MY_LIBRARIES); + await this.sidenav.clickLink(SIDEBAR_LABELS.MY_LIBRARIES); } - async clickRecentFilesAndWait() { - await this.sidenav.navigateToLink(SIDEBAR_LABELS.RECENT_FILES); + async goToMyLibrariesAndWait() { + await this.goToMyLibraries(); await this.dataTable.waitForHeader(); } + async clickRecentFiles() { - await this.sidenav.navigateToLink(SIDEBAR_LABELS.RECENT_FILES); + await this.sidenav.clickLink(SIDEBAR_LABELS.RECENT_FILES); } - - async clickSharedFilesAndWait() { - await this.sidenav.navigateToLink(SIDEBAR_LABELS.SHARED_FILES); + async clickRecentFilesAndWait() { + await this.clickRecentFiles(); await this.dataTable.waitForHeader(); } + async clickSharedFiles() { - await this.sidenav.navigateToLink(SIDEBAR_LABELS.SHARED_FILES); + await this.sidenav.clickLink(SIDEBAR_LABELS.SHARED_FILES); } - - async clickFavoritesAndWait() { - await this.sidenav.navigateToLink(SIDEBAR_LABELS.FAVORITES); + async clickSharedFilesAndWait() { + await this.clickSharedFiles(); await this.dataTable.waitForHeader(); } + async clickFavorites() { - await this.sidenav.navigateToLink(SIDEBAR_LABELS.FAVORITES); + await this.sidenav.clickLink(SIDEBAR_LABELS.FAVORITES); } - - async clickTrashAndWait() { - await this.sidenav.navigateToLink(SIDEBAR_LABELS.TRASH); + async clickFavoritesAndWait() { + await this.clickFavorites(); await this.dataTable.waitForHeader(); } + async clickTrash() { - await this.sidenav.navigateToLink(SIDEBAR_LABELS.TRASH); + await this.sidenav.clickLink(SIDEBAR_LABELS.TRASH); + } + + async clickTrashAndWait() { + await this.clickTrash(); + await this.dataTable.waitForHeader(); } } diff --git a/e2e/pages/page.ts b/e2e/pages/page.ts index 8eb8bc0935..f6bcb18def 100755 --- a/e2e/pages/page.ts +++ b/e2e/pages/page.ts @@ -27,7 +27,7 @@ import { browser, by, ElementFinder, ExpectedConditions as EC, until } from 'pro import { BROWSER_WAIT_TIMEOUT, USE_HASH_STRATEGY } from './../configs'; export abstract class Page { - private static selectors = { + protected static locators = { app: 'app-root', layout: 'app-layout', overlay: '.cdk-overlay-container', @@ -41,17 +41,17 @@ export abstract class Page { genericErrorTitle: '.generic-error__title' }; - app: ElementFinder = browser.element(by.css(Page.selectors.app)); - layout: ElementFinder = browser.element(by.css(Page.selectors.layout)); - overlay: ElementFinder = browser.element(by.css(Page.selectors.overlay)); - snackBar: ElementFinder = browser.element(by.css(Page.selectors.snackBar)); - dialogContainer: ElementFinder = browser.element(by.css(Page.selectors.dialogContainer)); - snackBarContainer: ElementFinder = browser.element(by.css(Page.selectors.snackBarContainer)); - snackBarAction: ElementFinder = browser.element(by.css(Page.selectors.snackBarAction)); - - genericError: ElementFinder = browser.element(by.css(Page.selectors.genericError)); - genericErrorIcon: ElementFinder = browser.element(by.css(Page.selectors.genericErrorIcon)); - genericErrorTitle: ElementFinder = browser.element(by.css(Page.selectors.genericErrorTitle)); + app: ElementFinder = browser.element(by.css(Page.locators.app)); + layout: ElementFinder = browser.element(by.css(Page.locators.layout)); + overlay: ElementFinder = browser.element(by.css(Page.locators.overlay)); + snackBar: ElementFinder = browser.element(by.css(Page.locators.snackBar)); + dialogContainer: ElementFinder = browser.element(by.css(Page.locators.dialogContainer)); + snackBarContainer: ElementFinder = browser.element(by.css(Page.locators.snackBarContainer)); + snackBarAction: ElementFinder = browser.element(by.css(Page.locators.snackBarAction)); + + genericError: ElementFinder = browser.element(by.css(Page.locators.genericError)); + genericErrorIcon: ElementFinder = browser.element(by.css(Page.locators.genericErrorIcon)); + genericErrorTitle: ElementFinder = browser.element(by.css(Page.locators.genericErrorTitle)); constructor(public url: string = '') {} diff --git a/e2e/suites/actions/context-menu-multiple-selection.test.ts b/e2e/suites/actions/context-menu-multiple-selection.test.ts index 12e05aeac2..19045b5d47 100755 --- a/e2e/suites/actions/context-menu-multiple-selection.test.ts +++ b/e2e/suites/actions/context-menu-multiple-selection.test.ts @@ -23,7 +23,7 @@ * along with Alfresco. If not, see . */ -import { LoginPage, BrowsingPage } from '../../pages/pages'; +import { LoginPage, BrowsingPage, SearchResultsPage } from '../../pages/pages'; import { SITE_VISIBILITY } from '../../configs'; import { RepoClient } from '../../utilities/repo-client/repo-client'; import { Utils } from '../../utilities/utils'; @@ -31,11 +31,11 @@ import { Utils } from '../../utilities/utils'; describe('Context menu actions - multiple selection : ', () => { const username = `user-${Utils.random()}`; - const file1 = `file1-${Utils.random()}.txt`; let file1Id; - const file2 = `file2-${Utils.random()}.txt`; let file2Id; + const file1 = `my-file1-${Utils.random()}.txt`; let file1Id; + const file2 = `my-file2-${Utils.random()}.txt`; let file2Id; - const folder1 = `folder1-${Utils.random()}`; let folder1Id; - const folder2 = `folder2-${Utils.random()}`; let folder2Id; + const folder1 = `my-folder1-${Utils.random()}`; let folder1Id; + const folder2 = `my-folder2-${Utils.random()}`; let folder2Id; const fileInTrash1 = `deletedFile1-${Utils.random()}.txt`; let fileInTrash1Id; const fileInTrash2 = `deletedFile2-${Utils.random()}.txt`; let fileInTrash2Id; @@ -43,10 +43,10 @@ describe('Context menu actions - multiple selection : ', () => { const folderInTrash2 = `deletedFolder2-${Utils.random()}`; let folderInTrash2Id; const siteName = `site-${Utils.random()}`; - const file1Site = `file1-${Utils.random()}.txt`; - const file2Site = `file2-${Utils.random()}.txt`; - const folder1Site = `folder1-${Utils.random()}`; - const folder2Site = `folder2-${Utils.random()}`; + const file1Site = `my-inSite-file1-${Utils.random()}.txt`; + const file2Site = `my-inSite-file2-${Utils.random()}.txt`; + const folder1Site = `my-inSite-folder1-${Utils.random()}`; + const folder2Site = `my-inSite-folder2-${Utils.random()}`; const apis = { admin: new RepoClient(), @@ -57,6 +57,8 @@ describe('Context menu actions - multiple selection : ', () => { const page = new BrowsingPage(); const { dataTable } = page; const contextMenu = dataTable.menu; + const searchResultsPage = new SearchResultsPage(); + const { searchInput } = searchResultsPage.header; beforeAll(async (done) => { await apis.admin.people.createUser({ username }); @@ -70,7 +72,7 @@ describe('Context menu actions - multiple selection : ', () => { await apis.user.nodes.createFile(file1Site, docLibId); await apis.user.nodes.createFile(file2Site, docLibId); await apis.user.nodes.createFolder(folder1Site, docLibId); - await apis.user.nodes.createFile(folder2Site, docLibId); + await apis.user.nodes.createFolder(folder2Site, docLibId); await apis.user.shared.shareFilesByIds([ file1Id, file2Id ]); await apis.user.shared.waitForApi({ expect: 2 }); @@ -179,10 +181,9 @@ describe('Context menu actions - multiple selection : ', () => { describe('on File Libraries', () => { beforeEach(async (done) => { await Utils.pressEscape(); - await page.clickFileLibrariesAndWait(); + await page.goToMyLibrariesAndWait(); await dataTable.doubleClickOnRowByName(siteName); await dataTable.waitForHeader(); - await dataTable.clearSelection(); done(); }); @@ -382,4 +383,63 @@ describe('Context menu actions - multiple selection : ', () => { expect(await contextMenu.isFavoritePresent()).toBe(false, `Favorite is displayed`); }); }); + + describe('on Search Results', () => { + beforeEach(async (done) => { + await Utils.pressEscape(); + await page.clickPersonalFilesAndWait(); + done(); + }); + + it('correct actions appear when multiple files are selected - [C291831]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFiles(); + await searchInput.searchForTextAndCloseSearchOptions('my-inSite-file'); + await dataTable.selectMultipleItems([ file1Site, file2Site ]); + await dataTable.rightClickOnMultipleSelection(); + + expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); + expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); + expect(await contextMenu.isEditPresent()).toBe(false, 'Edit is displayed'); + expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); + expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); + expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed`); + }); + + it('correct actions appear when multiple folders are selected - [C291832]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFolders(); + await searchInput.searchForTextAndCloseSearchOptions('my-inSite-folder'); + await dataTable.selectMultipleItems([ folder1Site, folder2Site ]); + await dataTable.rightClickOnMultipleSelection(); + + expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); + expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); + expect(await contextMenu.isEditPresent()).toBe(false, 'Edit is displayed'); + expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); + expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); + expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed`); + }); + + it('correct actions appear when both files and folders are selected - [C291833]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkFilesAndFolders(); + await searchInput.searchForTextAndCloseSearchOptions('my-inSite-f'); + await dataTable.selectMultipleItems([ file1Site, file2Site, folder1Site, folder2Site ]); + await dataTable.rightClickOnMultipleSelection(); + + expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); + expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); + expect(await contextMenu.isEditPresent()).toBe(false, 'Edit is displayed'); + expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); + expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); + expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed`); + }); + }); }); diff --git a/e2e/suites/actions/context-menu-single-selection.test.ts b/e2e/suites/actions/context-menu-single-selection.test.ts index 1fc3f77c20..3e9c084a7d 100755 --- a/e2e/suites/actions/context-menu-single-selection.test.ts +++ b/e2e/suites/actions/context-menu-single-selection.test.ts @@ -23,7 +23,7 @@ * along with Alfresco. If not, see . */ -import { LoginPage, BrowsingPage } from '../../pages/pages'; +import { LoginPage, BrowsingPage, SearchResultsPage } from '../../pages/pages'; import { SITE_VISIBILITY } from '../../configs'; import { RepoClient } from '../../utilities/repo-client/repo-client'; import { Utils } from '../../utilities/utils'; @@ -52,6 +52,8 @@ describe('Context menu actions - single selection : ', () => { const page = new BrowsingPage(); const { dataTable } = page; const contextMenu = dataTable.menu; + const searchResultsPage = new SearchResultsPage(); + const { searchInput } = searchResultsPage.header; beforeAll(async (done) => { await apis.admin.people.createUser({ username }); @@ -82,6 +84,10 @@ describe('Context menu actions - single selection : ', () => { await apis.user.favorites.addFavoriteById('site', adminModerated); await apis.user.sites.requestToJoin(adminModerated); + await apis.user.queries.waitForSites(siteName, { expect: 1 }); + await apis.user.queries.waitForSites(adminPublic, { expect: 1 }); + await apis.user.queries.waitForSites(adminModerated, { expect: 1 }); + await loginPage.loginWith(username); done(); }); @@ -186,7 +192,7 @@ describe('Context menu actions - single selection : ', () => { describe('on File Libraries', () => { beforeEach(async (done) => { await Utils.pressEscape(); - await page.clickFileLibrariesAndWait(); + await page.goToMyLibrariesAndWait(); await dataTable.doubleClickOnRowByName(siteName); await dataTable.waitForHeader(); done(); @@ -231,8 +237,8 @@ describe('Context menu actions - single selection : ', () => { done(); }); - it('Available actions when a library is selected - My Libraries - [C290080]', async () => { - await page.goToMyLibraries(); + it('Available actions for a library - My Libraries - [C290080]', async () => { + await page.goToMyLibrariesAndWait(); await dataTable.rightClickOnItem(siteName); expect(await dataTable.hasContextMenu()).toBe(true, 'Context menu is not displayed'); @@ -241,8 +247,8 @@ describe('Context menu actions - single selection : ', () => { expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${siteName}`); }); - it('Available actions when a library is selected - Favorite Libraries - user is a member - [C290081]', async () => { - await page.goToFavoriteLibraries(); + it('Available actions for a library - Favorite Libraries - user is a member - [C290081]', async () => { + await page.goToFavoriteLibrariesAndWait(); await dataTable.rightClickOnItem(siteName); expect(await dataTable.hasContextMenu()).toBe(true, 'Context menu is not displayed'); @@ -251,8 +257,8 @@ describe('Context menu actions - single selection : ', () => { expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${siteName}`); }); - it('Available actions when a library is selected - Favorite Libraries - user is not a member - [C290082]', async () => { - await page.goToFavoriteLibraries(); + it('Available actions for a library - Favorite Libraries - user is not a member - [C290082]', async () => { + await page.goToFavoriteLibrariesAndWait(); await dataTable.rightClickOnItem(adminPublic); expect(await dataTable.hasContextMenu()).toBe(true, 'Context menu is not displayed'); @@ -261,8 +267,44 @@ describe('Context menu actions - single selection : ', () => { expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${adminPublic}`); }); - it('Available actions when a library is selected - Favorite Libraries - user requested to join - [C290089]', async () => { - await page.goToFavoriteLibraries(); + it('Available actions for a moderated library - Favorite Libraries - user requested to join - [C290089]', async () => { + await page.goToFavoriteLibrariesAndWait(); + await dataTable.rightClickOnItem(adminModerated); + + expect(await dataTable.hasContextMenu()).toBe(true, 'Context menu is not displayed'); + expect(await contextMenu.isCancelJoinPresent()).toBe(true, `Cancel join is not displayed for ${adminModerated}`); + expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed for ${adminModerated}`); + expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${adminModerated}`); + }); + + it('Available actions for a library - Search Results - user is a member - [C291812]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkLibraries(); + await searchInput.searchForTextAndCloseSearchOptions(siteName); + await dataTable.rightClickOnItem(siteName); + + expect(await dataTable.hasContextMenu()).toBe(true, 'Context menu is not displayed'); + expect(await contextMenu.isLeaveLibraryPresent()).toBe(true, `Leave is not displayed for ${siteName}`); + expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed for ${siteName}`); + expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${siteName}`); + }); + + it('Available actions for a library - Search Results - user is not a member - [C291813]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkLibraries(); + await searchInput.searchForTextAndCloseSearchOptions(adminPublic); + await dataTable.rightClickOnItem(adminPublic); + + expect(await dataTable.hasContextMenu()).toBe(true, 'Context menu is not displayed'); + expect(await contextMenu.isJoinLibraryPresent()).toBe(true, `Join is not displayed for ${adminPublic}`); + expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed for ${adminPublic}`); + expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${adminPublic}`); + }); + + it('Available actions for a moderated library - Search Results - user requested to join - [C291814]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkLibraries(); + await searchInput.searchForTextAndCloseSearchOptions(adminModerated); await dataTable.rightClickOnItem(adminModerated); expect(await dataTable.hasContextMenu()).toBe(true, 'Context menu is not displayed'); @@ -374,15 +416,15 @@ describe('Context menu actions - single selection : ', () => { expect(await contextMenu.isPermanentDeletePresent()) .toBe(true, `Permanently delete is not displayed for ${fileInTrash}`); expect(await contextMenu.isRestorePresent()).toBe(true, `Restore is not displayed for ${fileInTrash}`); - expect(await contextMenu.isDownloadPresent()).toBe(false, `Download is not displayed for ${fileInTrash}`); - expect(await contextMenu.isViewPresent()).toBe(false, `View is not displayed for ${fileInTrash}`); - expect(await contextMenu.isFavoritePresent()).toBe(false, `Favorite is not displayed for ${fileInTrash}`); - expect(await contextMenu.isCopyPresent()).toBe(false, `Copy is not displayed for ${fileInTrash}`); - expect(await contextMenu.isMovePresent()).toBe(false, `Move is not displayed for ${fileInTrash}`); - expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is not displayed for ${fileInTrash}`); - expect(await contextMenu.isSharePresent()).toBe(false, `Share is not displayed for ${fileInTrash}`); + expect(await contextMenu.isDownloadPresent()).toBe(false, `Download is displayed for ${fileInTrash}`); + expect(await contextMenu.isViewPresent()).toBe(false, `View is displayed for ${fileInTrash}`); + expect(await contextMenu.isFavoritePresent()).toBe(false, `Favorite is displayed for ${fileInTrash}`); + expect(await contextMenu.isCopyPresent()).toBe(false, `Copy is displayed for ${fileInTrash}`); + expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed for ${fileInTrash}`); + expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed for ${fileInTrash}`); + expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed for ${fileInTrash}`); expect(await contextMenu.isManageVersionsPresent()) - .toBe(false, `Manage Versions is not displayed for ${fileInTrash}`); + .toBe(false, `Manage Versions is displayed for ${fileInTrash}`); expect(await contextMenu.isEditPresent()).toBe(false, `Edit is displayed for ${fileInTrash}`); expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${fileInTrash}`); }); @@ -393,17 +435,62 @@ describe('Context menu actions - single selection : ', () => { expect(await contextMenu.isPermanentDeletePresent()) .toBe(true, `Permanently delete is not displayed for ${folderInTrash}`); expect(await contextMenu.isRestorePresent()).toBe(true, `Restore is not displayed for ${folderInTrash}`); - expect(await contextMenu.isDownloadPresent()).toBe(false, `Download is not displayed for ${folderInTrash}`); - expect(await contextMenu.isViewPresent()).toBe(false, `View is not displayed for ${folderInTrash}`); - expect(await contextMenu.isFavoritePresent()).toBe(false, `Favorite is not displayed for ${folderInTrash}`); - expect(await contextMenu.isCopyPresent()).toBe(false, `Copy is not displayed for ${folderInTrash}`); - expect(await contextMenu.isMovePresent()).toBe(false, `Move is not displayed for ${folderInTrash}`); - expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is not displayed for ${folderInTrash}`); - expect(await contextMenu.isSharePresent()).toBe(false, `Share is not displayed for ${folderInTrash}`); + expect(await contextMenu.isDownloadPresent()).toBe(false, `Download is displayed for ${folderInTrash}`); + expect(await contextMenu.isViewPresent()).toBe(false, `View is displayed for ${folderInTrash}`); + expect(await contextMenu.isFavoritePresent()).toBe(false, `Favorite is displayed for ${folderInTrash}`); + expect(await contextMenu.isCopyPresent()).toBe(false, `Copy is displayed for ${folderInTrash}`); + expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed for ${folderInTrash}`); + expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed for ${folderInTrash}`); + expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed for ${folderInTrash}`); expect(await contextMenu.isManageVersionsPresent()) - .toBe(false, `Manage Versions is not displayed for ${folderInTrash}`); + .toBe(false, `Manage Versions is displayed for ${folderInTrash}`); expect(await contextMenu.isEditPresent()).toBe(false, `Edit is displayed for ${folderInTrash}`); expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${folderInTrash}`); }); }); + + describe('on Search Results', () => { + beforeEach(async (done) => { + await Utils.pressEscape(); + await page.clickPersonalFilesAndWait(); + done(); + }); + + it('Context menu has the correct actions for a file - [C291827]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFiles(); + await searchInput.searchForTextAndCloseSearchOptions(fileSiteUser); + await dataTable.rightClickOnItem(fileSiteUser); + + expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileSiteUser}`); + expect(await contextMenu.isViewPresent()).toBe(true, `View is not displayed for ${fileSiteUser}`); + expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${fileSiteUser}`); + expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileSiteUser}`); + expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed for ${fileSiteUser}`); + expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed for ${fileSiteUser}`); + expect(await contextMenu.isSharePresent()).toBe(true, `Share is not displayed for ${fileSiteUser}`); + expect(await contextMenu.isManageVersionsPresent()).toBe(true, `Manage Versions not displayed for ${fileSiteUser}`); + expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed for ${fileSiteUser}`); + expect(await contextMenu.isEditPresent()).toBe(false, `Edit is displayed for ${fileSiteUser}`); + expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${fileSiteUser}`); + }); + + it('Context menu has the correct actions for a folder - [C291828]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFolders(); + await searchInput.searchForTextAndCloseSearchOptions(folderSiteUser); + await dataTable.rightClickOnItem(folderSiteUser); + + expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${folderSiteUser}`); + expect(await contextMenu.isEditPresent()).toBe(true, `Edit is not displayed for ${folderSiteUser}`); + expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${folderSiteUser}`); + expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${folderSiteUser}`); + expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed for ${folderSiteUser}`); + expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed for ${folderSiteUser}`); + expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed for ${folderSiteUser}`); + expect(await contextMenu.isViewPresent()).toBe(false, `View is displayed for ${folderSiteUser}`); + expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions displayed for ${folderSiteUser}`); + expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed for ${folderSiteUser}`); + }); + }); }); diff --git a/e2e/suites/actions/create-folder.test.ts b/e2e/suites/actions/create-folder.test.ts index 9d6b26ea5f..e609ddbecb 100755 --- a/e2e/suites/actions/create-folder.test.ts +++ b/e2e/suites/actions/create-folder.test.ts @@ -216,7 +216,7 @@ describe('Create folder', () => { const fileLibrariesPage = new BrowsingPage(); beforeEach(async (done) => { - await fileLibrariesPage.clickFileLibrariesAndWait(); + await fileLibrariesPage.goToMyLibrariesAndWait(); done(); }); diff --git a/e2e/suites/actions/create-library.test.ts b/e2e/suites/actions/create-library.test.ts index 1e4bc532ce..1706a996c5 100755 --- a/e2e/suites/actions/create-library.test.ts +++ b/e2e/suites/actions/create-library.test.ts @@ -106,7 +106,7 @@ describe('Create library', () => { await createDialog.waitForDialogToClose(); expect(await page.breadcrumb.getCurrentItemName()).toEqual(site1Name, `Not navigated into ${site1Name}`); - await page.clickFileLibrariesAndWait(); + await page.goToMyLibrariesAndWait(); expect(await dataTable.isItemPresent(site1Name)).toBe(true, `${site1Name} not in the list`); expect(await apis.user.sites.getVisibility(site1Name)).toEqual(SITE_VISIBILITY.PUBLIC); }); @@ -120,7 +120,7 @@ describe('Create library', () => { await createDialog.waitForDialogToClose(); expect(await page.breadcrumb.getCurrentItemName()).toEqual(site2Name, `Not navigated into ${site2Name}`); - await page.clickFileLibrariesAndWait(); + await page.goToMyLibrariesAndWait(); expect(await dataTable.isItemPresent(site2Name)).toBe(true, `${site2Name} not in the list`); expect(await apis.user.sites.getVisibility(site2Name)).toEqual(SITE_VISIBILITY.MODERATED); }); @@ -134,7 +134,7 @@ describe('Create library', () => { await createDialog.waitForDialogToClose(); expect(await page.breadcrumb.getCurrentItemName()).toEqual(site3Name, `Not navigated into ${site3Name}`); - await page.clickFileLibrariesAndWait(); + await page.goToMyLibrariesAndWait(); expect(await dataTable.isItemPresent(site3Name)).toBe(true, `${site3Name} not in the list`); expect(await apis.user.sites.getVisibility(site3Name)).toEqual(SITE_VISIBILITY.PRIVATE); }); @@ -150,7 +150,7 @@ describe('Create library', () => { await createDialog.waitForDialogToClose(); expect(await page.breadcrumb.getCurrentItemName()).toEqual(site4.name, `Not navigated into ${site4.name}`); - await page.clickFileLibrariesAndWait(); + await page.goToMyLibrariesAndWait(); expect(await dataTable.isItemPresent(site4.name)).toBe(true, `${site4.name} not in the list`); expect(await apis.user.sites.getVisibility(site4.id)).toEqual(SITE_VISIBILITY.PUBLIC); expect(await apis.user.sites.getDescription(site4.id)).toEqual(site4.description); @@ -209,7 +209,7 @@ describe('Create library', () => { await createDialog.waitForDialogToClose(); expect(await page.breadcrumb.getCurrentItemName()).toEqual(duplicateSite.name, `Not navigated into ${duplicateSite.name}`); - await page.clickFileLibrariesAndWait(); + await page.goToMyLibrariesAndWait(); expect(await dataTable.isItemPresent(`${duplicateSite.name} (${duplicateSite.id}-2)`)).toBe(true, `${duplicateSite.name} not in the list`); expect(await apis.user.sites.getTitle(`${duplicateSite.id}-2`)).toEqual(duplicateSite.name); }); diff --git a/e2e/suites/actions/edit-folder.test.ts b/e2e/suites/actions/edit-folder.test.ts index 887982eff9..86f9243570 100755 --- a/e2e/suites/actions/edit-folder.test.ts +++ b/e2e/suites/actions/edit-folder.test.ts @@ -244,7 +244,7 @@ describe('Edit folder', () => { describe('on My Libraries', () => { beforeEach(async (done) => { - await page.clickFileLibrariesAndWait(); + await page.goToMyLibrariesAndWait(); await dataTable.doubleClickOnRowByName(siteName); done(); }); diff --git a/e2e/suites/actions/library-actions.test.ts b/e2e/suites/actions/library-actions.test.ts index b892c0d6b9..e7a3d89d86 100755 --- a/e2e/suites/actions/library-actions.test.ts +++ b/e2e/suites/actions/library-actions.test.ts @@ -96,7 +96,7 @@ describe('Library actions', () => { }); it('Join a public library - Favorite Libraries - [C290105]', async () => { - await page.goToFavoriteLibraries(); + await page.goToFavoriteLibrariesAndWait(); await dataTable.selectItem(sitePublic1Admin); await toolbar.clickJoin(); @@ -104,7 +104,7 @@ describe('Library actions', () => { }); it('Join a moderated library - Favorite Libraries - [C290109]', async () => { - await page.goToFavoriteLibraries(); + await page.goToFavoriteLibrariesAndWait(); await dataTable.selectItem(siteModerated1Admin); await toolbar.clickJoin(); @@ -114,7 +114,7 @@ describe('Library actions', () => { }); it('Leave a library - My Libraries - [C290106]', async () => { - await page.goToMyLibraries(); + await page.goToMyLibrariesAndWait(); await dataTable.selectItem(sitePublic2Admin); await toolbar.clickLeave(); await page.waitForDialog(); @@ -125,7 +125,7 @@ describe('Library actions', () => { }); it('Leave a library - Favorite Libraries - [C290110]', async () => { - await page.goToFavoriteLibraries(); + await page.goToFavoriteLibrariesAndWait(); await dataTable.selectItem(sitePublic3Admin); await toolbar.clickLeave(); await page.waitForDialog(); @@ -136,7 +136,7 @@ describe('Library actions', () => { }); it('Confirmation dialog UI - [C290136]', async () => { - await page.goToMyLibraries(); + await page.goToMyLibrariesAndWait(); await dataTable.selectItem(sitePublic4Admin); await toolbar.clickLeave(); await page.waitForDialog(); @@ -149,7 +149,7 @@ describe('Library actions', () => { }); it('Cancel Leave library - [C290111]', async () => { - await page.goToMyLibraries(); + await page.goToMyLibrariesAndWait(); await dataTable.selectItem(sitePublic4Admin); await toolbar.clickLeave(); await page.waitForDialog(); @@ -160,7 +160,7 @@ describe('Library actions', () => { }); it('Leave a library - failure notification - [C290107]', async () => { - await page.goToMyLibraries(); + await page.goToMyLibrariesAndWait(); await dataTable.selectItem(sitePublicUser); await toolbar.clickLeave(); await page.waitForDialog(); @@ -170,7 +170,7 @@ describe('Library actions', () => { }); it('Cancel join - Favorite Libraries - [C290108]', async () => { - await page.goToFavoriteLibraries(); + await page.goToFavoriteLibrariesAndWait(); await dataTable.selectItem(siteModerated2Admin); await toolbar.clickButton('Cancel join request'); diff --git a/e2e/suites/actions/mark-favorite.test.ts b/e2e/suites/actions/mark-favorite.test.ts index 1268b87815..9019f240b5 100644 --- a/e2e/suites/actions/mark-favorite.test.ts +++ b/e2e/suites/actions/mark-favorite.test.ts @@ -369,7 +369,7 @@ describe('Mark items as favorites', () => { beforeEach(async (done) => { await Utils.pressEscape(); - await page.clickFileLibrariesAndWait(); + await page.goToMyLibrariesAndWait(); await page.dataTable.doubleClickOnRowByName(siteName); await page.dataTable.waitForHeader(); done(); @@ -457,7 +457,7 @@ describe('Mark items as favorites', () => { }); it('Mark a library as favorite - [C289974]', async () => { - await page.goToMyLibraries(); + await page.goToMyLibrariesAndWait(); await dataTable.selectItem(adminSite1); await toolbar.clickMoreActionsFavorite(); @@ -465,7 +465,7 @@ describe('Mark items as favorites', () => { }); it('Remove a library from favorites - on My Libraries - [C289975]', async () => { - await page.goToMyLibraries(); + await page.goToMyLibrariesAndWait(); await dataTable.selectItem(adminSite2); await toolbar.clickMoreActionsFavorite(); @@ -473,7 +473,7 @@ describe('Mark items as favorites', () => { }); it('Remove a library from favorites - on Favorite Libraries - [C289976]', async () => { - await page.goToFavoriteLibraries(); + await page.goToFavoriteLibrariesAndWait(); await dataTable.selectItem(adminSite3); await toolbar.clickMoreActionsFavorite(); diff --git a/e2e/suites/actions/new-menu.test.ts b/e2e/suites/actions/new-menu.test.ts index e9764eb35d..f66c985cb0 100755 --- a/e2e/suites/actions/new-menu.test.ts +++ b/e2e/suites/actions/new-menu.test.ts @@ -86,14 +86,14 @@ describe('New menu', () => { }); it('Create folder is enabled when having enough permissions - File Libraries - [C280393]', async () => { - await page.clickFileLibraries(); + await page.goToMyLibrariesAndWait(); await page.dataTable.doubleClickOnRowByName(siteUser); await page.sidenav.openNewMenu(); expect(await sidenav.menu.isCreateFolderEnabled()).toBe(true, 'Create folder is not enabled'); }); it('Create folder is disabled when not enough permissions - [C280397]', async () => { - await page.clickFileLibraries(); + await page.goToMyLibrariesAndWait(); await dataTable.doubleClickOnRowByName(siteAdmin); await sidenav.openNewMenu(); expect(await sidenav.menu.isCreateFolderEnabled()).toBe(false, 'Create folder is not disabled'); @@ -107,7 +107,7 @@ describe('New menu', () => { }); it('Upload File option is enabled when having permissions - on File Libraries - [C290142]', async () => { - await page.clickFileLibraries(); + await page.goToMyLibrariesAndWait(); await dataTable.doubleClickOnRowByName(siteUser); await sidenav.openNewMenu(); @@ -115,7 +115,7 @@ describe('New menu', () => { }); it('Upload File option is disabled when user cannot create content in that location - [C217146]', async () => { - await page.clickFileLibraries(); + await page.goToMyLibrariesAndWait(); await dataTable.doubleClickOnRowByName(siteAdmin); await sidenav.openNewMenu(); @@ -130,7 +130,7 @@ describe('New menu', () => { }); it('Upload Folder option is enabled when having permissions - on File Libraries - [C290146]', async () => { - await page.clickFileLibraries(); + await page.goToMyLibrariesAndWait(); await dataTable.doubleClickOnRowByName(siteUser); await sidenav.openNewMenu(); @@ -138,7 +138,7 @@ describe('New menu', () => { }); it('Upload Folder option is disabled when user cannot create content in that location - [C213193]', async () => { - await page.clickFileLibraries(); + await page.goToMyLibrariesAndWait(); await dataTable.doubleClickOnRowByName(siteAdmin); await sidenav.openNewMenu(); @@ -154,7 +154,7 @@ describe('New menu', () => { }); it('Create folder disabled button tooltip - [C280398]', async () => { - await page.clickFileLibraries(); + await page.goToMyLibrariesAndWait(); await dataTable.doubleClickOnRowByName(siteAdmin); await sidenav.openNewMenu(); diff --git a/e2e/suites/actions/share-file.test.ts b/e2e/suites/actions/share-file.test.ts index 1cec0703c4..df0444caf5 100755 --- a/e2e/suites/actions/share-file.test.ts +++ b/e2e/suites/actions/share-file.test.ts @@ -261,14 +261,14 @@ describe('Share a file', () => { describe('from File Libraries', () => { - const file1 = `file1-${Utils.random()}.txt`; let file1Id; - const file2 = `file2-${Utils.random()}.txt`; let file2Id; + const file1 = `file1-${Utils.random()}.txt`; + const file2 = `file2-${Utils.random()}.txt`; const file3 = `file3-${Utils.random()}.txt`; let file3Id; - const file4 = `file4-${Utils.random()}.txt`; let file4Id; + const file4 = `file4-${Utils.random()}.txt`; const file5 = `file5-${Utils.random()}.txt`; let file5Id; const file6 = `file6-${Utils.random()}.txt`; let file6Id; const file7 = `file7-${Utils.random()}.txt`; let file7Id; - const file8 = `file8-${Utils.random()}.txt`; let file8Id; + const file8 = `file8-${Utils.random()}.txt`; const file9 = `file9-${Utils.random()}.txt`; let file9Id; const siteName = `site-${Utils.random()}`; @@ -279,14 +279,14 @@ describe('Share a file', () => { const docLibId = await apis.user.sites.getDocLibId(siteName); parentInSiteId = (await apis.user.nodes.createFolder(parentInSite, docLibId)).entry.id; - file1Id = (await apis.user.nodes.createFile(file1, parentInSiteId)).entry.id; - file2Id = (await apis.user.nodes.createFile(file2, parentInSiteId)).entry.id; + await apis.user.nodes.createFile(file1, parentInSiteId); + await apis.user.nodes.createFile(file2, parentInSiteId); file3Id = (await apis.user.nodes.createFile(file3, parentInSiteId)).entry.id; - file4Id = (await apis.user.nodes.createFile(file4, parentInSiteId)).entry.id; + await apis.user.nodes.createFile(file4, parentInSiteId); file5Id = (await apis.user.nodes.createFile(file5, parentInSiteId)).entry.id; file6Id = (await apis.user.nodes.createFile(file6, parentInSiteId)).entry.id; file7Id = (await apis.user.nodes.createFile(file7, parentInSiteId)).entry.id; - file8Id = (await apis.user.nodes.createFile(file8, parentInSiteId)).entry.id; + await apis.user.nodes.createFile(file8, parentInSiteId); file9Id = (await apis.user.nodes.createFile(file9, parentInSiteId)).entry.id; await apis.user.shared.shareFileById(file6Id, expiryDate); await apis.user.shared.shareFileById(file7Id, expiryDate); @@ -295,7 +295,7 @@ describe('Share a file', () => { }); beforeEach(async (done) => { - await page.clickFileLibrariesAndWait(); + await page.goToMyLibrariesAndWait(); await dataTable.doubleClickOnRowByName(siteName); await dataTable.waitForHeader(); await dataTable.doubleClickOnRowByName(parentInSite); diff --git a/e2e/suites/actions/special-permissions-available-actions.test.ts b/e2e/suites/actions/special-permissions-available-actions.test.ts index 8955e6721b..50de63aae4 100755 --- a/e2e/suites/actions/special-permissions-available-actions.test.ts +++ b/e2e/suites/actions/special-permissions-available-actions.test.ts @@ -23,7 +23,7 @@ * along with Alfresco. If not, see . */ -import { LoginPage, BrowsingPage } from '../../pages/pages'; +import { LoginPage, BrowsingPage, SearchResultsPage } from '../../pages/pages'; import { SITE_VISIBILITY, SITE_ROLES, FILES } from '../../configs'; import { RepoClient } from '../../utilities/repo-client/repo-client'; import { Utils } from '../../utilities/utils'; @@ -34,16 +34,16 @@ describe('Granular permissions available actions : ', () => { const userManager = `manager-${Utils.random()}`; const siteName = `site-private-${Utils.random()}`; - const file1 = `file1-${Utils.random()}.txt`; + const file1 = `my-file1-${Utils.random()}.txt`; let file1Id; - const file2 = `file2-${Utils.random()}.txt`; + const file2 = `my-file2-${Utils.random()}.txt`; let file2Id; - const file3 = `file3-${Utils.random()}.txt`; + const file3 = `my-file3-${Utils.random()}.txt`; let file3Id; - const folder1 = `folder1-${Utils.random()}`; + const folder1 = `my-folder1-${Utils.random()}`; let folder1Id; - const folder2 = `folder2-${Utils.random()}`; + const folder2 = `my-folder2-${Utils.random()}`; let folder2Id; const docxFile = FILES.docxFile; @@ -61,8 +61,10 @@ describe('Granular permissions available actions : ', () => { const contextMenu = dataTable.menu; const viewer = new Viewer(); const viewerToolbar = viewer.toolbar; + const searchResultsPage = new SearchResultsPage(); + const { searchInput } = searchResultsPage.header; - beforeAll(async done => { + beforeAll(async (done) => { await apis.admin.people.createUser({ username: userConsumer }); await apis.admin.people.createUser({ username: userManager }); @@ -96,7 +98,7 @@ describe('Granular permissions available actions : ', () => { done(); }); - afterAll(async done => { + afterAll(async (done) => { await apis.admin.sites.deleteSite(siteName); done(); }); @@ -104,8 +106,10 @@ describe('Granular permissions available actions : ', () => { xit(''); describe('toolbar displays correct actions when selecting multiple files with different granular permissions', () => { - beforeEach(async done => { + beforeEach(async (done) => { await Utils.pressEscape(); + await dataTable.clearSelection(); + await page.clickPersonalFiles(); done(); }); @@ -114,6 +118,7 @@ describe('Granular permissions available actions : ', () => { await dataTable.doubleClickOnRowByName(siteName); await dataTable.waitForHeader(); await dataTable.selectMultipleItems([file1, file2]); + expect(await toolbar.isViewPresent()).toBe(false, `View is displayed for selected files`); expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for selected files`); expect(await toolbar.isEditPresent()).toBe(false, `Edit is displayed for selected files`); @@ -128,6 +133,7 @@ describe('Granular permissions available actions : ', () => { it('on Shared Files - [C280477]', async () => { await page.clickSharedFilesAndWait(); await dataTable.selectMultipleItems([file1, file2]); + expect(await toolbar.isViewPresent()).toBe(false, `View is displayed for selected files`); expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for selected files`); expect(await toolbar.isEditPresent()).toBe(false, `Edit is displayed for selected files`); @@ -142,6 +148,7 @@ describe('Granular permissions available actions : ', () => { it('on Favorites - [C280478]', async () => { await page.clickFavoritesAndWait(); await dataTable.selectMultipleItems([file1, file2]); + expect(await toolbar.isViewPresent()).toBe(false, `View is displayed for selected files`); expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for selected files`); expect(await toolbar.isEditPresent()).toBe(false, `Edit is displayed for selected files`); @@ -153,11 +160,30 @@ describe('Granular permissions available actions : ', () => { expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); await toolbar.closeMoreMenu(); }); + + it('on Search Results - [C291823]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFiles(); + await searchInput.searchForTextAndCloseSearchOptions('my-file'); + await dataTable.selectMultipleItems([file1, file2]); + + expect(await toolbar.isViewPresent()).toBe(false, `View is displayed for selected files`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for selected files`); + expect(await toolbar.isEditPresent()).toBe(false, `Edit is displayed for selected files`); + await toolbar.openMoreMenu(); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); + expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for selected files`); + expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for selected files`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); + await toolbar.closeMoreMenu(); + }); }); describe('toolbar actions appear correctly for a file - consumer', () => { - beforeEach(async done => { + beforeEach(async (done) => { await Utils.pressEscape(); + await dataTable.clearSelection(); + await page.clickPersonalFiles(); done(); }); @@ -210,11 +236,32 @@ describe('Granular permissions available actions : ', () => { expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${file1}`); await toolbar.closeMoreMenu(); }); + + it('on Search Results - [C291818]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFiles(); + await searchInput.searchForTextAndCloseSearchOptions(file1); + await dataTable.selectItem(file1); + + expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${file1}`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${file1}`); + expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${file1}`); + expect(await toolbar.isEditPresent()).toBe(false, `Edit is displayed for ${file1}`); + + await toolbar.openMoreMenu(); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${file1}`); + expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${file1}`); + expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${file1}`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${file1}`); + await toolbar.closeMoreMenu(); + }); }); describe('toolbar actions appear correctly for a folder - consumer', () => { - beforeEach(async done => { + beforeEach(async (done) => { await Utils.pressEscape(); + await dataTable.clearSelection(); + await page.clickPersonalFiles(); done(); }); @@ -252,12 +299,32 @@ describe('Granular permissions available actions : ', () => { expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${folder1}`); await toolbar.closeMoreMenu(); }); + + it('on Search Results - [C291819]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFolders(); + await searchInput.searchForTextAndCloseSearchOptions(folder1); + await dataTable.selectItem(folder1); + + expect(await toolbar.isViewPresent()).toBe(false, `View is displayed for ${folder1}`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${folder1}`); + expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${folder1}`); + expect(await toolbar.isEditPresent()).toBe(false, `Edit is displayed for ${folder1}`); + + await toolbar.openMoreMenu(); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${folder1}`); + expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${folder1}`); + expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${folder1}`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${folder1}`); + await toolbar.closeMoreMenu(); + }); }); describe('toolbar actions appear correctly for multiple selection of files - consumer', () => { beforeEach(async (done) => { await Utils.pressEscape(); await dataTable.clearSelection(); + await page.clickPersonalFiles(); done(); }); @@ -305,12 +372,30 @@ describe('Granular permissions available actions : ', () => { expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); await toolbar.closeMoreMenu(); }); + + it('on Search Results - [C291824]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFiles(); + await searchInput.searchForTextAndCloseSearchOptions('my-file'); + await dataTable.selectMultipleItems([file1, file2]); + + expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); + expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); + expect(await toolbar.isEditPresent()).toBe(false, 'Edit is displayed'); + await toolbar.openMoreMenu(); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); + expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + await toolbar.closeMoreMenu(); + }); }); describe('toolbar actions appear correctly for multiple selection of folders - consumer', () => { beforeEach(async (done) => { await Utils.pressEscape(); await dataTable.clearSelection(); + await page.clickPersonalFiles(); done(); }); @@ -344,12 +429,30 @@ describe('Granular permissions available actions : ', () => { expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); await toolbar.closeMoreMenu(); }); + + it('on Search Results - [C291825]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFolders(); + await searchInput.searchForTextAndCloseSearchOptions('my-folder'); + await dataTable.selectMultipleItems([folder1, folder2]); + + expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); + expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); + expect(await toolbar.isEditPresent()).toBe(false, 'Edit is displayed'); + await toolbar.openMoreMenu(); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); + expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + await toolbar.closeMoreMenu(); + }); }); describe('toolbar actions appear correctly for when both files and folders are selected - consumer', () => { - beforeEach(async done => { + beforeEach(async (done) => { await Utils.pressEscape(); await dataTable.clearSelection(); + await page.clickPersonalFiles(); done(); }); @@ -383,11 +486,30 @@ describe('Granular permissions available actions : ', () => { expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); await toolbar.closeMoreMenu(); }); + + it('on Search Results - [C291826]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkFilesAndFolders(); + await searchInput.searchForTextAndCloseSearchOptions('my-f'); + await dataTable.selectMultipleItems([file1, folder1]); + + expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); + expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); + expect(await toolbar.isEditPresent()).toBe(false, 'Edit is displayed'); + await toolbar.openMoreMenu(); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); + expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + await toolbar.closeMoreMenu(); + }); }); describe('context menu actions are correct for a file - consumer', () => { beforeEach(async (done) => { await Utils.pressEscape(); + await dataTable.clearSelection(); + await page.clickPersonalFiles(); done(); }); @@ -443,11 +565,31 @@ describe('Granular permissions available actions : ', () => { expect(await contextMenu.isEditPresent()).toBe(false, `Edit is displayed for ${file1}`); expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${file1}`); }); + + it('on Search Results - [C291829]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFiles(); + await searchInput.searchForTextAndCloseSearchOptions(file1); + await dataTable.rightClickOnItem(file1); + expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${file1}`); + expect(await contextMenu.isViewPresent()).toBe(true, `View is not displayed for ${file1}`); + expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${file1}`); + expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${file1}`); + expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed for ${file1}`); + expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed for ${file1}`); + expect(await contextMenu.isSharePresent()).toBe(true, `Share is not displayed for ${file1}`); + expect(await contextMenu.isManageVersionsPresent()).toBe(true, `Manage Versions not displayed for ${file1}`); + expect(await contextMenu.isManagePermissionsPresent()).toBe(false, `Permissions is displayed for ${file1}`); + expect(await contextMenu.isEditPresent()).toBe(false, `Edit is displayed for ${file1}`); + expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${file1}`); + }); }); describe('context menu actions are correct for a folder - consumer', () => { beforeEach(async (done) => { await Utils.pressEscape(); + await dataTable.clearSelection(); + await page.clickPersonalFiles(); done(); }); @@ -485,12 +627,30 @@ describe('Granular permissions available actions : ', () => { expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions is displayed for ${folder1}`); expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed for ${folder1}`); }); + + it('on Search Results - [C291830]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFolders(); + await searchInput.searchForTextAndCloseSearchOptions(folder1); + await dataTable.rightClickOnItem(folder1); + expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${folder1}`); + expect(await contextMenu.isEditPresent()).toBe(false, `Edit is displayed for ${folder1}`); + expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${folder1}`); + expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${folder1}`); + expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed for ${folder1}`); + expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed for ${folder1}`); + expect(await contextMenu.isManagePermissionsPresent()).toBe(false, `Permissions is displayed for ${folder1}`); + expect(await contextMenu.isViewPresent()).toBe(false, `View is displayed for ${folder1}`); + expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions displayed for ${folder1}`); + expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed for ${folder1}`); + }); }); describe('context menu actions are correct for multiple selection of files - consumer', () => { beforeEach(async (done) => { await Utils.pressEscape(); await dataTable.clearSelection(); + await page.clickPersonalFiles(); done(); }); @@ -535,12 +695,29 @@ describe('Granular permissions available actions : ', () => { expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); expect(await contextMenu.isManagePermissionsPresent()).toBe(false, `Permissions is displayed`); }); + + it('on Search Results - [C291834]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFiles(); + await searchInput.searchForTextAndCloseSearchOptions('my-file'); + await dataTable.selectMultipleItems([file1, file2]); + await dataTable.rightClickOnMultipleSelection(); + + expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); + expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); + expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); + expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); + expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await contextMenu.isManagePermissionsPresent()).toBe(false, `Permissions is displayed`); + }); }); describe('context menu actions are correct for multiple selection of folders - consumer', () => { beforeEach(async (done) => { await Utils.pressEscape(); await dataTable.clearSelection(); + await page.clickPersonalFiles(); done(); }); @@ -572,12 +749,29 @@ describe('Granular permissions available actions : ', () => { expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); expect(await contextMenu.isManagePermissionsPresent()).toBe(false, `Permissions is displayed`); }); + + it('on Search Results - [C291835]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFolders(); + await searchInput.searchForTextAndCloseSearchOptions('my-folder'); + await dataTable.selectMultipleItems([folder1, folder2]); + await dataTable.rightClickOnMultipleSelection(); + + expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); + expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); + expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); + expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); + expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await contextMenu.isManagePermissionsPresent()).toBe(false, `Permissions is displayed`); + }); }); describe('context menu actions are correct when both files and folders are selected - consumer', () => { beforeEach(async (done) => { await Utils.pressEscape(); await dataTable.clearSelection(); + await page.clickPersonalFiles(); done(); }); @@ -609,11 +803,29 @@ describe('Granular permissions available actions : ', () => { expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); expect(await contextMenu.isManagePermissionsPresent()).toBe(false, `Permissions is displayed`); }); + + it('on Search Results - [C291836]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkFilesAndFolders(); + await searchInput.searchForTextAndCloseSearchOptions('my-f'); + await dataTable.selectMultipleItems([file1, folder1]); + await dataTable.rightClickOnMultipleSelection(); + + expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); + expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); + expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); + expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); + expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await contextMenu.isManagePermissionsPresent()).toBe(false, `Permissions is displayed`); + }); }); describe('toolbar actions appear correctly in the viewer - consumer', () => { beforeEach(async (done) => { await Utils.pressEscape(); + await dataTable.clearSelection(); + await page.clickPersonalFiles(); done(); }); diff --git a/e2e/suites/actions/toolbar-multiple-selection.test.ts b/e2e/suites/actions/toolbar-multiple-selection.test.ts index 0d484be508..83142553a4 100755 --- a/e2e/suites/actions/toolbar-multiple-selection.test.ts +++ b/e2e/suites/actions/toolbar-multiple-selection.test.ts @@ -24,7 +24,7 @@ */ import { browser, protractor } from 'protractor'; -import { LoginPage, BrowsingPage } from '../../pages/pages'; +import { LoginPage, BrowsingPage, SearchResultsPage } from '../../pages/pages'; import { SITE_VISIBILITY } from '../../configs'; import { RepoClient } from '../../utilities/repo-client/repo-client'; import { Utils } from '../../utilities/utils'; @@ -32,14 +32,14 @@ import { Utils } from '../../utilities/utils'; describe('Toolbar actions - multiple selection : ', () => { const username = `user-${Utils.random()}`; - const file1 = `file1-${Utils.random()}.txt`; + const file1 = `my-file1-${Utils.random()}.txt`; let file1Id; - const file2 = `file2-${Utils.random()}.txt`; + const file2 = `my-file2-${Utils.random()}.txt`; let file2Id; - const folder1 = `folder1-${Utils.random()}`; + const folder1 = `my-folder1-${Utils.random()}`; let folder1Id; - const folder2 = `folder2-${Utils.random()}`; + const folder2 = `my-folder2-${Utils.random()}`; let folder2Id; const fileForDelete1 = `file-${Utils.random()}.txt`; @@ -52,10 +52,10 @@ describe('Toolbar actions - multiple selection : ', () => { let folderForDelete2Id; const siteName = `site-${Utils.random()}`; - const file1InSite = `file1-${Utils.random()}.txt`; - const file2InSite = `file2-${Utils.random()}.txt`; - const folder1InSite = `folder1-${Utils.random()}`; - const folder2InSite = `folder2-${Utils.random()}`; + const file1InSite = `my-fileInSite1-${Utils.random()}.txt`; + const file2InSite = `my-fileInSite2-${Utils.random()}.txt`; + const folder1InSite = `my-folderInSite1-${Utils.random()}`; + const folder2InSite = `my-folderInSite2-${Utils.random()}`; const apis = { admin: new RepoClient(), @@ -65,8 +65,10 @@ describe('Toolbar actions - multiple selection : ', () => { const loginPage = new LoginPage(); const page = new BrowsingPage(); const { dataTable, toolbar } = page; + const searchResultsPage = new SearchResultsPage(); + const { searchInput } = searchResultsPage.header; - beforeAll(async done => { + beforeAll(async (done) => { await apis.admin.people.createUser({ username }); file1Id = (await apis.user.nodes.createFiles([file1])).entry.id; @@ -100,7 +102,7 @@ describe('Toolbar actions - multiple selection : ', () => { done(); }); - afterAll(async done => { + afterAll(async (done) => { await Promise.all([ apis.user.nodes.deleteNodesById([file1Id, file2Id, folder1Id, folder2Id]), apis.user.trashcan.emptyTrash(), @@ -111,11 +113,11 @@ describe('Toolbar actions - multiple selection : ', () => { xit(''); - describe('Personal Files', () => { - beforeEach(async done => { + describe('on Personal Files', () => { + beforeEach(async (done) => { await Utils.pressEscape(); - await page.clickPersonalFilesAndWait(); await dataTable.clearSelection(); + await page.clickPersonalFilesAndWait(); done(); }); @@ -182,13 +184,12 @@ describe('Toolbar actions - multiple selection : ', () => { }); }); - describe('File Libraries', () => { - beforeEach(async done => { + describe('on File Libraries', () => { + beforeEach(async (done) => { await Utils.pressEscape(); - await page.clickFileLibrariesAndWait(); + await page.goToMyLibrariesAndWait(); await dataTable.doubleClickOnRowByName(siteName); await dataTable.waitForHeader(); - await dataTable.clearSelection(); done(); }); @@ -202,6 +203,7 @@ describe('Toolbar actions - multiple selection : ', () => { expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for selected files`); expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for selected files`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); + await toolbar.closeMoreMenu(); }); it('correct actions appear when multiple folders are selected - [C280462]', async () => { @@ -214,6 +216,7 @@ describe('Toolbar actions - multiple selection : ', () => { expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for selected files`); expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for selected files`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); + await toolbar.closeMoreMenu(); }); it('correct actions appear when both files and folders are selected - [C280463]', async () => { @@ -226,15 +229,15 @@ describe('Toolbar actions - multiple selection : ', () => { expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for selected files`); expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for selected files`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); + await toolbar.closeMoreMenu(); }); }); - describe('Shared Files', () => { - beforeEach(async done => { - // await browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform(); + describe('on Shared Files', () => { + beforeEach(async (done) => { await Utils.pressEscape(); - await page.clickSharedFilesAndWait(); await dataTable.clearSelection(); + await page.clickSharedFilesAndWait(); done(); }); @@ -248,14 +251,15 @@ describe('Toolbar actions - multiple selection : ', () => { expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for selected files`); expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for selected files`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); + await toolbar.closeMoreMenu(); }); }); - describe('Recent Files', () => { - beforeEach(async done => { + describe('on Recent Files', () => { + beforeEach(async (done) => { await Utils.pressEscape(); - await page.clickRecentFilesAndWait(); await dataTable.clearSelection(); + await page.clickRecentFilesAndWait(); done(); }); @@ -269,15 +273,15 @@ describe('Toolbar actions - multiple selection : ', () => { expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for selected files`); expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for selected files`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); + await toolbar.closeMoreMenu(); }); }); - describe('Favorites', () => { - beforeEach(async done => { - // await browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform(); + describe('on Favorites', () => { + beforeEach(async (done) => { await Utils.pressEscape(); - await page.clickFavoritesAndWait(); await dataTable.clearSelection(); + await page.clickFavoritesAndWait(); done(); }); @@ -291,6 +295,7 @@ describe('Toolbar actions - multiple selection : ', () => { expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for selected files`); expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for selected files`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); + await toolbar.closeMoreMenu(); }); it('correct actions appear when multiple folders are selected - [C280470]', async () => { @@ -303,6 +308,7 @@ describe('Toolbar actions - multiple selection : ', () => { expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for selected files`); expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for selected files`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); + await toolbar.closeMoreMenu(); }); it('correct actions appear when both files and folders are selected - [C280471]', async () => { @@ -315,14 +321,13 @@ describe('Toolbar actions - multiple selection : ', () => { expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for selected files`); expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for selected files`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); + await toolbar.closeMoreMenu(); }); }); - describe('Trash', () => { - beforeEach(async done => { - await Utils.pressEscape(); + describe('on Trash', () => { + beforeEach(async (done) => { await page.clickTrashAndWait(); - await dataTable.clearSelection(); done(); }); @@ -344,4 +349,63 @@ describe('Toolbar actions - multiple selection : ', () => { expect(await toolbar.isButtonPresent('Restore')).toBe(true, 'Restore is not displayed'); }); }); + + describe('on Search Results', () => { + beforeEach(async (done) => { + await Utils.pressEscape(); + await page.clickPersonalFilesAndWait(); + done(); + }); + + it('correct actions appear when multiple files are selected - [C291820]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFiles(); + await searchInput.searchForTextAndCloseSearchOptions('my-fileInSite'); + await dataTable.selectMultipleItems([file1InSite, file2InSite]); + + expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed for selected files'); + expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed for selected files'); + expect(await toolbar.isEditPresent()).toBe(false, 'Edit is displayed for selected files'); + await toolbar.openMoreMenu(); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); + expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for selected files`); + expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for selected files`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); + await toolbar.closeMoreMenu(); + }); + + it('correct actions appear when multiple folders are selected - [C291821]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFolders(); + await searchInput.searchForTextAndCloseSearchOptions('my-folderInSite'); + await dataTable.selectMultipleItems([folder1InSite, folder2InSite]); + + expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); + expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); + expect(await toolbar.isEditPresent()).toBe(false, 'Edit is displayed'); + await toolbar.openMoreMenu(); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); + expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for selected files`); + expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for selected files`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); + await toolbar.closeMoreMenu(); + }); + + it('correct actions appear when both files and folders are selected - [C291822]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkFilesAndFolders(); + await searchInput.searchForTextAndCloseSearchOptions('my-f'); + await dataTable.selectMultipleItems([file1InSite, file2InSite, folder1InSite, folder2InSite]); + + expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); + expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); + expect(await toolbar.isEditPresent()).toBe(false, 'Edit is displayed'); + await toolbar.openMoreMenu(); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); + expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for selected files`); + expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for selected files`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); + await toolbar.closeMoreMenu(); + }); + }); }); diff --git a/e2e/suites/actions/toolbar-single-selection.test.ts b/e2e/suites/actions/toolbar-single-selection.test.ts index 6cd5704b6b..378da05101 100755 --- a/e2e/suites/actions/toolbar-single-selection.test.ts +++ b/e2e/suites/actions/toolbar-single-selection.test.ts @@ -23,7 +23,7 @@ * along with Alfresco. If not, see . */ -import { LoginPage, BrowsingPage } from '../../pages/pages'; +import { LoginPage, BrowsingPage, SearchResultsPage } from '../../pages/pages'; import { SITE_VISIBILITY } from '../../configs'; import { RepoClient } from '../../utilities/repo-client/repo-client'; import { Utils } from '../../utilities/utils'; @@ -37,8 +37,8 @@ describe('Toolbar actions - single selection : ', () => { const folderForDelete = `folderForDelete-${Utils.random()}`; let folderForDeleteId; const siteName = `site-${Utils.random()}`; - const fileInSite = `fileAdmin-${Utils.random()}.txt`; - const folderInSite = `folderAdmin-${Utils.random()}`; + const fileInSite = `file-site-${Utils.random()}.txt`; + const folderInSite = `folder-site-${Utils.random()}`; const adminPublic = `admin-public-${Utils.random()}`; const adminModerated = `admin-moderated-${Utils.random()}`; @@ -51,6 +51,8 @@ describe('Toolbar actions - single selection : ', () => { const loginPage = new LoginPage(); const page = new BrowsingPage(); const { dataTable, toolbar } = page; + const searchResultsPage = new SearchResultsPage(); + const { searchInput } = searchResultsPage.header; beforeAll(async (done) => { await apis.admin.people.createUser({ username }); @@ -81,6 +83,8 @@ describe('Toolbar actions - single selection : ', () => { await apis.user.favorites.addFavoriteById('site', adminModerated); await apis.user.sites.requestToJoin(adminModerated); + await apis.user.queries.waitForSites(siteName, { expect: 1 }); + await loginPage.loginWith(username); done(); }); @@ -99,27 +103,18 @@ describe('Toolbar actions - single selection : ', () => { xit(''); - describe('General tests', () => { + describe('on Personal Files', () => { beforeEach(async (done) => { await Utils.pressEscape(); await dataTable.clearSelection(); + await page.clickPersonalFilesAndWait(); done(); }); it('selected row is marked with a check circle icon - [C213134]', async () => { - await page.clickPersonalFilesAndWait(); await dataTable.selectItem(fileUser); expect(await dataTable.hasCheckMarkIcon(fileUser)).toBe(true, 'check mark missing'); }); - }); - - describe('on Personal Files', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await page.clickPersonalFilesAndWait(); - await dataTable.clearSelection(); - done(); - }); it('actions are not displayed when no item is selected - [C213120]', async () => { expect(await toolbar.isEmpty()).toBe(true, `actions displayed though nothing selected`); @@ -157,10 +152,9 @@ describe('Toolbar actions - single selection : ', () => { describe('on File Libraries', () => { beforeEach(async (done) => { await Utils.pressEscape(); - await page.clickFileLibrariesAndWait(); + await page.goToMyLibrariesAndWait(); await dataTable.doubleClickOnRowByName(siteName); await dataTable.waitForHeader(); - await dataTable.clearSelection(); done(); }); @@ -200,12 +194,16 @@ describe('Toolbar actions - single selection : ', () => { describe('on a library', () => { beforeEach(async (done) => { await Utils.pressEscape(); - await dataTable.clearSelection(); done(); }); - it('Available actions when a library is selected - My Libraries - [C213135]', async () => { - await page.goToMyLibraries(); + afterAll(async (done) => { + await page.clickPersonalFiles(); + done(); + }); + + it('Available actions for a library - My Libraries - [C213135]', async () => { + await page.goToMyLibrariesAndWait(); await dataTable.selectItem(siteName); expect(await toolbar.isEmpty()).toBe(false, 'toolbar not displayed'); expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${siteName}`); @@ -213,39 +211,88 @@ describe('Toolbar actions - single selection : ', () => { await toolbar.openMoreMenu(); expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${siteName}`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${siteName}`); + await toolbar.closeMoreMenu(); + }); + + it('Available actions for a library - Favorite Libraries - user is a member - [C289892]', async () => { + await page.goToFavoriteLibrariesAndWait(); + await dataTable.selectItem(siteName); + expect(await toolbar.isEmpty()).toBe(false, 'toolbar not displayed'); + expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${siteName}`); + expect(await toolbar.isButtonPresent('Leave library')).toBe(true, `Leave is not displayed for ${siteName}`); + await toolbar.openMoreMenu(); + expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${siteName}`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${siteName}`); + await toolbar.closeMoreMenu(); + }); + + it('Available actions for a library - Favorite Libraries - user is not a member - [C290090]', async () => { + await page.goToFavoriteLibrariesAndWait(); + await dataTable.selectItem(adminPublic); + expect(await toolbar.isEmpty()).toBe(false, 'toolbar not displayed'); + expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${adminPublic}`); + expect(await toolbar.isButtonPresent('Join')).toBe(true, `Join is not displayed for ${adminPublic}`); + await toolbar.openMoreMenu(); + expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${adminPublic}`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${adminPublic}`); + await toolbar.closeMoreMenu(); + }); + + it('Available actions for a moderated library - Favorite Libraries - user requested to join - [C290091]', async () => { + await page.goToFavoriteLibrariesAndWait(); + await dataTable.selectItem(adminModerated); + expect(await toolbar.isEmpty()).toBe(false, 'toolbar not displayed'); + expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${adminModerated}`); + expect(await toolbar.isButtonPresent('Cancel join request')).toBe(true, `Cancel join is not displayed for ${adminModerated}`); + await toolbar.openMoreMenu(); + expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${adminModerated}`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${adminModerated}`); + await toolbar.closeMoreMenu(); }); - it('Available actions when a library is selected - Favorite Libraries - user is a member - [C289892]', async () => { - await page.goToFavoriteLibraries(); + it('Available actions for a library - Search Results - [C290084]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkLibraries(); + await searchInput.searchForTextAndCloseSearchOptions(siteName); await dataTable.selectItem(siteName); + expect(await toolbar.isEmpty()).toBe(false, 'toolbar not displayed'); expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${siteName}`); expect(await toolbar.isButtonPresent('Leave library')).toBe(true, `Leave is not displayed for ${siteName}`); await toolbar.openMoreMenu(); expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${siteName}`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${siteName}`); + await toolbar.closeMoreMenu(); }); - it('Available actions when a library is selected - Favorite Libraries - user is not a member - [C290090]', async () => { - await page.goToFavoriteLibraries(); + it('Available actions for a library - Search Results - user is not a member - [C290085]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkLibraries(); + await searchInput.searchForTextAndCloseSearchOptions(adminPublic); await dataTable.selectItem(adminPublic); + expect(await toolbar.isEmpty()).toBe(false, 'toolbar not displayed'); expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${adminPublic}`); expect(await toolbar.isButtonPresent('Join')).toBe(true, `Join is not displayed for ${adminPublic}`); await toolbar.openMoreMenu(); expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${adminPublic}`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${adminPublic}`); + await toolbar.closeMoreMenu(); }); - it('Available actions when a library is selected - Favorite Libraries - user requested to join - [C290091]', async () => { - await page.goToFavoriteLibraries(); + it('Available actions for a moderated library - Search Results - user requested to join - [C290086]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkLibraries(); + await searchInput.searchForTextAndCloseSearchOptions(adminModerated); await dataTable.selectItem(adminModerated); + expect(await toolbar.isEmpty()).toBe(false, 'toolbar not displayed'); expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${adminModerated}`); expect(await toolbar.isButtonPresent('Cancel join request')).toBe(true, `Cancel join is not displayed for ${adminModerated}`); await toolbar.openMoreMenu(); expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${adminModerated}`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${adminModerated}`); + await toolbar.closeMoreMenu(); }); }); @@ -253,7 +300,6 @@ describe('Toolbar actions - single selection : ', () => { beforeEach(async (done) => { await Utils.pressEscape(); await page.clickSharedFilesAndWait(); - await dataTable.clearSelection(); done(); }); @@ -281,7 +327,6 @@ describe('Toolbar actions - single selection : ', () => { beforeEach(async (done) => { await Utils.pressEscape(); await page.clickRecentFilesAndWait(); - await dataTable.clearSelection(); done(); }); @@ -308,7 +353,6 @@ describe('Toolbar actions - single selection : ', () => { beforeEach(async (done) => { await Utils.pressEscape(); await page.clickFavoritesAndWait(); - await dataTable.clearSelection(); done(); }); @@ -349,7 +393,6 @@ describe('Toolbar actions - single selection : ', () => { beforeEach(async (done) => { await Utils.pressEscape(); await page.clickTrashAndWait(); - await dataTable.clearSelection(); done(); }); @@ -371,4 +414,56 @@ describe('Toolbar actions - single selection : ', () => { expect(await toolbar.isButtonPresent('Restore')).toBe(true, `Restore is not enabled for folder`); }); }); + + describe('on Search Results', () => { + beforeEach(async (done) => { + await Utils.pressEscape(); + await page.clickPersonalFilesAndWait(); + done(); + }); + + it('actions are not displayed when no item is selected - [C291815]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkFilesAndFolders(); + await searchInput.searchForTextAndCloseSearchOptions(fileInSite); + + expect(await toolbar.isEmpty()).toBe(true, `actions displayed though nothing selected`); + }); + + it('correct actions appear when a file is selected - [C291816]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFiles(); + await searchInput.searchForTextAndCloseSearchOptions(fileUser); + await dataTable.selectItem(fileUser); + + expect(await toolbar.isEmpty()).toBe(false, `actions not displayed for ${fileUser}`); + expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileUser}`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileUser}`); + expect(await toolbar.isEditPresent()).toBe(false, `Edit is displayed for ${fileUser}`); + await toolbar.openMoreMenu(); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileUser}`); + expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${fileUser}`); + expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${fileUser}`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${fileUser}`); + await toolbar.closeMoreMenu(); + }); + + it('correct actions appear when a folder is selected - [C291817]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFolders(); + await searchInput.searchForTextAndCloseSearchOptions(folderUser); + await dataTable.selectItem(folderUser); + + expect(await toolbar.isEmpty()).toBe(false, `actions not displayed for ${folderUser}`); + expect(await toolbar.isViewPresent()).toBe(false, `View is displayed for ${folderUser}`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not enabled for ${folderUser}`); + expect(await toolbar.isEditPresent()).toBe(true, `Edit is not displayed for ${folderUser}`); + await toolbar.openMoreMenu(); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${folderUser}`); + expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${folderUser}`); + expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${folderUser}`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${folderUser}`); + await toolbar.closeMoreMenu(); + }); + }); }); diff --git a/e2e/suites/actions/unshare-file.test.ts b/e2e/suites/actions/unshare-file.test.ts index 23b342c4b2..84c0c57799 100755 --- a/e2e/suites/actions/unshare-file.test.ts +++ b/e2e/suites/actions/unshare-file.test.ts @@ -214,7 +214,7 @@ describe('Unshare a file', () => { beforeEach(async (done) => { await page.refresh(); - await page.clickFileLibrariesAndWait(); + await page.goToMyLibrariesAndWait(); await dataTable.doubleClickOnRowByName(siteName); await dataTable.waitForHeader(); await dataTable.doubleClickOnRowByName(parentInSite); @@ -733,7 +733,7 @@ describe('Unshare a file', () => { }); it('on File Libraries - file shared by other user - [C286682]', async () => { - await page.clickFileLibrariesAndWait(); + await page.goToMyLibrariesAndWait(); await dataTable.doubleClickOnRowByName(sitePrivate); await dataTable.waitForHeader(); await dataTable.selectItem(file1); @@ -744,7 +744,7 @@ describe('Unshare a file', () => { }); it('on File Libraries - file shared by the user - [C286701]', async () => { - await page.clickFileLibrariesAndWait(); + await page.goToMyLibrariesAndWait(); await dataTable.doubleClickOnRowByName(sitePrivate); await dataTable.waitForHeader(); await dataTable.selectItem(file2); diff --git a/e2e/suites/application/page-titles.test.ts b/e2e/suites/application/page-titles.test.ts index cdb636c34a..16fadbe0d6 100755 --- a/e2e/suites/application/page-titles.test.ts +++ b/e2e/suites/application/page-titles.test.ts @@ -24,12 +24,11 @@ */ import { browser } from 'protractor'; -import { SIDEBAR_LABELS, PAGE_TITLES } from '../../configs'; +import { PAGE_TITLES } from '../../configs'; import { LoginPage, BrowsingPage } from '../../pages/pages'; import { RepoClient } from '../../utilities/repo-client/repo-client'; import { Utils } from '../../utilities/utils'; - describe('Page titles', () => { const loginPage = new LoginPage(); const page = new BrowsingPage(); @@ -73,10 +72,8 @@ describe('Page titles', () => { }); it('Personal Files page - [C217157]', async () => { - const label = SIDEBAR_LABELS.PERSONAL_FILES; - - await page.sidenav.navigateToLink(label); - expect(await browser.getTitle()).toContain(label); + await page.clickPersonalFiles(); + expect(await browser.getTitle()).toContain(PAGE_TITLES.PERSONAL_FILES); }); it('My Libraries page - [C217158]', async () => { @@ -90,31 +87,23 @@ describe('Page titles', () => { }); it('Shared Files page - [C217159]', async () => { - const label = SIDEBAR_LABELS.SHARED_FILES; - - await page.sidenav.navigateToLink(label); - expect(await browser.getTitle()).toContain(label); + await page.clickSharedFiles(); + expect(await browser.getTitle()).toContain(PAGE_TITLES.SHARED_FILES); }); it('Recent Files page - [C217160]', async () => { - const label = SIDEBAR_LABELS.RECENT_FILES; - - await page.sidenav.navigateToLink(label); - expect(await browser.getTitle()).toContain(label); + await page.clickRecentFiles(); + expect(await browser.getTitle()).toContain(PAGE_TITLES.RECENT_FILES); }); it('Favorites page - [C217161]', async () => { - const label = SIDEBAR_LABELS.FAVORITES; - - await page.sidenav.navigateToLink(label); - expect(await browser.getTitle()).toContain(label); + await page.clickFavorites(); + expect(await browser.getTitle()).toContain(PAGE_TITLES.FAVORITES); }); it('Trash page - [C217162]', async () => { - const label = SIDEBAR_LABELS.TRASH; - - await page.sidenav.navigateToLink(label); - expect(await browser.getTitle()).toContain(label); + await page.clickTrash(); + expect(await browser.getTitle()).toContain(PAGE_TITLES.TRASH); }); it('File Preview page - [C280415]', async () => { diff --git a/e2e/suites/info-drawer/library-properties.test.ts b/e2e/suites/info-drawer/library-properties.test.ts index 7e8dd04d70..34391b7095 100755 --- a/e2e/suites/info-drawer/library-properties.test.ts +++ b/e2e/suites/info-drawer/library-properties.test.ts @@ -187,7 +187,7 @@ describe('Library properties', () => { }); it('Warning appears when editing the name of the library by entering an existing name - [C289341]', async () => { - await apis.user.queries.waitForApi(site.name, { expect: 1 }); + await apis.user.queries.waitForSites(site.name, { expect: 1 }); await dataTable.selectItem(siteDup); await page.toolbar.clickViewDetails(); diff --git a/e2e/suites/list-views/file-libraries.test.ts b/e2e/suites/list-views/file-libraries.test.ts index c9d22662ab..aea6e6be40 100755 --- a/e2e/suites/list-views/file-libraries.test.ts +++ b/e2e/suites/list-views/file-libraries.test.ts @@ -100,7 +100,7 @@ describe('File Libraries', () => { describe('My Libraries', () => { beforeEach(async (done) => { - await page.goToMyLibraries(); + await page.goToMyLibrariesAndWait(); done(); }); @@ -171,7 +171,7 @@ describe('File Libraries', () => { describe('Favorite Libraries', () => { beforeEach(async (done) => { - await page.goToFavoriteLibraries(); + await page.goToFavoriteLibrariesAndWait(); done(); }); diff --git a/e2e/suites/navigation/breadcrumb.test.ts b/e2e/suites/navigation/breadcrumb.test.ts index 8f1c1626f6..c1d76b3cbc 100755 --- a/e2e/suites/navigation/breadcrumb.test.ts +++ b/e2e/suites/navigation/breadcrumb.test.ts @@ -90,13 +90,13 @@ describe('Breadcrumb', () => { }); it('My Libraries breadcrumb main node - [C260966]', async () => { - await page.goToMyLibraries(); + await page.goToMyLibrariesAndWait(); expect(await breadcrumb.getItemsCount()).toEqual(1, 'Breadcrumb has incorrect number of items'); expect(await breadcrumb.getCurrentItemName()).toBe('My Libraries'); }); it('Favorite Libraries breadcrumb main node - [C289891]', async () => { - await page.goToFavoriteLibraries(); + await page.goToFavoriteLibrariesAndWait(); expect(await breadcrumb.getItemsCount()).toEqual(1, 'Breadcrumb has incorrect number of items'); expect(await breadcrumb.getCurrentItemName()).toBe('Favorite Libraries'); }); @@ -186,7 +186,7 @@ describe('Breadcrumb', () => { }); describe('as admin', () => { - const user2 = 'a_user'; + const user2 = `user2-${Utils.random()}`; const userFolder = `userFolder-${Utils.random()}`; let userFolderId; const user2Api = new RepoClient(user2, user2); diff --git a/e2e/suites/navigation/sidebar.test.ts b/e2e/suites/navigation/sidebar.test.ts index ed61a3dffc..bbc585fa63 100755 --- a/e2e/suites/navigation/sidebar.test.ts +++ b/e2e/suites/navigation/sidebar.test.ts @@ -40,7 +40,7 @@ describe('Sidebar', () => { it('has "Personal Files" as default - [C217149]', async () => { expect(await browser.getCurrentUrl()).toContain(APP_ROUTES.PERSONAL_FILES); - expect(await sidenav.isActive(SIDEBAR_LABELS.PERSONAL_FILES)).toBe(true, 'Active link'); + expect(await sidenav.isActive(SIDEBAR_LABELS.PERSONAL_FILES)).toBe(true, 'Default active link'); }); it('File Libraries has correct sub-categories - [C217150]', async () => { diff --git a/e2e/suites/pagination/pag-file-libraries.test.ts b/e2e/suites/pagination/pag-file-libraries.test.ts index 132ba64463..64433da0a0 100755 --- a/e2e/suites/pagination/pag-file-libraries.test.ts +++ b/e2e/suites/pagination/pag-file-libraries.test.ts @@ -52,7 +52,7 @@ describe('Pagination on multiple pages on File Libraries', () => { }); beforeEach(async (done) => { - await page.clickFileLibrariesAndWait(); + await page.goToMyLibrariesAndWait(); done(); }); diff --git a/e2e/suites/search/search-input.test.ts b/e2e/suites/search/search-input.test.ts index 78cfb54605..f616d47b41 100644 --- a/e2e/suites/search/search-input.test.ts +++ b/e2e/suites/search/search-input.test.ts @@ -38,6 +38,7 @@ describe('Search input', () => { beforeEach(async (done) => { await Utils.pressEscape(); + await page.clickPersonalFiles(); done(); }); diff --git a/e2e/suites/search/search-results-libraries.test.ts b/e2e/suites/search/search-results-libraries.test.ts index a320259037..e44431d843 100644 --- a/e2e/suites/search/search-results-libraries.test.ts +++ b/e2e/suites/search/search-results-libraries.test.ts @@ -102,7 +102,7 @@ describe('Search results - libraries', () => { await apis.admin.sites.createSite(adminPrivate, SITE_VISIBILITY.PRIVATE); await apis.user.sites.waitForApi({ expect: 12 }); - await apis.user.queries.waitForApi('lib', { expect: 2 }); + await apis.user.queries.waitForSites('lib', { expect: 2 }); await loginPage.loginWith(username); done(); diff --git a/e2e/suites/search/search-results.test.ts b/e2e/suites/search/search-results.test.ts index c6024b6aea..ed400e844a 100644 --- a/e2e/suites/search/search-results.test.ts +++ b/e2e/suites/search/search-results.test.ts @@ -52,7 +52,7 @@ describe('Search results', () => { await apis.user.sites.createSite(site); await apis.user.search.waitForApi(username, { expect: 1 }); - await apis.user.queries.waitForApi(site, { expect: 1 }); + await apis.user.queries.waitForSites(site, { expect: 1 }); await loginPage.loginWith(username); done(); diff --git a/e2e/suites/viewer/viewer-actions.test.ts b/e2e/suites/viewer/viewer-actions.test.ts index 5f55ceeb3a..a60585dc31 100755 --- a/e2e/suites/viewer/viewer-actions.test.ts +++ b/e2e/suites/viewer/viewer-actions.test.ts @@ -251,7 +251,7 @@ describe('Viewer actions', () => { }); beforeEach(async (done) => { - await page.clickFileLibrariesAndWait(); + await page.goToMyLibrariesAndWait(); await dataTable.doubleClickOnRowByName(siteName); await dataTable.waitForHeader(); done(); diff --git a/e2e/suites/viewer/viewer-general.test.ts b/e2e/suites/viewer/viewer-general.test.ts index 2a5f72ba55..70a3144e00 100755 --- a/e2e/suites/viewer/viewer-general.test.ts +++ b/e2e/suites/viewer/viewer-general.test.ts @@ -23,7 +23,6 @@ * along with Alfresco. If not, see . */ -import { protractor, browser } from 'protractor'; import { LoginPage, BrowsingPage } from '../../pages/pages'; import { FILES, SITE_VISIBILITY } from '../../configs'; import { RepoClient } from '../../utilities/repo-client/repo-client'; @@ -83,7 +82,7 @@ describe('Viewer general', () => { }); afterEach(async (done) => { - await browser.actions().sendKeys(protractor.Key.ESCAPE).perform(); + await Utils.pressEscape(); done(); }); @@ -101,7 +100,7 @@ describe('Viewer general', () => { it('Viewer opens when clicking the View action for a file - [C279270]', async () => { await dataTable.selectItem(xlsxFile); - await page.toolbar.getButtonByTitleAttribute('View').click(); + await page.toolbar.clickView(); expect(await viewer.isViewerOpened()).toBe(true, 'Viewer is not opened'); }); @@ -139,7 +138,7 @@ describe('Viewer general', () => { }); it('Viewer opens for a file from File Libraries - [C284633]', async () => { - await page.clickFileLibrariesAndWait(); + await page.goToMyLibrariesAndWait(); await dataTable.doubleClickOnRowByName(siteUser); await dataTable.waitForHeader(); await dataTable.doubleClickOnRowByName(fileInSite); diff --git a/e2e/utilities/repo-client/apis/queries/queries-api.ts b/e2e/utilities/repo-client/apis/queries/queries-api.ts index 87aba7bc45..e2ce4ef675 100755 --- a/e2e/utilities/repo-client/apis/queries/queries-api.ts +++ b/e2e/utilities/repo-client/apis/queries/queries-api.ts @@ -42,7 +42,17 @@ export class QueriesApi extends RepoApi { return this.alfrescoJsApi.core.queriesApi.findSites(searchTerm, data); } - async waitForApi(searchTerm, data) { + async findNodes(searchTerm: string) { + const data = { + term: searchTerm, + fields: ['name'] + }; + + await this.apiAuth(); + return this.alfrescoJsApi.core.queriesApi.findNodes(searchTerm, data); + } + + async waitForSites(searchTerm, data) { try { const sites = async () => { const totalItems = (await this.findSites(searchTerm)).list.pagination.totalItems; @@ -58,4 +68,21 @@ export class QueriesApi extends RepoApi { console.log('-----> catch queries findSites: ', error); } } + + async waitForFilesAndFolders(searchTerm, data) { + try { + const nodes = async () => { + const totalItems = (await this.findNodes(searchTerm)).list.pagination.totalItems; + if ( totalItems !== data.expect ) { + return Promise.reject(totalItems); + } else { + return Promise.resolve(totalItems); + } + }; + + return await Utils.retryCall(nodes); + } catch (error) { + console.log('-----> catch queries findFilesAndFolders: ', error); + } + } } diff --git a/e2e/utilities/repo-client/apis/search/search-api.ts b/e2e/utilities/repo-client/apis/search/search-api.ts index c1f23f4bb7..135d2006b4 100755 --- a/e2e/utilities/repo-client/apis/search/search-api.ts +++ b/e2e/utilities/repo-client/apis/search/search-api.ts @@ -47,7 +47,36 @@ export class SearchApi extends RepoApi { await this.apiAuth(); return this.alfrescoJsApi.search.searchApi.search(data); + } + + async queryNodesNames(searchTerm: string) { + const data = { + query: { + query: `cm:name:\"${searchTerm}*\"`, + language: 'afts' + }, + filterQueries: [ + { query: `+TYPE:'cm:folder' OR +TYPE:'cm:content'`} + ] + }; + + await this.apiAuth(); + return this.alfrescoJsApi.search.searchApi.search(data); + } + async queryNodesExactNames(searchTerm: string) { + const data = { + query: { + query: `cm:name:\"${searchTerm}\"`, + language: 'afts' + }, + filterQueries: [ + { query: `+TYPE:'cm:folder' OR +TYPE:'cm:content'`} + ] + }; + + await this.apiAuth(); + return this.alfrescoJsApi.search.searchApi.search(data); } async waitForApi(username, data) { @@ -66,4 +95,21 @@ export class SearchApi extends RepoApi { console.log('-----> catch search: ', error); } } + + async waitForNodes(searchTerm: string, data) { + try { + const nodes = async () => { + const totalItems = (await this.queryNodesNames(searchTerm)).list.pagination.totalItems; + if ( totalItems !== data.expect) { + return Promise.reject(totalItems); + } else { + return Promise.resolve(totalItems); + } + }; + + return await Utils.retryCall(nodes); + } catch (error) { + console.log('-----> catch search nodes: ', error); + } + } } diff --git a/src/app/components/sidenav/sidenav.component.html b/src/app/components/sidenav/sidenav.component.html index 6bda93f6a3..e3792dc90e 100644 --- a/src/app/components/sidenav/sidenav.component.html +++ b/src/app/components/sidenav/sidenav.component.html @@ -66,6 +66,7 @@ In order to modify or disable existing entries, you need to know the id of the target element, along with its parents ids.

Your extensions can perform the following actions at runtime: -* Add new presets items. -* Add new items to existing presets at any level. -* Disable specific items down to the aspect level. -* Modify any existing item based on id. + +- Add new presets items. +- Add new items to existing presets at any level. +- Disable specific items down to the aspect level. +- Modify any existing item based on id. Regarding properties, you can either: - * Add new properties to existing aspect, or - * Redefine the properties of an aspect. - + +- Add new properties to existing aspect, or +- Redefine the properties of an aspect. + Review this code snippet to see how you can overwrite the properties for `exif:exif` aspect from an external plugin: + ```json - { - "$schema": "../../../extension.schema.json", - "$version": "1.0.0", - "$name": "plugin1", - - "features": { - "content-metadata-presets": [ - { - "id": "app.content.metadata.custom", - "custom": [ - { - "id": "app.content.metadata.customGroup", - "items": [ - { - "id": "app.content.metadata.exifAspect", - "disabled": true - }, - { - "id": "app.content.metadata.exifAspect2", - "aspect": "exif:exif", - "properties": [ - "exif:orientation", - "exif:manufacturer", - "exif:model", - "exif:software" - ] - } - ] - } - ] - } - ] - } - } -``` -This external plugin disables the initial `exif:exif` aspect already defined in the `app.extensions.json` and defines other properties for the `exif:exif` aspect. +{ + "$schema": "../../../extension.schema.json", + "$version": "1.0.0", + "$name": "plugin1", + + "features": { + "content-metadata-presets": [ + { + "id": "app.content.metadata.custom", + "custom": [ + { + "id": "app.content.metadata.customGroup", + "items": [ + { + "id": "app.content.metadata.exifAspect", + "disabled": true + }, + { + "id": "app.content.metadata.exifAspect2", + "aspect": "exif:exif", + "properties": [ + "exif:orientation", + "exif:manufacturer", + "exif:model", + "exif:software" + ] + } + ] + } + ] + } + ] + } +} +``` + +This external plugin disables the initial `exif:exif` aspect already defined in the `app.extensions.json` and defines other properties for the `exif:exif` aspect. Here is the initial setting from `app.extension.json`: + ```json ... "content-metadata-presets": [ @@ -630,7 +639,8 @@ Here is the initial setting from `app.extension.json`: ] ... -``` +``` +

In order to allow the content-metadata presets to be extended, the settings from `app.config.json` must be copied to the `app.extensions.json` file and its ids must be added to all the items. Having ids allows external plugins to extend the current setting. diff --git a/e2e/resources/extensibility-configs/context-submenus-ext.json b/e2e/resources/extensibility-configs/context-submenus-ext.json index 5f86b51fda..51c26e0c26 100644 --- a/e2e/resources/extensibility-configs/context-submenus-ext.json +++ b/e2e/resources/extensibility-configs/context-submenus-ext.json @@ -759,111 +759,118 @@ "rules": { "visible": "app.toolbar.canViewFile" } - } - ], - "toolbarMoreMenu": [ - { - "id": "app.viewer.favorite.add", - "order": 100, - "title": "APP.ACTIONS.FAVORITE", - "icon": "star_border", - "actions": { - "click": "ADD_FAVORITE" - }, - "rules": { - "visible": "app.toolbar.favorite.canAdd" - } - }, - { - "id": "app.viewer.favorite.remove", - "order": 200, - "title": "APP.ACTIONS.FAVORITE", - "icon": "star", - "actions": { - "click": "REMOVE_FAVORITE" - }, - "rules": { - "visible": "app.toolbar.favorite.canRemove" - } - }, - { - "id": "app.viewer.favorite", - "comment": "workaround for Recent Files and Search API issue", - "type": "custom", - "order": 101, - "component": "app.toolbar.toggleFavorite", - "rules": { - "visible": "app.toolbar.favorite.canToggle" - } - }, - { - "id": "app.viewer.share", - "type": "custom", - "order": 300, - "component": "app.shared-link.toggleSharedLink", - "rules": { - "visible": "app.selection.file.canShare" - } }, { - "id": "app.viewer.copy", - "order": 400, - "title": "APP.ACTIONS.COPY", - "icon": "content_copy", - "actions": { - "click": "COPY_NODES" - }, - "rules": { - "visible": "app.toolbar.canCopyNode" - } - }, - { - "id": "app.viewer.move", - "order": 500, - "title": "APP.ACTIONS.MOVE", - "icon": "library_books", - "actions": { - "click": "MOVE_NODES" - }, - "rules": { - "visible": "app.selection.canDelete" - } - }, - { - "id": "app.viewer.delete", - "order": 600, - "title": "APP.ACTIONS.DELETE", - "icon": "delete", - "actions": { - "click": "DELETE_NODES" - }, - "rules": { - "visible": "app.selection.canDelete" - } - }, - { - "id": "app.viewer.versions", - "order": 700, - "title": "APP.ACTIONS.VERSIONS", - "icon": "history", - "actions": { - "click": "MANAGE_VERSIONS" - }, - "rules": { - "visible": "app.toolbar.versions" - } - }, - { - "id": "app.viewer.permissions", - "order": 800, - "title": "APP.ACTIONS.PERMISSIONS", - "icon": "settings_input_component", - "actions": { - "click": "MANAGE_PERMISSIONS" - }, - "rules": { - "visible": "app.toolbar.permissions" - } + "id": "app.toolbar.more", + "type": "menu", + "order": 10000, + "icon": "more_vert", + "title": "APP.ACTIONS.MORE", + "children": [ + { + "id": "app.viewer.favorite.add", + "order": 100, + "title": "APP.ACTIONS.FAVORITE", + "icon": "star_border", + "actions": { + "click": "ADD_FAVORITE" + }, + "rules": { + "visible": "app.toolbar.favorite.canAdd" + } + }, + { + "id": "app.viewer.favorite.remove", + "order": 200, + "title": "APP.ACTIONS.FAVORITE", + "icon": "star", + "actions": { + "click": "REMOVE_FAVORITE" + }, + "rules": { + "visible": "app.toolbar.favorite.canRemove" + } + }, + { + "id": "app.viewer.favorite", + "comment": "workaround for Recent Files and Search API issue", + "type": "custom", + "order": 101, + "component": "app.toolbar.toggleFavorite", + "rules": { + "visible": "app.toolbar.favorite.canToggle" + } + }, + { + "id": "app.viewer.share", + "type": "custom", + "order": 300, + "component": "app.shared-link.toggleSharedLink", + "rules": { + "visible": "app.selection.file.canShare" + } + }, + { + "id": "app.viewer.copy", + "order": 400, + "title": "APP.ACTIONS.COPY", + "icon": "content_copy", + "actions": { + "click": "COPY_NODES" + }, + "rules": { + "visible": "app.toolbar.canCopyNode" + } + }, + { + "id": "app.viewer.move", + "order": 500, + "title": "APP.ACTIONS.MOVE", + "icon": "library_books", + "actions": { + "click": "MOVE_NODES" + }, + "rules": { + "visible": "app.selection.canDelete" + } + }, + { + "id": "app.viewer.delete", + "order": 600, + "title": "APP.ACTIONS.DELETE", + "icon": "delete", + "actions": { + "click": "DELETE_NODES" + }, + "rules": { + "visible": "app.selection.canDelete" + } + }, + { + "id": "app.viewer.versions", + "order": 700, + "title": "APP.ACTIONS.VERSIONS", + "icon": "history", + "actions": { + "click": "MANAGE_VERSIONS" + }, + "rules": { + "visible": "app.toolbar.versions" + } + }, + { + "id": "app.viewer.permissions", + "order": 800, + "title": "APP.ACTIONS.PERMISSIONS", + "icon": "settings_input_component", + "actions": { + "click": "MANAGE_PERMISSIONS" + }, + "rules": { + "visible": "app.toolbar.permissions" + } + } + ] } ], "content": [ diff --git a/e2e/resources/extensibility-configs/document-presets-ext.json b/e2e/resources/extensibility-configs/document-presets-ext.json index 5797cc32d2..45f006c3d9 100644 --- a/e2e/resources/extensibility-configs/document-presets-ext.json +++ b/e2e/resources/extensibility-configs/document-presets-ext.json @@ -692,111 +692,118 @@ "rules": { "visible": "app.toolbar.canViewFile" } - } - ], - "toolbarMoreMenu": [ - { - "id": "app.viewer.favorite.add", - "order": 100, - "title": "APP.ACTIONS.FAVORITE", - "icon": "star_border", - "actions": { - "click": "ADD_FAVORITE" - }, - "rules": { - "visible": "app.toolbar.favorite.canAdd" - } - }, - { - "id": "app.viewer.favorite.remove", - "order": 200, - "title": "APP.ACTIONS.FAVORITE", - "icon": "star", - "actions": { - "click": "REMOVE_FAVORITE" - }, - "rules": { - "visible": "app.toolbar.favorite.canRemove" - } - }, - { - "id": "app.viewer.favorite", - "comment": "workaround for Recent Files and Search API issue", - "type": "custom", - "order": 101, - "component": "app.toolbar.toggleFavorite", - "rules": { - "visible": "app.toolbar.favorite.canToggle" - } - }, - { - "id": "app.viewer.share", - "type": "custom", - "order": 300, - "component": "app.shared-link.toggleSharedLink", - "rules": { - "visible": "app.selection.file.canShare" - } }, { - "id": "app.viewer.copy", - "order": 400, - "title": "APP.ACTIONS.COPY", - "icon": "content_copy", - "actions": { - "click": "COPY_NODES" - }, - "rules": { - "visible": "app.toolbar.canCopyNode" - } - }, - { - "id": "app.viewer.move", - "order": 500, - "title": "APP.ACTIONS.MOVE", - "icon": "library_books", - "actions": { - "click": "MOVE_NODES" - }, - "rules": { - "visible": "app.selection.canDelete" - } - }, - { - "id": "app.viewer.delete", - "order": 600, - "title": "APP.ACTIONS.DELETE", - "icon": "delete", - "actions": { - "click": "DELETE_NODES" - }, - "rules": { - "visible": "app.selection.canDelete" - } - }, - { - "id": "app.viewer.versions", - "order": 700, - "title": "APP.ACTIONS.VERSIONS", - "icon": "history", - "actions": { - "click": "MANAGE_VERSIONS" - }, - "rules": { - "visible": "app.toolbar.versions" - } - }, - { - "id": "app.viewer.permissions", - "order": 800, - "title": "APP.ACTIONS.PERMISSIONS", - "icon": "settings_input_component", - "actions": { - "click": "MANAGE_PERMISSIONS" - }, - "rules": { - "visible": "app.toolbar.permissions" - } + "id": "app.toolbar.more", + "type": "menu", + "order": 10000, + "icon": "more_vert", + "title": "APP.ACTIONS.MORE", + "children": [ + { + "id": "app.viewer.favorite.add", + "order": 100, + "title": "APP.ACTIONS.FAVORITE", + "icon": "star_border", + "actions": { + "click": "ADD_FAVORITE" + }, + "rules": { + "visible": "app.toolbar.favorite.canAdd" + } + }, + { + "id": "app.viewer.favorite.remove", + "order": 200, + "title": "APP.ACTIONS.FAVORITE", + "icon": "star", + "actions": { + "click": "REMOVE_FAVORITE" + }, + "rules": { + "visible": "app.toolbar.favorite.canRemove" + } + }, + { + "id": "app.viewer.favorite", + "comment": "workaround for Recent Files and Search API issue", + "type": "custom", + "order": 101, + "component": "app.toolbar.toggleFavorite", + "rules": { + "visible": "app.toolbar.favorite.canToggle" + } + }, + { + "id": "app.viewer.share", + "type": "custom", + "order": 300, + "component": "app.shared-link.toggleSharedLink", + "rules": { + "visible": "app.selection.file.canShare" + } + }, + { + "id": "app.viewer.copy", + "order": 400, + "title": "APP.ACTIONS.COPY", + "icon": "content_copy", + "actions": { + "click": "COPY_NODES" + }, + "rules": { + "visible": "app.toolbar.canCopyNode" + } + }, + { + "id": "app.viewer.move", + "order": 500, + "title": "APP.ACTIONS.MOVE", + "icon": "library_books", + "actions": { + "click": "MOVE_NODES" + }, + "rules": { + "visible": "app.selection.canDelete" + } + }, + { + "id": "app.viewer.delete", + "order": 600, + "title": "APP.ACTIONS.DELETE", + "icon": "delete", + "actions": { + "click": "DELETE_NODES" + }, + "rules": { + "visible": "app.selection.canDelete" + } + }, + { + "id": "app.viewer.versions", + "order": 700, + "title": "APP.ACTIONS.VERSIONS", + "icon": "history", + "actions": { + "click": "MANAGE_VERSIONS" + }, + "rules": { + "visible": "app.toolbar.versions" + } + }, + { + "id": "app.viewer.permissions", + "order": 800, + "title": "APP.ACTIONS.PERMISSIONS", + "icon": "settings_input_component", + "actions": { + "click": "MANAGE_PERMISSIONS" + }, + "rules": { + "visible": "app.toolbar.permissions" + } + } + ] } ], "content": [ diff --git a/e2e/resources/extensibility-configs/extensions-default.json b/e2e/resources/extensibility-configs/extensions-default.json index d46e6fa117..348d85289a 100644 --- a/e2e/resources/extensibility-configs/extensions-default.json +++ b/e2e/resources/extensibility-configs/extensions-default.json @@ -674,114 +674,121 @@ "rules": { "visible": "app.toolbar.canViewFile" } - } - ], - "toolbarMoreMenu": [ - { - "id": "app.viewer.favorite.add", - "order": 100, - "title": "APP.ACTIONS.FAVORITE", - "icon": "star_border", - "actions": { - "click": "ADD_FAVORITE" - }, - "rules": { - "visible": "app.toolbar.favorite.canAdd" - } - }, - { - "id": "app.viewer.favorite.remove", - "order": 200, - "title": "APP.ACTIONS.FAVORITE", - "icon": "star", - "actions": { - "click": "REMOVE_FAVORITE" - }, - "rules": { - "visible": "app.toolbar.favorite.canRemove" - } - }, - { - "id": "app.viewer.favorite", - "comment": "workaround for Recent Files and Search API issue", - "type": "custom", - "order": 101, - "component": "app.toolbar.toggleFavorite", - "rules": { - "visible": "app.toolbar.favorite.canToggle" - } - }, - { - "id": "app.viewer.share", - "order": 300, - "title": "APP.ACTIONS.SHARE", - "icon": "share", - "actions": { - "click": "SHARE_NODE" - }, - "rules": { - "visible": "app.selection.file.canShare" - } - }, - { - "id": "app.viewer.copy", - "order": 400, - "title": "APP.ACTIONS.COPY", - "icon": "content_copy", - "actions": { - "click": "COPY_NODES" - }, - "rules": { - "visible": "app.toolbar.canCopyNode" - } - }, - { - "id": "app.viewer.move", - "order": 500, - "title": "APP.ACTIONS.MOVE", - "icon": "library_books", - "actions": { - "click": "MOVE_NODES" - }, - "rules": { - "visible": "app.selection.canDelete" - } }, { - "id": "app.viewer.delete", - "order": 600, - "title": "APP.ACTIONS.DELETE", - "icon": "delete", - "actions": { - "click": "DELETE_NODES" - }, - "rules": { - "visible": "app.selection.canDelete" - } - }, - { - "id": "app.viewer.versions", - "order": 700, - "title": "APP.ACTIONS.VERSIONS", - "icon": "history", - "actions": { - "click": "MANAGE_VERSIONS" - }, - "rules": { - "visible": "app.toolbar.versions" - } - }, - { - "id": "app.viewer.permissions", - "order": 800, - "title": "APP.ACTIONS.PERMISSIONS", - "icon": "settings_input_component", - "actions": { - "click": "MANAGE_PERMISSIONS" - }, - "rules": { - "visible": "app.toolbar.permissions" - } + "id": "app.toolbar.more", + "type": "menu", + "order": 10000, + "icon": "more_vert", + "title": "APP.ACTIONS.MORE", + "children": [ + { + "id": "app.viewer.favorite.add", + "order": 100, + "title": "APP.ACTIONS.FAVORITE", + "icon": "star_border", + "actions": { + "click": "ADD_FAVORITE" + }, + "rules": { + "visible": "app.toolbar.favorite.canAdd" + } + }, + { + "id": "app.viewer.favorite.remove", + "order": 200, + "title": "APP.ACTIONS.FAVORITE", + "icon": "star", + "actions": { + "click": "REMOVE_FAVORITE" + }, + "rules": { + "visible": "app.toolbar.favorite.canRemove" + } + }, + { + "id": "app.viewer.favorite", + "comment": "workaround for Recent Files and Search API issue", + "type": "custom", + "order": 101, + "component": "app.toolbar.toggleFavorite", + "rules": { + "visible": "app.toolbar.favorite.canToggle" + } + }, + { + "id": "app.viewer.share", + "order": 300, + "title": "APP.ACTIONS.SHARE", + "icon": "share", + "actions": { + "click": "SHARE_NODE" + }, + "rules": { + "visible": "app.selection.file.canShare" + } + }, + { + "id": "app.viewer.copy", + "order": 400, + "title": "APP.ACTIONS.COPY", + "icon": "content_copy", + "actions": { + "click": "COPY_NODES" + }, + "rules": { + "visible": "app.toolbar.canCopyNode" + } + }, + { + "id": "app.viewer.move", + "order": 500, + "title": "APP.ACTIONS.MOVE", + "icon": "library_books", + "actions": { + "click": "MOVE_NODES" + }, + "rules": { + "visible": "app.selection.canDelete" + } + }, + { + "id": "app.viewer.delete", + "order": 600, + "title": "APP.ACTIONS.DELETE", + "icon": "delete", + "actions": { + "click": "DELETE_NODES" + }, + "rules": { + "visible": "app.selection.canDelete" + } + }, + { + "id": "app.viewer.versions", + "order": 700, + "title": "APP.ACTIONS.VERSIONS", + "icon": "history", + "actions": { + "click": "MANAGE_VERSIONS" + }, + "rules": { + "visible": "app.toolbar.versions" + } + }, + { + "id": "app.viewer.permissions", + "order": 800, + "title": "APP.ACTIONS.PERMISSIONS", + "icon": "settings_input_component", + "actions": { + "click": "MANAGE_PERMISSIONS" + }, + "rules": { + "visible": "app.toolbar.permissions" + } + } + ] } ], "content": [ diff --git a/e2e/resources/extensibility-configs/header-ext.json b/e2e/resources/extensibility-configs/header-ext.json index 5439bd575c..7d3f5086a5 100644 --- a/e2e/resources/extensibility-configs/header-ext.json +++ b/e2e/resources/extensibility-configs/header-ext.json @@ -710,114 +710,121 @@ "rules": { "visible": "app.toolbar.canViewFile" } - } - ], - "toolbarMoreMenu": [ - { - "id": "app.viewer.favorite.add", - "order": 100, - "title": "APP.ACTIONS.FAVORITE", - "icon": "star_border", - "actions": { - "click": "ADD_FAVORITE" - }, - "rules": { - "visible": "app.toolbar.favorite.canAdd" - } - }, - { - "id": "app.viewer.favorite.remove", - "order": 200, - "title": "APP.ACTIONS.FAVORITE", - "icon": "star", - "actions": { - "click": "REMOVE_FAVORITE" - }, - "rules": { - "visible": "app.toolbar.favorite.canRemove" - } - }, - { - "id": "app.viewer.favorite", - "comment": "workaround for Recent Files and Search API issue", - "type": "custom", - "order": 101, - "component": "app.toolbar.toggleFavorite", - "rules": { - "visible": "app.toolbar.favorite.canToggle" - } - }, - { - "id": "app.viewer.share", - "order": 300, - "title": "APP.ACTIONS.SHARE", - "icon": "share", - "actions": { - "click": "SHARE_NODE" - }, - "rules": { - "visible": "app.selection.file.canShare" - } - }, - { - "id": "app.viewer.copy", - "order": 400, - "title": "APP.ACTIONS.COPY", - "icon": "content_copy", - "actions": { - "click": "COPY_NODES" - }, - "rules": { - "visible": "app.toolbar.canCopyNode" - } - }, - { - "id": "app.viewer.move", - "order": 500, - "title": "APP.ACTIONS.MOVE", - "icon": "library_books", - "actions": { - "click": "MOVE_NODES" - }, - "rules": { - "visible": "app.selection.canDelete" - } }, { - "id": "app.viewer.delete", - "order": 600, - "title": "APP.ACTIONS.DELETE", - "icon": "delete", - "actions": { - "click": "DELETE_NODES" - }, - "rules": { - "visible": "app.selection.canDelete" - } - }, - { - "id": "app.viewer.versions", - "order": 700, - "title": "APP.ACTIONS.VERSIONS", - "icon": "history", - "actions": { - "click": "MANAGE_VERSIONS" - }, - "rules": { - "visible": "app.toolbar.versions" - } - }, - { - "id": "app.viewer.permissions", - "order": 800, - "title": "APP.ACTIONS.PERMISSIONS", - "icon": "settings_input_component", - "actions": { - "click": "MANAGE_PERMISSIONS" - }, - "rules": { - "visible": "app.toolbar.permissions" - } + "id": "app.toolbar.more", + "type": "menu", + "order": 10000, + "icon": "more_vert", + "title": "APP.ACTIONS.MORE", + "children": [ + { + "id": "app.viewer.favorite.add", + "order": 100, + "title": "APP.ACTIONS.FAVORITE", + "icon": "star_border", + "actions": { + "click": "ADD_FAVORITE" + }, + "rules": { + "visible": "app.toolbar.favorite.canAdd" + } + }, + { + "id": "app.viewer.favorite.remove", + "order": 200, + "title": "APP.ACTIONS.FAVORITE", + "icon": "star", + "actions": { + "click": "REMOVE_FAVORITE" + }, + "rules": { + "visible": "app.toolbar.favorite.canRemove" + } + }, + { + "id": "app.viewer.favorite", + "comment": "workaround for Recent Files and Search API issue", + "type": "custom", + "order": 101, + "component": "app.toolbar.toggleFavorite", + "rules": { + "visible": "app.toolbar.favorite.canToggle" + } + }, + { + "id": "app.viewer.share", + "order": 300, + "title": "APP.ACTIONS.SHARE", + "icon": "share", + "actions": { + "click": "SHARE_NODE" + }, + "rules": { + "visible": "app.selection.file.canShare" + } + }, + { + "id": "app.viewer.copy", + "order": 400, + "title": "APP.ACTIONS.COPY", + "icon": "content_copy", + "actions": { + "click": "COPY_NODES" + }, + "rules": { + "visible": "app.toolbar.canCopyNode" + } + }, + { + "id": "app.viewer.move", + "order": 500, + "title": "APP.ACTIONS.MOVE", + "icon": "library_books", + "actions": { + "click": "MOVE_NODES" + }, + "rules": { + "visible": "app.selection.canDelete" + } + }, + { + "id": "app.viewer.delete", + "order": 600, + "title": "APP.ACTIONS.DELETE", + "icon": "delete", + "actions": { + "click": "DELETE_NODES" + }, + "rules": { + "visible": "app.selection.canDelete" + } + }, + { + "id": "app.viewer.versions", + "order": 700, + "title": "APP.ACTIONS.VERSIONS", + "icon": "history", + "actions": { + "click": "MANAGE_VERSIONS" + }, + "rules": { + "visible": "app.toolbar.versions" + } + }, + { + "id": "app.viewer.permissions", + "order": 800, + "title": "APP.ACTIONS.PERMISSIONS", + "icon": "settings_input_component", + "actions": { + "click": "MANAGE_PERMISSIONS" + }, + "rules": { + "visible": "app.toolbar.permissions" + } + } + ] } ], "content": [ diff --git a/e2e/resources/extensibility-configs/metadata-ext.json b/e2e/resources/extensibility-configs/metadata-ext.json index 01273636fe..a93b3d1569 100644 --- a/e2e/resources/extensibility-configs/metadata-ext.json +++ b/e2e/resources/extensibility-configs/metadata-ext.json @@ -709,114 +709,121 @@ "rules": { "visible": "app.toolbar.canViewFile" } - } - ], - "toolbarMoreMenu": [ - { - "id": "app.viewer.favorite.add", - "order": 100, - "title": "APP.ACTIONS.FAVORITE", - "icon": "star_border", - "actions": { - "click": "ADD_FAVORITE" - }, - "rules": { - "visible": "app.toolbar.favorite.canAdd" - } - }, - { - "id": "app.viewer.favorite.remove", - "order": 200, - "title": "APP.ACTIONS.FAVORITE", - "icon": "star", - "actions": { - "click": "REMOVE_FAVORITE" - }, - "rules": { - "visible": "app.toolbar.favorite.canRemove" - } - }, - { - "id": "app.viewer.favorite", - "comment": "workaround for Recent Files and Search API issue", - "type": "custom", - "order": 101, - "component": "app.toolbar.toggleFavorite", - "rules": { - "visible": "app.toolbar.favorite.canToggle" - } - }, - { - "id": "app.viewer.share", - "order": 300, - "title": "APP.ACTIONS.SHARE", - "icon": "share", - "actions": { - "click": "SHARE_NODE" - }, - "rules": { - "visible": "app.selection.file.canShare" - } - }, - { - "id": "app.viewer.copy", - "order": 400, - "title": "APP.ACTIONS.COPY", - "icon": "content_copy", - "actions": { - "click": "COPY_NODES" - }, - "rules": { - "visible": "app.toolbar.canCopyNode" - } - }, - { - "id": "app.viewer.move", - "order": 500, - "title": "APP.ACTIONS.MOVE", - "icon": "library_books", - "actions": { - "click": "MOVE_NODES" - }, - "rules": { - "visible": "app.selection.canDelete" - } }, { - "id": "app.viewer.delete", - "order": 600, - "title": "APP.ACTIONS.DELETE", - "icon": "delete", - "actions": { - "click": "DELETE_NODES" - }, - "rules": { - "visible": "app.selection.canDelete" - } - }, - { - "id": "app.viewer.versions", - "order": 700, - "title": "APP.ACTIONS.VERSIONS", - "icon": "history", - "actions": { - "click": "MANAGE_VERSIONS" - }, - "rules": { - "visible": "app.toolbar.versions" - } - }, - { - "id": "app.viewer.permissions", - "order": 800, - "title": "APP.ACTIONS.PERMISSIONS", - "icon": "settings_input_component", - "actions": { - "click": "MANAGE_PERMISSIONS" - }, - "rules": { - "visible": "app.toolbar.permissions" - } + "id": "app.toolbar.more", + "type": "menu", + "order": 10000, + "icon": "more_vert", + "title": "APP.ACTIONS.MORE", + "children": [ + { + "id": "app.viewer.favorite.add", + "order": 100, + "title": "APP.ACTIONS.FAVORITE", + "icon": "star_border", + "actions": { + "click": "ADD_FAVORITE" + }, + "rules": { + "visible": "app.toolbar.favorite.canAdd" + } + }, + { + "id": "app.viewer.favorite.remove", + "order": 200, + "title": "APP.ACTIONS.FAVORITE", + "icon": "star", + "actions": { + "click": "REMOVE_FAVORITE" + }, + "rules": { + "visible": "app.toolbar.favorite.canRemove" + } + }, + { + "id": "app.viewer.favorite", + "comment": "workaround for Recent Files and Search API issue", + "type": "custom", + "order": 101, + "component": "app.toolbar.toggleFavorite", + "rules": { + "visible": "app.toolbar.favorite.canToggle" + } + }, + { + "id": "app.viewer.share", + "order": 300, + "title": "APP.ACTIONS.SHARE", + "icon": "share", + "actions": { + "click": "SHARE_NODE" + }, + "rules": { + "visible": "app.selection.file.canShare" + } + }, + { + "id": "app.viewer.copy", + "order": 400, + "title": "APP.ACTIONS.COPY", + "icon": "content_copy", + "actions": { + "click": "COPY_NODES" + }, + "rules": { + "visible": "app.toolbar.canCopyNode" + } + }, + { + "id": "app.viewer.move", + "order": 500, + "title": "APP.ACTIONS.MOVE", + "icon": "library_books", + "actions": { + "click": "MOVE_NODES" + }, + "rules": { + "visible": "app.selection.canDelete" + } + }, + { + "id": "app.viewer.delete", + "order": 600, + "title": "APP.ACTIONS.DELETE", + "icon": "delete", + "actions": { + "click": "DELETE_NODES" + }, + "rules": { + "visible": "app.selection.canDelete" + } + }, + { + "id": "app.viewer.versions", + "order": 700, + "title": "APP.ACTIONS.VERSIONS", + "icon": "history", + "actions": { + "click": "MANAGE_VERSIONS" + }, + "rules": { + "visible": "app.toolbar.versions" + } + }, + { + "id": "app.viewer.permissions", + "order": 800, + "title": "APP.ACTIONS.PERMISSIONS", + "icon": "settings_input_component", + "actions": { + "click": "MANAGE_PERMISSIONS" + }, + "rules": { + "visible": "app.toolbar.permissions" + } + } + ] } ], "content": [ diff --git a/e2e/resources/extensibility-configs/viewer-ext.json b/e2e/resources/extensibility-configs/viewer-ext.json index 74f0ce5299..352f137e21 100644 --- a/e2e/resources/extensibility-configs/viewer-ext.json +++ b/e2e/resources/extensibility-configs/viewer-ext.json @@ -689,127 +689,134 @@ "rules": { "visible": "app.toolbar.canViewFile" } - } - ], - "toolbarMoreMenu": [ - { - "id": "app.viewer.favorite.add", - "order": 100, - "title": "APP.ACTIONS.FAVORITE", - "icon": "star_border", - "actions": { - "click": "ADD_FAVORITE" - }, - "rules": { - "visible": "app.toolbar.favorite.canAdd" - } }, { - "id": "app.viewer.favorite.remove", - "order": 200, - "title": "APP.ACTIONS.FAVORITE", - "icon": "star", - "actions": { - "click": "REMOVE_FAVORITE" + "id": "app.toolbar.more", + "type": "menu", + "order": 10000, + "icon": "more_vert", + "title": "APP.ACTIONS.MORE", + "children": [ + { + "id": "app.viewer.favorite.add", + "order": 100, + "title": "APP.ACTIONS.FAVORITE", + "icon": "star_border", + "actions": { + "click": "ADD_FAVORITE" + }, + "rules": { + "visible": "app.toolbar.favorite.canAdd" + } }, - "rules": { - "visible": "app.toolbar.favorite.canRemove" - } - }, - { - "id": "app.viewer.favorite", - "comment": "workaround for Recent Files and Search API issue", - "type": "custom", - "order": 101, - "component": "app.toolbar.toggleFavorite", - "rules": { - "visible": "app.toolbar.favorite.canToggle" - } - }, - { - "id": "app.toolbar.my-secondary-action", - "order": 150, - "title": "My secondary action", - "icon": "alarm", - "actions": { - "click": "PRINT_FILE" + { + "id": "app.viewer.favorite.remove", + "order": 200, + "title": "APP.ACTIONS.FAVORITE", + "icon": "star", + "actions": { + "click": "REMOVE_FAVORITE" + }, + "rules": { + "visible": "app.toolbar.favorite.canRemove" + } }, - "rules": { - "visible": "app.toolbar.canViewFile" - } - }, - { - "id": "app.viewer.share", - "order": 300, - "title": "APP.ACTIONS.SHARE", - "icon": "share", - "actions": { - "click": "SHARE_NODE" + { + "id": "app.viewer.favorite", + "comment": "workaround for Recent Files and Search API issue", + "type": "custom", + "order": 101, + "component": "app.toolbar.toggleFavorite", + "rules": { + "visible": "app.toolbar.favorite.canToggle" + } }, - "rules": { - "visible": "app.selection.file.canShare" - } - }, - { - "id": "app.viewer.copy", - "order": 400, - "title": "APP.ACTIONS.COPY", - "icon": "content_copy", - "actions": { - "click": "COPY_NODES" + { + "id": "app.toolbar.my-secondary-action", + "order": 150, + "title": "My secondary action", + "icon": "alarm", + "actions": { + "click": "PRINT_FILE" + }, + "rules": { + "visible": "app.toolbar.canViewFile" + } }, - "rules": { - "visible": "app.toolbar.canCopyNode" - } - }, - { - "id": "app.viewer.move", - "order": 500, - "title": "My new title", - "icon": "library_books", - "actions": { - "click": "MOVE_NODES" + { + "id": "app.viewer.share", + "order": 300, + "title": "APP.ACTIONS.SHARE", + "icon": "share", + "actions": { + "click": "SHARE_NODE" + }, + "rules": { + "visible": "app.selection.file.canShare" + } }, - "rules": { - "visible": "app.selection.canDelete" - } - }, - { - "id": "app.viewer.delete", - "order": 600, - "title": "APP.ACTIONS.DELETE", - "icon": "delete", - "actions": { - "click": "DELETE_NODES" + { + "id": "app.viewer.copy", + "order": 400, + "title": "APP.ACTIONS.COPY", + "icon": "content_copy", + "actions": { + "click": "COPY_NODES" + }, + "rules": { + "visible": "app.toolbar.canCopyNode" + } }, - "rules": { - "visible": "app.selection.canDelete" - } - }, - { - "id": "app.viewer.versions", - "order": 700, - "title": "APP.ACTIONS.VERSIONS", - "icon": "history", - "actions": { - "click": "MANAGE_VERSIONS" + { + "id": "app.viewer.move", + "order": 500, + "title": "My new title", + "icon": "library_books", + "actions": { + "click": "MOVE_NODES" + }, + "rules": { + "visible": "app.selection.canDelete" + } }, - "rules": { - "visible": "app.toolbar.versions" - } - }, - { - "id": "app.viewer.permissions", - "order": 800, - "title": "APP.ACTIONS.PERMISSIONS", - "disabled": true, - "icon": "settings_input_component", - "actions": { - "click": "MANAGE_PERMISSIONS" + { + "id": "app.viewer.delete", + "order": 600, + "title": "APP.ACTIONS.DELETE", + "icon": "delete", + "actions": { + "click": "DELETE_NODES" + }, + "rules": { + "visible": "app.selection.canDelete" + } }, - "rules": { - "visible": "app.toolbar.permissions" + { + "id": "app.viewer.versions", + "order": 700, + "title": "APP.ACTIONS.VERSIONS", + "icon": "history", + "actions": { + "click": "MANAGE_VERSIONS" + }, + "rules": { + "visible": "app.toolbar.versions" + } + }, + { + "id": "app.viewer.permissions", + "order": 800, + "title": "APP.ACTIONS.PERMISSIONS", + "disabled": true, + "icon": "settings_input_component", + "actions": { + "click": "MANAGE_PERMISSIONS" + }, + "rules": { + "visible": "app.toolbar.permissions" + } } + ] } ], "content": [ diff --git a/extension.schema.json b/extension.schema.json index 5d2786a0ba..cd9fb2d713 100644 --- a/extension.schema.json +++ b/extension.schema.json @@ -674,12 +674,6 @@ "items": { "$ref": "#/definitions/contentActionRef" }, "minItems": 1 }, - "toolbarMoreMenu": { - "description": "Toolbar entries from the More actions menu", - "type": "array", - "items": { "$ref": "#/definitions/contentActionRef" }, - "minItems": 1 - }, "toolbarActions": { "description": "Toolbar entries from outside the More menu", "type": "array", diff --git a/package-lock.json b/package-lock.json index d84bafc10b..fb1eb8259c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3100,6 +3100,7 @@ "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", "dev": true, + "optional": true, "requires": { "kind-of": "^3.0.2", "longest": "^1.0.1", @@ -6443,7 +6444,8 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -6467,13 +6469,15 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -6490,19 +6494,22 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -6633,7 +6640,8 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -6647,6 +6655,7 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -6663,6 +6672,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -6671,13 +6681,15 @@ "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.2.4.tgz", "integrity": "sha512-hzXIWWet/BzWhYs2b+u7dRHlruXhwdgvlTMDKC6Cb1U7ps6Ac6yQlR39xsbjWJE377YTCtKwIXIpJ5oP+j5y8g==", "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -6698,6 +6710,7 @@ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -6786,7 +6799,8 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -6800,6 +6814,7 @@ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -6895,7 +6910,8 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -6937,6 +6953,7 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -6958,6 +6975,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -7006,13 +7024,15 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.2.tgz", "integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=", - "dev": true + "dev": true, + "optional": true } } }, @@ -10366,7 +10386,8 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", - "dev": true + "dev": true, + "optional": true }, "loose-envify": { "version": "1.4.0", @@ -12665,9 +12686,9 @@ "dev": true }, "prettier": { - "version": "1.15.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.15.3.tgz", - "integrity": "sha512-gAU9AGAPMaKb3NNSUUuhhFAS7SCO4ALTN4nRIn6PJ075Qd28Yn2Ig2ahEJWdJwJmlEBTUfC7mMUSFy8MwsOCfg==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.16.0.tgz", + "integrity": "sha512-MCBCYeAuZfejUPdEpkleLWvpRBwLii/Sp5jQs0eb8Ul/drGIDjkL6tAU24tk6yCGf0KPV5rhPPPlczfBmN2pWQ==", "dev": true }, "pretty-format": { diff --git a/package.json b/package.json index e332e49fd9..2ee7944f24 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "e2e:docker": "npm run start:docker && npm run e2e && npm run stop:docker", "spellcheck": "cspell 'src/**/*.ts' 'e2e/**/*.ts' 'projects/**/*.ts'", "inspect.bundle": "ng build app --prod --stats-json && npx webpack-bundle-analyzer dist/app/stats.json", - "format:check": "prettier --list-different \"src/{app,environments}/**/*.{ts,js,css,scss,html}\"", + "format:check": "prettier --check \"src/{app,environments}/**/*.{ts,js,css,scss,html}\"", "format:fix": "prettier --write \"src/{app,environments}/**/*.{ts,js,css,scss,html}\"", "build.tomcat": "npm run build -- --base-href ./ && jar -cvf docker/tomcat/artifacts/content-app.war -C dist/app/ .", "build.tomcat.e2e": "./build-tomcat-e2e.sh", @@ -93,7 +93,7 @@ "lint-staged": "^8.1.0", "ng-packagr": "^4.4.0", "pre-commit": "^1.2.2", - "prettier": "^1.15.3", + "prettier": "^1.16.0", "protractor": "^5.4.0", "rimraf": "2.6.2", "rxjs-tslint-rules": "^4.11.0", diff --git a/src/app/components/page.component.ts b/src/app/components/page.component.ts index 3184392c43..3494898c2c 100644 --- a/src/app/components/page.component.ts +++ b/src/app/components/page.component.ts @@ -59,7 +59,6 @@ export abstract class PageComponent implements OnInit, OnDestroy { sharedPreviewUrl$: Observable; actions: Array = []; viewerToolbarActions: Array = []; - viewerToolbarMoreActions: Array = []; canUpdateNode = false; canUpload = false; @@ -101,7 +100,6 @@ export abstract class PageComponent implements OnInit, OnDestroy { this.selection = selection; this.actions = this.extensions.getAllowedToolbarActions(); this.viewerToolbarActions = this.extensions.getViewerToolbarActions(); - this.viewerToolbarMoreActions = this.extensions.getViewerToolbarMoreActions(); this.canUpdateNode = this.selection.count === 1 && this.content.canUpdateNode(selection.first); diff --git a/src/app/components/preview/preview.component.html b/src/app/components/preview/preview.component.html index 1bb50988b3..998a327b11 100644 --- a/src/app/components/preview/preview.component.html +++ b/src/app/components/preview/preview.component.html @@ -32,17 +32,6 @@ - - - - - - diff --git a/src/app/components/preview/preview.component.scss b/src/app/components/preview/preview.component.scss index 69d1ddb3c7..f75a7fc5bb 100644 --- a/src/app/components/preview/preview.component.scss +++ b/src/app/components/preview/preview.component.scss @@ -3,22 +3,16 @@ height: 100%; } -.hide-last-divider .adf-viewer-toolbar .mat-toolbar { - > adf-toolbar-divider:last-of-type { - display: none; - } - - > button:last-of-type { - right: 40px; - } -} - -#adf-viewer-moreactions { - right: -40px; +.adf-viewer-toolbar .adf-toolbar-divider { + display: none; } .adf-viewer-toolbar-actions { display: flex; flex-direction: row; align-items: center; + + .adf-toolbar-divider { + display: inline; + } } diff --git a/src/app/extensions/extension.service.spec.ts b/src/app/extensions/extension.service.spec.ts index 4709cbf6b7..0e7629b226 100644 --- a/src/app/extensions/extension.service.spec.ts +++ b/src/app/extensions/extension.service.spec.ts @@ -586,7 +586,7 @@ describe('AppExtensionService', () => { }); it('should filter out all disabled items', () => { - const items = [ + const items: any[] = [ { id: '1', disabled: true }, { id: '2', diff --git a/src/app/extensions/extension.service.ts b/src/app/extensions/extension.service.ts index 18952f002a..7c945da432 100644 --- a/src/app/extensions/extension.service.ts +++ b/src/app/extensions/extension.service.ts @@ -71,7 +71,6 @@ export class AppExtensionService implements RuleContext { headerActions: Array = []; toolbarActions: Array = []; viewerToolbarActions: Array = []; - viewerToolbarMoreActions: Array = []; viewerContentExtensions: Array = []; contextMenuActions: Array = []; openWithActions: Array = []; @@ -148,10 +147,6 @@ export class AppExtensionService implements RuleContext { config, 'features.viewer.toolbarActions' ); - this.viewerToolbarMoreActions = this.loader.getContentActions( - config, - 'features.viewer.toolbarMoreMenu' - ); this.viewerContentExtensions = this.loader.getElements( config, 'features.viewer.content' @@ -295,7 +290,7 @@ export class AppExtensionService implements RuleContext { return { presets }; } - filterDisabled(object) { + filterDisabled(object: Array<{ disabled: boolean }> | { disabled: boolean }) { if (Array.isArray(object)) { return object .filter(item => !item.disabled) @@ -398,15 +393,15 @@ export class AppExtensionService implements RuleContext { return actionRef; } - // evaluates content actions for the selection and parent folder node - getAllowedToolbarActions(): Array { - return this.toolbarActions + private getAllowedActions(actions: ContentActionRef[]): ContentActionRef[] { + return (actions || []) .filter(action => this.filterByRules(action)) .map(action => { if (action.type === ContentActionType.menu) { const copy = this.copyAction(action); if (copy.children && copy.children.length > 0) { copy.children = copy.children + .filter(entry => !entry.disabled) .filter(childAction => this.filterByRules(childAction)) .sort(sortByOrder) .reduce(reduceSeparators, []); @@ -419,41 +414,20 @@ export class AppExtensionService implements RuleContext { .reduce(reduceSeparators, []); } + getAllowedToolbarActions(): Array { + return this.getAllowedActions(this.toolbarActions); + } + getViewerToolbarActions(): Array { - return this.viewerToolbarActions.filter(action => - this.filterByRules(action) - ); + return this.getAllowedActions(this.viewerToolbarActions); } getHeaderActions(): Array { return this.headerActions.filter(action => this.filterByRules(action)); } - getViewerToolbarMoreActions(): Array { - return this.viewerToolbarMoreActions.filter(action => - this.filterByRules(action) - ); - } - getAllowedContextMenuActions(): Array { - return this.contextMenuActions - .filter(action => this.filterByRules(action)) - .map(action => { - if (action.type === ContentActionType.menu) { - const copy = this.copyAction(action); - if (copy.children && copy.children.length > 0) { - copy.children = copy.children - .filter(entry => !entry.disabled) - .filter(childAction => this.filterByRules(childAction)) - .sort(sortByOrder) - .reduce(reduceSeparators, []); - } - return copy; - } - return action; - }) - .reduce(reduceEmptyMenus, []) - .reduce(reduceSeparators, []); + return this.getAllowedActions(this.contextMenuActions); } copyAction(action: ContentActionRef): ContentActionRef { diff --git a/src/assets/app.extensions.json b/src/assets/app.extensions.json index 4c3cc36349..599721faa3 100644 --- a/src/assets/app.extensions.json +++ b/src/assets/app.extensions.json @@ -851,28 +851,21 @@ "viewer": { "toolbarActions": [ { - "id": "app.viewer.download", - "order": 300, - "title": "APP.ACTIONS.DOWNLOAD", - "icon": "get_app", + "id": "app.viewer.fullscreen", + "order": 100, + "title": "APP.ACTIONS.FULLSCREEN", + "icon": "fullscreen", "actions": { - "click": "DOWNLOAD_NODES" + "click": "FULLSCREEN_VIEWER" }, "rules": { - "visible": "app.toolbar.canDownload" + "visible": "app.toolbar.canViewFile" } }, { - "id": "app.viewer.print", - "order": 400, - "title": "APP.ACTIONS.PRINT", - "icon": "print", - "actions": { - "click": "PRINT_FILE" - }, - "rules": { - "visible": "app.toolbar.canViewFile" - } + "id": "app.viewer.separator.1", + "type": "separator", + "order": 180 }, { "id": "app.viewer.share", @@ -888,7 +881,7 @@ }, { "id": "app.viewer.share.edit", - "order": 201, + "order": 250, "title": "APP.ACTIONS.SHARE_EDIT", "icon": "link", "actions": { @@ -899,127 +892,141 @@ } }, { - "id": "app.viewer.fullscreen", - "order": 100, - "title": "APP.ACTIONS.FULLSCREEN", - "icon": "fullscreen", - "actions": { - "click": "FULLSCREEN_VIEWER" - }, - "rules": { - "visible": "app.toolbar.canViewFile" - } - }, - { - "id": "app.viewer.separator.1", - "type": "separator", - "order": 180 - } - ], - "toolbarMoreMenu": [ - { - "id": "app.viewer.favorite.add", - "order": 100, - "title": "APP.ACTIONS.FAVORITE", - "icon": "star_border", - "actions": { - "click": "ADD_FAVORITE" - }, - "rules": { - "visible": "app.toolbar.favorite.canAdd" - } - }, - { - "id": "app.viewer.favorite.remove", - "order": 200, - "title": "APP.ACTIONS.FAVORITE", - "icon": "star", + "id": "app.viewer.download", + "order": 300, + "title": "APP.ACTIONS.DOWNLOAD", + "icon": "get_app", "actions": { - "click": "REMOVE_FAVORITE" + "click": "DOWNLOAD_NODES" }, "rules": { - "visible": "app.toolbar.favorite.canRemove" - } - }, - { - "id": "app.viewer.favorite", - "comment": "workaround for Recent Files and Search API issue", - "type": "custom", - "order": 101, - "component": "app.toolbar.toggleFavorite", - "rules": { - "visible": "app.toolbar.favorite.canToggle" + "visible": "app.toolbar.canDownload" } }, { - "id": "app.viewer.more.separator.1", - "type": "separator", - "order": 280 - }, - { - "id": "app.viewer.copy", + "id": "app.viewer.print", "order": 400, - "title": "APP.ACTIONS.COPY", - "icon": "content_copy", - "actions": { - "click": "COPY_NODES" - }, - "rules": { - "visible": "app.toolbar.canCopyNode" - } - }, - { - "id": "app.viewer.move", - "order": 500, - "title": "APP.ACTIONS.MOVE", - "icon": "adf:move_file", - "actions": { - "click": "MOVE_NODES" - }, - "rules": { - "visible": "app.selection.canDelete" - } - }, - { - "id": "app.viewer.delete", - "order": 600, - "title": "APP.ACTIONS.DELETE", - "icon": "delete", - "actions": { - "click": "DELETE_NODES" - }, - "rules": { - "visible": "app.selection.canDelete" - } - }, - { - "id": "app.viewer.more.separator.2", - "type": "separator", - "order": 680 - }, - { - "id": "app.viewer.versions", - "order": 700, - "title": "APP.ACTIONS.VERSIONS", - "icon": "history", + "title": "APP.ACTIONS.PRINT", + "icon": "print", "actions": { - "click": "MANAGE_VERSIONS" + "click": "PRINT_FILE" }, "rules": { - "visible": "app.toolbar.versions" + "visible": "app.toolbar.canViewFile" } }, { - "id": "app.viewer.permissions", - "order": 800, - "title": "APP.ACTIONS.PERMISSIONS", - "icon": "settings_input_component", - "actions": { - "click": "MANAGE_PERMISSIONS" - }, - "rules": { - "visible": "app.toolbar.permissions" - } + "id": "app.viewer.toolbar.more", + "type": "menu", + "order": 10000, + "icon": "more_vert", + "title": "APP.ACTIONS.MORE", + "children": [ + { + "id": "app.viewer.favorite.add", + "order": 100, + "title": "APP.ACTIONS.FAVORITE", + "icon": "star_border", + "actions": { + "click": "ADD_FAVORITE" + }, + "rules": { + "visible": "app.toolbar.favorite.canAdd" + } + }, + { + "id": "app.viewer.favorite.remove", + "order": 200, + "title": "APP.ACTIONS.FAVORITE", + "icon": "star", + "actions": { + "click": "REMOVE_FAVORITE" + }, + "rules": { + "visible": "app.toolbar.favorite.canRemove" + } + }, + { + "id": "app.viewer.favorite", + "comment": "workaround for Recent Files and Search API issue", + "type": "custom", + "order": 101, + "component": "app.toolbar.toggleFavorite", + "rules": { + "visible": "app.toolbar.favorite.canToggle" + } + }, + { + "id": "app.viewer.more.separator.1", + "type": "separator", + "order": 280 + }, + { + "id": "app.viewer.copy", + "order": 400, + "title": "APP.ACTIONS.COPY", + "icon": "content_copy", + "actions": { + "click": "COPY_NODES" + }, + "rules": { + "visible": "app.toolbar.canCopyNode" + } + }, + { + "id": "app.viewer.move", + "order": 500, + "title": "APP.ACTIONS.MOVE", + "icon": "adf:move_file", + "actions": { + "click": "MOVE_NODES" + }, + "rules": { + "visible": "app.selection.canDelete" + } + }, + { + "id": "app.viewer.delete", + "order": 600, + "title": "APP.ACTIONS.DELETE", + "icon": "delete", + "actions": { + "click": "DELETE_NODES" + }, + "rules": { + "visible": "app.selection.canDelete" + } + }, + { + "id": "app.viewer.more.separator.2", + "type": "separator", + "order": 680 + }, + { + "id": "app.viewer.versions", + "order": 700, + "title": "APP.ACTIONS.VERSIONS", + "icon": "history", + "actions": { + "click": "MANAGE_VERSIONS" + }, + "rules": { + "visible": "app.toolbar.versions" + } + }, + { + "id": "app.viewer.permissions", + "order": 800, + "title": "APP.ACTIONS.PERMISSIONS", + "icon": "settings_input_component", + "actions": { + "click": "MANAGE_PERMISSIONS" + }, + "rules": { + "visible": "app.toolbar.permissions" + } + } + ] } ], "content": [ From afa6de5687a23d4822983184e82885188ed2cc96 Mon Sep 17 00:00:00 2001 From: Andy Stark <30621568+therealandeeee@users.noreply.github.com> Date: Mon, 21 Jan 2019 18:38:30 +0000 Subject: [PATCH 024/259] [ACA-2157] Added basic ABN metadata (#902) --- docs/README.md | 5 +++++ docs/extending/README.md | 2 ++ docs/extending/actions.md | 1 + docs/extending/application-actions.md | 1 + docs/extending/application-features.md | 1 + docs/extending/components.md | 1 + docs/extending/creating-custom-evaluators.md | 1 + docs/extending/extensibility-features.md | 1 + docs/extending/extension-format.md | 1 + docs/extending/icons.md | 4 ++++ docs/extending/redistributable-libraries.md | 1 + docs/extending/registration.md | 4 ++++ docs/extending/routes.md | 1 + docs/extending/rules.md | 1 + docs/extending/tutorials.md | 1 + docs/features/README.md | 2 ++ docs/features/document-list-layout.md | 1 + docs/features/file-viewer.md | 1 + docs/features/header.md | 1 + docs/features/info-drawer.md | 1 + docs/features/search-results.md | 1 + docs/features/side-navigation.md | 1 + docs/features/user-interface-layout.md | 1 + docs/features/version-manager.md | 1 + docs/getting-started/README.md | 2 ++ docs/getting-started/building-from-source.md | 1 + docs/getting-started/configuration.md | 1 + docs/getting-started/cors.md | 1 + docs/getting-started/docker.md | 1 + docs/getting-started/internationalization.md | 1 + docs/getting-started/navigation.md | 1 + docs/getting-started/prerequisites.md | 1 + docs/tutorials/README.md | 2 ++ docs/tutorials/custom-route-with-parameters.md | 1 + docs/tutorials/dialog-actions.md | 1 + docs/tutorials/introduction-to-extending.md | 1 + 36 files changed, 50 insertions(+) diff --git a/docs/README.md b/docs/README.md index 1dc9b6cea6..0831ddbfa4 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,3 +1,8 @@ +--- +Title: Alfresco Content Application +Github only: true +--- + # Alfresco Content Application diff --git a/docs/extending/README.md b/docs/extending/README.md index 5ed182648e..20c56a4a42 100644 --- a/docs/extending/README.md +++ b/docs/extending/README.md @@ -1,4 +1,6 @@ --- +Title: Extending +Github only: true --- # Extending diff --git a/docs/extending/actions.md b/docs/extending/actions.md index 4519889bdb..2151773e1e 100644 --- a/docs/extending/actions.md +++ b/docs/extending/actions.md @@ -1,4 +1,5 @@ --- +Title: Actions --- # Actions diff --git a/docs/extending/application-actions.md b/docs/extending/application-actions.md index 3210da661c..df939e0d4a 100644 --- a/docs/extending/application-actions.md +++ b/docs/extending/application-actions.md @@ -1,4 +1,5 @@ --- +Title: Application Actions --- # Application Actions diff --git a/docs/extending/application-features.md b/docs/extending/application-features.md index 73730fecb0..6aa5461813 100644 --- a/docs/extending/application-features.md +++ b/docs/extending/application-features.md @@ -1,4 +1,5 @@ --- +Title: Application Features --- # Application Features diff --git a/docs/extending/components.md b/docs/extending/components.md index e978a69d9c..1533f96518 100644 --- a/docs/extending/components.md +++ b/docs/extending/components.md @@ -1,4 +1,5 @@ --- +Title: Components --- # Components diff --git a/docs/extending/creating-custom-evaluators.md b/docs/extending/creating-custom-evaluators.md index 957dc54d47..a397d16502 100644 --- a/docs/extending/creating-custom-evaluators.md +++ b/docs/extending/creating-custom-evaluators.md @@ -1,4 +1,5 @@ --- +Title: Creating custom evaluators --- # Creating custom evaluators diff --git a/docs/extending/extensibility-features.md b/docs/extending/extensibility-features.md index 00c323ca94..22193d2c0a 100644 --- a/docs/extending/extensibility-features.md +++ b/docs/extending/extensibility-features.md @@ -1,4 +1,5 @@ --- +Title: Extensibility features --- # Extensibility features diff --git a/docs/extending/extension-format.md b/docs/extending/extension-format.md index ca78663654..b39e6383ad 100644 --- a/docs/extending/extension-format.md +++ b/docs/extending/extension-format.md @@ -1,4 +1,5 @@ --- +Title: Extension format --- # Extension format diff --git a/docs/extending/icons.md b/docs/extending/icons.md index 9903edb710..5bacc26a44 100644 --- a/docs/extending/icons.md +++ b/docs/extending/icons.md @@ -1,3 +1,7 @@ +--- +Title: Custom Icons +--- + # Custom Icons You can register and use custom `.svg` icons with toolbars, context menus, etc. diff --git a/docs/extending/redistributable-libraries.md b/docs/extending/redistributable-libraries.md index af848c211d..f73e8294da 100644 --- a/docs/extending/redistributable-libraries.md +++ b/docs/extending/redistributable-libraries.md @@ -1,4 +1,5 @@ --- +Title: Redistributable libraries --- # Redistributable libraries diff --git a/docs/extending/registration.md b/docs/extending/registration.md index d0afcecf48..6d4f1515ee 100644 --- a/docs/extending/registration.md +++ b/docs/extending/registration.md @@ -1,3 +1,7 @@ +--- +Title: Registration +--- + # Registration You can use `ExtensionService` to register custom components, authentication guards, diff --git a/docs/extending/routes.md b/docs/extending/routes.md index d72068ef43..05169ed102 100644 --- a/docs/extending/routes.md +++ b/docs/extending/routes.md @@ -1,4 +1,5 @@ --- +Title: Routes --- # Routes diff --git a/docs/extending/rules.md b/docs/extending/rules.md index fef4e91eba..1370c1e398 100644 --- a/docs/extending/rules.md +++ b/docs/extending/rules.md @@ -1,4 +1,5 @@ --- +Title: Rules --- # Rules diff --git a/docs/extending/tutorials.md b/docs/extending/tutorials.md index 7f1d7be4e3..e946e06b1e 100644 --- a/docs/extending/tutorials.md +++ b/docs/extending/tutorials.md @@ -1,4 +1,5 @@ --- +Title: Tutorials --- # Tutorials diff --git a/docs/features/README.md b/docs/features/README.md index 1f4a0bfc51..60ced23752 100644 --- a/docs/features/README.md +++ b/docs/features/README.md @@ -1,4 +1,6 @@ --- +Title: Application features +Github only: true --- # Application features diff --git a/docs/features/document-list-layout.md b/docs/features/document-list-layout.md index 1d1726cdb7..cf9cb4a715 100644 --- a/docs/features/document-list-layout.md +++ b/docs/features/document-list-layout.md @@ -1,4 +1,5 @@ --- +Title: Document List Layout --- # Document List Layout diff --git a/docs/features/file-viewer.md b/docs/features/file-viewer.md index a0dea420c5..998846f15a 100644 --- a/docs/features/file-viewer.md +++ b/docs/features/file-viewer.md @@ -1,4 +1,5 @@ --- +Title: File Viewer --- # File Viewer diff --git a/docs/features/header.md b/docs/features/header.md index 8f2953b05a..fa2c15ca73 100644 --- a/docs/features/header.md +++ b/docs/features/header.md @@ -1,4 +1,5 @@ --- +Title: Header --- # Header diff --git a/docs/features/info-drawer.md b/docs/features/info-drawer.md index 62aa2162b6..b10096d20e 100644 --- a/docs/features/info-drawer.md +++ b/docs/features/info-drawer.md @@ -1,4 +1,5 @@ --- +Title: Info Drawer --- # Info Drawer diff --git a/docs/features/search-results.md b/docs/features/search-results.md index 6c5aafe0b5..70772b2797 100644 --- a/docs/features/search-results.md +++ b/docs/features/search-results.md @@ -1,4 +1,5 @@ --- +Title: Search Results --- # Search Results diff --git a/docs/features/side-navigation.md b/docs/features/side-navigation.md index 4d5e4c14d8..bbe78d0d05 100644 --- a/docs/features/side-navigation.md +++ b/docs/features/side-navigation.md @@ -1,4 +1,5 @@ --- +Title: Side Navigation --- # Side Navigation diff --git a/docs/features/user-interface-layout.md b/docs/features/user-interface-layout.md index aa8f6b5b54..5d2f49d72a 100644 --- a/docs/features/user-interface-layout.md +++ b/docs/features/user-interface-layout.md @@ -1,4 +1,5 @@ --- +Title: User Interface - layout --- # User Interface - layout diff --git a/docs/features/version-manager.md b/docs/features/version-manager.md index 22dff20ec3..a397b5c006 100644 --- a/docs/features/version-manager.md +++ b/docs/features/version-manager.md @@ -1,4 +1,5 @@ --- +Title: Version Manager --- # Version Manager diff --git a/docs/getting-started/README.md b/docs/getting-started/README.md index e3ed3c9b62..486181fb08 100644 --- a/docs/getting-started/README.md +++ b/docs/getting-started/README.md @@ -1,4 +1,6 @@ --- +Title: Getting started +Github only: true --- # Getting started diff --git a/docs/getting-started/building-from-source.md b/docs/getting-started/building-from-source.md index 084b279229..bf535d4213 100644 --- a/docs/getting-started/building-from-source.md +++ b/docs/getting-started/building-from-source.md @@ -1,4 +1,5 @@ --- +Title: Building from source --- # Building from source diff --git a/docs/getting-started/configuration.md b/docs/getting-started/configuration.md index 98e331c988..04bb1fbdb3 100644 --- a/docs/getting-started/configuration.md +++ b/docs/getting-started/configuration.md @@ -1,4 +1,5 @@ --- +Title: Configuration --- # Configuration diff --git a/docs/getting-started/cors.md b/docs/getting-started/cors.md index 6396ce7f2f..07fae3339d 100644 --- a/docs/getting-started/cors.md +++ b/docs/getting-started/cors.md @@ -1,4 +1,5 @@ --- +Title: CORS --- # CORS diff --git a/docs/getting-started/docker.md b/docs/getting-started/docker.md index 8b3a0f6ed4..e52006ec16 100644 --- a/docs/getting-started/docker.md +++ b/docs/getting-started/docker.md @@ -1,4 +1,5 @@ --- +Title: Docker --- # Docker diff --git a/docs/getting-started/internationalization.md b/docs/getting-started/internationalization.md index b929d4b9dd..9d568d3556 100644 --- a/docs/getting-started/internationalization.md +++ b/docs/getting-started/internationalization.md @@ -1,4 +1,5 @@ --- +Title: Internationalization --- # Internationalization (i18n) diff --git a/docs/getting-started/navigation.md b/docs/getting-started/navigation.md index b6275c89d5..5ec08fb46f 100644 --- a/docs/getting-started/navigation.md +++ b/docs/getting-started/navigation.md @@ -1,4 +1,5 @@ --- +Title: Navigation --- # Navigation diff --git a/docs/getting-started/prerequisites.md b/docs/getting-started/prerequisites.md index bdb5dc7a97..e3fd3d00c6 100644 --- a/docs/getting-started/prerequisites.md +++ b/docs/getting-started/prerequisites.md @@ -1,4 +1,5 @@ --- +Title: Prerequisites --- # Prerequisites diff --git a/docs/tutorials/README.md b/docs/tutorials/README.md index 1758fcc80c..ba178af6da 100644 --- a/docs/tutorials/README.md +++ b/docs/tutorials/README.md @@ -1,4 +1,6 @@ --- +Title: Tutorials +Github only: true --- # Tutorials diff --git a/docs/tutorials/custom-route-with-parameters.md b/docs/tutorials/custom-route-with-parameters.md index cba3b730d7..eadb8ca9c2 100644 --- a/docs/tutorials/custom-route-with-parameters.md +++ b/docs/tutorials/custom-route-with-parameters.md @@ -1,4 +1,5 @@ --- +Title: Custom route with parameters --- # Custom route with parameters diff --git a/docs/tutorials/dialog-actions.md b/docs/tutorials/dialog-actions.md index 0773afe4b7..6d82285874 100644 --- a/docs/tutorials/dialog-actions.md +++ b/docs/tutorials/dialog-actions.md @@ -1,4 +1,5 @@ --- +Title: Dialog actions --- # Dialog actions diff --git a/docs/tutorials/introduction-to-extending.md b/docs/tutorials/introduction-to-extending.md index fb850d25ec..21a3eefc2c 100644 --- a/docs/tutorials/introduction-to-extending.md +++ b/docs/tutorials/introduction-to-extending.md @@ -1,4 +1,5 @@ --- +Title: Introduction to extending ACA --- # Introduction to extending the Alfresco Content Application From f0a3f6f63049c4265570843867d032a47ea329a0 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Tue, 22 Jan 2019 14:10:48 +0000 Subject: [PATCH 025/259] upgrade to latest JS-API and ADF (#896) * improved update script and latest ADF libs * upgrade to latest js-api and ADF * upgrade tests * update viewer code * use @alfresco/js-api * update to latest adf * fix deprecation issues * update viewer * fix copy/move dialog * change expect * fix remove site from favorites * fix unit test * update adf version * use ADF upload dialog --- e2e/suites/list-views/permissions.test.ts | 6 +- .../apis/favorites/favorites-api.ts | 16 +- .../repo-client/apis/nodes/nodes-api.ts | 33 ++- .../repo-client/apis/people/people-api.ts | 8 +- .../repo-client/apis/queries/queries-api.ts | 4 +- e2e/utilities/repo-client/apis/repo-api.ts | 15 +- .../repo-client/apis/search/search-api.ts | 8 +- .../apis/shared-links/shared-links-api.ts | 8 +- .../repo-client/apis/sites/sites-api.ts | 24 +- .../repo-client/apis/trashcan/trashcan-api.ts | 8 +- .../repo-client/apis/upload/upload-api.ts | 6 +- package-lock.json | 97 +++----- package.json | 9 +- scripts/update-version.sh | 107 ++------- src/app/app.component.ts | 2 +- src/app/components/about/about.component.ts | 2 +- .../module-list/module-list.component.ts | 2 +- src/app/components/common/common.module.ts | 10 +- .../common/icon/icon.component.html | 7 - .../common/icon/icon.component.scss | 4 - .../components/common/icon/icon.component.ts | 58 ----- .../location-link/location-link.component.ts | 2 +- .../favorite-libraries.component.spec.ts | 2 +- .../favorite-libraries.component.ts | 2 +- .../favorites/favorites.component.ts | 2 +- src/app/components/files/files.component.html | 2 +- .../components/files/files.component.spec.ts | 28 +-- src/app/components/files/files.component.ts | 2 +- .../comments-tab/comments-tab.component.ts | 2 +- .../info-drawer/info-drawer.component.spec.ts | 10 +- .../info-drawer/info-drawer.component.ts | 12 +- .../library-metadata-form.component.spec.ts | 2 +- .../library-metadata-form.component.ts | 6 +- .../library-metadata-tab.component.ts | 2 +- .../metadata-tab/metadata-tab.component.ts | 2 +- .../versions-tab/versions-tab.component.ts | 4 +- .../app-layout/app-layout.component.html | 4 +- .../app-layout/app-layout.component.spec.ts | 4 +- src/app/components/layout/layout.module.ts | 4 +- .../libraries/libraries.component.ts | 2 +- src/app/components/page.component.ts | 2 +- .../permission-manager.component.ts | 2 +- .../preview/preview-extension.component.ts | 2 +- .../components/preview/preview.component.html | 4 +- .../components/preview/preview.component.ts | 2 +- .../recent-files/recent-files.component.ts | 2 +- .../search-libraries-query-builder.service.ts | 2 +- .../search-libraries-results.component.ts | 2 +- .../search-results-row.component.ts | 2 +- .../search-results.component.ts | 2 +- .../components/settings/settings.component.ts | 10 +- .../content-node-share.dialog.ts | 2 +- .../file-uploading-dialog.component.html | 134 ----------- .../file-uploading-dialog.component.ts | 195 ---------------- .../file-uploading-list-row.component.html | 94 -------- .../file-uploading-list-row.component.ts | 47 ---- .../file-uploading-list.component.html | 4 - .../file-uploading-list.component.ts | 180 --------------- .../upload-dialog/upload-dialog.module.ts | 46 ---- .../node-versions/node-versions.dialog.ts | 2 +- src/app/directives/document-list.directive.ts | 2 +- .../library-favorite.directive.spec.ts | 4 +- .../directives/library-favorite.directive.ts | 4 +- .../library-membership.directive.ts | 2 +- .../extensions/evaluators/app.evaluators.ts | 2 +- src/app/services/content-api.service.ts | 12 +- .../content-management.service.spec.ts | 210 ++++++++++-------- .../services/content-management.service.ts | 18 +- src/app/services/data.service.ts | 2 +- src/app/services/node-actions.service.spec.ts | 8 +- src/app/services/node-actions.service.ts | 15 +- src/app/store/actions/app.actions.ts | 2 +- src/app/store/actions/favorite.actions.ts | 2 +- src/app/store/actions/library.actions.ts | 2 +- src/app/store/actions/node.actions.ts | 2 +- src/app/store/actions/router.actions.ts | 2 +- src/app/store/actions/viewer.actions.ts | 2 +- src/app/store/effects/download.effects.ts | 4 +- src/app/store/effects/library.effects.ts | 3 +- src/app/store/effects/router.effects.ts | 2 +- src/app/store/effects/viewer.effects.ts | 4 +- src/app/store/reducers/app.reducer.ts | 6 +- 82 files changed, 360 insertions(+), 1214 deletions(-) delete mode 100644 src/app/components/common/icon/icon.component.html delete mode 100644 src/app/components/common/icon/icon.component.scss delete mode 100644 src/app/components/common/icon/icon.component.ts delete mode 100644 src/app/components/upload-dialog/file-uploading-dialog.component.html delete mode 100644 src/app/components/upload-dialog/file-uploading-dialog.component.ts delete mode 100644 src/app/components/upload-dialog/file-uploading-list-row.component.html delete mode 100644 src/app/components/upload-dialog/file-uploading-list-row.component.ts delete mode 100644 src/app/components/upload-dialog/file-uploading-list.component.html delete mode 100644 src/app/components/upload-dialog/file-uploading-list.component.ts delete mode 100644 src/app/components/upload-dialog/upload-dialog.module.ts diff --git a/e2e/suites/list-views/permissions.test.ts b/e2e/suites/list-views/permissions.test.ts index a4e1fb82e9..b10e9d1f87 100755 --- a/e2e/suites/list-views/permissions.test.ts +++ b/e2e/suites/list-views/permissions.test.ts @@ -84,7 +84,7 @@ describe('Special permissions', () => { expect(await dataTable.countRows()).toBe(1, 'Incorrect number of items'); await apis.admin.sites.deleteSiteMember(sitePrivate, username); await page.refresh(); - expect(await dataTable.countRows()).toBe(0, 'Incorrect number of items'); + expect(await dataTable.isEmptyList()).toBe(true, 'Items are still displayed'); }); it('on Favorites - [C213227]', async () => { @@ -92,7 +92,7 @@ describe('Special permissions', () => { expect(await dataTable.countRows()).toBe(1, 'Incorrect number of items'); await apis.admin.sites.deleteSiteMember(sitePrivate, username); await page.refresh(); - expect(await dataTable.countRows()).toBe(0, 'Incorrect number of items'); + expect(await dataTable.isEmptyList()).toBe(true, 'Items are still displayed'); }); it('on Shared Files - [C213116]', async () => { @@ -100,7 +100,7 @@ describe('Special permissions', () => { expect(await dataTable.countRows()).toBe(1, 'Incorrect number of items'); await apis.admin.sites.deleteSiteMember(sitePrivate, username); await page.refresh(); - expect(await dataTable.countRows()).toBe(0, 'Incorrect number of items'); + expect(await dataTable.isEmptyList()).toBe(true, 'Items are still displayed'); }); }); diff --git a/e2e/utilities/repo-client/apis/favorites/favorites-api.ts b/e2e/utilities/repo-client/apis/favorites/favorites-api.ts index 2c5239a501..d303139736 100755 --- a/e2e/utilities/repo-client/apis/favorites/favorites-api.ts +++ b/e2e/utilities/repo-client/apis/favorites/favorites-api.ts @@ -26,8 +26,11 @@ import { RepoApi } from '../repo-api'; import { RepoClient } from './../../repo-client'; import { Utils } from '../../../../utilities/utils'; +import { FavoritesApi as AdfFavoritesApi, SitesApi as AdfSiteApi } from '@alfresco/js-api'; export class FavoritesApi extends RepoApi { + favoritesApi = new AdfFavoritesApi(this.alfrescoJsApi); + sitesApi = new AdfSiteApi(this.alfrescoJsApi); constructor(username?, password?) { super(username, password); @@ -42,7 +45,7 @@ export class FavoritesApi extends RepoApi { } } }; - return await this.alfrescoJsApi.core.favoritesApi.addFavorite('-me-', data); + return await this.favoritesApi.createFavorite('-me-', data); } async addFavoriteById(nodeType: 'file' | 'folder' | 'site', id: string) { @@ -50,7 +53,7 @@ export class FavoritesApi extends RepoApi { await this.apiAuth(); if ( nodeType === 'site' ) { - guid = (await this.alfrescoJsApi.core.sitesApi.getSite(id)).entry.guid; + guid = (await this.sitesApi.getSite(id)).entry.guid; } else { guid = id; } @@ -62,7 +65,7 @@ export class FavoritesApi extends RepoApi { } }; try { - return await this.alfrescoJsApi.core.favoritesApi.addFavorite('-me-', data); + return await this.favoritesApi.createFavorite('-me-', data); } catch (error) { // console.log('--- add favorite by id catch '); } @@ -77,12 +80,12 @@ export class FavoritesApi extends RepoApi { async getFavorites() { await this.apiAuth(); - return await this.alfrescoJsApi.core.favoritesApi.getFavorites(this.getUsername()); + return await this.favoritesApi.listFavorites(this.getUsername()); } async getFavoriteById(nodeId: string) { await this.apiAuth(); - return await this.alfrescoJsApi.core.favoritesApi.getFavorite('-me-', nodeId); + return await this.favoritesApi.getFavorite('-me-', nodeId); } async isFavorite(nodeId: string) { @@ -111,7 +114,7 @@ export class FavoritesApi extends RepoApi { async removeFavoriteById(nodeId: string) { await this.apiAuth(); try { - return await this.alfrescoJsApi.core.peopleApi.removeFavoriteSite('-me-', nodeId); + return await this.favoritesApi.deleteSiteFavorite('-me-', nodeId); } catch (error) { // console.log('--- remove favorite by id catch '); } @@ -139,6 +142,5 @@ export class FavoritesApi extends RepoApi { } catch (error) { console.log('-----> catch favorites: ', error); } - } } diff --git a/e2e/utilities/repo-client/apis/nodes/nodes-api.ts b/e2e/utilities/repo-client/apis/nodes/nodes-api.ts index 9f04bd18fc..63304ea7a8 100755 --- a/e2e/utilities/repo-client/apis/nodes/nodes-api.ts +++ b/e2e/utilities/repo-client/apis/nodes/nodes-api.ts @@ -23,27 +23,26 @@ * along with Alfresco. If not, see . */ -import { NodeBodyLock } from 'alfresco-js-api-node'; import { RepoApi } from '../repo-api'; import { NodeBodyCreate } from './node-body-create'; import { NodeContentTree, flattenNodeContentTree } from './node-content-tree'; +import { NodesApi as AdfNodeApi, NodeBodyLock} from '@alfresco/js-api'; export class NodesApi extends RepoApi { + nodesApi = new AdfNodeApi(this.alfrescoJsApi); constructor(username?, password?) { super(username, password); } - // nodes - async getNodeByPath(relativePath: string = '/') { await this.apiAuth(); - return await this.alfrescoJsApi.core.nodesApi.getNode('-my-', { relativePath }); + return await this.nodesApi.getNode('-my-', { relativePath }); } async getNodeById(id: string) { await this.apiAuth(); - return await this.alfrescoJsApi.core.nodesApi.getNode(id); + return await this.nodesApi.getNode(id); } async getNodeDescription(name: string, parentId: string) { @@ -75,7 +74,7 @@ export class NodesApi extends RepoApi { async deleteNodeById(id: string, permanent: boolean = true) { await this.apiAuth(); try { - return await this.alfrescoJsApi.core.nodesApi.deleteNode(id, { permanent }); + return await this.nodesApi.deleteNode(id, { permanent }); } catch (error) { console.log('------ deleteNodeById failed '); } @@ -100,14 +99,12 @@ export class NodesApi extends RepoApi { }, Promise.resolve()); } - // children - async getNodeChildren(nodeId: string) { const opts = { include: [ 'properties' ] }; await this.apiAuth(); - return await this.alfrescoJsApi.core.nodesApi.getNodeChildren(nodeId, opts); + return await this.nodesApi.listNodeChildren(nodeId, opts); } async deleteNodeChildren(parentId: string) { @@ -138,7 +135,7 @@ export class NodesApi extends RepoApi { } await this.apiAuth(); - return await this.alfrescoJsApi.core.nodesApi.addNode(parentId, nodeBody); + return await this.nodesApi.createNode(parentId, nodeBody); } async createFile(name: string, parentId: string = '-my-', title: string = '', description: string = '') { @@ -155,7 +152,7 @@ export class NodesApi extends RepoApi { async createChildren(data: NodeBodyCreate[]): Promise { await this.apiAuth(); - return await this.alfrescoJsApi.core.nodesApi.addNode('-my-', data); + return await this.nodesApi.createNode('-my-', data); } async createContent(content: NodeContentTree, relativePath: string = '/') { @@ -173,17 +170,17 @@ export class NodesApi extends RepoApi { // node content async getNodeContent(nodeId: string) { await this.apiAuth(); - return await this.alfrescoJsApi.core.nodesApi.getNodeContent(nodeId); + return await this.nodesApi.getNodeContent(nodeId); } async editNodeContent(nodeId: string, content: string) { await this.apiAuth(); - return await this.alfrescoJsApi.core.nodesApi.updateNodeContent(nodeId, content); + return await this.nodesApi.updateNodeContent(nodeId, content); } async renameNode(nodeId: string, newName: string) { await this.apiAuth(); - return this.alfrescoJsApi.core.nodesApi.updateNode(nodeId, { name: newName }); + return this.nodesApi.updateNode(nodeId, { name: newName }); } // node permissions @@ -201,12 +198,12 @@ export class NodesApi extends RepoApi { }; await this.apiAuth(); - return await this.alfrescoJsApi.core.nodesApi.updateNode(nodeId, data); + return await this.nodesApi.updateNode(nodeId, data); } async getNodePermissions(nodeId: string) { await this.apiAuth(); - return await this.alfrescoJsApi.core.nodesApi.getNode(nodeId, { include: ['permissions'] }); + return await this.nodesApi.getNode(nodeId, { include: ['permissions'] }); } // lock node @@ -215,11 +212,11 @@ export class NodesApi extends RepoApi { type: lockType }; await this.apiAuth(); - return await this.alfrescoJsApi.core.nodesApi.lockNode(nodeId, data ); + return await this.nodesApi.lockNode(nodeId, data ); } async unlockFile(nodeId: string) { await this.apiAuth(); - return await this.alfrescoJsApi.core.nodesApi.unlockNode(nodeId); + return await this.nodesApi.unlockNode(nodeId); } } diff --git a/e2e/utilities/repo-client/apis/people/people-api.ts b/e2e/utilities/repo-client/apis/people/people-api.ts index f6a7af8b11..9715423053 100755 --- a/e2e/utilities/repo-client/apis/people/people-api.ts +++ b/e2e/utilities/repo-client/apis/people/people-api.ts @@ -25,8 +25,10 @@ import { PersonModel, Person } from './people-api-models'; import { RepoApi } from '../repo-api'; +import { PeopleApi as AdfPeopleApi} from '@alfresco/js-api'; export class PeopleApi extends RepoApi { + peopleApi = new AdfPeopleApi(this.alfrescoJsApi); constructor(username?, password?) { super(username, password); @@ -35,17 +37,17 @@ export class PeopleApi extends RepoApi { async createUser(user: PersonModel) { const person = new Person(user); await this.apiAuth(); - return await this.alfrescoJsApi.core.peopleApi.addPerson(person); + return await this.peopleApi.createPerson(person); } async getUser(username: string) { await this.apiAuth(); - return await this.alfrescoJsApi.core.peopleApi.getPerson(username); + return await this.peopleApi.getPerson(username); } async updateUser(username: string, userDetails?: PersonModel) { await this.apiAuth(); - return this.alfrescoJsApi.core.peopleApi.updatePerson(username, userDetails); + return this.peopleApi.updatePerson(username, userDetails); } async disableUser(username: string) { diff --git a/e2e/utilities/repo-client/apis/queries/queries-api.ts b/e2e/utilities/repo-client/apis/queries/queries-api.ts index e2ce4ef675..c181e173bf 100755 --- a/e2e/utilities/repo-client/apis/queries/queries-api.ts +++ b/e2e/utilities/repo-client/apis/queries/queries-api.ts @@ -25,8 +25,10 @@ import { RepoApi } from '../repo-api'; import { Utils } from '../../../../utilities/utils'; +import { QueriesApi as AdfQueriesApi } from '@alfresco/js-api'; export class QueriesApi extends RepoApi { + queriesApi = new AdfQueriesApi(this.alfrescoJsApi); constructor(username?, password?) { super(username, password); @@ -39,7 +41,7 @@ export class QueriesApi extends RepoApi { }; await this.apiAuth(); - return this.alfrescoJsApi.core.queriesApi.findSites(searchTerm, data); + return this.queriesApi.findSites(searchTerm, data); } async findNodes(searchTerm: string) { diff --git a/e2e/utilities/repo-client/apis/repo-api.ts b/e2e/utilities/repo-client/apis/repo-api.ts index e90596a82b..7e6b5a32fd 100644 --- a/e2e/utilities/repo-client/apis/repo-api.ts +++ b/e2e/utilities/repo-client/apis/repo-api.ts @@ -23,21 +23,22 @@ * along with Alfresco. If not, see . */ -import * as AlfrescoApi from 'alfresco-js-api-node'; +import { AlfrescoApi } from '@alfresco/js-api'; import { REPO_API_HOST } from '../../../configs'; import { RepoClientAuth } from '../repo-client-models'; export abstract class RepoApi { - - alfrescoJsApi = new AlfrescoApi({ - provider: 'ECM', - hostEcm: REPO_API_HOST - }); + alfrescoJsApi = new AlfrescoApi(); constructor( private username: string = RepoClientAuth.DEFAULT_USERNAME, private password: string = RepoClientAuth.DEFAULT_PASSWORD - ) {} + ) { + this.alfrescoJsApi.setConfig({ + provider: 'ECM', + hostEcm: REPO_API_HOST + }); + } apiAuth() { return this.alfrescoJsApi.login(this.username, this.password); diff --git a/e2e/utilities/repo-client/apis/search/search-api.ts b/e2e/utilities/repo-client/apis/search/search-api.ts index 135d2006b4..2ff6d31610 100755 --- a/e2e/utilities/repo-client/apis/search/search-api.ts +++ b/e2e/utilities/repo-client/apis/search/search-api.ts @@ -25,8 +25,10 @@ import { RepoApi } from '../repo-api'; import { Utils } from '../../../../utilities/utils'; +import { SearchApi as AdfSearchApi } from '@alfresco/js-api'; export class SearchApi extends RepoApi { + searchApi = new AdfSearchApi(this.alfrescoJsApi); constructor(username?, password?) { super(username, password); @@ -46,7 +48,7 @@ export class SearchApi extends RepoApi { }; await this.apiAuth(); - return this.alfrescoJsApi.search.searchApi.search(data); + return this.searchApi.search(data); } async queryNodesNames(searchTerm: string) { @@ -61,7 +63,7 @@ export class SearchApi extends RepoApi { }; await this.apiAuth(); - return this.alfrescoJsApi.search.searchApi.search(data); + return this.searchApi.search(data); } async queryNodesExactNames(searchTerm: string) { @@ -76,7 +78,7 @@ export class SearchApi extends RepoApi { }; await this.apiAuth(); - return this.alfrescoJsApi.search.searchApi.search(data); + return this.searchApi.search(data); } async waitForApi(username, data) { diff --git a/e2e/utilities/repo-client/apis/shared-links/shared-links-api.ts b/e2e/utilities/repo-client/apis/shared-links/shared-links-api.ts index 09b0882231..4f4e258930 100755 --- a/e2e/utilities/repo-client/apis/shared-links/shared-links-api.ts +++ b/e2e/utilities/repo-client/apis/shared-links/shared-links-api.ts @@ -25,8 +25,10 @@ import { RepoApi } from '../repo-api'; import { Utils } from '../../../../utilities/utils'; +import { SharedlinksApi as AdfSharedlinksApi } from '@alfresco/js-api'; export class SharedLinksApi extends RepoApi { + sharedlinksApi = new AdfSharedlinksApi(this.alfrescoJsApi); constructor(username?, password?) { super(username, password); @@ -39,7 +41,7 @@ export class SharedLinksApi extends RepoApi { nodeId: id, expiresAt: expireDate }; - return await this.alfrescoJsApi.core.sharedlinksApi.addSharedLink(data); + return await this.sharedlinksApi.createSharedLink(data); } catch (error) { console.log('---- shareFileById error: ', error); } @@ -60,12 +62,12 @@ export class SharedLinksApi extends RepoApi { async unshareFile(name: string) { const id = await this.getSharedIdOfNode(name); - return await this.alfrescoJsApi.core.sharedlinksApi.deleteSharedLink(id); + return await this.sharedlinksApi.deleteSharedLink(id); } async getSharedLinks() { await this.apiAuth(); - return await this.alfrescoJsApi.core.sharedlinksApi.findSharedLinks(); + return await this.sharedlinksApi.listSharedLinks(); } async waitForApi(data) { diff --git a/e2e/utilities/repo-client/apis/sites/sites-api.ts b/e2e/utilities/repo-client/apis/sites/sites-api.ts index 6bb05507af..1809baeab5 100755 --- a/e2e/utilities/repo-client/apis/sites/sites-api.ts +++ b/e2e/utilities/repo-client/apis/sites/sites-api.ts @@ -24,11 +24,13 @@ */ import { RepoApi } from '../repo-api'; -import { SiteBody, SiteMemberRoleBody, SiteMemberBody } from 'alfresco-js-api-node'; +import { SiteBody, SiteMemberRoleBody, SiteMemberBody } from '@alfresco/js-api'; import { SITE_VISIBILITY } from '../../../../configs'; import { Utils } from '../../../../utilities/utils'; +import { SitesApi as AdfSiteApi } from '@alfresco/js-api'; export class SitesApi extends RepoApi { + sitesApi = new AdfSiteApi(this.alfrescoJsApi); constructor(username?, password?) { super(username, password); @@ -36,17 +38,17 @@ export class SitesApi extends RepoApi { async getSite(siteId: string) { await this.apiAuth(); - return await this.alfrescoJsApi.core.sitesApi.getSite(siteId); + return await this.sitesApi.getSite(siteId); } async getSites() { await this.apiAuth(); - return await this.alfrescoJsApi.core.peopleApi.getSiteMembership(this.getUsername()); + return await this.sitesApi.listSiteMembershipsForPerson(this.getUsername()); } async getDocLibId(siteId: string) { await this.apiAuth(); - return (await this.alfrescoJsApi.core.sitesApi.getSiteContainers(siteId)).list.entries[0].entry.id; + return (await this.sitesApi.listSiteContainers(siteId)).list.entries[0].entry.id; } async getVisibility(siteId: string) { @@ -73,7 +75,7 @@ export class SitesApi extends RepoApi { }; await this.apiAuth(); - return await this.alfrescoJsApi.core.sitesApi.createSite(site); + return await this.sitesApi.createSite(site); } async createSites(titles: string[], visibility?: string) { @@ -85,7 +87,7 @@ export class SitesApi extends RepoApi { async deleteSite(siteId: string, permanent: boolean = true) { await this.apiAuth(); - return await this.alfrescoJsApi.core.sitesApi.deleteSite(siteId, { permanent }); + return await this.sitesApi.deleteSite(siteId, { permanent }); } async deleteSites(siteIds: string[], permanent: boolean = true) { @@ -110,7 +112,7 @@ export class SitesApi extends RepoApi { }; await this.apiAuth(); - return await this.alfrescoJsApi.core.sitesApi.updateSiteMember(siteId, userId, siteRole); + return await this.sitesApi.updateSiteMembership(siteId, userId, siteRole); } async addSiteMember(siteId: string, userId: string, role: string) { @@ -120,12 +122,12 @@ export class SitesApi extends RepoApi { }; await this.apiAuth(); - return await this.alfrescoJsApi.core.sitesApi.addSiteMember(siteId, memberBody); + return await this.sitesApi.createSiteMembership(siteId, memberBody); } async deleteSiteMember(siteId: string, userId: string) { await this.apiAuth(); - return await this.alfrescoJsApi.core.sitesApi.removeSiteMember(siteId, userId); + return await this.sitesApi.deleteSiteMembership(siteId, userId); } async requestToJoin(siteId: string) { @@ -134,7 +136,7 @@ export class SitesApi extends RepoApi { }; await this.apiAuth(); try { - return await this.alfrescoJsApi.core.peopleApi.addSiteMembershipRequest('-me-', body); + return await this.sitesApi.createSiteMembershipRequestForPerson('-me-', body); } catch (error) { console.log('====== requestToJoin catch ', error); }; @@ -142,7 +144,7 @@ export class SitesApi extends RepoApi { async hasMembershipRequest(siteId: string) { await this.apiAuth(); - const requests = (await this.alfrescoJsApi.core.peopleApi.getSiteMembershipRequests('-me-')).list.entries.map(e => e.entry.id); + const requests = (await this.sitesApi.getSiteMembershipRequests('-me-')).list.entries.map(e => e.entry.id); return requests.includes(siteId); } diff --git a/e2e/utilities/repo-client/apis/trashcan/trashcan-api.ts b/e2e/utilities/repo-client/apis/trashcan/trashcan-api.ts index 6c6a25e6d3..86174f2041 100644 --- a/e2e/utilities/repo-client/apis/trashcan/trashcan-api.ts +++ b/e2e/utilities/repo-client/apis/trashcan/trashcan-api.ts @@ -25,8 +25,10 @@ import { RepoApi } from '../repo-api'; import { Utils } from '../../../../utilities/utils'; +import { TrashcanApi as AdfTrashcanApi} from '@alfresco/js-api'; export class TrashcanApi extends RepoApi { + trashcanApi = new AdfTrashcanApi(this.alfrescoJsApi); constructor(username?, password?) { super(username, password); @@ -34,12 +36,12 @@ export class TrashcanApi extends RepoApi { async permanentlyDelete(id: string) { await this.apiAuth(); - return await this.alfrescoJsApi.core.nodesApi.purgeDeletedNode(id); + return await this.trashcanApi.deleteDeletedNode(id); } async restore(id: string) { await this.apiAuth(); - return await this.alfrescoJsApi.core.nodesApi.restoreNode(id); + return await this.trashcanApi.restoreDeletedNode(id); } async getDeletedNodes() { @@ -47,7 +49,7 @@ export class TrashcanApi extends RepoApi { maxItems: 1000 }; await this.apiAuth(); - return await this.alfrescoJsApi.core.nodesApi.getDeletedNodes(opts); + return await this.trashcanApi.listDeletedNodes(opts); } async emptyTrash() { diff --git a/e2e/utilities/repo-client/apis/upload/upload-api.ts b/e2e/utilities/repo-client/apis/upload/upload-api.ts index ca8762aea9..bf83dbd011 100644 --- a/e2e/utilities/repo-client/apis/upload/upload-api.ts +++ b/e2e/utilities/repo-client/apis/upload/upload-api.ts @@ -25,10 +25,12 @@ import { RepoApi } from '../repo-api'; import { E2E_ROOT_PATH } from '../../../../configs'; +import { UploadApi as AdfUploadApi } from '@alfresco/js-api'; const fs = require('fs'); export class UploadApi extends RepoApi { + upload = new AdfUploadApi(this.alfrescoJsApi); constructor(username?, password?) { super(username, password); @@ -42,7 +44,7 @@ export class UploadApi extends RepoApi { }; await this.apiAuth(); - return await this.alfrescoJsApi.upload.uploadFile(file, '', parentFolderId, null, opts); + return await this.upload.uploadFile(file, '', parentFolderId, null, opts); } async uploadFileWithRename(fileName: string, parentFolderId: string = '-my-', newName: string) { @@ -53,7 +55,7 @@ export class UploadApi extends RepoApi { }; await this.apiAuth(); - return await this.alfrescoJsApi.upload.uploadFile(file, '', parentFolderId, null, opts); + return await this.upload.uploadFile(file, '', parentFolderId, null, opts); } } diff --git a/package-lock.json b/package-lock.json index fb1eb8259c..880c9e5d17 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,29 +5,38 @@ "requires": true, "dependencies": { "@alfresco/adf-content-services": { - "version": "3.0.0-dd25467a98fad2898a2b71d07fa50bb175cea81c", - "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-3.0.0-dd25467a98fad2898a2b71d07fa50bb175cea81c.tgz", - "integrity": "sha512-lzR6pL/563J9IcSXR/X6p2lqFVMRADrnDglAHk4a1k58QBypfIFsmbLX8h9acMhAn/DydEgjQ6pXxLRuxoVLFg==", + "version": "3.0.0-7c66589b26e57061a07a8d38bfebc2ee05fb1b83", + "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-3.0.0-7c66589b26e57061a07a8d38bfebc2ee05fb1b83.tgz", + "integrity": "sha512-1Cca7AG8vH+U15k125PCiKdTRYb6uQd29x4Idle48urDFUpkUXBF3elnR15CWCwBuw+Idl0HVogAIIbbKsP2CQ==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/adf-core": { - "version": "3.0.0-dd25467a98fad2898a2b71d07fa50bb175cea81c", - "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-3.0.0-dd25467a98fad2898a2b71d07fa50bb175cea81c.tgz", - "integrity": "sha512-Dj+mef9GUpyn1eMM6ZgMDqEH+rAZxGb4Xgw01lbZA40XhW3lRqlkh1SwuTBSlNYN8RwTlNJVKb/nT9hpaR1Kag==", + "version": "3.0.0-7c66589b26e57061a07a8d38bfebc2ee05fb1b83", + "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-3.0.0-7c66589b26e57061a07a8d38bfebc2ee05fb1b83.tgz", + "integrity": "sha512-s5E3dAgb7pkB6JP/EjOTlWvddjuykTqR4WxUsVQahGkPYqg7O2PkvkElIVeeerB/oBjXYW1LY8p5HUCZoIiqGg==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/adf-extensions": { - "version": "3.0.0-dd25467a98fad2898a2b71d07fa50bb175cea81c", - "resolved": "https://registry.npmjs.org/@alfresco/adf-extensions/-/adf-extensions-3.0.0-dd25467a98fad2898a2b71d07fa50bb175cea81c.tgz", - "integrity": "sha512-gEaOWVUmG9OqmcNXjTJYk/IG7T6As4SGuHc3veCNPnikf41yrkQ86/eS4iIWuCC3z/dv+ejZT7x5PVRhAvuXBw==", + "version": "3.0.0-7c66589b26e57061a07a8d38bfebc2ee05fb1b83", + "resolved": "https://registry.npmjs.org/@alfresco/adf-extensions/-/adf-extensions-3.0.0-7c66589b26e57061a07a8d38bfebc2ee05fb1b83.tgz", + "integrity": "sha512-he7h49WJeEIv2lVNblVDzRvdKoJmvdf33KDpv078r/JAkd7cAbueOtUKJtYSQWsqDs2e041Q2PXJOQz2sfmJew==", "requires": { "tslib": "^1.9.0" } }, + "@alfresco/js-api": { + "version": "3.0.0-e9c8ed80decc71d2fc6833cef22851b64ce4b604", + "resolved": "https://registry.npmjs.org/@alfresco/js-api/-/js-api-3.0.0-e9c8ed80decc71d2fc6833cef22851b64ce4b604.tgz", + "integrity": "sha512-EgCTW+ZOJGvxVUFu5Ul8e0vnW1aITuxTgOKk5AGMFW4JxJoFqEYuo77oqXJITE/1JFsyeuqG63oOjQs2NDjHHw==", + "requires": { + "event-emitter": "0.3.4", + "superagent": "3.8.2" + } + }, "@angular-devkit/architect": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.11.0.tgz", @@ -3076,31 +3085,11 @@ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz", "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=" }, - "alfresco-js-api": { - "version": "3.0.0-beta7", - "resolved": "https://registry.npmjs.org/alfresco-js-api/-/alfresco-js-api-3.0.0-beta7.tgz", - "integrity": "sha512-gpIi2+zcSkkrccRJDxqFP0HrO525GdylGr3elLysmUQH1NMROWMGjbpcZbmQEsWR0eIunQPPxbvYq2lzwgomog==", - "requires": { - "event-emitter": "0.3.4", - "superagent": "3.8.2" - } - }, - "alfresco-js-api-node": { - "version": "3.0.0-beta6", - "resolved": "https://registry.npmjs.org/alfresco-js-api-node/-/alfresco-js-api-node-3.0.0-beta6.tgz", - "integrity": "sha512-tKy+D4feKvtsKb6X/g1SRFmVMBKcJenWCZ6ejPwaQLw1t+jn+iBTnRsrGWJ2bGowhDUIIvB1D+X+Wt/ZbU0R6g==", - "dev": true, - "requires": { - "event-emitter": "0.3.4", - "superagent": "3.8.2" - } - }, "align-text": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", "dev": true, - "optional": true, "requires": { "kind-of": "^3.0.2", "longest": "^1.0.1", @@ -5673,9 +5662,9 @@ } }, "es5-ext": { - "version": "0.10.46", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.46.tgz", - "integrity": "sha512-24XxRvJXNFwEMpJb3nOkiRJKRoupmjYmOPVlI65Qy2SrtxwOTB+g6ODjBKOtwEHbYrhWRty9xxOWLNdClT2djw==", + "version": "0.10.47", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.47.tgz", + "integrity": "sha512-/1TItLfj+TTfWoeRcDn/0FbGV6SNo4R+On2GGVucPU/j3BWnXE2Co8h8CTo4Tu34gFJtnmwS9xiScKs4EjZhdw==", "requires": { "es6-iterator": "~2.0.3", "es6-symbol": "~3.1.1", @@ -6444,8 +6433,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, - "optional": true + "dev": true }, "aproba": { "version": "1.2.0", @@ -6469,15 +6457,13 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -6494,22 +6480,19 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -6640,8 +6623,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -6655,7 +6637,6 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -6672,7 +6653,6 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -6681,15 +6661,13 @@ "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true, - "optional": true + "dev": true }, "minipass": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.2.4.tgz", "integrity": "sha512-hzXIWWet/BzWhYs2b+u7dRHlruXhwdgvlTMDKC6Cb1U7ps6Ac6yQlR39xsbjWJE377YTCtKwIXIpJ5oP+j5y8g==", "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -6710,7 +6688,6 @@ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -6799,8 +6776,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -6814,7 +6790,6 @@ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -6910,8 +6885,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", - "dev": true, - "optional": true + "dev": true }, "safer-buffer": { "version": "2.1.2", @@ -6953,7 +6927,6 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -6975,7 +6948,6 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -7024,15 +6996,13 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true, - "optional": true + "dev": true }, "yallist": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.2.tgz", "integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=", - "dev": true, - "optional": true + "dev": true } } }, @@ -10386,8 +10356,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", - "dev": true, - "optional": true + "dev": true }, "loose-envify": { "version": "1.4.0", diff --git a/package.json b/package.json index 2ee7944f24..ec00e164fc 100644 --- a/package.json +++ b/package.json @@ -32,9 +32,10 @@ }, "private": true, "dependencies": { - "@alfresco/adf-content-services": "3.0.0-dd25467a98fad2898a2b71d07fa50bb175cea81c", - "@alfresco/adf-core": "3.0.0-dd25467a98fad2898a2b71d07fa50bb175cea81c", - "@alfresco/adf-extensions": "3.0.0-dd25467a98fad2898a2b71d07fa50bb175cea81c", + "@alfresco/adf-content-services": "3.0.0-7c66589b26e57061a07a8d38bfebc2ee05fb1b83", + "@alfresco/adf-core": "3.0.0-7c66589b26e57061a07a8d38bfebc2ee05fb1b83", + "@alfresco/adf-extensions": "3.0.0-7c66589b26e57061a07a8d38bfebc2ee05fb1b83", + "@alfresco/js-api": "3.0.0-e9c8ed80decc71d2fc6833cef22851b64ce4b604", "@angular/animations": "7.1.4", "@angular/cdk": "^7.2.0", "@angular/common": "7.1.4", @@ -55,7 +56,6 @@ "@ngrx/store": "^7.0.0", "@ngrx/store-devtools": "^7.0.0", "@ngx-translate/core": "^10.0.2", - "alfresco-js-api": "3.0.0-beta7", "core-js": "^2.5.7", "hammerjs": "2.0.8", "minimatch-browser": "^1.0.0", @@ -75,7 +75,6 @@ "@types/jasminewd2": "^2.0.2", "@types/node": "9.3.0", "@types/selenium-webdriver": "^3.0.8", - "alfresco-js-api-node": "3.0.0-beta6", "chrome-remote-interface": "^0.26.1", "codelyzer": "^4.5.0", "cspell": "^3.1.3", diff --git a/scripts/update-version.sh b/scripts/update-version.sh index 6c03c0d3d0..22d0762c30 100755 --- a/scripts/update-version.sh +++ b/scripts/update-version.sh @@ -1,104 +1,45 @@ #!/usr/bin/env bash DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -eval JS_API=true eval GNU=false -eval EXEC_COMPONENT=true -eval DIFFERENT_JS_API=false -eval AUTO=false -eval libs=( "core" - "content-services" - "extensions" - #"process-services" - #"insights" +eval libs=( "@alfresco/adf-core" + "@alfresco/adf-content-services" + "@alfresco/adf-extensions" + "@alfresco/js-api" ) cd ${DIR}/.. -prefix="@alfresco/adf-" - show_help() { - echo "Usage: update-version.sh" + echo "Usage: update-version.sh -v latest" echo "" - echo "-sj or -sjsapi don't update js-api version" - echo "-vj or -versionjsapi to use a different version of js-api" - echo "-v or -version version to update" - echo "-alpha update last alpha version of js-api and lib automatically" - echo "-beta update beta alpha version of js-api and lib automatically" + echo "-v or -version the new version of the libraries, can also be alpha|beta|latest" echo "-gnu for gnu" } -skip_js() { - echo "====== Skip JS-API change version $1 =====" - JS_API=false -} - -last_alpha_mode() { - echo "====== Auto find last ALPHA version =====" - VERSION=$(npm view @alfresco/adf-core@alpha version) - - echo "====== version lib ${VERSION} =====" - - DIFFERENT_JS_API=true - VERSION_JS_API=$(npm view alfresco-js-api@alpha version) - - echo "====== version js-api ${DIFFERENT_JS_API} =====" -} - -last_beta_mode() { - echo "====== Auto find last BETA version =====" - VERSION=$(npm view @alfresco/adf-core@beta version) - - echo "====== version lib ${VERSION} =====" - - DIFFERENT_JS_API=true - VERSION_JS_API=$(npm view alfresco-js-api@beta version) - - echo "====== version js-api ${DIFFERENT_JS_API} =====" -} - -gnu_mode() { - echo "====== GNU MODE =====" +set_gnu_mode() { GNU=true } -version_change() { - echo "====== New version $1 =====" +set_version() { VERSION=$1 } -version_js_change() { - echo "====== Alfresco JS-API version $1 =====" - VERSION_JS_API=$1 - DIFFERENT_JS_API=true -} - -update_component_dependency_version(){ +update(){ for (( j=0; j<${libslength}; j++ )); do - echo "====== UPDATE ${prefix}${libs[$j]} to ${VERSION}======" - EXACT_VERSION="${prefix}${libs[$j]}@${VERSION}" - npm install -E ${EXACT_VERSION} + EXACT_VERSION="${libs[$j]}@${VERSION}" + echo "====== ${EXACT_VERSION} ======" + npm i -E ${EXACT_VERSION} done } -update_component_js_version(){ - echo "====== UPDATE alfresco-js-api to ${1} ======" - PACKAGETOCHANGE="alfresco-js-api" - EXACT_VERSION="${PACKAGETOCHANGE}@${1}" - npm install -E ${EXACT_VERSION} -} - while [[ $1 == -* ]]; do case "$1" in -h|--help|-\?) show_help; exit 0;; - -v|version) version_change $2; shift 2;; - -sj|sjsapi) skip_js; shift;; - -vj|versionjsapi) version_js_change $2; shift 2;; - -gnu) gnu_mode; shift;; - -alpha) last_alpha_mode; shift;; - -beta) last_beta_mode; shift;; + -v|version) set_version $2; shift 2;; + -gnu) set_gnu_mode; shift;; -*) shift;; esac done @@ -111,25 +52,11 @@ fi if [[ "${VERSION}" == "" ]] then - echo "Version number required" + echo "Error: version number is required" exit 1 fi -projectslength=${#projects[@]} libslength=${#libs[@]} -if $EXEC_COMPONENT == true; then - echo "====== UPDATE ======" - - update_component_dependency_version - - if $JS_API == true; then - - if $DIFFERENT_JS_API == true; then - update_component_js_version ${VERSION_JS_API} - else - update_component_js_version ${VERSION} - fi - - fi -fi +echo "====== Updating dependencies ======" +update diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 85c3cdb474..074cb5b995 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -50,7 +50,7 @@ import { } from './store/states/app.state'; import { filter, takeUntil } from 'rxjs/operators'; import { ContentApiService } from './services/content-api.service'; -import { DiscoveryEntry } from 'alfresco-js-api'; +import { DiscoveryEntry } from '@alfresco/js-api'; import { AppService } from './services/app.service'; import { Subject } from 'rxjs'; diff --git a/src/app/components/about/about.component.ts b/src/app/components/about/about.component.ts index 63075faf7a..2c7ea8edf5 100644 --- a/src/app/components/about/about.component.ts +++ b/src/app/components/about/about.component.ts @@ -25,7 +25,7 @@ import { ExtensionRef } from '@alfresco/adf-extensions'; import { Component, OnInit, ViewEncapsulation } from '@angular/core'; -import { RepositoryInfo } from 'alfresco-js-api'; +import { RepositoryInfo } from '@alfresco/js-api'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; import { AppExtensionService } from '../../extensions/extension.service'; diff --git a/src/app/components/about/module-list/module-list.component.ts b/src/app/components/about/module-list/module-list.component.ts index f4d5aa7cf3..6e6aba3dbd 100644 --- a/src/app/components/about/module-list/module-list.component.ts +++ b/src/app/components/about/module-list/module-list.component.ts @@ -29,7 +29,7 @@ import { ChangeDetectionStrategy, Input } from '@angular/core'; -import { ModuleInfo } from 'alfresco-js-api'; +import { ModuleInfo } from '@alfresco/js-api'; @Component({ selector: 'app-module-list', diff --git a/src/app/components/common/common.module.ts b/src/app/components/common/common.module.ts index 3742784baa..c9f5e92f67 100644 --- a/src/app/components/common/common.module.ts +++ b/src/app/components/common/common.module.ts @@ -28,7 +28,6 @@ import { CommonModule } from '@angular/common'; import { GenericErrorComponent } from './generic-error/generic-error.component'; import { CoreModule } from '@alfresco/adf-core'; import { LocationLinkComponent } from './location-link/location-link.component'; -import { IconComponent } from './icon/icon.component'; import { MatIconModule } from '@angular/material'; import { ExtensionsModule } from '@alfresco/adf-extensions'; @@ -39,13 +38,8 @@ import { ExtensionsModule } from '@alfresco/adf-extensions'; MatIconModule, ExtensionsModule ], - declarations: [GenericErrorComponent, LocationLinkComponent, IconComponent], - exports: [ - ExtensionsModule, - GenericErrorComponent, - LocationLinkComponent, - IconComponent - ], + declarations: [GenericErrorComponent, LocationLinkComponent], + exports: [ExtensionsModule, GenericErrorComponent, LocationLinkComponent], entryComponents: [LocationLinkComponent] }) export class AppCommonModule {} diff --git a/src/app/components/common/icon/icon.component.html b/src/app/components/common/icon/icon.component.html deleted file mode 100644 index 55f3bde643..0000000000 --- a/src/app/components/common/icon/icon.component.html +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - {{ value }} - diff --git a/src/app/components/common/icon/icon.component.scss b/src/app/components/common/icon/icon.component.scss deleted file mode 100644 index ab73482199..0000000000 --- a/src/app/components/common/icon/icon.component.scss +++ /dev/null @@ -1,4 +0,0 @@ -.adf-icon { - display: inline-flex; - vertical-align: middle; -} diff --git a/src/app/components/common/icon/icon.component.ts b/src/app/components/common/icon/icon.component.ts deleted file mode 100644 index d27b3bd733..0000000000 --- a/src/app/components/common/icon/icon.component.ts +++ /dev/null @@ -1,58 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2018 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { - Component, - Input, - ViewEncapsulation, - ChangeDetectionStrategy -} from '@angular/core'; - -@Component({ - selector: 'adf-icon', - templateUrl: './icon.component.html', - encapsulation: ViewEncapsulation.None, - changeDetection: ChangeDetectionStrategy.OnPush, - host: { class: 'adf-icon' }, - styleUrls: ['./icon.component.scss'] -}) -export class IconComponent { - private _value = ''; - private _isCustom = false; - - get value(): string { - return this._value; - } - - @Input() - set value(value: string) { - this._value = value || 'settings'; - this._isCustom = this._value.includes(':'); - } - - get isCustom(): boolean { - return this._isCustom; - } -} diff --git a/src/app/components/common/location-link/location-link.component.ts b/src/app/components/common/location-link/location-link.component.ts index 018e21e324..0e4ea7f171 100644 --- a/src/app/components/common/location-link/location-link.component.ts +++ b/src/app/components/common/location-link/location-link.component.ts @@ -31,7 +31,7 @@ import { ViewEncapsulation, HostListener } from '@angular/core'; -import { PathInfo, MinimalNodeEntity } from 'alfresco-js-api'; +import { PathInfo, MinimalNodeEntity } from '@alfresco/js-api'; import { Observable, BehaviorSubject, of } from 'rxjs'; import { Store } from '@ngrx/store'; diff --git a/src/app/components/favorite-libraries/favorite-libraries.component.spec.ts b/src/app/components/favorite-libraries/favorite-libraries.component.spec.ts index 9c311719da..f21ea0cc1d 100644 --- a/src/app/components/favorite-libraries/favorite-libraries.component.spec.ts +++ b/src/app/components/favorite-libraries/favorite-libraries.component.spec.ts @@ -146,7 +146,7 @@ describe('FavoriteLibrariesComponent', () => { it('does not navigate when id is not passed', () => { spyOn(router, 'navigate').and.stub(); - component.navigateTo({ entry: { guid: 'guid' } }); + component.navigateTo({ entry: { guid: 'guid' } }); expect(router.navigate).toHaveBeenCalledWith(['libraries', 'libraryId']); }); diff --git a/src/app/components/favorite-libraries/favorite-libraries.component.ts b/src/app/components/favorite-libraries/favorite-libraries.component.ts index d76d317ca4..1fff95c841 100644 --- a/src/app/components/favorite-libraries/favorite-libraries.component.ts +++ b/src/app/components/favorite-libraries/favorite-libraries.component.ts @@ -26,7 +26,7 @@ import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout'; import { Component, OnInit } from '@angular/core'; import { Store } from '@ngrx/store'; -import { SiteEntry, FavoritePaging, Pagination } from 'alfresco-js-api'; +import { SiteEntry, FavoritePaging, Pagination } from '@alfresco/js-api'; import { AppExtensionService } from '../../extensions/extension.service'; import { ContentManagementService } from '../../services/content-management.service'; import { ContentApiService } from '../../services/content-api.service'; diff --git a/src/app/components/favorites/favorites.component.ts b/src/app/components/favorites/favorites.component.ts index 3240304c5f..99c860225a 100644 --- a/src/app/components/favorites/favorites.component.ts +++ b/src/app/components/favorites/favorites.component.ts @@ -32,7 +32,7 @@ import { MinimalNodeEntryEntity, PathElementEntity, PathInfo -} from 'alfresco-js-api'; +} from '@alfresco/js-api'; import { ContentManagementService } from '../../services/content-management.service'; import { AppStore } from '../../store/states/app.state'; import { PageComponent } from '../page.component'; diff --git a/src/app/components/files/files.component.html b/src/app/components/files/files.component.html index 0261a38531..24bdc22f93 100644 --- a/src/app/components/files/files.component.html +++ b/src/app/components/files/files.component.html @@ -20,7 +20,7 @@

- + { it('should call refresh onContentCopied event if parent is the same', () => { const nodes = [ - { entry: { parentId: '1' } }, - { entry: { parentId: '2' } } + { entry: { parentId: '1' } }, + { entry: { parentId: '2' } } ]; - component.node = { id: '1' }; + component.node = { id: '1' }; nodeActionsService.contentCopied.next(nodes); @@ -167,11 +167,11 @@ describe('FilesComponent', () => { it('should not call refresh onContentCopied event when parent mismatch', () => { const nodes = [ - { entry: { parentId: '1' } }, - { entry: { parentId: '2' } } + { entry: { parentId: '1' } }, + { entry: { parentId: '2' } } ]; - component.node = { id: '3' }; + component.node = { id: '3' }; nodeActionsService.contentCopied.next(nodes); @@ -210,7 +210,7 @@ describe('FilesComponent', () => { it('should call refresh on fileUploadComplete event if parent node match', fakeAsync(() => { const file = { file: { options: { parentId: 'parentId' } } }; - component.node = { id: 'parentId' }; + component.node = { id: 'parentId' }; uploadService.fileUploadComplete.next(file); @@ -221,7 +221,7 @@ describe('FilesComponent', () => { it('should not call refresh on fileUploadComplete event if parent mismatch', fakeAsync(() => { const file = { file: { options: { parentId: 'otherId' } } }; - component.node = { id: 'parentId' }; + component.node = { id: 'parentId' }; uploadService.fileUploadComplete.next(file); @@ -232,7 +232,7 @@ describe('FilesComponent', () => { it('should call refresh on fileUploadDeleted event if parent node match', fakeAsync(() => { const file = { file: { options: { parentId: 'parentId' } } }; - component.node = { id: 'parentId' }; + component.node = { id: 'parentId' }; uploadService.fileUploadDeleted.next(file); @@ -243,7 +243,7 @@ describe('FilesComponent', () => { it('should not call refresh on fileUploadDeleted event if parent mismatch', fakeAsync(() => { const file: any = { file: { options: { parentId: 'otherId' } } }; - component.node = { id: 'parentId' }; + component.node = { id: 'parentId' }; uploadService.fileUploadDeleted.next(file); @@ -293,7 +293,7 @@ describe('FilesComponent', () => { }); it('should navigate home if node is root', () => { - component.node = { + component.node = { path: { elements: [{ id: 'node-id' }] } @@ -307,19 +307,19 @@ describe('FilesComponent', () => { describe('isSiteContainer', () => { it('should return false if node has no aspectNames', () => { - const mock = { aspectNames: [] }; + const mock = { aspectNames: [] }; expect(component.isSiteContainer(mock)).toBe(false); }); it('should return false if node is not site container', () => { - const mock = { aspectNames: ['something-else'] }; + const mock = { aspectNames: ['something-else'] }; expect(component.isSiteContainer(mock)).toBe(false); }); it('should return true if node is a site container', () => { - const mock = { aspectNames: ['st:siteContainer'] }; + const mock = { aspectNames: ['st:siteContainer'] }; expect(component.isSiteContainer(mock)).toBe(true); }); diff --git a/src/app/components/files/files.component.ts b/src/app/components/files/files.component.ts index 22c367f772..a907e2915a 100644 --- a/src/app/components/files/files.component.ts +++ b/src/app/components/files/files.component.ts @@ -32,7 +32,7 @@ import { MinimalNodeEntryEntity, PathElement, PathElementEntity -} from 'alfresco-js-api'; +} from '@alfresco/js-api'; import { ContentManagementService } from '../../services/content-management.service'; import { NodeActionsService } from '../../services/node-actions.service'; import { AppStore } from '../../store/states/app.state'; diff --git a/src/app/components/info-drawer/comments-tab/comments-tab.component.ts b/src/app/components/info-drawer/comments-tab/comments-tab.component.ts index 91273d28ba..a92b6730f6 100644 --- a/src/app/components/info-drawer/comments-tab/comments-tab.component.ts +++ b/src/app/components/info-drawer/comments-tab/comments-tab.component.ts @@ -24,7 +24,7 @@ */ import { Component, Input } from '@angular/core'; -import { MinimalNodeEntryEntity } from 'alfresco-js-api'; +import { MinimalNodeEntryEntity } from '@alfresco/js-api'; import { NodePermissionService } from '../../../services/node-permission.service'; @Component({ diff --git a/src/app/components/info-drawer/info-drawer.component.spec.ts b/src/app/components/info-drawer/info-drawer.component.spec.ts index dc2311361e..1aaad4c384 100644 --- a/src/app/components/info-drawer/info-drawer.component.spec.ts +++ b/src/app/components/info-drawer/info-drawer.component.spec.ts @@ -83,7 +83,7 @@ describe('InfoDrawerComponent', () => { it('should set displayNode when node is from personal list', () => { spyOn(contentApiService, 'getNodeInfo'); - const nodeMock = { entry: { id: 'nodeId' } }; + const nodeMock = { entry: { id: 'nodeId' } }; component.node = nodeMock; fixture.detectChanges(); @@ -109,9 +109,9 @@ describe('InfoDrawerComponent', () => { })); it('should call getNodeInfo() when node is a shared file', async(() => { - const response = { entry: { id: 'nodeId' } }; + const response = { entry: { id: 'nodeId' } }; spyOn(contentApiService, 'getNodeInfo').and.returnValue(of(response)); - const nodeMock = { entry: { nodeId: 'nodeId' }, isLibrary: false }; + const nodeMock = { entry: { nodeId: 'nodeId' }, isLibrary: false }; component.node = nodeMock; fixture.detectChanges(); @@ -122,7 +122,7 @@ describe('InfoDrawerComponent', () => { })); it('should call getNodeInfo() when node is a favorite file', async(() => { - const response = { entry: { id: 'nodeId' } }; + const response = { entry: { id: 'nodeId' } }; spyOn(contentApiService, 'getNodeInfo').and.returnValue(of(response)); const nodeMock = { entry: { id: 'nodeId', guid: 'guidId' }, @@ -138,7 +138,7 @@ describe('InfoDrawerComponent', () => { })); it('should call getNodeInfo() when node is a recent file', async(() => { - const response = { entry: { id: 'nodeId' } }; + const response = { entry: { id: 'nodeId' } }; spyOn(contentApiService, 'getNodeInfo').and.returnValue(of(response)); const nodeMock = { entry: { diff --git a/src/app/components/info-drawer/info-drawer.component.ts b/src/app/components/info-drawer/info-drawer.component.ts index 9572d5140f..355725bc03 100644 --- a/src/app/components/info-drawer/info-drawer.component.ts +++ b/src/app/components/info-drawer/info-drawer.component.ts @@ -28,7 +28,7 @@ import { MinimalNodeEntity, MinimalNodeEntryEntity, SiteEntry -} from 'alfresco-js-api'; +} from '@alfresco/js-api'; import { ContentApiService } from '../../services/content-api.service'; import { AppExtensionService } from '../../extensions/extension.service'; import { SidebarTabRef } from '@alfresco/adf-extensions'; @@ -66,7 +66,7 @@ export class InfoDrawerComponent implements OnChanges, OnInit, OnDestroy { ngOnChanges() { if (this.node) { - const entry = this.node.entry; + const entry: any = this.node.entry; if (this.isLibraryListNode(this.node)) { return this.setDisplayNode(this.node); @@ -113,19 +113,19 @@ export class InfoDrawerComponent implements OnChanges, OnInit, OnDestroy { } } - private setDisplayNode(node: MinimalNodeEntryEntity | SiteEntry) { + private setDisplayNode(node: any) { this.displayNode = node; } - private isLibraryListNode(node: SiteEntry): boolean { - return (node).isLibrary; + private isLibraryListNode(node: any): boolean { + return node.isLibrary; } private isFavoriteListNode(node: MinimalNodeEntity): boolean { return !this.isLibraryListNode(node) && (node).entry.guid; } - private isSharedFilesNode(node: MinimalNodeEntity): boolean { + private isSharedFilesNode(node: any): boolean { return !!node.entry.nodeId; } diff --git a/src/app/components/info-drawer/library-metadata-tab/library-metadata-form.component.spec.ts b/src/app/components/info-drawer/library-metadata-tab/library-metadata-form.component.spec.ts index ab7652fb68..6689d61035 100644 --- a/src/app/components/info-drawer/library-metadata-tab/library-metadata-form.component.spec.ts +++ b/src/app/components/info-drawer/library-metadata-tab/library-metadata-form.component.spec.ts @@ -33,7 +33,7 @@ import { Store } from '@ngrx/store'; import { UpdateLibraryAction } from '../../../store/actions'; import { AppTestingModule } from '../../../testing/app-testing.module'; import { NO_ERRORS_SCHEMA } from '@angular/core'; -import { Site, SiteBody } from 'alfresco-js-api'; +import { Site, SiteBody } from '@alfresco/js-api'; import { AlfrescoApiService, AlfrescoApiServiceMock } from '@alfresco/adf-core'; describe('LibraryMetadataFormComponent', () => { diff --git a/src/app/components/info-drawer/library-metadata-tab/library-metadata-form.component.ts b/src/app/components/info-drawer/library-metadata-tab/library-metadata-form.component.ts index c9a707d9e6..61f0384742 100644 --- a/src/app/components/info-drawer/library-metadata-tab/library-metadata-form.component.ts +++ b/src/app/components/info-drawer/library-metadata-tab/library-metadata-form.component.ts @@ -25,7 +25,7 @@ import { Component, Input, OnInit, OnChanges, OnDestroy } from '@angular/core'; import { FormGroup, FormControl, Validators } from '@angular/forms'; -import { SiteEntry, SitePaging } from 'alfresco-js-api'; +import { SiteEntry, SitePaging } from '@alfresco/js-api'; import { Store } from '@ngrx/store'; import { UpdateLibraryAction } from '../../../store/actions'; import { AppStore } from '../../../store/states/app.state'; @@ -138,7 +138,9 @@ export class LibraryMetadataFormComponent }); } - private findLibraryByTitle(libraryTitle: string): Observable { + private findLibraryByTitle( + libraryTitle: string + ): Observable { return from( this.alfrescoApiService .getInstance() diff --git a/src/app/components/info-drawer/library-metadata-tab/library-metadata-tab.component.ts b/src/app/components/info-drawer/library-metadata-tab/library-metadata-tab.component.ts index 317d15a3fa..965d318d0a 100644 --- a/src/app/components/info-drawer/library-metadata-tab/library-metadata-tab.component.ts +++ b/src/app/components/info-drawer/library-metadata-tab/library-metadata-tab.component.ts @@ -24,7 +24,7 @@ */ import { Component, Input } from '@angular/core'; -import { SiteEntry } from 'alfresco-js-api'; +import { SiteEntry } from '@alfresco/js-api'; @Component({ selector: 'app-metadata-tab', diff --git a/src/app/components/info-drawer/metadata-tab/metadata-tab.component.ts b/src/app/components/info-drawer/metadata-tab/metadata-tab.component.ts index 6aa52c59bb..5e04507a63 100644 --- a/src/app/components/info-drawer/metadata-tab/metadata-tab.component.ts +++ b/src/app/components/info-drawer/metadata-tab/metadata-tab.component.ts @@ -24,7 +24,7 @@ */ import { Component, Input, ViewEncapsulation } from '@angular/core'; -import { MinimalNodeEntryEntity } from 'alfresco-js-api'; +import { MinimalNodeEntryEntity } from '@alfresco/js-api'; import { NodePermissionService } from '../../../services/node-permission.service'; import { AppExtensionService } from '../../../extensions/extension.service'; import { AppConfigService } from '@alfresco/adf-core'; diff --git a/src/app/components/info-drawer/versions-tab/versions-tab.component.ts b/src/app/components/info-drawer/versions-tab/versions-tab.component.ts index d9f3431af6..bc4df8b19b 100644 --- a/src/app/components/info-drawer/versions-tab/versions-tab.component.ts +++ b/src/app/components/info-drawer/versions-tab/versions-tab.component.ts @@ -24,7 +24,7 @@ */ import { Component, Input, OnChanges, OnInit } from '@angular/core'; -import { MinimalNodeEntryEntity } from 'alfresco-js-api'; +import { MinimalNodeEntryEntity } from '@alfresco/js-api'; @Component({ selector: 'app-versions-tab', @@ -65,7 +65,7 @@ export class VersionsTabComponent implements OnInit, OnChanges { } private updateState() { - if (this.node && this.node.nodeId) { + if (this.node && (this.node).nodeId) { // workaround for shared files type. this.isFileSelected = true; } else { diff --git a/src/app/components/layout/app-layout/app-layout.component.html b/src/app/components/layout/app-layout/app-layout.component.html index 59e88dcdbd..4771392894 100644 --- a/src/app/components/layout/app-layout/app-layout.component.html +++ b/src/app/components/layout/app-layout/app-layout.component.html @@ -1,4 +1,4 @@ - + - + diff --git a/src/app/components/layout/app-layout/app-layout.component.spec.ts b/src/app/components/layout/app-layout/app-layout.component.spec.ts index 56c5c6b80f..842b32eac3 100644 --- a/src/app/components/layout/app-layout/app-layout.component.spec.ts +++ b/src/app/components/layout/app-layout/app-layout.component.spec.ts @@ -140,7 +140,7 @@ describe('AppLayoutComponent', () => { it('should reset selection before navigation', done => { fixture.detectChanges(); - const selection = [{ entry: { id: 'nodeId', name: 'name' } }]; + const selection = [{ entry: { id: 'nodeId', name: 'name' } }]; store.dispatch(new SetSelectedNodesAction(selection)); router.navigateByUrl('somewhere/over/the/rainbow'); @@ -153,7 +153,7 @@ describe('AppLayoutComponent', () => { it('should not reset selection if route is `/search`', done => { fixture.detectChanges(); - const selection = [{ entry: { id: 'nodeId', name: 'name' } }]; + const selection = [{ entry: { id: 'nodeId', name: 'name' } }]; store.dispatch(new SetSelectedNodesAction(selection)); router.navigateByUrl('/search;q='); diff --git a/src/app/components/layout/layout.module.ts b/src/app/components/layout/layout.module.ts index 4ce8ba5d05..78959e4551 100644 --- a/src/app/components/layout/layout.module.ts +++ b/src/app/components/layout/layout.module.ts @@ -32,7 +32,6 @@ import { RouterModule } from '@angular/router'; import { AppSidenavModule } from '../sidenav/sidenav.module'; import { AppCommonModule } from '../common/common.module'; import { AppHeaderModule } from '../header/header.module'; -import { AppUploadingDialogModule } from '../upload-dialog/upload-dialog.module'; import { PageLayoutComponent } from './page-layout/page-layout.component'; import { PageLayoutHeaderComponent } from './page-layout/page-layout-header.component'; import { PageLayoutContentComponent } from './page-layout/page-layout-content.component'; @@ -48,8 +47,7 @@ import { HttpClientModule } from '@angular/common/http'; AppCommonModule, AppSidenavModule, AppHeaderModule, - HttpClientModule, - AppUploadingDialogModule + HttpClientModule ], declarations: [ AppLayoutComponent, diff --git a/src/app/components/libraries/libraries.component.ts b/src/app/components/libraries/libraries.component.ts index 377c1f32a4..ba53574e9c 100644 --- a/src/app/components/libraries/libraries.component.ts +++ b/src/app/components/libraries/libraries.component.ts @@ -26,7 +26,7 @@ import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout'; import { Component, OnInit } from '@angular/core'; import { Store } from '@ngrx/store'; -import { SiteEntry } from 'alfresco-js-api'; +import { SiteEntry } from '@alfresco/js-api'; import { AppExtensionService } from '../../extensions/extension.service'; import { ContentManagementService } from '../../services/content-management.service'; import { NavigateLibraryAction } from '../../store/actions'; diff --git a/src/app/components/page.component.ts b/src/app/components/page.component.ts index 3494898c2c..0e19958fe0 100644 --- a/src/app/components/page.component.ts +++ b/src/app/components/page.component.ts @@ -30,7 +30,7 @@ import { import { ContentActionRef, SelectionState } from '@alfresco/adf-extensions'; import { OnDestroy, OnInit, ViewChild } from '@angular/core'; import { Store } from '@ngrx/store'; -import { MinimalNodeEntity, MinimalNodeEntryEntity } from 'alfresco-js-api'; +import { MinimalNodeEntity, MinimalNodeEntryEntity } from '@alfresco/js-api'; import { Observable, Subject, Subscription } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; import { AppExtensionService } from '../extensions/extension.service'; diff --git a/src/app/components/permissions/permission-manager/permission-manager.component.ts b/src/app/components/permissions/permission-manager/permission-manager.component.ts index 0edb0f35a8..dd6f0c783a 100644 --- a/src/app/components/permissions/permission-manager/permission-manager.component.ts +++ b/src/app/components/permissions/permission-manager/permission-manager.component.ts @@ -30,7 +30,7 @@ import { import { Component, Input, OnInit, ViewChild } from '@angular/core'; import { MatDialog } from '@angular/material'; import { Store } from '@ngrx/store'; -import { MinimalNodeEntryEntity } from 'alfresco-js-api'; +import { MinimalNodeEntryEntity } from '@alfresco/js-api'; import { ContentApiService } from '../../../services/content-api.service'; import { SnackbarErrorAction } from '../../../store/actions/snackbar.actions'; import { AppStore } from '../../../store/states/app.state'; diff --git a/src/app/components/preview/preview-extension.component.ts b/src/app/components/preview/preview-extension.component.ts index 5e2f07c82c..3c554102b8 100644 --- a/src/app/components/preview/preview-extension.component.ts +++ b/src/app/components/preview/preview-extension.component.ts @@ -35,7 +35,7 @@ import { OnChanges } from '@angular/core'; import { AppExtensionService } from '../../extensions/extension.service'; -import { MinimalNodeEntryEntity } from 'alfresco-js-api'; +import { MinimalNodeEntryEntity } from '@alfresco/js-api'; @Component({ selector: 'app-preview-extension', diff --git a/src/app/components/preview/preview.component.html b/src/app/components/preview/preview.component.html index 998a327b11..16bec8ee31 100644 --- a/src/app/components/preview/preview.component.html +++ b/src/app/components/preview/preview.component.html @@ -1,8 +1,8 @@ , private appConfig: AppConfigService, - private settingsService: SettingsService, private storage: StorageService, private fb: FormBuilder ) { @@ -106,7 +101,8 @@ export class SettingsComponent implements OnInit { reset() { this.form.reset({ - ecmHost: this.storage.getItem('ecmHost') || this.settingsService.ecmHost + ecmHost: + this.storage.getItem('ecmHost') || this.appConfig.get('ecmHost') }); } diff --git a/src/app/components/shared/content-node-share/content-node-share.dialog.ts b/src/app/components/shared/content-node-share/content-node-share.dialog.ts index b6382a2495..c336f885d7 100644 --- a/src/app/components/shared/content-node-share/content-node-share.dialog.ts +++ b/src/app/components/shared/content-node-share/content-node-share.dialog.ts @@ -36,7 +36,7 @@ import { distinctUntilChanged } from 'rxjs/operators'; import { SharedLinksApiService, NodesApiService } from '@alfresco/adf-core'; -import { SharedLinkEntry, MinimalNodeEntryEntity } from 'alfresco-js-api'; +import { SharedLinkEntry, MinimalNodeEntryEntity } from '@alfresco/js-api'; import { ConfirmDialogComponent } from '@alfresco/adf-content-services'; import * as moment from 'moment'; diff --git a/src/app/components/upload-dialog/file-uploading-dialog.component.html b/src/app/components/upload-dialog/file-uploading-dialog.component.html deleted file mode 100644 index cda584cde9..0000000000 --- a/src/app/components/upload-dialog/file-uploading-dialog.component.html +++ /dev/null @@ -1,134 +0,0 @@ -
-
- - - - {{ - 'FILE_UPLOAD.MESSAGES.UPLOAD_COMPLETED' - | translate - : { - completed: totalCompleted, - total: filesUploadingList.length - } - }} - - - - {{ 'FILE_UPLOAD.MESSAGES.UPLOAD_CANCELED' | translate }} - -
- -
- {{ - (totalErrors > 1 - ? 'FILE_UPLOAD.MESSAGES.UPLOAD_ERRORS' - : 'FILE_UPLOAD.MESSAGES.UPLOAD_ERROR') - | translate: { total: totalErrors } - }} -
- -
- - - - - - - -
-

- {{ 'ADF_FILE_UPLOAD.CONFIRMATION.MESSAGE.TITLE' | translate }} -

- -

- {{ 'ADF_FILE_UPLOAD.CONFIRMATION.MESSAGE.TEXT' | translate }} -

-
-
- -
- - - -
- -
- - - -
-
diff --git a/src/app/components/upload-dialog/file-uploading-dialog.component.ts b/src/app/components/upload-dialog/file-uploading-dialog.component.ts deleted file mode 100644 index c2f4615d97..0000000000 --- a/src/app/components/upload-dialog/file-uploading-dialog.component.ts +++ /dev/null @@ -1,195 +0,0 @@ -/*! - * @license - * Copyright 2016 Alfresco Software, Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { - FileModel, - FileUploadCompleteEvent, - FileUploadDeleteEvent, - FileUploadErrorEvent, - FileUploadStatus, - UploadService -} from '@alfresco/adf-core'; -import { - ChangeDetectorRef, - Component, - Input, - Output, - EventEmitter, - OnDestroy, - OnInit, - ViewChild -} from '@angular/core'; -import { Subscription, merge } from 'rxjs'; -import { FileUploadingListComponent } from './file-uploading-list.component'; - -// @deprecated file-uploading-dialog TODO remove in 3.0.0 -@Component({ - selector: 'app-file-uploading-dialog', - templateUrl: './file-uploading-dialog.component.html' -}) -export class FileUploadingDialogComponent implements OnInit, OnDestroy { - @ViewChild('uploadList') - uploadList: FileUploadingListComponent; - - /** Dialog position. Can be 'left' or 'right'. */ - @Input() - position = 'right'; - - /** Emitted when a file in the list has an error. */ - @Output() - error: EventEmitter = new EventEmitter(); - - filesUploadingList: FileModel[] = []; - isDialogActive = false; - totalCompleted = 0; - totalErrors = 0; - isDialogMinimized = false; - isConfirmation = false; - - private listSubscription: Subscription; - private counterSubscription: Subscription; - private fileUploadSubscription: Subscription; - private errorSubscription: Subscription; - private errors = []; - - constructor( - private uploadService: UploadService, - private changeDetector: ChangeDetectorRef - ) {} - - ngOnInit() { - this.listSubscription = this.uploadService.queueChanged.subscribe( - (fileList: FileModel[]) => { - this.filesUploadingList = fileList; - - if (this.filesUploadingList.length) { - this.isDialogActive = true; - } - } - ); - - this.counterSubscription = merge( - this.uploadService.fileUploadComplete, - this.uploadService.fileUploadDeleted - ).subscribe((event: FileUploadDeleteEvent | FileUploadCompleteEvent) => { - this.totalCompleted = event.totalComplete; - this.changeDetector.detectChanges(); - }); - - // todo: move to ADF ACA-2051 - this.errorSubscription = this.uploadService.fileUploadError.subscribe( - (event: FileUploadErrorEvent) => { - const statusCode = (event.error || {}).response - ? event.error.response.statusCode - : null; - this.errors.push({ - fileName: event.file.name, - status: statusCode, - message: this.getUploadErrorMessage(statusCode) - }); - this.totalErrors = event.totalError; - this.changeDetector.detectChanges(); - } - ); - - this.fileUploadSubscription = this.uploadService.fileUpload.subscribe( - event => { - this.changeDetector.detectChanges(); - } - ); - - this.uploadService.fileDeleted.subscribe(objId => { - if (this.filesUploadingList) { - const file = this.filesUploadingList.find(item => { - return item.data.entry.id === objId; - }); - if (file) { - file.status = FileUploadStatus.Cancelled; - this.changeDetector.detectChanges(); - } - } - }); - } - - getFileUploadError(file) { - return this.errors.find(error => (error.fileName = file.name)); - } - - /** - * Toggle confirmation message. - */ - toggleConfirmation() { - this.isConfirmation = !this.isConfirmation; - - if (this.isDialogMinimized) { - this.isDialogMinimized = false; - } - } - - /** - * Cancel uploads and hide confirmation - */ - cancelAllUploads() { - this.toggleConfirmation(); - - this.uploadList.cancelAllFiles(); - } - - /** - * Toggle dialog minimized state. - */ - toggleMinimized(): void { - this.isDialogMinimized = !this.isDialogMinimized; - this.changeDetector.detectChanges(); - } - - /** - * Dismiss dialog - */ - close(): void { - this.isConfirmation = false; - this.totalCompleted = 0; - this.totalErrors = 0; - this.filesUploadingList = []; - this.isDialogActive = false; - this.isDialogMinimized = false; - this.uploadService.clearQueue(); - this.changeDetector.detectChanges(); - this.errors = []; - } - - ngOnDestroy() { - this.uploadService.clearQueue(); - this.listSubscription.unsubscribe(); - this.counterSubscription.unsubscribe(); - this.fileUploadSubscription.unsubscribe(); - this.errorSubscription.unsubscribe(); - } - - // todo: move to ADF ACA-2051 - private getUploadErrorMessage(status) { - const messages = { - 500: 'APP.MESSAGES.UPLOAD.ERROR.500', - 504: 'APP.MESSAGES.UPLOAD.ERROR.504', - 403: 'APP.MESSAGES.UPLOAD.ERROR.403', - 404: 'APP.MESSAGES.UPLOAD.ERROR.404', - generic: 'APP.MESSAGES.UPLOAD.ERROR.GENERIC' - }; - - return messages[status] || messages['generic']; - } -} diff --git a/src/app/components/upload-dialog/file-uploading-list-row.component.html b/src/app/components/upload-dialog/file-uploading-list-row.component.html deleted file mode 100644 index 578129cf8b..0000000000 --- a/src/app/components/upload-dialog/file-uploading-list-row.component.html +++ /dev/null @@ -1,94 +0,0 @@ -
- - insert_drive_file - - - - {{ file.name }} - - -
- - {{ file.progress.loaded | adfFileSize }} / - {{ file.progress.total | adfFileSize }} - - - - clear - -
- -
- - check_circle - - - - remove_circle - -
- -
- - schedule - - - - remove_circle - -
- - -
- - report_problem - -
- -
- {{ 'ADF_FILE_UPLOAD.STATUS.FILE_CANCELED_STATUS' | translate }} -
-
-
diff --git a/src/app/components/upload-dialog/file-uploading-list-row.component.ts b/src/app/components/upload-dialog/file-uploading-list-row.component.ts deleted file mode 100644 index 7bb564eccd..0000000000 --- a/src/app/components/upload-dialog/file-uploading-list-row.component.ts +++ /dev/null @@ -1,47 +0,0 @@ -/*! - * @license - * Copyright 2016 Alfresco Software, Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { FileModel, FileUploadStatus } from '@alfresco/adf-core'; -import { Component, EventEmitter, Input, Output } from '@angular/core'; - -@Component({ - selector: 'app-file-uploading-list-row', - templateUrl: './file-uploading-list-row.component.html' -}) -export class FileUploadingListRowComponent { - @Input() - file: FileModel; - - @Input() - error: any; - - @Output() - cancel: EventEmitter = new EventEmitter(); - - @Output() - remove: EventEmitter = new EventEmitter(); - - FileUploadStatus = FileUploadStatus; - - onCancel(file: FileModel): void { - this.cancel.emit(file); - } - - onRemove(file: FileModel): void { - this.remove.emit(file); - } -} diff --git a/src/app/components/upload-dialog/file-uploading-list.component.html b/src/app/components/upload-dialog/file-uploading-list.component.html deleted file mode 100644 index 475b084b12..0000000000 --- a/src/app/components/upload-dialog/file-uploading-list.component.html +++ /dev/null @@ -1,4 +0,0 @@ -
- - -
diff --git a/src/app/components/upload-dialog/file-uploading-list.component.ts b/src/app/components/upload-dialog/file-uploading-list.component.ts deleted file mode 100644 index f70e07e035..0000000000 --- a/src/app/components/upload-dialog/file-uploading-list.component.ts +++ /dev/null @@ -1,180 +0,0 @@ -/*! - * @license - * Copyright 2016 Alfresco Software, Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { - FileModel, - FileUploadStatus, - NodesApiService, - TranslationService, - UploadService -} from '@alfresco/adf-core'; -import { - Component, - ContentChild, - Input, - Output, - TemplateRef, - EventEmitter -} from '@angular/core'; -import { Observable, forkJoin, of } from 'rxjs'; -import { map, catchError } from 'rxjs/operators'; - -@Component({ - selector: 'app-file-uploading-list', - templateUrl: './file-uploading-list.component.html' -}) -export class FileUploadingListComponent { - FileUploadStatus = FileUploadStatus; - - @ContentChild(TemplateRef) - template: any; - - @Input() - files: FileModel[] = []; - - /** Emitted when a file in the list has an error. */ - @Output() - error: EventEmitter = new EventEmitter(); - - constructor( - private uploadService: UploadService, - private nodesApi: NodesApiService, - private translateService: TranslationService - ) {} - - /** - * Cancel file upload - * - * @param file File model to cancel upload for. - * - * @memberOf FileUploadingListComponent - */ - cancelFile(file: FileModel): void { - this.uploadService.cancelUpload(file); - } - - removeFile(file: FileModel): void { - this.deleteNode(file).subscribe(() => { - if (file.status === FileUploadStatus.Error) { - this.notifyError(file); - } - - this.uploadService.cancelUpload(file); - }); - } - - /** - * Call the appropriate method for each file, depending on state - */ - cancelAllFiles(): void { - this.getUploadingFiles().forEach(file => - this.uploadService.cancelUpload(file) - ); - - const deletedFiles = this.files - .filter(file => file.status === FileUploadStatus.Complete) - .map(file => this.deleteNode(file)); - - forkJoin(...deletedFiles).subscribe((files: FileModel[]) => { - const errors = files.filter( - file => file.status === FileUploadStatus.Error - ); - - if (errors.length) { - this.notifyError(...errors); - } - - this.uploadService.cancelUpload(...files); - }); - } - - /** - * Checks if all the files are uploaded false if there is at least one file in Progress | Starting | Pending - */ - isUploadCompleted(): boolean { - return ( - !this.isUploadCancelled() && - Boolean(this.files.length) && - !this.files.some( - ({ status }) => - status === FileUploadStatus.Starting || - status === FileUploadStatus.Progress || - status === FileUploadStatus.Pending - ) - ); - } - - /** - * Check if all the files are Cancelled | Aborted | Error. false if there is at least one file in uploading states - */ - isUploadCancelled(): boolean { - return ( - !!this.files.length && - this.files.every( - ({ status }) => - status === FileUploadStatus.Aborted || - status === FileUploadStatus.Cancelled || - status === FileUploadStatus.Deleted - ) - ); - } - - private deleteNode(file: FileModel): Observable { - const { id } = file.data.entry; - - return this.nodesApi.deleteNode(id, { permanent: true }).pipe( - map(() => { - file.status = FileUploadStatus.Deleted; - return file; - }), - catchError(() => { - file.status = FileUploadStatus.Error; - return of(file); - }) - ); - } - - private notifyError(...files: FileModel[]) { - let messageError: string = null; - - if (files.length === 1) { - messageError = this.translateService.instant( - 'FILE_UPLOAD.MESSAGES.REMOVE_FILE_ERROR', - { fileName: files[0].name } - ); - } else { - messageError = this.translateService.instant( - 'FILE_UPLOAD.MESSAGES.REMOVE_FILES_ERROR', - { total: files.length } - ); - } - - this.error.emit(messageError); - } - - private getUploadingFiles() { - return this.files.filter(item => { - if ( - item.status === FileUploadStatus.Pending || - item.status === FileUploadStatus.Progress || - item.status === FileUploadStatus.Starting - ) { - return item; - } - }); - } -} diff --git a/src/app/components/upload-dialog/upload-dialog.module.ts b/src/app/components/upload-dialog/upload-dialog.module.ts deleted file mode 100644 index 24606c41e5..0000000000 --- a/src/app/components/upload-dialog/upload-dialog.module.ts +++ /dev/null @@ -1,46 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2018 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { CoreModule } from '@alfresco/adf-core'; -import { FileUploadingDialogComponent } from './file-uploading-dialog.component'; -import { FileUploadingListRowComponent } from './file-uploading-list-row.component'; -import { FileUploadingListComponent } from './file-uploading-list.component'; - -@NgModule({ - imports: [CommonModule, CoreModule.forChild()], - declarations: [ - FileUploadingDialogComponent, - FileUploadingListRowComponent, - FileUploadingListComponent - ], - exports: [ - FileUploadingDialogComponent, - FileUploadingListRowComponent, - FileUploadingListComponent - ] -}) -export class AppUploadingDialogModule {} diff --git a/src/app/dialogs/node-versions/node-versions.dialog.ts b/src/app/dialogs/node-versions/node-versions.dialog.ts index be326220bc..2e15888fde 100644 --- a/src/app/dialogs/node-versions/node-versions.dialog.ts +++ b/src/app/dialogs/node-versions/node-versions.dialog.ts @@ -25,7 +25,7 @@ import { Component, Inject, ViewEncapsulation } from '@angular/core'; import { MAT_DIALOG_DATA } from '@angular/material'; -import { MinimalNodeEntryEntity } from 'alfresco-js-api'; +import { MinimalNodeEntryEntity } from '@alfresco/js-api'; import { Store } from '@ngrx/store'; import { AppStore } from '../../store/states/app.state'; import { SnackbarErrorAction } from '../../store/actions'; diff --git a/src/app/directives/document-list.directive.ts b/src/app/directives/document-list.directive.ts index d096d29c28..2a9dd4152e 100644 --- a/src/app/directives/document-list.directive.ts +++ b/src/app/directives/document-list.directive.ts @@ -31,7 +31,7 @@ import { Subscription } from 'rxjs'; import { Store } from '@ngrx/store'; import { AppStore } from '../store/states/app.state'; import { SetSelectedNodesAction } from '../store/actions'; -import { MinimalNodeEntryEntity } from 'alfresco-js-api'; +import { MinimalNodeEntryEntity } from '@alfresco/js-api'; @Directive({ selector: '[acaDocumentList]' diff --git a/src/app/directives/library-favorite.directive.spec.ts b/src/app/directives/library-favorite.directive.spec.ts index 567591a90e..ceb6a31bd4 100644 --- a/src/app/directives/library-favorite.directive.spec.ts +++ b/src/app/directives/library-favorite.directive.spec.ts @@ -123,7 +123,7 @@ describe('LibraryFavoriteDirective', () => { it('should call removeFavoriteSite() on click event when selection is not a favorite', async(() => { spyOn(api.peopleApi, 'getFavoriteSite').and.returnValue(Promise.resolve()); - spyOn(api.peopleApi, 'removeFavoriteSite').and.returnValue( + spyOn(api.favoritesApi, 'removeFavoriteSite').and.returnValue( Promise.resolve() ); component.selection = selection; @@ -138,7 +138,7 @@ describe('LibraryFavoriteDirective', () => { fixture.detectChanges(); - expect(api.peopleApi.removeFavoriteSite).toHaveBeenCalled(); + expect(api.favoritesApi.removeFavoriteSite).toHaveBeenCalled(); }); })); }); diff --git a/src/app/directives/library-favorite.directive.ts b/src/app/directives/library-favorite.directive.ts index 8d8026d497..8fdbac77f7 100644 --- a/src/app/directives/library-favorite.directive.ts +++ b/src/app/directives/library-favorite.directive.ts @@ -31,7 +31,7 @@ import { Output, EventEmitter } from '@angular/core'; -import { SiteBody, FavoriteBody, FavoriteEntry, Site } from 'alfresco-js-api'; +import { SiteBody, FavoriteBody, FavoriteEntry, Site } from '@alfresco/js-api'; import { AlfrescoApiService } from '@alfresco/adf-core'; interface LibraryEntity { @@ -119,7 +119,7 @@ export class LibraryFavoriteDirective implements OnChanges { } private removeFavorite(favoriteId: string) { - this.alfrescoApiService.peopleApi + this.alfrescoApiService.favoritesApi .removeFavoriteSite('-me-', favoriteId) .then((libraryBody: SiteBody) => { this.targetLibrary.isFavorite = false; diff --git a/src/app/directives/library-membership.directive.ts b/src/app/directives/library-membership.directive.ts index 8eb3e2b5ff..0100bb085c 100644 --- a/src/app/directives/library-membership.directive.ts +++ b/src/app/directives/library-membership.directive.ts @@ -31,7 +31,7 @@ import { OnChanges, Output } from '@angular/core'; -import { SiteEntry, SiteMembershipRequestBody } from 'alfresco-js-api'; +import { SiteEntry, SiteMembershipRequestBody } from '@alfresco/js-api'; import { AlfrescoApiService } from '@alfresco/adf-core'; import { BehaviorSubject, from } from 'rxjs'; diff --git a/src/app/extensions/evaluators/app.evaluators.ts b/src/app/extensions/evaluators/app.evaluators.ts index c677fcf751..8b7ebbb29b 100644 --- a/src/app/extensions/evaluators/app.evaluators.ts +++ b/src/app/extensions/evaluators/app.evaluators.ts @@ -178,7 +178,7 @@ export function canDownloadSelection( ...args: RuleParameter[] ): boolean { if (!context.selection.isEmpty) { - return context.selection.nodes.every(node => { + return context.selection.nodes.every((node: any) => { return ( node.entry && (node.entry.isFile || node.entry.isFolder || !!node.entry.nodeId) diff --git a/src/app/services/content-api.service.ts b/src/app/services/content-api.service.ts index df3696d1d6..421d871ede 100644 --- a/src/app/services/content-api.service.ts +++ b/src/app/services/content-api.service.ts @@ -41,7 +41,7 @@ import { SiteBody, SiteEntry, FavoriteBody -} from 'alfresco-js-api'; +} from '@alfresco/js-api'; import { map } from 'rxjs/operators'; @Injectable({ @@ -81,13 +81,13 @@ export class ContentApiService { return from(this.api.nodesApi.getNode(nodeId, queryOptions)); } - getNodeInfo(nodeId: string, options: any = {}): Observable { + getNodeInfo(nodeId: string, options?: any): Observable { const defaults = { include: ['isFavorite', 'allowableOperations'] }; - const queryOptions = Object.assign(defaults, options); + const queryOptions = Object.assign(defaults, options || {}); - return from(this.api.nodesApi.getNodeInfo(nodeId, queryOptions)); + return from((this.api.nodesApi).getNodeInfo(nodeId, queryOptions)); } /** @@ -254,7 +254,7 @@ export class ContentApiService { addFavorite(nodes: Array): Observable { const payload: FavoriteBody[] = nodes.map(node => { - const { isFolder, nodeId, id } = node.entry; + const { isFolder, nodeId, id } = node.entry; const siteId = node.entry['guid']; const type = siteId ? 'site' : isFolder ? 'folder' : 'file'; const guid = siteId || nodeId || id; @@ -274,7 +274,7 @@ export class ContentApiService { removeFavorite(nodes: Array): Observable { return from( Promise.all( - nodes.map(node => { + nodes.map((node: any) => { const id = node.entry.nodeId || node.entry.id; return this.api.favoritesApi.removeFavoriteSite('-me-', id); }) diff --git a/src/app/services/content-management.service.spec.ts b/src/app/services/content-management.service.spec.ts index f608425cd6..29845e5e84 100644 --- a/src/app/services/content-management.service.spec.ts +++ b/src/app/services/content-management.service.spec.ts @@ -91,7 +91,9 @@ describe('ContentManagementService', () => { of('OPERATION.SUCCES.CONTENT.COPY') ); - const selection = [{ entry: { id: 'node-to-copy-id', name: 'name' } }]; + const selection = [ + { entry: { id: 'node-to-copy-id', name: 'name' } } + ]; const createdItems = [{ entry: { id: 'copy-id', name: 'name' } }]; store.dispatch(new CopyNodesAction(selection)); @@ -109,16 +111,16 @@ describe('ContentManagementService', () => { ); const selection = [ - { entry: { id: 'node-to-copy-1', name: 'name1' } }, - { entry: { id: 'node-to-copy-2', name: 'name2' } } + { entry: { id: 'node-to-copy-1', name: 'name1' } }, + { entry: { id: 'node-to-copy-2', name: 'name2' } } ]; const createdItems = [ - { entry: { id: 'copy-of-node-1', name: 'name1' } }, - { entry: { id: 'copy-of-node-2', name: 'name2' } } + { entry: { id: 'copy-of-node-1', name: 'name1' } }, + { entry: { id: 'copy-of-node-2', name: 'name2' } } ]; store.dispatch(new CopyNodesAction(selection)); - nodeActions.contentCopied.next(createdItems); + nodeActions.contentCopied.next(createdItems); expect(nodeActions.copyNodes).toHaveBeenCalled(); expect(snackBar.open['calls'].argsFor(0)[0]).toBe( @@ -132,13 +134,15 @@ describe('ContentManagementService', () => { ); const selection = [ - { entry: { id: 'node-to-copy-1', name: 'name1' } }, - { entry: { id: 'node-to-copy-2', name: 'name2' } } + { entry: { id: 'node-to-copy-1', name: 'name1' } }, + { entry: { id: 'node-to-copy-2', name: 'name2' } } + ]; + const createdItems = [ + { entry: { id: 'copy-of-node-1', name: 'name1' } } ]; - const createdItems = [{ entry: { id: 'copy-of-node-1', name: 'name1' } }]; store.dispatch(new CopyNodesAction(selection)); - nodeActions.contentCopied.next(createdItems); + nodeActions.contentCopied.next(createdItems); expect(nodeActions.copyNodes).toHaveBeenCalled(); expect(snackBar.open['calls'].argsFor(0)[0]).toBe( @@ -152,17 +156,17 @@ describe('ContentManagementService', () => { ); const selection = [ - { entry: { id: 'node-to-copy-0', name: 'name0' } }, - { entry: { id: 'node-to-copy-1', name: 'name1' } }, - { entry: { id: 'node-to-copy-2', name: 'name2' } } + { entry: { id: 'node-to-copy-0', name: 'name0' } }, + { entry: { id: 'node-to-copy-1', name: 'name1' } }, + { entry: { id: 'node-to-copy-2', name: 'name2' } } ]; const createdItems = [ - { entry: { id: 'copy-of-node-0', name: 'name0' } }, - { entry: { id: 'copy-of-node-1', name: 'name1' } } + { entry: { id: 'copy-of-node-0', name: 'name0' } }, + { entry: { id: 'copy-of-node-1', name: 'name1' } } ]; store.dispatch(new CopyNodesAction(selection)); - nodeActions.contentCopied.next(createdItems); + nodeActions.contentCopied.next(createdItems); expect(nodeActions.copyNodes).toHaveBeenCalled(); expect(snackBar.open['calls'].argsFor(0)[0]).toBe( @@ -176,9 +180,9 @@ describe('ContentManagementService', () => { ); const selection = [ - { entry: { id: 'node-to-copy-0', name: 'name0' } }, - { entry: { id: 'node-to-copy-1', name: 'name1' } }, - { entry: { id: 'node-to-copy-2', name: 'name2' } } + { entry: { id: 'node-to-copy-0', name: 'name0' } }, + { entry: { id: 'node-to-copy-1', name: 'name1' } }, + { entry: { id: 'node-to-copy-2', name: 'name2' } } ]; const createdItems = []; @@ -196,7 +200,7 @@ describe('ContentManagementService', () => { of('OPERATION.SUCCES.CONTENT.COPY') ); - const selection = [{ entry: { id: 'node-to-copy', name: 'name' } }]; + const selection = [{ entry: { id: 'node-to-copy', name: 'name' } }]; const createdItems = []; store.dispatch(new CopyNodesAction(selection)); @@ -211,7 +215,9 @@ describe('ContentManagementService', () => { it('notifies error if success message was not emitted', () => { spyOn(nodeActions, 'copyNodes').and.returnValue(of('')); - const selection = [{ entry: { id: 'node-to-copy-id', name: 'name' } }]; + const selection = [ + { entry: { id: 'node-to-copy-id', name: 'name' } } + ]; store.dispatch(new CopyNodesAction(selection)); nodeActions.contentCopied.next(); @@ -227,7 +233,7 @@ describe('ContentManagementService', () => { throwError(new Error(JSON.stringify({ error: { statusCode: 403 } }))) ); - const selection = [{ entry: { id: '1', name: 'name' } }]; + const selection = [{ entry: { id: '1', name: 'name' } }]; store.dispatch(new CopyNodesAction(selection)); expect(nodeActions.copyNodes).toHaveBeenCalled(); @@ -241,7 +247,7 @@ describe('ContentManagementService', () => { throwError(new Error(JSON.stringify({ error: { statusCode: 404 } }))) ); - const selection = [{ entry: { id: '1', name: 'name' } }]; + const selection = [{ entry: { id: '1', name: 'name' } }]; store.dispatch(new CopyNodesAction(selection)); @@ -266,7 +272,9 @@ describe('ContentManagementService', () => { it('should delete the newly created node on Undo action', () => { spyOn(contentApi, 'deleteNode').and.returnValue(of(null)); - const selection = [{ entry: { id: 'node-to-copy-id', name: 'name' } }]; + const selection = [ + { entry: { id: 'node-to-copy-id', name: 'name' } } + ]; const createdItems = [{ entry: { id: 'copy-id', name: 'name' } }]; store.dispatch(new CopyNodesAction(selection)); @@ -289,8 +297,8 @@ describe('ContentManagementService', () => { ); const selection = [ - { entry: { id: 'node-to-copy-1', name: 'name1' } }, - { + { entry: { id: 'node-to-copy-1', name: 'name1' } }, + { entry: { id: 'node-to-copy-2', name: 'folder-with-name-already-existing-on-destination' @@ -330,11 +338,13 @@ describe('ContentManagementService', () => { it('notifies when error occurs on Undo action', () => { spyOn(contentApi, 'deleteNode').and.returnValue(throwError(null)); - const selection = [{ entry: { id: 'node-to-copy-id', name: 'name' } }]; - const createdItems = [{ entry: { id: 'copy-id', name: 'name' } }]; + const selection = [ + { entry: { id: 'node-to-copy-id', name: 'name' } } + ]; + const createdItems = [{ entry: { id: 'copy-id', name: 'name' } }]; store.dispatch(new CopyNodesAction(selection)); - nodeActions.contentCopied.next(createdItems); + nodeActions.contentCopied.next(createdItems); expect(nodeActions.copyNodes).toHaveBeenCalled(); expect(contentApi.deleteNode).toHaveBeenCalled(); @@ -348,11 +358,13 @@ describe('ContentManagementService', () => { throwError(new Error('oops!')) ); - const selection = [{ entry: { id: 'node-to-copy-id', name: 'name' } }]; - const createdItems = [{ entry: { id: 'copy-id', name: 'name' } }]; + const selection = [ + { entry: { id: 'node-to-copy-id', name: 'name' } } + ]; + const createdItems = [{ entry: { id: 'copy-id', name: 'name' } }]; store.dispatch(new CopyNodesAction(selection)); - nodeActions.contentCopied.next(createdItems); + nodeActions.contentCopied.next(createdItems); expect(nodeActions.copyNodes).toHaveBeenCalled(); expect(contentApi.deleteNode).toHaveBeenCalled(); @@ -366,11 +378,13 @@ describe('ContentManagementService', () => { throwError(new Error(JSON.stringify({ error: { statusCode: 403 } }))) ); - const selection = [{ entry: { id: 'node-to-copy-id', name: 'name' } }]; - const createdItems = [{ entry: { id: 'copy-id', name: 'name' } }]; + const selection = [ + { entry: { id: 'node-to-copy-id', name: 'name' } } + ]; + const createdItems = [{ entry: { id: 'copy-id', name: 'name' } }]; store.dispatch(new CopyNodesAction(selection)); - nodeActions.contentCopied.next(createdItems); + nodeActions.contentCopied.next(createdItems); expect(nodeActions.copyNodes).toHaveBeenCalled(); expect(contentApi.deleteNode).toHaveBeenCalled(); @@ -412,7 +426,7 @@ describe('ContentManagementService', () => { ); spyOn(nodeActions, 'processResponse').and.returnValue(moveResponse); - const selection = node; + const selection: any = node; store.dispatch(new MoveNodesAction(selection)); nodeActions.contentMoved.next(moveResponse); @@ -439,7 +453,7 @@ describe('ContentManagementService', () => { ); spyOn(nodeActions, 'processResponse').and.returnValue(moveResponse); - const selection = nodes; + const selection: any = nodes; store.dispatch(new MoveNodesAction(selection)); nodeActions.contentMoved.next(moveResponse); @@ -451,7 +465,7 @@ describe('ContentManagementService', () => { }); it('notifies partial move of a node', () => { - const nodes = [{ entry: { id: '1', name: 'name' } }]; + const nodes = [{ entry: { id: '1', name: 'name' } }]; const moveResponse = { succeeded: [], failed: [], @@ -476,8 +490,8 @@ describe('ContentManagementService', () => { it('notifies partial move of multiple nodes', () => { const nodes = [ - { entry: { id: '1', name: 'name' } }, - { entry: { id: '2', name: 'name2' } } + { entry: { id: '1', name: 'name' } }, + { entry: { id: '2', name: 'name2' } } ]; const moveResponse = { succeeded: [], @@ -503,8 +517,8 @@ describe('ContentManagementService', () => { it('notifies successful move and the number of nodes that could not be moved', () => { const nodes = [ - { entry: { id: '1', name: 'name' } }, - { entry: { id: '2', name: 'name2' } } + { entry: { id: '1', name: 'name' } }, + { entry: { id: '2', name: 'name2' } } ]; const moveResponse = { succeeded: [nodes[0]], @@ -529,8 +543,8 @@ describe('ContentManagementService', () => { it('notifies successful move and the number of partially moved ones', () => { const nodes = [ - { entry: { id: '1', name: 'name' } }, - { entry: { id: '2', name: 'name2' } } + { entry: { id: '1', name: 'name' } }, + { entry: { id: '2', name: 'name2' } } ]; const moveResponse = { succeeded: [nodes[0]], @@ -553,7 +567,7 @@ describe('ContentManagementService', () => { }); it('notifies error if success message was not emitted', () => { - const nodes = [{ entry: { id: 'node-to-move-id', name: 'name' } }]; + const nodes = [{ entry: { id: 'node-to-move-id', name: 'name' } }]; const moveResponse = { succeeded: [], failed: [], @@ -576,7 +590,7 @@ describe('ContentManagementService', () => { throwError(new Error(JSON.stringify({ error: { statusCode: 403 } }))) ); - const selection = [{ entry: { id: '1', name: 'name' } }]; + const selection = [{ entry: { id: '1', name: 'name' } }]; store.dispatch(new MoveNodesAction(selection)); expect(nodeActions.moveNodes).toHaveBeenCalled(); @@ -590,7 +604,7 @@ describe('ContentManagementService', () => { throwError(new Error(JSON.stringify({ error: { statusCode: 404 } }))) ); - const selection = [{ entry: { id: '1', name: 'name' } }]; + const selection = [{ entry: { id: '1', name: 'name' } }]; store.dispatch(new MoveNodesAction(selection)); expect(nodeActions.moveNodes).toHaveBeenCalled(); @@ -604,7 +618,7 @@ describe('ContentManagementService', () => { throwError(new Error(JSON.stringify({ error: { statusCode: 409 } }))) ); - const selection = [{ entry: { id: '1', name: 'name' } }]; + const selection = [{ entry: { id: '1', name: 'name' } }]; store.dispatch(new MoveNodesAction(selection)); expect(nodeActions.moveNodes).toHaveBeenCalled(); @@ -614,7 +628,7 @@ describe('ContentManagementService', () => { }); it('notifies error if move response has only failed items', () => { - const nodes = [{ entry: { id: '1', name: 'name' } }]; + const nodes = [{ entry: { id: '1', name: 'name' } }]; const moveResponse = { succeeded: [], failed: [{}], @@ -668,7 +682,7 @@ describe('ContentManagementService', () => { const node = { entry: { id: 'node-to-move-id', name: 'name', parentId: initialParent } }; - const selection = [node]; + const selection = [node]; spyOn(nodeActions, 'moveNodeAction').and.returnValue(of({})); @@ -699,7 +713,7 @@ describe('ContentManagementService', () => { parentId: initialParent } }; - const selection = [node]; + const selection = [node]; spyOn(nodeActions, 'moveNodeAction').and.returnValue(of({})); @@ -734,7 +748,7 @@ describe('ContentManagementService', () => { isFolder: true } }; - const selection = [node]; + const selection = [node]; const itemMoved = {}; // folder was empty nodeActions.moveDeletedEntries = [node]; // folder got deleted @@ -770,7 +784,7 @@ describe('ContentManagementService', () => { parentId: initialParent } }; - const selection = [node]; + const selection = [node]; const afterMoveParentId = 'parent-id-1'; const childMoved = { @@ -805,7 +819,7 @@ describe('ContentManagementService', () => { ); const initialParent = 'parent-id-0'; - const node = { + const node: any = { entry: { id: 'node-to-move-id', name: 'name', parentId: initialParent } }; const selection = [node]; @@ -841,7 +855,7 @@ describe('ContentManagementService', () => { const node = { entry: { id: 'node-to-move-id', name: 'name', parentId: initialParent } }; - const selection = [node]; + const selection = [node]; const childMoved = { entry: { id: 'child-of-node-to-move-id', name: 'child-name' } @@ -873,7 +887,7 @@ describe('ContentManagementService', () => { }) ); - const selection = [{ entry: { id: '1', name: 'name1' } }]; + const selection = [{ entry: { id: '1', name: 'name1' } }]; store.dispatch(new DeleteNodesAction(selection)); })); @@ -888,7 +902,7 @@ describe('ContentManagementService', () => { }) ); - const selection = [{ entry: { id: '1', name: 'name1' } }]; + const selection = [{ entry: { id: '1', name: 'name1' } }]; store.dispatch(new DeleteNodesAction(selection)); })); @@ -904,8 +918,8 @@ describe('ContentManagementService', () => { ); const selection = [ - { entry: { id: '1', name: 'name1' } }, - { entry: { id: '2', name: 'name2' } } + { entry: { id: '1', name: 'name1' } }, + { entry: { id: '2', name: 'name2' } } ]; store.dispatch(new DeleteNodesAction(selection)); @@ -922,8 +936,8 @@ describe('ContentManagementService', () => { ); const selection = [ - { entry: { id: '1', name: 'name1' } }, - { entry: { id: '2', name: 'name2' } } + { entry: { id: '1', name: 'name1' } }, + { entry: { id: '2', name: 'name2' } } ]; store.dispatch(new DeleteNodesAction(selection)); @@ -946,8 +960,8 @@ describe('ContentManagementService', () => { ); const selection = [ - { entry: { id: '1', name: 'name1' } }, - { entry: { id: '2', name: 'name2' } } + { entry: { id: '1', name: 'name1' } }, + { entry: { id: '2', name: 'name2' } } ]; store.dispatch(new DeleteNodesAction(selection)); @@ -976,9 +990,9 @@ describe('ContentManagementService', () => { ); const selection = [ - { entry: { id: '1', name: 'name1' } }, - { entry: { id: '2', name: 'name2' } }, - { entry: { id: '3', name: 'name3' } } + { entry: { id: '1', name: 'name1' } }, + { entry: { id: '2', name: 'name2' } }, + { entry: { id: '3', name: 'name3' } } ]; store.dispatch(new DeleteNodesAction(selection)); @@ -1004,7 +1018,7 @@ describe('ContentManagementService', () => { it('call purge nodes if selection is not empty', fakeAsync(() => { spyOn(contentApi, 'purgeDeletedNode').and.returnValue(of({})); - const selection = [{ entry: { id: '1' } }]; + const selection = [{ entry: { id: '1' } }]; store.dispatch(new PurgeDeletedNodesAction(selection)); expect(contentApi.purgeDeletedNode).toHaveBeenCalled(); @@ -1034,9 +1048,9 @@ describe('ContentManagementService', () => { }); const selection = [ - { entry: { id: '1', name: 'name1' } }, - { entry: { id: '2', name: 'name2' } }, - { entry: { id: '3', name: 'name3' } } + { entry: { id: '1', name: 'name1' } }, + { entry: { id: '2', name: 'name2' } }, + { entry: { id: '3', name: 'name3' } } ]; store.dispatch(new PurgeDeletedNodesAction(selection)); @@ -1069,10 +1083,10 @@ describe('ContentManagementService', () => { }); const selection = [ - { entry: { id: '1', name: 'name1' } }, - { entry: { id: '2', name: 'name2' } }, - { entry: { id: '3', name: 'name3' } }, - { entry: { id: '4', name: 'name4' } } + { entry: { id: '1', name: 'name1' } }, + { entry: { id: '2', name: 'name2' } }, + { entry: { id: '3', name: 'name3' } }, + { entry: { id: '4', name: 'name4' } } ]; store.dispatch(new PurgeDeletedNodesAction(selection)); @@ -1088,7 +1102,7 @@ describe('ContentManagementService', () => { spyOn(contentApi, 'purgeDeletedNode').and.returnValue(of({})); - const selection = [{ entry: { id: '1', name: 'name1' } }]; + const selection = [{ entry: { id: '1', name: 'name1' } }]; store.dispatch(new PurgeDeletedNodesAction(selection)); })); @@ -1103,7 +1117,7 @@ describe('ContentManagementService', () => { spyOn(contentApi, 'purgeDeletedNode').and.returnValue(throwError({})); - const selection = [{ entry: { id: '1', name: 'name1' } }]; + const selection = [{ entry: { id: '1', name: 'name1' } }]; store.dispatch(new PurgeDeletedNodesAction(selection)); })); @@ -1126,8 +1140,8 @@ describe('ContentManagementService', () => { }); const selection = [ - { entry: { id: '1', name: 'name1' } }, - { entry: { id: '2', name: 'name2' } } + { entry: { id: '1', name: 'name1' } }, + { entry: { id: '2', name: 'name2' } } ]; store.dispatch(new PurgeDeletedNodesAction(selection)); @@ -1151,8 +1165,8 @@ describe('ContentManagementService', () => { }); const selection = [ - { entry: { id: '1', name: 'name1' } }, - { entry: { id: '2', name: 'name2' } } + { entry: { id: '1', name: 'name1' } }, + { entry: { id: '2', name: 'name2' } } ]; store.dispatch(new PurgeDeletedNodesAction(selection)); @@ -1173,7 +1187,7 @@ describe('ContentManagementService', () => { it('does not restore nodes if selection has nodes without path', () => { spyOn(contentApi, 'restoreNode'); - const selection = [{ entry: { id: '1' } }]; + const selection = [{ entry: { id: '1' } }]; store.dispatch(new RestoreDeletedNodesAction(selection)); @@ -1198,7 +1212,7 @@ describe('ContentManagementService', () => { }; const selection = [ - { + { entry: { id: '1', path @@ -1234,7 +1248,7 @@ describe('ContentManagementService', () => { }; const selection = [ - { + { entry: { id: '1', path @@ -1269,7 +1283,7 @@ describe('ContentManagementService', () => { }; const selection = [ - { + { entry: { id: '1', path @@ -1324,9 +1338,9 @@ describe('ContentManagementService', () => { }; const selection = [ - { entry: { id: '1', name: 'name1', path } }, - { entry: { id: '2', name: 'name2', path } }, - { entry: { id: '3', name: 'name3', path } } + { entry: { id: '1', name: 'name1', path } }, + { entry: { id: '2', name: 'name2', path } }, + { entry: { id: '3', name: 'name3', path } } ]; store.dispatch(new RestoreDeletedNodesAction(selection)); @@ -1350,7 +1364,7 @@ describe('ContentManagementService', () => { ] }; - const selection = [{ entry: { id: '1', name: 'name1', path } }]; + const selection = [{ entry: { id: '1', name: 'name1', path } }]; store.dispatch(new RestoreDeletedNodesAction(selection)); })); @@ -1374,7 +1388,7 @@ describe('ContentManagementService', () => { ] }; - const selection = [{ entry: { id: '1', name: 'name1', path } }]; + const selection = [{ entry: { id: '1', name: 'name1', path } }]; store.dispatch(new RestoreDeletedNodesAction(selection)); })); @@ -1398,7 +1412,7 @@ describe('ContentManagementService', () => { ] }; - const selection = [{ entry: { id: '1', name: 'name1', path } }]; + const selection = [{ entry: { id: '1', name: 'name1', path } }]; store.dispatch(new RestoreDeletedNodesAction(selection)); })); @@ -1429,8 +1443,8 @@ describe('ContentManagementService', () => { }; const selection = [ - { entry: { id: '1', name: 'name1', path } }, - { entry: { id: '2', name: 'name2', path } } + { entry: { id: '1', name: 'name1', path } }, + { entry: { id: '2', name: 'name2', path } } ]; store.dispatch(new RestoreDeletedNodesAction(selection)); @@ -1453,7 +1467,7 @@ describe('ContentManagementService', () => { ] }; - const selection = [{ entry: { id: '1', name: 'name1', path } }]; + const selection = [{ entry: { id: '1', name: 'name1', path } }]; store.dispatch(new RestoreDeletedNodesAction(selection)); })); @@ -1476,7 +1490,7 @@ describe('ContentManagementService', () => { }; const selection = [ - { + { entry: { id: '1', name: 'name1', @@ -1492,7 +1506,7 @@ describe('ContentManagementService', () => { describe('Share Node', () => { it('should open dialog for nodes without requesting getNodeInfo', fakeAsync(() => { - const node = { entry: { id: '1', name: 'name1' } }; + const node = { entry: { id: '1', name: 'name1' } }; spyOn(contentApi, 'getNodeInfo').and.returnValue(of({})); spyOn(dialog, 'open').and.returnValue({ afterClosed() { @@ -1507,7 +1521,7 @@ describe('ContentManagementService', () => { })); it('should open dialog with getNodeInfo data when `id` property is missing', fakeAsync(() => { - const node = { entry: { nodeId: '1', name: 'name1' } }; + const node = { entry: { nodeId: '1', name: 'name1' } }; spyOn(contentApi, 'getNodeInfo').and.returnValue(of({})); spyOn(dialog, 'open').and.returnValue({ afterClosed() { @@ -1522,7 +1536,7 @@ describe('ContentManagementService', () => { })); it('should update node selection after dialog is closed', fakeAsync(() => { - const node = { entry: { id: '1', name: 'name1' } }; + const node = { entry: { id: '1', name: 'name1' } }; spyOn(store, 'dispatch').and.callThrough(); spyOn(dialog, 'open').and.returnValue({ afterClosed() { @@ -1538,7 +1552,7 @@ describe('ContentManagementService', () => { })); it('should emit event when node is un-shared', fakeAsync(() => { - const node = { entry: { id: '1', name: 'name1' } }; + const node = { entry: { id: '1', name: 'name1' } }; spyOn(contentManagementService.linksUnshared, 'next').and.callThrough(); spyOn(dialog, 'open').and.returnValue({ afterClosed: () => of(node) diff --git a/src/app/services/content-management.service.ts b/src/app/services/content-management.service.ts index f8aa5a146e..7a0c4e48e2 100644 --- a/src/app/services/content-management.service.ts +++ b/src/app/services/content-management.service.ts @@ -52,7 +52,7 @@ import { DeletedNodesPaging, PathInfoEntity, SiteBody -} from 'alfresco-js-api'; +} from '@alfresco/js-api'; import { NodePermissionService } from './node-permission.service'; import { NodeInfo, DeletedNodeInfo, DeleteStatus } from '../store/models'; import { ContentApiService } from './content-api.service'; @@ -132,7 +132,7 @@ export class ContentManagementService { managePermissions(node: MinimalNodeEntity): void { if (node && node.entry) { - const { nodeId, id } = node.entry; + const { nodeId, id } = node.entry; const siteId = node.entry['guid']; const targetId = siteId || nodeId || id; @@ -150,7 +150,7 @@ export class ContentManagementService { } } - manageVersions(node: MinimalNodeEntity) { + manageVersions(node: any) { if (node && node.entry) { // shared and favorite const id = node.entry.nodeId || (node).entry.guid; @@ -165,7 +165,7 @@ export class ContentManagementService { } } - private openVersionManagerDialog(node: MinimalNodeEntryEntity) { + private openVersionManagerDialog(node: any) { // workaround Shared if (node.isFile || node.nodeId) { this.dialogRef.open(NodeVersionsDialogComponent, { @@ -180,7 +180,7 @@ export class ContentManagementService { } } - shareNode(node: MinimalNodeEntity): void { + shareNode(node: any): void { if (node && node.entry) { // shared and favorite const id = node.entry.nodeId || (node).entry.guid; @@ -389,7 +389,7 @@ export class ContentManagementService { if (result === true) { const nodesToDelete: NodeInfo[] = nodes.map(node => { const { name } = node.entry; - const id = node.entry.nodeId || node.entry.id; + const id = (node).entry.nodeId || node.entry.id; return { id, @@ -973,7 +973,7 @@ export class ContentManagementService { }); } - private deleteNode(node: MinimalNodeEntity): Observable { + private deleteNode(node: any): Observable { const { name } = node.entry; const id = node.entry.nodeId || node.entry.id; @@ -1162,10 +1162,10 @@ export class ContentManagementService { return i18nMessageString; } - printFile(node: MinimalNodeEntity) { + printFile(node: any) { if (node && node.entry) { // shared and favorite - const id = node.entry.nodeId || (node).entry.guid || node.entry.id; + const id = node.entry.nodeId || node.entry.guid || node.entry.id; const mimeType = node.entry.content.mimeType; if (id) { diff --git a/src/app/services/data.service.ts b/src/app/services/data.service.ts index 18ad94c56c..847500f31a 100644 --- a/src/app/services/data.service.ts +++ b/src/app/services/data.service.ts @@ -31,7 +31,7 @@ import { AlfrescoApiService } from '@alfresco/adf-core'; import { Observable } from 'rxjs'; -import { PersonEntry, SearchRequest, ResultSetPaging } from 'alfresco-js-api'; +import { PersonEntry, SearchRequest, ResultSetPaging } from '@alfresco/js-api'; @Injectable({ providedIn: 'root' diff --git a/src/app/services/node-actions.service.spec.ts b/src/app/services/node-actions.service.spec.ts index 5fb1abc6ee..2534b4ba67 100644 --- a/src/app/services/node-actions.service.spec.ts +++ b/src/app/services/node-actions.service.spec.ts @@ -29,7 +29,7 @@ import { of, throwError } from 'rxjs'; import { AlfrescoApiService, TranslationService } from '@alfresco/adf-core'; import { DocumentListService } from '@alfresco/adf-content-services'; import { NodeActionsService } from './node-actions.service'; -import { MinimalNodeEntryEntity } from 'alfresco-js-api'; +import { MinimalNodeEntryEntity } from '@alfresco/js-api'; import { AppTestingModule } from '../testing/app-testing.module'; import { ContentApiService } from '../services/content-api.service'; @@ -44,7 +44,7 @@ class TestNode { nodeType?: string, properties?: any ) { - this.entry = {}; + this.entry = {}; this.entry.id = id || 'node-id'; this.entry.isFile = isFile; this.entry.isFolder = !isFile; @@ -241,14 +241,14 @@ describe('NodeActionsService', () => { describe('getEntryParentId', () => { it('should return the parentId, if that exists on the node entry', () => { const parentID = 'parent-id'; - const entry = { nodeId: '1234', parentId: parentID }; + const entry = { nodeId: '1234', parentId: parentID }; expect(service.getEntryParentId(entry)).toBe(parentID); }); it('should give the last element in path property, if parentId is missing and path exists on the node entry', () => { const firstParentId = 'parent-0-id'; - const entry = { + const entry = { nodeId: '1234', path: { elements: [{ id: 'parent-1-id' }, { id: firstParentId }] } }; diff --git a/src/app/services/node-actions.service.ts b/src/app/services/node-actions.service.ts index d0860d2b45..aa6e1f7fe2 100644 --- a/src/app/services/node-actions.service.ts +++ b/src/app/services/node-actions.service.ts @@ -41,8 +41,9 @@ import { import { MinimalNodeEntity, MinimalNodeEntryEntity, - SitePaging -} from 'alfresco-js-api'; + SitePaging, + Site +} from '@alfresco/js-api'; import { ContentApiService } from '../services/content-api.service'; import { catchError, map, mergeMap } from 'rxjs/operators'; @@ -217,24 +218,24 @@ export class NodeActionsService { contentEntities[0].entry ); - const customDropdown: SitePaging = { + const customDropdown = new SitePaging({ list: { entries: [ { - entry: { + entry: { guid: '-my-', title: 'APP.BROWSE.PERSONAL.SIDENAV_LINK.LABEL' } }, { - entry: { + entry: { guid: '-mysites-', title: 'APP.BROWSE.LIBRARIES.SIDENAV_LINK.LABEL' } } ] } - }; + }); const title = this.getTitleTranslation(action, contentEntities); @@ -340,7 +341,7 @@ export class NodeActionsService { } } } else if (node === null && this.isSitesDestinationAvailable) { - node = { + node = { name: this.translation.instant('APP.BROWSE.LIBRARIES.TITLE'), path: { elements: [] } }; diff --git a/src/app/store/actions/app.actions.ts b/src/app/store/actions/app.actions.ts index 249d46ffb9..880c81572a 100644 --- a/src/app/store/actions/app.actions.ts +++ b/src/app/store/actions/app.actions.ts @@ -24,7 +24,7 @@ */ import { Action } from '@ngrx/store'; -import { Node, Person } from 'alfresco-js-api'; +import { Node, Person } from '@alfresco/js-api'; import { AppState } from '../states'; export const SET_INITIAL_STATE = 'SET_INITIAL_STATE'; diff --git a/src/app/store/actions/favorite.actions.ts b/src/app/store/actions/favorite.actions.ts index be7b6e5954..3812b3119a 100644 --- a/src/app/store/actions/favorite.actions.ts +++ b/src/app/store/actions/favorite.actions.ts @@ -24,7 +24,7 @@ */ import { Action } from '@ngrx/store'; -import { MinimalNodeEntity } from 'alfresco-js-api'; +import { MinimalNodeEntity } from '@alfresco/js-api'; export const ADD_FAVORITE = 'ADD_FAVORITE'; export const REMOVE_FAVORITE = 'REMOVE_FAVORITE'; diff --git a/src/app/store/actions/library.actions.ts b/src/app/store/actions/library.actions.ts index d44a393587..fde0298bf5 100644 --- a/src/app/store/actions/library.actions.ts +++ b/src/app/store/actions/library.actions.ts @@ -24,7 +24,7 @@ */ import { Action } from '@ngrx/store'; -import { SiteBody } from 'alfresco-js-api'; +import { SiteBody } from '@alfresco/js-api'; export const DELETE_LIBRARY = 'DELETE_LIBRARY'; export const CREATE_LIBRARY = 'CREATE_LIBRARY'; diff --git a/src/app/store/actions/node.actions.ts b/src/app/store/actions/node.actions.ts index a487b52c69..586736125c 100644 --- a/src/app/store/actions/node.actions.ts +++ b/src/app/store/actions/node.actions.ts @@ -24,7 +24,7 @@ */ import { Action } from '@ngrx/store'; -import { MinimalNodeEntity } from 'alfresco-js-api'; +import { MinimalNodeEntity } from '@alfresco/js-api'; export const SET_SELECTED_NODES = 'SET_SELECTED_NODES'; export const DELETE_NODES = 'DELETE_NODES'; diff --git a/src/app/store/actions/router.actions.ts b/src/app/store/actions/router.actions.ts index c118a6bcd8..b2b5423f14 100644 --- a/src/app/store/actions/router.actions.ts +++ b/src/app/store/actions/router.actions.ts @@ -24,7 +24,7 @@ */ import { Action } from '@ngrx/store'; -import { MinimalNodeEntity } from 'alfresco-js-api'; +import { MinimalNodeEntity } from '@alfresco/js-api'; export const NAVIGATE_URL = 'NAVIGATE_URL'; export const NAVIGATE_ROUTE = 'NAVIGATE_ROUTE'; diff --git a/src/app/store/actions/viewer.actions.ts b/src/app/store/actions/viewer.actions.ts index cb02e33dea..fc478fb695 100644 --- a/src/app/store/actions/viewer.actions.ts +++ b/src/app/store/actions/viewer.actions.ts @@ -24,7 +24,7 @@ */ import { Action } from '@ngrx/store'; -import { MinimalNodeEntity } from 'alfresco-js-api'; +import { MinimalNodeEntity } from '@alfresco/js-api'; export const VIEW_FILE = 'VIEW_FILE'; diff --git a/src/app/store/effects/download.effects.ts b/src/app/store/effects/download.effects.ts index 4d402f46b4..8a49e1779d 100644 --- a/src/app/store/effects/download.effects.ts +++ b/src/app/store/effects/download.effects.ts @@ -31,7 +31,7 @@ import { map, take } from 'rxjs/operators'; import { DownloadNodesAction, DOWNLOAD_NODES } from '../actions'; import { NodeInfo } from '../models'; import { ContentApiService } from '../../services/content-api.service'; -import { MinimalNodeEntity } from 'alfresco-js-api'; +import { MinimalNodeEntity } from '@alfresco/js-api'; import { Store } from '@ngrx/store'; import { AppStore } from '../states'; import { appSelection } from '../selectors/app.selectors'; @@ -66,7 +66,7 @@ export class DownloadEffects { private downloadNodes(toDownload: Array) { const nodes = toDownload.map(node => { - const { id, nodeId, name, isFile, isFolder } = node.entry; + const { id, nodeId, name, isFile, isFolder } = node.entry; return { id: nodeId || id, diff --git a/src/app/store/effects/library.effects.ts b/src/app/store/effects/library.effects.ts index 1e9c66bae7..6d97d36b86 100644 --- a/src/app/store/effects/library.effects.ts +++ b/src/app/store/effects/library.effects.ts @@ -44,7 +44,6 @@ import { Store } from '@ngrx/store'; import { AppStore } from '../states'; import { appSelection } from '../selectors/app.selectors'; import { ContentApiService } from '../../services/content-api.service'; -import { SiteBody } from 'alfresco-js-api-node'; import { SnackbarErrorAction } from '../actions/snackbar.actions'; @Injectable() @@ -136,7 +135,7 @@ export class LibraryEffects { const { id } = selection.library.entry; const { title, description, visibility } = action.payload; - const siteBody = { + const siteBody = { title, description, visibility diff --git a/src/app/store/effects/router.effects.ts b/src/app/store/effects/router.effects.ts index 82136d7bdd..a70c2954fc 100644 --- a/src/app/store/effects/router.effects.ts +++ b/src/app/store/effects/router.effects.ts @@ -26,7 +26,7 @@ import { Injectable } from '@angular/core'; import { Router } from '@angular/router'; import { Actions, Effect, ofType } from '@ngrx/effects'; -import { MinimalNodeEntryEntity, PathInfoEntity } from 'alfresco-js-api'; +import { MinimalNodeEntryEntity, PathInfoEntity } from '@alfresco/js-api'; import { map } from 'rxjs/operators'; import { NavigateRouteAction, diff --git a/src/app/store/effects/viewer.effects.ts b/src/app/store/effects/viewer.effects.ts index 7baa24268a..ff76199a2b 100644 --- a/src/app/store/effects/viewer.effects.ts +++ b/src/app/store/effects/viewer.effects.ts @@ -56,7 +56,7 @@ export class ViewerEffects { ofType(VIEW_FILE), map(action => { if (action.payload && action.payload.entry) { - const { id, nodeId, isFile } = action.payload.entry; + const { id, nodeId, isFile } = action.payload.entry; if (isFile || nodeId) { this.displayPreview(nodeId || id, action.parentId); @@ -67,7 +67,7 @@ export class ViewerEffects { .pipe(take(1)) .subscribe(result => { if (result.selection && result.selection.file) { - const { id, nodeId, isFile } = result.selection.file.entry; + const { id, nodeId, isFile } = result.selection.file.entry; if (isFile || nodeId) { const parentId = result.folder ? result.folder.id : null; diff --git a/src/app/store/reducers/app.reducer.ts b/src/app/store/reducers/app.reducer.ts index c1b8d9f86a..a2b7a6d7b2 100644 --- a/src/app/store/reducers/app.reducer.ts +++ b/src/app/store/reducers/app.reducer.ts @@ -189,7 +189,7 @@ function updateSelectedNodes( last = nodes[nodes.length - 1]; if (nodes.length === 1) { - file = nodes.find(entity => { + file = nodes.find((entity: any) => { // workaround Shared return entity.entry.isFile || entity.entry.nodeId ? true : false; }); @@ -197,7 +197,9 @@ function updateSelectedNodes( } } - const libraries = [...action.payload].filter((node: any) => node.isLibrary); + const libraries: any[] = [...action.payload].filter( + (node: any) => node.isLibrary + ); if (libraries.length === 1) { library = libraries[0]; } From b61b54d5e910b7d42a4c0eb623276f61a07bb410 Mon Sep 17 00:00:00 2001 From: Adina Parpalita Date: Tue, 22 Jan 2019 18:09:35 +0200 Subject: [PATCH 026/259] [ACA-820] add tests for Copy content (#899) * add tests for Copy content * fix * forgot some ids * update expected favorites number --- e2e/components/data-table/data-table.ts | 18 +- e2e/components/dialog/copy-move-dialog.ts | 7 + e2e/suites/actions/copy.test.ts | 560 ++++++++++++++++++++++ 3 files changed, 578 insertions(+), 7 deletions(-) create mode 100755 e2e/suites/actions/copy.test.ts diff --git a/e2e/components/data-table/data-table.ts b/e2e/components/data-table/data-table.ts index c78cdca493..2241d01f4f 100755 --- a/e2e/components/data-table/data-table.ts +++ b/e2e/components/data-table/data-table.ts @@ -157,12 +157,16 @@ export class DataTable extends Component { return this.getRows().get(nth - 1); } - getRowByName(name: string) { + getRowByName(name: string, location: string = '') { + if (location) { + return this.body.all(by.cssContainingText(DataTable.selectors.row, name)) + .filter(async (elem) => await browser.isElementPresent(elem.element(by.cssContainingText(DataTable.selectors.cell, location)))); + } return this.body.element(by.cssContainingText(DataTable.selectors.row, name)); } - getRowFirstCell(name: string) { - return this.getRowByName(name).all(by.css(DataTable.selectors.cell)).get(0); + getRowFirstCell(name: string, location: string = '') { + return this.getRowByName(name, location).all(by.css(DataTable.selectors.cell)).get(0); } getRowNameCell(name: string) { @@ -201,9 +205,9 @@ export class DataTable extends Component { } } - async selectItem(name: string) { + async selectItem(name: string, location: string = '') { try{ - const item = this.getRowFirstCell(name); + const item = this.getRowFirstCell(name, location); await item.click(); } catch (e) { @@ -215,11 +219,11 @@ export class DataTable extends Component { await this.getNameLink(itemName).click(); } - async selectMultipleItems(names: string[]) { + async selectMultipleItems(names: string[], location: string = '') { await this.clearSelection(); await browser.actions().sendKeys(protractor.Key.COMMAND).perform(); for (const name of names) { - await this.selectItem(name); + await this.selectItem(name, location); } await browser.actions().sendKeys(protractor.Key.NULL).perform(); } diff --git a/e2e/components/dialog/copy-move-dialog.ts b/e2e/components/dialog/copy-move-dialog.ts index e4ef948eab..40540c1d38 100755 --- a/e2e/components/dialog/copy-move-dialog.ts +++ b/e2e/components/dialog/copy-move-dialog.ts @@ -102,6 +102,13 @@ export class CopyMoveDialog extends Component { return this.dataTable.element(by.cssContainingText('.adf-name-location-cell', folderName)); } + async doubleClickOnRow(name: string) { + const item = this.getRow(name); + await Utils.waitUntilElementClickable(item); + await browser.actions().mouseMove(item).perform(); + await browser.actions().click().click().perform(); + } + async selectLocation(location: 'Personal Files' | 'File Libraries') { await this.locationDropDown.click(); await this.waitForDropDownToOpen(); diff --git a/e2e/suites/actions/copy.test.ts b/e2e/suites/actions/copy.test.ts new file mode 100755 index 0000000000..924bc7dc42 --- /dev/null +++ b/e2e/suites/actions/copy.test.ts @@ -0,0 +1,560 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2018 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { LoginPage, BrowsingPage } from '../../pages/pages'; +import { CopyMoveDialog } from './../../components/dialog/copy-move-dialog'; +import { RepoClient } from '../../utilities/repo-client/repo-client'; +import { Utils } from '../../utilities/utils'; + +describe('Copy', () => { + const username = `user-${Utils.random()}`; + + const source = `source-${Utils.random()}`; let sourceId; + const destinationPF = `destinationPersonal-${Utils.random()}`; let destinationIdPF; + const destinationRF = `destinationRecent-${Utils.random()}`; let destinationIdRF; + const destinationSF = `destinationShared-${Utils.random()}`; let destinationIdSF; + const destinationFav = `destinationFav-${Utils.random()}`; let destinationIdFav; + + const file1 = `file1-${Utils.random()}.txt`; let file1Id; + + const folder1 = `folder1-${Utils.random()}`; let folder1Id; + const fileInFolder = `fileInFolder-${Utils.random()}.txt`; + + const file2 = `file2-${Utils.random()}.txt`; let file2Id; + const file3 = `file3-${Utils.random()}.txt`; let file3Id; + + const existingFile = `existing-${Utils.random()}`; let existingFileId; + + const existingFolder = `existing-${Utils.random()}`; + let existingId1, existingId2, existingId2RF, existingId2SF, existingId2Fav; + const file2InFolder = `file2InFolder-${Utils.random()}.txt`; + const file3InFolder = `file3InFolder-${Utils.random()}.txt`; + + const siteName = `site-${Utils.random()}`; + const folderSitePF = `folderSitePersonal-${Utils.random()}`; + const folderSiteRF = `folderSiteRecent-${Utils.random()}`; + const folderSiteSF = `folderSiteShared-${Utils.random()}`; + const folderSiteFav = `folderSiteFav-${Utils.random()}`; + + const apis = { + admin: new RepoClient(), + user: new RepoClient(username, username) + }; + + const loginPage = new LoginPage(); + const page = new BrowsingPage(); + const { dataTable, toolbar } = page; + const copyDialog = new CopyMoveDialog(); + + beforeAll(async (done) => { + await apis.admin.people.createUser({ username }); + + sourceId = (await apis.user.nodes.createFolder(source)).entry.id; + destinationIdPF = (await apis.user.nodes.createFolder(destinationPF)).entry.id; + destinationIdRF = (await apis.user.nodes.createFolder(destinationRF)).entry.id; + destinationIdSF = (await apis.user.nodes.createFolder(destinationSF)).entry.id; + destinationIdFav = (await apis.user.nodes.createFolder(destinationFav)).entry.id; + + file1Id = (await apis.user.nodes.createFile(file1, sourceId)).entry.id; + await apis.user.shared.shareFileById(file1Id); + await apis.user.favorites.addFavoriteById('file', file1Id); + + folder1Id = (await apis.user.nodes.createFolder(folder1, sourceId)).entry.id; + await apis.user.nodes.createFile(fileInFolder, folder1Id); + await apis.user.favorites.addFavoriteById('folder', folder1Id); + + file2Id = (await apis.user.nodes.createFile(file2, sourceId)).entry.id; + file3Id = (await apis.user.nodes.createFile(file3, sourceId)).entry.id; + await apis.user.shared.shareFileById(file2Id); + await apis.user.shared.shareFileById(file3Id); + await apis.user.favorites.addFavoriteById('file', file2Id); + await apis.user.favorites.addFavoriteById('file', file3Id); + + existingFileId = (await apis.user.nodes.createFile(`${existingFile}.txt`, sourceId)).entry.id; + await apis.user.shared.shareFileById(existingFileId); + await apis.user.favorites.addFavoriteById('file', existingFileId); + await apis.user.nodes.createFile(`${existingFile}.txt`, destinationIdPF); + await apis.user.nodes.createFile(`${existingFile}.txt`, destinationIdRF); + await apis.user.nodes.createFile(`${existingFile}.txt`, destinationIdSF); + await apis.user.nodes.createFile(`${existingFile}.txt`, destinationIdFav); + + existingId1 = (await apis.user.nodes.createFolder(existingFolder, sourceId)).entry.id; + existingId2 = (await apis.user.nodes.createFolder(existingFolder, destinationIdPF)).entry.id; + existingId2RF = (await apis.user.nodes.createFolder(existingFolder, destinationIdRF)).entry.id; + existingId2SF = (await apis.user.nodes.createFolder(existingFolder, destinationIdSF)).entry.id; + existingId2Fav = (await apis.user.nodes.createFolder(existingFolder, destinationIdFav)).entry.id; + await apis.user.nodes.createFile(file2InFolder, existingId1); + await apis.user.nodes.createFile(file3InFolder, existingId2); + await apis.user.nodes.createFile(file3InFolder, existingId2RF); + await apis.user.nodes.createFile(file3InFolder, existingId2SF); + await apis.user.nodes.createFile(file3InFolder, existingId2Fav); + await apis.user.favorites.addFavoriteById('folder', existingId1); + + await apis.user.sites.createSite(siteName); + const docLibId = await apis.user.sites.getDocLibId(siteName); + await apis.user.nodes.createFolder(folderSitePF, docLibId); + await apis.user.nodes.createFolder(folderSiteRF, docLibId); + await apis.user.nodes.createFolder(folderSiteSF, docLibId); + await apis.user.nodes.createFolder(folderSiteFav, docLibId); + + await apis.user.shared.waitForApi({ expect: 4 }); + await apis.user.favorites.waitForApi({ expect: 7 }); + + await loginPage.loginWith(username); + done(); + }); + + afterAll(async (done) => { + await apis.user.nodes.deleteNodeById(sourceId); + await apis.user.nodes.deleteNodeById(destinationIdPF); + await apis.user.nodes.deleteNodeById(destinationIdRF); + await apis.user.nodes.deleteNodeById(destinationIdSF); + await apis.user.nodes.deleteNodeById(destinationIdFav); + await apis.user.sites.deleteSite(siteName); + done(); + }); + + describe('from Personal Files', () => { + beforeEach(async (done) => { + await Utils.pressEscape(); + await page.clickPersonalFilesAndWait(); + await dataTable.doubleClickOnRowByName(source); + done(); + }); + + it('Copy a file - [C217135]', async () => { + await dataTable.selectItem(file1); + await toolbar.clickMoreActionsCopy(); + await copyDialog.selectLocation('Personal Files'); + await copyDialog.selectDestination(destinationPF); + await copyDialog.clickCopy(); + const msg = await page.getSnackBarMessage(); + expect(msg).toContain('Copied 1 item'); + expect(msg).toContain('Undo'); + + await copyDialog.waitForDialogToClose(); + expect(await dataTable.isItemPresent(file1)).toBe(true, `${file1} not present in source folder`); + await page.clickPersonalFilesAndWait(); + await dataTable.doubleClickOnRowByName(destinationPF); + expect(await dataTable.isItemPresent(file1)).toBe(true, `${file1} not present in destination folder`); + }); + + it('Copy a folder with content - [C291888]', async () => { + await dataTable.selectItem(folder1); + await toolbar.clickMoreActionsCopy(); + await copyDialog.selectLocation('Personal Files'); + await copyDialog.selectDestination(destinationPF); + await copyDialog.clickCopy(); + const msg = await page.getSnackBarMessage(); + expect(msg).toContain('Copied 1 item'); + expect(msg).toContain('Undo'); + + await copyDialog.waitForDialogToClose(); + expect(await dataTable.isItemPresent(folder1)).toBe(true, `${folder1} not present in source folder`); + await page.clickPersonalFilesAndWait(); + await dataTable.doubleClickOnRowByName(destinationPF); + expect(await dataTable.isItemPresent(folder1)).toBe(true, `${folder1} not present in destination folder`); + expect(await dataTable.isItemPresent(fileInFolder)).toBe(false, `${fileInFolder} is present in destination`); + + await dataTable.doubleClickOnRowByName(folder1); + expect(await dataTable.isItemPresent(fileInFolder)).toBe(true, `${fileInFolder} is not present in parent folder`); + }); + + it('Copy multiple items - [C291889]', async () => { + await dataTable.selectMultipleItems([file2, file3]); + await toolbar.clickMoreActionsCopy(); + await copyDialog.selectLocation('Personal Files'); + await copyDialog.selectDestination(destinationPF); + await copyDialog.clickCopy(); + const msg = await page.getSnackBarMessage(); + expect(msg).toContain('Copied 2 items'); + expect(msg).toContain('Undo'); + + await copyDialog.waitForDialogToClose(); + expect(await dataTable.isItemPresent(file2)).toBe(true, `${file2} not present in source folder`); + expect(await dataTable.isItemPresent(file3)).toBe(true, `${file3} not present in source folder`); + await page.clickPersonalFilesAndWait(); + await dataTable.doubleClickOnRowByName(destinationPF); + expect(await dataTable.isItemPresent(file2)).toBe(true, `${file2} not present in destination folder`); + expect(await dataTable.isItemPresent(file3)).toBe(true, `${file3} not present in destination folder`); + }); + + it('Copy a file with a name that already exists on the destination - [C217137]', async () => { + await dataTable.selectItem(existingFile); + await toolbar.clickMoreActionsCopy(); + await copyDialog.selectLocation('Personal Files'); + await copyDialog.selectDestination(destinationPF); + await copyDialog.clickCopy(); + const msg = await page.getSnackBarMessage(); + expect(msg).toContain('Copied 1 item'); + expect(msg).toContain('Undo'); + + await copyDialog.waitForDialogToClose(); + expect(await dataTable.isItemPresent(`${existingFile}.txt`)).toBe(true, `${existingFile}.txt not present in source folder`); + await page.clickPersonalFilesAndWait(); + await dataTable.doubleClickOnRowByName(destinationPF); + expect(await dataTable.isItemPresent(`${existingFile}.txt`)).toBe(true, `${existingFile}.txt not present in destination folder`); + expect(await dataTable.isItemPresent(`${existingFile}-1.txt`)).toBe(true, `${existingFile}-1.txt not present in destination folder`); + }); + + it('Copy a folder with a name that already exists on the destination - [C217138]', async () => { + await dataTable.selectItem(existingFolder); + await toolbar.clickMoreActionsCopy(); + await copyDialog.selectLocation('Personal Files'); + await copyDialog.selectDestination(destinationPF); + await copyDialog.clickCopy(); + const msg = await page.getSnackBarMessage(); + expect(msg).toContain('Copied 1 item'); + expect(msg).toContain('Undo'); + + await copyDialog.waitForDialogToClose(); + expect(await dataTable.isItemPresent(existingFolder)).toBe(true, `${existingFolder} not present in source folder`); + await page.clickPersonalFilesAndWait(); + await dataTable.doubleClickOnRowByName(destinationPF); + expect(await dataTable.isItemPresent(existingFolder)).toBe(true, `${existingFolder} not present in destination folder`); + await dataTable.doubleClickOnRowByName(existingFolder); + expect(await dataTable.isItemPresent(file2InFolder)).toBe(true, `${file2InFolder} not present in destination folder`); + expect(await dataTable.isItemPresent(file3InFolder)).toBe(true, `${file3InFolder} not present in destination folder`); + }); + + it('Copy items into a library - [C280282]', async () => { + await dataTable.selectMultipleItems([file1, folder1]); + await toolbar.clickMoreActionsCopy(); + await copyDialog.selectLocation('File Libraries'); + await copyDialog.doubleClickOnRow(siteName); + await copyDialog.doubleClickOnRow('documentLibrary'); + await copyDialog.selectDestination(folderSitePF); + await copyDialog.clickCopy(); + const msg = await page.getSnackBarMessage(); + expect(msg).toContain('Copied 2 items'); + expect(msg).toContain('Undo'); + + await copyDialog.waitForDialogToClose(); + expect(await dataTable.isItemPresent(file1)).toBe(true, `${file1} not present in source folder`); + expect(await dataTable.isItemPresent(folder1)).toBe(true, `${folder1} not present in source folder`); + + await page.goToMyLibraries(); + await dataTable.doubleClickOnRowByName(siteName); + await dataTable.doubleClickOnRowByName(folderSitePF); + + expect(await dataTable.isItemPresent(file1)).toBe(true, `${file1} not present in destination folder`); + expect(await dataTable.isItemPresent(folder1)).toBe(true, `${folder1} not present in destination folder`); + await dataTable.doubleClickOnRowByName(folder1); + expect(await dataTable.isItemPresent(fileInFolder)).toBe(true, `${fileInFolder} not present in parent folder`); + }); + }); + + describe('from Recent Files', () => { + beforeEach(async (done) => { + await Utils.pressEscape(); + await page.clickRecentFilesAndWait(); + done(); + }); + + it('Copy a file - [C280194]', async () => { + await dataTable.selectItem(file1, source); + await toolbar.clickMoreActionsCopy(); + await copyDialog.selectLocation('Personal Files'); + await copyDialog.selectDestination(destinationRF); + await copyDialog.clickCopy(); + const msg = await page.getSnackBarMessage(); + expect(msg).toContain('Copied 1 item'); + expect(msg).toContain('Undo'); + + await copyDialog.waitForDialogToClose(); + await page.clickPersonalFilesAndWait(); + await dataTable.doubleClickOnRowByName(destinationRF); + expect(await dataTable.isItemPresent(file1)).toBe(true, `${file1} not present in destination folder`); + }); + + it('Copy multiple items - [C280201]', async () => { + await dataTable.selectMultipleItems([file2, file3], source); + await toolbar.clickMoreActionsCopy(); + await copyDialog.selectLocation('Personal Files'); + await copyDialog.selectDestination(destinationRF); + await copyDialog.clickCopy(); + const msg = await page.getSnackBarMessage(); + expect(msg).toContain('Copied 2 items'); + expect(msg).toContain('Undo'); + + await copyDialog.waitForDialogToClose(); + await page.clickPersonalFilesAndWait(); + await dataTable.doubleClickOnRowByName(destinationRF); + expect(await dataTable.isItemPresent(file2)).toBe(true, `${file2} not present in destination folder`); + expect(await dataTable.isItemPresent(file3)).toBe(true, `${file3} not present in destination folder`); + }); + + it('Copy a file with a name that already exists on the destination - [C280196]', async () => { + await dataTable.selectItem(existingFile, source); + await toolbar.clickMoreActionsCopy(); + await copyDialog.selectLocation('Personal Files'); + await copyDialog.selectDestination(destinationRF); + await copyDialog.clickCopy(); + const msg = await page.getSnackBarMessage(); + expect(msg).toContain('Copied 1 item'); + expect(msg).toContain('Undo'); + + await copyDialog.waitForDialogToClose(); + await page.clickPersonalFilesAndWait(); + await dataTable.doubleClickOnRowByName(destinationRF); + expect(await dataTable.isItemPresent(`${existingFile}.txt`)).toBe(true, `${existingFile}.txt not present in destination folder`); + expect(await dataTable.isItemPresent(`${existingFile}-1.txt`)).toBe(true, `${existingFile}-1.txt not present in destination folder`); + }); + + it('Copy items into a library - [C291899]', async () => { + await dataTable.selectItem(file1, source); + await toolbar.clickMoreActionsCopy(); + await copyDialog.selectLocation('File Libraries'); + await copyDialog.doubleClickOnRow(siteName); + await copyDialog.doubleClickOnRow('documentLibrary'); + await copyDialog.selectDestination(folderSiteRF); + await copyDialog.clickCopy(); + const msg = await page.getSnackBarMessage(); + expect(msg).toContain('Copied 1 item'); + expect(msg).toContain('Undo'); + + await copyDialog.waitForDialogToClose(); + expect(await dataTable.isItemPresent(file1)).toBe(true, `${file1} not present in source folder`); + + await page.goToMyLibraries(); + await dataTable.doubleClickOnRowByName(siteName); + await dataTable.doubleClickOnRowByName(folderSiteRF); + + expect(await dataTable.isItemPresent(file1)).toBe(true, `${file1} not present in destination folder`); + }); + }); + + describe('from Shared Files', () => { + beforeEach(async (done) => { + await Utils.pressEscape(); + await page.clickSharedFilesAndWait(); + done(); + }); + + it('Copy a file - [C280206]', async () => { + await dataTable.selectItem(file1, source); + await toolbar.clickMoreActionsCopy(); + await copyDialog.selectLocation('Personal Files'); + await copyDialog.selectDestination(destinationSF); + await copyDialog.clickCopy(); + const msg = await page.getSnackBarMessage(); + expect(msg).toContain('Copied 1 item'); + expect(msg).toContain('Undo'); + + await copyDialog.waitForDialogToClose(); + await page.clickPersonalFilesAndWait(); + await dataTable.doubleClickOnRowByName(destinationSF); + expect(await dataTable.isItemPresent(file1)).toBe(true, `${file1} not present in destination folder`); + }); + + it('Copy multiple items - [C280213]', async () => { + await dataTable.selectMultipleItems([file2, file3], source); + await toolbar.clickMoreActionsCopy(); + await copyDialog.selectLocation('Personal Files'); + await copyDialog.selectDestination(destinationSF); + await copyDialog.clickCopy(); + const msg = await page.getSnackBarMessage(); + expect(msg).toContain('Copied 2 items'); + expect(msg).toContain('Undo'); + + await copyDialog.waitForDialogToClose(); + await page.clickPersonalFilesAndWait(); + await dataTable.doubleClickOnRowByName(destinationSF); + expect(await dataTable.isItemPresent(file2)).toBe(true, `${file2} not present in destination folder`); + expect(await dataTable.isItemPresent(file3)).toBe(true, `${file3} not present in destination folder`); + }); + + it('Copy a file with a name that already exists on the destination - [C280208]', async () => { + await dataTable.selectItem(existingFile, source); + await toolbar.clickMoreActionsCopy(); + await copyDialog.selectLocation('Personal Files'); + await copyDialog.selectDestination(destinationSF); + await copyDialog.clickCopy(); + const msg = await page.getSnackBarMessage(); + expect(msg).toContain('Copied 1 item'); + expect(msg).toContain('Undo'); + + await copyDialog.waitForDialogToClose(); + await page.clickPersonalFilesAndWait(); + await dataTable.doubleClickOnRowByName(destinationSF); + expect(await dataTable.isItemPresent(`${existingFile}.txt`)).toBe(true, `${existingFile}.txt not present in destination folder`); + expect(await dataTable.isItemPresent(`${existingFile}-1.txt`)).toBe(true, `${existingFile}-1.txt not present in destination folder`); + }); + + it('Copy items into a library - [C291900]', async () => { + await dataTable.selectItem(file1, source); + await toolbar.clickMoreActionsCopy(); + await copyDialog.selectLocation('File Libraries'); + await copyDialog.doubleClickOnRow(siteName); + await copyDialog.doubleClickOnRow('documentLibrary'); + await copyDialog.selectDestination(folderSiteSF); + await copyDialog.clickCopy(); + const msg = await page.getSnackBarMessage(); + expect(msg).toContain('Copied 1 item'); + expect(msg).toContain('Undo'); + + await copyDialog.waitForDialogToClose(); + expect(await dataTable.isItemPresent(file1)).toBe(true, `${file1} not present in source folder`); + + await page.goToMyLibraries(); + await dataTable.doubleClickOnRowByName(siteName); + await dataTable.doubleClickOnRowByName(folderSiteSF); + + expect(await dataTable.isItemPresent(file1)).toBe(true, `${file1} not present in destination folder`); + }); + }); + + describe('from Favorites', () => { + beforeEach(async (done) => { + await Utils.pressEscape(); + await page.clickFavoritesAndWait(); + done(); + }); + + it('Copy a file - [C280218]', async () => { + await dataTable.selectItem(file1); + await toolbar.clickMoreActionsCopy(); + await copyDialog.selectLocation('Personal Files'); + await copyDialog.selectDestination(destinationFav); + await copyDialog.clickCopy(); + const msg = await page.getSnackBarMessage(); + expect(msg).toContain('Copied 1 item'); + expect(msg).toContain('Undo'); + + await copyDialog.waitForDialogToClose(); + expect(await dataTable.isItemPresent(file1)).toBe(true, `${file1} not present in source folder`); + await page.clickPersonalFilesAndWait(); + await dataTable.doubleClickOnRowByName(destinationFav); + expect(await dataTable.isItemPresent(file1)).toBe(true, `${file1} not present in destination folder`); + }); + + it('Copy a folder with content - [C280219]', async () => { + await dataTable.selectItem(folder1); + await toolbar.clickMoreActionsCopy(); + await copyDialog.selectLocation('Personal Files'); + await copyDialog.selectDestination(destinationFav); + await copyDialog.clickCopy(); + const msg = await page.getSnackBarMessage(); + expect(msg).toContain('Copied 1 item'); + expect(msg).toContain('Undo'); + + await copyDialog.waitForDialogToClose(); + expect(await dataTable.isItemPresent(folder1)).toBe(true, `${folder1} not present in source folder`); + await page.clickPersonalFilesAndWait(); + await dataTable.doubleClickOnRowByName(destinationFav); + expect(await dataTable.isItemPresent(folder1)).toBe(true, `${folder1} not present in destination folder`); + expect(await dataTable.isItemPresent(fileInFolder)).toBe(false, `${fileInFolder} is present in destination`); + + await dataTable.doubleClickOnRowByName(folder1); + expect(await dataTable.isItemPresent(fileInFolder)).toBe(true, `${fileInFolder} is not present in parent folder`); + }); + + it('Copy multiple items - [C280225]', async () => { + await dataTable.selectMultipleItems([file2, file3]); + await toolbar.clickMoreActionsCopy(); + await copyDialog.selectLocation('Personal Files'); + await copyDialog.selectDestination(destinationFav); + await copyDialog.clickCopy(); + const msg = await page.getSnackBarMessage(); + expect(msg).toContain('Copied 2 items'); + expect(msg).toContain('Undo'); + + await copyDialog.waitForDialogToClose(); + expect(await dataTable.isItemPresent(file2)).toBe(true, `${file2} not present in source folder`); + expect(await dataTable.isItemPresent(file3)).toBe(true, `${file3} not present in source folder`); + await page.clickPersonalFilesAndWait(); + await dataTable.doubleClickOnRowByName(destinationFav); + expect(await dataTable.isItemPresent(file2)).toBe(true, `${file2} not present in destination folder`); + expect(await dataTable.isItemPresent(file3)).toBe(true, `${file3} not present in destination folder`); + }); + + it('Copy a file with a name that already exists on the destination - [C280220]', async () => { + await dataTable.selectItem(existingFile); + await toolbar.clickMoreActionsCopy(); + await copyDialog.selectLocation('Personal Files'); + await copyDialog.selectDestination(destinationFav); + await copyDialog.clickCopy(); + const msg = await page.getSnackBarMessage(); + expect(msg).toContain('Copied 1 item'); + expect(msg).toContain('Undo'); + + await copyDialog.waitForDialogToClose(); + expect(await dataTable.isItemPresent(`${existingFile}.txt`)).toBe(true, `${existingFile}.txt not present in source folder`); + await page.clickPersonalFilesAndWait(); + await dataTable.doubleClickOnRowByName(destinationFav); + expect(await dataTable.isItemPresent(`${existingFile}.txt`)).toBe(true, `${existingFile}.txt not present in destination folder`); + expect(await dataTable.isItemPresent(`${existingFile}-1.txt`)).toBe(true, `${existingFile}-1.txt not present in destination folder`); + }); + + it('Copy a folder with a name that already exists on the destination - [C280221]', async () => { + await dataTable.selectItem(existingFolder); + await toolbar.clickMoreActionsCopy(); + await copyDialog.selectLocation('Personal Files'); + await copyDialog.selectDestination(destinationFav); + await copyDialog.clickCopy(); + const msg = await page.getSnackBarMessage(); + expect(msg).toContain('Copied 1 item'); + expect(msg).toContain('Undo'); + + await copyDialog.waitForDialogToClose(); + expect(await dataTable.isItemPresent(existingFolder)).toBe(true, `${existingFolder} not present in source folder`); + await page.clickPersonalFilesAndWait(); + await dataTable.doubleClickOnRowByName(destinationFav); + expect(await dataTable.isItemPresent(existingFolder)).toBe(true, `${existingFolder} not present in destination folder`); + await dataTable.doubleClickOnRowByName(existingFolder); + expect(await dataTable.isItemPresent(file2InFolder)).toBe(true, `${file2InFolder} not present in destination folder`); + expect(await dataTable.isItemPresent(file3InFolder)).toBe(true, `${file3InFolder} not present in destination folder`); + }); + + it('Copy items into a library - [C291901]', async () => { + await dataTable.selectMultipleItems([file1, folder1], source); + await toolbar.clickMoreActionsCopy(); + await copyDialog.selectLocation('File Libraries'); + await copyDialog.doubleClickOnRow(siteName); + await copyDialog.doubleClickOnRow('documentLibrary'); + await copyDialog.selectDestination(folderSiteFav); + await copyDialog.clickCopy(); + const msg = await page.getSnackBarMessage(); + expect(msg).toContain('Copied 2 items'); + expect(msg).toContain('Undo'); + + await copyDialog.waitForDialogToClose(); + expect(await dataTable.isItemPresent(file1)).toBe(true, `${file1} not present in source folder`); + expect(await dataTable.isItemPresent(folder1)).toBe(true, `${folder1} not present in source folder`); + + await page.goToMyLibraries(); + await dataTable.doubleClickOnRowByName(siteName); + await dataTable.doubleClickOnRowByName(folderSiteFav); + + expect(await dataTable.isItemPresent(file1)).toBe(true, `${file1} not present in destination folder`); + expect(await dataTable.isItemPresent(folder1)).toBe(true, `${folder1} not present in destination folder`); + await dataTable.doubleClickOnRowByName(folder1); + expect(await dataTable.isItemPresent(fileInFolder)).toBe(true, `${fileInFolder} not present in parent folder`); + }); + }); + + xit(''); + +}); From a12c60337ddc177e329eaebd30e5649ef030f8bf Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Tue, 22 Jan 2019 16:43:26 +0000 Subject: [PATCH 027/259] support for SSO settings (#905) --- src/app.config.json | 2 +- .../settings/settings.component.html | 60 ++++++++++++------- .../components/settings/settings.component.ts | 42 +++++++++++-- 3 files changed, 75 insertions(+), 29 deletions(-) diff --git a/src/app.config.json b/src/app.config.json index 3205c49636..dc8b4edc82 100644 --- a/src/app.config.json +++ b/src/app.config.json @@ -4,7 +4,7 @@ "providers": "ECM", "authType": "BASIC", "oauth2": { - "host": "http://localhost:8081/auth/realms/alfresco", + "host": "http://localhost:4200/auth/realms/alfresco", "clientId": "alfresco", "scope": "openid", "secret": "", diff --git a/src/app/components/settings/settings.component.html b/src/app/components/settings/settings.component.html index 0f9022415f..9dd0370305 100644 --- a/src/app/components/settings/settings.component.html +++ b/src/app/components/settings/settings.component.html @@ -23,14 +23,9 @@ (ngSubmit)="apply(form.value, form.valid)" >
- - + + ACS Repository URL + {{ 'APP.SETTINGS.INVALID-VALUE-FORMAT' | translate }} @@ -40,6 +35,23 @@
+
+ + Authentication Type + + Basic + OAuth (Identity Service) + + +
+ +
+ + Alfresco Identity Service URL + + +
+
+ `, + encapsulation: ViewEncapsulation.None, + host: { class: 'app-toggle-edit-offline' } +}) +export class ToggleEditOfflineComponent implements OnInit { + selection: MinimalNodeEntity; + + constructor(private store: Store) {} + + ngOnInit() { + this.store.select(appSelection).subscribe(({ file }) => { + this.selection = file; + }); + } + + onToggleEvent(isNodeLocked: boolean) { + if (isNodeLocked) { + this.store.dispatch(new DownloadNodesAction([this.selection])); + } + this.store.dispatch(new EditOfflineAction(this.selection)); + } + + onError() { + this.store.dispatch( + new SnackbarErrorAction('APP.MESSAGES.ERRORS.LOCK_NODE', { + fileName: this.selection.entry.name + }) + ); + } +} diff --git a/src/app/components/toolbar/toolbar.module.ts b/src/app/components/toolbar/toolbar.module.ts index 4bbd9f2957..aae49ac549 100644 --- a/src/app/components/toolbar/toolbar.module.ts +++ b/src/app/components/toolbar/toolbar.module.ts @@ -38,6 +38,7 @@ import { ToggleJoinLibraryButtonComponent } from './toggle-join-library/toggle-j import { ToggleJoinLibraryMenuComponent } from './toggle-join-library/toggle-join-library-menu.component'; import { DirectivesModule } from '../../directives/directives.module'; import { ToggleFavoriteLibraryComponent } from './toggle-favorite-library/toggle-favorite-library.component'; +import { ToggleEditOfflineComponent } from './toggle-edit-offline/toggle-edit-offline.component'; import { AppCommonModule } from '../common/common.module'; export function components() { @@ -51,7 +52,8 @@ export function components() { ToolbarMenuComponent, ToggleJoinLibraryButtonComponent, ToggleJoinLibraryMenuComponent, - ToggleFavoriteLibraryComponent + ToggleFavoriteLibraryComponent, + ToggleEditOfflineComponent ]; } diff --git a/src/app/directives/directives.module.ts b/src/app/directives/directives.module.ts index f293dfdcc9..17abca047e 100644 --- a/src/app/directives/directives.module.ts +++ b/src/app/directives/directives.module.ts @@ -29,6 +29,7 @@ import { DocumentListDirective } from './document-list.directive'; import { PaginationDirective } from './pagination.directive'; import { LibraryMembershipDirective } from './library-membership.directive'; import { LibraryFavoriteDirective } from './library-favorite.directive'; +import { EditOfflineDirective } from './edit-offline.directive'; export function directives() { return [ @@ -36,7 +37,8 @@ export function directives() { DocumentListDirective, PaginationDirective, LibraryMembershipDirective, - LibraryFavoriteDirective + LibraryFavoriteDirective, + EditOfflineDirective ]; } diff --git a/src/app/directives/edit-offline.directive.spec.ts b/src/app/directives/edit-offline.directive.spec.ts new file mode 100644 index 0000000000..ff772b5a33 --- /dev/null +++ b/src/app/directives/edit-offline.directive.spec.ts @@ -0,0 +1,141 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2018 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { Component, ViewChild } from '@angular/core'; +import { EditOfflineDirective } from './edit-offline.directive'; +import { + AlfrescoApiService, + AlfrescoApiServiceMock, + setupTestBed, + CoreModule +} from '@alfresco/adf-core'; +import { TestBed, fakeAsync, tick } from '@angular/core/testing'; + +@Component({ + selector: 'app-test-component', + template: ` + + ` +}) +class TestComponent { + @ViewChild('editOffline') + directive: EditOfflineDirective; + + selection = null; +} + +describe('EditOfflineDirective', () => { + let fixture; + let api; + let component; + + setupTestBed({ + imports: [CoreModule], + declarations: [TestComponent, EditOfflineDirective], + providers: [ + { + provide: AlfrescoApiService, + useClass: AlfrescoApiServiceMock + } + ] + }); + + beforeEach(() => { + fixture = TestBed.createComponent(TestComponent); + component = fixture.componentInstance; + component.selection = null; + api = TestBed.get(AlfrescoApiService); + }); + + it('should return false if selection is not locked', () => { + component.selection = { entry: { name: 'test-name', properties: {} } }; + fixture.detectChanges(); + expect(component.directive.isNodeLocked()).toBe(false); + }); + + it('should return true if selection is locked', () => { + component.selection = { + entry: { + name: 'test-name', + properties: { 'cm:lockType': 'WRITE_LOCK' } + } + }; + + fixture.detectChanges(); + expect(component.directive.isNodeLocked()).toBe(true); + }); + + it('should lock selection', fakeAsync(() => { + component.selection = { + entry: { + id: 'id', + name: 'test-name', + properties: {} + } + }; + + spyOn(api.nodesApi, 'lockNode').and.returnValue( + Promise.resolve({ + entry: { properties: { 'cm:lockType': 'WRITE_LOCK' } } + }) + ); + + fixture.detectChanges(); + + component.directive.onClick(); + tick(); + fixture.detectChanges(); + + expect(component.selection.entry.properties['cm:lockType']).toBe( + 'WRITE_LOCK' + ); + })); + + it('should unlock selection', fakeAsync(() => { + component.selection = { + entry: { + id: 'id', + name: 'test-name', + properties: { + 'cm:lockType': 'WRITE_LOCK' + } + } + }; + + spyOn(api.nodesApi, 'unlockNode').and.returnValue( + Promise.resolve({ + entry: { properties: {} } + }) + ); + + fixture.detectChanges(); + component.directive.onClick(); + + tick(); + fixture.detectChanges(); + + expect(component.selection.entry.properties['cm:lockType']).toBe(undefined); + })); +}); diff --git a/src/app/directives/edit-offline.directive.ts b/src/app/directives/edit-offline.directive.ts new file mode 100644 index 0000000000..0902c5731f --- /dev/null +++ b/src/app/directives/edit-offline.directive.ts @@ -0,0 +1,105 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2018 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { + Directive, + EventEmitter, + HostListener, + Input, + Output +} from '@angular/core'; +import { NodeEntry, NodeBodyLock, SharedLinkEntry } from '@alfresco/js-api'; +import { AlfrescoApiService } from '@alfresco/adf-core'; + +@Directive({ + selector: '[acaEditOffline]', + exportAs: 'editOffline' +}) +export class EditOfflineDirective { + @Input('acaEditOffline') + node: NodeEntry = null; + + @Output() toggle: EventEmitter = new EventEmitter(); + @Output() error: EventEmitter = new EventEmitter(); + + @HostListener('click') + onClick() { + this.toggleEdit(this.node); + } + + constructor(private alfrescoApiService: AlfrescoApiService) {} + + isNodeLocked() { + return !!( + this.node && + this.node.entry.properties && + this.node.entry.properties['cm:lockType'] === 'WRITE_LOCK' + ); + } + + private async toggleEdit(node: NodeEntry | SharedLinkEntry) { + const id = (node).entry.nodeId || node.entry.id; + if (this.isNodeLocked()) { + try { + const response = await this.unlockNode(id); + const isLocked = false; + + this.update(response.entry); + this.toggle.emit(isLocked); + } catch (error) { + this.error.emit(error); + } + } else { + try { + const response = await this.lockNode(id); + const isLocked = true; + + this.update(response.entry); + this.toggle.emit(isLocked); + } catch (error) { + this.error.emit(error); + } + } + } + + private lockNode(nodeId: string) { + return this.alfrescoApiService.nodesApi.lockNode(nodeId, { + type: 'ALLOW_OWNER_CHANGES', + lifetime: 'PERSISTENT' + }); + } + + private unlockNode(nodeId: string) { + return this.alfrescoApiService.nodesApi.unlockNode(nodeId); + } + + private update(data) { + const properties = this.node.entry.properties || {}; + + properties['cm:lockLifetime'] = data.properties['cm:lockLifetime']; + properties['cm:lockOwner'] = data.properties['cm:lockOwner']; + properties['cm:lockType'] = data.properties['cm:lockType']; + } +} diff --git a/src/app/extensions/core.extensions.module.ts b/src/app/extensions/core.extensions.module.ts index 64a6d65b50..6379e8db59 100644 --- a/src/app/extensions/core.extensions.module.ts +++ b/src/app/extensions/core.extensions.module.ts @@ -45,12 +45,13 @@ import { LocationLinkComponent } from '../components/common/location-link/locati import { DocumentDisplayModeComponent } from '../components/toolbar/document-display-mode/document-display-mode.component'; import { ToggleJoinLibraryButtonComponent } from '../components/toolbar/toggle-join-library/toggle-join-library-button.component'; import { ToggleJoinLibraryMenuComponent } from '../components/toolbar/toggle-join-library/toggle-join-library-menu.component'; +import { ToggleEditOfflineComponent } from '../components/toolbar/toggle-edit-offline/toggle-edit-offline.component'; +import { CustomNameColumnComponent } from '../components/dl-custom-components/name-column/name-column.component'; import { LibraryNameColumnComponent, LibraryStatusColumnComponent, TrashcanNameColumnComponent, - LibraryRoleColumnComponent, - NameColumnComponent + LibraryRoleColumnComponent } from '@alfresco/adf-content-services'; export function setupExtensions(service: AppExtensionService): Function { @@ -95,12 +96,13 @@ export class CoreExtensionsModule { 'app.toolbar.cardView': DocumentDisplayModeComponent, 'app.menu.toggleJoinLibrary': ToggleJoinLibraryMenuComponent, 'app.shared-link.toggleSharedLink': ToggleSharedComponent, - 'app.columns.name': NameColumnComponent, + 'app.columns.name': CustomNameColumnComponent, 'app.columns.libraryName': LibraryNameColumnComponent, 'app.columns.libraryRole': LibraryRoleColumnComponent, 'app.columns.libraryStatus': LibraryStatusColumnComponent, 'app.columns.trashcanName': TrashcanNameColumnComponent, - 'app.columns.location': LocationLinkComponent + 'app.columns.location': LocationLinkComponent, + 'app.toolbar.toggleEditOffline': ToggleEditOfflineComponent }); extensions.setAuthGuards({ @@ -109,6 +111,7 @@ export class CoreExtensionsModule { extensions.setEvaluators({ 'app.selection.canDelete': app.canDeleteSelection, + 'app.selection.canEditLockedFile': app.canEditLockedFile, 'app.selection.canDownload': app.canDownloadSelection, 'app.selection.notEmpty': app.hasSelection, 'app.selection.canUnshare': app.canUnshareNodes, @@ -131,6 +134,8 @@ export class CoreExtensionsModule { 'app.navigation.isTrashcan': nav.isTrashcan, 'app.navigation.isNotTrashcan': nav.isNotTrashcan, 'app.navigation.isLibraries': nav.isLibraries, + 'app.navigation.isLibraryFiles': nav.isLibraryFiles, + 'app.navigation.isPersonalFiles': nav.isPersonalFiles, 'app.navigation.isNotLibraries': nav.isNotLibraries, 'app.navigation.isSharedFiles': nav.isSharedFiles, 'app.navigation.isNotSharedFiles': nav.isNotSharedFiles, diff --git a/src/app/extensions/evaluators/app.evaluators.ts b/src/app/extensions/evaluators/app.evaluators.ts index 8b7ebbb29b..c767f9c6ec 100644 --- a/src/app/extensions/evaluators/app.evaluators.ts +++ b/src/app/extensions/evaluators/app.evaluators.ts @@ -24,6 +24,7 @@ */ import { RuleContext, RuleParameter } from '@alfresco/adf-extensions'; +import { AppRuleContext } from '../app.interface'; import { isNotTrashcan, isNotLibraries, @@ -294,3 +295,27 @@ export function hasLockedFiles( ); }); } + +export function isWriteLocked( + context: AppRuleContext, + ...args: RuleParameter[] +): boolean { + return !!( + context.selection.file && + context.selection.file.entry && + context.selection.file.entry.properties && + context.selection.file.entry.properties['cm:lockType'] === 'WRITE_LOCK' + ); +} + +export function canEditLockedFile( + context: AppRuleContext, + ...args: RuleParameter[] +): boolean { + return !!( + !isWriteLocked(context, ...args) || + (context.selection.file.entry.properties['cm:lockOwner'] && + context.selection.file.entry.properties['cm:lockOwner'].id === + context.profile.id) + ); +} diff --git a/src/app/extensions/evaluators/navigation.evaluators.ts b/src/app/extensions/evaluators/navigation.evaluators.ts index 8955864f11..23ce69a2b5 100644 --- a/src/app/extensions/evaluators/navigation.evaluators.ts +++ b/src/app/extensions/evaluators/navigation.evaluators.ts @@ -70,6 +70,22 @@ export function isNotTrashcan( return !isTrashcan(context, ...args); } +export function isPersonalFiles( + context: RuleContext, + ...args: RuleParameter[] +): boolean { + const { url } = context.navigation; + return url && url.startsWith('/personal-files'); +} + +export function isLibraryFiles( + context: RuleContext, + ...args: RuleParameter[] +): boolean { + const { url } = context.navigation; + return url && url.startsWith('/libraries'); +} + export function isLibraries( context: RuleContext, ...args: RuleParameter[] diff --git a/src/app/store/actions/node.actions.ts b/src/app/store/actions/node.actions.ts index 586736125c..19be6d2286 100644 --- a/src/app/store/actions/node.actions.ts +++ b/src/app/store/actions/node.actions.ts @@ -42,6 +42,7 @@ export const MANAGE_PERMISSIONS = 'MANAGE_PERMISSIONS'; export const MANAGE_VERSIONS = 'MANAGE_VERSIONS'; export const PRINT_FILE = 'PRINT_FILE'; export const FULLSCREEN_VIEWER = 'FULLSCREEN_VIEWER'; +export const EDIT_OFFLINE = 'EDIT_OFFLINE'; export class SetSelectedNodesAction implements Action { readonly type = SET_SELECTED_NODES; @@ -122,3 +123,8 @@ export class FullscreenViewerAction implements Action { readonly type = FULLSCREEN_VIEWER; constructor(public payload: MinimalNodeEntity) {} } + +export class EditOfflineAction implements Action { + readonly type = EDIT_OFFLINE; + constructor(public payload: any) {} +} diff --git a/src/assets/app.extensions.json b/src/assets/app.extensions.json index 599721faa3..3c8f814166 100644 --- a/src/assets/app.extensions.json +++ b/src/assets/app.extensions.json @@ -166,6 +166,7 @@ "parameters": [ { "type": "rule", "value": "app.selection.file" }, { "type": "rule", "value": "app.navigation.isNotTrashcan" }, + { "type": "rule", "value": "app.selection.canEditLockedFile" }, { "type": "rule", "value": "core.not", @@ -216,6 +217,34 @@ { "type": "rule", "value": "app.selection.canDownload" }, { "type": "rule", "value": "app.navigation.isNotTrashcan" } ] + }, + { + "id": "app.toolbar.canDelete", + "type": "core.every", + "parameters": [ + { "type": "rule", "value": "app.selection.canDelete" }, + { "type": "rule", "value": "app.selection.canEditLockedFile" }, + { "type": "rule", "value": "app.navigation.isNotTrashcan" } + ] + }, + { + "id": "app.toolbar.canEditLockedFile", + "type": "core.every", + "parameters": [ + { "type": "rule", "value": "app.selection.file" }, + { "type": "rule", "value": "app.selection.canEditLockedFile" }, + { "type": "rule", "value": "app.navigation.isNotTrashcan" }, + { + "type": "rule", + "value": "core.some", + "parameters": [ + { "type": "rule", "value": "app.navigation.isPreview" }, + { "type": "rule", "value": "app.navigation.isPersonalFiles" }, + { "type": "rule", "value": "app.navigation.isLibraryFiles" }, + { "type": "rule", "value": "app.navigation.isRecentFiles" } + ] + } + ] } ], @@ -503,11 +532,20 @@ "icon": "more_vert", "title": "APP.ACTIONS.MORE", "children": [ + { + "id": "app.toolbar.toggleEditOffline", + "order": 100, + "type": "custom", + "component": "app.toolbar.toggleEditOffline", + "rules": { + "visible": "app.toolbar.canEditLockedFile" + } + }, { "id": "app.toolbar.favorite", "comment": "workaround for Recent Files and Search API issue", "type": "custom", - "order": 100, + "order": 200, "component": "app.toolbar.toggleFavorite", "rules": { "visible": "app.toolbar.favorite.canToggle" @@ -516,7 +554,7 @@ { "id": "app.libraries.toolbar.toggleFavorite", "type": "custom", - "order": 101, + "order": 201, "component": "app.toolbar.toggleFavoriteLibrary", "rules": { "visible": "app.libraries.toolbar" @@ -524,7 +562,7 @@ }, { "id": "app.toolbar.favorite.add", - "order": 200, + "order": 300, "title": "APP.ACTIONS.FAVORITE", "icon": "star_border", "actions": { @@ -536,7 +574,7 @@ }, { "id": "app.toolbar.favorite.remove", - "order": 300, + "order": 400, "title": "APP.ACTIONS.FAVORITE", "icon": "star", "actions": { @@ -549,11 +587,11 @@ { "id": "app.create.separator.3", "type": "separator", - "order": 380 + "order": 3480 }, { "id": "app.toolbar.copy", - "order": 400, + "order": 500, "title": "APP.ACTIONS.COPY", "icon": "content_copy", "actions": { @@ -565,14 +603,14 @@ }, { "id": "app.toolbar.move", - "order": 500, + "order": 600, "title": "APP.ACTIONS.MOVE", "icon": "adf:move_file", "actions": { "click": "MOVE_NODES" }, "rules": { - "visible": "app.selection.canDelete" + "visible": "app.toolbar.canDelete" } }, { @@ -584,7 +622,7 @@ "click": "DELETE_NODES" }, "rules": { - "visible": "app.selection.canDelete" + "visible": "app.toolbar.canDelete" } }, { @@ -632,10 +670,19 @@ } ], "contextMenu": [ + { + "id": "app.context.toggleEditOffline", + "order": 100, + "type": "custom", + "component": "app.toolbar.toggleEditOffline", + "rules": { + "visible": "app.toolbar.canEditLockedFile" + } + }, { "id": "app.context.menu.share", "type": "custom", - "order": 100, + "order": 200, "component": "app.shared-link.toggleSharedLink", "rules": { "visible": "app.context.canShare" @@ -643,7 +690,7 @@ }, { "id": "app.context.menu.download", - "order": 200, + "order": 300, "title": "APP.ACTIONS.DOWNLOAD", "icon": "get_app", "actions": { @@ -655,7 +702,7 @@ }, { "id": "app.context.menu.preview", - "order": 300, + "order": 400, "title": "APP.ACTIONS.VIEW", "icon": "visibility", "actions": { @@ -667,7 +714,7 @@ }, { "id": "app.context.menu.editFolder", - "order": 400, + "order": 500, "title": "APP.ACTIONS.EDIT", "icon": "create", "actions": { @@ -680,7 +727,7 @@ { "id": "app.context.menu.favorite.add", "title": "APP.ACTIONS.FAVORITE", - "order": 500, + "order": 600, "icon": "star_border", "actions": { "click": "ADD_FAVORITE" @@ -692,7 +739,7 @@ { "id": "app.context.menu.favorite.remove", "title": "APP.ACTIONS.FAVORITE", - "order": 600, + "order": 700, "icon": "star", "actions": { "click": "REMOVE_FAVORITE" @@ -705,7 +752,7 @@ "id": "app.context.menu.favorite", "comment": "workaround for Recent Files and Search API issue", "type": "custom", - "order": 601, + "order": 701, "component": "app.toolbar.toggleFavorite", "rules": { "visible": "app.toolbar.favorite.canToggle" @@ -714,7 +761,7 @@ { "id": "app.context.menu.libraries.toggleFavorite", "type": "custom", - "order": 602, + "order": 702, "component": "app.toolbar.toggleFavoriteLibrary", "rules": { "visible": "app.libraries.toolbar" @@ -723,7 +770,7 @@ { "id": "app.context.menu.joinLibrary", "type": "custom", - "order": 603, + "order": 703, "component": "app.menu.toggleJoinLibrary", "rules": { "visible": "app.libraries.toolbar.canToggleJoin" @@ -731,7 +778,7 @@ }, { "id": "app.context.menu.leaveLibrary", - "order": 703, + "order": 803, "title": "APP.ACTIONS.LEAVE", "icon": "exit_to_app", "actions": { @@ -744,12 +791,12 @@ { "id": "app.create.separator.5", "type": "separator", - "order": 720 + "order": 820 }, { "id": "app.context.menu.copy", "title": "APP.ACTIONS.COPY", - "order": 750, + "order": 850, "icon": "content_copy", "actions": { "click": "COPY_NODES" @@ -761,30 +808,30 @@ { "id": "app.context.menu.move", "title": "APP.ACTIONS.MOVE", - "order": 800, + "order": 900, "icon": "adf:move_file", "actions": { "click": "MOVE_NODES" }, "rules": { - "visible": "app.selection.canDelete" + "visible": "app.toolbar.canDelete" } }, { "id": "app.context.menu.delete", "title": "APP.ACTIONS.DELETE", - "order": 900, + "order": 1000, "icon": "delete", "actions": { "click": "DELETE_NODES" }, "rules": { - "visible": "app.selection.canDelete" + "visible": "app.toolbar.canDelete" } }, { "id": "app.context.menu.deleteLibrary", - "order": 901, + "order": 1001, "title": "APP.ACTIONS.DELETE", "icon": "delete", "actions": { @@ -797,12 +844,12 @@ { "id": "app.create.separator.6", "type": "separator", - "order": 980 + "order": 1080 }, { "id": "app.context.menu.versions", "title": "APP.ACTIONS.VERSIONS", - "order": 1000, + "order": 1100, "icon": "history", "actions": { "click": "MANAGE_VERSIONS" @@ -815,7 +862,7 @@ "id": "app.context.menu.permissions", "title": "APP.ACTIONS.PERMISSIONS", "icon": "settings_input_component", - "order": 1100, + "order": 1200, "actions": { "click": "MANAGE_PERMISSIONS" }, @@ -825,7 +872,7 @@ }, { "id": "app.context.menu.purgeDeletedNodes", - "order": 1200, + "order": 1300, "title": "APP.ACTIONS.DELETE_PERMANENT", "icon": "delete_forever", "actions": { @@ -837,7 +884,7 @@ }, { "id": "app.context.menu.restoreDeletedNodes", - "order": 1300, + "order": 1400, "title": "APP.ACTIONS.RESTORE", "icon": "restore", "actions": { @@ -923,8 +970,17 @@ "title": "APP.ACTIONS.MORE", "children": [ { - "id": "app.viewer.favorite.add", + "id": "app.viewer.toggleEditOffline", "order": 100, + "type": "custom", + "component": "app.toolbar.toggleEditOffline", + "rules": { + "visible": "app.toolbar.canEditLockedFile" + } + }, + { + "id": "app.viewer.favorite.add", + "order": 200, "title": "APP.ACTIONS.FAVORITE", "icon": "star_border", "actions": { @@ -936,7 +992,7 @@ }, { "id": "app.viewer.favorite.remove", - "order": 200, + "order": 300, "title": "APP.ACTIONS.FAVORITE", "icon": "star", "actions": { @@ -950,7 +1006,7 @@ "id": "app.viewer.favorite", "comment": "workaround for Recent Files and Search API issue", "type": "custom", - "order": 101, + "order": 201, "component": "app.toolbar.toggleFavorite", "rules": { "visible": "app.toolbar.favorite.canToggle" @@ -959,7 +1015,7 @@ { "id": "app.viewer.more.separator.1", "type": "separator", - "order": 280 + "order": 380 }, { "id": "app.viewer.copy", @@ -982,7 +1038,7 @@ "click": "MOVE_NODES" }, "rules": { - "visible": "app.selection.canDelete" + "visible": "app.toolbar.canDelete" } }, { @@ -994,7 +1050,7 @@ "click": "DELETE_NODES" }, "rules": { - "visible": "app.selection.canDelete" + "visible": "app.toolbar.canDelete" } }, { diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 04b6cad36a..2eb5aaa9e6 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -202,7 +202,9 @@ "FULLSCREEN": "Activate full-screen mode", "JOIN": "Join", "CANCEL_JOIN": "Cancel join request", - "LEAVE": "Leave library" + "LEAVE": "Leave library", + "EDIT_OFFLINE": "Edit offline", + "EDIT_OFFLINE_CANCEL": "Cancel editing" }, "DIALOGS": { "CONFIRM_PURGE": { @@ -240,7 +242,7 @@ }, "MESSAGES": { "ERRORS":{ - "CANNOT_NAVIGATE_LOCATION": "Cannot open this location", + "CANNOT_NAVIGATE_LOCATION": "Cannot open this location", "MISSING_CONTENT": "This item no longer exists or you don't have permission to view it.", "GENERIC": "The action was unsuccessful. Try again or contact your IT Team.", "CONFLICT": "This name is already in use, try a different name.", @@ -251,6 +253,7 @@ "NODE_RESTORE": "{{ name }} couldn't be restored", "NODE_RESTORE_PLURAL": "{{ number }} items couldn't be restored", "PERMISSION": "You don't have access to do this", + "LOCK_NODE": "There was a problem locking the {{ fileName }} file", "TRASH": { "NODES_PURGE": { "PLURAL": "{{ number }} items couldn't be deleted", @@ -402,7 +405,6 @@ "LIBRARY_UPDATED": "Library properties updated" } }, - "SEARCH": { "INPUT": { "PLACEHOLDER": "Search", From ecc94a6dd22797684978819f0e6b41857b128db5 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Fri, 1 Feb 2019 19:19:44 +0000 Subject: [PATCH 034/259] upgrade libraries (#910) * upgrade libraries * fix breaking changes * fix divider * remove header workarounds --- package-lock.json | 873 +++++++++--------- package.json | 42 +- .../favorite-libraries.component.html | 22 +- .../favorites/favorites.component.html | 18 +- .../components/header/header.component.html | 2 +- .../libraries/libraries.component.html | 18 +- .../recent-files/recent-files.component.html | 18 +- .../search-libraries-results.component.html | 20 +- .../search-results.component.html | 20 +- .../shared-files/shared-files.component.html | 18 +- .../trashcan/trashcan.component.html | 28 +- src/app/services/content-api.service.ts | 2 +- src/app/ui/custom-theme.scss | 2 - .../ui/overrides/adf-layout-header.theme.scss | 36 - .../overrides/adf-upload-drag-area.theme.scss | 10 +- 15 files changed, 520 insertions(+), 609 deletions(-) delete mode 100644 src/app/ui/overrides/adf-layout-header.theme.scss diff --git a/package-lock.json b/package-lock.json index 8f5a310469..b14fdd8a4c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,45 +5,45 @@ "requires": true, "dependencies": { "@alfresco/adf-content-services": { - "version": "3.0.0-7c66589b26e57061a07a8d38bfebc2ee05fb1b83", - "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-3.0.0-7c66589b26e57061a07a8d38bfebc2ee05fb1b83.tgz", - "integrity": "sha512-1Cca7AG8vH+U15k125PCiKdTRYb6uQd29x4Idle48urDFUpkUXBF3elnR15CWCwBuw+Idl0HVogAIIbbKsP2CQ==", + "version": "3.0.0-0282bfa4686accfd24cbac61795891378c25fb64", + "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-3.0.0-0282bfa4686accfd24cbac61795891378c25fb64.tgz", + "integrity": "sha512-Nr401vcfIWxUBjOzJWCfSELbPBhTmljhMXHyDJrsI4rBFepftSwARzkRJeMvFw21Z4lzBICmx9ZUDIDV43A7Lw==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/adf-core": { - "version": "3.0.0-7c66589b26e57061a07a8d38bfebc2ee05fb1b83", - "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-3.0.0-7c66589b26e57061a07a8d38bfebc2ee05fb1b83.tgz", - "integrity": "sha512-s5E3dAgb7pkB6JP/EjOTlWvddjuykTqR4WxUsVQahGkPYqg7O2PkvkElIVeeerB/oBjXYW1LY8p5HUCZoIiqGg==", + "version": "3.0.0-0282bfa4686accfd24cbac61795891378c25fb64", + "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-3.0.0-0282bfa4686accfd24cbac61795891378c25fb64.tgz", + "integrity": "sha512-I/XI+n/+hOpYvWsP7B2oGXmvRLQMDNU6j+PclfPoMb4vMeT7HBtuGukz+K0hvERcHzEfj3N84rrlSTZZ9jDRuQ==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/adf-extensions": { - "version": "3.0.0-7c66589b26e57061a07a8d38bfebc2ee05fb1b83", - "resolved": "https://registry.npmjs.org/@alfresco/adf-extensions/-/adf-extensions-3.0.0-7c66589b26e57061a07a8d38bfebc2ee05fb1b83.tgz", - "integrity": "sha512-he7h49WJeEIv2lVNblVDzRvdKoJmvdf33KDpv078r/JAkd7cAbueOtUKJtYSQWsqDs2e041Q2PXJOQz2sfmJew==", + "version": "3.0.0-0282bfa4686accfd24cbac61795891378c25fb64", + "resolved": "https://registry.npmjs.org/@alfresco/adf-extensions/-/adf-extensions-3.0.0-0282bfa4686accfd24cbac61795891378c25fb64.tgz", + "integrity": "sha512-Ke/8qTyCWceQPNo5qQ8YCHsQ9Ocg6n4+aiOJumqYhFqdbsapbp6dXcDHULh6ZfawVHInKBGvEIv12j7gjZDL2Q==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/js-api": { - "version": "3.0.0-e9c8ed80decc71d2fc6833cef22851b64ce4b604", - "resolved": "https://registry.npmjs.org/@alfresco/js-api/-/js-api-3.0.0-e9c8ed80decc71d2fc6833cef22851b64ce4b604.tgz", - "integrity": "sha512-EgCTW+ZOJGvxVUFu5Ul8e0vnW1aITuxTgOKk5AGMFW4JxJoFqEYuo77oqXJITE/1JFsyeuqG63oOjQs2NDjHHw==", + "version": "3.0.0-d7850f421268e21861e2cd219441b7343efd27ba", + "resolved": "https://registry.npmjs.org/@alfresco/js-api/-/js-api-3.0.0-d7850f421268e21861e2cd219441b7343efd27ba.tgz", + "integrity": "sha512-glHDIbJX5xoOT1SBlmryJ1aDEH99a/826KnJK5M/ybLfv5yBg+LFL8aMRRMkz26wzKn9YxRwxh14a+6u2u9o1A==", "requires": { "event-emitter": "0.3.4", "superagent": "3.8.2" } }, "@angular-devkit/architect": { - "version": "0.12.3", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.12.3.tgz", - "integrity": "sha512-nRZkuQkUMW0HS/YbVjsEA5zPMgsL4Icd0nFV2gM9vAK5X+Vzn9gZyCL1ogkOsJNlEP6Rc/Pc6Q1PPO2p5NxPsQ==", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.13.0.tgz", + "integrity": "sha512-oDBrWlfKh/0t2ag4T8gz9xzPMItxfctinlsHxhw7dPQ+etq1mIcWgQkiKiDrz4l46YiGipBRlC55j+6f37omAA==", "dev": true, "requires": { - "@angular-devkit/core": "7.2.3", + "@angular-devkit/core": "7.3.0", "rxjs": "6.3.3" }, "dependencies": { @@ -59,64 +59,63 @@ } }, "@angular-devkit/build-angular": { - "version": "0.12.3", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-0.12.3.tgz", - "integrity": "sha512-YS/xwpJ23F4Cw/gWxJvVzQ3ghYqs8nOAYyV/+frZ/ZbOE3iYWnRjwoeWmKhmgBjvTjEnoDne9PYYkQRCxmVBaA==", - "dev": true, - "requires": { - "@angular-devkit/architect": "0.12.3", - "@angular-devkit/build-optimizer": "0.12.3", - "@angular-devkit/build-webpack": "0.12.3", - "@angular-devkit/core": "7.2.3", - "@ngtools/webpack": "7.2.3", - "ajv": "6.6.2", - "autoprefixer": "9.4.3", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-0.13.0.tgz", + "integrity": "sha512-JjoSXbmwOsuDJxngyChr6aOSZ2qsrvSL1MHwqgXhZswmC/KghBF0aZ7y8Wzr27zDCQ174Axts7+IAk6b+aWIqw==", + "dev": true, + "requires": { + "@angular-devkit/architect": "0.13.0", + "@angular-devkit/build-optimizer": "0.13.0", + "@angular-devkit/build-webpack": "0.13.0", + "@angular-devkit/core": "7.3.0", + "@ngtools/webpack": "7.3.0", + "ajv": "6.7.0", + "autoprefixer": "9.4.6", "circular-dependency-plugin": "5.0.2", "clean-css": "4.2.1", "copy-webpack-plugin": "4.6.0", - "file-loader": "2.0.0", + "file-loader": "3.0.1", "glob": "7.1.3", "istanbul": "0.4.5", "istanbul-instrumenter-loader": "3.0.1", "karma-source-map-support": "1.3.0", "less": "3.9.0", "less-loader": "4.1.0", - "license-webpack-plugin": "2.0.4", - "loader-utils": "1.1.0", - "mini-css-extract-plugin": "0.4.4", + "license-webpack-plugin": "2.1.0", + "loader-utils": "1.2.3", + "mini-css-extract-plugin": "0.5.0", "minimatch": "3.0.4", - "node-sass": "4.10.0", + "node-sass": "4.11.0", "opn": "5.4.0", "parse5": "4.0.0", - "portfinder": "1.0.17", - "postcss": "7.0.13", + "postcss": "7.0.14", "postcss-import": "12.0.1", "postcss-loader": "3.0.0", - "raw-loader": "0.5.1", + "raw-loader": "1.0.0", "rxjs": "6.3.3", "sass-loader": "7.1.0", - "semver": "5.5.1", + "semver": "5.6.0", "source-map-loader": "0.2.4", - "source-map-support": "0.5.9", - "speed-measure-webpack-plugin": "1.2.5", + "source-map-support": "0.5.10", + "speed-measure-webpack-plugin": "1.3.0", "stats-webpack-plugin": "0.7.0", "style-loader": "0.23.1", "stylus": "0.54.5", "stylus-loader": "3.0.2", "terser-webpack-plugin": "1.2.1", - "tree-kill": "1.2.0", - "webpack": "4.28.4", - "webpack-dev-middleware": "3.4.0", + "tree-kill": "1.2.1", + "webpack": "4.29.0", + "webpack-dev-middleware": "3.5.1", "webpack-dev-server": "3.1.14", - "webpack-merge": "4.1.4", + "webpack-merge": "4.2.1", "webpack-sources": "1.3.0", "webpack-subresource-integrity": "1.1.0-rc.6" }, "dependencies": { "ajv": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.6.2.tgz", - "integrity": "sha512-FBHEW6Jf5TB9MGBgUUA9XHkTbjXYfAUjY43ACMfmdMRHniyoMHjHjzD50OK8LGDWQwp4rWEsIq5kEqq7rvIM1g==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.7.0.tgz", + "integrity": "sha512-RZXPviBTtfmtka9n9sy1N5M5b82CbxWIR6HIis4s3WQTXDJamc/0gpCWNGz6EWdWp4DOfjzJfhz/AS9zVPjjWg==", "dev": true, "requires": { "fast-deep-equal": "^2.0.1", @@ -126,34 +125,23 @@ } }, "autoprefixer": { - "version": "9.4.3", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.4.3.tgz", - "integrity": "sha512-/XSnzDepRkAU//xLcXA/lUWxpsBuw0WiriAHOqnxkuCtzLhaz+fL4it4gp20BQ8n5SyLzK/FOc7A0+u/rti2FQ==", + "version": "9.4.6", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.4.6.tgz", + "integrity": "sha512-Yp51mevbOEdxDUy5WjiKtpQaecqYq9OqZSL04rSoCiry7Tc5I9FEyo3bfxiTJc1DfHeKwSFCUYbBAiOQ2VGfiw==", "dev": true, "requires": { - "browserslist": "^4.3.6", - "caniuse-lite": "^1.0.30000921", + "browserslist": "^4.4.1", + "caniuse-lite": "^1.0.30000929", "normalize-range": "^0.1.2", "num2fraction": "^1.2.2", - "postcss": "^7.0.6", + "postcss": "^7.0.13", "postcss-value-parser": "^3.3.1" } }, - "browserslist": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.4.1.tgz", - "integrity": "sha512-pEBxEXg7JwaakBXjATYw/D1YZh4QUSCX/Mnd/wnqSRPPSi1U39iDhDoKGoBUcraKdxDlrYqJxSI5nNvD+dWP2A==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30000929", - "electron-to-chromium": "^1.3.103", - "node-releases": "^1.1.3" - } - }, - "caniuse-lite": { - "version": "1.0.30000932", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000932.tgz", - "integrity": "sha512-4bghJFItvzz8m0T3lLZbacmEY9X1Z2AtIzTr7s7byqZIOumASfr4ynDx7rtm0J85nDmx8vsgR6vnaSoeU8Oh0A==", + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", "dev": true }, "chalk": { @@ -192,94 +180,36 @@ "path-is-absolute": "^1.0.0" } }, - "less": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/less/-/less-3.9.0.tgz", - "integrity": "sha512-31CmtPEZraNUtuUREYjSqRkeETFdyEHSEPAGq4erDlUXtda7pzNmctdljdIagSb589d/qXGWiiP31R5JVf+v0w==", + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", "dev": true, "requires": { - "clone": "^2.1.2", - "errno": "^0.1.1", - "graceful-fs": "^4.1.2", - "image-size": "~0.5.0", - "mime": "^1.4.1", - "mkdirp": "^0.5.0", - "promise": "^7.1.1", - "request": "^2.83.0", - "source-map": "~0.6.0" + "minimist": "^1.2.0" } }, - "node-sass": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.10.0.tgz", - "integrity": "sha512-fDQJfXszw6vek63Fe/ldkYXmRYK/QS6NbvM3i5oEo9ntPDy4XX7BcKZyTKv+/kSSxRtXXc7l+MSwEmYc0CSy6Q==", + "loader-utils": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", + "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", "dev": true, - "optional": true, "requires": { - "async-foreach": "^0.1.3", - "chalk": "^1.1.1", - "cross-spawn": "^3.0.0", - "gaze": "^1.0.0", - "get-stdin": "^4.0.1", - "glob": "^7.0.3", - "in-publish": "^2.0.0", - "lodash.assign": "^4.2.0", - "lodash.clonedeep": "^4.3.2", - "lodash.mergewith": "^4.6.0", - "meow": "^3.7.0", - "mkdirp": "^0.5.1", - "nan": "^2.10.0", - "node-gyp": "^3.8.0", - "npmlog": "^4.0.0", - "request": "^2.88.0", - "sass-graph": "^2.2.4", - "stdout-stream": "^1.4.0", - "true-case-path": "^1.0.2" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true, - "optional": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "optional": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true, - "optional": true - } + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" } }, - "opn": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-5.4.0.tgz", - "integrity": "sha512-YF9MNdVy/0qvJvDtunAOzFw9iasOQHpVthTCvGzxt61Il64AYSGdK+rYwld7NAfk9qJ7dt+hymBNSc9LNYS+Sw==", - "dev": true, - "requires": { - "is-wsl": "^1.1.0" - } + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true }, "postcss": { - "version": "7.0.13", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.13.tgz", - "integrity": "sha512-h8SY6kQTd1wISHWjz+E6cswdhMuyBZRb16pSTv3W4zYZ3/YbyWeJdNUeOXB5IdZqE1U76OUEjjjqsC3z2f3hVg==", + "version": "7.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.14.tgz", + "integrity": "sha512-NsbD6XUUMZvBxtQAJuWDJeeC4QFsmWsfozWxCJPWf3M55K9iu2iMDaKqyoOdTJ1R4usBXuxlVFAIo8rZPQD4Bg==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -287,12 +217,6 @@ "supports-color": "^6.1.0" } }, - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, "rxjs": { "version": "6.3.3", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", @@ -303,9 +227,9 @@ } }, "semver": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.1.tgz", - "integrity": "sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", "dev": true }, "source-map": { @@ -315,9 +239,9 @@ "dev": true }, "source-map-support": { - "version": "0.5.9", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.9.tgz", - "integrity": "sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA==", + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.10.tgz", + "integrity": "sha512-YfQ3tQFTK/yzlGJuX8pTwa4tifQj4QS2Mj7UegOu8jAz59MqIiMGPXxQhVQiIMNzayuUSF/jEuVnfFF5JqybmQ==", "dev": true, "requires": { "buffer-from": "^1.0.0", @@ -336,15 +260,15 @@ } }, "@angular-devkit/build-ng-packagr": { - "version": "0.12.3", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-ng-packagr/-/build-ng-packagr-0.12.3.tgz", - "integrity": "sha512-Uct5nuQt+TWGNNcgaXqDTbi/x08GJkNgCoEmJuA0F40vfPNxLiD0ocpryMIczQ8qWNlpCb6Kdv/GEvKB42GgQw==", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-ng-packagr/-/build-ng-packagr-0.13.0.tgz", + "integrity": "sha512-Up7p300FJS7HJmZOvNZXzYsBRPqMJJKQGaOeINDPBsQFHcxIt4LQmQsqUa/4DEczR9Z2/KhlduXbNI+c7wmlgg==", "dev": true, "requires": { - "@angular-devkit/architect": "0.12.3", - "@angular-devkit/core": "7.2.3", + "@angular-devkit/architect": "0.13.0", + "@angular-devkit/core": "7.3.0", "rxjs": "6.3.3", - "semver": "5.5.1" + "semver": "5.6.0" }, "dependencies": { "rxjs": { @@ -357,65 +281,73 @@ } }, "semver": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.1.tgz", - "integrity": "sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", "dev": true } } }, "@angular-devkit/build-optimizer": { - "version": "0.12.3", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.12.3.tgz", - "integrity": "sha512-wwukO6SDP/vPxXwiW7U58EeU1xwylrrEiNWS8JTwkBE/AGQNt0+c7ExNw2ViKL3oBgSpz/6YY2eGrv0aatzfIA==", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.13.0.tgz", + "integrity": "sha512-fhWuzbMVV/UNYE7rHSKutrWTCZle34N5cdtFz6qhK1k/wn7Vmtg9cFOwzx0SPdIlOEn576NB4DS/4UG3B5WCUQ==", "dev": true, "requires": { - "loader-utils": "1.1.0", + "loader-utils": "1.2.3", "source-map": "0.5.6", "typescript": "3.2.4", - "webpack-sources": "1.2.0" + "webpack-sources": "1.3.0" }, "dependencies": { - "source-map": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", - "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=", + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", "dev": true }, - "typescript": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.2.4.tgz", - "integrity": "sha512-0RNDbSdEokBeEAkgNbxJ+BLwSManFy9TeXz8uW+48j/xhEXv1ePME60olyzw2XzUqUBNAYFeJadIqAgNqIACwg==", - "dev": true + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } }, - "webpack-sources": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.2.0.tgz", - "integrity": "sha512-9BZwxR85dNsjWz3blyxdOhTgtnQvv3OEs5xofI0wPYTwu5kaWxS08UuD1oI7WLBLpRO+ylf0ofnXLXWmGb2WMw==", + "loader-utils": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", + "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", "dev": true, "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "source-map": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=", + "dev": true } } }, "@angular-devkit/build-webpack": { - "version": "0.12.3", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.12.3.tgz", - "integrity": "sha512-yzsluzemzmhVxiSdgP03D770lSpAvlJF+k/E5rSb0tS9yENWTgodxMJSP8gRcveZzVW0lVvRUGKucDWyt3vnPQ==", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.13.0.tgz", + "integrity": "sha512-idtFoSbQ3Y3WqXlDlU7oTPV9TIU1kjLqce0nK1Kst+t40GTc+Q4iUJJ7KsKE3nV6TPyrL1N/IvIF7+hSJnYm8A==", "dev": true, "requires": { - "@angular-devkit/architect": "0.12.3", - "@angular-devkit/core": "7.2.3", + "@angular-devkit/architect": "0.13.0", + "@angular-devkit/core": "7.3.0", "rxjs": "6.3.3" }, "dependencies": { @@ -431,12 +363,12 @@ } }, "@angular-devkit/core": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.2.3.tgz", - "integrity": "sha512-NnN8O+97nJAxqD2zVTDlU8dSzrGCZmqYMDqDoRJJChYxAgmGwP4lhb+Jyi5D34tPxgKRTnjTOwC+G7D+WrXSDQ==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.3.0.tgz", + "integrity": "sha512-b0qtAUpgqLpWY8W6vWRv1aj6bXkZCP1rvywl8i8TbGMY67CWRcy5J3fNAMmjiZS+LJixFlIXYf4iOydglyJMfg==", "dev": true, "requires": { - "ajv": "6.6.2", + "ajv": "6.7.0", "chokidar": "2.0.4", "fast-json-stable-stringify": "2.0.0", "rxjs": "6.3.3", @@ -444,9 +376,9 @@ }, "dependencies": { "ajv": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.6.2.tgz", - "integrity": "sha512-FBHEW6Jf5TB9MGBgUUA9XHkTbjXYfAUjY43ACMfmdMRHniyoMHjHjzD50OK8LGDWQwp4rWEsIq5kEqq7rvIM1g==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.7.0.tgz", + "integrity": "sha512-RZXPviBTtfmtka9n9sy1N5M5b82CbxWIR6HIis4s3WQTXDJamc/0gpCWNGz6EWdWp4DOfjzJfhz/AS9zVPjjWg==", "dev": true, "requires": { "fast-deep-equal": "^2.0.1", @@ -823,22 +755,22 @@ } }, "@angular-devkit/schematics": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-7.2.3.tgz", - "integrity": "sha512-zhnI1zxEcjx4OZ0yIzAAOujS8fzXE6nxjyC1viqliQbbjbikA6WIL7UT0jQXZKDsRBl8VXOyutBOaeOXuqktTQ==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-7.3.0.tgz", + "integrity": "sha512-glOduymftH0LmJhITWgWUJK8QCDUltgTZ943/OyArIvLXTLL/8zCb+G6xL+3k33EQjwJicgQ3WIjonJmeTK/Ww==", "dev": true, "requires": { - "@angular-devkit/core": "7.2.3", + "@angular-devkit/core": "7.3.0", "rxjs": "6.3.3" }, "dependencies": { "@angular-devkit/core": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.2.3.tgz", - "integrity": "sha512-NnN8O+97nJAxqD2zVTDlU8dSzrGCZmqYMDqDoRJJChYxAgmGwP4lhb+Jyi5D34tPxgKRTnjTOwC+G7D+WrXSDQ==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.3.0.tgz", + "integrity": "sha512-b0qtAUpgqLpWY8W6vWRv1aj6bXkZCP1rvywl8i8TbGMY67CWRcy5J3fNAMmjiZS+LJixFlIXYf4iOydglyJMfg==", "dev": true, "requires": { - "ajv": "6.6.2", + "ajv": "6.7.0", "chokidar": "2.0.4", "fast-json-stable-stringify": "2.0.0", "rxjs": "6.3.3", @@ -846,9 +778,9 @@ } }, "ajv": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.6.2.tgz", - "integrity": "sha512-FBHEW6Jf5TB9MGBgUUA9XHkTbjXYfAUjY43ACMfmdMRHniyoMHjHjzD50OK8LGDWQwp4rWEsIq5kEqq7rvIM1g==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.7.0.tgz", + "integrity": "sha512-RZXPviBTtfmtka9n9sy1N5M5b82CbxWIR6HIis4s3WQTXDJamc/0gpCWNGz6EWdWp4DOfjzJfhz/AS9zVPjjWg==", "dev": true, "requires": { "fast-deep-equal": "^2.0.1", @@ -1225,9 +1157,9 @@ } }, "@angular/animations": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-7.2.2.tgz", - "integrity": "sha512-St03YR3N4Rv0vLr0+3V0kmf/QNi9q0tOenAlHP+jG/YySPkkv8P3xRcGVU38ID4JQzRiShUD+k2r+oZGCQMNjw==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-7.2.3.tgz", + "integrity": "sha512-5WoiDnVS2OhGgJ1oepFNF2UcfR4sJj97KRnTmLWQ0S4N4WpXX83CoOQVXvXwfotyb8uNtl4zRi2NuvN/MIuFuA==", "requires": { "tslib": "^1.9.0" } @@ -1250,71 +1182,53 @@ } }, "@angular/cli": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-7.2.3.tgz", - "integrity": "sha512-qhzVL600CdSr4gJY8jGd3TpbMAqse+wo7Tf3n6B89Jk0ssVdlxvMJfpHoUekZ80CxqRpFPX6l6XjrYHkpNN/6g==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-7.3.0.tgz", + "integrity": "sha512-6+NoHsW1MYG7GBHUg71zaWIFeIRps/SVksCmRFCpW0RXqErCQmzf0GZuDTZZ2Yo4RzU01150sVp1R8wEvEZfZQ==", "dev": true, "requires": { - "@angular-devkit/architect": "0.12.3", - "@angular-devkit/core": "7.2.3", - "@angular-devkit/schematics": "7.2.3", - "@schematics/angular": "7.2.3", - "@schematics/update": "0.12.3", + "@angular-devkit/architect": "0.13.0", + "@angular-devkit/core": "7.3.0", + "@angular-devkit/schematics": "7.3.0", + "@schematics/angular": "7.3.0", + "@schematics/update": "0.13.0", + "@yarnpkg/lockfile": "1.1.0", + "ini": "1.3.5", "inquirer": "6.2.1", - "opn": "5.3.0", - "semver": "5.5.1", + "npm-package-arg": "6.1.0", + "opn": "5.4.0", + "pacote": "9.4.0", + "semver": "5.6.0", "symbol-observable": "1.2.0" }, "dependencies": { "@angular-devkit/architect": { - "version": "0.12.3", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.12.3.tgz", - "integrity": "sha512-nRZkuQkUMW0HS/YbVjsEA5zPMgsL4Icd0nFV2gM9vAK5X+Vzn9gZyCL1ogkOsJNlEP6Rc/Pc6Q1PPO2p5NxPsQ==", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.13.0.tgz", + "integrity": "sha512-oDBrWlfKh/0t2ag4T8gz9xzPMItxfctinlsHxhw7dPQ+etq1mIcWgQkiKiDrz4l46YiGipBRlC55j+6f37omAA==", "dev": true, "requires": { - "@angular-devkit/core": "7.2.3", + "@angular-devkit/core": "7.3.0", "rxjs": "6.3.3" - }, - "dependencies": { - "rxjs": { - "version": "6.3.3", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", - "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - } } }, "@angular-devkit/core": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.2.3.tgz", - "integrity": "sha512-NnN8O+97nJAxqD2zVTDlU8dSzrGCZmqYMDqDoRJJChYxAgmGwP4lhb+Jyi5D34tPxgKRTnjTOwC+G7D+WrXSDQ==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.3.0.tgz", + "integrity": "sha512-b0qtAUpgqLpWY8W6vWRv1aj6bXkZCP1rvywl8i8TbGMY67CWRcy5J3fNAMmjiZS+LJixFlIXYf4iOydglyJMfg==", "dev": true, "requires": { - "ajv": "6.6.2", + "ajv": "6.7.0", "chokidar": "2.0.4", "fast-json-stable-stringify": "2.0.0", "rxjs": "6.3.3", "source-map": "0.7.3" - }, - "dependencies": { - "rxjs": { - "version": "6.3.3", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", - "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - } } }, "ajv": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.6.2.tgz", - "integrity": "sha512-FBHEW6Jf5TB9MGBgUUA9XHkTbjXYfAUjY43ACMfmdMRHniyoMHjHjzD50OK8LGDWQwp4rWEsIq5kEqq7rvIM1g==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.7.0.tgz", + "integrity": "sha512-RZXPviBTtfmtka9n9sy1N5M5b82CbxWIR6HIis4s3WQTXDJamc/0gpCWNGz6EWdWp4DOfjzJfhz/AS9zVPjjWg==", "dev": true, "requires": { "fast-deep-equal": "^2.0.1", @@ -1673,10 +1587,28 @@ "to-regex": "^3.0.2" } }, + "opn": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.4.0.tgz", + "integrity": "sha512-YF9MNdVy/0qvJvDtunAOzFw9iasOQHpVthTCvGzxt61Il64AYSGdK+rYwld7NAfk9qJ7dt+hymBNSc9LNYS+Sw==", + "dev": true, + "requires": { + "is-wsl": "^1.1.0" + } + }, + "rxjs": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", + "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, "semver": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.1.tgz", - "integrity": "sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", "dev": true }, "source-map": { @@ -1688,25 +1620,25 @@ } }, "@angular/common": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-7.2.2.tgz", - "integrity": "sha512-43EcR3mbM+dKH4VE1EYS1HxSuEToxxv5XPktKqdzY95g8PBOxe11ifcXoYHgImd7YOWzcKoy0k6yQbX3o0cZ8g==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-7.2.3.tgz", + "integrity": "sha512-VZOTZdvkitaKEhkxL6daHxPcKqAFwNJm0U4NFB4LRP9KspsFTE60QFVB63o129PTIH9iOQ2D3HRKSRl4o78ZKg==", "requires": { "tslib": "^1.9.0" } }, "@angular/compiler": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-7.2.2.tgz", - "integrity": "sha512-vjPreOVPca6HSuDmj7N1w5u8hwXdm98gEPo2wqQMVuJd6qvGEyLYE9FsHc0XCchyQEKSybAYl1dwsjZq2nNSvQ==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-7.2.3.tgz", + "integrity": "sha512-UM6n4MyZkR5+VVjlwhLH8IfqdWBkdFcF5at4ckJXOJ/gkIUq97irbis9pGj1b0TO7MAl8uhF4b68xe5lk8b49g==", "requires": { "tslib": "^1.9.0" } }, "@angular/compiler-cli": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-7.2.2.tgz", - "integrity": "sha512-ac62YlDescAaf0qPguyRkpzWCMNlwtsKObq80GKADP33Sxm0BxGt4+Wz6rolvUuWzCX8aZwJ0FA7ehKxdmdQoA==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-7.2.3.tgz", + "integrity": "sha512-31hcfTrU2GW66cvvaS629dNVPfiUrUWPncI28optvmKHBaH0mFqkdYNgabuslsXZV5AeidKMUJvR7GITjtvkQA==", "dev": true, "requires": { "canonical-path": "1.0.0", @@ -1875,41 +1807,41 @@ } }, "@angular/core": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-7.2.2.tgz", - "integrity": "sha512-kQ0HxUYAPvly8b3aibTGbiodFnBBgo3asXAQuPgFjYYEqcKR1zZII7PQdaEF9kb9sfm/IKLKj4nd9fZ0gcgqZg==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-7.2.3.tgz", + "integrity": "sha512-6Ql+sJJnrsxh8O0/IgIP1GgT4eLOHk+dlBs7zBbjstmLuhaQdY+awO9WKoQow+TiD1Go7FW1J3vZ2PTWXKxqjQ==", "requires": { "tslib": "^1.9.0" } }, "@angular/flex-layout": { - "version": "7.0.0-beta.19", - "resolved": "https://registry.npmjs.org/@angular/flex-layout/-/flex-layout-7.0.0-beta.19.tgz", - "integrity": "sha512-MXq+zZ6/s5/+GsL9fZ42mKL0LjZ/+L0sVU5FaQuSAJ57soLl5QAGWvdxVmROtqcHd3Htp35R49nKSZBJ0nfAjg==", + "version": "7.0.0-beta.23", + "resolved": "https://registry.npmjs.org/@angular/flex-layout/-/flex-layout-7.0.0-beta.23.tgz", + "integrity": "sha512-jH2i3i/M7SbK6scVlj2urVL5OhzwavbQ7KwvUjyc/UwccKnnzuOuWEGCINLja/aoaUO3I35LluCLv6a6VN0olA==", "requires": { "tslib": "^1.7.1" } }, "@angular/forms": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-7.2.2.tgz", - "integrity": "sha512-IsvVuUnzIA2ryRmh7l42AANPZFSyNcwqZNtxbmRq2wm3Lfed64U0rsRWWNqipjz7QTxZ2SRdAlP+XDgzg8hvMQ==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-7.2.3.tgz", + "integrity": "sha512-mZpyonfSmRwSvM6efvwFwkLJkK6wHQrm7X4OhVVu3s9i7BI253eLDY7WIRXFvoxJ/5jWIIarVnd/9UA7GINZGw==", "requires": { "tslib": "^1.9.0" } }, "@angular/http": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@angular/http/-/http-7.2.2.tgz", - "integrity": "sha512-+9dZgiVQStGUO3iJGxEWBkjDCARuVLIPk7QPl4Qntbz8Sd/kR7IBqXMM+74W7T5rlG6bunDxq6LuisvsjWCppw==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@angular/http/-/http-7.2.3.tgz", + "integrity": "sha512-wzvBKbO/TcSR3U8AQbsGftH8x1OdAgVGHlfXQPmZL1KjIDHrM1VpnkSvgqIt8coG+4OPfWcNklUCrTdEGwqMqw==", "requires": { "tslib": "^1.9.0" } }, "@angular/language-service": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-7.2.2.tgz", - "integrity": "sha512-qkyY5nUT3J/vBvTTZCTFy3isijQseBFGd6gM08o4ycwbTuOOnnC0XUFuv7o8eeu0jd32MGbaK0gikF+OQOCGNQ==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-7.2.3.tgz", + "integrity": "sha512-9FBVYbKaNx4Ap+Suz/2ZFBPca1voinZMOCN8LjXRYnfS2MHLQASQlTlK4qeZcomyRfy0FxWmO9R02S7YJ06cnw==", "dev": true }, "@angular/material": { @@ -1929,25 +1861,25 @@ } }, "@angular/platform-browser": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-7.2.2.tgz", - "integrity": "sha512-eiaqHq26PVASx1kTngBDkFkXhaJzEjoGtc5I+wQUef8CUjq6ZViWz8tUgiiDPOWdqUKUacRZG4q6VR/6uwQj0A==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-7.2.3.tgz", + "integrity": "sha512-DH0Y2lgEgcrP1I/DUQB/krL7Ob7yL685fu4sRapW17SndTQa2pqSFMBVf+mN3FupTXp7nJHSvlIktzedIk04+g==", "requires": { "tslib": "^1.9.0" } }, "@angular/platform-browser-dynamic": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-7.2.2.tgz", - "integrity": "sha512-bw5PuzMzjKMecB4slG/btmvxgn4qFWhNmJVpf2pbtZW7NtZz3HlrqipYzMk9XrCUDGjtwy7O2Z71C3ujI748iw==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-7.2.3.tgz", + "integrity": "sha512-M8Kiz5FUhnFybJuk/mgOhBjVbRgKDC4bGWKWH9Z9SXBR2dS/FL3QOJsLIthQcWlHOzSoJdEoPBRhn0R4pyLBSw==", "requires": { "tslib": "^1.9.0" } }, "@angular/router": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-7.2.2.tgz", - "integrity": "sha512-+cBC+JxbPdjk+Nyqq27PKkjfIdnc+H+xjMGrkO6dlAKhVMGxyNaYt5NUNugb8XJPsQ1XNXyzwTfZK6jcAGLw6w==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-7.2.3.tgz", + "integrity": "sha512-SH7H2I9WTj1puei4m4g5n0/Cp28HS14q4r8lOgW0gLWuT6Ls7MqH/nDjOMiW924iRR6zjQQs7G+WbhL1jmZc2A==", "requires": { "tslib": "^1.9.0" } @@ -2063,16 +1995,16 @@ "dev": true }, "@ngtools/webpack": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-7.2.3.tgz", - "integrity": "sha512-TbaCeE1mkruWzFGfAP1kSnwk4v5k0MQUxzy2reUvCfq80H8jYrqUuMZJa0VLPoEky5cYIy98Fe2Wz9xlEdx7sA==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-7.3.0.tgz", + "integrity": "sha512-U/By0Jlwy7nYwrGNtFirTg1aAsEHBL/9DhfFxPI0iu27FWiMttROuN6hmKbbnOmpbiYAVl5qTy3WXPXUIJjG1A==", "dev": true, "requires": { - "@angular-devkit/core": "7.2.3", + "@angular-devkit/core": "7.3.0", "enhanced-resolve": "4.1.0", "rxjs": "6.3.3", - "tree-kill": "1.2.0", - "webpack-sources": "1.2.0" + "tree-kill": "1.2.1", + "webpack-sources": "1.3.0" }, "dependencies": { "rxjs": { @@ -2083,29 +2015,13 @@ "requires": { "tslib": "^1.9.0" } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "webpack-sources": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.2.0.tgz", - "integrity": "sha512-9BZwxR85dNsjWz3blyxdOhTgtnQvv3OEs5xofI0wPYTwu5kaWxS08UuD1oI7WLBLpRO+ylf0ofnXLXWmGb2WMw==", - "dev": true, - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } } } }, "@ngx-translate/core": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/@ngx-translate/core/-/core-10.0.2.tgz", - "integrity": "sha512-7nM3DrJaqKswwtJlbu2kuKNl+hE8Isr18sKsKvGGpSxQk+G0gO0reDlx2PhUNus7TJTkA1C59vU/JoN8hIvZ4g==", + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/@ngx-translate/core/-/core-11.0.1.tgz", + "integrity": "sha512-nBCa1ZD9fAUY/3eskP3Lql2fNg8OMrYIej1/5GRsfcutx9tG/5fZLCv9m6UCw1aS+u4uK/vXjv1ctG/FdMvaWg==", "requires": { "tslib": "^1.9.0" } @@ -2129,44 +2045,33 @@ } }, "@schematics/angular": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-7.2.3.tgz", - "integrity": "sha512-hKp+qaM8YU55+JukteXOVY2N5IQBDIIIXkyPcikbC2GBXUeNOMiPqw9au9sjHrgtFp+SVGoaFzzz9+MOCc1gig==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-7.3.0.tgz", + "integrity": "sha512-fOjP/3Rz+Nqrgc+YVaiN88uhPX0FZgUjmMKgMp06lc3xmoc1ScGxoz8AF1fV50Zkvh0Etykzy1LTUczzEUJQqw==", "dev": true, "requires": { - "@angular-devkit/core": "7.2.3", - "@angular-devkit/schematics": "7.2.3", + "@angular-devkit/core": "7.3.0", + "@angular-devkit/schematics": "7.3.0", "typescript": "3.2.2" }, "dependencies": { "@angular-devkit/core": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.2.3.tgz", - "integrity": "sha512-NnN8O+97nJAxqD2zVTDlU8dSzrGCZmqYMDqDoRJJChYxAgmGwP4lhb+Jyi5D34tPxgKRTnjTOwC+G7D+WrXSDQ==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.3.0.tgz", + "integrity": "sha512-b0qtAUpgqLpWY8W6vWRv1aj6bXkZCP1rvywl8i8TbGMY67CWRcy5J3fNAMmjiZS+LJixFlIXYf4iOydglyJMfg==", "dev": true, "requires": { - "ajv": "6.6.2", + "ajv": "6.7.0", "chokidar": "2.0.4", "fast-json-stable-stringify": "2.0.0", "rxjs": "6.3.3", "source-map": "0.7.3" - }, - "dependencies": { - "rxjs": { - "version": "6.3.3", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", - "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - } } }, "ajv": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.6.2.tgz", - "integrity": "sha512-FBHEW6Jf5TB9MGBgUUA9XHkTbjXYfAUjY43ACMfmdMRHniyoMHjHjzD50OK8LGDWQwp4rWEsIq5kEqq7rvIM1g==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.7.0.tgz", + "integrity": "sha512-RZXPviBTtfmtka9n9sy1N5M5b82CbxWIR6HIis4s3WQTXDJamc/0gpCWNGz6EWdWp4DOfjzJfhz/AS9zVPjjWg==", "dev": true, "requires": { "fast-deep-equal": "^2.0.1", @@ -2525,6 +2430,15 @@ "to-regex": "^3.0.2" } }, + "rxjs": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", + "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, "source-map": { "version": "0.7.3", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", @@ -2540,28 +2454,28 @@ } }, "@schematics/update": { - "version": "0.12.3", - "resolved": "https://registry.npmjs.org/@schematics/update/-/update-0.12.3.tgz", - "integrity": "sha512-larMMlYtHyc/ha2N63DtAsnCVVkCePbw9hoAJxVDglBZY7ahShBAQ4RERKYXuHXvmEudG79I+s8P89HjdWsV1w==", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@schematics/update/-/update-0.13.0.tgz", + "integrity": "sha512-HGpZdIL/0w46UyaxpnIAg6SBwzKfaRixHIEihmgJUqA0DG8GZUixRPr1L0YIWC1EZ81cQ+yWL85XhkKBYR+wQg==", "dev": true, "requires": { - "@angular-devkit/core": "7.2.3", - "@angular-devkit/schematics": "7.2.3", + "@angular-devkit/core": "7.3.0", + "@angular-devkit/schematics": "7.3.0", "@yarnpkg/lockfile": "1.1.0", "ini": "1.3.5", - "pacote": "9.1.1", + "pacote": "9.4.0", "rxjs": "6.3.3", - "semver": "5.5.1", + "semver": "5.6.0", "semver-intersect": "1.4.0" }, "dependencies": { "@angular-devkit/core": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.2.3.tgz", - "integrity": "sha512-NnN8O+97nJAxqD2zVTDlU8dSzrGCZmqYMDqDoRJJChYxAgmGwP4lhb+Jyi5D34tPxgKRTnjTOwC+G7D+WrXSDQ==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.3.0.tgz", + "integrity": "sha512-b0qtAUpgqLpWY8W6vWRv1aj6bXkZCP1rvywl8i8TbGMY67CWRcy5J3fNAMmjiZS+LJixFlIXYf4iOydglyJMfg==", "dev": true, "requires": { - "ajv": "6.6.2", + "ajv": "6.7.0", "chokidar": "2.0.4", "fast-json-stable-stringify": "2.0.0", "rxjs": "6.3.3", @@ -2569,9 +2483,9 @@ } }, "ajv": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.6.2.tgz", - "integrity": "sha512-FBHEW6Jf5TB9MGBgUUA9XHkTbjXYfAUjY43ACMfmdMRHniyoMHjHjzD50OK8LGDWQwp4rWEsIq5kEqq7rvIM1g==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.7.0.tgz", + "integrity": "sha512-RZXPviBTtfmtka9n9sy1N5M5b82CbxWIR6HIis4s3WQTXDJamc/0gpCWNGz6EWdWp4DOfjzJfhz/AS9zVPjjWg==", "dev": true, "requires": { "fast-deep-equal": "^2.0.1", @@ -2940,9 +2854,9 @@ } }, "semver": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.1.tgz", - "integrity": "sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", "dev": true }, "source-map": { @@ -3246,19 +3160,16 @@ } }, "acorn": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", - "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==", + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.6.tgz", + "integrity": "sha512-5M3G/A4uBSMIlfJ+h9W125vJvPFH/zirISsW5qfxF5YzEvXJCtolLoQvM5yZft0DvMcUrPGKPOlgEu55I6iUtA==", "dev": true }, "acorn-dynamic-import": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz", - "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==", - "dev": true, - "requires": { - "acorn": "^5.0.0" - } + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz", + "integrity": "sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==", + "dev": true }, "adm-zip": { "version": "0.4.11", @@ -3317,6 +3228,7 @@ "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", "dev": true, + "optional": true, "requires": { "kind-of": "^3.0.2", "longest": "^1.0.1", @@ -6441,9 +6353,9 @@ } }, "file-loader": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-2.0.0.tgz", - "integrity": "sha512-YCsBfd1ZGCyonOKLxPiKPdu+8ld9HAaMEvJewzz+b2eTF7uL5Zm/HdBF6FjCrpCMRq25Mi0U1gl4pwn2TlH7hQ==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-3.0.1.tgz", + "integrity": "sha512-4sNIOXgtH/9WZq4NvlfU3Opn5ynUsqBwSLyM+I7UOwdGigTBYfVVQEwe/msZNX/j4pCJTIM14Fsw66Svo1oVrw==", "dev": true, "requires": { "loader-utils": "^1.0.2", @@ -6699,7 +6611,8 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -6723,13 +6636,15 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -6746,19 +6661,22 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -6889,7 +6807,8 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -6903,6 +6822,7 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -6919,6 +6839,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -6927,13 +6848,15 @@ "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.2.4.tgz", "integrity": "sha512-hzXIWWet/BzWhYs2b+u7dRHlruXhwdgvlTMDKC6Cb1U7ps6Ac6yQlR39xsbjWJE377YTCtKwIXIpJ5oP+j5y8g==", "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -6954,6 +6877,7 @@ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -7042,7 +6966,8 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -7056,6 +6981,7 @@ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -7151,7 +7077,8 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -7193,6 +7120,7 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -7214,6 +7142,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -7262,13 +7191,15 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.2.tgz", "integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=", - "dev": true + "dev": true, + "optional": true } } }, @@ -9855,9 +9786,9 @@ } }, "license-webpack-plugin": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-2.0.4.tgz", - "integrity": "sha512-FQgOqrrIcD4C/VQo6ecWgXZULK5rs0kIDJtHcSVO6SBUrD63kEHZwmKOvBTquFQSgMQn/yeH68qooKDfqiBF2Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-2.1.0.tgz", + "integrity": "sha512-vDiBeMWxjE9n6TabQ9J4FH8urFdsRK0Nvxn1cit9biCiR9aq1zBR0X2BlAkEiIG6qPamLeU0GzvIgLkrFc398A==", "dev": true, "requires": { "@types/webpack-sources": "^0.1.5", @@ -10554,7 +10485,8 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", - "dev": true + "dev": true, + "optional": true }, "loose-envify": { "version": "1.4.0", @@ -10912,9 +10844,9 @@ "dev": true }, "mini-css-extract-plugin": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.4.4.tgz", - "integrity": "sha512-o+Jm+ocb0asEngdM6FsZWtZsRzA8koFUudIDwYUfl94M3PejPHG7Vopw5hN9V8WsMkSFpm3tZP3Fesz89EyrfQ==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.5.0.tgz", + "integrity": "sha512-IuaLjruM0vMKhUUT51fQdQzBYTX49dLj8w68ALEAe2A4iYNpIC4eMac67mt3NzycvjOlf07/kYxJDc0RTl1Wqw==", "dev": true, "requires": { "loader-utils": "^1.1.0", @@ -12247,9 +12179,9 @@ } }, "opn": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-5.3.0.tgz", - "integrity": "sha512-bYJHo/LOmoTd+pfiYhfZDnf9zekVJrY+cnS2a5F2x+w5ppvTqObojTP7WiFG+kVZs9Inw+qQ/lw7TroWwhdd2g==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.4.0.tgz", + "integrity": "sha512-YF9MNdVy/0qvJvDtunAOzFw9iasOQHpVthTCvGzxt61Il64AYSGdK+rYwld7NAfk9qJ7dt+hymBNSc9LNYS+Sw==", "dev": true, "requires": { "is-wsl": "^1.1.0" @@ -12352,9 +12284,9 @@ "dev": true }, "p-is-promise": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz", - "integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.0.0.tgz", + "integrity": "sha512-pzQPhYMCAgLAKPWD2jC3Se9fEfrD9npNos0y150EeqZll7akhEgGhTW/slB6lHku8AvYGiJ+YJ5hfHKePPgFWg==", "dev": true }, "p-limit": { @@ -12400,17 +12332,17 @@ } }, "pacote": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/pacote/-/pacote-9.1.1.tgz", - "integrity": "sha512-f28Rq5ozzKAA9YwIKw61/ipwAatUZseYmVssDbHHaexF0wRIVotapVEZPAjOT7Eu3LYVqEp0NVpNizoAnYBUaA==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-9.4.0.tgz", + "integrity": "sha512-WQ1KL/phGMkedYEQx9ODsjj7xvwLSpdFJJdEXrLyw5SILMxcTNt5DTxT2Z93fXuLFYJBlZJdnwdalrQdB/rX5w==", "dev": true, "requires": { - "bluebird": "^3.5.2", - "cacache": "^11.2.0", + "bluebird": "^3.5.3", + "cacache": "^11.3.2", "figgy-pudding": "^3.5.1", "get-stream": "^4.1.0", "glob": "^7.1.3", - "lru-cache": "^4.1.3", + "lru-cache": "^5.1.1", "make-fetch-happen": "^4.0.1", "minimatch": "^3.0.4", "minipass": "^2.3.5", @@ -12419,7 +12351,7 @@ "normalize-package-data": "^2.4.0", "npm-package-arg": "^6.1.0", "npm-packlist": "^1.1.12", - "npm-pick-manifest": "^2.1.0", + "npm-pick-manifest": "^2.2.3", "npm-registry-fetch": "^3.8.0", "osenv": "^0.1.5", "promise-inflight": "^1.0.1", @@ -12429,7 +12361,7 @@ "safe-buffer": "^5.1.2", "semver": "^5.6.0", "ssri": "^6.0.1", - "tar": "^4.4.6", + "tar": "^4.4.8", "unique-filename": "^1.1.1", "which": "^1.3.1" }, @@ -12460,17 +12392,6 @@ "ssri": "^6.0.1", "unique-filename": "^1.1.1", "y18n": "^4.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - } } }, "get-stream": { @@ -12502,6 +12423,15 @@ "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", "dev": true }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, "mississippi": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", @@ -12781,9 +12711,9 @@ } }, "portfinder": { - "version": "1.0.17", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.17.tgz", - "integrity": "sha512-syFcRIRzVI1BoEFOCaAiizwDolh1S1YXSodsVhncbhjzjZQulhczNRbqnUl9N31Q4dKGOXsNDqxC2BWBgSMqeQ==", + "version": "1.0.20", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.20.tgz", + "integrity": "sha512-Yxe4mTyDzTd59PZJY4ojZR8F+E5e97iq2ZOHPz3HDgSvYC5siNad2tLooQ5y5QHyQhc3xVqvyk/eNA3wuoa7Sw==", "dev": true, "requires": { "async": "^1.5.2", @@ -12911,9 +12841,9 @@ } }, "postcss-value-parser": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz", - "integrity": "sha1-h/OPnxj3dKSrTIojL1xc6IcqnRU=", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", "dev": true }, "pre-commit": { @@ -13415,10 +13345,27 @@ } }, "raw-loader": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-0.5.1.tgz", - "integrity": "sha1-DD0L6u2KAclm2Xh793goElKpeao=", - "dev": true + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-1.0.0.tgz", + "integrity": "sha512-Uqy5AqELpytJTRxYT4fhltcKPj0TyaEpzJDcGz7DFJi+pQOOi3GjR/DOdxTkTsF+NzhnldIoG6TORaBlInUuqA==", + "dev": true, + "requires": { + "loader-utils": "^1.1.0", + "schema-utils": "^1.0.0" + }, + "dependencies": { + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + } + } }, "rc": { "version": "1.2.8", @@ -14013,9 +13960,9 @@ "dev": true }, "rxjs": { - "version": "6.3.3", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", - "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz", + "integrity": "sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw==", "requires": { "tslib": "^1.9.0" } @@ -14892,9 +14839,9 @@ } }, "speed-measure-webpack-plugin": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/speed-measure-webpack-plugin/-/speed-measure-webpack-plugin-1.2.5.tgz", - "integrity": "sha512-S/guYjC4Izn5wY2d0+M4zowED/F77Lxh9yjkTZ+XAr244pr9c1MYNcXcRe9lx2hmAj0GPbOrBXgOF2YIp/CZ8A==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/speed-measure-webpack-plugin/-/speed-measure-webpack-plugin-1.3.0.tgz", + "integrity": "sha512-b9Yd0TrzceMVYSbuamM1sFsGM1oVfyFTM22gOoyLhymNvBVApuYpkdFOgYkKJpN/KhTpcCYcTGHg7X+FJ33Vvw==", "dev": true, "requires": { "chalk": "^2.0.1" @@ -15606,9 +15553,9 @@ } }, "tree-kill": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.0.tgz", - "integrity": "sha512-DlX6dR0lOIRDFxI0mjL9IYg6OTncLm/Zt+JiBhE5OlFcAR8yc9S7FFXU9so0oda47frdM/JFsk7UjNt9vscKcg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.1.tgz", + "integrity": "sha512-4hjqbObwlh2dLyW4tcz0Ymw0ggoaVDMveUB9w8kFSQScdRLo0gxO9J7WFcUBo+W3C1TLdFIEwNOWebgZZ0RH9Q==", "dev": true }, "trim-newlines": { @@ -16610,17 +16557,17 @@ } }, "webpack": { - "version": "4.28.4", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.28.4.tgz", - "integrity": "sha512-NxjD61WsK/a3JIdwWjtIpimmvE6UrRi3yG54/74Hk9rwNj5FPkA4DJCf1z4ByDWLkvZhTZE+P3C/eh6UD5lDcw==", + "version": "4.29.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.29.0.tgz", + "integrity": "sha512-pxdGG0keDBtamE1mNvT5zyBdx+7wkh6mh7uzMOo/uRQ/fhsdj5FXkh/j5mapzs060forql1oXqXN9HJGju+y7w==", "dev": true, "requires": { "@webassemblyjs/ast": "1.7.11", "@webassemblyjs/helper-module-context": "1.7.11", "@webassemblyjs/wasm-edit": "1.7.11", "@webassemblyjs/wasm-parser": "1.7.11", - "acorn": "^5.6.2", - "acorn-dynamic-import": "^3.0.0", + "acorn": "^6.0.5", + "acorn-dynamic-import": "^4.0.0", "ajv": "^6.1.0", "ajv-keywords": "^3.1.0", "chrome-trace-event": "^1.0.0", @@ -16954,9 +16901,9 @@ } }, "webpack-dev-middleware": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.4.0.tgz", - "integrity": "sha512-Q9Iyc0X9dP9bAsYskAVJ/hmIZZQwf/3Sy4xCAZgL5cUkjZmUZLt4l5HpbST/Pdgjn3u6pE7u5OdGd1apgzRujA==", + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.5.1.tgz", + "integrity": "sha512-4dwCh/AyMOYAybggUr8fiCkRnjVDp+Cqlr9c+aaNB3GJYgRGYQWJ1YX/WAKUNA9dPNHZ6QSN2lYDKqjKSI8Vqw==", "dev": true, "requires": { "memory-fs": "~0.4.1", @@ -17455,14 +17402,14 @@ } }, "mem": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-4.0.0.tgz", - "integrity": "sha512-WQxG/5xYc3tMbYLXoXPm81ET2WDULiU5FxbuIoNbJqLOOI8zehXFdZuiUEgfdrU2mVB1pxBZUGlYORSrpuJreA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.1.0.tgz", + "integrity": "sha512-I5u6Q1x7wxO0kdOpYBB28xueHADYps5uty/zg936CiG8NTe5sJL8EjrCuLneuDW3PlMdZBGDIn8BirEVdovZvg==", "dev": true, "requires": { "map-age-cleaner": "^0.1.1", "mimic-fn": "^1.0.0", - "p-is-promise": "^1.1.0" + "p-is-promise": "^2.0.0" } }, "micromatch": { @@ -17486,6 +17433,12 @@ "to-regex": "^3.0.2" } }, + "mime": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.0.tgz", + "integrity": "sha512-ikBcWwyqXQSHKtciCcctu9YfPbFYZ4+gbHEmE0Q8jzcTYQg5dHCr3g2wwAZjPoJfQVXZq6KXAjpXOTf5/cjT7w==", + "dev": true + }, "os-locale": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", @@ -17569,6 +17522,18 @@ } } }, + "webpack-dev-middleware": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.4.0.tgz", + "integrity": "sha512-Q9Iyc0X9dP9bAsYskAVJ/hmIZZQwf/3Sy4xCAZgL5cUkjZmUZLt4l5HpbST/Pdgjn3u6pE7u5OdGd1apgzRujA==", + "dev": true, + "requires": { + "memory-fs": "~0.4.1", + "mime": "^2.3.1", + "range-parser": "^1.0.3", + "webpack-log": "^2.0.0" + } + }, "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", @@ -17614,9 +17579,9 @@ } }, "webpack-merge": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.1.4.tgz", - "integrity": "sha512-TmSe1HZKeOPey3oy1Ov2iS3guIZjWvMT2BBJDzzT5jScHTjVC3mpjJofgueEzaEd6ibhxRDD6MIblDr8tzh8iQ==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.1.tgz", + "integrity": "sha512-4p8WQyS98bUJcCvFMbdGZyZmsKuWjWVnVHnAS3FFg0HDaRVrPbkivx2RYCre8UiemD67RsiFFLfn4JhLAin8Vw==", "dev": true, "requires": { "lodash": "^4.17.5" diff --git a/package.json b/package.json index 00530c2d20..2312a8ced6 100644 --- a/package.json +++ b/package.json @@ -32,45 +32,45 @@ }, "private": true, "dependencies": { - "@alfresco/adf-content-services": "3.0.0-7c66589b26e57061a07a8d38bfebc2ee05fb1b83", - "@alfresco/adf-core": "3.0.0-7c66589b26e57061a07a8d38bfebc2ee05fb1b83", - "@alfresco/adf-extensions": "3.0.0-7c66589b26e57061a07a8d38bfebc2ee05fb1b83", - "@alfresco/js-api": "3.0.0-e9c8ed80decc71d2fc6833cef22851b64ce4b604", - "@angular/animations": "7.2.2", + "@alfresco/adf-content-services": "3.0.0-0282bfa4686accfd24cbac61795891378c25fb64", + "@alfresco/adf-core": "3.0.0-0282bfa4686accfd24cbac61795891378c25fb64", + "@alfresco/adf-extensions": "3.0.0-0282bfa4686accfd24cbac61795891378c25fb64", + "@alfresco/js-api": "3.0.0-d7850f421268e21861e2cd219441b7343efd27ba", + "@angular/animations": "7.2.3", "@angular/cdk": "^7.3.0", - "@angular/common": "7.2.2", - "@angular/compiler": "7.2.2", - "@angular/core": "7.2.2", - "@angular/flex-layout": "^7.0.0-beta.19", - "@angular/forms": "7.2.2", - "@angular/http": "7.2.2", + "@angular/common": "7.2.3", + "@angular/compiler": "7.2.3", + "@angular/core": "7.2.3", + "@angular/flex-layout": "^7.0.0-beta.23", + "@angular/forms": "7.2.3", + "@angular/http": "7.2.3", "@angular/material": "^7.3.0", "@angular/material-moment-adapter": "^7.3.0", - "@angular/platform-browser": "7.2.2", - "@angular/platform-browser-dynamic": "7.2.2", - "@angular/router": "7.2.2", + "@angular/platform-browser": "7.2.3", + "@angular/platform-browser-dynamic": "7.2.3", + "@angular/router": "7.2.3", "@mat-datetimepicker/core": "^3.0.0-beta.0", "@mat-datetimepicker/moment": "^3.0.0-beta.0", "@ngrx/effects": "^7.2.0", "@ngrx/router-store": "^7.2.0", "@ngrx/store": "^7.2.0", "@ngrx/store-devtools": "^7.2.0", - "@ngx-translate/core": "^10.0.2", + "@ngx-translate/core": "^11.0.1", "core-js": "^2.5.7", "hammerjs": "2.0.8", "minimatch-browser": "^1.0.0", "moment": "^2.24.0", "moment-es6": "1.0.0", "pdfjs-dist": "^2.0.489", - "rxjs": "^6.3.3", + "rxjs": "^6.4.0", "zone.js": "0.8.29" }, "devDependencies": { - "@angular-devkit/build-angular": "~0.12.0", - "@angular-devkit/build-ng-packagr": "~0.12.0", - "@angular/cli": "^7.2.3", - "@angular/compiler-cli": "7.2.2", - "@angular/language-service": "7.2.2", + "@angular-devkit/build-angular": "~0.13.0", + "@angular-devkit/build-ng-packagr": "~0.13.0", + "@angular/cli": "^7.3.0", + "@angular/compiler-cli": "7.2.3", + "@angular/language-service": "7.2.3", "@types/jasmine": "^2.5.53", "@types/jasminewd2": "^2.0.2", "@types/node": "9.3.0", diff --git a/src/app/components/favorite-libraries/favorite-libraries.component.html b/src/app/components/favorite-libraries/favorite-libraries.component.html index 8e1f54227c..19e6c06f75 100644 --- a/src/app/components/favorite-libraries/favorite-libraries.component.html +++ b/src/app/components/favorite-libraries/favorite-libraries.component.html @@ -31,18 +31,16 @@ [imageResolver]="imageResolver" (name-click)="navigateTo($event.detail?.node)" > - - - - - - + + + + diff --git a/src/app/components/favorites/favorites.component.html b/src/app/components/favorites/favorites.component.html index 86330b7b3d..e74033407a 100644 --- a/src/app/components/favorites/favorites.component.html +++ b/src/app/components/favorites/favorites.component.html @@ -23,16 +23,14 @@ (node-dblclick)="onNodeDoubleClick($event.detail?.node)" (name-click)="onNodeDoubleClick($event.detail?.node)" > - - - - - - + + + + diff --git a/src/app/components/header/header.component.html b/src/app/components/header/header.component.html index b771bb7b3a..694fec49fc 100644 --- a/src/app/components/header/header.component.html +++ b/src/app/components/header/header.component.html @@ -10,7 +10,7 @@ -
+ diff --git a/src/app/components/libraries/libraries.component.html b/src/app/components/libraries/libraries.component.html index 5c5155126c..2103ece1c5 100644 --- a/src/app/components/libraries/libraries.component.html +++ b/src/app/components/libraries/libraries.component.html @@ -25,16 +25,14 @@ (node-dblclick)="navigateTo($event.detail?.node)" (name-click)="navigateTo($event.detail?.node)" > - - - - - - + + + + diff --git a/src/app/components/recent-files/recent-files.component.html b/src/app/components/recent-files/recent-files.component.html index 5b1c99aeef..05a224afc3 100644 --- a/src/app/components/recent-files/recent-files.component.html +++ b/src/app/components/recent-files/recent-files.component.html @@ -24,16 +24,14 @@ (node-dblclick)="onNodeDoubleClick($event.detail?.node)" (name-click)="onNodeDoubleClick($event.detail?.node)" > - - - - - - + + + + diff --git a/src/app/components/search/search-libraries-results/search-libraries-results.component.html b/src/app/components/search/search-libraries-results/search-libraries-results.component.html index 6c1e167726..3c58d5ace6 100644 --- a/src/app/components/search/search-libraries-results/search-libraries-results.component.html +++ b/src/app/components/search/search-libraries-results/search-libraries-results.component.html @@ -99,17 +99,15 @@ - - - -
-

- {{ 'APP.BROWSE.SEARCH.NO_RESULTS' | translate }} -

-
-
-
-
+ + +
+

+ {{ 'APP.BROWSE.SEARCH.NO_RESULTS' | translate }} +

+
+
+
- - - -
-

- {{ 'APP.BROWSE.SEARCH.NO_RESULTS' | translate }} -

-
-
-
-
+ + +
+

+ {{ 'APP.BROWSE.SEARCH.NO_RESULTS' | translate }} +

+
+
+
- - - - - - + + + + diff --git a/src/app/components/trashcan/trashcan.component.html b/src/app/components/trashcan/trashcan.component.html index bd8519a266..2c6528eba2 100644 --- a/src/app/components/trashcan/trashcan.component.html +++ b/src/app/components/trashcan/trashcan.component.html @@ -22,21 +22,19 @@ [imageResolver]="imageResolver" [sorting]="['archivedAt', 'desc']" > - - - -

- {{ 'APP.BROWSE.TRASHCAN.EMPTY_STATE.FIRST_TEXT' | translate }} -

-

- {{ 'APP.BROWSE.TRASHCAN.EMPTY_STATE.SECOND_TEXT' | translate }} -

-
-
-
+ + +

+ {{ 'APP.BROWSE.TRASHCAN.EMPTY_STATE.FIRST_TEXT' | translate }} +

+

+ {{ 'APP.BROWSE.TRASHCAN.EMPTY_STATE.SECOND_TEXT' | translate }} +

+
+
diff --git a/src/app/services/content-api.service.ts b/src/app/services/content-api.service.ts index 421d871ede..fea3787b8a 100644 --- a/src/app/services/content-api.service.ts +++ b/src/app/services/content-api.service.ts @@ -87,7 +87,7 @@ export class ContentApiService { }; const queryOptions = Object.assign(defaults, options || {}); - return from((this.api.nodesApi).getNodeInfo(nodeId, queryOptions)); + return from(this.api.nodesApi.getNodeInfo(nodeId, queryOptions)); } /** diff --git a/src/app/ui/custom-theme.scss b/src/app/ui/custom-theme.scss index d8225826cd..4a992210e4 100644 --- a/src/app/ui/custom-theme.scss +++ b/src/app/ui/custom-theme.scss @@ -25,7 +25,6 @@ @import './overrides/adf-upload-drag-area.theme'; @import './overrides/adf-search-sorting-picker.theme'; @import './overrides/adf-content-node-selector.theme'; -@import './overrides/adf-layout-header.theme'; @import './overrides/adf-version-manager.theme'; @import 'snackbar'; @@ -81,7 +80,6 @@ $custom-theme: mat-light-theme($custom-theme-primary, $custom-theme-accent); @include adf-upload-drag-area-theme($theme); @include adf-search-sorting-picker-theme($theme); @include adf-content-node-selector-theme($theme); - @include adf-layout-header-theme($theme); @include adf-version-manager-theme($theme); @include layout-theme($theme); diff --git a/src/app/ui/overrides/adf-layout-header.theme.scss b/src/app/ui/overrides/adf-layout-header.theme.scss deleted file mode 100644 index 3befa5401d..0000000000 --- a/src/app/ui/overrides/adf-layout-header.theme.scss +++ /dev/null @@ -1,36 +0,0 @@ -@mixin adf-layout-header-theme($theme) { - $background: map-get($theme, background); - - .adf-layout-header { - .mat-toolbar-single-row { - color: #ffffff !important; - - .adf-app-logo { - margin-left: 6px; - vertical-align: middle; - margin-top: -3px; - } - .adf-app-title { - letter-spacing: -0.3px; - font-weight: 100; - cursor: pointer; - } - .mat-icon-button { - margin-right: 0; - - .mat-icon { - font-size: 29px; - padding: 0 5px 0 0; - } - } - } - - .adf-toolbar-divider { - margin: 0 5px; - - & > div { - background-color: mat-color($background, card, 1); - } - } - } -} diff --git a/src/app/ui/overrides/adf-upload-drag-area.theme.scss b/src/app/ui/overrides/adf-upload-drag-area.theme.scss index 73fc49b1b9..c1e90b0926 100644 --- a/src/app/ui/overrides/adf-upload-drag-area.theme.scss +++ b/src/app/ui/overrides/adf-upload-drag-area.theme.scss @@ -16,7 +16,7 @@ $alfresco-app-color--default: #00bcd4; adf-upload-drag-area { @include flex-column; - .upload-border { + .adf-upload-border { @include flex-column; vertical-align: unset; @@ -27,18 +27,18 @@ $alfresco-app-color--default: #00bcd4; adf-upload-drag-area:first-child { & > div { adf-upload-drag-area { - .file-draggable__input-focus { + .adf-file-draggable__input-focus { @include file-draggable__input-focus($theme); } } } - .upload-border { + .adf-upload-border { vertical-align: inherit !important; text-align: inherit !important; } - .file-draggable__input-focus { + .adf-file-draggable__input-focus { color: none !important; border: none !important; margin-left: 0 !important; @@ -52,7 +52,7 @@ $alfresco-app-color--default: #00bcd4; } adf-upload-drag-area { - .file-draggable__input-focus { + .adf-file-draggable__input-focus { adf-document-list { background: #e0f7fa; From 80dabdd26a13c8b80f87f7efb93f8a429d9aa143 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Sun, 3 Feb 2019 09:42:34 +0000 Subject: [PATCH 035/259] update repository to 6.1.2-ga, SSO example (#914) * remove old compose, update to 6.1.2-ga * SSO with vanilla keycloak --- docker-compose-keycloak.yml | 146 +++ docker-compose.yml | 23 +- docker-compose/README.md | 15 - docker-compose/docker-compose.yml | 94 -- docker-compose/nginx.conf | 45 - docker/auth/alfresco-realm.json | 1673 +++++++++++++++++++++++++++++ docker/nginx.conf | 29 + docs/getting-started/docker.md | 14 +- package.json | 5 +- start-sso.sh | 19 + 10 files changed, 1889 insertions(+), 174 deletions(-) create mode 100644 docker-compose-keycloak.yml delete mode 100644 docker-compose/README.md delete mode 100644 docker-compose/docker-compose.yml delete mode 100644 docker-compose/nginx.conf create mode 100644 docker/auth/alfresco-realm.json create mode 100644 docker/nginx.conf create mode 100755 start-sso.sh diff --git a/docker-compose-keycloak.yml b/docker-compose-keycloak.yml new file mode 100644 index 0000000000..2391a9ad10 --- /dev/null +++ b/docker-compose-keycloak.yml @@ -0,0 +1,146 @@ +version: '2' + +services: + alfresco: + image: alfresco/alfresco-content-repository-community:6.1.2-ga + mem_limit: 1500m + depends_on: + - postgres + - auth + environment: + AUTH_SERVER_URL: ${AUTH_SERVER_URL} + JAVA_OPTS: ' + -Ddb.driver=org.postgresql.Driver + -Ddb.username=alfresco + -Ddb.password=alfresco + -Ddb.url=jdbc:postgresql://postgres:5432/alfresco + -Dsolr.host=solr6 + -Dsolr.port=8983 + -Dsolr.secureComms=none + -Dsolr.base.url=/solr + -Dindex.subsystem.name=solr6 + -Dshare.host=localhost + -Dalfresco.port=8080 + -Daos.baseUrlOverwrite=http://localhost:8080/alfresco/aos + -Dmessaging.broker.url="failover:(nio://activemq:61616)?timeout=3000&jms.useCompression=true" + -Ddeployment.method=DOCKER_COMPOSE + -Dcsrf.filter.enabled=false + -Xms1g -Xmx1g + -Dauthentication.chain=identity-service1:identity-service,alfrescoNtlm1:alfrescoNtlm + -Didentity-service.enable-basic-auth=true + -Didentity-service.authentication.validation.failure.silent=false + -Didentity-service.auth-server-url=${AUTH_SERVER_URL} + -Didentity-service.realm=alfresco + -Didentity-service.resource=alfresco + ' + networks: + - internal + ports: + - 8080:8080 #Browser port + + share: + image: alfresco/alfresco-share:6.1.0-RC3 + mem_limit: 1g + depends_on: + - alfresco + environment: + - REPO_HOST=alfresco + - REPO_PORT=8080 + - 'CATALINA_OPTS= -Xms500m -Xmx500m' + networks: + - internal + ports: + - 8083:8080 + + postgres: + image: postgres:10.1 + mem_limit: 1500m + environment: + - POSTGRES_PASSWORD=alfresco + - POSTGRES_USER=alfresco + - POSTGRES_DB=alfresco + command: postgres -c max_connections=300 -c log_min_messages=LOG + networks: + - internal + ports: + - 5432:5432 + + solr6: + image: alfresco/alfresco-search-services:1.3.0-RC2 + mem_limit: 2500m + depends_on: + - alfresco + environment: + #Solr needs to know how to register itself with Alfresco + - SOLR_ALFRESCO_HOST=alfresco + - SOLR_ALFRESCO_PORT=8080 + #Alfresco needs to know how to call solr + - SOLR_SOLR_HOST=solr6 + - SOLR_SOLR_PORT=8983 + #Create the default alfresco and archive cores + - SOLR_CREATE_ALFRESCO_DEFAULTS=alfresco,archive + - 'SOLR_JAVA_MEM=-Xms2g -Xmx2g' + networks: + - internal + ports: + - 8983:8983 #Browser port + + activemq: + image: alfresco/alfresco-activemq:5.15.6 + mem_limit: 2048m + networks: + - internal + ports: + - 8161:8161 # Web Console + - 5672:5672 # AMQP + - 61616:61616 # OpenWire + - 61613:61613 # STOMP + + content-app: + image: alfresco/alfresco-content-app:latest + build: . + environment: + # BASEPATH: ./ + APP_CONFIG_OAUTH2_HOST: ${APP_CONFIG_OAUTH2_HOST} + APP_CONFIG_AUTH_TYPE: ${APP_CONFIG_AUTH_TYPE} + APP_CONFIG_OAUTH2_CLIENTID: ${APP_CONFIG_OAUTH2_CLIENTID} + APP_CONFIG_OAUTH2_REDIRECT_SILENT_IFRAME_URI: ${APP_CONFIG_OAUTH2_REDIRECT_SILENT_IFRAME_URI} + APP_CONFIG_OAUTH2_REDIRECT_LOGIN: ${APP_CONFIG_OAUTH2_REDIRECT_LOGIN} + APP_CONFIG_OAUTH2_REDIRECT_LOGOUT: ${APP_CONFIG_OAUTH2_REDIRECT_LOGOUT} + depends_on: + - alfresco + networks: + - internal + ports: + - 4001:80 + # volumes: + # - ./app.config.json:/usr/share/nginx/html/app.config.json + # - ./nginx.conf:/etc/nginx/conf.d/default.conf + + proxy: + image: nginx:stable-alpine + depends_on: + - content-app + volumes: + - ./docker/nginx.conf:/etc/nginx/conf.d/default.conf + networks: + - internal + ports: + - 4000:80 + + auth: + image: jboss/keycloak:4.8.3.Final + volumes: + - ./docker/auth/alfresco-realm.json:/tmp/alfresco-realm.json + environment: + - KEYCLOAK_USER=admin + - KEYCLOAK_PASSWORD=admin + - KEYCLOAK_IMPORT=/tmp/alfresco-realm.json + - DB_VENDOR=h2 + networks: + - internal + ports: + - 8085:8080 + +networks: + internal: diff --git a/docker-compose.yml b/docker-compose.yml index e484546775..523fe41d99 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,8 +1,9 @@ -version: '3' +version: '2' services: alfresco: - image: alfresco/alfresco-content-repository-community:6.1.0-ea + image: alfresco/alfresco-content-repository-community:6.1.2-ga + mem_limit: 1500m depends_on: - postgres environment: @@ -17,8 +18,12 @@ services: -Dsolr.base.url=/solr -Dindex.subsystem.name=solr6 -Dshare.host=localhost + -Dalfresco.port=8080 + -Daos.baseUrlOverwrite=http://localhost:8080/alfresco/aos + -Dmessaging.broker.url="failover:(nio://activemq:61616)?timeout=3000&jms.useCompression=true" -Ddeployment.method=DOCKER_COMPOSE -Dcsrf.filter.enabled=false + -Xms1g -Xmx1g ' networks: - internal @@ -26,12 +31,14 @@ services: - 8080:8080 #Browser port share: - image: alfresco/alfresco-share:6.0.c + image: alfresco/alfresco-share:6.1.0-RC3 + mem_limit: 1g depends_on: - alfresco environment: - REPO_HOST=alfresco - REPO_PORT=8080 + - 'CATALINA_OPTS= -Xms500m -Xmx500m' networks: - internal ports: @@ -39,6 +46,7 @@ services: postgres: image: postgres:10.1 + mem_limit: 1500m environment: - POSTGRES_PASSWORD=alfresco - POSTGRES_USER=alfresco @@ -50,7 +58,8 @@ services: - 5432:5432 solr6: - image: alfresco/alfresco-search-services:1.2.0 + image: alfresco/alfresco-search-services:1.3.0-RC2 + mem_limit: 2500m depends_on: - alfresco environment: @@ -62,6 +71,7 @@ services: - SOLR_SOLR_PORT=8983 #Create the default alfresco and archive cores - SOLR_CREATE_ALFRESCO_DEFAULTS=alfresco,archive + - 'SOLR_JAVA_MEM=-Xms2g -Xmx2g' networks: - internal ports: @@ -69,6 +79,7 @@ services: activemq: image: alfresco/alfresco-activemq:5.15.6 + mem_limit: 2048m networks: - internal ports: @@ -95,11 +106,11 @@ services: depends_on: - content-app volumes: - - ./docker-compose/nginx.conf:/etc/nginx/conf.d/default.conf + - ./docker/nginx.conf:/etc/nginx/conf.d/default.conf networks: - internal ports: - 4000:80 networks: - ? internal + internal: diff --git a/docker-compose/README.md b/docker-compose/README.md deleted file mode 100644 index 7cf4122e28..0000000000 --- a/docker-compose/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# ACA with ACS Community 6.0ea - -To run ACA together with the latest ACS community (6.0) use the following command: - -```sh -docker-compose up -``` - -The ACA is served on the port 3000. - -If you want to teardown the environment, use the following command: - -```sh -docker-compose down -``` diff --git a/docker-compose/docker-compose.yml b/docker-compose/docker-compose.yml deleted file mode 100644 index b2813417cf..0000000000 --- a/docker-compose/docker-compose.yml +++ /dev/null @@ -1,94 +0,0 @@ -version: "3" - -services: - alfresco: - image: alfresco/alfresco-content-repository-community:6.0.7-ga - depends_on: - - postgres - environment: - JAVA_OPTS : " - -Ddb.driver=org.postgresql.Driver - -Ddb.username=alfresco - -Ddb.password=alfresco - -Ddb.url=jdbc:postgresql://postgres:5432/alfresco - -Dsolr.host=solr6 - -Dsolr.port=8983 - -Dsolr.secureComms=none - -Dsolr.base.url=/solr - -Dindex.subsystem.name=solr6 - -Dshare.host=localhost - -Ddeployment.method=DOCKER_COMPOSE - -Dcsrf.filter.enabled=false - " - networks: - - internal - ports: - - 8080:8080 #Browser port - - share: - image: alfresco/alfresco-share:6.0.b - depends_on: - - alfresco - environment: - - REPO_HOST=alfresco - - REPO_PORT=8080 - networks: - - internal - ports: - - 8083:8080 - - postgres: - image: postgres:10.1 - environment: - - POSTGRES_PASSWORD=alfresco - - POSTGRES_USER=alfresco - - POSTGRES_DB=alfresco - command: postgres -c max_connections=300 -c log_min_messages=LOG - networks: - - internal - ports: - - 5432:5432 - - solr6: - image: alfresco/alfresco-search-services:1.1.1 - depends_on: - - alfresco - environment: - #Solr needs to know how to register itself with Alfresco - - SOLR_ALFRESCO_HOST=alfresco - - SOLR_ALFRESCO_PORT=8080 - #Alfresco needs to know how to call solr - - SOLR_SOLR_HOST=solr6 - - SOLR_SOLR_PORT=8983 - #Create the default alfresco and archive cores - - SOLR_CREATE_ALFRESCO_DEFAULTS=alfresco,archive - networks: - - internal - ports: - - 8983:8983 #Browser port - - content-app: - image: alfresco/alfresco-content-app:master-latest - depends_on: - - alfresco - networks: - - internal - ports: - - 3001:80 - # volumes: - # - ./app.config.json:/usr/share/nginx/html/app.config.json - # - ./nginx.conf:/etc/nginx/conf.d/default.conf - - proxy: - image: nginx - depends_on: - - content-app - volumes: - - ./nginx.conf:/etc/nginx/conf.d/default.conf - networks: - - internal - ports: - - 3000:80 - -networks: - internal: diff --git a/docker-compose/nginx.conf b/docker-compose/nginx.conf deleted file mode 100644 index 816f208655..0000000000 --- a/docker-compose/nginx.conf +++ /dev/null @@ -1,45 +0,0 @@ -server { - listen *:80; - - set $allowOriginSite *; - proxy_pass_request_headers on; - proxy_pass_header Set-Cookie; - - access_log off; - - location / { - proxy_pass http://content-app; - - proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; - proxy_redirect off; - proxy_buffering off; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_pass_header Set-Cookie; - } - - location /alfresco/ { - proxy_pass http://alfresco:8080; - - proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; - proxy_redirect off; - proxy_buffering off; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_pass_header Set-Cookie; - } - - location /share/ { - proxy_pass http://share:8080; - - proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; - proxy_redirect off; - proxy_buffering off; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_pass_header Set-Cookie; - } -} diff --git a/docker/auth/alfresco-realm.json b/docker/auth/alfresco-realm.json new file mode 100644 index 0000000000..ca02bd1256 --- /dev/null +++ b/docker/auth/alfresco-realm.json @@ -0,0 +1,1673 @@ +{ + "id": "alfresco", + "realm": "alfresco", + "notBefore": 0, + "revokeRefreshToken": false, + "refreshTokenMaxReuse": 0, + "accessTokenLifespan": 300, + "accessTokenLifespanForImplicitFlow": 900, + "ssoSessionIdleTimeout": 1800, + "ssoSessionMaxLifespan": 36000, + "offlineSessionIdleTimeout": 2592000, + "accessCodeLifespan": 60, + "accessCodeLifespanUserAction": 300, + "accessCodeLifespanLogin": 1800, + "actionTokenGeneratedByAdminLifespan": 43200, + "actionTokenGeneratedByUserLifespan": 300, + "enabled": true, + "sslRequired": "none", + "registrationAllowed": false, + "registrationEmailAsUsername": false, + "rememberMe": false, + "verifyEmail": false, + "loginWithEmailAllowed": true, + "duplicateEmailsAllowed": false, + "resetPasswordAllowed": false, + "editUsernameAllowed": false, + "bruteForceProtected": false, + "permanentLockout": false, + "maxFailureWaitSeconds": 900, + "minimumQuickLoginWaitSeconds": 60, + "waitIncrementSeconds": 60, + "quickLoginCheckMilliSeconds": 1000, + "maxDeltaTimeSeconds": 43200, + "failureFactor": 30, + "roles": { + "realm": [ + { + "id": "39654467-e529-418e-bd27-354a0414fb52", + "name": "admin", + "scopeParamRequired": false, + "composite": false, + "clientRole": false, + "containerId": "alfresco" + }, + { + "id": "5b481c9b-38fe-474a-a047-50c3935262cb", + "name": "uma_authorization", + "description": "${role_uma_authorization}", + "scopeParamRequired": false, + "composite": false, + "clientRole": false, + "containerId": "alfresco" + }, + { + "id": "86db4867-8c3c-4cdf-8950-e18790f5bf6a", + "name": "offline_access", + "description": "${role_offline-access}", + "scopeParamRequired": true, + "composite": false, + "clientRole": false, + "containerId": "alfresco" + } + ], + "client": { + "realm-management": [ + { + "id": "a637f20f-fd3e-4db6-9d2a-c91acb1e14e8", + "name": "create-client", + "description": "${role_create-client}", + "scopeParamRequired": false, + "composite": false, + "clientRole": true, + "containerId": "c1f65e94-ed07-4bba-bafd-413db402a5f2" + }, + { + "id": "4232f8bf-dab4-4b4a-8ccf-28b8984f8ae7", + "name": "realm-admin", + "description": "${role_realm-admin}", + "scopeParamRequired": false, + "composite": true, + "composites": { + "client": { + "realm-management": [ + "create-client", + "view-authorization", + "manage-events", + "query-users", + "manage-authorization", + "view-realm", + "view-clients", + "query-clients", + "query-groups", + "impersonation", + "manage-users", + "manage-clients", + "manage-identity-providers", + "view-users", + "query-realms", + "view-identity-providers", + "view-events", + "manage-realm" + ] + } + }, + "clientRole": true, + "containerId": "c1f65e94-ed07-4bba-bafd-413db402a5f2" + }, + { + "id": "ae0da5c2-643c-480e-8900-59bdca3581b3", + "name": "view-authorization", + "description": "${role_view-authorization}", + "scopeParamRequired": false, + "composite": false, + "clientRole": true, + "containerId": "c1f65e94-ed07-4bba-bafd-413db402a5f2" + }, + { + "id": "8a69ec22-4fe9-43e0-b4f0-16b632c2d324", + "name": "manage-events", + "description": "${role_manage-events}", + "scopeParamRequired": false, + "composite": false, + "clientRole": true, + "containerId": "c1f65e94-ed07-4bba-bafd-413db402a5f2" + }, + { + "id": "1c2c870c-5428-4144-ab12-c7304d1a7d2d", + "name": "query-users", + "description": "${role_query-users}", + "scopeParamRequired": false, + "composite": false, + "clientRole": true, + "containerId": "c1f65e94-ed07-4bba-bafd-413db402a5f2" + }, + { + "id": "9884df61-b63f-4f8b-8fba-650db69c8784", + "name": "manage-authorization", + "description": "${role_manage-authorization}", + "scopeParamRequired": false, + "composite": false, + "clientRole": true, + "containerId": "c1f65e94-ed07-4bba-bafd-413db402a5f2" + }, + { + "id": "003ae8b9-e32a-4c0b-b319-d2a985249348", + "name": "view-realm", + "description": "${role_view-realm}", + "scopeParamRequired": false, + "composite": false, + "clientRole": true, + "containerId": "c1f65e94-ed07-4bba-bafd-413db402a5f2" + }, + { + "id": "d0d2eaa3-e737-4a7e-990d-4c6efa323cc3", + "name": "view-clients", + "description": "${role_view-clients}", + "scopeParamRequired": false, + "composite": true, + "composites": { + "client": { + "realm-management": ["query-clients"] + } + }, + "clientRole": true, + "containerId": "c1f65e94-ed07-4bba-bafd-413db402a5f2" + }, + { + "id": "d9f0638c-e045-4d92-b4ff-e0c71f68f4ba", + "name": "query-clients", + "description": "${role_query-clients}", + "scopeParamRequired": false, + "composite": false, + "clientRole": true, + "containerId": "c1f65e94-ed07-4bba-bafd-413db402a5f2" + }, + { + "id": "02d5937c-929b-4928-8a55-b0de4c9b4924", + "name": "query-groups", + "description": "${role_query-groups}", + "scopeParamRequired": false, + "composite": false, + "clientRole": true, + "containerId": "c1f65e94-ed07-4bba-bafd-413db402a5f2" + }, + { + "id": "c74d9c9b-65e4-4847-a47a-3edbb2fce0fb", + "name": "impersonation", + "description": "${role_impersonation}", + "scopeParamRequired": false, + "composite": false, + "clientRole": true, + "containerId": "c1f65e94-ed07-4bba-bafd-413db402a5f2" + }, + { + "id": "e681501e-a8da-4653-861c-c37e2e1f8609", + "name": "manage-users", + "description": "${role_manage-users}", + "scopeParamRequired": false, + "composite": false, + "clientRole": true, + "containerId": "c1f65e94-ed07-4bba-bafd-413db402a5f2" + }, + { + "id": "067b5e3c-9918-4713-85ca-749c6aae13e1", + "name": "manage-clients", + "description": "${role_manage-clients}", + "scopeParamRequired": false, + "composite": false, + "clientRole": true, + "containerId": "c1f65e94-ed07-4bba-bafd-413db402a5f2" + }, + { + "id": "5b395e85-f5fa-4af9-b573-497cc9b1e694", + "name": "manage-identity-providers", + "description": "${role_manage-identity-providers}", + "scopeParamRequired": false, + "composite": false, + "clientRole": true, + "containerId": "c1f65e94-ed07-4bba-bafd-413db402a5f2" + }, + { + "id": "b4ec253f-4d52-425e-b091-ed51aac7bd4c", + "name": "view-users", + "description": "${role_view-users}", + "scopeParamRequired": false, + "composite": true, + "composites": { + "client": { + "realm-management": ["query-groups", "query-users"] + } + }, + "clientRole": true, + "containerId": "c1f65e94-ed07-4bba-bafd-413db402a5f2" + }, + { + "id": "574e930a-07d5-446f-9628-3d7568eb483a", + "name": "query-realms", + "description": "${role_query-realms}", + "scopeParamRequired": false, + "composite": false, + "clientRole": true, + "containerId": "c1f65e94-ed07-4bba-bafd-413db402a5f2" + }, + { + "id": "0cb1c9c8-55ce-4f22-b6d5-b6882c8b74fd", + "name": "view-identity-providers", + "description": "${role_view-identity-providers}", + "scopeParamRequired": false, + "composite": false, + "clientRole": true, + "containerId": "c1f65e94-ed07-4bba-bafd-413db402a5f2" + }, + { + "id": "5d07f2b1-9f28-4e8b-8f91-7d68699d327c", + "name": "view-events", + "description": "${role_view-events}", + "scopeParamRequired": false, + "composite": false, + "clientRole": true, + "containerId": "c1f65e94-ed07-4bba-bafd-413db402a5f2" + }, + { + "id": "53ccf3c9-4391-4d43-9d9e-6e644b989e9f", + "name": "manage-realm", + "description": "${role_manage-realm}", + "scopeParamRequired": false, + "composite": false, + "clientRole": true, + "containerId": "c1f65e94-ed07-4bba-bafd-413db402a5f2" + } + ], + "security-admin-console": [], + "alfresco": [], + "admin-cli": [], + "broker": [ + { + "id": "560b729f-ebc7-4ce6-967b-045611d35cde", + "name": "read-token", + "description": "${role_read-token}", + "scopeParamRequired": false, + "composite": false, + "clientRole": true, + "containerId": "887e537f-4a97-4374-a5de-45ad37bfe2df" + } + ], + "account": [ + { + "id": "86de6e40-74c1-4aa6-9a8b-bff434fb9a18", + "name": "manage-account-links", + "description": "${role_manage-account-links}", + "scopeParamRequired": false, + "composite": false, + "clientRole": true, + "containerId": "140feb9e-fd73-4d02-97f6-928ed67020f1" + }, + { + "id": "6a95ddc1-2b12-4e59-8d14-01a98c0fad71", + "name": "manage-account", + "description": "${role_manage-account}", + "scopeParamRequired": false, + "composite": true, + "composites": { + "client": { + "account": ["manage-account-links"] + } + }, + "clientRole": true, + "containerId": "140feb9e-fd73-4d02-97f6-928ed67020f1" + }, + { + "id": "a8e8d710-1f71-4481-93a1-db030533b64a", + "name": "view-profile", + "description": "${role_view-profile}", + "scopeParamRequired": false, + "composite": false, + "clientRole": true, + "containerId": "140feb9e-fd73-4d02-97f6-928ed67020f1" + } + ] + } + }, + "groups": [ + { + "id": "21cd4641-e7cb-456f-846d-214589cef3da", + "name": "admin", + "path": "/admin", + "attributes": {}, + "realmRoles": [], + "clientRoles": {}, + "subGroups": [] + } + ], + "defaultRoles": ["offline_access", "uma_authorization"], + "requiredCredentials": ["password"], + "otpPolicyType": "totp", + "otpPolicyAlgorithm": "HmacSHA256", + "otpPolicyInitialCounter": 0, + "otpPolicyDigits": 6, + "otpPolicyLookAheadWindow": 1, + "otpPolicyPeriod": 30, + "otpSupportedApplications": ["FreeOTP"], + "clients": [ + { + "id": "fca5da6d-fd90-4596-a754-346d872b779f", + "clientId": "security-admin-console", + "name": "${client_security-admin-console}", + "baseUrl": "/auth/admin/alfresco/console/index.html", + "surrogateAuthRequired": false, + "enabled": true, + "clientAuthenticatorType": "client-secret", + "secret": "**********", + "redirectUris": ["/auth/admin/alfresco/console/*"], + "webOrigins": [], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": false, + "serviceAccountsEnabled": false, + "publicClient": true, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": {}, + "fullScopeAllowed": false, + "nodeReRegistrationTimeout": 0, + "protocolMappers": [ + { + "id": "50435a57-d933-4392-aa63-c7b93969cb77", + "name": "role list", + "protocol": "saml", + "protocolMapper": "saml-role-list-mapper", + "consentRequired": false, + "config": { + "single": "false", + "attribute.nameformat": "Basic", + "attribute.name": "Role" + } + }, + { + "id": "9d065ef2-ac16-4314-bdce-6df1e32b45da", + "name": "username", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": true, + "consentText": "${username}", + "config": { + "userinfo.token.claim": "true", + "user.attribute": "username", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "preferred_username", + "jsonType.label": "String" + } + }, + { + "id": "f21fa9c5-090a-4873-a059-5a714e186e08", + "name": "full name", + "protocol": "openid-connect", + "protocolMapper": "oidc-full-name-mapper", + "consentRequired": true, + "consentText": "${fullName}", + "config": { + "id.token.claim": "true", + "access.token.claim": "true" + } + }, + { + "id": "1d28c5e3-d1ab-4563-838d-06c61e96fd3c", + "name": "family name", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": true, + "consentText": "${familyName}", + "config": { + "userinfo.token.claim": "true", + "user.attribute": "lastName", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "family_name", + "jsonType.label": "String" + } + }, + { + "id": "0fd5ed6e-65af-4661-9d40-09a0dc90d705", + "name": "locale", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "consentText": "${locale}", + "config": { + "userinfo.token.claim": "true", + "user.attribute": "locale", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "locale", + "jsonType.label": "String" + } + }, + { + "id": "47febcd5-e6e8-4c83-8ea0-551f66cbef51", + "name": "email", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": true, + "consentText": "${email}", + "config": { + "userinfo.token.claim": "true", + "user.attribute": "email", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "email", + "jsonType.label": "String" + } + }, + { + "id": "fc891ffd-b5b7-4d56-b1cd-60ae25ec0040", + "name": "given name", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": true, + "consentText": "${givenName}", + "config": { + "userinfo.token.claim": "true", + "user.attribute": "firstName", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "given_name", + "jsonType.label": "String" + } + } + ], + "useTemplateConfig": false, + "useTemplateScope": false, + "useTemplateMappers": false + }, + { + "id": "be13165d-2792-43aa-abdb-2c6cdb627184", + "clientId": "alfresco", + "surrogateAuthRequired": false, + "enabled": true, + "clientAuthenticatorType": "client-secret", + "secret": "**********", + "redirectUris": ["*"], + "webOrigins": [], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": true, + "directAccessGrantsEnabled": true, + "serviceAccountsEnabled": false, + "publicClient": true, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": {}, + "fullScopeAllowed": true, + "nodeReRegistrationTimeout": -1, + "protocolMappers": [ + { + "id": "202b6b67-dea4-440b-b250-867fa7eb7333", + "name": "role list", + "protocol": "saml", + "protocolMapper": "saml-role-list-mapper", + "consentRequired": false, + "config": { + "single": "false", + "attribute.nameformat": "Basic", + "attribute.name": "Role" + } + }, + { + "id": "cdb53973-5bf0-4de4-945d-901de3205016", + "name": "email", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": true, + "consentText": "${email}", + "config": { + "userinfo.token.claim": "true", + "user.attribute": "email", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "email", + "jsonType.label": "String" + } + }, + { + "id": "8dd3c664-426e-44e7-931f-5e0700ed9e7f", + "name": "username", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": true, + "consentText": "${username}", + "config": { + "userinfo.token.claim": "true", + "user.attribute": "username", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "preferred_username", + "jsonType.label": "String" + } + }, + { + "id": "aa1a443c-4716-424b-b695-49961d9cf98a", + "name": "family name", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": true, + "consentText": "${familyName}", + "config": { + "userinfo.token.claim": "true", + "user.attribute": "lastName", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "family_name", + "jsonType.label": "String" + } + }, + { + "id": "b29201a7-e442-47f6-a589-1b6faaf27b20", + "name": "full name", + "protocol": "openid-connect", + "protocolMapper": "oidc-full-name-mapper", + "consentRequired": true, + "consentText": "${fullName}", + "config": { + "id.token.claim": "true", + "access.token.claim": "true" + } + }, + { + "id": "292f1e75-3216-447d-886a-6ab91b0dee1d", + "name": "given name", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": true, + "consentText": "${givenName}", + "config": { + "userinfo.token.claim": "true", + "user.attribute": "firstName", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "given_name", + "jsonType.label": "String" + } + } + ], + "useTemplateConfig": false, + "useTemplateScope": false, + "useTemplateMappers": false + }, + { + "id": "887e537f-4a97-4374-a5de-45ad37bfe2df", + "clientId": "broker", + "name": "${client_broker}", + "surrogateAuthRequired": false, + "enabled": true, + "clientAuthenticatorType": "client-secret", + "secret": "**********", + "redirectUris": [], + "webOrigins": [], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": false, + "serviceAccountsEnabled": false, + "publicClient": false, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": {}, + "fullScopeAllowed": false, + "nodeReRegistrationTimeout": 0, + "protocolMappers": [ + { + "id": "865fd86a-4c5e-4900-80de-34f30feb55b8", + "name": "family name", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": true, + "consentText": "${familyName}", + "config": { + "userinfo.token.claim": "true", + "user.attribute": "lastName", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "family_name", + "jsonType.label": "String" + } + }, + { + "id": "80b5d7cc-1ec3-4d73-8344-d0479bb4178a", + "name": "username", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": true, + "consentText": "${username}", + "config": { + "userinfo.token.claim": "true", + "user.attribute": "username", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "preferred_username", + "jsonType.label": "String" + } + }, + { + "id": "54578e9a-e782-4a83-8f24-13da2b2f598c", + "name": "given name", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": true, + "consentText": "${givenName}", + "config": { + "userinfo.token.claim": "true", + "user.attribute": "firstName", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "given_name", + "jsonType.label": "String" + } + }, + { + "id": "a8cd846c-f538-4001-ba5f-e37d77ff87cd", + "name": "full name", + "protocol": "openid-connect", + "protocolMapper": "oidc-full-name-mapper", + "consentRequired": true, + "consentText": "${fullName}", + "config": { + "id.token.claim": "true", + "access.token.claim": "true" + } + }, + { + "id": "a259f058-dbda-473a-b96e-2998958f8510", + "name": "role list", + "protocol": "saml", + "protocolMapper": "saml-role-list-mapper", + "consentRequired": false, + "config": { + "single": "false", + "attribute.nameformat": "Basic", + "attribute.name": "Role" + } + }, + { + "id": "c7aed2b8-6716-4770-a936-31d973bdc557", + "name": "email", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": true, + "consentText": "${email}", + "config": { + "userinfo.token.claim": "true", + "user.attribute": "email", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "email", + "jsonType.label": "String" + } + } + ], + "useTemplateConfig": false, + "useTemplateScope": false, + "useTemplateMappers": false + }, + { + "id": "c1f65e94-ed07-4bba-bafd-413db402a5f2", + "clientId": "realm-management", + "name": "${client_realm-management}", + "surrogateAuthRequired": false, + "enabled": true, + "clientAuthenticatorType": "client-secret", + "secret": "**********", + "redirectUris": [], + "webOrigins": [], + "notBefore": 0, + "bearerOnly": true, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": false, + "serviceAccountsEnabled": false, + "publicClient": false, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": {}, + "fullScopeAllowed": false, + "nodeReRegistrationTimeout": 0, + "protocolMappers": [ + { + "id": "b51a2178-2121-42c8-9ae1-7a6f356377c0", + "name": "full name", + "protocol": "openid-connect", + "protocolMapper": "oidc-full-name-mapper", + "consentRequired": true, + "consentText": "${fullName}", + "config": { + "id.token.claim": "true", + "access.token.claim": "true" + } + }, + { + "id": "091f3317-7f74-417f-9854-1726ede0fba8", + "name": "username", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": true, + "consentText": "${username}", + "config": { + "userinfo.token.claim": "true", + "user.attribute": "username", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "preferred_username", + "jsonType.label": "String" + } + }, + { + "id": "033aeb3f-f04f-460b-9eeb-fd9376b1f639", + "name": "family name", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": true, + "consentText": "${familyName}", + "config": { + "userinfo.token.claim": "true", + "user.attribute": "lastName", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "family_name", + "jsonType.label": "String" + } + }, + { + "id": "5e3d143c-1792-41c1-bf10-2ece9684a8fc", + "name": "given name", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": true, + "consentText": "${givenName}", + "config": { + "userinfo.token.claim": "true", + "user.attribute": "firstName", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "given_name", + "jsonType.label": "String" + } + }, + { + "id": "e0464a63-f5ac-4fb8-9cf5-dc671badf59e", + "name": "email", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": true, + "consentText": "${email}", + "config": { + "userinfo.token.claim": "true", + "user.attribute": "email", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "email", + "jsonType.label": "String" + } + }, + { + "id": "b68aec8b-327d-4238-8021-cefda0f66690", + "name": "role list", + "protocol": "saml", + "protocolMapper": "saml-role-list-mapper", + "consentRequired": false, + "config": { + "single": "false", + "attribute.nameformat": "Basic", + "attribute.name": "Role" + } + } + ], + "useTemplateConfig": false, + "useTemplateScope": false, + "useTemplateMappers": false + }, + { + "id": "140feb9e-fd73-4d02-97f6-928ed67020f1", + "clientId": "account", + "name": "${client_account}", + "baseUrl": "/auth/realms/alfresco/account", + "surrogateAuthRequired": false, + "enabled": true, + "clientAuthenticatorType": "client-secret", + "secret": "**********", + "defaultRoles": ["view-profile", "manage-account"], + "redirectUris": ["/auth/realms/alfresco/account/*"], + "webOrigins": [], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": false, + "serviceAccountsEnabled": false, + "publicClient": false, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": {}, + "fullScopeAllowed": false, + "nodeReRegistrationTimeout": 0, + "protocolMappers": [ + { + "id": "fbda389d-78dd-4566-8238-c49a8809a3ac", + "name": "email", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": true, + "consentText": "${email}", + "config": { + "userinfo.token.claim": "true", + "user.attribute": "email", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "email", + "jsonType.label": "String" + } + }, + { + "id": "88b68fdb-7f1b-459b-9013-2c1dfcb4ab87", + "name": "family name", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": true, + "consentText": "${familyName}", + "config": { + "userinfo.token.claim": "true", + "user.attribute": "lastName", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "family_name", + "jsonType.label": "String" + } + }, + { + "id": "9d129b38-1b18-4c79-a987-088ec7460d8d", + "name": "username", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": true, + "consentText": "${username}", + "config": { + "userinfo.token.claim": "true", + "user.attribute": "username", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "preferred_username", + "jsonType.label": "String" + } + }, + { + "id": "6ca7c6ca-4d2f-4fbe-8288-c65ec1f1a2ef", + "name": "role list", + "protocol": "saml", + "protocolMapper": "saml-role-list-mapper", + "consentRequired": false, + "config": { + "single": "false", + "attribute.nameformat": "Basic", + "attribute.name": "Role" + } + }, + { + "id": "dcaaafc2-72d0-41b1-9df1-250aa82c3aa3", + "name": "full name", + "protocol": "openid-connect", + "protocolMapper": "oidc-full-name-mapper", + "consentRequired": true, + "consentText": "${fullName}", + "config": { + "id.token.claim": "true", + "access.token.claim": "true" + } + }, + { + "id": "64a2de57-3811-415f-a6b9-b550c3dfd8b0", + "name": "given name", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": true, + "consentText": "${givenName}", + "config": { + "userinfo.token.claim": "true", + "user.attribute": "firstName", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "given_name", + "jsonType.label": "String" + } + } + ], + "useTemplateConfig": false, + "useTemplateScope": false, + "useTemplateMappers": false + }, + { + "id": "b5947c98-5a51-47f4-b7c9-935c491d17e9", + "clientId": "admin-cli", + "name": "${client_admin-cli}", + "surrogateAuthRequired": false, + "enabled": true, + "clientAuthenticatorType": "client-secret", + "secret": "**********", + "redirectUris": [], + "webOrigins": [], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": false, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": true, + "serviceAccountsEnabled": false, + "publicClient": true, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": {}, + "fullScopeAllowed": false, + "nodeReRegistrationTimeout": 0, + "protocolMappers": [ + { + "id": "3a7400ad-d225-401f-bdb7-91d60db990f6", + "name": "username", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": true, + "consentText": "${username}", + "config": { + "userinfo.token.claim": "true", + "user.attribute": "username", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "preferred_username", + "jsonType.label": "String" + } + }, + { + "id": "e4353798-aaac-40fa-967d-64aea182dd69", + "name": "email", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": true, + "consentText": "${email}", + "config": { + "userinfo.token.claim": "true", + "user.attribute": "email", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "email", + "jsonType.label": "String" + } + }, + { + "id": "8fe5f0fa-b9f3-41c4-9a52-b195582d9239", + "name": "family name", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": true, + "consentText": "${familyName}", + "config": { + "userinfo.token.claim": "true", + "user.attribute": "lastName", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "family_name", + "jsonType.label": "String" + } + }, + { + "id": "44872cc3-57b5-41d3-aae1-825dd2c350c0", + "name": "full name", + "protocol": "openid-connect", + "protocolMapper": "oidc-full-name-mapper", + "consentRequired": true, + "consentText": "${fullName}", + "config": { + "id.token.claim": "true", + "access.token.claim": "true" + } + }, + { + "id": "29d794ba-6708-49cd-8a83-c50d6fc0e293", + "name": "role list", + "protocol": "saml", + "protocolMapper": "saml-role-list-mapper", + "consentRequired": false, + "config": { + "single": "false", + "attribute.nameformat": "Basic", + "attribute.name": "Role" + } + }, + { + "id": "4c266a5c-cb5f-407a-876e-18f002b7792a", + "name": "given name", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": true, + "consentText": "${givenName}", + "config": { + "userinfo.token.claim": "true", + "user.attribute": "firstName", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "given_name", + "jsonType.label": "String" + } + } + ], + "useTemplateConfig": false, + "useTemplateScope": false, + "useTemplateMappers": false + } + ], + "browserSecurityHeaders": { + "xContentTypeOptions": "nosniff", + "xRobotsTag": "none", + "xFrameOptions": "SAMEORIGIN", + "xXSSProtection": "1; mode=block", + "contentSecurityPolicy": "frame-src 'self'; frame-ancestors 'self'; object-src 'none';" + }, + "smtpServer": {}, + "loginTheme": "keycloak", + "eventsEnabled": false, + "eventsListeners": ["jboss-logging"], + "enabledEventTypes": [], + "adminEventsEnabled": false, + "adminEventsDetailsEnabled": false, + "components": { + "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy": [ + { + "id": "20f304be-9abc-4fa2-801e-c02440148d1b", + "name": "Trusted Hosts", + "providerId": "trusted-hosts", + "subType": "anonymous", + "subComponents": {}, + "config": { + "host-sending-registration-request-must-match": ["true"], + "client-uris-must-match": ["true"] + } + }, + { + "id": "dd0ae9d2-7af3-4d38-b8e7-d9c5825d3b1f", + "name": "Full Scope Disabled", + "providerId": "scope", + "subType": "anonymous", + "subComponents": {}, + "config": {} + }, + { + "id": "b3099bb7-0064-4315-85d9-cdbcc0bfef71", + "name": "Consent Required", + "providerId": "consent-required", + "subType": "anonymous", + "subComponents": {}, + "config": {} + }, + { + "id": "7f35ed4a-2140-478b-b2f8-46585315b71f", + "name": "Allowed Protocol Mapper Types", + "providerId": "allowed-protocol-mappers", + "subType": "anonymous", + "subComponents": {}, + "config": { + "allowed-protocol-mapper-types": [ + "saml-user-attribute-mapper", + "oidc-usermodel-property-mapper", + "saml-role-list-mapper", + "saml-user-property-mapper", + "oidc-address-mapper", + "oidc-full-name-mapper", + "oidc-sha256-pairwise-sub-mapper", + "oidc-usermodel-attribute-mapper" + ], + "consent-required-for-all-mappers": ["true"] + } + }, + { + "id": "30ac8e1b-b8e4-4877-aeab-42af7c2af5ff", + "name": "Allowed Client Templates", + "providerId": "allowed-client-templates", + "subType": "anonymous", + "subComponents": {}, + "config": {} + }, + { + "id": "db5b54f2-258b-40f9-92f9-ef83a887d1fa", + "name": "Allowed Protocol Mapper Types", + "providerId": "allowed-protocol-mappers", + "subType": "authenticated", + "subComponents": {}, + "config": { + "allowed-protocol-mapper-types": [ + "saml-user-attribute-mapper", + "oidc-usermodel-attribute-mapper", + "oidc-usermodel-property-mapper", + "saml-role-list-mapper", + "oidc-address-mapper", + "saml-user-property-mapper", + "oidc-full-name-mapper", + "oidc-sha256-pairwise-sub-mapper" + ], + "consent-required-for-all-mappers": ["true"] + } + }, + { + "id": "cd68d51f-9c85-4560-b1d6-9379bf3fce54", + "name": "Allowed Client Templates", + "providerId": "allowed-client-templates", + "subType": "authenticated", + "subComponents": {}, + "config": {} + }, + { + "id": "cd3bfc37-cc55-40dc-8d83-98b76ad5a521", + "name": "Max Clients Limit", + "providerId": "max-clients", + "subType": "anonymous", + "subComponents": {}, + "config": { + "max-clients": ["200"] + } + } + ], + "org.keycloak.keys.KeyProvider": [ + { + "id": "14b13815-a8b1-412c-a98d-0da235e8c8f9", + "name": "rsa-generated", + "providerId": "rsa-generated", + "subComponents": {}, + "config": { + "priority": ["100"] + } + }, + { + "id": "306d8c4c-9ad1-444e-af1a-d6c67dffc5b7", + "name": "hmac-generated", + "providerId": "hmac-generated", + "subComponents": {}, + "config": { + "priority": ["100"] + } + }, + { + "id": "bff7cf8c-001f-4cfb-8d47-9a8bd5bc48d3", + "name": "aes-generated", + "providerId": "aes-generated", + "subComponents": {}, + "config": { + "priority": ["100"] + } + } + ] + }, + "internationalizationEnabled": true, + "supportedLocales": [ + "de", + "no", + "ru", + "sv", + "pt-BR", + "lt", + "en", + "it", + "fr", + "zh-CN", + "es", + "ja", + "ca", + "nl" + ], + "defaultLocale": "en", + "authenticationFlows": [ + { + "id": "ac4ffcd4-6547-4e1c-90ac-aa56304011fb", + "alias": "Handle Existing Account", + "description": "Handle what to do if there is existing account with same email/username like authenticated identity provider", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "idp-confirm-link", + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "idp-email-verification", + "requirement": "ALTERNATIVE", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "requirement": "ALTERNATIVE", + "priority": 30, + "flowAlias": "Verify Existing Account by Re-authentication", + "userSetupAllowed": false, + "autheticatorFlow": true + } + ] + }, + { + "id": "affb11d0-0542-4824-a433-a41e90295ec1", + "alias": "Verify Existing Account by Re-authentication", + "description": "Reauthentication of existing account", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "idp-username-password-form", + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "auth-otp-form", + "requirement": "OPTIONAL", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + }, + { + "id": "19c7907b-c38a-4cbf-b106-f42ae613fce7", + "alias": "browser", + "description": "browser based authentication", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "auth-cookie", + "requirement": "ALTERNATIVE", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "auth-spnego", + "requirement": "DISABLED", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "identity-provider-redirector", + "requirement": "ALTERNATIVE", + "priority": 25, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "requirement": "ALTERNATIVE", + "priority": 30, + "flowAlias": "forms", + "userSetupAllowed": false, + "autheticatorFlow": true + } + ] + }, + { + "id": "5d678091-c1f9-4100-866f-fe35b032ae9d", + "alias": "clients", + "description": "Base authentication for clients", + "providerId": "client-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "client-secret", + "requirement": "ALTERNATIVE", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "client-jwt", + "requirement": "ALTERNATIVE", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + }, + { + "id": "d41512a5-3b62-477c-9590-badbe9f8044d", + "alias": "direct grant", + "description": "OpenID Connect Resource Owner Grant", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "direct-grant-validate-username", + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "direct-grant-validate-password", + "requirement": "REQUIRED", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "direct-grant-validate-otp", + "requirement": "OPTIONAL", + "priority": 30, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + }, + { + "id": "34c91e7e-dc6c-495a-889f-f033c9311911", + "alias": "docker auth", + "description": "Used by Docker clients to authenticate against the IDP", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "docker-http-basic-authenticator", + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + }, + { + "id": "d28bb33e-87a2-4712-a62c-01015ddfdf57", + "alias": "first broker login", + "description": "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticatorConfig": "review profile config", + "authenticator": "idp-review-profile", + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticatorConfig": "create unique user config", + "authenticator": "idp-create-user-if-unique", + "requirement": "ALTERNATIVE", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "requirement": "ALTERNATIVE", + "priority": 30, + "flowAlias": "Handle Existing Account", + "userSetupAllowed": false, + "autheticatorFlow": true + } + ] + }, + { + "id": "e65923ea-0c5b-43e3-9ebb-648391445207", + "alias": "forms", + "description": "Username, password, otp and other auth forms.", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "auth-username-password-form", + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "auth-otp-form", + "requirement": "OPTIONAL", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + }, + { + "id": "2d8d3a79-2e44-4d52-9aa2-919a400e0ab0", + "alias": "registration", + "description": "registration flow", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "registration-page-form", + "requirement": "REQUIRED", + "priority": 10, + "flowAlias": "registration form", + "userSetupAllowed": false, + "autheticatorFlow": true + } + ] + }, + { + "id": "5043cb5e-d76e-4a57-a0db-98366acb6bf7", + "alias": "registration form", + "description": "registration form", + "providerId": "form-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "registration-user-creation", + "requirement": "REQUIRED", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "registration-profile-action", + "requirement": "REQUIRED", + "priority": 40, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "registration-password-action", + "requirement": "REQUIRED", + "priority": 50, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "registration-recaptcha-action", + "requirement": "DISABLED", + "priority": 60, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + }, + { + "id": "79f99e59-6a78-4262-a86a-231e0c69d4bd", + "alias": "reset credentials", + "description": "Reset credentials for a user if they forgot their password or something", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "reset-credentials-choose-user", + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "reset-credential-email", + "requirement": "REQUIRED", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "reset-password", + "requirement": "REQUIRED", + "priority": 30, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "reset-otp", + "requirement": "OPTIONAL", + "priority": 40, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + }, + { + "id": "62e8ccd7-e995-4226-bee4-4ef9f1d6edc1", + "alias": "saml ecp", + "description": "SAML ECP Profile Authentication Flow", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "http-basic-authenticator", + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + } + ], + "authenticatorConfig": [ + { + "id": "d1eae692-c7d2-4d52-ac4d-7b1231ce0a22", + "alias": "create unique user config", + "config": { + "require.password.update.after.registration": "false" + } + }, + { + "id": "c6f89a26-2c86-4b6b-aee9-a483370fa20a", + "alias": "review profile config", + "config": { + "update.profile.on.first.login": "missing" + } + } + ], + "requiredActions": [ + { + "alias": "CONFIGURE_TOTP", + "name": "Configure OTP", + "providerId": "CONFIGURE_TOTP", + "enabled": true, + "defaultAction": false, + "config": {} + }, + { + "alias": "UPDATE_PASSWORD", + "name": "Update Password", + "providerId": "UPDATE_PASSWORD", + "enabled": true, + "defaultAction": false, + "config": {} + }, + { + "alias": "UPDATE_PROFILE", + "name": "Update Profile", + "providerId": "UPDATE_PROFILE", + "enabled": true, + "defaultAction": false, + "config": {} + }, + { + "alias": "VERIFY_EMAIL", + "name": "Verify Email", + "providerId": "VERIFY_EMAIL", + "enabled": true, + "defaultAction": false, + "config": {} + }, + { + "alias": "terms_and_conditions", + "name": "Terms and Conditions", + "providerId": "terms_and_conditions", + "enabled": false, + "defaultAction": false, + "config": {} + } + ], + "browserFlow": "browser", + "registrationFlow": "registration", + "directGrantFlow": "direct grant", + "resetCredentialsFlow": "reset credentials", + "clientAuthenticationFlow": "clients", + "dockerAuthenticationFlow": "docker auth", + "attributes": { + "_browser_header.xXSSProtection": "1; mode=block", + "_browser_header.xFrameOptions": "SAMEORIGIN", + "permanentLockout": "false", + "quickLoginCheckMilliSeconds": "1000", + "_browser_header.xRobotsTag": "none", + "maxFailureWaitSeconds": "900", + "minimumQuickLoginWaitSeconds": "60", + "failureFactor": "30", + "actionTokenGeneratedByUserLifespan": "300", + "maxDeltaTimeSeconds": "43200", + "_browser_header.xContentTypeOptions": "nosniff", + "actionTokenGeneratedByAdminLifespan": "43200", + "bruteForceProtected": "false", + "_browser_header.contentSecurityPolicy": "frame-src 'self'; frame-ancestors 'self'; object-src 'none';", + "waitIncrementSeconds": "60" + }, + "users": [ + { + "id": "9c978d30-c9ad-4dcb-b61c-840fe56f72f2", + "createdTimestamp": 1533234734911, + "username": "admin", + "enabled": true, + "totp": false, + "emailVerified": true, + "firstName": "admin", + "lastName": "admin", + "email": "admin.adf@alfresco.com", + "credentials": [ + { + "type": "password", + "value": "admin" + } + ], + "disableableCredentialTypes": ["password"], + "requiredActions": [], + "realmRoles": ["uma_authorization", "user", "offline_access"], + "clientRoles": { + "realm-management": [ + "view-clients", + "manage-users", + "manage-clients", + "view-users", + "manage-realm", + "view-realm" + ], + "account": ["manage-account", "view-profile"] + }, + "groups": ["/admin"] + } + ], + "keycloakVersion": "4.8.3.Final" +} diff --git a/docker/nginx.conf b/docker/nginx.conf new file mode 100644 index 0000000000..808f13ad05 --- /dev/null +++ b/docker/nginx.conf @@ -0,0 +1,29 @@ +server { + listen *:80; + + set $allowOriginSite *; + proxy_pass_request_headers on; + proxy_pass_header Set-Cookie; + + access_log off; + + proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; + proxy_redirect off; + proxy_buffering off; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_pass_header Set-Cookie; + + location / { + proxy_pass http://content-app; + } + + location /alfresco/ { + proxy_pass http://alfresco:8080; + } + + location /share/ { + proxy_pass http://share:8080; + } +} diff --git a/docs/getting-started/docker.md b/docs/getting-started/docker.md index 350e2c4b99..67c932663b 100644 --- a/docs/getting-started/docker.md +++ b/docs/getting-started/docker.md @@ -28,15 +28,5 @@ Use the following command to stop all the containers: npm run stop:docker ``` -## Preview Mode - -**Tip:** With this mode, you do not need building application from source code or installing dependencies. - -To run the latest published container go to the `docker-compose` folder and start docker compose from there: - -```sh -cd docker-compose -docker-compose up -``` - -The application is available at the `http://localhost:3000` address. +You can also develop the application and run in default port (4200), +it is going to use the same docker containers automatically. diff --git a/package.json b/package.json index 2312a8ced6..b0a3b1103e 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,8 @@ "wd:update": "webdriver-manager update --gecko=false", "e2e": "npm run wd:update && protractor --baseUrl=http://localhost:4000", "e2e.local": "npm run wd:update && protractor --baseUrl=http://localhost:4200", - "start:docker": "docker-compose up -d --build && wait-on http://localhost:8080 && wait-on http://localhost:4000", + "wait:app": "wait-on http://localhost:8080 && wait-on http://localhost:4000", + "start:docker": "docker-compose up -d --build && npm run wait:app", "stop:docker": "docker-compose stop", "e2e:docker": "npm run start:docker && npm run e2e && npm run stop:docker", "spellcheck": "cspell 'src/**/*.ts' 'e2e/**/*.ts' 'projects/**/*.ts'", @@ -25,7 +26,7 @@ "build.tomcat": "npm run build -- --base-href ./ && jar -cvf docker/tomcat/artifacts/content-app.war -C dist/app/ .", "build.tomcat.e2e": "./build-tomcat-e2e.sh", "e2e.tomcat": "npm run wd:update && protractor --baseUrl=http://localhost:4000/content-app/", - "docker.tomcat.start": "cd docker/tomcat && docker-compose up -d --build && wait-on http://localhost:8080 && wait-on http://localhost:4000", + "docker.tomcat.start": "cd docker/tomcat && docker-compose up -d --build && npm run wait:app", "docker.tomcat.stop": "cd docker/tomcat && docker-compose stop", "docker.tomcat.e2e": "npm run docker.tomcat.start && npm run e2e.tomcat", "lint:staged": "lint-staged" diff --git a/start-sso.sh b/start-sso.sh new file mode 100755 index 0000000000..87efca10d3 --- /dev/null +++ b/start-sso.sh @@ -0,0 +1,19 @@ +export HOST_IP=$(ifconfig | grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}" | grep -v 127.0.0.1 | awk '{ print $2 }' | cut -f2 -d: | head -n1) +export AUTH_SERVER_URL="http://${HOST_IP}:8085/auth" +export APP_URL="http://${HOST_IP}:4000" + +export APP_CONFIG_AUTH_TYPE="OAUTH" +export APP_CONFIG_OAUTH2_HOST="${AUTH_SERVER_URL}/realms/alfresco" +export APP_CONFIG_OAUTH2_CLIENTID="alfresco" +export APP_CONFIG_OAUTH2_REDIRECT_SILENT_IFRAME_URI="${APP_URL}/assets/silent-refresh.html" +export APP_CONFIG_OAUTH2_REDIRECT_LOGIN="/" +export APP_CONFIG_OAUTH2_REDIRECT_LOGOUT="/logout" + +docker-compose -f docker-compose-keycloak.yml up -d --build + +echo "Waiting for the app..." +npm run wait:app + +echo "Identity Service: ${AUTH_SERVER_URL}" +echo "Realm: ${APP_CONFIG_OAUTH2_HOST}" +echo "Content Workspace: ${APP_URL}" From ff19e57185851301251276e7e708c9feb2af094c Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Mon, 4 Feb 2019 21:11:10 +0000 Subject: [PATCH 036/259] [ACA-2162] allow custom icons with navbar (#917) * allow custom icons with navbar * fix breaking change * update protractor settings --- package-lock.json | 18 ++++---- package.json | 6 +-- protractor.conf.js | 43 +++++++++++-------- .../components/sidenav/sidenav.component.html | 26 ++++++----- src/app/services/node-actions.service.ts | 3 +- 5 files changed, 54 insertions(+), 42 deletions(-) diff --git a/package-lock.json b/package-lock.json index b14fdd8a4c..3cb695c93d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,25 +5,25 @@ "requires": true, "dependencies": { "@alfresco/adf-content-services": { - "version": "3.0.0-0282bfa4686accfd24cbac61795891378c25fb64", - "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-3.0.0-0282bfa4686accfd24cbac61795891378c25fb64.tgz", - "integrity": "sha512-Nr401vcfIWxUBjOzJWCfSELbPBhTmljhMXHyDJrsI4rBFepftSwARzkRJeMvFw21Z4lzBICmx9ZUDIDV43A7Lw==", + "version": "3.0.0-3a5fe3fb92cdc7397cbfd3d0869833ea1f1fe8d5", + "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-3.0.0-3a5fe3fb92cdc7397cbfd3d0869833ea1f1fe8d5.tgz", + "integrity": "sha512-TVR6PQznEWtrSWqZHaceogd/E32Q1RsQUxcdjysLJvKWwJZ0of3Nkl7PuJkw4l9SLEah85l0O1lZn0la5HgqtQ==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/adf-core": { - "version": "3.0.0-0282bfa4686accfd24cbac61795891378c25fb64", - "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-3.0.0-0282bfa4686accfd24cbac61795891378c25fb64.tgz", - "integrity": "sha512-I/XI+n/+hOpYvWsP7B2oGXmvRLQMDNU6j+PclfPoMb4vMeT7HBtuGukz+K0hvERcHzEfj3N84rrlSTZZ9jDRuQ==", + "version": "3.0.0-3a5fe3fb92cdc7397cbfd3d0869833ea1f1fe8d5", + "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-3.0.0-3a5fe3fb92cdc7397cbfd3d0869833ea1f1fe8d5.tgz", + "integrity": "sha512-XlubGS/9XDsvc0LLmih6t6X/bKq3UI2OfX8O6mZzfTGzztfkqvgvD1T4E8zgVuZg6J0bE8dTyO7RsNZpyQJBdQ==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/adf-extensions": { - "version": "3.0.0-0282bfa4686accfd24cbac61795891378c25fb64", - "resolved": "https://registry.npmjs.org/@alfresco/adf-extensions/-/adf-extensions-3.0.0-0282bfa4686accfd24cbac61795891378c25fb64.tgz", - "integrity": "sha512-Ke/8qTyCWceQPNo5qQ8YCHsQ9Ocg6n4+aiOJumqYhFqdbsapbp6dXcDHULh6ZfawVHInKBGvEIv12j7gjZDL2Q==", + "version": "3.0.0-3a5fe3fb92cdc7397cbfd3d0869833ea1f1fe8d5", + "resolved": "https://registry.npmjs.org/@alfresco/adf-extensions/-/adf-extensions-3.0.0-3a5fe3fb92cdc7397cbfd3d0869833ea1f1fe8d5.tgz", + "integrity": "sha512-Zq+rBpDqc7BJ+rMKxniXMWYWUex6tUOhW1wdSvh9oP5dgyLlHRgsvoyIDeDei76u0cuVjbZziQzzJGlWKShmrA==", "requires": { "tslib": "^1.9.0" } diff --git a/package.json b/package.json index b0a3b1103e..8731635c79 100644 --- a/package.json +++ b/package.json @@ -33,9 +33,9 @@ }, "private": true, "dependencies": { - "@alfresco/adf-content-services": "3.0.0-0282bfa4686accfd24cbac61795891378c25fb64", - "@alfresco/adf-core": "3.0.0-0282bfa4686accfd24cbac61795891378c25fb64", - "@alfresco/adf-extensions": "3.0.0-0282bfa4686accfd24cbac61795891378c25fb64", + "@alfresco/adf-content-services": "3.0.0-3a5fe3fb92cdc7397cbfd3d0869833ea1f1fe8d5", + "@alfresco/adf-core": "3.0.0-3a5fe3fb92cdc7397cbfd3d0869833ea1f1fe8d5", + "@alfresco/adf-extensions": "3.0.0-3a5fe3fb92cdc7397cbfd3d0869833ea1f1fe8d5", "@alfresco/js-api": "3.0.0-d7850f421268e21861e2cd219441b7343efd27ba", "@angular/animations": "7.2.3", "@angular/cdk": "^7.3.0", diff --git a/protractor.conf.js b/protractor.conf.js index 581cfb261f..91c0e5d325 100755 --- a/protractor.conf.js +++ b/protractor.conf.js @@ -2,9 +2,7 @@ // https://github.com/angular/protractor/blob/master/lib/config.ts const path = require('path'); -const { - SpecReporter -} = require('jasmine-spec-reporter'); +const { SpecReporter } = require('jasmine-spec-reporter'); const jasmineReporters = require('jasmine-reporters'); const CDP = require('chrome-remote-interface'); @@ -63,7 +61,13 @@ exports.config = { default_directory: downloadFolder } }, - args: ['--incognito', '--headless', '--remote-debugging-port=9222', '--disable-gpu', '--no-sandbox'] + args: [ + '--incognito', + '--headless', + '--remote-debugging-port=9222', + '--disable-gpu', + '--no-sandbox' + ] } }, @@ -76,21 +80,23 @@ exports.config = { jasmineNodeOpts: { showColors: true, defaultTimeoutInterval: 60000, - print: function () {} + print: function() {} }, - plugins: [{ - package: 'protractor-screenshoter-plugin', - screenshotPath: `${projectRoot}/e2e-output/report`, - screenshotOnExpect: 'failure', - screenshotOnSpec: 'none', - withLogs: true, - writeReportFreq: 'end', - imageToAscii: 'none', - htmlOnExpect: 'none', - htmlOnSpec: 'none', - clearFoldersBeforeTest: true - }], + plugins: [ + { + package: 'protractor-screenshoter-plugin', + screenshotPath: `${projectRoot}/e2e-output/report`, + screenshotOnExpect: 'failure', + screenshotOnSpec: 'none', + withLogs: true, + writeReportFreq: 'end', + imageToAscii: 'none', + htmlOnExpect: 'none', + htmlOnSpec: 'none', + clearFoldersBeforeTest: true + } + ], onPrepare() { require('ts-node').register({ @@ -105,7 +111,8 @@ exports.config = { jasmine.getEnv().addReporter( new SpecReporter({ spec: { - displayStacktrace: true + displayStacktrace: true, + displayDuration: true } }) ); diff --git a/src/app/components/sidenav/sidenav.component.html b/src/app/components/sidenav/sidenav.component.html index e3792dc90e..04cd19d84c 100644 --- a/src/app/components/sidenav/sidenav.component.html +++ b/src/app/components/sidenav/sidenav.component.html @@ -25,7 +25,10 @@ [matRippleCentered]="true" [matRippleRadius]="20" > - {{ item.icon }} + - - {{ item.icon }} - + [value]="item.icon" + > - {{ child.icon }} + - {{ item.icon }} +
@@ -160,15 +165,14 @@ #childMenu="matMenuTrigger" [matMenuTriggerFor]="menu" > - - {{ item.icon }} - + [value]="item.icon" + >
diff --git a/src/app/services/node-actions.service.ts b/src/app/services/node-actions.service.ts index aa6e1f7fe2..85db1644d8 100644 --- a/src/app/services/node-actions.service.ts +++ b/src/app/services/node-actions.service.ts @@ -250,7 +250,8 @@ export class NodeActionsService { imageResolver: this.imageResolver.bind(this), isSelectionValid: this.canCopyMoveInsideIt.bind(this), breadcrumbTransform: this.customizeBreadcrumb.bind(this), - select: new Subject() + select: new Subject(), + excludeSiteContent: [] }; this.dialog.open(ContentNodeSelectorComponent, { From 21daa1e6595699882d75f682e13ef6069947436b Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Tue, 5 Feb 2019 10:14:32 +0000 Subject: [PATCH 037/259] pin typescript version, regenerate lock file --- package-lock.json | 9596 +++++++++++++-------------------------------- package.json | 2 +- 2 files changed, 2662 insertions(+), 6936 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3cb695c93d..6eb2aff3af 100644 --- a/package-lock.json +++ b/package-lock.json @@ -124,99 +124,12 @@ "uri-js": "^4.2.2" } }, - "autoprefixer": { - "version": "9.4.6", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.4.6.tgz", - "integrity": "sha512-Yp51mevbOEdxDUy5WjiKtpQaecqYq9OqZSL04rSoCiry7Tc5I9FEyo3bfxiTJc1DfHeKwSFCUYbBAiOQ2VGfiw==", - "dev": true, - "requires": { - "browserslist": "^4.4.1", - "caniuse-lite": "^1.0.30000929", - "normalize-range": "^0.1.2", - "num2fraction": "^1.2.2", - "postcss": "^7.0.13", - "postcss-value-parser": "^3.3.1" - } - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": 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" - } - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "loader-utils": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", - "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^2.0.0", - "json5": "^1.0.1" - } - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "parse5": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", + "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", "dev": true }, - "postcss": { - "version": "7.0.14", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.14.tgz", - "integrity": "sha512-NsbD6XUUMZvBxtQAJuWDJeeC4QFsmWsfozWxCJPWf3M55K9iu2iMDaKqyoOdTJ1R4usBXuxlVFAIo8rZPQD4Bg==", - "dev": true, - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, "rxjs": { "version": "6.3.3", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", @@ -225,37 +138,6 @@ "requires": { "tslib": "^1.9.0" } - }, - "semver": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", - "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-support": { - "version": "0.5.10", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.10.tgz", - "integrity": "sha512-YfQ3tQFTK/yzlGJuX8pTwa4tifQj4QS2Mj7UegOu8jAz59MqIiMGPXxQhVQiIMNzayuUSF/jEuVnfFF5JqybmQ==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } } } }, @@ -279,12 +161,6 @@ "requires": { "tslib": "^1.9.0" } - }, - "semver": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", - "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", - "dev": true } } }, @@ -300,43 +176,17 @@ "webpack-sources": "1.3.0" }, "dependencies": { - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "loader-utils": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", - "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^2.0.0", - "json5": "^1.0.1" - } - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, "source-map": { "version": "0.5.6", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=", "dev": true + }, + "typescript": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.2.4.tgz", + "integrity": "sha512-0RNDbSdEokBeEAkgNbxJ+BLwSManFy9TeXz8uW+48j/xhEXv1ePME60olyzw2XzUqUBNAYFeJadIqAgNqIACwg==", + "dev": true } } }, @@ -387,2463 +237,731 @@ "uri-js": "^4.2.2" } }, + "rxjs": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", + "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + } + } + }, + "@angular-devkit/schematics": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-7.3.0.tgz", + "integrity": "sha512-glOduymftH0LmJhITWgWUJK8QCDUltgTZ943/OyArIvLXTLL/8zCb+G6xL+3k33EQjwJicgQ3WIjonJmeTK/Ww==", + "dev": true, + "requires": { + "@angular-devkit/core": "7.3.0", + "rxjs": "6.3.3" + }, + "dependencies": { + "rxjs": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", + "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + } + } + }, + "@angular/animations": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-7.2.3.tgz", + "integrity": "sha512-5WoiDnVS2OhGgJ1oepFNF2UcfR4sJj97KRnTmLWQ0S4N4WpXX83CoOQVXvXwfotyb8uNtl4zRi2NuvN/MIuFuA==", + "requires": { + "tslib": "^1.9.0" + } + }, + "@angular/cdk": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-7.3.1.tgz", + "integrity": "sha512-m6hy+HPLDgVM+Y2C3UWvIG06euIV8oG5QxrCitZui8JZ/dj/0V5bxATKgWN62haYnYR4en4z1bfH0kOvQj+LEA==", + "requires": { + "parse5": "^5.0.0", + "tslib": "^1.7.1" + } + }, + "@angular/cli": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-7.3.0.tgz", + "integrity": "sha512-6+NoHsW1MYG7GBHUg71zaWIFeIRps/SVksCmRFCpW0RXqErCQmzf0GZuDTZZ2Yo4RzU01150sVp1R8wEvEZfZQ==", + "dev": true, + "requires": { + "@angular-devkit/architect": "0.13.0", + "@angular-devkit/core": "7.3.0", + "@angular-devkit/schematics": "7.3.0", + "@schematics/angular": "7.3.0", + "@schematics/update": "0.13.0", + "@yarnpkg/lockfile": "1.1.0", + "ini": "1.3.5", + "inquirer": "6.2.1", + "npm-package-arg": "6.1.0", + "opn": "5.4.0", + "pacote": "9.4.0", + "semver": "5.6.0", + "symbol-observable": "1.2.0" + } + }, + "@angular/common": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-7.2.3.tgz", + "integrity": "sha512-VZOTZdvkitaKEhkxL6daHxPcKqAFwNJm0U4NFB4LRP9KspsFTE60QFVB63o129PTIH9iOQ2D3HRKSRl4o78ZKg==", + "requires": { + "tslib": "^1.9.0" + } + }, + "@angular/compiler": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-7.2.3.tgz", + "integrity": "sha512-UM6n4MyZkR5+VVjlwhLH8IfqdWBkdFcF5at4ckJXOJ/gkIUq97irbis9pGj1b0TO7MAl8uhF4b68xe5lk8b49g==", + "requires": { + "tslib": "^1.9.0" + } + }, + "@angular/compiler-cli": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-7.2.3.tgz", + "integrity": "sha512-31hcfTrU2GW66cvvaS629dNVPfiUrUWPncI28optvmKHBaH0mFqkdYNgabuslsXZV5AeidKMUJvR7GITjtvkQA==", + "dev": true, + "requires": { + "canonical-path": "1.0.0", + "chokidar": "^1.4.2", + "convert-source-map": "^1.5.1", + "dependency-graph": "^0.7.2", + "magic-string": "^0.25.0", + "minimist": "^1.2.0", + "reflect-metadata": "^0.1.2", + "shelljs": "^0.8.1", + "source-map": "^0.6.1", + "tslib": "^1.9.0", + "yargs": "9.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", + "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", "dev": true, "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" + "micromatch": "^2.1.5", + "normalize-path": "^2.0.0" } }, "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true, + "requires": { + "arr-flatten": "^1.0.1" + } }, "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", "dev": true }, "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", "dev": 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" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" } }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, "chokidar": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", - "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", + "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", "dev": true, "requires": { - "anymatch": "^2.0.0", + "anymatch": "^1.3.0", "async-each": "^1.0.0", - "braces": "^2.3.0", - "fsevents": "^1.2.2", - "glob-parent": "^3.1.0", + "fsevents": "^1.0.0", + "glob-parent": "^2.0.0", "inherits": "^2.0.1", "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "lodash.debounce": "^4.0.8", - "normalize-path": "^2.1.1", + "is-glob": "^2.0.0", "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0", - "upath": "^1.0.5" + "readdirp": "^2.0.0" } }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", "dev": true, "requires": { - "ms": "2.0.0" + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "dev": true, + "requires": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" } }, "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", "dev": true, "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } + "is-posix-bracket": "^0.1.0" } }, "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", "dev": true, "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } + "is-extglob": "^1.0.0" } }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", "dev": true, "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } + "is-glob": "^2.0.0" } }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", "dev": true, "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } + "is-extglob": "^1.0.0" } }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "kind-of": "^6.0.0" + "is-buffer": "^1.1.5" } }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", "dev": true, "requires": { - "kind-of": "^6.0.0" + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" } }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "mem": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", + "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", "dev": true, "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "mimic-fn": "^1.0.0" } }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true, + "requires": { + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" + } }, - "is-glob": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", - "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", + "os-locale": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", + "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", "dev": true, "requires": { - "is-extglob": "^2.1.1" + "execa": "^0.7.0", + "lcid": "^1.0.0", + "mem": "^1.1.0" } }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", "dev": true, "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } + "pify": "^2.0.0" } }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" } }, - "rxjs": { - "version": "6.3.3", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", - "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", "dev": true, "requires": { - "tslib": "^1.9.0" + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" } }, "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - } - } - }, - "@angular-devkit/schematics": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-7.3.0.tgz", - "integrity": "sha512-glOduymftH0LmJhITWgWUJK8QCDUltgTZ943/OyArIvLXTLL/8zCb+G6xL+3k33EQjwJicgQ3WIjonJmeTK/Ww==", - "dev": true, - "requires": { - "@angular-devkit/core": "7.3.0", - "rxjs": "6.3.3" - }, - "dependencies": { - "@angular-devkit/core": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.3.0.tgz", - "integrity": "sha512-b0qtAUpgqLpWY8W6vWRv1aj6bXkZCP1rvywl8i8TbGMY67CWRcy5J3fNAMmjiZS+LJixFlIXYf4iOydglyJMfg==", - "dev": true, - "requires": { - "ajv": "6.7.0", - "chokidar": "2.0.4", - "fast-json-stable-stringify": "2.0.0", - "rxjs": "6.3.3", - "source-map": "0.7.3" - } }, - "ajv": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.7.0.tgz", - "integrity": "sha512-RZXPviBTtfmtka9n9sy1N5M5b82CbxWIR6HIis4s3WQTXDJamc/0gpCWNGz6EWdWp4DOfjzJfhz/AS9zVPjjWg==", + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" } }, - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" + "ansi-regex": "^3.0.0" } }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": 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" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "dev": true }, - "chokidar": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", - "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", + "yargs": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-9.0.1.tgz", + "integrity": "sha1-UqzCP+7Kw0BCB47njAwAf1CF20w=", "dev": true, "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.0", - "braces": "^2.3.0", - "fsevents": "^1.2.2", - "glob-parent": "^3.1.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "lodash.debounce": "^4.0.8", - "normalize-path": "^2.1.1", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0", - "upath": "^1.0.5" + "camelcase": "^4.1.0", + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "os-locale": "^2.0.0", + "read-pkg-up": "^2.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^7.0.0" } }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "yargs-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", + "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", "dev": true, "requires": { - "ms": "2.0.0" + "camelcase": "^4.1.0" } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", - "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "rxjs": { - "version": "6.3.3", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", - "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true } } }, - "@angular/animations": { + "@angular/core": { "version": "7.2.3", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-7.2.3.tgz", - "integrity": "sha512-5WoiDnVS2OhGgJ1oepFNF2UcfR4sJj97KRnTmLWQ0S4N4WpXX83CoOQVXvXwfotyb8uNtl4zRi2NuvN/MIuFuA==", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-7.2.3.tgz", + "integrity": "sha512-6Ql+sJJnrsxh8O0/IgIP1GgT4eLOHk+dlBs7zBbjstmLuhaQdY+awO9WKoQow+TiD1Go7FW1J3vZ2PTWXKxqjQ==", "requires": { "tslib": "^1.9.0" } }, - "@angular/cdk": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-7.3.0.tgz", - "integrity": "sha512-8fH3wQ4WpOxgU06kxKf2MKelYBAq9ha6QrkXjtyb0ns6mJgsooSLX773G0dP9sAQn7rrqdsQh6SNj9zgvyRBDw==", + "@angular/flex-layout": { + "version": "7.0.0-beta.23", + "resolved": "https://registry.npmjs.org/@angular/flex-layout/-/flex-layout-7.0.0-beta.23.tgz", + "integrity": "sha512-jH2i3i/M7SbK6scVlj2urVL5OhzwavbQ7KwvUjyc/UwccKnnzuOuWEGCINLja/aoaUO3I35LluCLv6a6VN0olA==", + "requires": { + "tslib": "^1.7.1" + } + }, + "@angular/forms": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-7.2.3.tgz", + "integrity": "sha512-mZpyonfSmRwSvM6efvwFwkLJkK6wHQrm7X4OhVVu3s9i7BI253eLDY7WIRXFvoxJ/5jWIIarVnd/9UA7GINZGw==", + "requires": { + "tslib": "^1.9.0" + } + }, + "@angular/http": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@angular/http/-/http-7.2.3.tgz", + "integrity": "sha512-wzvBKbO/TcSR3U8AQbsGftH8x1OdAgVGHlfXQPmZL1KjIDHrM1VpnkSvgqIt8coG+4OPfWcNklUCrTdEGwqMqw==", + "requires": { + "tslib": "^1.9.0" + } + }, + "@angular/language-service": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-7.2.3.tgz", + "integrity": "sha512-9FBVYbKaNx4Ap+Suz/2ZFBPca1voinZMOCN8LjXRYnfS2MHLQASQlTlK4qeZcomyRfy0FxWmO9R02S7YJ06cnw==", + "dev": true + }, + "@angular/material": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@angular/material/-/material-7.3.1.tgz", + "integrity": "sha512-txq2y/JSB+05l8a/OfnByw7AEKSeAWAJ49jzCoeb3804sCeVEbvuWZfpmKBX8vCVTZh005Ypuk55R4NP5AIgaw==", + "requires": { + "tslib": "^1.7.1" + } + }, + "@angular/material-moment-adapter": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@angular/material-moment-adapter/-/material-moment-adapter-7.3.1.tgz", + "integrity": "sha512-LQEJcK4OKsi8go4C58QCdpMvX6uzi2b8Jcxgc3i1TzDfnz8ejoL4hDTerIaZea3aYqdSVoTLsQmrprd9FOD+eg==", "requires": { - "parse5": "^5.0.0", "tslib": "^1.7.1" + } + }, + "@angular/platform-browser": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-7.2.3.tgz", + "integrity": "sha512-DH0Y2lgEgcrP1I/DUQB/krL7Ob7yL685fu4sRapW17SndTQa2pqSFMBVf+mN3FupTXp7nJHSvlIktzedIk04+g==", + "requires": { + "tslib": "^1.9.0" + } + }, + "@angular/platform-browser-dynamic": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-7.2.3.tgz", + "integrity": "sha512-M8Kiz5FUhnFybJuk/mgOhBjVbRgKDC4bGWKWH9Z9SXBR2dS/FL3QOJsLIthQcWlHOzSoJdEoPBRhn0R4pyLBSw==", + "requires": { + "tslib": "^1.9.0" + } + }, + "@angular/router": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-7.2.3.tgz", + "integrity": "sha512-SH7H2I9WTj1puei4m4g5n0/Cp28HS14q4r8lOgW0gLWuT6Ls7MqH/nDjOMiW924iRR6zjQQs7G+WbhL1jmZc2A==", + "requires": { + "tslib": "^1.9.0" + } + }, + "@babel/runtime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.0.0.tgz", + "integrity": "sha512-7hGhzlcmg01CvH1EHdSPVXYX1aJ8KCEyz6I9xYIi/asDtzBPMyMhVibhM/K6g/5qnKBwjZtp10bNZIEFTRW1MA==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.12.0" }, "dependencies": { - "parse5": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", - "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==", - "optional": true + "regenerator-runtime": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz", + "integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==", + "dev": true } } }, - "@angular/cli": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-7.3.0.tgz", - "integrity": "sha512-6+NoHsW1MYG7GBHUg71zaWIFeIRps/SVksCmRFCpW0RXqErCQmzf0GZuDTZZ2Yo4RzU01150sVp1R8wEvEZfZQ==", + "@babel/runtime-corejs2": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.3.1.tgz", + "integrity": "sha512-YpO13776h3e6Wy8dl2J8T9Qwlvopr+b4trCEhHE+yek6yIqV8sx6g3KozdHMbXeBpjosbPi+Ii5Z7X9oXFHUKA==", "dev": true, "requires": { - "@angular-devkit/architect": "0.13.0", - "@angular-devkit/core": "7.3.0", - "@angular-devkit/schematics": "7.3.0", - "@schematics/angular": "7.3.0", - "@schematics/update": "0.13.0", - "@yarnpkg/lockfile": "1.1.0", - "ini": "1.3.5", - "inquirer": "6.2.1", - "npm-package-arg": "6.1.0", - "opn": "5.4.0", - "pacote": "9.4.0", - "semver": "5.6.0", - "symbol-observable": "1.2.0" + "core-js": "^2.5.7", + "regenerator-runtime": "^0.12.0" }, "dependencies": { - "@angular-devkit/architect": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.13.0.tgz", - "integrity": "sha512-oDBrWlfKh/0t2ag4T8gz9xzPMItxfctinlsHxhw7dPQ+etq1mIcWgQkiKiDrz4l46YiGipBRlC55j+6f37omAA==", + "regenerator-runtime": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz", + "integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==", + "dev": true + } + } + }, + "@iamstarkov/listr-update-renderer": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@iamstarkov/listr-update-renderer/-/listr-update-renderer-0.4.1.tgz", + "integrity": "sha512-IJyxQWsYDEkf8C8QthBn5N8tIUR9V9je6j3sMIpAkonaadjbvxmRC6RAhpa3RKxndhNnU2M6iNbtJwd7usQYIA==", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "cli-truncate": "^0.2.1", + "elegant-spinner": "^1.0.1", + "figures": "^1.7.0", + "indent-string": "^3.0.0", + "log-symbols": "^1.0.2", + "log-update": "^2.3.0", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { - "@angular-devkit/core": "7.3.0", - "rxjs": "6.3.3" - } - }, - "@angular-devkit/core": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.3.0.tgz", - "integrity": "sha512-b0qtAUpgqLpWY8W6vWRv1aj6bXkZCP1rvywl8i8TbGMY67CWRcy5J3fNAMmjiZS+LJixFlIXYf4iOydglyJMfg==", - "dev": true, - "requires": { - "ajv": "6.7.0", - "chokidar": "2.0.4", - "fast-json-stable-stringify": "2.0.0", - "rxjs": "6.3.3", - "source-map": "0.7.3" - } - }, - "ajv": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.7.0.tgz", - "integrity": "sha512-RZXPviBTtfmtka9n9sy1N5M5b82CbxWIR6HIis4s3WQTXDJamc/0gpCWNGz6EWdWp4DOfjzJfhz/AS9zVPjjWg==", - "dev": true, - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": 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" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chokidar": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", - "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.0", - "braces": "^2.3.0", - "fsevents": "^1.2.2", - "glob-parent": "^3.1.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "lodash.debounce": "^4.0.8", - "normalize-path": "^2.1.1", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0", - "upath": "^1.0.5" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", - "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "opn": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-5.4.0.tgz", - "integrity": "sha512-YF9MNdVy/0qvJvDtunAOzFw9iasOQHpVthTCvGzxt61Il64AYSGdK+rYwld7NAfk9qJ7dt+hymBNSc9LNYS+Sw==", - "dev": true, - "requires": { - "is-wsl": "^1.1.0" - } - }, - "rxjs": { - "version": "6.3.3", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", - "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "semver": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", - "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", - "dev": true - }, - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true - } - } - }, - "@angular/common": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-7.2.3.tgz", - "integrity": "sha512-VZOTZdvkitaKEhkxL6daHxPcKqAFwNJm0U4NFB4LRP9KspsFTE60QFVB63o129PTIH9iOQ2D3HRKSRl4o78ZKg==", - "requires": { - "tslib": "^1.9.0" - } - }, - "@angular/compiler": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-7.2.3.tgz", - "integrity": "sha512-UM6n4MyZkR5+VVjlwhLH8IfqdWBkdFcF5at4ckJXOJ/gkIUq97irbis9pGj1b0TO7MAl8uhF4b68xe5lk8b49g==", - "requires": { - "tslib": "^1.9.0" - } - }, - "@angular/compiler-cli": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-7.2.3.tgz", - "integrity": "sha512-31hcfTrU2GW66cvvaS629dNVPfiUrUWPncI28optvmKHBaH0mFqkdYNgabuslsXZV5AeidKMUJvR7GITjtvkQA==", - "dev": true, - "requires": { - "canonical-path": "1.0.0", - "chokidar": "^1.4.2", - "convert-source-map": "^1.5.1", - "dependency-graph": "^0.7.2", - "magic-string": "^0.25.0", - "minimist": "^1.2.0", - "reflect-metadata": "^0.1.2", - "shelljs": "^0.8.1", - "source-map": "^0.6.1", - "tslib": "^1.9.0", - "yargs": "9.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "load-json-file": { - "version": "2.0.0", - "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "strip-bom": "^3.0.0" - } - }, - "minimist": { - "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "os-locale": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", - "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", - "dev": true, - "requires": { - "execa": "^0.7.0", - "lcid": "^1.0.0", - "mem": "^1.1.0" - } - }, - "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", - "dev": true, - "requires": { - "pify": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", - "dev": true, - "requires": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" - } - }, - "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", - "dev": true - }, - "yargs": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-9.0.1.tgz", - "integrity": "sha1-UqzCP+7Kw0BCB47njAwAf1CF20w=", - "dev": true, - "requires": { - "camelcase": "^4.1.0", - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "os-locale": "^2.0.0", - "read-pkg-up": "^2.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^7.0.0" - } - }, - "yargs-parser": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", - "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", - "dev": true, - "requires": { - "camelcase": "^4.1.0" - } - } - } - }, - "@angular/core": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-7.2.3.tgz", - "integrity": "sha512-6Ql+sJJnrsxh8O0/IgIP1GgT4eLOHk+dlBs7zBbjstmLuhaQdY+awO9WKoQow+TiD1Go7FW1J3vZ2PTWXKxqjQ==", - "requires": { - "tslib": "^1.9.0" - } - }, - "@angular/flex-layout": { - "version": "7.0.0-beta.23", - "resolved": "https://registry.npmjs.org/@angular/flex-layout/-/flex-layout-7.0.0-beta.23.tgz", - "integrity": "sha512-jH2i3i/M7SbK6scVlj2urVL5OhzwavbQ7KwvUjyc/UwccKnnzuOuWEGCINLja/aoaUO3I35LluCLv6a6VN0olA==", - "requires": { - "tslib": "^1.7.1" - } - }, - "@angular/forms": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-7.2.3.tgz", - "integrity": "sha512-mZpyonfSmRwSvM6efvwFwkLJkK6wHQrm7X4OhVVu3s9i7BI253eLDY7WIRXFvoxJ/5jWIIarVnd/9UA7GINZGw==", - "requires": { - "tslib": "^1.9.0" - } - }, - "@angular/http": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/@angular/http/-/http-7.2.3.tgz", - "integrity": "sha512-wzvBKbO/TcSR3U8AQbsGftH8x1OdAgVGHlfXQPmZL1KjIDHrM1VpnkSvgqIt8coG+4OPfWcNklUCrTdEGwqMqw==", - "requires": { - "tslib": "^1.9.0" - } - }, - "@angular/language-service": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-7.2.3.tgz", - "integrity": "sha512-9FBVYbKaNx4Ap+Suz/2ZFBPca1voinZMOCN8LjXRYnfS2MHLQASQlTlK4qeZcomyRfy0FxWmO9R02S7YJ06cnw==", - "dev": true - }, - "@angular/material": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@angular/material/-/material-7.3.0.tgz", - "integrity": "sha512-wWf7dSX8pu9dY9GWiXJfYLA3LTSBREtHLr1NxhN26tQWxGKQ7NJBXth1GTgvojmwt5GzL2j4uyfq/PPvnp95iw==", - "requires": { - "tslib": "^1.7.1" - } - }, - "@angular/material-moment-adapter": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@angular/material-moment-adapter/-/material-moment-adapter-7.3.0.tgz", - "integrity": "sha512-TM4U3ZlBaK7PTvIXdOEAmBjLQZOUcqWdCECfpv7h54evQuvG5XXUc95Oz5bIca6xMiWuDY15qrWaSt8YZ0BgeA==", - "requires": { - "tslib": "^1.7.1" - } - }, - "@angular/platform-browser": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-7.2.3.tgz", - "integrity": "sha512-DH0Y2lgEgcrP1I/DUQB/krL7Ob7yL685fu4sRapW17SndTQa2pqSFMBVf+mN3FupTXp7nJHSvlIktzedIk04+g==", - "requires": { - "tslib": "^1.9.0" - } - }, - "@angular/platform-browser-dynamic": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-7.2.3.tgz", - "integrity": "sha512-M8Kiz5FUhnFybJuk/mgOhBjVbRgKDC4bGWKWH9Z9SXBR2dS/FL3QOJsLIthQcWlHOzSoJdEoPBRhn0R4pyLBSw==", - "requires": { - "tslib": "^1.9.0" - } - }, - "@angular/router": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-7.2.3.tgz", - "integrity": "sha512-SH7H2I9WTj1puei4m4g5n0/Cp28HS14q4r8lOgW0gLWuT6Ls7MqH/nDjOMiW924iRR6zjQQs7G+WbhL1jmZc2A==", - "requires": { - "tslib": "^1.9.0" - } - }, - "@iamstarkov/listr-update-renderer": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@iamstarkov/listr-update-renderer/-/listr-update-renderer-0.4.1.tgz", - "integrity": "sha512-IJyxQWsYDEkf8C8QthBn5N8tIUR9V9je6j3sMIpAkonaadjbvxmRC6RAhpa3RKxndhNnU2M6iNbtJwd7usQYIA==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "cli-truncate": "^0.2.1", - "elegant-spinner": "^1.0.1", - "figures": "^1.7.0", - "indent-string": "^3.0.0", - "log-symbols": "^1.0.2", - "log-update": "^2.3.0", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5", - "object-assign": "^4.1.0" - } - }, - "indent-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", - "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", - "dev": true - }, - "log-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", - "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", - "dev": true, - "requires": { - "chalk": "^1.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "http://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "@mat-datetimepicker/core": { - "version": "3.0.0-beta.0", - "resolved": "https://registry.npmjs.org/@mat-datetimepicker/core/-/core-3.0.0-beta.0.tgz", - "integrity": "sha512-bsEziG0qmzVmg5PoBYqdaoUm58M1m6Qf0JIS0xHMFkvuRtLKJsA4G1LJ9Up5ZruKMW1rmtE3wuBeZmyln4vsQQ==", - "requires": { - "tslib": "^1.9.0" - } - }, - "@mat-datetimepicker/moment": { - "version": "3.0.0-beta.0", - "resolved": "https://registry.npmjs.org/@mat-datetimepicker/moment/-/moment-3.0.0-beta.0.tgz", - "integrity": "sha512-nWRcOi5pZ4cXzuZnjr5EMgo3UxYjuOAIAvQ10t4NQBy+0VBsbLDB8+w9DKPBZCUBfqa1oH9U1/6ai6LL4aDdtw==", - "requires": { - "tslib": "^1.9.0" - } - }, - "@ngrx/effects": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@ngrx/effects/-/effects-7.2.0.tgz", - "integrity": "sha512-vymKSoubYlUWGbiclPK0N/LwB409sB9atjSTQRy2EisZfFtQ2tCDqmk4JGgDy/gV9SqZWrwPSy1xXsLqYnyN3g==" - }, - "@ngrx/router-store": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@ngrx/router-store/-/router-store-7.2.0.tgz", - "integrity": "sha512-deXDZg4FffuqxlFXqAaR8+lEy4yCJgTmKn2avKHltF3GP+8bxIRiD6GDCYjYJVhLFiBK8U3AFhgfoEuUUpFCag==" - }, - "@ngrx/store": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@ngrx/store/-/store-7.2.0.tgz", - "integrity": "sha512-E9c0cDot0HeE0mXyeqw18SwmJ2+eKnA5mMMfwvoskpMInCYGI2pq1i6/lCVQ2wrEHSH+KvObK4PQbepcA9vP+w==" - }, - "@ngrx/store-devtools": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@ngrx/store-devtools/-/store-devtools-7.2.0.tgz", - "integrity": "sha512-t+8K1IG8+MvFqLIuRSM+ZE1EkZIuUExJ0JsqZR4r4K3MRPRoGy1ZqlStBWYaYLumEToesiCOGxuJYQ4zyVwlZg==" - }, - "@ngtools/json-schema": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@ngtools/json-schema/-/json-schema-1.1.0.tgz", - "integrity": "sha1-w6DFRNYjkqzCgTpCyKDcb1j4aSI=", - "dev": true - }, - "@ngtools/webpack": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-7.3.0.tgz", - "integrity": "sha512-U/By0Jlwy7nYwrGNtFirTg1aAsEHBL/9DhfFxPI0iu27FWiMttROuN6hmKbbnOmpbiYAVl5qTy3WXPXUIJjG1A==", - "dev": true, - "requires": { - "@angular-devkit/core": "7.3.0", - "enhanced-resolve": "4.1.0", - "rxjs": "6.3.3", - "tree-kill": "1.2.1", - "webpack-sources": "1.3.0" - }, - "dependencies": { - "rxjs": { - "version": "6.3.3", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", - "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - } - } - }, - "@ngx-translate/core": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/@ngx-translate/core/-/core-11.0.1.tgz", - "integrity": "sha512-nBCa1ZD9fAUY/3eskP3Lql2fNg8OMrYIej1/5GRsfcutx9tG/5fZLCv9m6UCw1aS+u4uK/vXjv1ctG/FdMvaWg==", - "requires": { - "tslib": "^1.9.0" - } - }, - "@phenomnomnominal/tsquery": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@phenomnomnominal/tsquery/-/tsquery-3.0.0.tgz", - "integrity": "sha512-SW8lKitBHWJ9fAYkJ9kJivuctwNYCh3BUxLdH0+XiR1GPBiu+7qiZzh8p8jqlj1LgVC1TbvfNFroaEsmYlL8Iw==", - "dev": true, - "requires": { - "esquery": "^1.0.1" - } - }, - "@samverschueren/stream-to-observable": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz", - "integrity": "sha512-MI4Xx6LHs4Webyvi6EbspgyAb4D2Q2VtnCQ1blOJcoLS6mVa8lNN2rkIy1CVxfTUpoyIbCTkXES1rLXztFD1lg==", - "dev": true, - "requires": { - "any-observable": "^0.3.0" - } - }, - "@schematics/angular": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-7.3.0.tgz", - "integrity": "sha512-fOjP/3Rz+Nqrgc+YVaiN88uhPX0FZgUjmMKgMp06lc3xmoc1ScGxoz8AF1fV50Zkvh0Etykzy1LTUczzEUJQqw==", - "dev": true, - "requires": { - "@angular-devkit/core": "7.3.0", - "@angular-devkit/schematics": "7.3.0", - "typescript": "3.2.2" - }, - "dependencies": { - "@angular-devkit/core": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.3.0.tgz", - "integrity": "sha512-b0qtAUpgqLpWY8W6vWRv1aj6bXkZCP1rvywl8i8TbGMY67CWRcy5J3fNAMmjiZS+LJixFlIXYf4iOydglyJMfg==", - "dev": true, - "requires": { - "ajv": "6.7.0", - "chokidar": "2.0.4", - "fast-json-stable-stringify": "2.0.0", - "rxjs": "6.3.3", - "source-map": "0.7.3" - } - }, - "ajv": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.7.0.tgz", - "integrity": "sha512-RZXPviBTtfmtka9n9sy1N5M5b82CbxWIR6HIis4s3WQTXDJamc/0gpCWNGz6EWdWp4DOfjzJfhz/AS9zVPjjWg==", - "dev": true, - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": 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" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chokidar": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", - "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.0", - "braces": "^2.3.0", - "fsevents": "^1.2.2", - "glob-parent": "^3.1.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "lodash.debounce": "^4.0.8", - "normalize-path": "^2.1.1", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0", - "upath": "^1.0.5" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", - "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "rxjs": { - "version": "6.3.3", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", - "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true - }, - "typescript": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.2.2.tgz", - "integrity": "sha512-VCj5UiSyHBjwfYacmDuc/NOk4QQixbE+Wn7MFJuS0nRuPQbof132Pw4u53dm264O8LPc2MVsc7RJNml5szurkg==", - "dev": true - } - } - }, - "@schematics/update": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@schematics/update/-/update-0.13.0.tgz", - "integrity": "sha512-HGpZdIL/0w46UyaxpnIAg6SBwzKfaRixHIEihmgJUqA0DG8GZUixRPr1L0YIWC1EZ81cQ+yWL85XhkKBYR+wQg==", - "dev": true, - "requires": { - "@angular-devkit/core": "7.3.0", - "@angular-devkit/schematics": "7.3.0", - "@yarnpkg/lockfile": "1.1.0", - "ini": "1.3.5", - "pacote": "9.4.0", - "rxjs": "6.3.3", - "semver": "5.6.0", - "semver-intersect": "1.4.0" - }, - "dependencies": { - "@angular-devkit/core": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.3.0.tgz", - "integrity": "sha512-b0qtAUpgqLpWY8W6vWRv1aj6bXkZCP1rvywl8i8TbGMY67CWRcy5J3fNAMmjiZS+LJixFlIXYf4iOydglyJMfg==", - "dev": true, - "requires": { - "ajv": "6.7.0", - "chokidar": "2.0.4", - "fast-json-stable-stringify": "2.0.0", - "rxjs": "6.3.3", - "source-map": "0.7.3" - } - }, - "ajv": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.7.0.tgz", - "integrity": "sha512-RZXPviBTtfmtka9n9sy1N5M5b82CbxWIR6HIis4s3WQTXDJamc/0gpCWNGz6EWdWp4DOfjzJfhz/AS9zVPjjWg==", - "dev": true, - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": 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" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chokidar": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", - "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.0", - "braces": "^2.3.0", - "fsevents": "^1.2.2", - "glob-parent": "^3.1.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "lodash.debounce": "^4.0.8", - "normalize-path": "^2.1.1", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0", - "upath": "^1.0.5" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" } }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", "dev": true, "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "escape-string-regexp": "^1.0.5", + "object-assign": "^4.1.0" } }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "indent-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", + "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", "dev": true }, - "is-glob": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", - "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", + "log-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", + "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", "dev": true, "requires": { - "is-extglob": "^2.1.1" + "chalk": "^1.0.0" } }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "@mat-datetimepicker/core": { + "version": "3.0.0-beta.0", + "resolved": "https://registry.npmjs.org/@mat-datetimepicker/core/-/core-3.0.0-beta.0.tgz", + "integrity": "sha512-bsEziG0qmzVmg5PoBYqdaoUm58M1m6Qf0JIS0xHMFkvuRtLKJsA4G1LJ9Up5ZruKMW1rmtE3wuBeZmyln4vsQQ==", + "requires": { + "tslib": "^1.9.0" + } + }, + "@mat-datetimepicker/moment": { + "version": "3.0.0-beta.0", + "resolved": "https://registry.npmjs.org/@mat-datetimepicker/moment/-/moment-3.0.0-beta.0.tgz", + "integrity": "sha512-nWRcOi5pZ4cXzuZnjr5EMgo3UxYjuOAIAvQ10t4NQBy+0VBsbLDB8+w9DKPBZCUBfqa1oH9U1/6ai6LL4aDdtw==", + "requires": { + "tslib": "^1.9.0" + } + }, + "@ngrx/effects": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@ngrx/effects/-/effects-7.2.0.tgz", + "integrity": "sha512-vymKSoubYlUWGbiclPK0N/LwB409sB9atjSTQRy2EisZfFtQ2tCDqmk4JGgDy/gV9SqZWrwPSy1xXsLqYnyN3g==" + }, + "@ngrx/router-store": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@ngrx/router-store/-/router-store-7.2.0.tgz", + "integrity": "sha512-deXDZg4FffuqxlFXqAaR8+lEy4yCJgTmKn2avKHltF3GP+8bxIRiD6GDCYjYJVhLFiBK8U3AFhgfoEuUUpFCag==" + }, + "@ngrx/store": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@ngrx/store/-/store-7.2.0.tgz", + "integrity": "sha512-E9c0cDot0HeE0mXyeqw18SwmJ2+eKnA5mMMfwvoskpMInCYGI2pq1i6/lCVQ2wrEHSH+KvObK4PQbepcA9vP+w==" + }, + "@ngrx/store-devtools": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@ngrx/store-devtools/-/store-devtools-7.2.0.tgz", + "integrity": "sha512-t+8K1IG8+MvFqLIuRSM+ZE1EkZIuUExJ0JsqZR4r4K3MRPRoGy1ZqlStBWYaYLumEToesiCOGxuJYQ4zyVwlZg==" + }, + "@ngtools/json-schema": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@ngtools/json-schema/-/json-schema-1.1.0.tgz", + "integrity": "sha1-w6DFRNYjkqzCgTpCyKDcb1j4aSI=", + "dev": true + }, + "@ngtools/webpack": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-7.3.0.tgz", + "integrity": "sha512-U/By0Jlwy7nYwrGNtFirTg1aAsEHBL/9DhfFxPI0iu27FWiMttROuN6hmKbbnOmpbiYAVl5qTy3WXPXUIJjG1A==", + "dev": true, + "requires": { + "@angular-devkit/core": "7.3.0", + "enhanced-resolve": "4.1.0", + "rxjs": "6.3.3", + "tree-kill": "1.2.1", + "webpack-sources": "1.3.0" + }, + "dependencies": { + "rxjs": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", + "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", "dev": true, "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } + "tslib": "^1.9.0" } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + } + } + }, + "@ngx-translate/core": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/@ngx-translate/core/-/core-11.0.1.tgz", + "integrity": "sha512-nBCa1ZD9fAUY/3eskP3Lql2fNg8OMrYIej1/5GRsfcutx9tG/5fZLCv9m6UCw1aS+u4uK/vXjv1ctG/FdMvaWg==", + "requires": { + "tslib": "^1.9.0" + } + }, + "@phenomnomnominal/tsquery": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@phenomnomnominal/tsquery/-/tsquery-3.0.0.tgz", + "integrity": "sha512-SW8lKitBHWJ9fAYkJ9kJivuctwNYCh3BUxLdH0+XiR1GPBiu+7qiZzh8p8jqlj1LgVC1TbvfNFroaEsmYlL8Iw==", + "dev": true, + "requires": { + "esquery": "^1.0.1" + } + }, + "@samverschueren/stream-to-observable": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz", + "integrity": "sha512-MI4Xx6LHs4Webyvi6EbspgyAb4D2Q2VtnCQ1blOJcoLS6mVa8lNN2rkIy1CVxfTUpoyIbCTkXES1rLXztFD1lg==", + "dev": true, + "requires": { + "any-observable": "^0.3.0" + } + }, + "@schematics/angular": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-7.3.0.tgz", + "integrity": "sha512-fOjP/3Rz+Nqrgc+YVaiN88uhPX0FZgUjmMKgMp06lc3xmoc1ScGxoz8AF1fV50Zkvh0Etykzy1LTUczzEUJQqw==", + "dev": true, + "requires": { + "@angular-devkit/core": "7.3.0", + "@angular-devkit/schematics": "7.3.0", + "typescript": "3.2.2" + }, + "dependencies": { + "typescript": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.2.2.tgz", + "integrity": "sha512-VCj5UiSyHBjwfYacmDuc/NOk4QQixbE+Wn7MFJuS0nRuPQbof132Pw4u53dm264O8LPc2MVsc7RJNml5szurkg==", "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, + } + } + }, + "@schematics/update": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@schematics/update/-/update-0.13.0.tgz", + "integrity": "sha512-HGpZdIL/0w46UyaxpnIAg6SBwzKfaRixHIEihmgJUqA0DG8GZUixRPr1L0YIWC1EZ81cQ+yWL85XhkKBYR+wQg==", + "dev": true, + "requires": { + "@angular-devkit/core": "7.3.0", + "@angular-devkit/schematics": "7.3.0", + "@yarnpkg/lockfile": "1.1.0", + "ini": "1.3.5", + "pacote": "9.4.0", + "rxjs": "6.3.3", + "semver": "5.6.0", + "semver-intersect": "1.4.0" + }, + "dependencies": { "rxjs": { "version": "6.3.3", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", @@ -2852,18 +970,6 @@ "requires": { "tslib": "^1.9.0" } - }, - "semver": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", - "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", - "dev": true - }, - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true } } }, @@ -2874,15 +980,15 @@ "dev": true }, "@types/jasmine": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-2.8.8.tgz", - "integrity": "sha512-OJSUxLaxXsjjhob2DBzqzgrkLmukM3+JMpRp0r0E4HTdT1nwDCWhaswjYxazPij6uOdzHCJfNbDjmQ1/rnNbCg==", + "version": "2.8.16", + "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-2.8.16.tgz", + "integrity": "sha512-056oRlBBp7MDzr+HoU5su099s/s7wjZ3KcHxLfv+Byqb9MwdLUvsfLgw1VS97hsh3ddxSPyQu+olHMnoVTUY6g==", "dev": true }, "@types/jasminewd2": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/jasminewd2/-/jasminewd2-2.0.3.tgz", - "integrity": "sha512-hYDVmQZT5VA2kigd4H4bv7vl/OhlympwREUemqBdOqtrYTo5Ytm12a5W5/nGgGYdanGVxj0x/VhZ7J3hOg/YKg==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/jasminewd2/-/jasminewd2-2.0.6.tgz", + "integrity": "sha512-2ZOKrxb8bKRmP/po5ObYnRDgFE4i+lQiEB27bAMmtMWLgJSqlIDqlLx6S0IRorpOmOPRQ6O80NujTmQAtBkeNw==", "dev": true, "requires": { "@types/jasmine": "*" @@ -2901,9 +1007,9 @@ "dev": true }, "@types/selenium-webdriver": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-3.0.10.tgz", - "integrity": "sha512-ikB0JHv6vCR1KYUQAzTO4gi/lXLElT4Tx+6De2pc/OZwizE9LRNiTa+U8TBFKBD/nntPnr/MPSHSnOTybjhqNA==", + "version": "3.0.14", + "resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-3.0.14.tgz", + "integrity": "sha512-4GbNCDs98uHCT/OMv40qQC/OpoPbYn9XdXeTiFwHBBFO6eJhYEPUu2zDKirXSbHlvDV8oZ9l8EQ+HrEx/YS9DQ==", "dev": true }, "@types/source-list-map": { @@ -3160,9 +1266,9 @@ } }, "acorn": { - "version": "6.0.6", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.6.tgz", - "integrity": "sha512-5M3G/A4uBSMIlfJ+h9W125vJvPFH/zirISsW5qfxF5YzEvXJCtolLoQvM5yZft0DvMcUrPGKPOlgEu55I6iUtA==", + "version": "6.0.7", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.7.tgz", + "integrity": "sha512-HNJNgE60C9eOTgn974Tlp3dpLZdUr+SoxxDwPaY9J/kDNOLQTkaDgwBUXAF4SSsrAwD9RpdxuHK/EbuF+W9Ahw==", "dev": true }, "acorn-dynamic-import": { @@ -3172,9 +1278,9 @@ "dev": true }, "adm-zip": { - "version": "0.4.11", - "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.11.tgz", - "integrity": "sha512-L8vcjDTCOIJk7wFvmlEUN7AsSb8T+2JrdP7KINBjzr24TJ5Mwj590sLu3BC7zNZowvJWa/JtPmD8eJCzdtDWjA==", + "version": "0.4.13", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.13.tgz", + "integrity": "sha512-fERNJX8sOXfel6qCBCMPvZLzENBEhZTzKqg6vrOW5pvoEaQuJhRU4ndTAh6lHOxn1I6jnz2NHra56ZODM751uw==", "dev": true }, "after": { @@ -3202,14 +1308,14 @@ } }, "ajv": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.2.tgz", - "integrity": "sha512-hOs7GfvI6tUI1LfZddH82ky6mOMyTuY0mk7kE2pWpmhhUSkumzaTO5vbVwij39MdwPQWCV4Zv57Eo06NtL/GVA==", + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.8.1.tgz", + "integrity": "sha512-eqxCp82P+JfqL683wwsL73XmFs1eG6qjw+RD3YHx+Jll1r0jNd4dh8QG9NYAeNGA/hnZjeEDgtTskgJULbxpWQ==", "requires": { "fast-deep-equal": "^2.0.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.1" + "uri-js": "^4.2.2" } }, "ajv-errors": { @@ -3219,21 +1325,9 @@ "dev": true }, "ajv-keywords": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz", - "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=" - }, - "align-text": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", - "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^3.0.2", - "longest": "^1.0.1", - "repeat-string": "^1.5.2" - } + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.3.0.tgz", + "integrity": "sha512-CMzN9S62ZOO4sA/mJZIO4S++ZM7KFWzH3PPWkveLhy4OZ9i1/VatgwWMD46w/XbGCBy7Ye0gCk+Za6mmyfKK7g==" }, "amdefine": { "version": "1.0.1", @@ -3290,9 +1384,9 @@ "dev": true }, "ansi-escapes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", - "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", "dev": true }, "ansi-html": { @@ -3314,23 +1408,6 @@ "dev": true, "requires": { "color-convert": "^1.9.0" - }, - "dependencies": { - "color-convert": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.2.tgz", - "integrity": "sha512-3NUJZdhMhcdPn8vJ9v2UQJoH0qqoGUkYTgFEPZaPjEtwmmKUfNV46zZmgB2M5M4DCEQHMaCfWHCxiBflLm04Tg==", - "dev": true, - "requires": { - "color-name": "1.1.1" - } - }, - "color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok=", - "dev": true - } } }, "any-observable": { @@ -3340,13 +1417,13 @@ "dev": true }, "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", "dev": true, "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" } }, "app-root-path": { @@ -3356,12 +1433,12 @@ "dev": true }, "append-transform": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz", - "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-0.4.0.tgz", + "integrity": "sha1-126/jKlNJ24keja61EpLdKthGZE=", "dev": true, "requires": { - "default-require-extensions": "^2.0.0" + "default-require-extensions": "^1.0.0" } }, "aproba": { @@ -3390,13 +1467,10 @@ } }, "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1" - } + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true }, "arr-flatten": { "version": "1.1.0", @@ -3444,9 +1518,9 @@ "dev": true }, "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "dev": true }, "arraybuffer.slice": { @@ -3513,6 +1587,12 @@ } } }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, "assign-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", @@ -3520,13 +1600,10 @@ "dev": true }, "async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", - "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", - "dev": true, - "requires": { - "lodash": "^4.17.10" - } + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true }, "async-each": { "version": "1.0.1", @@ -3552,81 +1629,37 @@ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, "atob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.1.tgz", - "integrity": "sha1-ri1acpR38onWDdf5amMUoi3Wwio=", - "dev": true - }, - "autoprefixer": { - "version": "9.4.7", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.4.7.tgz", - "integrity": "sha512-qS5wW6aXHkm53Y4z73tFGsUhmZu4aMPV9iHXYlF0c/wxjknXNHuj/1cIQb+6YH692DbJGGWcckAXX+VxKvahMA==", - "dev": true, - "requires": { - "browserslist": "^4.4.1", - "caniuse-lite": "^1.0.30000932", - "normalize-range": "^0.1.2", - "num2fraction": "^1.2.2", - "postcss": "^7.0.14", - "postcss-value-parser": "^3.3.1" - }, - "dependencies": { - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "postcss": { - "version": "7.0.14", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.14.tgz", - "integrity": "sha512-NsbD6XUUMZvBxtQAJuWDJeeC4QFsmWsfozWxCJPWf3M55K9iu2iMDaKqyoOdTJ1R4usBXuxlVFAIo8rZPQD4Bg==", - "dev": true, - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "autoprefixer": { + "version": "9.4.6", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.4.6.tgz", + "integrity": "sha512-Yp51mevbOEdxDUy5WjiKtpQaecqYq9OqZSL04rSoCiry7Tc5I9FEyo3bfxiTJc1DfHeKwSFCUYbBAiOQ2VGfiw==", + "dev": true, + "requires": { + "browserslist": "^4.4.1", + "caniuse-lite": "^1.0.30000929", + "normalize-range": "^0.1.2", + "num2fraction": "^1.2.2", + "postcss": "^7.0.13", + "postcss-value-parser": "^3.3.1" } }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true + }, + "aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", + "dev": true + }, "babel-code-frame": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", @@ -3679,6 +1712,14 @@ "lodash": "^4.17.4", "source-map": "^0.5.7", "trim-right": "^1.0.1" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } } }, "babel-messages": { @@ -3757,6 +1798,12 @@ "requires": { "ms": "2.0.0" } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true } } }, @@ -3841,18 +1888,6 @@ "is-data-descriptor": "^1.0.0", "kind-of": "^6.0.2" } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true } } }, @@ -3885,7 +1920,6 @@ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", "dev": true, - "optional": true, "requires": { "tweetnacl": "^0.14.3" } @@ -3900,20 +1934,20 @@ } }, "big.js": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", - "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==" + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" }, "binary-extensions": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", - "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.0.tgz", + "integrity": "sha512-EgmjVLMn22z7eGGv3kcnHwSnJXmFHjISTY9E/S5lIcTD3Oxw05QTcBLNkJFzcb3cNueUdF/IN4U+d78V0zO8Hw==", "dev": true }, "blob": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz", - "integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE=", + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", + "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==", "dev": true }, "block-stream": { @@ -3932,20 +1966,12 @@ "dev": true, "requires": { "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } } }, "bluebird": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", - "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz", + "integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==", "dev": true }, "bn.js": { @@ -3955,21 +1981,21 @@ "dev": true }, "body-parser": { - "version": "1.18.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", - "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", + "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", "dev": true, "requires": { "bytes": "3.0.0", "content-type": "~1.0.4", "debug": "2.6.9", - "depd": "~1.1.1", - "http-errors": "~1.6.2", - "iconv-lite": "0.4.19", + "depd": "~1.1.2", + "http-errors": "~1.6.3", + "iconv-lite": "0.4.23", "on-finished": "~2.3.0", - "qs": "6.5.1", - "raw-body": "2.3.2", - "type-is": "~1.6.15" + "qs": "6.5.2", + "raw-body": "2.3.3", + "type-is": "~1.6.16" }, "dependencies": { "debug": { @@ -3981,16 +2007,16 @@ "ms": "2.0.0" } }, - "iconv-lite": { - "version": "0.4.19", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", - "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, "qs": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", - "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", "dev": true } } @@ -4030,6 +2056,12 @@ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", @@ -4067,14 +2099,32 @@ } }, "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" + "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" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } } }, "brorand": { @@ -4166,9 +2216,9 @@ } }, "browserstack": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/browserstack/-/browserstack-1.5.1.tgz", - "integrity": "sha512-O8VMT64P9NOLhuIoD4YngyxBURefaSdR4QdhG8l6HZ9VxtU7jc3m6jLufFwKA5gaf7fetfB2TnRJnMxyob+heg==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/browserstack/-/browserstack-1.5.2.tgz", + "integrity": "sha512-+6AFt9HzhKykcPF79W6yjEUJcdvZOV0lIXdkORXMJftGrDl0OKWqRF4GHqpDNkxiceDT/uB7Fb/aDwktvXX7dg==", "dev": true, "requires": { "https-proxy-agent": "^2.2.1" @@ -4285,14 +2335,24 @@ "to-object-path": "^0.3.0", "union-value": "^1.0.0", "unset-value": "^1.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } + } + }, + "caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", + "dev": true, + "requires": { + "callsites": "^2.0.0" + } + }, + "caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", + "dev": true, + "requires": { + "caller-callsite": "^2.0.0" } }, "callsite": { @@ -4301,10 +2361,16 @@ "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=", "dev": true }, + "callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", + "dev": true + }, "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", "dev": true }, "camelcase-keys": { @@ -4315,20 +2381,12 @@ "requires": { "camelcase": "^2.0.0", "map-obj": "^1.0.0" - }, - "dependencies": { - "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", - "dev": true - } } }, "caniuse-lite": { - "version": "1.0.30000932", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000932.tgz", - "integrity": "sha512-4bghJFItvzz8m0T3lLZbacmEY9X1Z2AtIzTr7s7byqZIOumASfr4ynDx7rtm0J85nDmx8vsgR6vnaSoeU8Oh0A==", + "version": "1.0.30000935", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000935.tgz", + "integrity": "sha512-1Y2uJ5y56qDt3jsDTdBHL1OqiImzjoQcBG6Yl3Qizq8mcc2SgCFpi+ZwLLqkztYnk9l87IYqRlNBnPSOTbFkXQ==", "dev": true }, "canonical-path": { @@ -4349,26 +2407,26 @@ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", "dev": true }, - "center-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", - "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", - "dev": true, - "optional": true, - "requires": { - "align-text": "^0.1.3", - "lazy-cache": "^1.0.3" - } - }, "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, "chardet": { @@ -4378,20 +2436,24 @@ "dev": true }, "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", + "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", "dev": true, "requires": { - "anymatch": "^1.3.0", + "anymatch": "^2.0.0", "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", + "braces": "^2.3.0", + "fsevents": "^1.2.2", + "glob-parent": "^3.1.0", "inherits": "^2.0.1", "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", + "is-glob": "^4.0.0", + "lodash.debounce": "^4.0.8", + "normalize-path": "^2.1.1", "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" + "readdirp": "^2.0.0", + "upath": "^1.0.5" } }, "chownr": { @@ -4450,9 +2512,9 @@ "dev": true }, "circular-json": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.5.5.tgz", - "integrity": "sha512-13YaR6kiz0kBNmIVM87Io8Hp7bWOo4r61vkEANy8iH9R9bc6avud/1FT0SBpqR1RpIQADOh/Q+yHZDA1iL6ysA==", + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.5.9.tgz", + "integrity": "sha512-4ivwqHpIFJZBuhN3g/pEcdbnGUywkBblloGbkglyloVjjR3uT6tieI89MVOfbP2tHX5sgb01FuLgAOzebNlJNQ==", "dev": true }, "class-utils": { @@ -4475,12 +2537,6 @@ "requires": { "is-descriptor": "^0.1.0" } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true } } }, @@ -4559,23 +2615,6 @@ "is-plain-object": "^2.0.4", "kind-of": "^6.0.0", "shallow-clone": "^1.0.0" - }, - "dependencies": { - "for-own": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", - "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } } }, "co": { @@ -4604,10 +2643,16 @@ "sprintf-js": "^1.1.1" }, "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, "sprintf-js": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.1.tgz", - "integrity": "sha1-Nr54Mgr+WAH2zqPueLblqrlA6gw=", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", + "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", "dev": true } } @@ -4622,6 +2667,21 @@ "object-visit": "^1.0.0" } }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, "colors": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", @@ -4638,17 +2698,17 @@ } }, "combined-stream": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", - "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", + "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", "requires": { "delayed-stream": "~1.0.0" } }, "commander": { - "version": "2.16.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.16.0.tgz", - "integrity": "sha512-sVXqklSaotK9at437sFlFpyOcJonxe0yST/AG9DkQKUdIE6IqGIMv4SfAQSKaJbSdVEJYItASCrBiVQHq1HQew==", + "version": "2.17.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", + "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", "dev": true }, "comment-json": { @@ -4666,12 +2726,6 @@ "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", "dev": true }, - "compare-versions": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.3.0.tgz", - "integrity": "sha512-MAAAIOdi2s4Gl6rZ76PNcUa9IOYB+5ICdT41o5uMRf09aEu/F9RK+qhe8RjXNPwcTjGV7KU7h2P/fljThFVqyQ==", - "dev": true - }, "component-bind": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", @@ -4696,14 +2750,6 @@ "dev": true, "requires": { "mime-db": ">= 1.36.0 < 2" - }, - "dependencies": { - "mime-db": { - "version": "1.37.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", - "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==", - "dev": true - } } }, "compression": { @@ -4729,6 +2775,12 @@ "requires": { "ms": "2.0.0" } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true } } }, @@ -4750,23 +2802,9 @@ } }, "configstore": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz", - "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==", - "dev": true, - "requires": { - "dot-prop": "^4.1.0", - "graceful-fs": "^4.1.2", - "make-dir": "^1.0.0", - "unique-string": "^1.0.0", - "write-file-atomic": "^2.0.0", - "xdg-basedir": "^3.0.0" - } - }, - "configstore-fork": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/configstore-fork/-/configstore-fork-3.1.6.tgz", - "integrity": "sha512-sQ31B6Ayj9Tqs2nPBrq+2cg8j9sb1Hd6iyqDx2rH+W1EoBDevYAkLk5ncNqktkj7hCeyrUzcNhQ5kUozKXd75A==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-4.0.0.tgz", + "integrity": "sha512-CmquAXFBocrzaSM8mtGPMM/HiWmyIpr4CcJl/rgY2uCObZ/S7cKU0silxslqJejl+t/T9HS8E0PUNQD81JGUEQ==", "dev": true, "requires": { "dot-prop": "^4.1.0", @@ -4813,6 +2851,12 @@ "unpipe": "~1.0.0" } }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, "statuses": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", @@ -4920,29 +2964,12 @@ "minimatch": "^3.0.4", "p-limit": "^1.0.0", "serialize-javascript": "^1.4.0" - }, - "dependencies": { - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", - "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - } } }, "core-js": { - "version": "2.5.7", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", - "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==" + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.3.tgz", + "integrity": "sha512-l00tmFFZOBHtYhN4Cz7k32VM7vTn3rE2ANjQDxdEN6zmXZ/xq1jQuutnmHvMG1ZJ7xd72+TA5YpUK8wz3rWsfQ==" }, "core-util-is": { "version": "1.0.2", @@ -5055,179 +3082,244 @@ "dev": true }, "cspell": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/cspell/-/cspell-3.1.3.tgz", - "integrity": "sha512-7N+ssYKkeYrwGRGlScUh3HvEePseY7VIHUpQwpMjDCdcRD91hUfuvphJEbvkWY++s4qjIF2w+9ZWcDO06sqPOQ==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/cspell/-/cspell-3.2.1.tgz", + "integrity": "sha512-VjEcxU+WUfJn1/ShgYVsH4fdT8MaOBmLATKZ2DpsY+zdh5i07NmC8fVlsF56F4rE5Ybz2e9KHMi+HcNN08ruEg==", "dev": true, "requires": { - "chalk": "^2.4.1", - "commander": "^2.15.1", + "chalk": "^2.4.2", + "commander": "^2.19.0", "comment-json": "^1.1.3", - "configstore-fork": "^3.1.6", - "cspell-dict-cpp": "^1.1.8", - "cspell-dict-django": "^1.0.4", - "cspell-dict-elixir": "^1.0.1", - "cspell-dict-en-gb": "^1.1.2", - "cspell-dict-en_us": "^1.2.5", - "cspell-dict-golang": "^1.1.3", - "cspell-dict-java": "^1.0.3", - "cspell-dict-latex": "^1.0.1", - "cspell-dict-lorem-ipsum": "^1.0.1", - "cspell-dict-php": "^1.0.2", - "cspell-dict-python": "^1.0.3", - "cspell-dict-rust": "^1.0.0", - "cspell-dict-scala": "^1.0.3", - "cspell-lib": "^3.0.2", - "cspell-trie": "^3.0.4", - "fs-extra": "^5.0.0", - "gensequence": "^2.1.1", - "glob": "^7.1.2", + "configstore": "^4.0.0", + "cspell-dict-companies": "^1.0.3", + "cspell-dict-cpp": "^1.1.11", + "cspell-dict-django": "^1.0.7", + "cspell-dict-elixir": "^1.0.4", + "cspell-dict-en-gb": "^1.1.7", + "cspell-dict-en_us": "^1.2.10", + "cspell-dict-fullstack": "^1.0.6", + "cspell-dict-golang": "^1.1.8", + "cspell-dict-java": "^1.0.5", + "cspell-dict-latex": "^1.0.6", + "cspell-dict-lorem-ipsum": "^1.0.4", + "cspell-dict-php": "^1.0.7", + "cspell-dict-python": "^1.0.8", + "cspell-dict-rust": "^1.0.6", + "cspell-dict-scala": "^1.0.5", + "cspell-lib": "^3.0.5", + "cspell-trie": "^3.0.7", + "fs-extra": "^7.0.1", + "gensequence": "^2.1.2", + "glob": "^7.1.3", "minimatch": "^3.0.4", - "rxjs": "^6.2.1", - "vscode-uri": "^1.0.5", - "xregexp": "^4.2.0" + "rxjs": "6.3.3", + "vscode-uri": "^1.0.6", + "xregexp": "^4.2.4" + }, + "dependencies": { + "commander": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", + "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", + "dev": true + }, + "rxjs": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", + "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "xregexp": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.2.4.tgz", + "integrity": "sha512-sO0bYdYeJAJBcJA8g7MJJX7UrOZIfJPd8U2SC7B2Dd/J24U0aQNoGp33shCaBSWeb0rD5rh6VBUIXOkGal1TZA==", + "dev": true, + "requires": { + "@babel/runtime-corejs2": "^7.2.0" + } + } + } + }, + "cspell-dict-companies": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/cspell-dict-companies/-/cspell-dict-companies-1.0.3.tgz", + "integrity": "sha512-L4CKmMuI2kSno99tKYHI807y02niwxaFZOsRtmTjb0+zJ8dzyscXvQFmTwynUn3XZf4G+TbYcCOZaSpsx0RlWA==", + "dev": true, + "requires": { + "configstore": "^4.0.0" } }, "cspell-dict-cpp": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/cspell-dict-cpp/-/cspell-dict-cpp-1.1.8.tgz", - "integrity": "sha512-l6/Lc0bCauWuMm/kxjOfS39QuMi8wDIU9c3xeCbbWGNc9rV81VeHRZpCkp+CIfjtTAfIcrn3ZJNzL41oMxTArQ==", + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/cspell-dict-cpp/-/cspell-dict-cpp-1.1.11.tgz", + "integrity": "sha512-FWiOe6nntT1k4r/CkSo8qG6Ib4phu3WXGPqg6txOw+e9wlojzXN7rND2Z8AHt4TUA36h3lHpk/y7gTBgJgR+lw==", "dev": true, "requires": { - "configstore": "^3.1.0" + "configstore": "^4.0.0" } }, "cspell-dict-django": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cspell-dict-django/-/cspell-dict-django-1.0.4.tgz", - "integrity": "sha512-UhD1fzgKOLGXZRRB+WjNwqLtWutcXJD1kHzT5ZC3IS613rPlWeK0N4q790Y9IjVk2S1sh3VYcJ/gStHS/CTLqA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/cspell-dict-django/-/cspell-dict-django-1.0.7.tgz", + "integrity": "sha512-Gi7fYuGLEJSH307ywkOIziQYS3hdIBwMesjvEW71ovqjg0CyQKADcU4ZUd5fcMlndxRLpVhG4NXo3tGdsDf3wA==", "dev": true, "requires": { - "configstore": "^3.1.0" + "configstore": "^4.0.0" } }, "cspell-dict-elixir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cspell-dict-elixir/-/cspell-dict-elixir-1.0.1.tgz", - "integrity": "sha512-/u9mEmfDZE/LkyrHRUeSy/bdXALeFE8Hwe8cMiVR3P1etJoVog8E8hp3JfkjEzwgIv/c9We9tv9UW5bMlWazGQ==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cspell-dict-elixir/-/cspell-dict-elixir-1.0.4.tgz", + "integrity": "sha512-K4W3kmb7ZLbtaoV0Xwd1XGS6DzNah3tygbp7yT4jaq2f6WvG8Uh80tSNog6YIF+DAVk6709RKbIurbHZsx08dg==", "dev": true, "requires": { - "configstore": "^3.1.0" + "configstore": "^4.0.0" } }, "cspell-dict-en-gb": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/cspell-dict-en-gb/-/cspell-dict-en-gb-1.1.2.tgz", - "integrity": "sha512-ry4yNIzjVMZDwSrK7U/0M9vXdbzo7ZFpUHUAYa4r6B4CwUFHBC/d8C0fcav2Hf1jjfQ866AApg00HiRJLP3Aug==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/cspell-dict-en-gb/-/cspell-dict-en-gb-1.1.7.tgz", + "integrity": "sha512-inEzvckvzzscmRE3zCF3dAtAdSD0xHeIba/KAFuu6/yVNWp0zwqMiW1UQ6lW6kXyueETjHLuZMSAJbC4R1DrOA==", "dev": true, "requires": { - "configstore": "^3.1.1" + "configstore": "^4.0.0" } }, "cspell-dict-en_us": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/cspell-dict-en_us/-/cspell-dict-en_us-1.2.5.tgz", - "integrity": "sha512-OaoOaVzIGxJeeyAjZE6Re2+S5OuLHsMFzQcZ3qaD87uO0Q7U9TF6EFPJEmwNuR0Ye9o1rXYYMiFKan6EzH40qg==", + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/cspell-dict-en_us/-/cspell-dict-en_us-1.2.10.tgz", + "integrity": "sha512-3unRvF++r1v2kh9C6R6jzIL0J67i8XIQ/RwNWjQ8fRBdchAzpiV9l0hnpXn4V98Icyy3r1aUpVzBIwGogBQiqw==", + "dev": true, + "requires": { + "configstore": "^4.0.0" + } + }, + "cspell-dict-fullstack": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cspell-dict-fullstack/-/cspell-dict-fullstack-1.0.6.tgz", + "integrity": "sha512-40rQ/6E5erZC4ZS7uQ8Q93M0VrFuqFhcGCup/ZrO2lRHsRPj5+iVeX80VY1jl/gPmG2H/pnJ5+oC5CJkgEBGVw==", "dev": true, "requires": { - "configstore": "^3.1.0" + "configstore": "^4.0.0" } }, "cspell-dict-golang": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/cspell-dict-golang/-/cspell-dict-golang-1.1.3.tgz", - "integrity": "sha512-maImSmm4ctZ5cQ3tFyZr5nglBQ/GwY5OYT1eq6O6USjJRQxzWtzmI1EV8WKng1UEA1i07NqgUDQLejTx3W1hIg==", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/cspell-dict-golang/-/cspell-dict-golang-1.1.8.tgz", + "integrity": "sha512-Ux7Qm9P9sWiVHgbsuKQGJWj+iJkcQkLrlKmqsmNxXc9JeGpS6exmhJLNkhTjQwryB+ry5zcsvvobpCGUC+NBPw==", "dev": true, "requires": { - "configstore": "^3.1.0" + "configstore": "^4.0.0" } }, "cspell-dict-java": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/cspell-dict-java/-/cspell-dict-java-1.0.3.tgz", - "integrity": "sha512-0ZIvoXco3DczG0LSJMWYDCYESjBU9JNPSaVetKwKymQ2TrYi6vk5N18B5TNNRVlRh6hv2hw4DtDB6sz+TyP/yw==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/cspell-dict-java/-/cspell-dict-java-1.0.5.tgz", + "integrity": "sha512-kwp3i+JW2LwzYFk0w9cPCGKe80z7V89GOubFTGpudm9E6y46eO+3YAAjVK5PhMIuuDYF69CicaiP6eW8FsbyhA==", "dev": true, "requires": { - "configstore": "^3.1.0" + "configstore": "^4.0.0" } }, "cspell-dict-latex": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cspell-dict-latex/-/cspell-dict-latex-1.0.1.tgz", - "integrity": "sha512-RyK6TgEpt6AfGbXStPi5G7Fy2CFJGmIAYs1ie6Qsyss7h3sAsHk19F2yZvwJU0dlHXyw4LujFbzo9ZR3HR7BIA==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cspell-dict-latex/-/cspell-dict-latex-1.0.6.tgz", + "integrity": "sha512-BQJbH1RwOPuIHfKsWKSBxIj2QZydVWPSRruwrMQ15gzcheYBz623QhedvrNMgm29AVoH7Lu7i0GIopOyb4ebPw==", "dev": true, "requires": { - "configstore": "^3.1.0" + "configstore": "^4.0.0" } }, "cspell-dict-lorem-ipsum": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cspell-dict-lorem-ipsum/-/cspell-dict-lorem-ipsum-1.0.1.tgz", - "integrity": "sha512-r9O2rD1KQN8URw9sAecXfcAAYyt4xr7OpCXHp4ps/Iw9xH/X6eNxigRtOiv7Xl9NhyX9nPDeD9y3RgVsvSr2kQ==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cspell-dict-lorem-ipsum/-/cspell-dict-lorem-ipsum-1.0.4.tgz", + "integrity": "sha512-JcYUh671h4eLQ3ZX11fnf9pwcGNdFmuSBSE0T37UMFRWkhTPYzoAqXuoWQ1JPE4r4uq9KIEBzGl/VPOIpw1g7w==", "dev": true, "requires": { - "configstore": "^3.1.0" + "configstore": "^4.0.0" } }, "cspell-dict-php": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cspell-dict-php/-/cspell-dict-php-1.0.2.tgz", - "integrity": "sha512-F2NyT9rZ6CmcLhbeGH8OKwLlD9Q5zQConpNDVdu/E/ucEQ+HXIf65Ou5KJzlQcyUGC8P9PUmmUBEF60oW5HcCA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/cspell-dict-php/-/cspell-dict-php-1.0.7.tgz", + "integrity": "sha512-D17wWNAAnlzqSzN9xo7tqPlxyXebKKNXaBFpsehyTZy9GBBk4jzCk6tYW6QKPmAm/Z6rATRdaeoRg2u866+87A==", "dev": true, "requires": { - "configstore": "^3.1.0" + "configstore": "^4.0.0" } }, "cspell-dict-python": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/cspell-dict-python/-/cspell-dict-python-1.0.3.tgz", - "integrity": "sha512-zQYJu/kWvsZusuMelRk7e9B5xINglh49uLswLv598T+ZptzRzKO83im/yCG0RHBWvgYS+ze0eCpr0Ja5uqHu3Q==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/cspell-dict-python/-/cspell-dict-python-1.0.8.tgz", + "integrity": "sha512-j89SutsSPefWxjk8UjYVNEEIaFS07ubh2qXCGQyjMe8nKer2244QBrbUtCCDGeePEIOqvSNP1IS26k32a6SEuw==", "dev": true, "requires": { - "configstore": "^3.1.0" + "configstore": "^4.0.0" } }, "cspell-dict-rust": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cspell-dict-rust/-/cspell-dict-rust-1.0.0.tgz", - "integrity": "sha512-9Rew1ad6yPXQW9fxFQ/J41+fbKg6t9p4oSm7JS0aHuCtWc3w0knFYK7Ty/mVMw6oDFlemBNaBCPZON0M3+oIKg==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cspell-dict-rust/-/cspell-dict-rust-1.0.6.tgz", + "integrity": "sha512-dOBSzOwV+HkfLqMq7JKNaxjUa3W0szWa2gKslZMvolwdaV5t2yWion0EfO63JvFZqky/oN2on52CQ3wSgHlT3w==", "dev": true, "requires": { - "configstore": "^3.1.0" + "configstore": "^4.0.0" } }, "cspell-dict-scala": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/cspell-dict-scala/-/cspell-dict-scala-1.0.3.tgz", - "integrity": "sha512-kYcnQcLk042pTn9EGyOEM9bZXZ/6NAnGKb/IhRJiF2+iStHm5u1jBMeTuHqiU4hOPDbVcE6lK6pZv7lDYQPNZA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/cspell-dict-scala/-/cspell-dict-scala-1.0.5.tgz", + "integrity": "sha512-7rAmPo36imNIb6X9wu02SCaF5hW8d6/ECPDixFD/X+yyHNGnZDOKlx1eVd4jDEHbL+m0v6CdHBxM2te8nnfgdA==", "dev": true, "requires": { - "configstore": "^3.1.0" + "configstore": "^4.0.0" } }, "cspell-lib": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/cspell-lib/-/cspell-lib-3.0.2.tgz", - "integrity": "sha512-a6T8qlqnFz40C36Rl/jfu72ev6YyHlN9cwSR0uDwKADl+BOfbvfEPpx9neUB3jYYwIafa3S5BRict7erD/H2EQ==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/cspell-lib/-/cspell-lib-3.0.5.tgz", + "integrity": "sha512-z2f5t4un43qWFYYtEKjdDj1aG2TIdOUUYQpytkDrzWcJxyOkSzxOPItOe9zypQeJrIQ8YeVnrazzKpzeap/Ulw==", "dev": true, "requires": { - "iconv-lite": "^0.4.22", - "rxjs-stream": "^2.0.3" + "iconv-lite": "^0.4.24", + "rxjs-stream": "^3.0.1" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + } } }, "cspell-trie": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/cspell-trie/-/cspell-trie-3.0.4.tgz", - "integrity": "sha512-dCc8YX54C4pfGcQDV/XpK4AcPfEME6Io+LATvLi0HHmkebuSTzOcal58TgbFXeL6+06s7zqID9K3Oq/wcmEwrw==", + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/cspell-trie/-/cspell-trie-3.0.7.tgz", + "integrity": "sha512-ASunLF5cb9qr8aLw23mcD6150Ipcn3c2pGcbIgN6Qoenk12An3JYZIi9+SLDvsf/LgPFa+EccUiFw1ox+WpvKg==", "dev": true, "requires": { - "commander": "^2.15.1", - "cspell-lib": "^3.0.2", - "fs-extra": "^5.0.0", + "commander": "^2.18.0", + "cspell-lib": "^3.0.4", + "fs-extra": "^7.0.0", "gensequence": "^2.1.1", - "hunspell-reader": "^2.0.2", - "rxjs": "^6.1.0", - "rxjs-stream": "^2.0.3" + "hunspell-reader": "^2.0.3", + "rxjs": "^6.3.3", + "rxjs-stream": "^3.0.1" + }, + "dependencies": { + "commander": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", + "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", + "dev": true + } } }, "css-parse": { @@ -5304,14 +3396,6 @@ "dev": true, "requires": { "assert-plus": "^1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } } }, "date-fns": { @@ -5333,11 +3417,11 @@ "dev": true }, "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" } }, "decamelize": { @@ -5384,53 +3468,15 @@ "requires": { "execa": "^0.10.0", "ip-regex": "^2.1.0" - }, - "dependencies": { - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "execa": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz", - "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==", - "dev": true, - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - } } }, "default-require-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", - "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-1.0.0.tgz", + "integrity": "sha1-836hXT4T/9m0N9M+GnW1+5eHTLg=", "dev": true, "requires": { - "strip-bom": "^3.0.0" - }, - "dependencies": { - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - } + "strip-bom": "^2.0.0" } }, "define-property": { @@ -5471,18 +3517,6 @@ "is-data-descriptor": "^1.0.0", "kind-of": "^6.0.2" } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true } } }, @@ -5668,9 +3702,9 @@ "dev": true }, "duplexify": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.6.1.tgz", - "integrity": "sha512-vM58DwdnKmty+FSPzT14K9JXb90H+j5emaR4KYbr2KTIz00WHGbWOe5ghQTx233ZCLZtrGDALzKwcjEtSt35mA==", + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", "dev": true, "requires": { "end-of-stream": "^1.0.0", @@ -5684,7 +3718,6 @@ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", "dev": true, - "optional": true, "requires": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" @@ -5697,9 +3730,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.3.108", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.108.tgz", - "integrity": "sha512-/QI4hMpAh48a1Sea6PALGv+kuVne9A2EWGd8HrWHMdYhIzGtbhVVHh6heL5fAzGaDnZuPyrlWJRl8WPm4RyiQQ==", + "version": "1.3.113", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.113.tgz", + "integrity": "sha512-De+lPAxEcpxvqPTyZAXELNpRZXABRxf+uL/rSykstQhzj/B0l1150G/ExIIxKc16lI89Hgz81J0BHAcbTqK49g==", "dev": true }, "elegant-spinner": { @@ -5753,9 +3786,9 @@ } }, "engine.io": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.2.0.tgz", - "integrity": "sha512-mRbgmAtQ4GAlKwuPnnAvXXwdPhEx+jkc0OBCLrXuD/CRvwNK3AxRSnqK4FSqmAMRRHryVJP8TopOvmEaA64fKw==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.2.1.tgz", + "integrity": "sha512-+VlKzHzMhaU+GsCIg4AoXF1UdDFjHHwMmMKqMJNDNLlUlejz58FCy4LBqB2YVJskHGYl06BatYWKP2TVdVXE5w==", "dev": true, "requires": { "accepts": "~1.3.4", @@ -5764,6 +3797,23 @@ "debug": "~3.1.0", "engine.io-parser": "~2.1.0", "ws": "~3.3.1" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } } }, "engine.io-client": { @@ -5783,18 +3833,35 @@ "ws": "~3.3.1", "xmlhttprequest-ssl": "~1.5.4", "yeast": "0.1.2" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } } }, "engine.io-parser": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.2.tgz", - "integrity": "sha512-dInLFzr80RijZ1rGpx1+56/uFoH7/7InhH3kZt+Ms6hT8tNx3NGW/WNSA/f8As1WkOfkuyb3tnRyuXGxusclMw==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.3.tgz", + "integrity": "sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA==", "dev": true, "requires": { "after": "0.8.2", "arraybuffer.slice": "~0.0.7", "base64-arraybuffer": "0.1.5", - "blob": "0.0.4", + "blob": "0.0.5", "has-binary2": "~1.0.2" } }, @@ -5870,9 +3937,9 @@ } }, "es6-promise": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz", - "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==", + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.5.tgz", + "integrity": "sha512-n6wvpdE43VFtJq+lUDYDBFUwV8TZbuGXLV4D6wKafg13ldznKsyEvatubnmUe31zcvelSzOHF+XbaT+Bl9ObDg==", "dev": true }, "es6-promisify": { @@ -6063,12 +4130,12 @@ } }, "execa": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz", + "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==", "dev": true, "requires": { - "cross-spawn": "^5.0.1", + "cross-spawn": "^6.0.0", "get-stream": "^3.0.0", "is-stream": "^1.1.0", "npm-run-path": "^2.0.0", @@ -6078,12 +4145,14 @@ }, "dependencies": { "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "dev": true, "requires": { - "lru-cache": "^4.0.1", + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", "shebang-command": "^1.2.0", "which": "^1.2.9" } @@ -6107,6 +4176,12 @@ "braces": "^0.1.2" }, "dependencies": { + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, "braces": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/braces/-/braces-0.1.5.tgz", @@ -6141,12 +4216,53 @@ } }, "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", "dev": true, "requires": { - "is-posix-bracket": "^0.1.0" + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } } }, "expand-range": { @@ -6156,6 +4272,48 @@ "dev": true, "requires": { "fill-range": "^2.1.0" + }, + "dependencies": { + "fill-range": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", + "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", + "dev": true, + "requires": { + "is-number": "^2.1.0", + "isobject": "^2.0.0", + "randomatic": "^3.0.0", + "repeat-element": "^1.1.2", + "repeat-string": "^1.5.2" + } + }, + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } } }, "express": { @@ -6202,24 +4360,6 @@ "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", "dev": true }, - "body-parser": { - "version": "1.18.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", - "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", - "dev": true, - "requires": { - "bytes": "3.0.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "~1.6.3", - "iconv-lite": "0.4.23", - "on-finished": "~2.3.0", - "qs": "6.5.2", - "raw-body": "2.3.3", - "type-is": "~1.6.16" - } - }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -6229,17 +4369,17 @@ "ms": "2.0.0" } }, - "raw-body": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", - "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", - "dev": true, - "requires": { - "bytes": "3.0.0", - "http-errors": "1.6.3", - "iconv-lite": "0.4.23", - "unpipe": "1.0.0" - } + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true } } }, @@ -6286,20 +4426,76 @@ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, "requires": { - "safer-buffer": ">= 2.1.2 < 3" + "safer-buffer": ">= 2.1.2 < 3" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } } } }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", @@ -6392,16 +4588,26 @@ } }, "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } } }, "finalhandler": { @@ -6427,6 +4633,12 @@ "requires": { "ms": "2.0.0" } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true } } }, @@ -6456,23 +4668,65 @@ "locate-path": "^2.0.0" } }, + "flatted": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.0.tgz", + "integrity": "sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg==", + "dev": true + }, "flush-write-stream": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.3.tgz", - "integrity": "sha512-calZMC10u0FMUqoiunI2AiGIIUtUIvifNwkHhNupZH4cbNnW1Itkoh/Nf5HFYmDrwWPjrUxpkZT0KhuCq0jmGw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.0.tgz", + "integrity": "sha512-6MHED/cmsyux1G4/Cek2Z776y9t7WCNd3h2h/HW91vFeU7pzMhA8XvAlDhHcanG5IWuIh/xcC7JASY4WQpG6xg==", "dev": true, "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.4" + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "dependencies": { + "readable-stream": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.1.1.tgz", + "integrity": "sha512-DkN66hPyqDhnIQ6Jcsvx9bFjhw214O4poMBcIMgPVpQvNy9a0e0Uhg5SqySyDKAmUlwt8LonTBz1ezOnM8pUdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } } }, + "fn-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fn-name/-/fn-name-2.0.1.tgz", + "integrity": "sha1-UhTXU3pNBqSjAcDMJi/rhBiAAuc=", + "dev": true + }, "follow-redirects": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.2.tgz", - "integrity": "sha512-kssLorP/9acIdpQ2udQVTiCS5LQmdEz9mvdIfDcl1gYX2tPKFADHSyFdvJS040XdFsPzemWtgI3q8mFVCxtX8A==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.6.1.tgz", + "integrity": "sha512-t2JCjbzxQpWvbhts3l6SH1DKzSrx8a+SsaVf4h6bG4kOXUuPYS/kg2Lr4gQSb7eemaHqJkOThF1BGyjlUkO1GQ==", "dev": true, "requires": { - "debug": "^3.1.0" + "debug": "=3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } } }, "for-in": { @@ -6482,9 +4736,9 @@ "dev": true }, "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", "dev": true, "requires": { "for-in": "^1.0.1" @@ -6497,12 +4751,12 @@ "dev": true }, "form-data": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", - "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", "requires": { "asynckit": "^0.4.0", - "combined-stream": "1.0.6", + "combined-stream": "^1.0.6", "mime-types": "^2.1.12" } }, @@ -6552,9 +4806,9 @@ } }, "fs-extra": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz", - "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", "dev": true, "requires": { "graceful-fs": "^4.1.2", @@ -6590,9 +4844,9 @@ "dev": true }, "fsevents": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", - "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.7.tgz", + "integrity": "sha512-Pxm6sI2MeBD7RdD12RYsqaP0nMiwx8eZBXCa6z2L+mRHm2DYrOYwihmhjpkdjUHwQhslWQjRpEgNq4XvBmaAuw==", "dev": true, "optional": true, "requires": { @@ -6602,29 +4856,24 @@ "dependencies": { "abbrev": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "bundled": true, "dev": true, "optional": true }, "ansi-regex": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, - "optional": true + "bundled": true, + "dev": true }, "aproba": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "bundled": true, "dev": true, "optional": true }, "are-we-there-yet": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz", - "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=", + "version": "1.1.5", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -6634,61 +4883,48 @@ }, "balanced-match": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true, - "optional": true + "bundled": true, + "dev": true }, "brace-expansion": { "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "bundled": true, "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "chownr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz", - "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=", + "version": "1.1.1", + "bundled": true, "dev": true, "optional": true }, "code-point-at": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true, - "optional": true + "bundled": true, + "dev": true }, "concat-map": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true, - "optional": true + "bundled": true, + "dev": true }, "console-control-strings": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true, - "optional": true + "bundled": true, + "dev": true }, "core-util-is": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "bundled": true, "dev": true, "optional": true }, "debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -6696,30 +4932,26 @@ } }, "deep-extend": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.5.1.tgz", - "integrity": "sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w==", + "version": "0.6.0", + "bundled": true, "dev": true, "optional": true }, "delegates": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "bundled": true, "dev": true, "optional": true }, "detect-libc": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", + "bundled": true, "dev": true, "optional": true }, "fs-minipass": { "version": "1.2.5", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.5.tgz", - "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -6728,15 +4960,13 @@ }, "fs.realpath": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "bundled": true, "dev": true, "optional": true }, "gauge": { "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -6751,9 +4981,8 @@ } }, "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "version": "7.1.3", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -6767,25 +4996,22 @@ }, "has-unicode": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "bundled": true, "dev": true, "optional": true }, "iconv-lite": { - "version": "0.4.21", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.21.tgz", - "integrity": "sha512-En5V9za5mBt2oUA03WGD3TwDv0MKAruqsuxstbMUZaj9W9k/m1CV/9py3l0L5kw9Bln8fdHQmzHSYtvpvTLpKw==", + "version": "0.4.24", + "bundled": true, "dev": true, "optional": true, "requires": { - "safer-buffer": "^2.1.0" + "safer-buffer": ">= 2.1.2 < 3" } }, "ignore-walk": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz", - "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -6794,8 +5020,7 @@ }, "inflight": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -6805,67 +5030,54 @@ }, "inherits": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true, - "optional": true + "bundled": true, + "dev": true }, "ini": { "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "bundled": true, "dev": true, "optional": true }, "is-fullwidth-code-point": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "bundled": true, "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } }, "isarray": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "bundled": true, "dev": true, "optional": true }, "minimatch": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "bundled": true, "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true, - "optional": true + "bundled": true, + "dev": true }, "minipass": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.2.4.tgz", - "integrity": "sha512-hzXIWWet/BzWhYs2b+u7dRHlruXhwdgvlTMDKC6Cb1U7ps6Ac6yQlR39xsbjWJE377YTCtKwIXIpJ5oP+j5y8g==", + "version": "2.3.5", + "bundled": true, "dev": true, - "optional": true, "requires": { - "safe-buffer": "^5.1.1", + "safe-buffer": "^5.1.2", "yallist": "^3.0.0" } }, "minizlib": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.1.0.tgz", - "integrity": "sha512-4T6Ur/GctZ27nHfpt9THOdRZNgyJ9FZchYO1ceg5S8Q3DNLCKYy44nCZzgCJgcvx2UM8czmqak5BCxJMrq37lA==", + "version": "1.2.1", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -6874,25 +5086,21 @@ }, "mkdirp": { "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } }, "ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "bundled": true, "dev": true, "optional": true }, "needle": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/needle/-/needle-2.2.0.tgz", - "integrity": "sha512-eFagy6c+TYayorXw/qtAdSvaUpEbBsDwDyxYFgLZ0lTojfH7K+OdBqAF7TAFwDokJaGpubpSGG0wO3iC0XPi8w==", + "version": "2.2.4", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -6902,19 +5110,18 @@ } }, "node-pre-gyp": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.10.0.tgz", - "integrity": "sha512-G7kEonQLRbcA/mOoFoxvlMrw6Q6dPf92+t/l0DFSMuSlDoWaI9JWIyPwK0jyE1bph//CUEL65/Fz1m2vJbmjQQ==", + "version": "0.10.3", + "bundled": true, "dev": true, "optional": true, "requires": { "detect-libc": "^1.0.2", "mkdirp": "^0.5.1", - "needle": "^2.2.0", + "needle": "^2.2.1", "nopt": "^4.0.1", "npm-packlist": "^1.1.6", "npmlog": "^4.0.2", - "rc": "^1.1.7", + "rc": "^1.2.7", "rimraf": "^2.6.1", "semver": "^5.3.0", "tar": "^4" @@ -6922,8 +5129,7 @@ }, "nopt": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", - "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -6932,16 +5138,14 @@ } }, "npm-bundled": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.3.tgz", - "integrity": "sha512-ByQ3oJ/5ETLyglU2+8dBObvhfWXX8dtPZDMePCahptliFX2iIuhyEszyFk401PZUNQH20vvdW5MLjJxkwU80Ow==", + "version": "1.0.5", + "bundled": true, "dev": true, "optional": true }, "npm-packlist": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.1.10.tgz", - "integrity": "sha512-AQC0Dyhzn4EiYEfIUjCdMl0JJ61I2ER9ukf/sLxJUcZHfo+VyEfz2rMJgLZSS1v30OxPQe1cN0LZA1xbcaVfWA==", + "version": "1.2.0", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -6951,8 +5155,7 @@ }, "npmlog": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -6964,46 +5167,38 @@ }, "number-is-nan": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true, - "optional": true + "bundled": true, + "dev": true }, "object-assign": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "bundled": true, "dev": true, "optional": true }, "once": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "bundled": true, "dev": true, - "optional": true, "requires": { "wrappy": "1" } }, "os-homedir": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "bundled": true, "dev": true, "optional": true }, "os-tmpdir": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "bundled": true, "dev": true, "optional": true }, "osenv": { "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -7013,26 +5208,23 @@ }, "path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "bundled": true, "dev": true, "optional": true }, "process-nextick-args": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "bundled": true, "dev": true, "optional": true }, "rc": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.7.tgz", - "integrity": "sha512-LdLD8xD4zzLsAT5xyushXDNscEjB7+2ulnl8+r1pnESlYtlJtVSoCMBGr30eDRJ3+2Gq89jK9P9e4tCEH1+ywA==", + "version": "1.2.8", + "bundled": true, "dev": true, "optional": true, "requires": { - "deep-extend": "^0.5.1", + "deep-extend": "^0.6.0", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" @@ -7040,8 +5232,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "bundled": true, "dev": true, "optional": true } @@ -7049,8 +5240,7 @@ }, "readable-stream": { "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -7064,63 +5254,53 @@ } }, "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "version": "2.6.3", + "bundled": true, "dev": true, "optional": true, "requires": { - "glob": "^7.0.5" + "glob": "^7.1.3" } }, "safe-buffer": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", - "dev": true, - "optional": true + "version": "5.1.2", + "bundled": true, + "dev": true }, "safer-buffer": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "bundled": true, "dev": true, "optional": true }, "sax": { "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "bundled": true, "dev": true, "optional": true }, "semver": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "version": "5.6.0", + "bundled": true, "dev": true, "optional": true }, "set-blocking": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "bundled": true, "dev": true, "optional": true }, "signal-exit": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "bundled": true, "dev": true, "optional": true }, "string-width": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "bundled": true, "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -7129,8 +5309,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -7139,67 +5318,57 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "bundled": true, "dev": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } }, "strip-json-comments": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "bundled": true, "dev": true, "optional": true }, "tar": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.1.tgz", - "integrity": "sha512-O+v1r9yN4tOsvl90p5HAP4AEqbYhx4036AGMm075fH9F8Qwi3oJ+v4u50FkT/KkvywNGtwkk0zRI+8eYm1X/xg==", + "version": "4.4.8", + "bundled": true, "dev": true, "optional": true, "requires": { - "chownr": "^1.0.1", + "chownr": "^1.1.1", "fs-minipass": "^1.2.5", - "minipass": "^2.2.4", - "minizlib": "^1.1.0", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.1", + "safe-buffer": "^5.1.2", "yallist": "^3.0.2" } }, "util-deprecate": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "bundled": true, "dev": true, "optional": true }, "wide-align": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz", - "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==", + "version": "1.1.3", + "bundled": true, "dev": true, "optional": true, "requires": { - "string-width": "^1.0.2" + "string-width": "^1.0.2 || 2" } }, "wrappy": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true, - "optional": true + "bundled": true, + "dev": true }, "yallist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.2.tgz", - "integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=", - "dev": true, - "optional": true + "version": "3.0.3", + "bundled": true, + "dev": true } } }, @@ -7258,9 +5427,9 @@ "dev": true }, "gensequence": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/gensequence/-/gensequence-2.1.1.tgz", - "integrity": "sha512-AyZrG5Qq8Tn0qnaDCnH2n9TsWnJLKBXEa2FcUlHWfEgl1rRS3MbcvB4OsarxyEekx/PwYlyKXvjQwNvYsByXAw==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/gensequence/-/gensequence-2.1.2.tgz", + "integrity": "sha512-TH0HcxnR7gpvpdMbiQ7+mL10Vf+9zekenuaSmUl7dHWzzeiiaCelk3Xv3V2ebrsVMLfi1KJ8Q0CpGthaxiM9zQ==", "dev": true }, "get-caller-file": { @@ -7300,20 +5469,12 @@ "dev": true, "requires": { "assert-plus": "^1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } } }, "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -7332,15 +5493,53 @@ "requires": { "glob-parent": "^2.0.0", "is-glob": "^2.0.0" + }, + "dependencies": { + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dev": true, + "requires": { + "is-glob": "^2.0.0" + } + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + } + } } }, "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", "dev": true, "requires": { - "is-glob": "^2.0.0" + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } } }, "global-dirs": { @@ -7403,9 +5602,9 @@ } }, "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", "dev": true }, "hammerjs": { @@ -7420,87 +5619,50 @@ "dev": true }, "handlebars": { - "version": "4.0.11", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.11.tgz", - "integrity": "sha1-Ywo13+ApS8KB7a5v/F0yn8eYLcw=", + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.12.tgz", + "integrity": "sha512-RhmTekP+FZL+XNhwS1Wf+bTTZpdLougwt5pcgA1tuz6Jcx0fpH/7z0qd71RKnZHBCxIRBHfBOnio4gViPemNzA==", "dev": true, "requires": { - "async": "^1.4.0", + "async": "^2.5.0", "optimist": "^0.6.1", - "source-map": "^0.4.4", - "uglify-js": "^2.6" + "source-map": "^0.6.1", + "uglify-js": "^3.1.4" }, "dependencies": { "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true - }, - "camelcase": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", - "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", + "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", "dev": true, - "optional": true - }, - "cliui": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", - "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", - "dev": true, - "optional": true, "requires": { - "center-align": "^0.1.1", - "right-align": "^0.1.1", - "wordwrap": "0.0.2" + "lodash": "^4.17.10" } }, "source-map": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", - "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", - "dev": true, - "requires": { - "amdefine": ">=0.0.4" - } - }, - "uglify-js": { - "version": "2.8.29", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", - "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", - "dev": true, - "optional": true, - "requires": { - "source-map": "~0.5.1", - "uglify-to-browserify": "~1.0.0", - "yargs": "~3.10.0" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true, - "optional": true - } - } - }, - "yargs": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", - "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", - "dev": true, - "optional": true, - "requires": { - "camelcase": "^1.0.2", - "cliui": "^2.1.0", - "decamelize": "^1.0.0", - "window-size": "0.1.0" - } + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true } } }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "dev": true, + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, "has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", @@ -7554,14 +5716,6 @@ "get-value": "^2.0.6", "has-values": "^1.0.0", "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } } }, "has-values": { @@ -7574,26 +5728,6 @@ "kind-of": "^4.0.0" }, "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, "kind-of": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", @@ -7724,6 +5858,23 @@ "requires": { "agent-base": "4", "debug": "3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } } }, "http-proxy-middleware": { @@ -7736,306 +5887,17 @@ "is-glob": "^4.0.0", "lodash": "^4.17.5", "micromatch": "^3.1.9" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": 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" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", - "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - } + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" } }, "https-browserify": { @@ -8064,17 +5926,25 @@ } }, "hunspell-reader": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/hunspell-reader/-/hunspell-reader-2.0.3.tgz", - "integrity": "sha512-TYztrMmCOuz/HI2BluZBprWvfqCcQXNErj2ZqJjR/zGWkXkhVwqgcdiW7T8HCHnGQDlV3RuuRlkRcfyo0W9kdQ==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/hunspell-reader/-/hunspell-reader-2.1.2.tgz", + "integrity": "sha512-RuaK4dpY1iUIazNxQcqSA5d5B0vcih0JPsb2X87nwxjqWSlM5fnckSVC9vLYrKddF/PL53fH9nQOqoHKvFndxg==", "dev": true, "requires": { - "commander": "^2.15.1", - "cspell-lib": "^3.0.2", - "fs-extra": "^5.0.0", - "gensequence": "^2.1.1", - "rxjs": "^6.2.0", - "rxjs-stream": "^2.0.3" + "commander": "^2.19.0", + "cspell-lib": "^3.0.5", + "fs-extra": "^7.0.1", + "gensequence": "^2.1.2", + "rxjs": "^6.3.3", + "rxjs-stream": "^3.0.1" + }, + "dependencies": { + "commander": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", + "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", + "dev": true + } } }, "iconv-lite": { @@ -8135,6 +6005,16 @@ "import-from": "^2.1.0" } }, + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + } + }, "import-from": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz", @@ -8397,6 +6277,17 @@ "dev": true, "requires": { "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } } }, "is-arrayish": { @@ -8445,6 +6336,17 @@ "dev": true, "requires": { "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } } }, "is-descriptor": { @@ -8494,9 +6396,9 @@ "dev": true }, "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true }, "is-finite": { @@ -8518,12 +6420,12 @@ } }, "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", + "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", "dev": true, "requires": { - "is-extglob": "^1.0.0" + "is-extglob": "^2.1.1" } }, "is-installed-globally": { @@ -8549,12 +6451,23 @@ "dev": true }, "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } } }, "is-obj": { @@ -8603,14 +6516,6 @@ "dev": true, "requires": { "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } } }, "is-posix-bracket": { @@ -8694,9 +6599,9 @@ } }, "isemail": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/isemail/-/isemail-3.1.3.tgz", - "integrity": "sha512-5xbsG5wYADIcB+mfLsd+nst1V/D+I7EU7LEZPo2GOIMu4JzfcRs5yQoypP4avA7QtUqgxYLKBYNv4IdzBmbhdw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/isemail/-/isemail-3.2.0.tgz", + "integrity": "sha512-zKqkK+O+dGqevc93KNsbZ/TqTUFd46MwWjYOoMrjIMZ51eU7DtQG3Wmd9SQQT7i7RVnuTPEiYEWHU3MSbxC1Tg==", "dev": true, "requires": { "punycode": "2.x.x" @@ -8709,13 +6614,10 @@ "dev": true }, "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true }, "isstream": { "version": "0.1.2", @@ -8745,12 +6647,6 @@ "wordwrap": "^1.0.0" }, "dependencies": { - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true - }, "glob": { "version": "5.0.15", "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", @@ -8766,14 +6662,8 @@ }, "has-flag": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", - "dev": true - }, - "resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", "dev": true }, "supports-color": { @@ -8784,33 +6674,37 @@ "requires": { "has-flag": "^1.0.0" } - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true } } }, "istanbul-api": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-1.3.1.tgz", - "integrity": "sha512-duj6AlLcsWNwUpfyfHt0nWIeRiZpuShnP40YTxOGQgtaN8fd6JYSxsvxUphTDy8V5MfDXo4s/xVCIIvVCO808g==", + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-1.3.7.tgz", + "integrity": "sha512-4/ApBnMVeEPG3EkSzcw25wDe4N66wxwn+KKn6b47vyek8Xb3NBAcg4xfuQbS7BqcZuTX4wxfD5lVagdggR3gyA==", "dev": true, "requires": { "async": "^2.1.4", - "compare-versions": "^3.1.0", "fileset": "^2.0.2", - "istanbul-lib-coverage": "^1.2.0", - "istanbul-lib-hook": "^1.2.0", - "istanbul-lib-instrument": "^1.10.1", - "istanbul-lib-report": "^1.1.4", - "istanbul-lib-source-maps": "^1.2.4", - "istanbul-reports": "^1.3.0", + "istanbul-lib-coverage": "^1.2.1", + "istanbul-lib-hook": "^1.2.2", + "istanbul-lib-instrument": "^1.10.2", + "istanbul-lib-report": "^1.1.5", + "istanbul-lib-source-maps": "^1.2.6", + "istanbul-reports": "^1.5.1", "js-yaml": "^3.7.0", "mkdirp": "^0.5.1", "once": "^1.4.0" + }, + "dependencies": { + "async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", + "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", + "dev": true, + "requires": { + "lodash": "^4.17.10" + } + } } }, "istanbul-instrumenter-loader": { @@ -8861,24 +6755,24 @@ } }, "istanbul-lib-coverage": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.0.tgz", - "integrity": "sha512-GvgM/uXRwm+gLlvkWHTjDAvwynZkL9ns15calTrmhGgowlwJBbWMYzWbKqE2DT6JDP1AFXKa+Zi0EkqNCUqY0A==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.1.tgz", + "integrity": "sha512-PzITeunAgyGbtY1ibVIUiV679EFChHjoMNRibEIobvmrCRaIgwLxNucOSimtNWUhEib/oO7QY2imD75JVgCJWQ==", "dev": true }, "istanbul-lib-hook": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-1.2.1.tgz", - "integrity": "sha512-eLAMkPG9FU0v5L02lIkcj/2/Zlz9OuluaXikdr5iStk8FDbSwAixTK9TkYxbF0eNnzAJTwM2fkV2A1tpsIp4Jg==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-1.2.2.tgz", + "integrity": "sha512-/Jmq7Y1VeHnZEQ3TL10VHyb564mn6VrQXHchON9Jf/AEcmQ3ZIiyD1BVzNOKTZf/G3gE+kiGK6SmpF9y3qGPLw==", "dev": true, "requires": { - "append-transform": "^1.0.0" + "append-transform": "^0.4.0" } }, "istanbul-lib-instrument": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.1.tgz", - "integrity": "sha512-1dYuzkOCbuR5GRJqySuZdsmsNKPL3PTuyPevQfoCXJePT9C8y1ga75neU+Tuy9+yS3G/dgx8wgOmp2KLpgdoeQ==", + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.2.tgz", + "integrity": "sha512-aWHxfxDqvh/ZlxR8BBaEPVSWDPUkGD63VjGQn3jcw8jCp7sHEMKcrj4xfJn/ABzdMEHiQNyvDQhqm5o8+SQg7A==", "dev": true, "requires": { "babel-generator": "^6.18.0", @@ -8886,17 +6780,17 @@ "babel-traverse": "^6.18.0", "babel-types": "^6.18.0", "babylon": "^6.18.0", - "istanbul-lib-coverage": "^1.2.0", + "istanbul-lib-coverage": "^1.2.1", "semver": "^5.3.0" } }, "istanbul-lib-report": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-1.1.4.tgz", - "integrity": "sha512-Azqvq5tT0U09nrncK3q82e/Zjkxa4tkFZv7E6VcqP0QCPn6oNljDPfrZEC/umNXds2t7b8sRJfs6Kmpzt8m2kA==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-1.1.5.tgz", + "integrity": "sha512-UsYfRMoi6QO/doUshYNqcKJqVmFe9w51GZz8BS3WB0lYxAllQYklka2wP9+dGZeHYaWIdcXUx8JGdbqaoXRXzw==", "dev": true, "requires": { - "istanbul-lib-coverage": "^1.2.0", + "istanbul-lib-coverage": "^1.2.1", "mkdirp": "^0.5.1", "path-parse": "^1.0.5", "supports-color": "^3.1.2" @@ -8920,22 +6814,30 @@ } }, "istanbul-lib-source-maps": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.5.tgz", - "integrity": "sha512-8O2T/3VhrQHn0XcJbP1/GN7kXMiRAlPi+fj3uEHrjBD8Oz7Py0prSC25C09NuAZS6bgW1NNKAvCSHZXB0irSGA==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.6.tgz", + "integrity": "sha512-TtbsY5GIHgbMsMiRw35YBHGpZ1DVFEO19vxxeiDMYaeOFOCzfnYVxvl6pOUIZR4dtPhAGpSMup8OyF8ubsaqEg==", "dev": true, "requires": { "debug": "^3.1.0", - "istanbul-lib-coverage": "^1.2.0", + "istanbul-lib-coverage": "^1.2.1", "mkdirp": "^0.5.1", "rimraf": "^2.6.1", "source-map": "^0.5.3" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } } }, "istanbul-reports": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-1.3.0.tgz", - "integrity": "sha512-y2Z2IMqE1gefWUaVjrBm0mSKvUkaBy9Vqz8iwr/r40Y9hBbIteH5wqHG/9DLTfJ9xUnUT2j7A3+VVJ6EaYBllA==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-1.5.1.tgz", + "integrity": "sha512-+cfoZ0UXzWjhAdzosCPP3AN8vvef8XDkWtTfgaN+7L3YTpNYITnCaEkceo5SEYy644VkHka/P1FvkWvrG/rrJw==", "dev": true, "requires": { "handlebars": "^4.0.3" @@ -8983,28 +6885,10 @@ "integrity": "sha1-43zwsX8ZnM4jvqcbIDk5Uka07E4=", "dev": true }, - "jest-get-type": { - "version": "22.4.3", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-22.4.3.tgz", - "integrity": "sha512-/jsz0Y+V29w1chdXVygEKSz2nBoHoYqNShPe+QgxSNjAuP1i8+k4LbQNrfoliKej0P45sivkSCh7yiD6ubHS3w==", - "dev": true - }, - "jest-validate": { - "version": "23.6.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-23.6.0.tgz", - "integrity": "sha512-OFKapYxe72yz7agrDAWi8v2WL8GIfVqcbKRCLbRG9PAxtzF9b1SEDdTpytNDN12z2fJynoBwpMpvj2R39plI2A==", - "dev": true, - "requires": { - "chalk": "^2.0.1", - "jest-get-type": "^22.1.0", - "leven": "^2.1.0", - "pretty-format": "^23.6.0" - } - }, "joi": { - "version": "13.6.0", - "resolved": "https://registry.npmjs.org/joi/-/joi-13.6.0.tgz", - "integrity": "sha512-E4QB0yRgEa6ZZKcSHJuBC+QeAwy+akCG0Bsa9edLqljyhlr+GuGDSmXYW1q7sj/FuAPy+ECUI3evVtK52tVfwg==", + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/joi/-/joi-13.7.0.tgz", + "integrity": "sha512-xuY5VkHfeOYK3Hdi91ulocfuFopwgbSORmIwzcwHKESQhC7w1kD5jaVSPnqDxS2I8t3RZ9omCKAxNwXN5zG1/Q==", "dev": true, "requires": { "hoek": "5.x.x", @@ -9013,9 +6897,9 @@ } }, "js-base64": { - "version": "2.4.8", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.8.tgz", - "integrity": "sha512-hm2nYpDrwoO/OzBhdcqs/XGT6XjSuSSCVEpia+Kl2J6x4CYt5hISlVL/AYU1khoDXv0AQVgxtdJySb9gjAn56Q==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.5.1.tgz", + "integrity": "sha512-M7kLczedRMYX4L8Mdh4MzyAMM9O5osx+4FcOQuTvr3A9F2D9S5JXheN0ewNbrvK2UatkTRhL5ejGmGSjNMiZuw==", "dev": true }, "js-tokens": { @@ -9025,9 +6909,9 @@ "dev": true }, "js-yaml": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", - "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", + "version": "3.12.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.1.tgz", + "integrity": "sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA==", "dev": true, "requires": { "argparse": "^1.0.7", @@ -9046,8 +6930,7 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true, - "optional": true + "dev": true }, "jsesc": { "version": "1.3.0", @@ -9094,9 +6977,12 @@ "dev": true }, "json5": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "requires": { + "minimist": "^1.2.0" + } }, "jsonfile": { "version": "4.0.0", @@ -9123,14 +7009,6 @@ "extsprintf": "1.3.0", "json-schema": "0.2.3", "verror": "1.10.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } } }, "jszip": { @@ -9151,430 +7029,81 @@ "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.3.0.tgz", "integrity": "sha1-+rg/uwstjchfpjbEudNMdUIMbWU=", "dev": true - }, - "es6-promise": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.0.2.tgz", - "integrity": "sha1-AQ1YWEI6XxGJeWZfRkhqlcbuK7Y=", - "dev": true - }, - "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", - "dev": true - }, - "readable-stream": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", - "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "string_decoder": "~0.10.x", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - } - } - }, - "karma": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/karma/-/karma-3.0.0.tgz", - "integrity": "sha512-ZTjyuDXVXhXsvJ1E4CnZzbCjSxD6sEdzEsFYogLuZM0yqvg/mgz+O+R1jb0J7uAQeuzdY8kJgx6hSNXLwFuHIQ==", - "dev": true, - "requires": { - "bluebird": "^3.3.0", - "body-parser": "^1.16.1", - "chokidar": "^2.0.3", - "colors": "^1.1.0", - "combine-lists": "^1.0.0", - "connect": "^3.6.0", - "core-js": "^2.2.0", - "di": "^0.0.1", - "dom-serialize": "^2.2.0", - "expand-braces": "^0.1.1", - "glob": "^7.1.1", - "graceful-fs": "^4.1.2", - "http-proxy": "^1.13.0", - "isbinaryfile": "^3.0.0", - "lodash": "^4.17.4", - "log4js": "^3.0.0", - "mime": "^2.3.1", - "minimatch": "^3.0.2", - "optimist": "^0.6.1", - "qjobs": "^1.1.4", - "range-parser": "^1.2.0", - "rimraf": "^2.6.0", - "safe-buffer": "^5.0.1", - "socket.io": "2.1.1", - "source-map": "^0.6.1", - "tmp": "0.0.33", - "useragent": "2.2.1" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": 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" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chokidar": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", - "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.0", - "braces": "^2.3.0", - "fsevents": "^1.2.2", - "glob-parent": "^3.1.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "lodash.debounce": "^4.0.8", - "normalize-path": "^2.1.1", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0", - "upath": "^1.0.5" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + }, + "es6-promise": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.0.2.tgz", + "integrity": "sha1-AQ1YWEI6XxGJeWZfRkhqlcbuK7Y=", "dev": true }, - "is-glob": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", - "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "dev": true }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "readable-stream": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", "dev": true, "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~0.10.x", + "util-deprecate": "~1.0.1" } }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, + } + } + }, + "karma": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/karma/-/karma-3.1.4.tgz", + "integrity": "sha512-31Vo8Qr5glN+dZEVIpnPCxEGleqE0EY6CtC2X9TagRV3rRQ3SNrvfhddICkJgUK3AgqpeKSZau03QumTGhGoSw==", + "dev": true, + "requires": { + "bluebird": "^3.3.0", + "body-parser": "^1.16.1", + "chokidar": "^2.0.3", + "colors": "^1.1.0", + "combine-lists": "^1.0.0", + "connect": "^3.6.0", + "core-js": "^2.2.0", + "di": "^0.0.1", + "dom-serialize": "^2.2.0", + "expand-braces": "^0.1.1", + "flatted": "^2.0.0", + "glob": "^7.1.1", + "graceful-fs": "^4.1.2", + "http-proxy": "^1.13.0", + "isbinaryfile": "^3.0.0", + "lodash": "^4.17.5", + "log4js": "^3.0.0", + "mime": "^2.3.1", + "minimatch": "^3.0.2", + "optimist": "^0.6.1", + "qjobs": "^1.1.4", + "range-parser": "^1.2.0", + "rimraf": "^2.6.0", + "safe-buffer": "^5.0.1", + "socket.io": "2.1.1", + "source-map": "^0.6.1", + "tmp": "0.0.33", + "useragent": "2.3.0" + }, + "dependencies": { "mime": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.3.1.tgz", - "integrity": "sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.0.tgz", + "integrity": "sha512-ikBcWwyqXQSHKtciCcctu9YfPbFYZ4+gbHEmE0Q8jzcTYQg5dHCr3g2wwAZjPoJfQVXZq6KXAjpXOTf5/cjT7w==", "dev": true }, "source-map": { @@ -9636,24 +7165,6 @@ "dev": true, "requires": { "source-map-support": "^0.5.5" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-support": { - "version": "0.5.10", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.10.tgz", - "integrity": "sha512-YfQ3tQFTK/yzlGJuX8pTwa4tifQj4QS2Mj7UegOu8jAz59MqIiMGPXxQhVQiIMNzayuUSF/jEuVnfFF5JqybmQ==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - } } }, "killable": { @@ -9663,13 +7174,10 @@ "dev": true }, "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true }, "klaw-sync": { "version": "6.0.0", @@ -9689,13 +7197,6 @@ "package-json": "^4.0.0" } }, - "lazy-cache": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", - "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", - "dev": true, - "optional": true - }, "lcid": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", @@ -9760,21 +7261,9 @@ "requires": { "asap": "~2.0.3" } - }, - "resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", - "dev": true } } }, - "leven": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", - "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=", - "dev": true - }, "levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", @@ -9805,15 +7294,15 @@ } }, "lint-staged": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-8.1.0.tgz", - "integrity": "sha512-yfSkyJy7EuVsaoxtUSEhrD81spdJOe/gMTGea3XaV7HyoRhTb9Gdlp6/JppRZERvKSEYXP9bjcmq6CA5oL2lYQ==", + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-8.1.3.tgz", + "integrity": "sha512-6TGkikL1B+6mIOuSNq2TV6oP21IhPMnV8q0cf9oYZ296ArTVNcbFh1l1pfVOHHbBIYLlziWNsQ2q45/ffmJ4AA==", "dev": true, "requires": { "@iamstarkov/listr-update-renderer": "0.4.1", "chalk": "^2.3.1", "commander": "^2.14.1", - "cosmiconfig": "5.0.6", + "cosmiconfig": "^5.0.2", "debug": "^3.1.0", "dedent": "^0.7.0", "del": "^3.0.0", @@ -9822,7 +7311,6 @@ "g-status": "^2.0.2", "is-glob": "^4.0.0", "is-windows": "^1.0.2", - "jest-validate": "^23.5.0", "listr": "^0.14.2", "lodash": "^4.17.5", "log-symbols": "^2.2.0", @@ -9834,56 +7322,17 @@ "please-upgrade-node": "^3.0.2", "staged-git-files": "1.1.2", "string-argv": "^0.0.2", - "stringify-object": "^3.2.2" + "stringify-object": "^3.2.2", + "yup": "^0.26.10" }, "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": 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" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, "cosmiconfig": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.0.6.tgz", - "integrity": "sha512-6DWfizHriCrFWURP1/qyhsiFvYdlJzbCzmtFWh744+KyWsJo5+kPzUZZaMRSSItoYc0pxFX7gEO7ZC1/gN/7AQ==", + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.0.7.tgz", + "integrity": "sha512-PcLqxTKiDmNT6pSpy4N6KtuPwb53W+2tzNvwOZw0WH9N6O0vLIBq0x8aj8Oj75ere4YcGi48bDFCL+3fRJdlNA==", "dev": true, "requires": { + "import-fresh": "^2.0.0", "is-directory": "^0.3.1", "js-yaml": "^3.9.0", "parse-json": "^4.0.0" @@ -9917,270 +7366,13 @@ "strip-eof": "^1.0.0" } }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", - "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" } }, "parse-json": { @@ -10298,7 +7490,7 @@ }, "supports-color": { "version": "2.0.0", - "resolved": "http://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true } @@ -10344,13 +7536,13 @@ "dev": true }, "loader-utils": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz", - "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", + "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", "requires": { - "big.js": "^3.1.3", + "big.js": "^5.2.2", "emojis-list": "^2.0.0", - "json5": "^0.5.0" + "json5": "^1.0.1" } }, "locate-path": { @@ -10364,9 +7556,9 @@ } }, "lodash": { - "version": "4.17.10", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", - "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", "dev": true }, "lodash.assign": { @@ -10463,9 +7655,9 @@ } }, "log4js": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/log4js/-/log4js-3.0.5.tgz", - "integrity": "sha512-IX5c3G/7fuTtdr0JjOT2OIR12aTESVhsH6cEsijloYwKgcPRlO6DgOU72v0UFhWcoV1HN6+M3dwT89qVPLXm0w==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-3.0.6.tgz", + "integrity": "sha512-ezXZk6oPJCWL483zj64pNkMuY/NcRX5MPiB0zE6tjZM137aeusrOnW1ecxgF9cmwMWkBMhjteQxBPoZBh9FDxQ==", "dev": true, "requires": { "circular-json": "^0.5.5", @@ -10481,13 +7673,6 @@ "integrity": "sha1-4PyVEztu8nbNyIh82vJKpvFW+Po=", "dev": true }, - "longest": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", - "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", - "dev": true, - "optional": true - }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -10514,9 +7699,9 @@ "dev": true }, "lru-cache": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", - "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", "dev": true, "requires": { "pseudomap": "^1.0.2", @@ -10524,12 +7709,12 @@ } }, "magic-string": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.1.tgz", - "integrity": "sha512-sCuTz6pYom8Rlt4ISPFn6wuFodbKMIHUMv4Qko9P17dpxb7s52KJTmRuZZqHdGmLCK9AOcDare039nRIcfdkEg==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.2.tgz", + "integrity": "sha512-iLs9mPjh9IuTtRsqqhNGYcZXGei0Nh/A4xirrsqW7c+QhKVFL2vm7U09ru6cHRD22azaP/wMDgI+HCqbETMTtg==", "dev": true, "requires": { - "sourcemap-codec": "^1.4.1" + "sourcemap-codec": "^1.4.4" } }, "make-dir": { @@ -10542,9 +7727,9 @@ } }, "make-error": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.4.tgz", - "integrity": "sha512-0Dab5btKVPhibSalc9QGXb559ED7G7iLjFXBaj9Wq8O3vorueR5K5jaE3hkG6ZQINyhA/JgG6Qk4qdFQjsYV6g==", + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", + "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", "dev": true }, "make-fetch-happen": { @@ -10566,12 +7751,6 @@ "ssri": "^6.0.0" }, "dependencies": { - "bluebird": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz", - "integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==", - "dev": true - }, "cacache": { "version": "11.3.2", "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.2.tgz", @@ -10605,26 +7784,6 @@ } } }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": 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" - } - }, - "graceful-fs": { - "version": "4.1.15", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", - "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", - "dev": true - }, "mississippi": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", @@ -10733,12 +7892,14 @@ "dev": true }, "mem": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", - "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.1.0.tgz", + "integrity": "sha512-I5u6Q1x7wxO0kdOpYBB28xueHADYps5uty/zg936CiG8NTe5sJL8EjrCuLneuDW3PlMdZBGDIn8BirEVdovZvg==", "dev": true, "requires": { - "mimic-fn": "^1.0.0" + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^1.0.0", + "p-is-promise": "^2.0.0" } }, "memory-fs": { @@ -10767,14 +7928,6 @@ "read-pkg-up": "^1.0.1", "redent": "^1.0.0", "trim-newlines": "^1.0.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } } }, "merge-descriptors": { @@ -10789,24 +7942,24 @@ "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" }, "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" } }, "miller-rabin": { @@ -10825,16 +7978,16 @@ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" }, "mime-db": { - "version": "1.35.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.35.0.tgz", - "integrity": "sha512-JWT/IcCTsB0Io3AhWUMjRqucrHSPsSf2xKLaRldJVULioggvkJvggZ3VXNNSRkCddE6D+BUI4HEIZIA2OjwIvg==" + "version": "1.37.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", + "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==" }, "mime-types": { - "version": "2.1.19", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.19.tgz", - "integrity": "sha512-P1tKYHVSZ6uFo26mtnve4HQFE3koh1UWVkp8YUC+ESBHe945xWSoXuHHiGarDqcEZ+whpCDnlNw5LON0kLo+sw==", + "version": "2.1.21", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", + "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", "requires": { - "mime-db": "~1.35.0" + "mime-db": "~1.37.0" } }, "mimic-fn": { @@ -10897,10 +8050,9 @@ } }, "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" }, "minipass": { "version": "2.3.5", @@ -10993,6 +8145,14 @@ "dev": true, "requires": { "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + } } }, "moment": { @@ -11023,9 +8183,9 @@ } }, "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" }, "multicast-dns": { "version": "6.2.3", @@ -11050,9 +8210,9 @@ "dev": true }, "nan": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", - "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.12.1.tgz", + "integrity": "sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw==", "dev": true }, "nanomatch": { @@ -11072,26 +8232,6 @@ "regex-not": "^1.0.0", "snapdragon": "^0.8.1", "to-regex": "^3.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } } }, "negotiator": { @@ -11147,354 +8287,14 @@ "update-notifier": "^2.3.0" }, "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": 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" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chokidar": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", - "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.0", - "braces": "^2.3.0", - "fsevents": "^1.2.2", - "glob-parent": "^3.1.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "lodash.debounce": "^4.0.8", - "normalize-path": "^2.1.1", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0", - "upath": "^1.0.5" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, "find-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", - "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true + "requires": { + "locate-path": "^3.0.0" + } }, "load-json-file": { "version": "4.0.0", @@ -11518,27 +8318,6 @@ "path-exists": "^3.0.0" } }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, "p-limit": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz", @@ -11708,9 +8487,9 @@ } }, "node-releases": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.6.tgz", - "integrity": "sha512-lODUVHEIZutZx+TDdOk47qLik8FJMXzJ+WnyUGci1MTvTOyzZrz5eVPIIpc5Hb3NfHZGeGHeuwrRYVI1PEITWg==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.7.tgz", + "integrity": "sha512-bKdrwaqJUPHqlCzDD7so/R+Nk0jGv9a11ZhLrD9f6i947qGLrGAhU3OxRENa19QQmwzGy/g6zCDEuLGDO8HPvA==", "dev": true, "requires": { "semver": "^5.3.0" @@ -11789,9 +8568,9 @@ } }, "normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.2.tgz", + "integrity": "sha512-YcMnjqeoUckXTPKZSAsPjUPLxH85XotbpqK3w4RyCwdFQSU5FxxBys8buehkSfg0j9fKvV1hn7O0+8reEgkAiw==", "dev": true, "requires": { "hosted-git-info": "^2.1.4", @@ -11816,9 +8595,9 @@ "dev": true }, "npm-bundled": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.5.tgz", - "integrity": "sha512-m/e6jgWu8/v5niCUKQi9qQl8QdeEduFA96xHDDzFGqly0OOjI7c+60KM/2sppfnUU9JJagf+zs+yGhqSOFj71g==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.6.tgz", + "integrity": "sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g==", "dev": true }, "npm-package-arg": { @@ -11927,6 +8706,12 @@ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", "dev": true }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -11958,6 +8743,15 @@ "requires": { "is-descriptor": "^0.1.0" } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } } } }, @@ -11968,14 +8762,6 @@ "dev": true, "requires": { "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } } }, "object.omit": { @@ -11986,6 +8772,17 @@ "requires": { "for-own": "^0.1.4", "is-extendable": "^0.1.1" + }, + "dependencies": { + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "dev": true, + "requires": { + "for-in": "^1.0.1" + } + } } }, "object.pick": { @@ -11995,14 +8792,6 @@ "dev": true, "requires": { "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } } }, "obuf": { @@ -12133,12 +8922,6 @@ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, "opn": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/opn/-/opn-4.0.2.tgz", @@ -12195,6 +8978,20 @@ "requires": { "minimist": "~0.0.1", "wordwrap": "~0.0.2" + }, + "dependencies": { + "minimist": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", + "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", + "dev": true + }, + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "dev": true + } } }, "optionator": { @@ -12209,14 +9006,6 @@ "prelude-ls": "~1.1.2", "type-check": "~0.3.2", "wordwrap": "~1.0.0" - }, - "dependencies": { - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - } } }, "original": { @@ -12366,12 +9155,6 @@ "which": "^1.3.1" }, "dependencies": { - "bluebird": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz", - "integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==", - "dev": true - }, "cacache": { "version": "11.3.2", "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.2.tgz", @@ -12403,26 +9186,6 @@ "pump": "^3.0.0" } }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": 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" - } - }, - "graceful-fs": { - "version": "4.1.15", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", - "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", - "dev": true - }, "lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -12460,12 +9223,6 @@ "once": "^1.3.1" } }, - "semver": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", - "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", - "dev": true - }, "ssri": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", @@ -12499,9 +9256,9 @@ } }, "pako": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz", - "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.8.tgz", + "integrity": "sha512-6i0HVbUfcKaTv+EG8ZTr75az7GFXcLYk9UyLEg7Notv/Ma+z/UG3TCoz6GiNeOrn1E/e63I0X/Hpw18jHOTUnA==", "dev": true }, "parallel-transform": { @@ -12539,6 +9296,23 @@ "is-dotfile": "^1.0.0", "is-extglob": "^1.0.0", "is-glob": "^2.0.0" + }, + "dependencies": { + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + } + } } }, "parse-json": { @@ -12557,10 +9331,10 @@ "dev": true }, "parse5": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", - "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", - "dev": true + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", + "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==", + "optional": true }, "parseqs": { "version": "0.0.5", @@ -12629,9 +9403,9 @@ "dev": true }, "path-parse": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", - "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", "dev": true }, "path-to-regexp": { @@ -12663,14 +9437,20 @@ } }, "pdfjs-dist": { - "version": "2.0.489", - "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-2.0.489.tgz", - "integrity": "sha1-Y+VLKSqGeQpFRpfrRNQ0e4+/rSc=", + "version": "2.0.943", + "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-2.0.943.tgz", + "integrity": "sha512-iLhNcm4XceTHRaSU5o22ZGCm4YpuW5+rf4+BJFH/feBhMQLbCGBry+Jet8Q419QDI4qgARaIQzXuiNrsNWS8Yw==", "requires": { "node-ensure": "^0.0.0", - "worker-loader": "^1.1.1" + "worker-loader": "^2.0.0" } }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", @@ -12721,12 +9501,6 @@ "mkdirp": "0.5.x" }, "dependencies": { - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true - }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -12735,6 +9509,12 @@ "requires": { "ms": "2.0.0" } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true } } }, @@ -12745,14 +9525,14 @@ "dev": true }, "postcss": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.5.tgz", - "integrity": "sha512-HBNpviAUFCKvEh7NZhw1e8MBPivRszIiUnhrJ+sBFVSYSqubrzwX3KG51mYgcRHX8j/cAgZJedONZcm5jTBdgQ==", + "version": "7.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.14.tgz", + "integrity": "sha512-NsbD6XUUMZvBxtQAJuWDJeeC4QFsmWsfozWxCJPWf3M55K9iu2iMDaKqyoOdTJ1R4usBXuxlVFAIo8rZPQD4Bg==", "dev": true, "requires": { - "chalk": "^2.4.1", + "chalk": "^2.4.2", "source-map": "^0.6.1", - "supports-color": "^5.5.0" + "supports-color": "^6.1.0" }, "dependencies": { "source-map": { @@ -12760,15 +9540,6 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } } } }, @@ -12898,29 +9669,11 @@ "dev": true }, "prettier": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.16.0.tgz", - "integrity": "sha512-MCBCYeAuZfejUPdEpkleLWvpRBwLii/Sp5jQs0eb8Ul/drGIDjkL6tAU24tk6yCGf0KPV5rhPPPlczfBmN2pWQ==", + "version": "1.16.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.16.4.tgz", + "integrity": "sha512-ZzWuos7TI5CKUeQAtFd6Zhm2s6EpAD/ZLApIhsF9pRvRtM1RFo61dM/4MSRUA0SuLugA/zgrZD8m0BaY46Og7g==", "dev": true }, - "pretty-format": { - "version": "23.6.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-23.6.0.tgz", - "integrity": "sha512-zf9NV1NSlDLDjycnwm6hpFATCGl/K1lt0R/GdkAK2O5LN/rwJoB+Mh93gGJjut4YbmecbfgLWVGSTCr0Ewvvbw==", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0", - "ansi-styles": "^3.2.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - } - } - }, "process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -12958,6 +9711,12 @@ "retry": "^0.10.0" } }, + "property-expr": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-1.5.1.tgz", + "integrity": "sha512-CGuc0VUTGthpJXL36ydB6jnbyOf/rAHFvmVrJlH+Rg0DqqLFQGAP6hIaxD/G0OAmBJPhXDHuEJigrp0e0wFV6g==", + "dev": true + }, "protoduck": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/protoduck/-/protoduck-5.0.1.tgz", @@ -12968,12 +9727,11 @@ } }, "protractor": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/protractor/-/protractor-5.4.0.tgz", - "integrity": "sha512-6TSYqMhUUzxr4/wN0ttSISqPMKvcVRXF4k8jOEpGWD8OioLak4KLgfzHK9FJ49IrjzRrZ+Mx1q2Op8Rk0zEcnQ==", + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/protractor/-/protractor-5.4.2.tgz", + "integrity": "sha512-zlIj64Cr6IOWP7RwxVeD8O4UskLYPoyIcg0HboWJL9T79F1F0VWtKkGTr/9GN6BKL+/Q/GmM7C9kFVCfDbP5sA==", "dev": true, "requires": { - "@types/node": "^6.0.46", "@types/q": "^0.0.32", "@types/selenium-webdriver": "^3.0.0", "blocking-proxy": "^1.0.0", @@ -12987,16 +9745,10 @@ "saucelabs": "^1.5.0", "selenium-webdriver": "3.6.0", "source-map-support": "~0.4.0", - "webdriver-js-extender": "2.0.0", + "webdriver-js-extender": "2.1.0", "webdriver-manager": "^12.0.6" }, "dependencies": { - "@types/node": { - "version": "6.0.117", - "resolved": "https://registry.npmjs.org/@types/node/-/node-6.0.117.tgz", - "integrity": "sha512-sihk0SnN8PpiS5ihu5xJQ5ddnURNq4P+XPmW+nORlKkHy21CoZO/IVHK/Wq/l3G8fFW06Fkltgnqx229uPlnRg==", - "dev": true - }, "ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", @@ -13045,24 +9797,12 @@ "pinkie-promise": "^2.0.0" } }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true }, - "q": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz", - "integrity": "sha1-VXBbzZPF82c1MMLCy8DCs63cKG4=", - "dev": true - }, "selenium-webdriver": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-3.6.0.tgz", @@ -13075,6 +9815,21 @@ "xml2js": "^0.4.17" } }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-support": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", + "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "dev": true, + "requires": { + "source-map": "^0.5.6" + } + }, "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", @@ -13091,9 +9846,9 @@ } }, "webdriver-manager": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/webdriver-manager/-/webdriver-manager-12.1.0.tgz", - "integrity": "sha512-oEc5fmkpz6Yh6udhwir5m0eN5mgRPq9P/NU5YWuT3Up5slt6Zz+znhLU7q4+8rwCZz/Qq3Fgpr/4oao7NPCm2A==", + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/webdriver-manager/-/webdriver-manager-12.1.1.tgz", + "integrity": "sha512-L9TEQmZs6JbMMRQI1w60mfps265/NCr0toYJl7p/R2OAk6oXAfwI6jqYP7EWae+d7Ad2S2Aj4+rzxoSjqk3ZuA==", "dev": true, "requires": { "adm-zip": "^0.4.9", @@ -13128,21 +9883,10 @@ "uuid": "^3.1.0" }, "dependencies": { - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", "dev": true } } @@ -13170,9 +9914,9 @@ "dev": true }, "psl": { - "version": "1.1.29", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz", - "integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==", + "version": "1.1.31", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", + "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==", "dev": true }, "public-encrypt": { @@ -13216,9 +9960,9 @@ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz", + "integrity": "sha1-VXBbzZPF82c1MMLCy8DCs63cKG4=", "dev": true }, "qjobs": { @@ -13228,9 +9972,9 @@ "dev": true }, "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.6.0.tgz", + "integrity": "sha512-KIJqT9jQJDQx5h5uAVPimw6yVg2SekOKu959OCtktD3FjzbpvaPr8i4zzg07DOMz+igA4W/aNM7OV8H37pFYfA==" }, "querystring": { "version": "0.2.0", @@ -13266,12 +10010,6 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true } } }, @@ -13301,47 +10039,15 @@ "dev": true }, "raw-body": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", - "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", + "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", "dev": true, "requires": { "bytes": "3.0.0", - "http-errors": "1.6.2", - "iconv-lite": "0.4.19", + "http-errors": "1.6.3", + "iconv-lite": "0.4.23", "unpipe": "1.0.0" - }, - "dependencies": { - "depd": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", - "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=", - "dev": true - }, - "http-errors": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", - "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", - "dev": true, - "requires": { - "depd": "1.1.1", - "inherits": "2.0.3", - "setprototypeof": "1.0.3", - "statuses": ">= 1.3.1 < 2" - } - }, - "iconv-lite": { - "version": "0.4.19", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", - "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", - "dev": true - }, - "setprototypeof": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", - "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=", - "dev": true - } } }, "raw-loader": { @@ -13377,14 +10083,6 @@ "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } } }, "read-cache": { @@ -13480,15 +10178,14 @@ } }, "readdirp": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", - "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "minimatch": "^3.0.2", - "readable-stream": "^2.0.2", - "set-immediate-shim": "^1.0.1" + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" } }, "rechoir": { @@ -13607,9 +10304,9 @@ "dev": true }, "repeat-element": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", - "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", "dev": true }, "repeat-string": { @@ -13648,109 +10345,18 @@ "mime-types": "~2.1.19", "oauth-sign": "~0.9.0", "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "dependencies": { - "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", - "dev": true, - "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", - "dev": true - }, - "fast-deep-equal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", - "dev": true - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true - }, - "har-validator": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.0.tgz", - "integrity": "sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA==", - "dev": true, - "requires": { - "ajv": "^5.3.0", - "har-schema": "^2.0.0" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", - "dev": true - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", "dev": true - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "dev": true, - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - } } } }, @@ -13779,13 +10385,10 @@ "dev": true }, "resolve": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", - "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==", - "dev": true, - "requires": { - "path-parse": "^1.0.5" - } + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true }, "resolve-cwd": { "version": "2.0.0", @@ -13836,16 +10439,6 @@ "integrity": "sha512-92ktAgvZhBzYTIK0Mja9uen5q5J3NRVMoDkJL2VMwq6SXjVCgqvQeVP2XAaUY6HT+XpQYeLSjb3UoitBryKmdA==", "dev": true }, - "right-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", - "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", - "dev": true, - "optional": true, - "requires": { - "align-text": "^0.1.1" - } - }, "rimraf": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", @@ -13885,6 +10478,17 @@ "magic-string": "^0.25.1", "resolve": "^1.8.1", "rollup-pluginutils": "^2.3.3" + }, + "dependencies": { + "resolve": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", + "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + } } }, "rollup-plugin-json": { @@ -13912,6 +10516,15 @@ "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.0.0.tgz", "integrity": "sha512-hMIeU4K2ilbXV6Uv93ZZ0Avg/M91RaKXucQ+4me2Do1txxBDyDZWCBa5bJSLqoNTRpXTLwEzIk1KmloenDDjhg==", "dev": true + }, + "resolve": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", + "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } } } }, @@ -13933,6 +10546,97 @@ "requires": { "estree-walker": "^0.5.2", "micromatch": "^2.3.11" + }, + "dependencies": { + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true, + "requires": { + "arr-flatten": "^1.0.1" + } + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true, + "requires": { + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" + } + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": true, + "requires": { + "is-posix-bracket": "^0.1.0" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + } + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true, + "requires": { + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" + } + } } }, "run-async": { @@ -13968,15 +10672,15 @@ } }, "rxjs-stream": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/rxjs-stream/-/rxjs-stream-2.0.3.tgz", - "integrity": "sha512-i8sN1i6hld1n0gK8pJEtJIERwz5MgpRvVx3US9tPG1ynJSonFq/VlRx2DFSx0zTyhE4Vl96/rIYSZ6lJdP810g==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/rxjs-stream/-/rxjs-stream-3.0.1.tgz", + "integrity": "sha512-KZ+B7MWw2mygAsLJJ+mjYkCXHtSeYRXWhUVQBQRX4NgBmEiAEGAmVz7epY+8Gj0REL22W0T8ZbysFbzI/76ikA==", "dev": true }, "rxjs-tslint-rules": { - "version": "4.16.1", - "resolved": "https://registry.npmjs.org/rxjs-tslint-rules/-/rxjs-tslint-rules-4.16.1.tgz", - "integrity": "sha512-SRNXpBhdi9OL5Wc8KXcN34evf9sTJR+8NAjBJne6d5tYaoqgJhy7MmswVwjlwc/xBzdvcpoEaaVtYUu2py/vBA==", + "version": "4.16.2", + "resolved": "https://registry.npmjs.org/rxjs-tslint-rules/-/rxjs-tslint-rules-4.16.2.tgz", + "integrity": "sha512-yX/rG/aqjIZNTv6Ugq9ST43IV+g2a3JY3YwWTA8Q7VY+jGRhoILLWJbvJlL5gwmeT4HZXybpVGEBsZU4NPx15g==", "dev": true, "requires": { "@phenomnomnominal/tsquery": "^3.0.0", @@ -13995,20 +10699,14 @@ "xregexp": "4.0.0" } }, - "tsutils": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.7.0.tgz", - "integrity": "sha512-n+e+3q7Jx2kfZw7tjfI9axEIWBY0sFMOlC+1K70X0SeXpO/UYSB+PN+E9tIJNqViB7oiXQdqD7dNchnvoneZew==", + "resolve": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", + "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", "dev": true, "requires": { - "tslib": "^1.8.1" + "path-parse": "^1.0.6" } - }, - "xregexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.0.0.tgz", - "integrity": "sha512-PHyM+sQouu7xspQQwELlGwwd05mXUFqwFYfqPO0cC7x4fxyHnnuetmQr6CjJiafIDoH4MogHb9dOoJzR/Y4rFg==", - "dev": true } } }, @@ -14074,9 +10772,9 @@ "dev": true }, "schema-utils": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.5.tgz", - "integrity": "sha512-yYrjb9TX2k/J1Y5UNy3KYdZq10xhYcF8nMpAW6o3hy6Q8WSIEf9lJHG/ePnOBfziPM3fvQwfOwa13U/Fh8qTfA==", + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", + "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", "requires": { "ajv": "^6.1.0", "ajv-keywords": "^3.1.0" @@ -14148,9 +10846,9 @@ } }, "semver": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", "dev": true }, "semver-compare": { @@ -14221,6 +10919,12 @@ "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true } } }, @@ -14253,6 +10957,12 @@ "requires": { "ms": "2.0.0" } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true } } }, @@ -14274,12 +10984,6 @@ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, - "set-immediate-shim": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", - "dev": true - }, "set-value": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", @@ -14393,12 +11097,6 @@ "requires": { "ms": "^2.1.1" } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true } } }, @@ -14410,7 +11108,7 @@ }, "slice-ansi": { "version": "0.0.4", - "resolved": "http://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", "dev": true }, @@ -14462,6 +11160,18 @@ "requires": { "is-extendable": "^0.1.0" } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true } } }, @@ -14513,18 +11223,6 @@ "is-data-descriptor": "^1.0.0", "kind-of": "^6.0.2" } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true } } }, @@ -14535,6 +11233,17 @@ "dev": true, "requires": { "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } } }, "socket.io": { @@ -14549,6 +11258,23 @@ "socket.io-adapter": "~1.1.0", "socket.io-client": "2.1.1", "socket.io-parser": "~3.2.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } } }, "socket.io-adapter": { @@ -14577,6 +11303,23 @@ "parseuri": "0.0.5", "socket.io-parser": "~3.2.0", "to-array": "0.1.4" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } } }, "socket.io-parser": { @@ -14590,11 +11333,26 @@ "isarray": "2.0.1" }, "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, "isarray": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true } } }, @@ -14622,15 +11380,6 @@ "url-parse": "^1.4.3" }, "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, "faye-websocket": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.1.tgz", @@ -14639,12 +11388,6 @@ "requires": { "websocket-driver": ">=0.5.1" } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true } } }, @@ -14675,9 +11418,9 @@ "dev": true }, "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", "dev": true }, "source-map-loader": { @@ -14688,6 +11431,17 @@ "requires": { "async": "^2.5.0", "loader-utils": "^1.1.0" + }, + "dependencies": { + "async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", + "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", + "dev": true, + "requires": { + "lodash": "^4.17.10" + } + } } }, "source-map-resolve": { @@ -14704,12 +11458,21 @@ } }, "source-map-support": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", - "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.10.tgz", + "integrity": "sha512-YfQ3tQFTK/yzlGJuX8pTwa4tifQj4QS2Mj7UegOu8jAz59MqIiMGPXxQhVQiIMNzayuUSF/jEuVnfFF5JqybmQ==", "dev": true, "requires": { - "source-map": "^0.5.6" + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } } }, "source-map-url": { @@ -14735,9 +11498,9 @@ } }, "spdx-correct": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", - "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", + "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", "dev": true, "requires": { "spdx-expression-parse": "^3.0.0", @@ -14745,9 +11508,9 @@ } }, "spdx-exceptions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz", - "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", + "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", "dev": true }, "spdx-expression-parse": { @@ -14761,9 +11524,9 @@ } }, "spdx-license-ids": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz", - "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz", + "integrity": "sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g==", "dev": true }, "spdy": { @@ -14787,12 +11550,6 @@ "requires": { "ms": "^2.1.1" } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true } } }, @@ -14819,12 +11576,6 @@ "ms": "^2.1.1" } }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, "readable-stream": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.1.1.tgz", @@ -14863,9 +11614,9 @@ "dev": true }, "sshpk": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz", - "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=", + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", "dev": true, "requires": { "asn1": "~0.2.3", @@ -14877,14 +11628,6 @@ "jsbn": "~0.1.0", "safer-buffer": "^2.0.2", "tweetnacl": "~0.14.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } } }, "ssri": { @@ -14939,9 +11682,9 @@ "dev": true }, "stdout-stream": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.0.tgz", - "integrity": "sha1-osfIWH5U2UJ+qe2zrD8s1SLfN4s=", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz", + "integrity": "sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA==", "dev": true, "requires": { "readable-stream": "^2.0.1" @@ -15164,9 +11907,9 @@ } }, "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", "dev": true, "requires": { "has-flag": "^3.0.0" @@ -15178,6 +11921,12 @@ "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", "dev": true }, + "synchronous-promise": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/synchronous-promise/-/synchronous-promise-2.0.6.tgz", + "integrity": "sha512-TyOuWLwkmtPL49LHCX1caIwHjRzcVd62+GF6h8W/jHOeZUFHpnd2XJDVuUlaTaLPH1nuu2M69mfHr5XbQJnf/g==", + "dev": true + }, "tapable": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.1.tgz", @@ -15202,40 +11951,52 @@ "dev": true, "requires": { "execa": "^0.7.0" + }, + "dependencies": { + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "dev": true, + "requires": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + } } }, "terser": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-3.14.1.tgz", - "integrity": "sha512-NSo3E99QDbYSMeJaEk9YW2lTg3qS9V0aKGlb+PlOrei1X02r1wSBHCNX/O+yeTRFSWPKPIGj6MqvvdqV4rnVGw==", + "version": "3.16.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-3.16.1.tgz", + "integrity": "sha512-JDJjgleBROeek2iBcSNzOHLKsB/MdDf+E/BOAJ0Tk9r7p9/fVobfv7LMJ/g/k3v9SXdmjZnIlFd5nfn/Rt0Xow==", "dev": true, "requires": { "commander": "~2.17.1", "source-map": "~0.6.1", - "source-map-support": "~0.5.6" + "source-map-support": "~0.5.9" }, "dependencies": { - "commander": { - "version": "2.17.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", - "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", - "dev": true - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - }, - "source-map-support": { - "version": "0.5.10", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.10.tgz", - "integrity": "sha512-YfQ3tQFTK/yzlGJuX8pTwa4tifQj4QS2Mj7UegOu8jAz59MqIiMGPXxQhVQiIMNzayuUSF/jEuVnfFF5JqybmQ==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } } } }, @@ -15255,12 +12016,6 @@ "worker-farm": "^1.5.2" }, "dependencies": { - "bluebird": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz", - "integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==", - "dev": true - }, "cacache": { "version": "11.3.2", "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.2.tgz", @@ -15303,26 +12058,6 @@ "locate-path": "^3.0.0" } }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": 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" - } - }, - "graceful-fs": { - "version": "4.1.15", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", - "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", - "dev": true - }, "locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", @@ -15444,12 +12179,12 @@ "dev": true }, "through2": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", - "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", "dev": true, "requires": { - "readable-stream": "^2.1.5", + "readable-stream": "~2.3.6", "xtend": "~4.0.1" } }, @@ -15508,6 +12243,17 @@ "dev": true, "requires": { "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } } }, "to-regex": { @@ -15530,26 +12276,47 @@ "requires": { "is-number": "^3.0.0", "repeat-string": "^1.6.1" + } + }, + "topo": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/topo/-/topo-3.0.3.tgz", + "integrity": "sha512-IgpPtvD4kjrJ7CRA3ov2FhWQADwv+Tdqbsf1ZnPUSAtCJ9e1Z44MmoSGDXGk4IppoZA7jd/QRkNddlLJWlUZsQ==", + "dev": true, + "requires": { + "hoek": "6.x.x" }, "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } + "hoek": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-6.1.2.tgz", + "integrity": "sha512-6qhh/wahGYZHFSFw12tBbJw5fsAhhwrrG/y3Cs0YMTv2WzMnL0oLPnQJjv1QJvEfylRSOFuP+xCu+tdx0tD16Q==", + "dev": true } } }, - "topo": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/topo/-/topo-3.0.0.tgz", - "integrity": "sha512-Tlu1fGlR90iCdIPURqPiufqAlCZYzLjHYVVbcFWDMcX7+tK8hdZWAfsMrD/pBul9jqHHwFjNdf1WaxA9vTRRhw==", + "toposort": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz", + "integrity": "sha1-riF2gXXRVZ1IvvNUILL0li8JwzA=", + "dev": true + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", "dev": true, "requires": { - "hoek": "5.x.x" + "psl": "^1.1.24", + "punycode": "^1.4.1" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + } } }, "tree-kill": { @@ -15571,27 +12338,12 @@ "dev": true }, "true-case-path": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.2.tgz", - "integrity": "sha1-fskRMJJHZsf1c74wIMNPj9/QDWI=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz", + "integrity": "sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew==", "dev": true, "requires": { - "glob": "^6.0.4" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } + "glob": "^7.1.2" } }, "ts-node": { @@ -15610,30 +12362,6 @@ "tsconfig": "^7.0.0", "v8flags": "^3.0.0", "yn": "^2.0.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-support": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.6.tgz", - "integrity": "sha512-N4KXEz7jcKqPf2b2vZF11lQIz9W5ZMuUcIOGj243lduidkf2fjkVKJS9vNxVWn3u/uxX38AcE8U9nnH9FPcq+g==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - } } }, "tsconfig": { @@ -15665,20 +12393,6 @@ "minimist": "^1.2.0", "mkdirp": "^0.5.1", "source-map": "^0.7.3" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true - } } }, "tslib": { @@ -15704,12 +12418,32 @@ "semver": "^5.3.0", "tslib": "^1.8.0", "tsutils": "^2.27.2" + }, + "dependencies": { + "resolve": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", + "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + } } }, "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.8.0.tgz", + "integrity": "sha512-XQdPhgcoTbCD8baXC38PQ0vpTZ8T3YrE+vR66YIj/xvDt1//8iAhafpIT/4DmvzzC1QFapEImERu48Pa01dIUA==", "dev": true, "requires": { "tslib": "^1.8.1" @@ -15734,8 +12468,7 @@ "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true, - "optional": true + "dev": true }, "type-check": { "version": "0.3.2", @@ -15763,9 +12496,9 @@ "dev": true }, "typescript": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.2.4.tgz", - "integrity": "sha512-0RNDbSdEokBeEAkgNbxJ+BLwSManFy9TeXz8uW+48j/xhEXv1ePME60olyzw2XzUqUBNAYFeJadIqAgNqIACwg==", + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.1.6.tgz", + "integrity": "sha512-tDMYfVtvpb96msS1lDX9MEdHrW4yOuZ4Kdc4Him9oU796XldPYF/t2+uKoX0BBa0hXXwDlqYQbXY5Rzjzc5hBA==", "dev": true }, "uglify-js": { @@ -15778,12 +12511,6 @@ "source-map": "~0.6.1" }, "dependencies": { - "commander": { - "version": "2.17.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", - "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", - "dev": true - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -15792,13 +12519,6 @@ } } }, - "uglify-to-browserify": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", - "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", - "dev": true, - "optional": true - }, "ultron": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", @@ -15916,12 +12636,6 @@ "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true } } }, @@ -15953,6 +12667,22 @@ "latest-version": "^3.0.0", "semver-diff": "^2.0.0", "xdg-basedir": "^3.0.0" + }, + "dependencies": { + "configstore": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz", + "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==", + "dev": true, + "requires": { + "dot-prop": "^4.1.0", + "graceful-fs": "^4.1.2", + "make-dir": "^1.0.0", + "unique-string": "^1.0.0", + "write-file-atomic": "^2.0.0", + "xdg-basedir": "^3.0.0" + } + } } }, "uri-js": { @@ -15975,543 +12705,167 @@ "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", "dev": true, "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "url-parse": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.4.tgz", - "integrity": "sha512-/92DTTorg4JjktLNLe6GPS2/RvAd/RGr6LuktmWSMLEOa6rjnlrFXNgSbSmkNvCoL2T028A0a1JaJLzRMlFoHg==", - "dev": true, - "requires": { - "querystringify": "^2.0.0", - "requires-port": "^1.0.0" - } - }, - "url-parse-lax": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", - "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", - "dev": true, - "requires": { - "prepend-http": "^1.0.1" - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "useragent": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/useragent/-/useragent-2.2.1.tgz", - "integrity": "sha1-z1k+9PLRdYdei7ZY6pLhik/QbY4=", - "dev": true, - "requires": { - "lru-cache": "2.2.x", - "tmp": "0.0.x" - }, - "dependencies": { - "lru-cache": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.2.4.tgz", - "integrity": "sha1-bGWGGb7PFAMdDQtZSxYELOTcBj0=", - "dev": true - } - } - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, - "requires": { - "inherits": "2.0.3" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", - "dev": true - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "dev": true - }, - "v8flags": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.1.tgz", - "integrity": "sha512-iw/1ViSEaff8NJ3HLyEjawk/8hjJib3E7pvG4pddVXfUg1983s3VGsiClDjhK64MQVDGqc1Q8r18S4VKQZS9EQ==", - "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1" - } - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "validate-npm-package-name": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", - "integrity": "sha1-X6kS2B630MdK/BQN5zF/DKffQ34=", - "dev": true, - "requires": { - "builtins": "^1.0.3" - } - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "dev": true - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" + "punycode": "1.3.2", + "querystring": "0.2.0" }, "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", "dev": true } } }, - "vm-browserify": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", - "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", + "url-parse": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.4.tgz", + "integrity": "sha512-/92DTTorg4JjktLNLe6GPS2/RvAd/RGr6LuktmWSMLEOa6rjnlrFXNgSbSmkNvCoL2T028A0a1JaJLzRMlFoHg==", "dev": true, "requires": { - "indexof": "0.0.1" + "querystringify": "^2.0.0", + "requires-port": "^1.0.0" } }, - "void-elements": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", - "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=", - "dev": true + "url-parse-lax": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", + "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", + "dev": true, + "requires": { + "prepend-http": "^1.0.1" + } }, - "vscode-uri": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.5.tgz", - "integrity": "sha1-O4majvccN/MFTXm9vdoxx7828g0=", + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", "dev": true }, - "wait-on": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-3.0.1.tgz", - "integrity": "sha512-lZmX4gw2qgjEkobhe5lPEYAJZuV2erI31N1+vyzCgm3CdtrJv0karckpY5jKKyfaSrIPotUroQbN/pDaNC5d8w==", + "useragent": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/useragent/-/useragent-2.3.0.tgz", + "integrity": "sha512-4AoH4pxuSvHCjqLO04sU6U/uE65BYza8l/KKBS0b0hnUPWi+cQ2BpeTEwejCSx9SPV5/U03nniDTrWx5NrmKdw==", "dev": true, "requires": { - "core-js": "^2.5.7", - "joi": "^13.0.0", - "minimist": "^1.2.0", - "request": "^2.88.0", - "rx": "^4.1.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } + "lru-cache": "4.1.x", + "tmp": "0.0.x" } }, - "watchpack": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", - "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==", + "util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", "dev": true, "requires": { - "chokidar": "^2.0.2", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": 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" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chokidar": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", - "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.0", - "braces": "^2.3.0", - "fsevents": "^1.2.2", - "glob-parent": "^3.1.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "lodash.debounce": "^4.0.8", - "normalize-path": "^2.1.1", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0", - "upath": "^1.0.5" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", - "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - } + "inherits": "2.0.3" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true + }, + "v8flags": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.2.tgz", + "integrity": "sha512-MtivA7GF24yMPte9Rp/BWGCYQNaUj86zeYxV/x2RRJMKagImbbv3u8iJC57lNhWLPcGLJmHcHmFWkNsplbbLWw==", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "validate-npm-package-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", + "integrity": "sha1-X6kS2B630MdK/BQN5zF/DKffQ34=", + "dev": true, + "requires": { + "builtins": "^1.0.3" + } + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "dev": true + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "vm-browserify": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", + "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", + "dev": true, + "requires": { + "indexof": "0.0.1" + } + }, + "void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", + "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=", + "dev": true + }, + "vscode-uri": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.6.tgz", + "integrity": "sha512-sLI2L0uGov3wKVb9EB+vIQBl9tVP90nqRvxSoJ35vI3NjxE8jfsE5DSOhWgSunHSZmKS4OCi2jrtfxK7uyp2ww==", + "dev": true + }, + "wait-on": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-3.2.0.tgz", + "integrity": "sha512-QUGNKlKLDyY6W/qHdxaRlXUAgLPe+3mLL/tRByHpRNcHs/c7dZXbu+OnJWGNux6tU1WFh/Z8aEwvbuzSAu79Zg==", + "dev": true, + "requires": { + "core-js": "^2.5.7", + "joi": "^13.0.0", + "minimist": "^1.2.0", + "request": "^2.88.0", + "rx": "^4.1.0" + } + }, + "watchpack": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", + "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==", + "dev": true, + "requires": { + "chokidar": "^2.0.2", + "graceful-fs": "^4.1.2", + "neo-async": "^2.5.0" } }, "wbuf": { @@ -16524,9 +12878,9 @@ } }, "webdriver-js-extender": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/webdriver-js-extender/-/webdriver-js-extender-2.0.0.tgz", - "integrity": "sha512-fbyKiVu3azzIc5d4+26YfuPQcFTlgFQV5yQ/0OQj4Ybkl4g1YQuIPskf5v5wqwRJhHJnPHthB6tqCjWHOKLWag==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/webdriver-js-extender/-/webdriver-js-extender-2.1.0.tgz", + "integrity": "sha512-lcUKrjbBfCK6MNsh7xaY2UAUmZwe+/ib03AjVOpFobX4O7+83BUveSrLfU0Qsyb1DaKJdQRbuU+kM9aZ6QUhiQ==", "dev": true, "requires": { "@types/selenium-webdriver": "^3.0.0", @@ -16556,321 +12910,36 @@ } } }, - "webpack": { - "version": "4.29.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.29.0.tgz", - "integrity": "sha512-pxdGG0keDBtamE1mNvT5zyBdx+7wkh6mh7uzMOo/uRQ/fhsdj5FXkh/j5mapzs060forql1oXqXN9HJGju+y7w==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/wasm-edit": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "acorn": "^6.0.5", - "acorn-dynamic-import": "^4.0.0", - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0", - "chrome-trace-event": "^1.0.0", - "enhanced-resolve": "^4.1.0", - "eslint-scope": "^4.0.0", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.3.0", - "loader-utils": "^1.1.0", - "memory-fs": "~0.4.1", - "micromatch": "^3.1.8", - "mkdirp": "~0.5.0", - "neo-async": "^2.5.0", - "node-libs-browser": "^2.0.0", - "schema-utils": "^0.4.4", - "tapable": "^1.1.0", - "terser-webpack-plugin": "^1.1.0", - "watchpack": "^1.5.0", - "webpack-sources": "^1.3.0" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": 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" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - } + "webpack": { + "version": "4.29.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.29.0.tgz", + "integrity": "sha512-pxdGG0keDBtamE1mNvT5zyBdx+7wkh6mh7uzMOo/uRQ/fhsdj5FXkh/j5mapzs060forql1oXqXN9HJGju+y7w==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.7.11", + "@webassemblyjs/helper-module-context": "1.7.11", + "@webassemblyjs/wasm-edit": "1.7.11", + "@webassemblyjs/wasm-parser": "1.7.11", + "acorn": "^6.0.5", + "acorn-dynamic-import": "^4.0.0", + "ajv": "^6.1.0", + "ajv-keywords": "^3.1.0", + "chrome-trace-event": "^1.0.0", + "enhanced-resolve": "^4.1.0", + "eslint-scope": "^4.0.0", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^2.3.0", + "loader-utils": "^1.1.0", + "memory-fs": "~0.4.1", + "micromatch": "^3.1.8", + "mkdirp": "~0.5.0", + "neo-async": "^2.5.0", + "node-libs-browser": "^2.0.0", + "schema-utils": "^0.4.4", + "tapable": "^1.1.0", + "terser-webpack-plugin": "^1.1.0", + "watchpack": "^1.5.0", + "webpack-sources": "^1.3.0" } }, "webpack-core": { @@ -16964,78 +13033,12 @@ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", "dev": true }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": 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" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chokidar": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", - "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.0", - "braces": "^2.3.0", - "fsevents": "^1.2.2", - "glob-parent": "^3.1.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "lodash.debounce": "^4.0.8", - "normalize-path": "^2.1.1", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0", - "upath": "^1.0.5" - } - }, "cliui": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", @@ -17095,166 +13098,6 @@ "strip-eof": "^1.0.0" } }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, "find-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", @@ -17273,115 +13116,18 @@ "pump": "^3.0.0" } }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, "invert-kv": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", "dev": true }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, - "is-glob": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", - "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - }, "lcid": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", @@ -17401,38 +13147,6 @@ "path-exists": "^3.0.0" } }, - "mem": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-4.1.0.tgz", - "integrity": "sha512-I5u6Q1x7wxO0kdOpYBB28xueHADYps5uty/zg936CiG8NTe5sJL8EjrCuLneuDW3PlMdZBGDIn8BirEVdovZvg==", - "dev": true, - "requires": { - "map-age-cleaner": "^0.1.1", - "mimic-fn": "^1.0.0", - "p-is-promise": "^2.0.0" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, "mime": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.0.tgz", @@ -17495,12 +13209,6 @@ "ajv-keywords": "^3.1.0" } }, - "semver": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", - "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", - "dev": true - }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", @@ -17522,6 +13230,15 @@ } } }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, "webpack-dev-middleware": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.4.0.tgz", @@ -17540,12 +13257,6 @@ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, - "xregexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.0.0.tgz", - "integrity": "sha512-PHyM+sQouu7xspQQwELlGwwd05mXUFqwFYfqPO0cC7x4fxyHnnuetmQr6CjJiafIDoH4MogHb9dOoJzR/Y4rFg==", - "dev": true - }, "yargs": { "version": "12.0.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.2.tgz", @@ -17565,6 +13276,15 @@ "y18n": "^3.2.1 || ^4.0.0", "yargs-parser": "^10.1.0" } + }, + "yargs-parser": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", + "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", + "dev": true, + "requires": { + "camelcase": "^4.1.0" + } } } }, @@ -17702,17 +13422,10 @@ } } }, - "window-size": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", - "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", - "dev": true, - "optional": true - }, "wordwrap": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", - "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", "dev": true }, "worker-farm": { @@ -17725,9 +13438,9 @@ } }, "worker-loader": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/worker-loader/-/worker-loader-1.1.1.tgz", - "integrity": "sha512-qJZLVS/jMCBITDzPo/RuweYSIG8VJP5P67mP/71alGyTZRe1LYJFdwLjLalY3T5ifx0bMDRD3OB6P2p1escvlg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/worker-loader/-/worker-loader-2.0.0.tgz", + "integrity": "sha512-tnvNp4K3KQOpfRnD20m8xltE3eWh89Ye+5oj7wXEEHKac1P4oZ6p9oTj8/8ExqoSBnk9nu5Pr4nKfQ1hn2APJw==", "requires": { "loader-utils": "^1.0.0", "schema-utils": "^0.4.0" @@ -17750,9 +13463,9 @@ "dev": true }, "write-file-atomic": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz", - "integrity": "sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.2.tgz", + "integrity": "sha512-s0b6vB3xIVRLWywa6X9TOMA7k9zio0TMOsl9ZnDkliA/cfJlpHXAscj0gbHVJiTdIuAYpIyqS5GW91fqm6gG5g==", "dev": true, "requires": { "graceful-fs": "^4.1.11", @@ -17814,9 +13527,9 @@ "dev": true }, "xregexp": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.2.0.tgz", - "integrity": "sha512-IyMa7SVe9FyT4WbQVW3b95mTLVceHhLEezQ02+QMvmIqDnKTxk0MLWIQPSW2MXAr1zQb+9yvwYhcyQULneh3wA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.0.0.tgz", + "integrity": "sha512-PHyM+sQouu7xspQQwELlGwwd05mXUFqwFYfqPO0cC7x4fxyHnnuetmQr6CjJiafIDoH4MogHb9dOoJzR/Y4rFg==", "dev": true }, "xtend": { @@ -17878,25 +13591,24 @@ "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", "dev": true - }, - "yargs-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", - "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", - "dev": true, - "requires": { - "camelcase": "^3.0.0" - } } } }, "yargs-parser": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", - "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", + "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", "dev": true, "requires": { - "camelcase": "^4.1.0" + "camelcase": "^3.0.0" + }, + "dependencies": { + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", + "dev": true + } } }, "yeast": { @@ -17911,6 +13623,20 @@ "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", "dev": true }, + "yup": { + "version": "0.26.10", + "resolved": "https://registry.npmjs.org/yup/-/yup-0.26.10.tgz", + "integrity": "sha512-keuNEbNSnsOTOuGCt3UJW69jDE3O4P+UHAakO7vSeFMnjaitcmlbij/a3oNb9g1Y1KvSKH/7O1R2PQ4m4TRylw==", + "dev": true, + "requires": { + "@babel/runtime": "7.0.0", + "fn-name": "~2.0.1", + "lodash": "^4.17.10", + "property-expr": "^1.5.0", + "synchronous-promise": "^2.0.5", + "toposort": "^2.0.2" + } + }, "zone.js": { "version": "0.8.29", "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.8.29.tgz", diff --git a/package.json b/package.json index 8731635c79..f809c9d4ad 100644 --- a/package.json +++ b/package.json @@ -102,7 +102,7 @@ "tsickle": "0.34.0", "tslib": "^1.9.0", "tslint": "~5.11.0", - "typescript": "^3.2.4", + "typescript": "3.1.6", "wait-on": "^3.0.1" }, "lint-staged": { From f7ed576847e7b30de6a80b5f07b525cc3fa22e10 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Tue, 5 Feb 2019 13:12:09 +0000 Subject: [PATCH 038/259] [ACA-2168] auto-generate licenses for docker image (#918) * auto-generate licenses for docker image * update version label * make app agnostic --- Dockerfile | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index bf3087e396..68bcbbd480 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,17 @@ +# 1. Generate licenses + +FROM node:11.9-alpine AS builder +WORKDIR /usr/src/alfresco +COPY package.json package.json + +RUN mkdir -p ./licenses && \ + yarn licenses list > ./licenses/licenses.txt && \ + yarn licenses generate-disclaimer > ./licenses/disclaimer.txt + +# 2. Generate image + FROM nginx:stable-alpine -LABEL version="1.4" +LABEL version="1.7" LABEL maintainer="Denys Vuika " COPY nginx.conf /etc/nginx/nginx.conf @@ -9,5 +21,6 @@ RUN chmod +x /docker-entrypoint.sh WORKDIR /usr/share/nginx/html COPY dist/app/ . +COPY --from=builder /usr/src/alfresco/licenses ./licenses ENTRYPOINT [ "/docker-entrypoint.sh" ] From 913685eb1471aee27670e013a355b9702ee317a9 Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Tue, 5 Feb 2019 20:39:11 +0200 Subject: [PATCH 039/259] [ACA-213] Edit Offline - permissions (#911) * edit offline action rules * unlock node error message * update extensions rules * lock unlock evaluators * LockNodeDirective over EditOfflineDirective * disable tests failing cause of unrelated bug * isUserWriteLockOwner over isUserWriteLock --- e2e/suites/actions/copy.test.ts | 12 ++++++--- e2e/suites/actions/move.test.ts | 12 ++++++--- .../toggle-edit-offline.component.spec.ts | 23 +++++++++++++--- .../toggle-edit-offline.component.ts | 23 +++++++++++----- src/app/directives/directives.module.ts | 4 +-- ...ve.spec.ts => lock-node.directive.spec.ts} | 12 ++++----- ...ne.directive.ts => lock-node.directive.ts} | 19 ++++++------- src/app/extensions/core.extensions.module.ts | 3 ++- .../extensions/evaluators/app.evaluators.ts | 27 ++++++++++++++++--- src/assets/app.extensions.json | 23 +++++++--------- src/assets/i18n/en.json | 1 + 11 files changed, 105 insertions(+), 54 deletions(-) rename src/app/directives/{edit-offline.directive.spec.ts => lock-node.directive.spec.ts} (92%) rename src/app/directives/{edit-offline.directive.ts => lock-node.directive.ts} (87%) diff --git a/e2e/suites/actions/copy.test.ts b/e2e/suites/actions/copy.test.ts index c1a1c97044..743dfa5b8b 100755 --- a/e2e/suites/actions/copy.test.ts +++ b/e2e/suites/actions/copy.test.ts @@ -239,7 +239,8 @@ describe('Copy content', () => { expect(await dataTable.isItemPresent(file3InFolder)).toBe(true, `${file3InFolder} not present in destination folder`); }); - it('Copy items into a library - [C280282]', async () => { + // TODO disabled until ACA-2171 is fixed + xit('Copy items into a library - [C280282]', async () => { await dataTable.selectMultipleItems([file1, folder1]); await toolbar.clickMoreActionsCopy(); await copyDialog.selectLocation('File Libraries'); @@ -323,7 +324,8 @@ describe('Copy content', () => { expect(await dataTable.isItemPresent(`${existingFile}-1.txt`)).toBe(true, `${existingFile}-1.txt not present in destination folder`); }); - it('Copy items into a library - [C291899]', async () => { + // TODO disabled until ACA-2171 is fixed + xit('Copy items into a library - [C291899]', async () => { await dataTable.selectItem(file1, source); await toolbar.clickMoreActionsCopy(); await copyDialog.selectLocation('File Libraries'); @@ -401,7 +403,8 @@ describe('Copy content', () => { expect(await dataTable.isItemPresent(`${existingFile}-1.txt`)).toBe(true, `${existingFile}-1.txt not present in destination folder`); }); - it('Copy items into a library - [C291900]', async () => { + // TODO disabled until ACA-2171 is fixed + xit('Copy items into a library - [C291900]', async () => { await dataTable.selectItem(file1, source); await toolbar.clickMoreActionsCopy(); await copyDialog.selectLocation('File Libraries'); @@ -526,7 +529,8 @@ describe('Copy content', () => { expect(await dataTable.isItemPresent(file3InFolder)).toBe(true, `${file3InFolder} not present in destination folder`); }); - it('Copy items into a library - [C291901]', async () => { + // TODO disabled until ACA-2171 is fixed + xit('Copy items into a library - [C291901]', async () => { await dataTable.selectMultipleItems([file1, folder1], source); await toolbar.clickMoreActionsCopy(); await copyDialog.selectLocation('File Libraries'); diff --git a/e2e/suites/actions/move.test.ts b/e2e/suites/actions/move.test.ts index ded079434f..c4936326b2 100755 --- a/e2e/suites/actions/move.test.ts +++ b/e2e/suites/actions/move.test.ts @@ -250,7 +250,8 @@ describe('Move content', () => { expect(await dataTable.isItemPresent(file3InFolder)).toBe(true, `${file3InFolder} not present in destination folder`); }); - it('Move items into a library - [C291969]', async () => { + // TODO disabled until ACA-2171 is fixed + xit('Move items into a library - [C291969]', async () => { await dataTable.selectMultipleItems([file4, folder2]); await toolbar.clickMoreActionsMove(); await moveDialog.selectLocation('File Libraries'); @@ -370,7 +371,8 @@ describe('Move content', () => { expect(await dataTable.isItemPresent(`${existingFile}-1.txt`)).toBe(false, `${existingFile}-1.txt is present in destination folder`); }); - it('Move items into a library - [C291971]', async () => { + // TODO disabled until ACA-2171 is fixed + xit('Move items into a library - [C291971]', async () => { await dataTable.selectItem(file4, sourceRF); await toolbar.clickMoreActionsMove(); await moveDialog.selectLocation('File Libraries'); @@ -492,7 +494,8 @@ describe('Move content', () => { expect(await dataTable.isItemPresent(`${existingFile}-1.txt`)).toBe(false, `${existingFile}-1.txt not present in destination folder`); }); - it('Move items into a library - [C291978]', async () => { + // TODO disabled until ACA-2171 is fixed + xit('Move items into a library - [C291978]', async () => { await dataTable.selectItem(file4, sourceSF); await toolbar.clickMoreActionsMove(); await moveDialog.selectLocation('File Libraries'); @@ -682,7 +685,8 @@ describe('Move content', () => { expect(await dataTable.isItemPresent(file3InFolder)).toBe(true, `${file3InFolder} not present in destination folder`); }); - it('Move items into a library - [C291979]', async () => { + // TODO disabled until ACA-2171 is fixed + xit('Move items into a library - [C291979]', async () => { await dataTable.selectMultipleItems([file4, folder2], sourceFav); await toolbar.clickMoreActionsMove(); await moveDialog.selectLocation('File Libraries'); diff --git a/src/app/components/toolbar/toggle-edit-offline/toggle-edit-offline.component.spec.ts b/src/app/components/toolbar/toggle-edit-offline/toggle-edit-offline.component.spec.ts index 85ed8d52cb..05df3af261 100644 --- a/src/app/components/toolbar/toggle-edit-offline/toggle-edit-offline.component.spec.ts +++ b/src/app/components/toolbar/toggle-edit-offline/toggle-edit-offline.component.spec.ts @@ -24,7 +24,7 @@ */ import { ToggleEditOfflineComponent } from './toggle-edit-offline.component'; -import { EditOfflineDirective } from '../../../directives/edit-offline.directive'; +import { LockNodeDirective } from '../../../directives/lock-node.directive'; import { setupTestBed, CoreModule } from '@alfresco/adf-core'; import { TestBed } from '@angular/core/testing'; import { of } from 'rxjs'; @@ -44,7 +44,7 @@ describe('ToggleEditOfflineComponent', () => { setupTestBed({ imports: [CoreModule], - declarations: [ToggleEditOfflineComponent, EditOfflineDirective], + declarations: [ToggleEditOfflineComponent, LockNodeDirective], providers: [ { provide: Store, @@ -115,12 +115,12 @@ describe('ToggleEditOfflineComponent', () => { ]); }); - it('should raise notification on error', () => { + it('should raise notification on lock error', () => { component.selection = { entry: { name: 'test' } }; - component.onError(); + component.onLockError(); fixture.detectChanges(); expect(dispatchSpy.calls.argsFor(0)).toEqual([ @@ -129,4 +129,19 @@ describe('ToggleEditOfflineComponent', () => { }) ]); }); + + it('should raise notification on unlock error', () => { + component.selection = { + entry: { name: 'test' } + }; + + component.onUnlockLockError(); + fixture.detectChanges(); + + expect(dispatchSpy.calls.argsFor(0)).toEqual([ + new SnackbarErrorAction('APP.MESSAGES.ERRORS.UNLOCK_NODE', { + fileName: 'test' + }) + ]); + }); }); diff --git a/src/app/components/toolbar/toggle-edit-offline/toggle-edit-offline.component.ts b/src/app/components/toolbar/toggle-edit-offline/toggle-edit-offline.component.ts index 2a1f634f9c..1edc7ff6af 100644 --- a/src/app/components/toolbar/toggle-edit-offline/toggle-edit-offline.component.ts +++ b/src/app/components/toolbar/toggle-edit-offline/toggle-edit-offline.component.ts @@ -38,23 +38,24 @@ import { MinimalNodeEntity } from '@alfresco/js-api'; selector: 'app-toggle-edit-offline', template: ` + ` }) class TestComponent { - @ViewChild('editOffline') - directive: EditOfflineDirective; + @ViewChild('lock') + directive: LockNodeDirective; selection = null; } -describe('EditOfflineDirective', () => { +describe('LockNodeDirective', () => { let fixture; let api; let component; setupTestBed({ imports: [CoreModule], - declarations: [TestComponent, EditOfflineDirective], + declarations: [TestComponent, LockNodeDirective], providers: [ { provide: AlfrescoApiService, diff --git a/src/app/directives/edit-offline.directive.ts b/src/app/directives/lock-node.directive.ts similarity index 87% rename from src/app/directives/edit-offline.directive.ts rename to src/app/directives/lock-node.directive.ts index 0902c5731f..d89ae8f981 100644 --- a/src/app/directives/edit-offline.directive.ts +++ b/src/app/directives/lock-node.directive.ts @@ -34,19 +34,20 @@ import { NodeEntry, NodeBodyLock, SharedLinkEntry } from '@alfresco/js-api'; import { AlfrescoApiService } from '@alfresco/adf-core'; @Directive({ - selector: '[acaEditOffline]', - exportAs: 'editOffline' + selector: '[acaLockNode]', + exportAs: 'lockNode' }) -export class EditOfflineDirective { - @Input('acaEditOffline') +export class LockNodeDirective { + @Input('acaLockNode') node: NodeEntry = null; @Output() toggle: EventEmitter = new EventEmitter(); - @Output() error: EventEmitter = new EventEmitter(); + @Output() lockError: EventEmitter = new EventEmitter(); + @Output() unlockError: EventEmitter = new EventEmitter(); @HostListener('click') onClick() { - this.toggleEdit(this.node); + this.toggleLock(this.node); } constructor(private alfrescoApiService: AlfrescoApiService) {} @@ -59,7 +60,7 @@ export class EditOfflineDirective { ); } - private async toggleEdit(node: NodeEntry | SharedLinkEntry) { + private async toggleLock(node: NodeEntry | SharedLinkEntry) { const id = (node).entry.nodeId || node.entry.id; if (this.isNodeLocked()) { try { @@ -69,7 +70,7 @@ export class EditOfflineDirective { this.update(response.entry); this.toggle.emit(isLocked); } catch (error) { - this.error.emit(error); + this.unlockError.emit(error); } } else { try { @@ -79,7 +80,7 @@ export class EditOfflineDirective { this.update(response.entry); this.toggle.emit(isLocked); } catch (error) { - this.error.emit(error); + this.lockError.emit(error); } } } diff --git a/src/app/extensions/core.extensions.module.ts b/src/app/extensions/core.extensions.module.ts index 6379e8db59..885715d12e 100644 --- a/src/app/extensions/core.extensions.module.ts +++ b/src/app/extensions/core.extensions.module.ts @@ -111,7 +111,8 @@ export class CoreExtensionsModule { extensions.setEvaluators({ 'app.selection.canDelete': app.canDeleteSelection, - 'app.selection.canEditLockedFile': app.canEditLockedFile, + 'app.selection.canUnlockFile': app.canUnlockFile, + 'app.selection.canLockFile': app.canLockFile, 'app.selection.canDownload': app.canDownloadSelection, 'app.selection.notEmpty': app.hasSelection, 'app.selection.canUnshare': app.canUnshareNodes, diff --git a/src/app/extensions/evaluators/app.evaluators.ts b/src/app/extensions/evaluators/app.evaluators.ts index c767f9c6ec..00ae64f596 100644 --- a/src/app/extensions/evaluators/app.evaluators.ts +++ b/src/app/extensions/evaluators/app.evaluators.ts @@ -308,14 +308,35 @@ export function isWriteLocked( ); } -export function canEditLockedFile( +export function isUserWriteLockOwner( context: AppRuleContext, ...args: RuleParameter[] ): boolean { - return !!( - !isWriteLocked(context, ...args) || + return ( + isWriteLocked(context, ...args) && (context.selection.file.entry.properties['cm:lockOwner'] && context.selection.file.entry.properties['cm:lockOwner'].id === context.profile.id) ); } + +export function canLockFile( + context: AppRuleContext, + ...args: RuleParameter[] +): boolean { + return ( + !isWriteLocked(context, ...args) && canUpdateSelectedNode(context, ...args) + ); +} + +export function canUnlockFile( + context: AppRuleContext, + ...args: RuleParameter[] +): boolean { + const { file } = context.selection; + return ( + (isWriteLocked(context, ...args) && + context.permissions.check(file.entry, ['delete'])) || + isUserWriteLockOwner(context, ...args) + ); +} diff --git a/src/assets/app.extensions.json b/src/assets/app.extensions.json index 3c8f814166..cc17cc9460 100644 --- a/src/assets/app.extensions.json +++ b/src/assets/app.extensions.json @@ -166,7 +166,6 @@ "parameters": [ { "type": "rule", "value": "app.selection.file" }, { "type": "rule", "value": "app.navigation.isNotTrashcan" }, - { "type": "rule", "value": "app.selection.canEditLockedFile" }, { "type": "rule", "value": "core.not", @@ -223,25 +222,21 @@ "type": "core.every", "parameters": [ { "type": "rule", "value": "app.selection.canDelete" }, - { "type": "rule", "value": "app.selection.canEditLockedFile" }, { "type": "rule", "value": "app.navigation.isNotTrashcan" } ] }, { - "id": "app.toolbar.canEditLockedFile", + "id": "app.toolbar.canToggleLock", "type": "core.every", "parameters": [ { "type": "rule", "value": "app.selection.file" }, - { "type": "rule", "value": "app.selection.canEditLockedFile" }, { "type": "rule", "value": "app.navigation.isNotTrashcan" }, { "type": "rule", "value": "core.some", "parameters": [ - { "type": "rule", "value": "app.navigation.isPreview" }, - { "type": "rule", "value": "app.navigation.isPersonalFiles" }, - { "type": "rule", "value": "app.navigation.isLibraryFiles" }, - { "type": "rule", "value": "app.navigation.isRecentFiles" } + { "type": "rule", "value": "app.selection.canUnlockFile" }, + { "type": "rule", "value": "app.selection.canLockFile" } ] } ] @@ -533,12 +528,12 @@ "title": "APP.ACTIONS.MORE", "children": [ { - "id": "app.toolbar.toggleEditOffline", + "id": "app.toolbar.toggleLock", "order": 100, "type": "custom", "component": "app.toolbar.toggleEditOffline", "rules": { - "visible": "app.toolbar.canEditLockedFile" + "visible": "app.toolbar.canToggleLock" } }, { @@ -671,12 +666,12 @@ ], "contextMenu": [ { - "id": "app.context.toggleEditOffline", + "id": "app.context.toggleLock", "order": 100, "type": "custom", "component": "app.toolbar.toggleEditOffline", "rules": { - "visible": "app.toolbar.canEditLockedFile" + "visible": "app.toolbar.canToggleLock" } }, { @@ -970,12 +965,12 @@ "title": "APP.ACTIONS.MORE", "children": [ { - "id": "app.viewer.toggleEditOffline", + "id": "app.viewer.toggleLock", "order": 100, "type": "custom", "component": "app.toolbar.toggleEditOffline", "rules": { - "visible": "app.toolbar.canEditLockedFile" + "visible": "app.toolbar.canToggleLock" } }, { diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 2eb5aaa9e6..386a7fe687 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -254,6 +254,7 @@ "NODE_RESTORE_PLURAL": "{{ number }} items couldn't be restored", "PERMISSION": "You don't have access to do this", "LOCK_NODE": "There was a problem locking the {{ fileName }} file", + "UNLOCK_NODE": "There was a problem unlocking the {{ fileName }} file", "TRASH": { "NODES_PURGE": { "PLURAL": "{{ number }} items couldn't be deleted", From 455866a98e7c62dda1a820de3cfb3cd2690b5718 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Tue, 5 Feb 2019 20:51:13 +0000 Subject: [PATCH 040/259] fix lock icon for retina displays --- src/app/components/page.component.ts | 2 +- src/assets/images/baseline-lock-24px.svg | 1 + src/assets/images/ic_lock_black_24dp_1x.png | Bin 205 -> 0 bytes 3 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 src/assets/images/baseline-lock-24px.svg delete mode 100644 src/assets/images/ic_lock_black_24dp_1x.png diff --git a/src/app/components/page.component.ts b/src/app/components/page.component.ts index 54976879e0..9c9f406fc4 100644 --- a/src/app/components/page.component.ts +++ b/src/app/components/page.component.ts @@ -143,7 +143,7 @@ export abstract class PageComponent implements OnInit, OnDestroy { PageComponent.isLockedNode(entry) || PageComponent.isWriteLockedNode(entry) ) { - return 'assets/images/ic_lock_black_24dp_1x.png'; + return 'assets/images/baseline-lock-24px.svg'; } if (PageComponent.isLibrary(entry)) { diff --git a/src/assets/images/baseline-lock-24px.svg b/src/assets/images/baseline-lock-24px.svg new file mode 100644 index 0000000000..74ee5f04f7 --- /dev/null +++ b/src/assets/images/baseline-lock-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/ic_lock_black_24dp_1x.png b/src/assets/images/ic_lock_black_24dp_1x.png deleted file mode 100644 index 3a4a1586e538d8c74a1d8b5c653911118754ab22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_+iDV{ElAr*{gFZgpcB?z>AJbv!M zd~436r)!(~ggneO)?aecJ>>fEQ?8kl0`GmNRrfc~EjQL#xF~VUxg3rS?$;7d-fCR$ zbmv6pnkMT-N3JRqsbwGGyne#rNXpS>b-luevE5?QIXf5ef1PsX#?Ij5J%8$KEd(Y9 zwDTu1T>9Y1 Date: Thu, 7 Feb 2019 11:04:46 +0200 Subject: [PATCH 041/259] [ACA-2164] Node version action (#916) * export upload effects and actions * remove node version effect and action * remove node version theme * change old version manager implementation * get node info from store selection * upload version dialog container * node version form * update app module * upload version effect and action * update version action * internationalization * refresh on upload version * remove old implementation tests * remove adf-version-manager dialog implementation * revert adf version component * fix viewer version action --- src/app/app.module.ts | 10 ++- .../favorites/favorites.component.ts | 15 +++- .../node-version-form.component.html | 27 +++++++ .../node-version-form.component.scss | 24 ++++++ .../node-version-form.component.ts | 80 +++++++++++++++++++ .../node-version/node-version.module.ts | 57 +++++++++++++ .../recent-files/recent-files.component.ts | 14 ++++ .../shared-files/shared-files.component.ts | 9 +++ .../node-version-upload.dialog.html | 20 +++++ .../node-version-upload.dialog.scss | 11 +++ .../node-version-upload.dialog.ts | 34 ++++++++ .../node-versions/node-versions.dialog.html | 10 ++- .../services/content-management.service.ts | 26 +++++- src/app/store/actions.ts | 1 + src/app/store/actions/node.actions.ts | 12 +-- src/app/store/actions/upload.actions.ts | 5 ++ src/app/store/effects.ts | 1 + src/app/store/effects/node.effects.spec.ts | 35 +------- src/app/store/effects/node.effects.ts | 6 +- src/app/store/effects/upload.effects.ts | 71 +++++++++++++++- src/assets/app.extensions.json | 48 +++++++++-- src/assets/i18n/en.json | 21 ++++- 22 files changed, 475 insertions(+), 62 deletions(-) create mode 100644 src/app/components/node-version/node-version-form.component.html create mode 100644 src/app/components/node-version/node-version-form.component.scss create mode 100644 src/app/components/node-version/node-version-form.component.ts create mode 100644 src/app/components/node-version/node-version.module.ts create mode 100644 src/app/dialogs/node-version-upload/node-version-upload.dialog.html create mode 100644 src/app/dialogs/node-version-upload/node-version-upload.dialog.scss create mode 100644 src/app/dialogs/node-version-upload/node-version-upload.dialog.ts diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 529759f538..00797dff30 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -50,6 +50,7 @@ import { APP_ROUTES } from './app.routes'; import { FilesComponent } from './components/files/files.component'; import { LibrariesComponent } from './components/libraries/libraries.component'; import { FavoriteLibrariesComponent } from './components/favorite-libraries/favorite-libraries.component'; +import { NodeVersionUploadDialogComponent } from './dialogs/node-version-upload/node-version-upload.dialog'; import { NodeVersionsDialogComponent } from './dialogs/node-versions/node-versions.dialog'; import { AppStoreModule } from './store/app-store.module'; @@ -74,6 +75,7 @@ import { DocumentListCustomComponentsModule } from './components/dl-custom-compo import { AppSearchResultsModule } from './components/search/search-results.module'; import { AppLoginModule } from './components/login/login.module'; import { AppHeaderModule } from './components/header/header.module'; +import { AppNodeVersionModule } from './components/node-version/node-version.module'; import { environment } from '../environments/environment'; import { AppDataService } from './services/data.service'; import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; @@ -111,6 +113,7 @@ import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; AppSearchInputModule, AppSearchResultsModule, AppHeaderModule, + AppNodeVersionModule, TranslateModule.forRoot({ loader: { provide: TranslateLoader, useClass: TranslateLoaderService } }) @@ -120,6 +123,7 @@ import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; FilesComponent, LibrariesComponent, FavoriteLibrariesComponent, + NodeVersionUploadDialogComponent, NodeVersionsDialogComponent ], providers: [ @@ -135,7 +139,11 @@ import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; } } ], - entryComponents: [LibraryDialogComponent, NodeVersionsDialogComponent], + entryComponents: [ + NodeVersionsDialogComponent, + NodeVersionUploadDialogComponent, + LibraryDialogComponent + ], bootstrap: [AppComponent] }) export class AppModule {} diff --git a/src/app/components/favorites/favorites.component.ts b/src/app/components/favorites/favorites.component.ts index 99c860225a..fea7d4c51e 100644 --- a/src/app/components/favorites/favorites.component.ts +++ b/src/app/components/favorites/favorites.component.ts @@ -38,7 +38,8 @@ import { AppStore } from '../../store/states/app.state'; import { PageComponent } from '../page.component'; import { ContentApiService } from '../../services/content-api.service'; import { AppExtensionService } from '../../extensions/extension.service'; -import { map } from 'rxjs/operators'; +import { map, debounceTime } from 'rxjs/operators'; +import { FileUploadEvent, UploadService } from '@alfresco/adf-core'; @Component({ templateUrl: './favorites.component.html' @@ -54,6 +55,7 @@ export class FavoritesComponent extends PageComponent implements OnInit { extensions: AppExtensionService, private contentApi: ContentApiService, content: ContentManagementService, + private uploadService: UploadService, private breakpointObserver: BreakpointObserver ) { super(store, extensions, content); @@ -69,6 +71,13 @@ export class FavoritesComponent extends PageComponent implements OnInit { this.content.nodesMoved.subscribe(() => this.reload()), this.content.favoriteRemoved.subscribe(() => this.reload()), this.content.favoriteToggle.subscribe(() => this.reload()), + this.content.favoriteToggle.subscribe(() => this.reload()), + this.uploadService.fileUploadComplete + .pipe(debounceTime(300)) + .subscribe(file => this.onFileUploadedEvent(file)), + this.uploadService.fileUploadDeleted + .pipe(debounceTime(300)) + .subscribe(file => this.onFileUploadedEvent(file)), this.breakpointObserver .observe([Breakpoints.HandsetPortrait, Breakpoints.HandsetLandscape]) @@ -114,4 +123,8 @@ export class FavoritesComponent extends PageComponent implements OnInit { } } } + + private onFileUploadedEvent(event: FileUploadEvent) { + this.documentList.reload(); + } } diff --git a/src/app/components/node-version/node-version-form.component.html b/src/app/components/node-version/node-version-form.component.html new file mode 100644 index 0000000000..b7d265c964 --- /dev/null +++ b/src/app/components/node-version/node-version-form.component.html @@ -0,0 +1,27 @@ +
+

+ {{ 'VERSION.FORM.SUBTITLE' | translate }} +

+ + + + {{ option.label | translate }} + + + + + + +
diff --git a/src/app/components/node-version/node-version-form.component.scss b/src/app/components/node-version/node-version-form.component.scss new file mode 100644 index 0000000000..1eba72091e --- /dev/null +++ b/src/app/components/node-version/node-version-form.component.scss @@ -0,0 +1,24 @@ +.app-node-version-form__container { + display: flex; + max-width: 400px; + + .form { + width: 100%; + } + + .form__version { + display: flex; + flex-direction: column; + padding: 20px 0; + } + + .form__version--option:last-child { + padding-top: 20px; + } + + .form { + padding: 0 10px; + display: flex; + flex-direction: column; + } +} diff --git a/src/app/components/node-version/node-version-form.component.ts b/src/app/components/node-version/node-version-form.component.ts new file mode 100644 index 0000000000..5caed5ac16 --- /dev/null +++ b/src/app/components/node-version/node-version-form.component.ts @@ -0,0 +1,80 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2018 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { + Component, + OnDestroy, + OnInit, + ViewEncapsulation, + Output, + EventEmitter +} from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; + +@Component({ + selector: 'app-node-version-form', + templateUrl: './node-version-form.component.html', + styleUrls: ['./node-version-form.component.scss'], + encapsulation: ViewEncapsulation.None, + host: { class: 'app-node-version-form__container' }, + exportAs: 'nodeVersionForm' +}) +export class AppNodeVersionFormComponent implements OnInit, OnDestroy { + @Output() update: EventEmitter = new EventEmitter(); + + form: FormGroup; + + private onDestroy$: Subject = new Subject(); + private versionOptions = [ + { label: 'VERSION.FORM.VERSION.MAJOR', value: 'major' }, + { label: 'VERSION.FORM.VERSION.MINOR', value: 'minor' } + ]; + + constructor(private formBuilder: FormBuilder) {} + + ngOnInit() { + this.form = this.formBuilder.group({ + comment: ['', Validators.required], + version: [this.versionOptions[0].value] + }); + + this.form.valueChanges + .pipe(takeUntil(this.onDestroy$)) + .subscribe(values => { + this.update.emit(values); + }); + } + + get versions() { + return this.versionOptions; + } + + ngOnDestroy() { + this.onDestroy$.next(true); + this.onDestroy$.complete(); + } +} diff --git a/src/app/components/node-version/node-version.module.ts b/src/app/components/node-version/node-version.module.ts new file mode 100644 index 0000000000..d8d5672c04 --- /dev/null +++ b/src/app/components/node-version/node-version.module.ts @@ -0,0 +1,57 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2018 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { AppNodeVersionFormComponent } from './node-version-form.component'; +import { MatDialogModule } from '@angular/material/dialog'; +import { MatButtonModule } from '@angular/material/button'; + +import { CoreModule } from '@alfresco/adf-core'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { BrowserModule } from '@angular/platform-browser'; +import { CommonModule } from '@angular/common'; +import { MatRadioModule } from '@angular/material/radio'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; + +import { NgModule } from '@angular/core'; +@NgModule({ + imports: [ + CoreModule, + MatButtonModule, + MatDialogModule, + FormsModule, + ReactiveFormsModule, + BrowserModule, + CommonModule, + MatRadioModule, + MatFormFieldModule, + MatInputModule + ], + exports: [AppNodeVersionFormComponent], + declarations: [AppNodeVersionFormComponent], + providers: [], + entryComponents: [AppNodeVersionFormComponent] +}) +export class AppNodeVersionModule {} diff --git a/src/app/components/recent-files/recent-files.component.ts b/src/app/components/recent-files/recent-files.component.ts index 4e29af2445..95e4996ef9 100644 --- a/src/app/components/recent-files/recent-files.component.ts +++ b/src/app/components/recent-files/recent-files.component.ts @@ -31,6 +31,8 @@ import { PageComponent } from '../page.component'; import { Store } from '@ngrx/store'; import { AppStore } from '../../store/states/app.state'; import { AppExtensionService } from '../../extensions/extension.service'; +import { FileUploadEvent, UploadService } from '@alfresco/adf-core'; +import { debounceTime } from 'rxjs/operators'; @Component({ templateUrl: './recent-files.component.html' @@ -44,6 +46,7 @@ export class RecentFilesComponent extends PageComponent implements OnInit { store: Store, extensions: AppExtensionService, content: ContentManagementService, + private uploadService: UploadService, private breakpointObserver: BreakpointObserver ) { super(store, extensions, content); @@ -57,6 +60,13 @@ export class RecentFilesComponent extends PageComponent implements OnInit { this.content.nodesMoved.subscribe(() => this.reload()), this.content.nodesRestored.subscribe(() => this.reload()), + this.uploadService.fileUploadComplete + .pipe(debounceTime(300)) + .subscribe(file => this.onFileUploadedEvent(file)), + this.uploadService.fileUploadDeleted + .pipe(debounceTime(300)) + .subscribe(file => this.onFileUploadedEvent(file)), + this.breakpointObserver .observe([Breakpoints.HandsetPortrait, Breakpoints.HandsetLandscape]) .subscribe(result => { @@ -77,4 +87,8 @@ export class RecentFilesComponent extends PageComponent implements OnInit { this.showPreview(node); } } + + private onFileUploadedEvent(event: FileUploadEvent) { + this.documentList.reload(); + } } diff --git a/src/app/components/shared-files/shared-files.component.ts b/src/app/components/shared-files/shared-files.component.ts index 0dcacc2eb9..3808bf1626 100644 --- a/src/app/components/shared-files/shared-files.component.ts +++ b/src/app/components/shared-files/shared-files.component.ts @@ -31,6 +31,7 @@ import { Store } from '@ngrx/store'; import { AppStore } from '../../store/states/app.state'; import { AppExtensionService } from '../../extensions/extension.service'; import { debounceTime } from 'rxjs/operators'; +import { UploadService } from '@alfresco/adf-core'; @Component({ templateUrl: './shared-files.component.html' @@ -44,6 +45,7 @@ export class SharedFilesComponent extends PageComponent implements OnInit { store: Store, extensions: AppExtensionService, content: ContentManagementService, + private uploadService: UploadService, private breakpointObserver: BreakpointObserver ) { super(store, extensions, content); @@ -60,6 +62,13 @@ export class SharedFilesComponent extends PageComponent implements OnInit { .pipe(debounceTime(300)) .subscribe(() => this.reload()), + this.uploadService.fileUploadComplete + .pipe(debounceTime(300)) + .subscribe(file => this.reload()), + this.uploadService.fileUploadDeleted + .pipe(debounceTime(300)) + .subscribe(file => this.reload()), + this.breakpointObserver .observe([Breakpoints.HandsetPortrait, Breakpoints.HandsetLandscape]) .subscribe(result => { diff --git a/src/app/dialogs/node-version-upload/node-version-upload.dialog.html b/src/app/dialogs/node-version-upload/node-version-upload.dialog.html new file mode 100644 index 0000000000..fe3def10ed --- /dev/null +++ b/src/app/dialogs/node-version-upload/node-version-upload.dialog.html @@ -0,0 +1,20 @@ +

+ {{ 'VERSION.DIALOG.TITLE' | translate }} +

+ +
+ +
+ +
+ + +
diff --git a/src/app/dialogs/node-version-upload/node-version-upload.dialog.scss b/src/app/dialogs/node-version-upload/node-version-upload.dialog.scss new file mode 100644 index 0000000000..54210b6359 --- /dev/null +++ b/src/app/dialogs/node-version-upload/node-version-upload.dialog.scss @@ -0,0 +1,11 @@ +.aca-node-version-upload-dialog { + overflow: unset; + + .dialog-actions { + justify-content: flex-end; + } + + .node-version-dialog__title { + padding-left: 8px; + } +} diff --git a/src/app/dialogs/node-version-upload/node-version-upload.dialog.ts b/src/app/dialogs/node-version-upload/node-version-upload.dialog.ts new file mode 100644 index 0000000000..52ce3e598a --- /dev/null +++ b/src/app/dialogs/node-version-upload/node-version-upload.dialog.ts @@ -0,0 +1,34 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2018 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { Component, ViewEncapsulation } from '@angular/core'; + +@Component({ + templateUrl: './node-version-upload.dialog.html', + encapsulation: ViewEncapsulation.None, + styleUrls: ['./node-version-upload.dialog.scss'], + host: { class: 'aca-node-version-upload-dialog' } +}) +export class NodeVersionUploadDialogComponent {} diff --git a/src/app/dialogs/node-versions/node-versions.dialog.html b/src/app/dialogs/node-versions/node-versions.dialog.html index 10beef5b98..48a3c7d810 100644 --- a/src/app/dialogs/node-versions/node-versions.dialog.html +++ b/src/app/dialogs/node-versions/node-versions.dialog.html @@ -1,15 +1,17 @@ -
{{'VERSION.DIALOG.TITLE' | translate}}
+
+ {{ 'VERSION.DIALOG_ADF.TITLE' | translate }} +
diff --git a/src/app/services/content-management.service.ts b/src/app/services/content-management.service.ts index 7a0c4e48e2..d1de29484a 100644 --- a/src/app/services/content-management.service.ts +++ b/src/app/services/content-management.service.ts @@ -56,12 +56,13 @@ import { import { NodePermissionService } from './node-permission.service'; import { NodeInfo, DeletedNodeInfo, DeleteStatus } from '../store/models'; import { ContentApiService } from './content-api.service'; -import { sharedUrl } from '../store/selectors/app.selectors'; +import { sharedUrl, appSelection } from '../store/selectors/app.selectors'; import { NodeActionsService } from './node-actions.service'; import { TranslationService, ViewUtilService } from '@alfresco/adf-core'; +import { NodeVersionUploadDialogComponent } from '../dialogs/node-version-upload/node-version-upload.dialog'; import { NodeVersionsDialogComponent } from '../dialogs/node-versions/node-versions.dialog'; import { ShareDialogComponent } from '../components/shared/content-node-share/content-node-share.dialog'; -import { take, map, tap, mergeMap, catchError } from 'rxjs/operators'; +import { take, map, tap, mergeMap, catchError, flatMap } from 'rxjs/operators'; import { NodePermissionsDialogComponent } from '../components/permissions/permission-dialog/node-permissions.dialog'; interface RestoredNode { @@ -180,6 +181,13 @@ export class ContentManagementService { } } + versionUploadDialog() { + return this.dialogRef.open(NodeVersionUploadDialogComponent, { + disableClose: true, + panelClass: 'aca-node-version-dialog' + }); + } + shareNode(node: any): void { if (node && node.entry) { // shared and favorite @@ -1195,4 +1203,18 @@ export class ContentManagementService { } } } + + getNodeInfo() { + return this.store.select(appSelection).pipe( + take(1), + flatMap(({ file }) => { + const id = (file).entry.nodeId || (file).entry.guid; + if (!id) { + return of(file.entry); + } else { + return this.contentApi.getNodeInfo(id); + } + }) + ); + } } diff --git a/src/app/store/actions.ts b/src/app/store/actions.ts index 7e41eafa99..3d823daec0 100644 --- a/src/app/store/actions.ts +++ b/src/app/store/actions.ts @@ -35,3 +35,4 @@ export * from './actions/upload.actions'; export * from './actions/modals.actions'; export * from './actions/repository.actions'; export * from './actions/info-drawer.actions'; +export * from './actions/upload.actions'; diff --git a/src/app/store/actions/node.actions.ts b/src/app/store/actions/node.actions.ts index 19be6d2286..c97b4e2152 100644 --- a/src/app/store/actions/node.actions.ts +++ b/src/app/store/actions/node.actions.ts @@ -39,9 +39,9 @@ export const UNSHARE_NODES = 'UNSHARE_NODES'; export const COPY_NODES = 'COPY_NODES'; export const MOVE_NODES = 'MOVE_NODES'; export const MANAGE_PERMISSIONS = 'MANAGE_PERMISSIONS'; -export const MANAGE_VERSIONS = 'MANAGE_VERSIONS'; export const PRINT_FILE = 'PRINT_FILE'; export const FULLSCREEN_VIEWER = 'FULLSCREEN_VIEWER'; +export const MANAGE_VERSIONS = 'MANAGE_VERSIONS'; export const EDIT_OFFLINE = 'EDIT_OFFLINE'; export class SetSelectedNodesAction implements Action { @@ -109,11 +109,6 @@ export class ManagePermissionsAction implements Action { constructor(public payload: MinimalNodeEntity) {} } -export class ManageVersionsAction implements Action { - readonly type = MANAGE_VERSIONS; - constructor(public payload: MinimalNodeEntity) {} -} - export class PrintFileAction implements Action { readonly type = PRINT_FILE; constructor(public payload: MinimalNodeEntity) {} @@ -124,6 +119,11 @@ export class FullscreenViewerAction implements Action { constructor(public payload: MinimalNodeEntity) {} } +export class ManageVersionsAction implements Action { + readonly type = MANAGE_VERSIONS; + constructor(public payload: MinimalNodeEntity) {} +} + export class EditOfflineAction implements Action { readonly type = EDIT_OFFLINE; constructor(public payload: any) {} diff --git a/src/app/store/actions/upload.actions.ts b/src/app/store/actions/upload.actions.ts index f60858e183..267c3ac3b2 100644 --- a/src/app/store/actions/upload.actions.ts +++ b/src/app/store/actions/upload.actions.ts @@ -27,6 +27,7 @@ import { Action } from '@ngrx/store'; export const UPLOAD_FILES = 'UPLOAD_FILES'; export const UPLOAD_FOLDER = 'UPLOAD_FOLDER'; +export const UPLOAD_FILE_VERSION = 'UPLOAD_FILE_VERSION'; export class UploadFilesAction implements Action { readonly type = UPLOAD_FILES; @@ -37,3 +38,7 @@ export class UploadFolderAction implements Action { readonly type = UPLOAD_FOLDER; constructor(public payload: any) {} } + +export class UploadFileVersionAction implements Action { + readonly type = UPLOAD_FILE_VERSION; +} diff --git a/src/app/store/effects.ts b/src/app/store/effects.ts index ce4fa76b50..bbe4e8fed0 100644 --- a/src/app/store/effects.ts +++ b/src/app/store/effects.ts @@ -34,3 +34,4 @@ export * from './effects/search.effects'; export * from './effects/library.effects'; export * from './effects/upload.effects'; export * from './effects/modals.effects'; +export * from './effects/upload.effects'; diff --git a/src/app/store/effects/node.effects.spec.ts b/src/app/store/effects/node.effects.spec.ts index 1c9ad669cd..cb78022a90 100644 --- a/src/app/store/effects/node.effects.spec.ts +++ b/src/app/store/effects/node.effects.spec.ts @@ -42,8 +42,7 @@ import { EditFolderAction, CopyNodesAction, MoveNodesAction, - ManagePermissionsAction, - ManageVersionsAction + ManagePermissionsAction } from '../actions/node.actions'; import { SetCurrentFolderAction } from '../actions/app.actions'; @@ -399,36 +398,4 @@ describe('NodeEffects', () => { expect(contentService.managePermissions).not.toHaveBeenCalled(); }); }); - - describe('manageVersions$', () => { - it('should manage versions from the payload', () => { - spyOn(contentService, 'manageVersions').and.stub(); - - const node: any = { entry: { isFile: true } }; - store.dispatch(new ManageVersionsAction(node)); - - expect(contentService.manageVersions).toHaveBeenCalledWith(node); - }); - - it('should manage versions from the active selection', fakeAsync(() => { - spyOn(contentService, 'manageVersions').and.stub(); - - const node: any = { entry: { isFile: true } }; - store.dispatch(new SetSelectedNodesAction([node])); - - tick(100); - - store.dispatch(new ManageVersionsAction(null)); - - expect(contentService.manageVersions).toHaveBeenCalledWith(node); - })); - - it('should do nothing if invoking manage versions with no data', () => { - spyOn(contentService, 'manageVersions').and.stub(); - - store.dispatch(new ManageVersionsAction(null)); - - expect(contentService.manageVersions).not.toHaveBeenCalled(); - }); - }); }); diff --git a/src/app/store/effects/node.effects.ts b/src/app/store/effects/node.effects.ts index 94cbc5359e..10d60f2d7a 100644 --- a/src/app/store/effects/node.effects.ts +++ b/src/app/store/effects/node.effects.ts @@ -42,7 +42,9 @@ import { RestoreDeletedNodesAction, RESTORE_DELETED_NODES, ShareNodeAction, - SHARE_NODE + SHARE_NODE, + ManageVersionsAction, + MANAGE_VERSIONS } from '../actions'; import { ContentManagementService } from '../../services/content-management.service'; import { currentFolder, appSelection } from '../selectors/app.selectors'; @@ -55,8 +57,6 @@ import { MOVE_NODES, ManagePermissionsAction, MANAGE_PERMISSIONS, - ManageVersionsAction, - MANAGE_VERSIONS, PRINT_FILE, PrintFileAction, FULLSCREEN_VIEWER, diff --git a/src/app/store/effects/upload.effects.ts b/src/app/store/effects/upload.effects.ts index 45a09f6ccb..640881a19a 100644 --- a/src/app/store/effects/upload.effects.ts +++ b/src/app/store/effects/upload.effects.ts @@ -27,23 +27,41 @@ import { Injectable, RendererFactory2, NgZone } from '@angular/core'; import { Actions, Effect, ofType } from '@ngrx/effects'; import { Store } from '@ngrx/store'; import { AppStore } from '../states'; -import { UploadFilesAction, UPLOAD_FILES } from '../actions'; -import { map, take } from 'rxjs/operators'; +import { + UploadFilesAction, + UPLOAD_FILES, + UploadFolderAction, + UPLOAD_FOLDER, + UPLOAD_FILE_VERSION, + UploadFileVersionAction, + SnackbarErrorAction +} from '../actions'; +import { + map, + take, + flatMap, + distinctUntilChanged, + catchError, + switchMap +} from 'rxjs/operators'; import { FileUtils, FileModel, UploadService } from '@alfresco/adf-core'; import { currentFolder } from '../selectors/app.selectors'; -import { UploadFolderAction, UPLOAD_FOLDER } from '../actions/upload.actions'; +import { fromEvent, of, forkJoin } from 'rxjs'; +import { ContentManagementService } from '../../services/content-management.service'; @Injectable() export class UploadEffects { private fileInput: HTMLInputElement; private folderInput: HTMLInputElement; + private fileVersionInput: HTMLInputElement; constructor( private store: Store, private actions$: Actions, private ngZone: NgZone, private uploadService: UploadService, - rendererFactory: RendererFactory2 + rendererFactory: RendererFactory2, + private contentService: ContentManagementService ) { const renderer = rendererFactory.createRenderer(null, null); @@ -55,6 +73,13 @@ export class UploadEffects { this.fileInput.addEventListener('change', event => this.upload(event)); renderer.appendChild(document.body, this.fileInput); + this.fileVersionInput = renderer.createElement('input') as HTMLInputElement; + this.fileVersionInput.id = 'app-upload-file-version'; + this.fileVersionInput.type = 'file'; + this.fileVersionInput.style.display = 'none'; + this.fileVersionInput.addEventListener('change', event => event); + renderer.appendChild(document.body, this.fileVersionInput); + this.folderInput = renderer.createElement('input') as HTMLInputElement; this.folderInput.id = 'app-upload-folder'; this.folderInput.type = 'file'; @@ -81,6 +106,44 @@ export class UploadEffects { }) ); + @Effect({ dispatch: false }) + uploadVersion$ = this.actions$.pipe( + ofType(UPLOAD_FILE_VERSION), + switchMap(() => { + this.fileVersionInput.click(); + return fromEvent(this.fileVersionInput, 'change').pipe( + distinctUntilChanged(), + flatMap(() => this.contentService.versionUploadDialog().afterClosed()), + flatMap(form => forkJoin(of(form), this.contentService.getNodeInfo())), + map(([form, node]) => { + const file = this.fileVersionInput.files[0]; + const fileModel = new FileModel( + file, + { + comment: form.comment, + majorVersion: form.major ? true : false, + parentId: node.parentId, + path: ((file).webkitRelativePath || '').replace( + /\/[^\/]*$/, + '' + ), + newVersion: true, + nodeType: 'cm:content' + }, + node.id + ); + + this.fileVersionInput.value = ''; + this.uploadQueue([fileModel]); + }), + catchError(error => { + this.fileVersionInput.value = ''; + return of(new SnackbarErrorAction('VERSION.ERROR.GENERIC')); + }) + ); + }) + ); + private upload(event: any): void { this.store .select(currentFolder) diff --git a/src/assets/app.extensions.json b/src/assets/app.extensions.json index cc17cc9460..97c142fdca 100644 --- a/src/assets/app.extensions.json +++ b/src/assets/app.extensions.json @@ -637,6 +637,18 @@ "type": "separator", "order": 980 }, + { + "id": "app.toolbar.uploadNodeVersion", + "order": 1000, + "title": "APP.ACTIONS.UPLOAD_VERSION", + "icon": "playlist_add", + "actions": { + "click": "UPLOAD_FILE_VERSION" + }, + "rules": { + "visible": "app.toolbar.versions" + } + }, { "id": "app.toolbar.versions", "order": 1000, @@ -644,10 +656,10 @@ "icon": "history", "actions": { "click": "MANAGE_VERSIONS" - }, - "rules": { + }, + "rules": { "visible": "app.toolbar.versions" - } + } }, { "id": "app.toolbar.permissions", @@ -841,6 +853,18 @@ "type": "separator", "order": 1080 }, + { + "id": "app.context.menu.uploadNodeVersion", + "title": "APP.ACTIONS.UPLOAD_VERSION", + "order": 1100, + "icon": "playlist_add", + "actions": { + "click": "UPLOAD_FILE_VERSION" + }, + "rules": { + "visible": "app.toolbar.versions" + } + }, { "id": "app.context.menu.versions", "title": "APP.ACTIONS.VERSIONS", @@ -1054,8 +1078,20 @@ "order": 680 }, { - "id": "app.viewer.versions", + "id": "app.toolbar.uploadNodeVersion", "order": 700, + "title": "APP.ACTIONS.UPLOAD_VERSION", + "icon": "playlist_add", + "actions": { + "click": "UPLOAD_FILE_VERSION" + }, + "rules": { + "visible": "app.toolbar.versions" + } + }, + { + "id": "app.viewer.versions", + "order": 800, "title": "APP.ACTIONS.VERSIONS", "icon": "history", "actions": { @@ -1067,7 +1103,7 @@ }, { "id": "app.viewer.permissions", - "order": 800, + "order": 900, "title": "APP.ACTIONS.PERMISSIONS", "icon": "settings_input_component", "actions": { @@ -1117,7 +1153,7 @@ { "id": "app.sidebar.versions", "order": 300, - "disabled": true, + "disabled": false, "title": "APP.INFO_DRAWER.TABS.VERSIONS", "component": "app.components.tabs.versions", "rules": { diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 386a7fe687..fc8441913a 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -195,6 +195,7 @@ "UNSHARE": "Unshare", "DETAILS": "View details", "VERSIONS": "Manage Versions", + "UPLOAD_VERSION": "Upload new version", "TOGGLE-SIDENAV": "Toggle side navigation bar", "SHARE": "Share", "SHARE_EDIT": "Shared link settings", @@ -360,13 +361,31 @@ "UNSHARE_PERMISSION_ERROR": "You don't have permission to unshare this file" }, "VERSION": { - "DIALOG": { + "DIALOG_ADF": { "TITLE": "Manage Versions", "CLOSE": "Close" }, + "DIALOG": { + "TITLE": "Upload New Version", + "CLOSE": "Close", + "UPLOAD": "Upload" + }, + "FORM": { + "SUBTITLE": "What level of changes were made to this version?", + "VERSION": { + "MINOR": "Minor (2.#)", + "MAJOR": "Major (#.1)" + }, + "COMMENT": { + "PLACEHOLDER": "Add notes describing what changed" + } + }, "SELECTION": { "EMPTY": "Please choose a document to see the versions of it.", "NO_PERMISSION": "You don't have permission to manage the versions of this content." + }, + "ERROR": { + "GENERIC": "There was an error versioning the file" } }, "LIBRARY": { From 819f6ddced78f74cdf407d35ad0bff150e6534bc Mon Sep 17 00:00:00 2001 From: Adina Parpalita Date: Thu, 7 Feb 2019 21:45:24 +0200 Subject: [PATCH 042/259] [ACA-2160] add tests for Edit offline actions availability (#921) * add tests for Edit offline actions availability * fix delete / undo delete tests --- e2e/components/menu/menu.ts | 44 +- e2e/components/search/search-input.ts | 3 + e2e/components/toolbar/toolbar.ts | 39 +- .../context-menu-multiple-selection.test.ts | 280 ++- .../context-menu-single-selection.test.ts | 239 +- e2e/suites/actions/delete-undo-delete.test.ts | 16 +- e2e/suites/actions/edit-folder.test.ts | 24 +- ...cial-permissions-available-actions.test.ts | 2073 +++++++++++------ .../toolbar-multiple-selection.test.ts | 370 ++- .../actions/toolbar-single-selection.test.ts | 308 ++- e2e/suites/list-views/tooltips.test.ts | 2 +- e2e/suites/viewer/viewer-actions.test.ts | 271 ++- .../repo-client/apis/nodes/nodes-api.ts | 3 +- src/app/extensions/core.extensions.module.ts | 2 + .../extensions/evaluators/app.evaluators.ts | 6 +- .../evaluators/navigation.evaluators.ts | 20 + src/assets/app.extensions.json | 16 + 17 files changed, 2836 insertions(+), 880 deletions(-) diff --git a/e2e/components/menu/menu.ts b/e2e/components/menu/menu.ts index ed0ed7bf3b..3afdd87c32 100755 --- a/e2e/components/menu/menu.ts +++ b/e2e/components/menu/menu.ts @@ -37,7 +37,9 @@ export class Menu extends Component { submenu: 'app-context-menu-item .mat-menu-item', - editFolder: `app.context.menu.editFolder` + editFolder: `app.context.menu.editFolder`, + editOffline: `.mat-menu-item[title='Edit offline']`, + cancelEditing: `.mat-menu-item[title='Cancel editing']` }; items: ElementArrayFinder = this.component.all(by.css(Menu.selectors.item)); @@ -45,27 +47,29 @@ export class Menu extends Component { uploadFiles: ElementFinder = browser.element(by.id(Menu.selectors.uploadFiles)); submenus: ElementArrayFinder = browser.element.all(by.css(Menu.selectors.submenu)); - shareAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Share')); - shareEditAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Shared link settings')); - viewAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'View')); - downloadAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Download')); - editAction: ElementFinder = this.component.element(by.id(Menu.selectors.editFolder)); + cancelEditingAction: ElementFinder = this.component.element(by.css(Menu.selectors.cancelEditing)); + cancelJoinAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Cancel join')); copyAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Copy')); - moveAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Move')); + createFolderAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Create folder')); + createLibraryAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Create Library')); deleteAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Delete')); - managePermissionsAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Permissions')); - manageVersionsAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Manage Versions')); + downloadAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Download')); + editFolderAction: ElementFinder = this.component.element(by.id(Menu.selectors.editFolder)); + editOfflineAction: ElementFinder = this.component.element(by.css(Menu.selectors.editOffline)); favoriteAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Favorite')); - leaveAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Leave')); joinAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Join')); - cancelJoinAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Cancel join')); + leaveAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Leave')); + managePermissionsAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Permissions')); + manageVersionsAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Manage Versions')); + moveAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Move')); permanentDeleteAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Permanently delete')); restoreAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Restore')); - viewDetailsAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'View details')); - createFolderAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Create folder')); - createLibraryAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Create Library')); + shareAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Share')); + shareEditAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Shared link settings')); uploadFileAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Upload file')); uploadFolderAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Upload folder')); + viewAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'View')); + viewDetailsAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'View details')); constructor(ancestor?: ElementFinder) { super(Menu.selectors.root, ancestor); @@ -212,8 +216,16 @@ export class Menu extends Component { return await this.downloadAction.isPresent(); } - async isEditPresent() { - return await this.editAction.isPresent(); + async isEditFolderPresent() { + return await this.editFolderAction.isPresent(); + } + + async isEditOfflinePresent() { + return await this.editOfflineAction.isPresent(); + } + + async isCancelEditingPresent() { + return await this.cancelEditingAction.isPresent(); } async isCopyPresent() { diff --git a/e2e/components/search/search-input.ts b/e2e/components/search/search-input.ts index 0698fa11ae..42f9ad9479 100755 --- a/e2e/components/search/search-input.ts +++ b/e2e/components/search/search-input.ts @@ -74,14 +74,17 @@ export class SearchInput extends Component { } async clickFilesOption() { + await browser.wait(EC.elementToBeClickable(this.searchFilesOption), BROWSER_WAIT_TIMEOUT, '--- timeout waiting for Files to be clickable'); return await this.searchFilesOption.click(); } async clickFoldersOption() { + await browser.wait(EC.elementToBeClickable(this.searchFoldersOption), BROWSER_WAIT_TIMEOUT, '--- timeout waiting for Folders to be clickable'); return await this.searchFoldersOption.click(); } async clickLibrariesOption() { + await browser.wait(EC.elementToBeClickable(this.searchLibrariesOption), BROWSER_WAIT_TIMEOUT, '--- timeout waiting for Libraries to be clickable'); return await this.searchLibrariesOption.click(); } diff --git a/e2e/components/toolbar/toolbar.ts b/e2e/components/toolbar/toolbar.ts index 44a6699626..2fecb66c4b 100755 --- a/e2e/components/toolbar/toolbar.ts +++ b/e2e/components/toolbar/toolbar.ts @@ -37,7 +37,7 @@ export class Toolbar extends Component { shareEdit: `.mat-icon-button[title='Shared link settings']`, view: `.mat-icon-button[title='View']`, download: `.mat-icon-button[title='Download']`, - edit: `.mat-icon-button[title='Edit']`, + editFolder: 'app.toolbar.editFolder', viewDetails: `.mat-icon-button[title='View details']`, print: `.mat-icon-button[title='Print']`, fullScreen: `.mat-icon-button[title='Activate full-screen mode']`, @@ -53,7 +53,7 @@ export class Toolbar extends Component { shareEditButton: ElementFinder = this.component.element(by.css(Toolbar.selectors.shareEdit)); viewButton: ElementFinder = this.component.element(by.css(Toolbar.selectors.view)); downloadButton: ElementFinder = this.component.element(by.css(Toolbar.selectors.download)); - editButton: ElementFinder = this.component.element(by.css(Toolbar.selectors.edit)); + editFolderButton: ElementFinder = this.component.element(by.id(Toolbar.selectors.editFolder)); viewDetailsButton: ElementFinder = this.component.element(by.css(Toolbar.selectors.viewDetails)); printButton: ElementFinder = this.component.element(by.css(Toolbar.selectors.print)); fullScreenButton: ElementFinder = this.component.element(by.css(Toolbar.selectors.fullScreen)); @@ -108,15 +108,6 @@ export class Toolbar extends Component { await btn.click(); } - async clickShare() { - const btn = this.shareButton; - await btn.click(); - } - - async clickSharedLinkSettings() { - const btn = this.shareEditButton; - await btn.click(); - } async isSharedLinkSettingsPresent() { return await browser.isElementPresent(this.shareEditButton); @@ -134,8 +125,16 @@ export class Toolbar extends Component { return await browser.isElementPresent(this.downloadButton); } - async isEditPresent() { - return await browser.isElementPresent(this.editButton); + async isPermanentlyDeletePresent() { + return await browser.isElementPresent(this.permanentlyDeleteButton); + } + + async isRestorePresent() { + return await browser.isElementPresent(this.restoreButton); + } + + async isEditFolderPresent() { + return await browser.isElementPresent(this.editFolderButton); } async isViewDetailsPresent() { @@ -151,12 +150,22 @@ export class Toolbar extends Component { } + async clickShare() { + const btn = this.shareButton; + await btn.click(); + } + + async clickSharedLinkSettings() { + const btn = this.shareEditButton; + await btn.click(); + } + async clickView() { return await this.viewButton.click(); } - async clickEdit() { - return await this.editButton.click(); + async clickEditFolder() { + return await this.editFolderButton.click(); } async clickViewDetails() { diff --git a/e2e/suites/actions/context-menu-multiple-selection.test.ts b/e2e/suites/actions/context-menu-multiple-selection.test.ts index c818ef3372..7684136db9 100755 --- a/e2e/suites/actions/context-menu-multiple-selection.test.ts +++ b/e2e/suites/actions/context-menu-multiple-selection.test.ts @@ -31,8 +31,12 @@ import { Utils } from '../../utilities/utils'; describe('Context menu actions - multiple selection : ', () => { const username = `user-${Utils.random()}`; + const parent = `parent=${Utils.random()}`; let parentId; + const file1 = `my-file1-${Utils.random()}.txt`; let file1Id; const file2 = `my-file2-${Utils.random()}.txt`; let file2Id; + const fileLocked1 = `my-fileLocked1-${Utils.random()}.txt`; let fileLocked1Id; + const fileLocked2 = `my-fileLocked2-${Utils.random()}.txt`; let fileLocked2Id; const folder1 = `my-folder1-${Utils.random()}`; let folder1Id; const folder2 = `my-folder2-${Utils.random()}`; let folder2Id; @@ -45,6 +49,8 @@ describe('Context menu actions - multiple selection : ', () => { const siteName = `site-${Utils.random()}`; const file1Site = `my-inSite-file1-${Utils.random()}.txt`; const file2Site = `my-inSite-file2-${Utils.random()}.txt`; + const fileLocked1Site = `my-inSite-fileLocked1-${Utils.random()}.txt`; let fileLocked1SiteId; + const fileLocked2Site = `my-inSite-fileLocked2-${Utils.random()}.txt`; let fileLocked2SiteId; const folder1Site = `my-inSite-folder1-${Utils.random()}`; const folder2Site = `my-inSite-folder2-${Utils.random()}`; @@ -62,10 +68,17 @@ describe('Context menu actions - multiple selection : ', () => { beforeAll(async (done) => { await apis.admin.people.createUser({ username }); - file1Id = (await apis.user.nodes.createFile(file1)).entry.id; - file2Id = (await apis.user.nodes.createFile(file2)).entry.id; - folder1Id = (await apis.user.nodes.createFolder(folder1)).entry.id; - folder2Id = (await apis.user.nodes.createFolder(folder2)).entry.id; + parentId = (await apis.user.nodes.createFolder(parent)).entry.id; + + file1Id = (await apis.user.nodes.createFile(file1, parentId)).entry.id; + file2Id = (await apis.user.nodes.createFile(file2, parentId)).entry.id; + folder1Id = (await apis.user.nodes.createFolder(folder1, parentId)).entry.id; + folder2Id = (await apis.user.nodes.createFolder(folder2, parentId)).entry.id; + + fileLocked1Id = (await apis.user.nodes.createFile(fileLocked1, parentId)).entry.id; + fileLocked2Id = (await apis.user.nodes.createFile(fileLocked2, parentId)).entry.id; + await apis.user.nodes.lockFile(fileLocked1Id); + await apis.user.nodes.lockFile(fileLocked2Id); await apis.user.sites.createSite(siteName, SITE_VISIBILITY.PUBLIC); const docLibId = await apis.user.sites.getDocLibId(siteName); @@ -73,13 +86,17 @@ describe('Context menu actions - multiple selection : ', () => { await apis.user.nodes.createFile(file2Site, docLibId); await apis.user.nodes.createFolder(folder1Site, docLibId); await apis.user.nodes.createFolder(folder2Site, docLibId); + fileLocked1SiteId = (await apis.user.nodes.createFile(fileLocked1Site, docLibId)).entry.id; + fileLocked2SiteId = (await apis.user.nodes.createFile(fileLocked2Site, docLibId)).entry.id; + await apis.user.nodes.lockFile(fileLocked1SiteId); + await apis.user.nodes.lockFile(fileLocked2SiteId); - await apis.user.shared.shareFilesByIds([ file1Id, file2Id ]); - await apis.user.shared.waitForApi({ expect: 2 }); + await apis.user.shared.shareFilesByIds([ file1Id, file2Id, fileLocked1Id, fileLocked2Id ]); + await apis.user.shared.waitForApi({ expect: 4 }); - await apis.user.favorites.addFavoritesByIds('file', [ file1Id, file2Id ]); + await apis.user.favorites.addFavoritesByIds('file', [ file1Id, file2Id, fileLocked1Id, fileLocked2Id ]); await apis.user.favorites.addFavoritesByIds('folder', [ folder1Id, folder2Id ]); - await apis.user.favorites.waitForApi({ expect: 4 + 1 }); + await apis.user.favorites.waitForApi({ expect: 6 + 1 }); fileInTrash1Id = (await apis.user.nodes.createFile(fileInTrash1)).entry.id; fileInTrash2Id = (await apis.user.nodes.createFile(fileInTrash2)).entry.id; @@ -92,7 +109,7 @@ describe('Context menu actions - multiple selection : ', () => { }); afterAll(async (done) => { - await apis.user.nodes.deleteNodesById([ file1Id, file2Id, folder1Id, folder2Id ]); + await apis.user.nodes.deleteNodeById(parentId); await apis.user.sites.deleteSite(siteName); await apis.user.trashcan.emptyTrash(); done(); @@ -102,7 +119,12 @@ describe('Context menu actions - multiple selection : ', () => { beforeEach(async (done) => { await Utils.pressEscape(); await page.clickPersonalFilesAndWait(); - await dataTable.clearSelection(); + await dataTable.doubleClickOnRowByName(parent); + done(); + }); + + afterAll(async (done) => { + await Utils.pressEscape(); done(); }); @@ -119,7 +141,7 @@ describe('Context menu actions - multiple selection : ', () => { expect(await dataTable.hasContextMenu()).toBe(true, `Context menu is not displayed for ${file1}`); expect(await dataTable.countSelectedRows()).toEqual(1, 'incorrect number of selected rows'); - expect(await contextMenu.isEditPresent()).toBe(false, `Edit is displayed for ${file1}`); + expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${file1}`); expect(await dataTable.hasCheckMarkIcon(file1)).toBe(true, `${file1} is not selected`); expect(await dataTable.hasCheckMarkIcon(file2)).toBe(false, `${file2} is selected`); expect(await dataTable.hasCheckMarkIcon(folder1)).toBe(false, `${folder1} is selected`); @@ -130,7 +152,13 @@ describe('Context menu actions - multiple selection : ', () => { beforeEach(async (done) => { await Utils.pressEscape(); await page.clickPersonalFilesAndWait(); - await dataTable.clearSelection(); + await dataTable.doubleClickOnRowByName(parent); + await dataTable.waitForBody(); + done(); + }); + + afterAll(async (done) => { + await Utils.pressEscape(); done(); }); @@ -138,41 +166,62 @@ describe('Context menu actions - multiple selection : ', () => { await dataTable.selectMultipleItems([file1, file2]); await dataTable.rightClickOnMultipleSelection(); + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed`); expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed`); expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); - expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed`); + expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); + }); + + it('correct actions appear when multiple locked files are selected - []', async () => { + await dataTable.selectMultipleItems([fileLocked1, fileLocked2]); + await dataTable.rightClickOnMultipleSelection(); + + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); + expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); + expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed`); + expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed`); + expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); }); it('correct actions appear when multiple folders are selected - [C280632]', async () => { await dataTable.selectMultipleItems([folder1, folder2]); await dataTable.rightClickOnMultipleSelection(); + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isEditPresent()).toBe(false, 'Edit is displayed'); + expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed`); expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed`); expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); - expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed`); + expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); }); it('correct actions appear when both files and folders are selected - [C280631]', async () => { await dataTable.selectMultipleItems([file1, file2, folder1, folder2]); await dataTable.rightClickOnMultipleSelection(); + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isEditPresent()).toBe(false, 'Edit is displayed'); + expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed`); expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed`); expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); - expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed`); + expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); }); }); @@ -185,46 +234,73 @@ describe('Context menu actions - multiple selection : ', () => { done(); }); + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + it('correct actions appear when multiple files are selected - [C280641]', async () => { await dataTable.selectMultipleItems([ file1Site, file2Site ]); await dataTable.rightClickOnMultipleSelection(); + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isEditPresent()).toBe(false, 'Edit is displayed'); + expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed`); expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed`); expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); - expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed`); + expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); + }); + + it('correct actions appear when multiple locked files are selected - []', async () => { + await dataTable.selectMultipleItems([ fileLocked1Site, fileLocked2Site ]); + await dataTable.rightClickOnMultipleSelection(); + + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); + expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); + expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); + expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed`); + expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed`); + expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); }); it('correct actions appear when multiple folders are selected - [C280574]', async () => { await dataTable.selectMultipleItems([ folder1Site, folder2Site ]); await dataTable.rightClickOnMultipleSelection(); + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isEditPresent()).toBe(false, 'Edit is displayed'); + expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed`); expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed`); expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); - expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed`); + expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); }); it('correct actions appear when both files and folders are selected - [C280642]', async () => { await dataTable.selectMultipleItems([ file1Site, file2Site, folder1Site, folder2Site ]); await dataTable.rightClickOnMultipleSelection(); + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isEditPresent()).toBe(false, 'Edit is displayed'); + expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed`); expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed`); expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); - expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed`); + expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); }); }); @@ -236,18 +312,41 @@ describe('Context menu actions - multiple selection : ', () => { done(); }); + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + it('correct actions appear when multiple files are selected - [C280648]', async () => { await dataTable.selectMultipleItems([ file1, file2 ]); await dataTable.rightClickOnMultipleSelection(); + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); + expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); + expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); + expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed`); + expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed`); + expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is not displayed`); + }); + + it('correct actions appear when multiple locked files are selected - []', async () => { + await dataTable.selectMultipleItems([ fileLocked1, fileLocked2 ]); + await dataTable.rightClickOnMultipleSelection(); + + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isEditPresent()).toBe(false, 'Edit is displayed'); + expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed`); expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed`); expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); - expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed`); + expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is not displayed`); }); }); @@ -259,18 +358,41 @@ describe('Context menu actions - multiple selection : ', () => { done(); }); + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + it('correct actions appear when multiple files are selected - [C280652]', async () => { await dataTable.selectMultipleItems([ file1, file2 ]); await dataTable.rightClickOnMultipleSelection(); + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isEditPresent()).toBe(false, 'Edit is displayed'); + expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed`); expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed`); expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); - expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed`); + expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); + }); + + it('correct actions appear when multiple locked files are selected - []', async () => { + await dataTable.selectMultipleItems([ fileLocked1, fileLocked2 ]); + await dataTable.rightClickOnMultipleSelection(); + + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); + expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); + expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); + expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed`); + expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed`); + expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); }); }); @@ -282,49 +404,73 @@ describe('Context menu actions - multiple selection : ', () => { done(); }); + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + it('correct actions appear when multiple files are selected - [C280656]', async () => { await dataTable.selectMultipleItems([ file1, file2 ]); await dataTable.rightClickOnMultipleSelection(); + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); + expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); + expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); + expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed`); + expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed`); + expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); + }); + + it('correct actions appear when multiple locked files are selected - []', async () => { + await dataTable.selectMultipleItems([ fileLocked1, fileLocked2 ]); + await dataTable.rightClickOnMultipleSelection(); + + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isEditPresent()).toBe(false, 'Edit is displayed'); + expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed`); expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed`); expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); - // TODO: enable when ACA-1794 is fixed - // expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed`); + expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); }); it('correct actions appear when multiple folders are selected - [C280664]', async () => { await dataTable.selectMultipleItems([ folder1, folder2 ]); await dataTable.rightClickOnMultipleSelection(); + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isEditPresent()).toBe(false, 'Edit is displayed'); + expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed`); expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed`); expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); - // TODO: enable when ACA-1794 is fixed - // expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed`); + expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); }); it('correct actions appear when both files and folders are selected - [C280657]', async () => { await dataTable.selectMultipleItems([ file1, file2, folder1, folder2 ]); await dataTable.rightClickOnMultipleSelection(); + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isEditPresent()).toBe(false, 'Edit is displayed'); + expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed`); expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed`); expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); - // TODO: enable when ACA-1794 is fixed - // expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed`); + expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); }); }); @@ -336,6 +482,11 @@ describe('Context menu actions - multiple selection : ', () => { done(); }); + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + it('correct actions appear when multiple files are selected - [C286273]', async () => { await dataTable.selectMultipleItems([ fileInTrash1, fileInTrash2 ]); await dataTable.rightClickOnMultipleSelection(); @@ -344,11 +495,14 @@ describe('Context menu actions - multiple selection : ', () => { expect(await contextMenu.isRestorePresent()).toBe(true, 'Restore is not displayed'); expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); expect(await contextMenu.isDownloadPresent()).toBe(false, 'Download is displayed'); - expect(await contextMenu.isEditPresent()).toBe(false, 'Edit is displayed'); + expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); expect(await contextMenu.isCopyPresent()).toBe(false, `Copy is displayed`); expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); expect(await contextMenu.isFavoritePresent()).toBe(false, `Favorite is displayed`); + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); }); it('correct actions appear when multiple folders are selected - [C286274]', async () => { @@ -359,11 +513,14 @@ describe('Context menu actions - multiple selection : ', () => { expect(await contextMenu.isRestorePresent()).toBe(true, 'Restore is not displayed'); expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); expect(await contextMenu.isDownloadPresent()).toBe(false, 'Download is displayed'); - expect(await contextMenu.isEditPresent()).toBe(false, 'Edit is displayed'); + expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); expect(await contextMenu.isCopyPresent()).toBe(false, `Copy is displayed`); expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); expect(await contextMenu.isFavoritePresent()).toBe(false, `Favorite is displayed`); + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); }); it('correct actions appear when both files and folders are selected - [C286275]', async () => { @@ -374,11 +531,14 @@ describe('Context menu actions - multiple selection : ', () => { expect(await contextMenu.isRestorePresent()).toBe(true, 'Restore is not displayed'); expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); expect(await contextMenu.isDownloadPresent()).toBe(false, 'Download is displayed'); - expect(await contextMenu.isEditPresent()).toBe(false, 'Edit is displayed'); + expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); expect(await contextMenu.isCopyPresent()).toBe(false, `Copy is displayed`); expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); expect(await contextMenu.isFavoritePresent()).toBe(false, `Favorite is displayed`); + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); }); }); @@ -389,6 +549,11 @@ describe('Context menu actions - multiple selection : ', () => { done(); }); + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + it('correct actions appear when multiple files are selected - [C291831]', async () => { await searchInput.clickSearchButton(); await searchInput.checkOnlyFiles(); @@ -396,14 +561,35 @@ describe('Context menu actions - multiple selection : ', () => { await dataTable.selectMultipleItems([ file1Site, file2Site ]); await dataTable.rightClickOnMultipleSelection(); + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); + expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); + expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); + expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); + expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); + expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); + }); + + it('correct actions appear when multiple locked files are selected - []', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFiles(); + await searchInput.searchForTextAndCloseSearchOptions('my-inSite-file'); + await dataTable.selectMultipleItems([ fileLocked1Site, fileLocked2Site ]); + await dataTable.rightClickOnMultipleSelection(); + + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isEditPresent()).toBe(false, 'Edit is displayed'); + expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); - expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed`); + expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); }); it('correct actions appear when multiple folders are selected - [C291832]', async () => { @@ -413,14 +599,16 @@ describe('Context menu actions - multiple selection : ', () => { await dataTable.selectMultipleItems([ folder1Site, folder2Site ]); await dataTable.rightClickOnMultipleSelection(); + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isEditPresent()).toBe(false, 'Edit is displayed'); + expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); - expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed`); + expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); }); it('correct actions appear when both files and folders are selected - [C291833]', async () => { @@ -430,14 +618,16 @@ describe('Context menu actions - multiple selection : ', () => { await dataTable.selectMultipleItems([ file1Site, file2Site, folder1Site, folder2Site ]); await dataTable.rightClickOnMultipleSelection(); + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isEditPresent()).toBe(false, 'Edit is displayed'); + expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); - expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed`); + expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); }); }); }); diff --git a/e2e/suites/actions/context-menu-single-selection.test.ts b/e2e/suites/actions/context-menu-single-selection.test.ts index df8eb9b423..b20e5b0be6 100755 --- a/e2e/suites/actions/context-menu-single-selection.test.ts +++ b/e2e/suites/actions/context-menu-single-selection.test.ts @@ -35,9 +35,11 @@ describe('Context menu actions - single selection : ', () => { const folderUser = `folderUser-${Utils.random()}`; let folderUserId; const fileInTrash = `fileForDelete-${Utils.random()}.txt`; let fileInTrashId; const folderInTrash = `folderForDelete-${Utils.random()}`; let folderInTrashId; + const fileLocked = `fileLocked-${Utils.random()}.txt`; let fileLockedId; const siteName = `userSite-${Utils.random()}`; const fileSiteUser = `fileUser-${Utils.random()}.txt`; + const fileLockedInSite = `file-locked-site-${Utils.random()}.txt`; let fileLockedInSiteId; const folderSiteUser = `folderUser-${Utils.random()}`; const adminPublic = `admin-public-${Utils.random()}`; @@ -61,10 +63,15 @@ describe('Context menu actions - single selection : ', () => { fileUserId = (await apis.user.nodes.createFile(fileUser)).entry.id; folderUserId = (await apis.user.nodes.createFolder(folderUser)).entry.id; + fileLockedId = (await apis.user.nodes.createFile(fileLocked)).entry.id; + await apis.user.nodes.lockFile(fileLockedId); + await apis.user.sites.createSite(siteName, SITE_VISIBILITY.PUBLIC); const docLibId = await apis.user.sites.getDocLibId(siteName); await apis.user.nodes.createFile(fileSiteUser, docLibId); + fileLockedInSiteId = (await apis.user.nodes.createFile(fileLockedInSite, docLibId)).entry.id; await apis.user.nodes.createFolder(folderSiteUser, docLibId); + await apis.user.nodes.lockFile(fileLockedInSiteId); fileInTrashId = (await apis.user.nodes.createFiles([fileInTrash])).entry.id; folderInTrashId = (await apis.user.nodes.createFolders([ folderInTrash ])).entry.id; @@ -72,11 +79,13 @@ describe('Context menu actions - single selection : ', () => { await apis.user.nodes.deleteNodeById(folderInTrashId, false); await apis.user.shared.shareFileById(fileUserId); - await apis.user.shared.waitForApi({ expect: 1 }); + await apis.user.shared.shareFileById(fileLockedId); + await apis.user.shared.waitForApi({ expect: 2 }); await apis.user.favorites.addFavoriteById('file', fileUserId); + await apis.user.favorites.addFavoriteById('file', fileLockedId); await apis.user.favorites.addFavoriteById('folder', folderUserId); - await apis.user.favorites.waitForApi({ expect: 3 }); + await apis.user.favorites.waitForApi({ expect: 4 }); await apis.admin.sites.createSite(adminPublic); await apis.admin.sites.createSite(adminModerated, SITE_VISIBILITY.MODERATED); @@ -109,6 +118,11 @@ describe('Context menu actions - single selection : ', () => { done(); }); + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + it('Row is marked with a check circle icon on direct right click - [C286252]', async () => { await dataTable.rightClickOnItem(fileUser); @@ -133,7 +147,7 @@ describe('Context menu actions - single selection : ', () => { await dataTable.rightClickOnItem(folderUser); expect(await dataTable.hasContextMenu()).toBe(true, `Context menu is not displayed for ${folderUser}`); - expect(await contextMenu.isEditPresent()).toBe(true, `Edit is not displayed for ${folderUser}`); + expect(await contextMenu.isEditFolderPresent()).toBe(true, `Edit folder is not displayed for ${folderUser}`); expect(await dataTable.hasCheckMarkIcon(folderUser)).toBe(true, `${folderUser} is not selected`); expect(await dataTable.hasCheckMarkIcon(fileUser)).toBe(false, `${fileUser} is not selected`); }); @@ -142,7 +156,9 @@ describe('Context menu actions - single selection : ', () => { await dataTable.rightClickOnItem(fileUser); expect(await dataTable.hasContextMenu()).toBe(true, 'Context menu is not displayed'); + await page.sidenav.getActiveLink().click(); + expect(await dataTable.hasContextMenu()).toBe(false, 'Context menu is displayed'); }); }); @@ -155,9 +171,16 @@ describe('Context menu actions - single selection : ', () => { done(); }); + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + it('Context menu has the correct actions for a file - [C280615]', async () => { await dataTable.rightClickOnItem(fileUser); + expect(await contextMenu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed for ${fileUser}`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${fileUser}`); expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileUser}`); expect(await contextMenu.isViewPresent()).toBe(true, `View is not displayed for ${fileUser}`); expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${fileUser}`); @@ -167,15 +190,33 @@ describe('Context menu actions - single selection : ', () => { expect(await contextMenu.isSharePresent()).toBe(true, `Share is not displayed for ${fileUser}`); expect(await contextMenu.isManageVersionsPresent()).toBe(true, `Manage Versions is not displayed for ${fileUser}`); expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed for ${fileUser}`); - expect(await contextMenu.isEditPresent()).toBe(false, `Edit is displayed for ${fileUser}`); + expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileUser}`); expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${fileUser}`); }); + it('Context menu has the correct actions for a locked file - []', async () => { + await dataTable.rightClickOnItem(fileLocked); + + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileLocked}`); + expect(await contextMenu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed for ${fileLocked}`); + expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLocked}`); + expect(await contextMenu.isViewPresent()).toBe(true, `View is not displayed for ${fileLocked}`); + expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${fileLocked}`); + expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLocked}`); + expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed for ${fileLocked}`); + expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed for ${fileLocked}`); + expect(await contextMenu.isSharePresent()).toBe(true, `Share is not displayed for ${fileLocked}`); + expect(await contextMenu.isManageVersionsPresent()).toBe(true, `Manage Versions is not displayed for ${fileLocked}`); + expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed for ${fileLocked}`); + expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLocked}`); + expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${fileLocked}`); + }); + it('Context menu has the correct actions for a folder - [C280616]', async () => { await dataTable.rightClickOnItem(folderUser); expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${folderUser}`); - expect(await contextMenu.isEditPresent()).toBe(true, `Edit is not displayed for ${folderUser}`); + expect(await contextMenu.isEditFolderPresent()).toBe(true, `Edit folder is not displayed for ${folderUser}`); expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${folderUser}`); expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${folderUser}`); expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed for ${folderUser}`); @@ -184,6 +225,8 @@ describe('Context menu actions - single selection : ', () => { expect(await contextMenu.isViewPresent()).toBe(false, `View is displayed for ${folderUser}`); expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions is displayed for ${folderUser}`); expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed for ${folderUser}`); + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${folderUser}`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${folderUser}`); }); }); @@ -196,9 +239,16 @@ describe('Context menu actions - single selection : ', () => { done(); }); + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + it('Context menu has the correct actions for a file - [C280594]', async () => { await dataTable.rightClickOnItem(fileSiteUser); + expect(await contextMenu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed for ${fileSiteUser}`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${fileSiteUser}`); expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileSiteUser}`); expect(await contextMenu.isViewPresent()).toBe(true, `View is not displayed for ${fileSiteUser}`); expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${fileSiteUser}`); @@ -208,15 +258,33 @@ describe('Context menu actions - single selection : ', () => { expect(await contextMenu.isSharePresent()).toBe(true, `Share is not displayed for ${fileSiteUser}`); expect(await contextMenu.isManageVersionsPresent()).toBe(true, `Manage Versions not displayed for ${fileSiteUser}`); expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed for ${fileSiteUser}`); - expect(await contextMenu.isEditPresent()).toBe(false, `Edit is displayed for ${fileSiteUser}`); + expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileSiteUser}`); expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${fileSiteUser}`); }); + it('Context menu has the correct actions for a locked file - []', async () => { + await dataTable.rightClickOnItem(fileLockedInSite); + + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is not displayed for ${fileLockedInSite}`); + expect(await contextMenu.isCancelEditingPresent()).toBe(true, `Cancel editing is displayed for ${fileLockedInSite}`); + expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLockedInSite}`); + expect(await contextMenu.isViewPresent()).toBe(true, `View is not displayed for ${fileLockedInSite}`); + expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${fileLockedInSite}`); + expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLockedInSite}`); + expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed for ${fileLockedInSite}`); + expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed for ${fileLockedInSite}`); + expect(await contextMenu.isSharePresent()).toBe(true, `Share is not displayed for ${fileLockedInSite}`); + expect(await contextMenu.isManageVersionsPresent()).toBe(true, `Manage Versions not displayed for ${fileLockedInSite}`); + expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed for ${fileLockedInSite}`); + expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLockedInSite}`); + expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${fileLockedInSite}`); + }); + it('Context menu has the correct actions for a folder - [C280595]', async () => { await dataTable.rightClickOnItem(folderSiteUser); expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${folderSiteUser}`); - expect(await contextMenu.isEditPresent()).toBe(true, `Edit is not displayed for ${folderSiteUser}`); + expect(await contextMenu.isEditFolderPresent()).toBe(true, `Edit folder is not displayed for ${folderSiteUser}`); expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${folderSiteUser}`); expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${folderSiteUser}`); expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed for ${folderSiteUser}`); @@ -225,6 +293,8 @@ describe('Context menu actions - single selection : ', () => { expect(await contextMenu.isViewPresent()).toBe(false, `View is displayed for ${folderSiteUser}`); expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions displayed for ${folderSiteUser}`); expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed for ${folderSiteUser}`); + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${folderSiteUser}`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${folderSiteUser}`); }); }); @@ -235,6 +305,11 @@ describe('Context menu actions - single selection : ', () => { done(); }); + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + it('Available actions for a library - My Libraries - [C290080]', async () => { await page.goToMyLibrariesAndWait(); await dataTable.rightClickOnItem(siteName); @@ -319,9 +394,17 @@ describe('Context menu actions - single selection : ', () => { done(); }); + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + it('Context menu has the correct actions for a file - [C280601]', async () => { await dataTable.rightClickOnItem(fileUser); + // TODO: change expect to true when ACA-2173 is done + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileUser}`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${fileUser}`); expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileUser}`); expect(await contextMenu.isViewPresent()).toBe(true, `View is not displayed for ${fileUser}`); expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${fileUser}`); @@ -331,9 +414,28 @@ describe('Context menu actions - single selection : ', () => { expect(await contextMenu.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed for ${fileUser}`); expect(await contextMenu.isManageVersionsPresent()).toBe(true, `Manage Versions not displayed for ${fileUser}`); expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed for ${fileUser}`); - expect(await contextMenu.isEditPresent()).toBe(false, `Edit is displayed for ${fileUser}`); + expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileUser}`); expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${fileUser}`); }); + + it('Context menu has the correct actions for a locked file - []', async () => { + await dataTable.rightClickOnItem(fileLocked); + + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileLocked}`); + // TODO: change expect to true when ACA-2173 is done + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${fileLocked}`); + expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLocked}`); + expect(await contextMenu.isViewPresent()).toBe(true, `View is not displayed for ${fileLocked}`); + expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${fileLocked}`); + expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLocked}`); + expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed for ${fileLocked}`); + expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed for ${fileLocked}`); + expect(await contextMenu.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed for ${fileLocked}`); + expect(await contextMenu.isManageVersionsPresent()).toBe(true, `Manage Versions not displayed for ${fileLocked}`); + expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed for ${fileLocked}`); + expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLocked}`); + expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${fileLocked}`); + }); }); describe('on Recent Files', () => { @@ -343,9 +445,16 @@ describe('Context menu actions - single selection : ', () => { done(); }); + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + it('Context menu has the correct actions for a file - [C280622]', async () => { await dataTable.rightClickOnItem(fileUser); + expect(await contextMenu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed for ${fileUser}`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${fileUser}`); expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileUser}`); expect(await contextMenu.isViewPresent()).toBe(true, `View is not displayed for ${fileUser}`); expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${fileUser}`); @@ -355,9 +464,27 @@ describe('Context menu actions - single selection : ', () => { expect(await contextMenu.isSharePresent()).toBe(true, `Share is not displayed for ${fileUser}`); expect(await contextMenu.isManageVersionsPresent()).toBe(true, `Manage Versions not displayed for ${fileUser}`); expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed for ${fileUser}`); - expect(await contextMenu.isEditPresent()).toBe(false, `Edit is displayed for ${fileUser}`); + expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileUser}`); expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${fileUser}`); }); + + it('Context menu has the correct actions for a locked file - []', async () => { + await dataTable.rightClickOnItem(fileLocked); + + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileLocked}`); + expect(await contextMenu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed for ${fileLocked}`); + expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLocked}`); + expect(await contextMenu.isViewPresent()).toBe(true, `View is not displayed for ${fileLocked}`); + expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${fileLocked}`); + expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLocked}`); + expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed for ${fileLocked}`); + expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed for ${fileLocked}`); + expect(await contextMenu.isSharePresent()).toBe(true, `Share is not displayed for ${fileLocked}`); + expect(await contextMenu.isManageVersionsPresent()).toBe(true, `Manage Versions not displayed for ${fileLocked}`); + expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed for ${fileLocked}`); + expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLocked}`); + expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${fileLocked}`); + }); }); describe('on Favorites', () => { @@ -367,9 +494,17 @@ describe('Context menu actions - single selection : ', () => { done(); }); + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + it('Context menu has the correct actions for a file - [C280608]', async () => { await dataTable.rightClickOnItem(fileUser); + // TODO: change expect to true when ACA-2174 is done + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileUser}`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${fileUser}`); expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileUser}`); expect(await contextMenu.isViewPresent()).toBe(true, `View is not displayed for ${fileUser}`); expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${fileUser}`); @@ -378,26 +513,42 @@ describe('Context menu actions - single selection : ', () => { expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed for ${fileUser}`); expect(await contextMenu.isSharePresent()).toBe(true, `Share is not displayed for ${fileUser}`); expect(await contextMenu.isManageVersionsPresent()).toBe(true, `Manage Versions is not displayed for ${fileUser}`); - // TODO: enable when ACA-1794 is fixed - // expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed for ${fileUser}`); - expect(await contextMenu.isEditPresent()).toBe(false, `Edit is displayed for ${fileUser}`); + expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileUser}`); expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${fileUser}`); }); + it('Context menu has the correct actions for a locked file - []', async () => { + await dataTable.rightClickOnItem(fileLocked); + + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileLocked}`); + // TODO: change expect to true when ACA-2174 is done + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${fileLocked}`); + expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLocked}`); + expect(await contextMenu.isViewPresent()).toBe(true, `View is not displayed for ${fileLocked}`); + expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${fileLocked}`); + expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLocked}`); + expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed for ${fileLocked}`); + expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed for ${fileLocked}`); + expect(await contextMenu.isSharePresent()).toBe(true, `Share is not displayed for ${fileLocked}`); + expect(await contextMenu.isManageVersionsPresent()).toBe(true, `Manage Versions is not displayed for ${fileLocked}`); + expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLocked}`); + expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${fileLocked}`); + }); + it('Context menu has the correct actions for a folder - [C280609]', async () => { await dataTable.rightClickOnItem(folderUser); expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${folderUser}`); - expect(await contextMenu.isEditPresent()).toBe(true, `Edit is not displayed for ${folderUser}`); + expect(await contextMenu.isEditFolderPresent()).toBe(true, `Edit folder is not displayed for ${folderUser}`); expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${folderUser}`); expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${folderUser}`); expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed for ${folderUser}`); expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed for ${folderUser}`); - // TODO: enable when ACA-1794 is fixed - // expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed for ${folderUser}`); expect(await contextMenu.isViewPresent()).toBe(false, `View is displayed for ${folderUser}`); expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions is displayed for ${folderUser}`); expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed for ${folderUser}`); + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${folderUser}`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${folderUser}`); }); }); @@ -408,11 +559,15 @@ describe('Context menu actions - single selection : ', () => { done(); }); + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + it('Context menu has the correct actions for a file - [C286258]', async () => { await dataTable.rightClickOnItem(fileInTrash); - expect(await contextMenu.isPermanentDeletePresent()) - .toBe(true, `Permanently delete is not displayed for ${fileInTrash}`); + expect(await contextMenu.isPermanentDeletePresent()).toBe(true, `Permanently delete is not displayed for ${fileInTrash}`); expect(await contextMenu.isRestorePresent()).toBe(true, `Restore is not displayed for ${fileInTrash}`); expect(await contextMenu.isDownloadPresent()).toBe(false, `Download is displayed for ${fileInTrash}`); expect(await contextMenu.isViewPresent()).toBe(false, `View is displayed for ${fileInTrash}`); @@ -421,17 +576,17 @@ describe('Context menu actions - single selection : ', () => { expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed for ${fileInTrash}`); expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed for ${fileInTrash}`); expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed for ${fileInTrash}`); - expect(await contextMenu.isManageVersionsPresent()) - .toBe(false, `Manage Versions is displayed for ${fileInTrash}`); - expect(await contextMenu.isEditPresent()).toBe(false, `Edit is displayed for ${fileInTrash}`); + expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions is displayed for ${fileInTrash}`); + expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileInTrash}`); expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${fileInTrash}`); + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileInTrash}`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${fileInTrash}`); }); it('Context menu has the correct actions for a folder - [C286259]', async () => { await dataTable.rightClickOnItem(folderInTrash); - expect(await contextMenu.isPermanentDeletePresent()) - .toBe(true, `Permanently delete is not displayed for ${folderInTrash}`); + expect(await contextMenu.isPermanentDeletePresent()).toBe(true, `Permanently delete is not displayed for ${folderInTrash}`); expect(await contextMenu.isRestorePresent()).toBe(true, `Restore is not displayed for ${folderInTrash}`); expect(await contextMenu.isDownloadPresent()).toBe(false, `Download is displayed for ${folderInTrash}`); expect(await contextMenu.isViewPresent()).toBe(false, `View is displayed for ${folderInTrash}`); @@ -440,10 +595,10 @@ describe('Context menu actions - single selection : ', () => { expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed for ${folderInTrash}`); expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed for ${folderInTrash}`); expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed for ${folderInTrash}`); - expect(await contextMenu.isManageVersionsPresent()) - .toBe(false, `Manage Versions is displayed for ${folderInTrash}`); - expect(await contextMenu.isEditPresent()).toBe(false, `Edit is displayed for ${folderInTrash}`); + expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions is displayed for ${folderInTrash}`); + expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${folderInTrash}`); expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${folderInTrash}`); + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${folderInTrash}`); }); }); @@ -454,12 +609,19 @@ describe('Context menu actions - single selection : ', () => { done(); }); + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + it('Context menu has the correct actions for a file - [C291827]', async () => { await searchInput.clickSearchButton(); await searchInput.checkOnlyFiles(); await searchInput.searchForTextAndCloseSearchOptions(fileSiteUser); await dataTable.rightClickOnItem(fileSiteUser); + expect(await contextMenu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed for ${fileSiteUser}`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${fileSiteUser}`); expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileSiteUser}`); expect(await contextMenu.isViewPresent()).toBe(true, `View is not displayed for ${fileSiteUser}`); expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${fileSiteUser}`); @@ -469,10 +631,31 @@ describe('Context menu actions - single selection : ', () => { expect(await contextMenu.isSharePresent()).toBe(true, `Share is not displayed for ${fileSiteUser}`); expect(await contextMenu.isManageVersionsPresent()).toBe(true, `Manage Versions not displayed for ${fileSiteUser}`); expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed for ${fileSiteUser}`); - expect(await contextMenu.isEditPresent()).toBe(false, `Edit is displayed for ${fileSiteUser}`); + expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileSiteUser}`); expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${fileSiteUser}`); }); + it('Context menu has the correct actions for a locked file - []', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFiles(); + await searchInput.searchForTextAndCloseSearchOptions(fileLocked); + await dataTable.rightClickOnItem(fileLocked); + + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileLocked}`); + expect(await contextMenu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed for ${fileLocked}`); + expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLocked}`); + expect(await contextMenu.isViewPresent()).toBe(true, `View is not displayed for ${fileLocked}`); + expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${fileLocked}`); + expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLocked}`); + expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed for ${fileLocked}`); + expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed for ${fileLocked}`); + expect(await contextMenu.isSharePresent()).toBe(true, `Share is not displayed for ${fileLocked}`); + expect(await contextMenu.isManageVersionsPresent()).toBe(true, `Manage Versions not displayed for ${fileLocked}`); + expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed for ${fileLocked}`); + expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLocked}`); + expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${fileLocked}`); + }); + it('Context menu has the correct actions for a folder - [C291828]', async () => { await searchInput.clickSearchButton(); await searchInput.checkOnlyFolders(); @@ -480,7 +663,7 @@ describe('Context menu actions - single selection : ', () => { await dataTable.rightClickOnItem(folderSiteUser); expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${folderSiteUser}`); - expect(await contextMenu.isEditPresent()).toBe(true, `Edit is not displayed for ${folderSiteUser}`); + expect(await contextMenu.isEditFolderPresent()).toBe(true, `Edit folder is not displayed for ${folderSiteUser}`); expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${folderSiteUser}`); expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${folderSiteUser}`); expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed for ${folderSiteUser}`); @@ -489,6 +672,8 @@ describe('Context menu actions - single selection : ', () => { expect(await contextMenu.isViewPresent()).toBe(false, `View is displayed for ${folderSiteUser}`); expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions displayed for ${folderSiteUser}`); expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed for ${folderSiteUser}`); + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${folderSiteUser}`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${folderSiteUser}`); }); }); }); diff --git a/e2e/suites/actions/delete-undo-delete.test.ts b/e2e/suites/actions/delete-undo-delete.test.ts index 03f2be9e9b..3c3f2b8dda 100755 --- a/e2e/suites/actions/delete-undo-delete.test.ts +++ b/e2e/suites/actions/delete-undo-delete.test.ts @@ -99,10 +99,10 @@ describe('Delete and undo delete', () => { fileLocked4Id = (await apis.user.nodes.createFile(fileLocked4, folder5Id)).entry.id; await apis.user.nodes.createFile(file2InFolder, folder6Id); - await apis.user.nodes.lockFile(fileLocked1Id); - await apis.user.nodes.lockFile(fileLocked2Id); - await apis.user.nodes.lockFile(fileLocked3Id); - await apis.user.nodes.lockFile(fileLocked4Id); + await apis.user.nodes.lockFile(fileLocked1Id, 'FULL'); + await apis.user.nodes.lockFile(fileLocked2Id, 'FULL'); + await apis.user.nodes.lockFile(fileLocked3Id, 'FULL'); + await apis.user.nodes.lockFile(fileLocked4Id, 'FULL'); await loginPage.loginWith(username); @@ -364,10 +364,10 @@ describe('Delete and undo delete', () => { fileLocked4Id = (await apis.user.nodes.createFile(fileLocked4, favFolder5Id)).entry.id; await apis.user.nodes.createFile(file2InFolder, favFolder6Id); - await apis.user.nodes.lockFile(fileLocked1Id); - await apis.user.nodes.lockFile(fileLocked2Id); - await apis.user.nodes.lockFile(fileLocked3Id); - await apis.user.nodes.lockFile(fileLocked4Id); + await apis.user.nodes.lockFile(fileLocked1Id, 'FULL'); + await apis.user.nodes.lockFile(fileLocked2Id, 'FULL'); + await apis.user.nodes.lockFile(fileLocked3Id, 'FULL'); + await apis.user.nodes.lockFile(fileLocked4Id, 'FULL'); await apis.user.favorites.addFavoritesByIds('file', [ favFile1Id, favFile2Id, favFile3Id, favFile4Id, favFile5Id, favFile6Id, favFile7Id ]); await apis.user.favorites.addFavoritesByIds('folder', [ favFolder1Id, favFolder2Id, favFolder3Id, favFolder4Id, favFolder5Id, favFolder6Id ]); diff --git a/e2e/suites/actions/edit-folder.test.ts b/e2e/suites/actions/edit-folder.test.ts index 86f9243570..df86932df2 100755 --- a/e2e/suites/actions/edit-folder.test.ts +++ b/e2e/suites/actions/edit-folder.test.ts @@ -111,7 +111,7 @@ describe('Edit folder', () => { it('dialog UI defaults - [C216331]', async () => { await dataTable.doubleClickOnRowByName(parent); await dataTable.selectItem(folderName); - await toolbar.clickEdit(); + await toolbar.clickEditFolder(); expect(await editDialog.getTitle()).toEqual('Edit folder'); expect(await editDialog.getName()).toBe(folderName); @@ -130,7 +130,7 @@ describe('Edit folder', () => { it('properties are modified when pressing OK - [C216335]', async (done) => { await dataTable.selectItem(folderNameToEdit); - await toolbar.clickEdit(); + await toolbar.clickEditFolder(); await editDialog.waitForDialogToOpen(); await editDialog.enterDescription(folderDescriptionEdited); await editDialog.enterName(folderNameEdited); @@ -146,7 +146,7 @@ describe('Edit folder', () => { it('with empty folder name - [C216332]', async () => { await dataTable.selectItem(folderName); - await toolbar.clickEdit(); + await toolbar.clickEditFolder(); await editDialog.deleteNameWithBackspace(); expect(await editDialog.isUpdateButtonEnabled()).toBe(false, 'upload button is not enabled'); @@ -157,7 +157,7 @@ describe('Edit folder', () => { const namesWithSpecialChars = [ 'a*a', 'a"a', 'aa', `a\\a`, 'a/a', 'a?a', 'a:a', 'a|a' ]; await dataTable.selectItem(folderName); - await toolbar.clickEdit(); + await toolbar.clickEditFolder(); for (const name of namesWithSpecialChars) { await editDialog.enterName(name); @@ -168,7 +168,7 @@ describe('Edit folder', () => { it('with name ending with a dot - [C216334]', async () => { await dataTable.selectItem(folderName); - await toolbar.clickEdit(); + await toolbar.clickEditFolder(); await editDialog.waitForDialogToOpen(); await editDialog.nameInput.sendKeys('.'); @@ -178,7 +178,7 @@ describe('Edit folder', () => { it('Cancel button - [C216336]', async () => { await dataTable.selectItem(folderName); - await toolbar.clickEdit(); + await toolbar.clickEditFolder(); await editDialog.waitForDialogToOpen(); await editDialog.clickCancel(); @@ -187,7 +187,7 @@ describe('Edit folder', () => { it('with duplicate folder name - [C216337]', async () => { await dataTable.selectItem(folderName); - await toolbar.clickEdit(); + await toolbar.clickEditFolder(); await editDialog.waitForDialogToOpen(); await editDialog.enterName(duplicateFolderName); await editDialog.clickUpdate(); @@ -198,7 +198,7 @@ describe('Edit folder', () => { it('trim ending spaces - [C216338]', async () => { await dataTable.selectItem(folderName); - await toolbar.clickEdit(); + await toolbar.clickEditFolder(); await editDialog.nameInput.sendKeys(' '); await editDialog.clickUpdate(); await editDialog.waitForDialogToClose(); @@ -216,7 +216,7 @@ describe('Edit folder', () => { it('properties are modified when pressing OK - [C280384]', async (done) => { await dataTable.selectItem(folderFavoriteToEdit); - await toolbar.clickEdit(); + await toolbar.clickEditFolder(); await editDialog.waitForDialogToOpen(); await editDialog.enterDescription(folderDescriptionEdited); await editDialog.enterName(folderNameEdited); @@ -232,7 +232,7 @@ describe('Edit folder', () => { it('with duplicate folder name - [C280386]', async () => { await dataTable.selectItem(folderFavorite); - await toolbar.clickEdit(); + await toolbar.clickEditFolder(); await editDialog.waitForDialogToOpen(); await editDialog.enterName(folderFavoriteDuplicate); await editDialog.clickUpdate(); @@ -251,7 +251,7 @@ describe('Edit folder', () => { it('properties are modified when pressing OK - [C280509]', async (done) => { await dataTable.selectItem(folderSiteToEdit); - await toolbar.clickEdit(); + await toolbar.clickEditFolder(); await editDialog.waitForDialogToOpen(); await editDialog.enterDescription(folderDescriptionEdited); await editDialog.enterName(folderNameEdited); @@ -267,7 +267,7 @@ describe('Edit folder', () => { it('with duplicate folder name - [C280511]', async () => { await dataTable.selectItem(folderSite); - await toolbar.clickEdit(); + await toolbar.clickEditFolder(); await editDialog.waitForDialogToOpen(); await editDialog.enterName(duplicateFolderSite); await editDialog.clickUpdate(); diff --git a/e2e/suites/actions/special-permissions-available-actions.test.ts b/e2e/suites/actions/special-permissions-available-actions.test.ts index 082a366098..242dee3d02 100755 --- a/e2e/suites/actions/special-permissions-available-actions.test.ts +++ b/e2e/suites/actions/special-permissions-available-actions.test.ts @@ -32,6 +32,8 @@ import { Viewer } from '../../components/viewer/viewer'; describe('Granular permissions available actions : ', () => { const userConsumer = `consumer-${Utils.random()}`; const userManager = `manager-${Utils.random()}`; + const userCollaborator = `collaborator-${Utils.random()}`; + const userDemoted = `demoted-${Utils.random()}`; const siteName = `site-private-${Utils.random()}`; const file1 = `my-file1-${Utils.random()}.txt`; @@ -40,6 +42,8 @@ describe('Granular permissions available actions : ', () => { let file2Id; const file3 = `my-file3-${Utils.random()}.txt`; let file3Id; + const fileLocked = `my-file-locked-${Utils.random()}.txt`; + let fileLockedId; const folder1 = `my-folder1-${Utils.random()}`; let folder1Id; @@ -52,7 +56,8 @@ describe('Granular permissions available actions : ', () => { const apis = { admin: new RepoClient(), userConsumer: new RepoClient(userConsumer, userConsumer), - userManager: new RepoClient(userManager, userManager) + userCollaborator: new RepoClient(userCollaborator, userCollaborator), + userDemoted: new RepoClient(userDemoted, userDemoted) }; const loginPage = new LoginPage(); @@ -67,6 +72,8 @@ describe('Granular permissions available actions : ', () => { beforeAll(async (done) => { await apis.admin.people.createUser({ username: userConsumer }); await apis.admin.people.createUser({ username: userManager }); + await apis.admin.people.createUser({ username: userCollaborator }); + await apis.admin.people.createUser({ username: userDemoted }); await apis.admin.sites.createSite(siteName, SITE_VISIBILITY.PRIVATE); const docLibId = await apis.admin.sites.getDocLibId(siteName); @@ -81,6 +88,14 @@ describe('Granular permissions available actions : ', () => { await apis.admin.sites.addSiteMember(siteName, userManager, SITE_ROLES.SITE_MANAGER.ROLE); await apis.admin.sites.addSiteMember(siteName, userConsumer, SITE_ROLES.SITE_CONSUMER.ROLE); + await apis.admin.sites.addSiteMember(siteName, userCollaborator, SITE_ROLES.SITE_COLLABORATOR.ROLE); + await apis.admin.sites.addSiteMember(siteName, userDemoted, SITE_ROLES.SITE_MANAGER.ROLE); + + fileLockedId = (await apis.admin.nodes.createFile(fileLocked, docLibId)).entry.id; + await apis.userDemoted.nodes.lockFile(fileLockedId); + await apis.userDemoted.favorites.addFavoriteById('file', fileLockedId); + await apis.userDemoted.shared.shareFileById(fileLockedId); + await apis.admin.sites.updateSiteMember(siteName, userDemoted, SITE_ROLES.SITE_CONSUMER.ROLE); await apis.admin.nodes.setGranularPermission(file3Id, false, userConsumer, SITE_ROLES.SITE_MANAGER.ROLE); @@ -88,13 +103,15 @@ describe('Granular permissions available actions : ', () => { await apis.userConsumer.shared.shareFileById(file2Id); await apis.userConsumer.shared.shareFileById(docxFileId); await apis.userConsumer.shared.shareFileById(file3Id); - await apis.userConsumer.shared.waitForApi({ expect: 4 }); + await apis.userConsumer.shared.waitForApi({ expect: 5 }); await apis.userConsumer.favorites.addFavoritesByIds('file', [file1Id, file2Id, file3Id, docxFileId]); await apis.userConsumer.favorites.addFavoritesByIds('folder', [folder1Id, folder2Id]); await apis.userConsumer.favorites.waitForApi({ expect: 6 }); - await loginPage.loginWith(userConsumer); + await apis.userCollaborator.favorites.addFavoritesByIds('file', [file1Id, docxFileId]); + await apis.userCollaborator.favorites.waitForApi({ expect: 2 }); + done(); }); @@ -103,139 +120,1181 @@ describe('Granular permissions available actions : ', () => { done(); }); - describe('toolbar displays correct actions when selecting multiple files with different granular permissions', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await dataTable.clearSelection(); - await page.clickPersonalFiles(); + describe('Consumer', () => { + beforeAll(async (done) => { + await loginPage.loginWith(userConsumer); done(); }); - it('on File Libraries - [C280476]', async () => { - await page.clickFileLibrariesAndWait(); - await dataTable.doubleClickOnRowByName(siteName); - await dataTable.waitForHeader(); - await dataTable.selectMultipleItems([file1, file2]); + describe('toolbar displays correct actions when selecting multiple files with different granular permissions', () => { + beforeEach(async (done) => { + await Utils.pressEscape(); + await dataTable.clearSelection(); + await page.clickPersonalFiles(); + done(); + }); + + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + + it('on File Libraries - [C280476]', async () => { + await page.clickFileLibrariesAndWait(); + await dataTable.doubleClickOnRowByName(siteName); + await dataTable.waitForHeader(); + await dataTable.selectMultipleItems([file1, file2]); + + expect(await toolbar.isViewPresent()).toBe(false, `View is displayed for selected files`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for selected files`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for selected files`); + expect(await toolbar.isSharePresent()).toBe(false, `Share is displayed`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for selected files`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for selected files`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); + expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for selected files`); + expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for selected files`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed for selected files`); + + await toolbar.closeMoreMenu(); + }); + + it('on Shared Files - [C280477]', async () => { + await page.clickSharedFilesAndWait(); + await dataTable.selectMultipleItems([file1, file2]); + + expect(await toolbar.isViewPresent()).toBe(false, `View is displayed for selected files`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for selected files`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for selected files`); + expect(await toolbar.isSharePresent()).toBe(false, `Share is displayed`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for selected files`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for selected files`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); + expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for selected files`); + expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for selected files`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed for selected files`); + + await toolbar.closeMoreMenu(); + }); + + it('on Favorites - [C280478]', async () => { + await page.clickFavoritesAndWait(); + await dataTable.selectMultipleItems([file1, file2]); + + expect(await toolbar.isViewPresent()).toBe(false, `View is displayed for selected files`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for selected files`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for selected files`); + expect(await toolbar.isSharePresent()).toBe(false, `Share is displayed`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for selected files`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); + // TODO: change expect to false when ACA-1737 is done + expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is displayed for selected files`); + // TODO: change expect to false when ACA-1737 is done + expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is displayed for selected files`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed for selected files`); + + await toolbar.closeMoreMenu(); + }); + + it('on Search Results - [C291823]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFiles(); + await searchInput.searchForTextAndCloseSearchOptions('my-file'); + await dataTable.selectMultipleItems([file1, file2]); + + expect(await toolbar.isViewPresent()).toBe(false, `View is displayed for selected files`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for selected files`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for selected files`); + expect(await toolbar.isSharePresent()).toBe(false, `Share is displayed`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for selected files`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for selected files`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); + expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for selected files`); + expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for selected files`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed for selected files`); + + await toolbar.closeMoreMenu(); + }); + }); - expect(await toolbar.isViewPresent()).toBe(false, `View is displayed for selected files`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for selected files`); - expect(await toolbar.isEditPresent()).toBe(false, `Edit is displayed for selected files`); - await toolbar.openMoreMenu(); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); - expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for selected files`); - expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for selected files`); - expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); - await toolbar.closeMoreMenu(); + describe('toolbar actions appear correctly for a file', () => { + beforeEach(async (done) => { + await Utils.pressEscape(); + await dataTable.clearSelection(); + await page.clickPersonalFiles(); + done(); + }); + + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + + it('on File Libraries - [C280455]', async () => { + await page.clickFileLibrariesAndWait(); + await dataTable.doubleClickOnRowByName(siteName); + await dataTable.waitForHeader(); + await dataTable.selectItem(file1); + + expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${file1}`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${file1}`); + expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${file1}`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${file1}`); + expect(await toolbar.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${file1}`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${file1}`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${file1}`); + expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${file1}`); + expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${file1}`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${file1}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed for ${file1}`); + + await toolbar.closeMoreMenu(); + }); + + it('on Shared Files - [C280456]', async () => { + await page.clickSharedFilesAndWait(); + await page.dataTable.selectItem(file1); + + expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${file1}`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${file1}`); + expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${file1}`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${file1}`); + expect(await toolbar.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${file1}`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${file1}`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${file1}`); + expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${file1}`); + expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${file1}`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${file1}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed for ${file1}`); + + await toolbar.closeMoreMenu(); + }); + + it('on Favorites - [C213121]', async () => { + await page.clickFavoritesAndWait(); + await dataTable.selectItem(file1); + + expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${file1}`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${file1}`); + expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${file1}`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${file1}`); + // TODO: replace with isSharedLinkSettingsPresent when ACA-2175 is done + expect(await toolbar.isSharePresent()).toBe(true, `Share is not displayed`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${file1}`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${file1}`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${file1}`); + // TODO: change expect to false when ACA-1737 is done + expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is displayed for ${file1}`); + // TODO: change expect to false when ACA-1737 is done + expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is displayed for ${file1}`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${file1}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed for ${file1}`); + + await toolbar.closeMoreMenu(); + }); + + it('on Search Results - [C291818]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFiles(); + await searchInput.searchForTextAndCloseSearchOptions(file1); + await dataTable.selectItem(file1); + + expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${file1}`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${file1}`); + expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${file1}`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${file1}`); + expect(await toolbar.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${file1}`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${file1}`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${file1}`); + expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${file1}`); + expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${file1}`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${file1}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed for ${file1}`); + + await toolbar.closeMoreMenu(); + }); }); - it('on Shared Files - [C280477]', async () => { - await page.clickSharedFilesAndWait(); - await dataTable.selectMultipleItems([file1, file2]); + describe('toolbar actions appear correctly for a folder', () => { + beforeEach(async (done) => { + await Utils.pressEscape(); + await dataTable.clearSelection(); + await page.clickPersonalFiles(); + done(); + }); + + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + + it('on File Libraries - [C280444]', async () => { + await page.clickFileLibrariesAndWait(); + await dataTable.doubleClickOnRowByName(siteName); + await dataTable.waitForHeader(); + await dataTable.selectItem(folder1); + + expect(await toolbar.isViewPresent()).toBe(false, `View is displayed for ${folder1}`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${folder1}`); + expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${folder1}`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${folder1}`); + expect(await toolbar.isSharePresent()).toBe(false, `Share is displayed`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${folder1}`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${folder1}`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${folder1}`); + expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${folder1}`); + expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${folder1}`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${folder1}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed for ${folder1}`); + + await toolbar.closeMoreMenu(); + }); + + it('on Favorites - [C286266]', async () => { + await page.clickFavoritesAndWait(); + await dataTable.selectItem(folder1); + + expect(await toolbar.isViewPresent()).toBe(false, `View is not displayed for ${folder1}`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${folder1}`); + expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${folder1}`); + // TODO: change expect to false when ACA-1737 is done + expect(await toolbar.isEditFolderPresent()).toBe(true, `Edit folder is displayed for ${folder1}`); + expect(await toolbar.isSharePresent()).toBe(false, `Share is displayed`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${folder1}`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${folder1}`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${folder1}`); + // TODO: change expect to false when ACA-1737 is done + expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is displayed for ${folder1}`); + // TODO: change expect to false when ACA-1737 is done + expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is displayed for ${folder1}`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${folder1}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed for ${folder1}`); + + await toolbar.closeMoreMenu(); + }); + + it('on Search Results - [C291819]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFolders(); + await searchInput.searchForTextAndCloseSearchOptions(folder1); + await dataTable.selectItem(folder1); + + expect(await toolbar.isViewPresent()).toBe(false, `View is displayed for ${folder1}`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${folder1}`); + expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${folder1}`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${folder1}`); + expect(await toolbar.isSharePresent()).toBe(false, `Share is displayed`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${folder1}`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${folder1}`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${folder1}`); + expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${folder1}`); + expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${folder1}`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${folder1}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed for ${folder1}`); + + await toolbar.closeMoreMenu(); + }); + }); - expect(await toolbar.isViewPresent()).toBe(false, `View is displayed for selected files`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for selected files`); - expect(await toolbar.isEditPresent()).toBe(false, `Edit is displayed for selected files`); - await toolbar.openMoreMenu(); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); - expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for selected files`); - expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for selected files`); - expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); - await toolbar.closeMoreMenu(); + describe('toolbar actions appear correctly for multiple selection of files', () => { + beforeEach(async (done) => { + await Utils.pressEscape(); + await dataTable.clearSelection(); + await page.clickPersonalFiles(); + done(); + }); + + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + + it('on File Libraries - [C280464]', async () => { + await page.clickFileLibrariesAndWait(); + await dataTable.doubleClickOnRowByName(siteName); + await dataTable.waitForHeader(); + await dataTable.selectMultipleItems([file1, file2]); + + expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); + expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); + expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); + expect(await toolbar.isSharePresent()).toBe(false, `Share is displayed`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); + expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); + + await toolbar.closeMoreMenu(); + }); + + it('on Shared Files - [C286284]', async () => { + await page.clickSharedFilesAndWait(); + await dataTable.selectMultipleItems([file1, file2]); + + expect(await toolbar.isViewPresent()).toBe(false, `View is displayed for selected files`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for selected files`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for selected files`); + expect(await toolbar.isSharePresent()).toBe(false, `Share is displayed`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); + expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for selected files`); + expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for selected files`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); + + await toolbar.closeMoreMenu(); + }); + + it('on Favorites - [C286285]', async () => { + await page.clickFavoritesAndWait(); + await dataTable.selectMultipleItems([file1, file2]); + + expect(await toolbar.isViewPresent()).toBe(false, `View is displayed for selected files`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for selected files`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for selected files`); + expect(await toolbar.isSharePresent()).toBe(false, `Share is displayed`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); + // TODO: change expect to false when ACA-1737 is done + expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is displayed for selected files`); + // TODO: change expect to false when ACA-1737 is done + expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is displayed for selected files`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); + + await toolbar.closeMoreMenu(); + }); + + it('on Search Results - [C291824]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFiles(); + await searchInput.searchForTextAndCloseSearchOptions('my-file'); + await dataTable.selectMultipleItems([file1, file2]); + + expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); + expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); + expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); + expect(await toolbar.isSharePresent()).toBe(false, `Share is displayed`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); + expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); + + await toolbar.closeMoreMenu(); + }); }); - it('on Favorites - [C280478]', async () => { - await page.clickFavoritesAndWait(); - await dataTable.selectMultipleItems([file1, file2]); + describe('toolbar actions appear correctly for multiple selection of folders', () => { + beforeEach(async (done) => { + await Utils.pressEscape(); + await dataTable.clearSelection(); + await page.clickPersonalFiles(); + done(); + }); + + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + + it('on File Libraries - [C280465]', async () => { + await page.clickFileLibrariesAndWait(); + await dataTable.doubleClickOnRowByName(siteName); + await dataTable.waitForHeader(); + await dataTable.selectMultipleItems([folder1, folder2]); + + expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); + expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); + expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); + expect(await toolbar.isSharePresent()).toBe(false, `Share is displayed`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); + expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); + + await toolbar.closeMoreMenu(); + }); + + it('on Favorites - [C286286]', async () => { + await page.clickFavoritesAndWait(); + await dataTable.selectMultipleItems([folder1, folder2]); + + expect(await toolbar.isViewPresent()).toBe(false, `View is displayed`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed`); + expect(await toolbar.isSharePresent()).toBe(false, `Share is displayed`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); + // TODO: change expect to false when ACA-1737 is done + expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is displayed`); + // TODO: change expect to false when ACA-1737 is done + expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is displayed`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); + + await toolbar.closeMoreMenu(); + }); + + it('on Search Results - [C291825]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFolders(); + await searchInput.searchForTextAndCloseSearchOptions('my-folder'); + await dataTable.selectMultipleItems([folder1, folder2]); + + expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); + expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); + expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); + expect(await toolbar.isSharePresent()).toBe(false, `Share is displayed`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); + expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); + + await toolbar.closeMoreMenu(); + }); + }); - expect(await toolbar.isViewPresent()).toBe(false, `View is displayed for selected files`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for selected files`); - expect(await toolbar.isEditPresent()).toBe(false, `Edit is displayed for selected files`); - await toolbar.openMoreMenu(); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); - // TODO: enable when ACA-1737 is done - // expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for selected files`); - // expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for selected files`); - expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); - await toolbar.closeMoreMenu(); + describe('toolbar actions appear correctly for when both files and folders are selected', () => { + beforeEach(async (done) => { + await Utils.pressEscape(); + await dataTable.clearSelection(); + await page.clickPersonalFiles(); + done(); + }); + + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + + it('on File Libraries - [C280466]', async () => { + await page.clickFileLibrariesAndWait(); + await dataTable.doubleClickOnRowByName(siteName); + await dataTable.waitForHeader(); + await dataTable.selectMultipleItems([file1, folder1]); + + expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); + expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); + expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); + expect(await toolbar.isSharePresent()).toBe(false, `Share is displayed`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); + expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); + + await toolbar.closeMoreMenu(); + }); + + it('on Favorites - [C286287]', async () => { + await page.clickFavoritesAndWait(); + await dataTable.selectMultipleItems([file1, folder1]); + + expect(await toolbar.isViewPresent()).toBe(false, `View is displayed`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed`); + expect(await toolbar.isSharePresent()).toBe(false, `Share is displayed`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); + // TODO: change expect to false when ACA-1737 is done + expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is displayed`); + // TODO: change expect to false when ACA-1737 is done + expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is displayed`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); + + await toolbar.closeMoreMenu(); + }); + + it('on Search Results - [C291826]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkFilesAndFolders(); + await searchInput.searchForTextAndCloseSearchOptions('my-f'); + await dataTable.selectMultipleItems([file1, folder1]); + + expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); + expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); + expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); + expect(await toolbar.isSharePresent()).toBe(false, `Share is displayed`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); + expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); + + await toolbar.closeMoreMenu(); + }); }); - it('on Search Results - [C291823]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkOnlyFiles(); - await searchInput.searchForTextAndCloseSearchOptions('my-file'); - await dataTable.selectMultipleItems([file1, file2]); + describe('context menu actions are correct for a file', () => { + beforeEach(async (done) => { + await Utils.pressEscape(); + await dataTable.clearSelection(); + await page.clickPersonalFiles(); + done(); + }); + + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + + it('on File Libraries - [C280599]', async () => { + await page.clickFileLibrariesAndWait(); + await dataTable.doubleClickOnRowByName(siteName); + await dataTable.waitForHeader(); + await dataTable.rightClickOnItem(file1); + + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${file1}`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${file1}`); + expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${file1}`); + expect(await contextMenu.isViewPresent()).toBe(true, `View is not displayed for ${file1}`); + expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${file1}`); + expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${file1}`); + expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed for ${file1}`); + expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed for ${file1}`); + expect(await contextMenu.isManageVersionsPresent()).toBe(true, `Manage Versions is not displayed for ${file1}`); + expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${file1}`); + expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${file1}`); + expect(await contextMenu.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed`); + }); + + it('on Shared Files - [C286264]', async () => { + await page.clickSharedFilesAndWait(); + await dataTable.rightClickOnItem(file1); + + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${file1}`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${file1}`); + expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${file1}`); + expect(await contextMenu.isViewPresent()).toBe(true, `View is not displayed for ${file1}`); + expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${file1}`); + expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${file1}`); + expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed for ${file1}`); + expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed for ${file1}`); + expect(await contextMenu.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed for ${file1}`); + expect(await contextMenu.isManageVersionsPresent()).toBe(true, `Manage Versions is not displayed for ${file1}`); + expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${file1}`); + expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${file1}`); + }); + + it('on Favorites - [C286262]', async () => { + await page.clickFavoritesAndWait(); + await dataTable.rightClickOnItem(file1); + + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${file1}`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${file1}`); + expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${file1}`); + expect(await contextMenu.isViewPresent()).toBe(true, `View is not displayed for ${file1}`); + expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${file1}`); + expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${file1}`); + // TODO: change expect to false when ACA-1737 is done + expect(await contextMenu.isMovePresent()).toBe(true, `Move is displayed for ${file1}`); + // TODO: change expect to false when ACA-1737 is done + expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is displayed for ${file1}`); + // TODO: replace with isSharedLinkSettingsPresent when ACA-2175 is done + expect(await toolbar.isSharePresent()).toBe(true, `Share is not displayed`); + expect(await contextMenu.isManageVersionsPresent()).toBe(true, `Manage Versions is not displayed for ${file1}`); + expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${file1}`); + expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${file1}`); + }); + + it('on Search Results - [C291829]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFiles(); + await searchInput.searchForTextAndCloseSearchOptions(file1); + await dataTable.rightClickOnItem(file1); + + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${file1}`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${file1}`); + expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${file1}`); + expect(await contextMenu.isViewPresent()).toBe(true, `View is not displayed for ${file1}`); + expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${file1}`); + expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${file1}`); + expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed for ${file1}`); + expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed for ${file1}`); + expect(await contextMenu.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed`); + expect(await contextMenu.isManageVersionsPresent()).toBe(true, `Manage Versions is not displayed for ${file1}`); + expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${file1}`); + expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${file1}`); + }); + }); - expect(await toolbar.isViewPresent()).toBe(false, `View is displayed for selected files`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for selected files`); - expect(await toolbar.isEditPresent()).toBe(false, `Edit is displayed for selected files`); - await toolbar.openMoreMenu(); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); - expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for selected files`); - expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for selected files`); - expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); - await toolbar.closeMoreMenu(); + describe('context menu actions are correct for a folder', () => { + beforeEach(async (done) => { + await Utils.pressEscape(); + await dataTable.clearSelection(); + await page.clickPersonalFiles(); + done(); + }); + + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + + it('on File Libraries - [C280600]', async () => { + await page.clickFileLibrariesAndWait(); + await dataTable.doubleClickOnRowByName(siteName); + await dataTable.waitForHeader(); + await dataTable.rightClickOnItem(folder1); + + expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${folder1}`); + expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${folder1}`); + expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${folder1}`); + expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${folder1}`); + expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed for ${folder1}`); + expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed for ${folder1}`); + expect(await contextMenu.isViewPresent()).toBe(false, `View is displayed for ${folder1}`); + expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions is displayed for ${folder1}`); + expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed for ${folder1}`); + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${folder1}`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${folder1}`); + }); + + it('on Favorites - [C286263]', async () => { + await page.clickFavoritesAndWait(); + await dataTable.rightClickOnItem(folder1); + + expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${folder1}`); + // TODO: change expect to false when ACA-1737 is done + expect(await contextMenu.isEditFolderPresent()).toBe(true, `Edit folder is displayed for ${folder1}`); + expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${folder1}`); + expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${folder1}`); + // TODO: change expect to false when ACA-1737 is done + expect(await contextMenu.isMovePresent()).toBe(true, `Move is displayed for ${folder1}`); + // TODO: change expect to false when ACA-1737 is done + expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is displayed for ${folder1}`); + expect(await contextMenu.isViewPresent()).toBe(false, `View is displayed for ${folder1}`); + expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions is displayed for ${folder1}`); + expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed for ${folder1}`); + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${folder1}`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${folder1}`); + }); + + it('on Search Results - [C291830]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFolders(); + await searchInput.searchForTextAndCloseSearchOptions(folder1); + await dataTable.rightClickOnItem(folder1); + + expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${folder1}`); + expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${folder1}`); + expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${folder1}`); + expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${folder1}`); + expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed for ${folder1}`); + expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed for ${folder1}`); + expect(await contextMenu.isViewPresent()).toBe(false, `View is displayed for ${folder1}`); + expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions is displayed for ${folder1}`); + expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed for ${folder1}`); + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${folder1}`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${folder1}`); + }); + }); + + describe('context menu actions are correct for multiple selection of files', () => { + beforeEach(async (done) => { + await Utils.pressEscape(); + await dataTable.clearSelection(); + await page.clickPersonalFiles(); + done(); + }); + + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + + it('on File Libraries - [C280647]', async () => { + await page.clickFileLibrariesAndWait(); + await dataTable.doubleClickOnRowByName(siteName); + await dataTable.waitForHeader(); + await dataTable.selectMultipleItems([file1, file2]); + await dataTable.rightClickOnMultipleSelection(); + + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); + expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); + expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); + expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); + expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions is displayed`); + expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed`); + }); + + it('on Shared Files - [C286283]', async () => { + await page.clickSharedFilesAndWait(); + await dataTable.selectMultipleItems([file1, file2]); + await dataTable.rightClickOnMultipleSelection(); + + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); + expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); + expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); + expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); + expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions is displayed`); + expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed`); + }); + + it('on Favorites - [C286280]', async () => { + await page.clickFavoritesAndWait(); + await dataTable.selectMultipleItems([file1, file2]); + await dataTable.rightClickOnMultipleSelection(); + + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); + expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); + expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); + // TODO: change expect to false when ACA-1737 is done + expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is displayed`); + // TODO: change expect to false when ACA-1737 is done + expect(await contextMenu.isMovePresent()).toBe(true, `Move is displayed`); + expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions is displayed`); + expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed`); + }); + + it('on Search Results - [C291834]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFiles(); + await searchInput.searchForTextAndCloseSearchOptions('my-file'); + await dataTable.selectMultipleItems([file1, file2]); + await dataTable.rightClickOnMultipleSelection(); + + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); + expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); + expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); + expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); + expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions is displayed`); + expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed`); + }); + }); + + describe('context menu actions are correct for multiple selection of folders', () => { + beforeEach(async (done) => { + await Utils.pressEscape(); + await dataTable.clearSelection(); + await page.clickPersonalFiles(); + done(); + }); + + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + + it('on File Libraries - [C280666]', async () => { + await page.clickFileLibrariesAndWait(); + await dataTable.doubleClickOnRowByName(siteName); + await dataTable.waitForHeader(); + await dataTable.selectMultipleItems([folder1, folder2]); + await dataTable.rightClickOnMultipleSelection(); + + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed`); + expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); + expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); + expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); + expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); + expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions is displayed`); + expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed`); + }); + + it('on Favorites - [C286281]', async () => { + await page.clickFavoritesAndWait(); + await dataTable.selectMultipleItems([folder1, folder2]); + await dataTable.rightClickOnMultipleSelection(); + + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed`); + expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); + expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); + expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); + // TODO: change expect to false when ACA-1737 is done + expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is displayed`); + // TODO: change expect to false when ACA-1737 is done + expect(await contextMenu.isMovePresent()).toBe(true, `Move is displayed`); + expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions is displayed`); + expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed`); + }); + + it('on Search Results - [C291835]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFolders(); + await searchInput.searchForTextAndCloseSearchOptions('my-folder'); + await dataTable.selectMultipleItems([folder1, folder2]); + await dataTable.rightClickOnMultipleSelection(); + + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed`); + expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); + expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); + expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); + expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); + expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions is displayed`); + expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed`); + }); + }); + + describe('context menu actions are correct when both files and folders are selected', () => { + beforeEach(async (done) => { + await Utils.pressEscape(); + await dataTable.clearSelection(); + await page.clickPersonalFiles(); + done(); + }); + + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + + it('on File Libraries - [C280669]', async () => { + await page.clickFileLibrariesAndWait(); + await dataTable.doubleClickOnRowByName(siteName); + await dataTable.waitForHeader(); + await dataTable.selectMultipleItems([file1, folder1]); + await dataTable.rightClickOnMultipleSelection(); + + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); + expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); + expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); + expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); + expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions is displayed`); + expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed`); + }); + + it('on Favorites - [C286282]', async () => { + await page.clickFavoritesAndWait(); + await dataTable.selectMultipleItems([file1, folder1]); + await dataTable.rightClickOnMultipleSelection(); + + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); + expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); + expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); + // TODO: change expect to false when ACA-1737 is done + expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is displayed`); + // TODO: change expect to false when ACA-1737 is done + expect(await contextMenu.isMovePresent()).toBe(true, `Move is displayed`); + expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions is displayed`); + expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed`); + }); + + it('on Search Results - [C291836]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkFilesAndFolders(); + await searchInput.searchForTextAndCloseSearchOptions('my-f'); + await dataTable.selectMultipleItems([file1, folder1]); + await dataTable.rightClickOnMultipleSelection(); + + expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); + expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); + expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); + expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); + expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions is displayed`); + expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed`); + }); + }); + + describe('toolbar actions appear correctly in the viewer', () => { + beforeEach(async (done) => { + await Utils.pressEscape(); + await dataTable.clearSelection(); + await page.clickPersonalFiles(); + done(); + }); + + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + + it('file from File Libraries - [C268128]', async () => { + await page.clickFileLibrariesAndWait(); + await dataTable.doubleClickOnRowByName(siteName); + await dataTable.waitForHeader(); + await dataTable.doubleClickOnRowByName(docxFile); + await viewer.waitForViewerToOpen(); + + expect(await viewerToolbar.isViewPresent()).toBe(false, `View is displayed`); + expect(await viewerToolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); + expect(await viewerToolbar.isPrintPresent()).toBe(true, `Print is not displayed`); + expect(await viewerToolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); + expect(await viewerToolbar.isSharedLinkSettingsPresent()).toBe(true, 'Shared link settings is not displayed'); + expect(await viewerToolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed`); + + await viewerToolbar.openMoreMenu(); + + expect(await viewerToolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await viewerToolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await viewerToolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await viewerToolbar.menu.isSharePresent()).toBe(false, `Share is displayed in More actions`); + expect(await viewerToolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await viewerToolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); + expect(await viewerToolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); + expect(await viewerToolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); + + await toolbar.closeMoreMenu(); + }); + + it('file from Shared Files - [C286310]', async () => { + await page.clickSharedFilesAndWait(); + await dataTable.doubleClickOnRowByName(docxFile); + await viewer.waitForViewerToOpen(); + + expect(await viewerToolbar.isViewPresent()).toBe(false, `View is displayed`); + expect(await viewerToolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); + expect(await viewerToolbar.isPrintPresent()).toBe(true, `Print is not displayed`); + expect(await viewerToolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); + expect(await viewerToolbar.isSharedLinkSettingsPresent()).toBe(true, 'Shared link settings is not displayed'); + expect(await viewerToolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed`); + + await viewerToolbar.openMoreMenu(); + + expect(await viewerToolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await viewerToolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await viewerToolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await viewerToolbar.menu.isSharePresent()).toBe(false, `Share is displayed in More actions`); + expect(await viewerToolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await viewerToolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); + expect(await viewerToolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); + expect(await viewerToolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); + + await toolbar.closeMoreMenu(); + }); + + it('file from Favorites - [C286311]', async () => { + await page.clickFavoritesAndWait(); + await dataTable.doubleClickOnRowByName(docxFile); + await viewer.waitForViewerToOpen(); + + expect(await viewerToolbar.isViewPresent()).toBe(false, `View is displayed`); + expect(await viewerToolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); + expect(await viewerToolbar.isPrintPresent()).toBe(true, `Print is not displayed`); + expect(await viewerToolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); + expect(await viewerToolbar.isSharedLinkSettingsPresent()).toBe(true, 'Shared link settings is not displayed'); + expect(await viewerToolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed`); + + await viewerToolbar.openMoreMenu(); + + expect(await viewerToolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await viewerToolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await viewerToolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await viewerToolbar.menu.isSharePresent()).toBe(false, `Share is displayed in More actions`); + expect(await viewerToolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); + // TODO: change expect to false when ACA-1737 is done + expect(await viewerToolbar.menu.isMovePresent()).toBe(true, `Move is displayed`); + // TODO: change expect to false when ACA-1737 is done + expect(await viewerToolbar.menu.isDeletePresent()).toBe(true, `Delete is displayed`); + expect(await viewerToolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); + + await toolbar.closeMoreMenu(); + }); }); }); - describe('toolbar actions appear correctly for a file - consumer', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await dataTable.clearSelection(); - await page.clickPersonalFiles(); + describe('Collaborator', () => { + beforeAll(async (done) => { + await loginPage.loginWith(userCollaborator); done(); }); - it('on File Libraries - [C280455]', async () => { + it('on File Libraries - []', async () => { await page.clickFileLibrariesAndWait(); await dataTable.doubleClickOnRowByName(siteName); await dataTable.waitForHeader(); await dataTable.selectItem(file1); + expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${file1}`); expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${file1}`); expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${file1}`); - expect(await toolbar.isEditPresent()).toBe(false, `Edit is displayed for ${file1}`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${file1}`); + expect(await toolbar.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed`); await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed for ${file1}`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${file1}`); expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${file1}`); expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${file1}`); expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${file1}`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${file1}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); + await toolbar.closeMoreMenu(); }); - it('on Shared Files - [C280456]', async () => { + it('on Shared Files - []', async () => { await page.clickSharedFilesAndWait(); await page.dataTable.selectItem(file1); + expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${file1}`); expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${file1}`); expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${file1}`); - expect(await toolbar.isEditPresent()).toBe(false, `Edit is displayed for ${file1}`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${file1}`); + expect(await toolbar.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed`); + await toolbar.openMoreMenu(); + // TODO: change expect to true when ACA-2173 is done + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${file1}`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${file1}`); expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${file1}`); expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${file1}`); expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${file1}`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${file1}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); + await toolbar.closeMoreMenu(); }); - it('on Favorites - [C213121]', async () => { + it('on Favorites - []', async () => { await page.clickFavoritesAndWait(); await dataTable.selectItem(file1); + expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${file1}`); expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${file1}`); expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${file1}`); - expect(await toolbar.isEditPresent()).toBe(false, `Edit is displayed for ${file1}`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${file1}`); + // TODO: replace with isSharedLinkSettingsPresent when ACA-2175 is done + expect(await toolbar.isSharePresent()).toBe(true, `Share is not displayed`); + await toolbar.openMoreMenu(); + + // TODO: change expect to true when ACA-2174 is done + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is not displayed for ${file1}`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${file1}`); expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${file1}`); - // TODO: enable when ACA-1737 is done - // expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${file1}`); - // expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${file1}`); + // TODO: change expect to false when ACA-1737 is done + expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is displayed for ${file1}`); + // TODO: change expect to false when ACA-1737 is done + expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is displayed for ${file1}`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${file1}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); + await toolbar.closeMoreMenu(); }); - it('on Search Results - [C291818]', async () => { + it('on Search Results - []', async () => { await searchInput.clickSearchButton(); await searchInput.checkOnlyFiles(); await searchInput.searchForTextAndCloseSearchOptions(file1); @@ -244,657 +1303,321 @@ describe('Granular permissions available actions : ', () => { expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${file1}`); expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${file1}`); expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${file1}`); - expect(await toolbar.isEditPresent()).toBe(false, `Edit is displayed for ${file1}`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${file1}`); + expect(await toolbar.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed`); await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed for ${file1}`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${file1}`); expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${file1}`); expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${file1}`); expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${file1}`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${file1}`); - await toolbar.closeMoreMenu(); - }); - }); - - describe('toolbar actions appear correctly for a folder - consumer', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await dataTable.clearSelection(); - await page.clickPersonalFiles(); - done(); - }); - - it('on File Libraries - [C280444]', async () => { - await page.clickFileLibrariesAndWait(); - await dataTable.doubleClickOnRowByName(siteName); - await dataTable.waitForHeader(); - await dataTable.selectItem(folder1); - expect(await toolbar.isViewPresent()).toBe(false, `View is displayed for ${folder1}`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${folder1}`); - expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${folder1}`); - expect(await toolbar.isEditPresent()).toBe(false, `Edit is displayed for ${folder1}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); - await toolbar.openMoreMenu(); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${folder1}`); - expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${folder1}`); - expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${folder1}`); - expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${folder1}`); await toolbar.closeMoreMenu(); }); - it('on Favorites - [C286266]', async () => { - await page.clickFavoritesAndWait(); - await dataTable.selectItem(folder1); - expect(await toolbar.isViewPresent()).toBe(false, `View is not displayed for ${folder1}`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${folder1}`); - expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${folder1}`); - // TODO: enable when ACA-1737 is done - // expect(await toolbar.isEditButtonPresent()).toBe(false, `Edit is displayed for ${folder1}`); - await toolbar.openMoreMenu(); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${folder1}`); - // TODO: enable when ACA-1737 is done - // expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${folder1}`); - // expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${folder1}`); - expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${folder1}`); - await toolbar.closeMoreMenu(); - }); - - it('on Search Results - [C291819]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkOnlyFolders(); - await searchInput.searchForTextAndCloseSearchOptions(folder1); - await dataTable.selectItem(folder1); - - expect(await toolbar.isViewPresent()).toBe(false, `View is displayed for ${folder1}`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${folder1}`); - expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${folder1}`); - expect(await toolbar.isEditPresent()).toBe(false, `Edit is displayed for ${folder1}`); - - await toolbar.openMoreMenu(); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${folder1}`); - expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${folder1}`); - expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${folder1}`); - expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${folder1}`); - await toolbar.closeMoreMenu(); + describe('in the viewer', () => { + beforeEach(async (done) => { + await Utils.pressEscape(); + await dataTable.clearSelection(); + await page.clickPersonalFiles(); + done(); + }); + + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + + it('file opened from File Libraries - []', async () => { + await page.clickFileLibrariesAndWait(); + await dataTable.doubleClickOnRowByName(siteName); + await dataTable.waitForHeader(); + await dataTable.doubleClickOnRowByName(docxFile); + await viewer.waitForViewerToOpen(); + + expect(await viewerToolbar.isViewPresent()).toBe(false, `View is displayed`); + expect(await viewerToolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); + expect(await viewerToolbar.isPrintPresent()).toBe(true, `Print is not displayed`); + expect(await viewerToolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); + expect(await viewerToolbar.isSharedLinkSettingsPresent()).toBe(true, 'Shared link settings is not displayed'); + expect(await viewerToolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed`); + + await viewerToolbar.openMoreMenu(); + + expect(await viewerToolbar.menu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed`); + expect(await viewerToolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await viewerToolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await viewerToolbar.menu.isSharePresent()).toBe(false, `Share is displayed in More actions`); + expect(await viewerToolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await viewerToolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); + expect(await viewerToolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); + expect(await viewerToolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); + + await viewerToolbar.closeMoreMenu(); + }); + + it('file opened from Shared Files - []', async () => { + await page.clickSharedFilesAndWait(); + await dataTable.doubleClickOnRowByName(docxFile); + await viewer.waitForViewerToOpen(); + + expect(await viewerToolbar.isViewPresent()).toBe(false, `View is displayed`); + expect(await viewerToolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); + expect(await viewerToolbar.isPrintPresent()).toBe(true, `Print is not displayed`); + expect(await viewerToolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); + expect(await viewerToolbar.isSharedLinkSettingsPresent()).toBe(true, 'Shared link settings is not displayed'); + expect(await viewerToolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed`); + + await viewerToolbar.openMoreMenu(); + + expect(await viewerToolbar.menu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed`); + expect(await viewerToolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await viewerToolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await viewerToolbar.menu.isSharePresent()).toBe(false, `Share is displayed in More actions`); + expect(await viewerToolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await viewerToolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); + expect(await viewerToolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); + expect(await viewerToolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); + + await viewerToolbar.closeMoreMenu(); + }); + + it('file opened from Favorites - []', async () => { + await page.clickFavoritesAndWait(); + await dataTable.doubleClickOnRowByName(docxFile); + await viewer.waitForViewerToOpen(); + + expect(await viewerToolbar.isViewPresent()).toBe(false, `View is displayed`); + expect(await viewerToolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); + expect(await viewerToolbar.isPrintPresent()).toBe(true, `Print is not displayed`); + expect(await viewerToolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); + expect(await viewerToolbar.isSharedLinkSettingsPresent()).toBe(true, 'Shared link settings is not displayed'); + expect(await viewerToolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed`); + + await viewerToolbar.openMoreMenu(); + + expect(await viewerToolbar.menu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed`); + expect(await viewerToolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await viewerToolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await viewerToolbar.menu.isSharePresent()).toBe(false, `Share is displayed in More actions`); + expect(await viewerToolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); + // TODO: change expect to false when ACA-1737 is done + expect(await viewerToolbar.menu.isMovePresent()).toBe(true, `Move is displayed`); + // TODO: change expect to false when ACA-1737 is done + expect(await viewerToolbar.menu.isDeletePresent()).toBe(true, `Delete is displayed`); + expect(await viewerToolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); + + await viewerToolbar.closeMoreMenu(); + }); }); }); - describe('toolbar actions appear correctly for multiple selection of files - consumer', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await dataTable.clearSelection(); - await page.clickPersonalFiles(); + describe('File locked - lock owner : ', () => { + beforeAll(async (done) => { + await loginPage.loginWith(userDemoted); done(); }); - it('on File Libraries - [C280464]', async () => { + it('on File Libraries - []', async () => { await page.clickFileLibrariesAndWait(); await dataTable.doubleClickOnRowByName(siteName); await dataTable.waitForHeader(); - await dataTable.selectMultipleItems([file1, file2]); - expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); - expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await toolbar.isEditPresent()).toBe(false, 'Edit is displayed'); - await toolbar.openMoreMenu(); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); - await toolbar.closeMoreMenu(); - }); + await dataTable.selectItem(fileLocked); - it('on Shared Files - [C286284]', async () => { - await page.clickSharedFilesAndWait(); - await dataTable.selectMultipleItems([file1, file2]); - expect(await toolbar.isViewPresent()).toBe(false, `View is displayed for selected files`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for selected files`); - expect(await toolbar.isEditPresent()).toBe(false, `Edit is displayed for selected files`); - await toolbar.openMoreMenu(); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); - expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for selected files`); - expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for selected files`); - expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); - await toolbar.closeMoreMenu(); - }); + expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileLocked}`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLocked}`); + expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${fileLocked}`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLocked}`); + expect(await toolbar.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed`); - it('on Favorites - [C286285]', async () => { - await page.clickFavoritesAndWait(); - await dataTable.selectMultipleItems([file1, file2]); - expect(await toolbar.isViewPresent()).toBe(false, `View is displayed for selected files`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for selected files`); - expect(await toolbar.isEditPresent()).toBe(false, `Edit is displayed for selected files`); await toolbar.openMoreMenu(); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); - // TODO: enable when ACA-1737 is done - // expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for selected files`); - // expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for selected files`); - expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); - await toolbar.closeMoreMenu(); - }); - it('on Search Results - [C291824]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkOnlyFiles(); - await searchInput.searchForTextAndCloseSearchOptions('my-file'); - await dataTable.selectMultipleItems([file1, file2]); + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileLocked}`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${fileLocked}`); + expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${fileLocked}`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, 'Manage versions is not displayed'); - expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); - expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await toolbar.isEditPresent()).toBe(false, 'Edit is displayed'); - await toolbar.openMoreMenu(); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); - await toolbar.closeMoreMenu(); - }); - }); - - describe('toolbar actions appear correctly for multiple selection of folders - consumer', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await dataTable.clearSelection(); - await page.clickPersonalFiles(); - done(); - }); - - it('on File Libraries - [C280465]', async () => { - await page.clickFileLibrariesAndWait(); - await dataTable.doubleClickOnRowByName(siteName); - await dataTable.waitForHeader(); - await dataTable.selectMultipleItems([folder1, folder2]); - expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); - expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await toolbar.isEditPresent()).toBe(false, 'Edit is displayed'); - await toolbar.openMoreMenu(); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); await toolbar.closeMoreMenu(); }); - it('on Favorites - [C286286]', async () => { - await page.clickFavoritesAndWait(); - await dataTable.selectMultipleItems([folder1, folder2]); - expect(await toolbar.isViewPresent()).toBe(false, `View is displayed for selected files`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for selected files`); - expect(await toolbar.isEditPresent()).toBe(false, `Edit is displayed for selected files`); - await toolbar.openMoreMenu(); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); - // TODO: enable when ACA-1737 is done - // expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for selected files`); - // expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for selected files`); - expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); - await toolbar.closeMoreMenu(); - }); + it('on Shared Files - []', async () => { + await page.clickSharedFilesAndWait(); + await page.dataTable.selectItem(fileLocked); - it('on Search Results - [C291825]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkOnlyFolders(); - await searchInput.searchForTextAndCloseSearchOptions('my-folder'); - await dataTable.selectMultipleItems([folder1, folder2]); + expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileLocked}`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLocked}`); + expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${fileLocked}`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLocked}`); + expect(await toolbar.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed`); - expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); - expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await toolbar.isEditPresent()).toBe(false, 'Edit is displayed'); await toolbar.openMoreMenu(); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); - await toolbar.closeMoreMenu(); - }); - }); - describe('toolbar actions appear correctly for when both files and folders are selected - consumer', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await dataTable.clearSelection(); - await page.clickPersonalFiles(); - done(); - }); + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileLocked}`); + // TODO: change expect to true when ACA-2173 is done + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${fileLocked}`); + expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${fileLocked}`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, 'Manage versions is not displayed'); - it('on File Libraries - [C280466]', async () => { - await page.clickFileLibrariesAndWait(); - await dataTable.doubleClickOnRowByName(siteName); - await dataTable.waitForHeader(); - await dataTable.selectMultipleItems([file1, folder1]); - expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); - expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await toolbar.isEditPresent()).toBe(false, 'Edit is displayed'); - await toolbar.openMoreMenu(); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); await toolbar.closeMoreMenu(); }); - it('on Favorites - [C286287]', async () => { + it('on Favorites - []', async () => { await page.clickFavoritesAndWait(); - await dataTable.selectMultipleItems([file1, folder1]); - expect(await toolbar.isViewPresent()).toBe(false, `View is displayed for selected files`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for selected files`); - expect(await toolbar.isEditPresent()).toBe(false, `Edit is displayed for selected files`); - await toolbar.openMoreMenu(); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); - // TODO: enable when ACA-1737 is done - // expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for selected files`); - // expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for selected files`); - expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); - await toolbar.closeMoreMenu(); - }); + await dataTable.selectItem(fileLocked); - it('on Search Results - [C291826]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkFilesAndFolders(); - await searchInput.searchForTextAndCloseSearchOptions('my-f'); - await dataTable.selectMultipleItems([file1, folder1]); + expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileLocked}`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLocked}`); + expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${fileLocked}`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLocked}`); + // TODO: replace with isSharedLinkSettingsPresent when ACA-2175 is done + expect(await toolbar.isSharePresent()).toBe(true, `Share is not displayed`); - expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); - expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await toolbar.isEditPresent()).toBe(false, 'Edit is displayed'); await toolbar.openMoreMenu(); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); - await toolbar.closeMoreMenu(); - }); - }); - - describe('context menu actions are correct for a file - consumer', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await dataTable.clearSelection(); - await page.clickPersonalFiles(); - done(); - }); - - it('on File Libraries - [C280599]', async () => { - await page.clickFileLibrariesAndWait(); - await dataTable.doubleClickOnRowByName(siteName); - await dataTable.waitForHeader(); - await dataTable.rightClickOnItem(file1); - expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${file1}`); - expect(await contextMenu.isViewPresent()).toBe(true, `View is not displayed for ${file1}`); - expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${file1}`); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${file1}`); - expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed for ${file1}`); - expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed for ${file1}`); - expect(await contextMenu.isSharePresent()).toBe(true, `Share is not displayed for ${file1}`); - expect(await contextMenu.isManageVersionsPresent()).toBe(true, `Manage Versions not displayed for ${file1}`); - expect(await contextMenu.isManagePermissionsPresent()).toBe(false, `Permissions is displayed for ${file1}`); - expect(await contextMenu.isEditPresent()).toBe(false, `Edit is displayed for ${file1}`); - expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${file1}`); - }); - - it('on Shared Files - [C286264]', async () => { - await page.clickSharedFilesAndWait(); - await dataTable.rightClickOnItem(file1); - expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${file1}`); - expect(await contextMenu.isViewPresent()).toBe(true, `View is not displayed for ${file1}`); - expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${file1}`); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${file1}`); - expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed for ${file1}`); - expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed for ${file1}`); - // TODO: enable this when the action is properly implemented: ACA-92 - // expect(await contextMenu.isSharePresent()).toBe(true, `Share is not displayed for ${file1}`); - expect(await contextMenu.isManageVersionsPresent()).toBe(true, `Manage Versions not displayed for ${file1}`); - expect(await contextMenu.isManagePermissionsPresent()).toBe(false, `Permissions is displayed for ${file1}`); - expect(await contextMenu.isEditPresent()).toBe(false, `Edit is displayed for ${file1}`); - expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${file1}`); - }); - - it('on Favorites - [C286262]', async () => { - await page.clickFavoritesAndWait(); - await dataTable.rightClickOnItem(file1); - expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${file1}`); - expect(await contextMenu.isViewPresent()).toBe(true, `View is not displayed for ${file1}`); - expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${file1}`); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${file1}`); - // TODO: enable when ACA-1737 is done - // expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed for ${file1}`); - // expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed for ${file1}`); - expect(await contextMenu.isSharePresent()).toBe(true, `Share is not displayed for ${file1}`); - expect(await contextMenu.isManageVersionsPresent()).toBe(true, `Manage Versions is not displayed for ${file1}`); - // TODO: enable when ACA-1794 is fixed - // expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed for ${file1}`); - expect(await contextMenu.isEditPresent()).toBe(false, `Edit is displayed for ${file1}`); - expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${file1}`); - }); - - it('on Search Results - [C291829]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkOnlyFiles(); - await searchInput.searchForTextAndCloseSearchOptions(file1); - await dataTable.rightClickOnItem(file1); - expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${file1}`); - expect(await contextMenu.isViewPresent()).toBe(true, `View is not displayed for ${file1}`); - expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${file1}`); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${file1}`); - expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed for ${file1}`); - expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed for ${file1}`); - expect(await contextMenu.isSharePresent()).toBe(true, `Share is not displayed for ${file1}`); - expect(await contextMenu.isManageVersionsPresent()).toBe(true, `Manage Versions not displayed for ${file1}`); - expect(await contextMenu.isManagePermissionsPresent()).toBe(false, `Permissions is displayed for ${file1}`); - expect(await contextMenu.isEditPresent()).toBe(false, `Edit is displayed for ${file1}`); - expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${file1}`); - }); - }); - - describe('context menu actions are correct for a folder - consumer', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await dataTable.clearSelection(); - await page.clickPersonalFiles(); - done(); - }); - - it('on File Libraries - [C280600]', async () => { - await page.clickFileLibrariesAndWait(); - await dataTable.doubleClickOnRowByName(siteName); - await dataTable.waitForHeader(); - await dataTable.rightClickOnItem(folder1); - expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${folder1}`); - expect(await contextMenu.isEditPresent()).toBe(false, `Edit is displayed for ${folder1}`); - expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${folder1}`); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${folder1}`); - expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed for ${folder1}`); - expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed for ${folder1}`); - expect(await contextMenu.isManagePermissionsPresent()).toBe(false, `Permissions is displayed for ${folder1}`); - expect(await contextMenu.isViewPresent()).toBe(false, `View is displayed for ${folder1}`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions displayed for ${folder1}`); - expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed for ${folder1}`); - }); - - it('on Favorites - [C286263]', async () => { - await page.clickFavoritesAndWait(); - await dataTable.rightClickOnItem(folder1); - expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${folder1}`); - // enable when ACA-1737 is done - // expect(await contextMenu.isEditPresent()).toBe(false, `Edit is displayed for ${folder1}`); - expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${folder1}`); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${folder1}`); - // TODO: enable when ACA-1737 is done - // expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed for ${folder1}`); - // expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed for ${folder1}`); - // TODO: enable when ACA-1794 is fixed - // expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed for ${folder1}`); - expect(await contextMenu.isViewPresent()).toBe(false, `View is displayed for ${folder1}`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions is displayed for ${folder1}`); - expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed for ${folder1}`); - }); - - it('on Search Results - [C291830]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkOnlyFolders(); - await searchInput.searchForTextAndCloseSearchOptions(folder1); - await dataTable.rightClickOnItem(folder1); - expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${folder1}`); - expect(await contextMenu.isEditPresent()).toBe(false, `Edit is displayed for ${folder1}`); - expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${folder1}`); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${folder1}`); - expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed for ${folder1}`); - expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed for ${folder1}`); - expect(await contextMenu.isManagePermissionsPresent()).toBe(false, `Permissions is displayed for ${folder1}`); - expect(await contextMenu.isViewPresent()).toBe(false, `View is displayed for ${folder1}`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions displayed for ${folder1}`); - expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed for ${folder1}`); - }); - }); - - describe('context menu actions are correct for multiple selection of files - consumer', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await dataTable.clearSelection(); - await page.clickPersonalFiles(); - done(); - }); - - it('on File Libraries - [C280647]', async () => { - await page.clickFileLibrariesAndWait(); - await dataTable.doubleClickOnRowByName(siteName); - await dataTable.waitForHeader(); - await dataTable.selectMultipleItems([file1, file2]); - await dataTable.rightClickOnMultipleSelection(); - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); - expect(await contextMenu.isManagePermissionsPresent()).toBe(false, `Permissions is displayed`); - }); - it('on Shared Files - [C286283]', async () => { - await page.clickSharedFilesAndWait(); - await dataTable.selectMultipleItems([file1, file2]); - await dataTable.rightClickOnMultipleSelection(); - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); - expect(await contextMenu.isManagePermissionsPresent()).toBe(false, `Permissions is displayed`); - }); + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileLocked}`); + // TODO: change expect to true when ACA-2174 is fixed + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLocked}`); + // TODO: change expect to false when ACA-1737 is fixed + expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is displayed for ${fileLocked}`); + // TODO: change expect to false when ACA-1737 is fixed + expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is displayed for ${fileLocked}`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, 'Manage versions is not displayed'); - it('on Favorites - [C286280]', async () => { - await page.clickFavoritesAndWait(); - await dataTable.selectMultipleItems([file1, file2]); - await dataTable.rightClickOnMultipleSelection(); - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); - // TODO: enable when ACA-1737 is done - // expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); - // expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); - expect(await contextMenu.isManagePermissionsPresent()).toBe(false, `Permissions is displayed`); + await toolbar.closeMoreMenu(); }); - it('on Search Results - [C291834]', async () => { + it('on Search Results - []', async () => { await searchInput.clickSearchButton(); await searchInput.checkOnlyFiles(); - await searchInput.searchForTextAndCloseSearchOptions('my-file'); - await dataTable.selectMultipleItems([file1, file2]); - await dataTable.rightClickOnMultipleSelection(); - - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); - expect(await contextMenu.isManagePermissionsPresent()).toBe(false, `Permissions is displayed`); - }); - }); + await searchInput.searchForTextAndCloseSearchOptions(fileLocked); + await dataTable.selectItem(fileLocked); - describe('context menu actions are correct for multiple selection of folders - consumer', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await dataTable.clearSelection(); - await page.clickPersonalFiles(); - done(); - }); + expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileLocked}`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLocked}`); + expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${fileLocked}`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLocked}`); + expect(await toolbar.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed`); - it('on File Libraries - [C280666]', async () => { - await page.clickFileLibrariesAndWait(); - await dataTable.doubleClickOnRowByName(siteName); - await dataTable.waitForHeader(); - await dataTable.selectMultipleItems([folder1, folder2]); - await dataTable.rightClickOnMultipleSelection(); - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); - expect(await contextMenu.isManagePermissionsPresent()).toBe(false, `Permissions is displayed`); - }); - - it('on Favorites - [C286281]', async () => { - await page.clickFavoritesAndWait(); - await dataTable.selectMultipleItems([folder1, folder2]); - await dataTable.rightClickOnMultipleSelection(); - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); - // TODO: enable when ACA-1737 is done - // expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); - // expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); - expect(await contextMenu.isManagePermissionsPresent()).toBe(false, `Permissions is displayed`); - }); - - it('on Search Results - [C291835]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkOnlyFolders(); - await searchInput.searchForTextAndCloseSearchOptions('my-folder'); - await dataTable.selectMultipleItems([folder1, folder2]); - await dataTable.rightClickOnMultipleSelection(); - - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); - expect(await contextMenu.isManagePermissionsPresent()).toBe(false, `Permissions is displayed`); - }); - }); - - describe('context menu actions are correct when both files and folders are selected - consumer', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await dataTable.clearSelection(); - await page.clickPersonalFiles(); - done(); - }); - - it('on File Libraries - [C280669]', async () => { - await page.clickFileLibrariesAndWait(); - await dataTable.doubleClickOnRowByName(siteName); - await dataTable.waitForHeader(); - await dataTable.selectMultipleItems([file1, folder1]); - await dataTable.rightClickOnMultipleSelection(); - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); - expect(await contextMenu.isManagePermissionsPresent()).toBe(false, `Permissions is displayed`); - }); - - it('on Favorites - [C286282]', async () => { - await page.clickFavoritesAndWait(); - await dataTable.selectMultipleItems([file1, folder1]); - await dataTable.rightClickOnMultipleSelection(); - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); - // TODO: enable when ACA-1737 is done - // expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); - // expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); - expect(await contextMenu.isManagePermissionsPresent()).toBe(false, `Permissions is displayed`); - }); - - it('on Search Results - [C291836]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkFilesAndFolders(); - await searchInput.searchForTextAndCloseSearchOptions('my-f'); - await dataTable.selectMultipleItems([file1, folder1]); - await dataTable.rightClickOnMultipleSelection(); - - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); - expect(await contextMenu.isManagePermissionsPresent()).toBe(false, `Permissions is displayed`); - }); - }); - - describe('toolbar actions appear correctly in the viewer - consumer', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await dataTable.clearSelection(); - await page.clickPersonalFiles(); - done(); - }); + await toolbar.openMoreMenu(); - it('file from File Libraries - [C268128]', async () => { - await page.clickFileLibrariesAndWait(); - await dataTable.doubleClickOnRowByName(siteName); - await dataTable.waitForHeader(); - await dataTable.doubleClickOnRowByName(docxFile); - expect(await viewer.isViewerOpened()).toBe(true, 'Viewer is not opened'); - - expect(await viewerToolbar.isEmpty()).toBe(false, `viewer toolbar is empty`); - expect(await viewerToolbar.isViewPresent()).toBe(false, `View is displayed`); - expect(await viewerToolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); - expect(await viewerToolbar.isPrintPresent()).toBe(true, `Print is not displayed`); - expect(await viewerToolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); - expect(await viewerToolbar.isSharedLinkSettingsPresent()).toBe(true, 'Shared link settings is not displayed'); - expect(await viewerToolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed`); - await viewerToolbar.openMoreMenu(); - expect(await viewerToolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); - expect(await viewerToolbar.menu.isSharePresent()).toBe(false, `Share is displayed in More actions`); - expect(await viewerToolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await viewerToolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await viewerToolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await viewerToolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is displayed`); - expect(await viewerToolbar.menu.isManagePermissionsPresent()).toBe(false, `Permissions is displayed`); - await toolbar.closeMoreMenu(); - }); + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileLocked}`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${fileLocked}`); + expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${fileLocked}`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, 'Manage versions is not displayed'); - it('file from Shared Files - [C286310]', async () => { - await page.clickSharedFilesAndWait(); - await dataTable.doubleClickOnRowByName(docxFile); - expect(await viewer.isViewerOpened()).toBe(true, 'Viewer is not opened'); - - expect(await viewerToolbar.isEmpty()).toBe(false, `viewer toolbar is empty`); - expect(await viewerToolbar.isViewPresent()).toBe(false, `View is displayed`); - expect(await viewerToolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); - expect(await viewerToolbar.isPrintPresent()).toBe(true, `Print is not displayed`); - expect(await viewerToolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); - expect(await viewerToolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed`); - await viewerToolbar.openMoreMenu(); - expect(await viewerToolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); - expect(await viewerToolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await viewerToolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await viewerToolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await viewerToolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is displayed`); - expect(await viewerToolbar.menu.isManagePermissionsPresent()).toBe(false, `Permissions is displayed`); await toolbar.closeMoreMenu(); }); - it('file from Favorites - [C286311]', async () => { - await page.clickFavoritesAndWait(); - await dataTable.doubleClickOnRowByName(docxFile); - expect(await viewer.isViewerOpened()).toBe(true, 'Viewer is not opened'); - - expect(await viewerToolbar.isEmpty()).toBe(false, `viewer toolbar is empty`); - expect(await viewerToolbar.isViewPresent()).toBe(false, `View is displayed`); - expect(await viewerToolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); - expect(await viewerToolbar.isPrintPresent()).toBe(true, `Print is not displayed`); - expect(await viewerToolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); - expect(await viewerToolbar.isSharedLinkSettingsPresent()).toBe(true, 'Shared link settings is not displayed'); - expect(await viewerToolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed`); - await viewerToolbar.openMoreMenu(); - expect(await viewerToolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); - expect(await viewerToolbar.menu.isSharePresent()).toBe(false, `Share is displayed in More actions`); - expect(await viewerToolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - // TODO: enable when ACA-1737 is done - // expect(await viewerToolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); - // expect(await viewerToolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await viewerToolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is displayed`); - expect(await viewerToolbar.menu.isManagePermissionsPresent()).toBe(false, `Permissions is displayed`); - await toolbar.closeMoreMenu(); + describe('in the viewer', () => { + beforeEach(async (done) => { + await Utils.pressEscape(); + await dataTable.clearSelection(); + await page.clickPersonalFiles(); + done(); + }); + + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + + it('file opened from File Libraries - []', async () => { + await page.clickFileLibrariesAndWait(); + await dataTable.doubleClickOnRowByName(siteName); + await dataTable.waitForHeader(); + await dataTable.doubleClickOnRowByName(fileLocked); + await viewer.waitForViewerToOpen(); + + expect(await viewerToolbar.isViewPresent()).toBe(false, `View is displayed`); + expect(await viewerToolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); + expect(await viewerToolbar.isPrintPresent()).toBe(true, `Print is not displayed`); + expect(await viewerToolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); + expect(await viewerToolbar.isSharedLinkSettingsPresent()).toBe(true, 'Shared link settings is not displayed'); + expect(await viewerToolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed`); + + await viewerToolbar.openMoreMenu(); + + expect(await viewerToolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await viewerToolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed`); + expect(await viewerToolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await viewerToolbar.menu.isSharePresent()).toBe(false, `Share is displayed in More actions`); + expect(await viewerToolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await viewerToolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); + expect(await viewerToolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); + expect(await viewerToolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); + + await viewerToolbar.closeMoreMenu(); + }); + + it('file opened from Shared Files - []', async () => { + await page.clickSharedFilesAndWait(); + await dataTable.doubleClickOnRowByName(fileLocked); + await viewer.waitForViewerToOpen(); + + expect(await viewerToolbar.isViewPresent()).toBe(false, `View is displayed`); + expect(await viewerToolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); + expect(await viewerToolbar.isPrintPresent()).toBe(true, `Print is not displayed`); + expect(await viewerToolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); + expect(await viewerToolbar.isSharedLinkSettingsPresent()).toBe(true, 'Shared link settings is not displayed'); + expect(await viewerToolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed`); + + await viewerToolbar.openMoreMenu(); + + expect(await viewerToolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await viewerToolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed`); + expect(await viewerToolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await viewerToolbar.menu.isSharePresent()).toBe(false, `Share is displayed in More actions`); + expect(await viewerToolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await viewerToolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); + expect(await viewerToolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); + expect(await viewerToolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); + + await viewerToolbar.closeMoreMenu(); + }); + + it('file opened from Favorites - []', async () => { + await page.clickFavoritesAndWait(); + await dataTable.doubleClickOnRowByName(fileLocked); + await viewer.waitForViewerToOpen(); + + expect(await viewerToolbar.isEmpty()).toBe(false, `viewer toolbar is empty`); + expect(await viewerToolbar.isViewPresent()).toBe(false, `View is displayed`); + expect(await viewerToolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); + expect(await viewerToolbar.isPrintPresent()).toBe(true, `Print is not displayed`); + expect(await viewerToolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); + expect(await viewerToolbar.isSharedLinkSettingsPresent()).toBe(true, 'Shared link settings is not displayed'); + expect(await viewerToolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed`); + + await viewerToolbar.openMoreMenu(); + + expect(await viewerToolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await viewerToolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed`); + expect(await viewerToolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await viewerToolbar.menu.isSharePresent()).toBe(false, `Share is displayed in More actions`); + expect(await viewerToolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); + // TODO: change expect to false when ACA-1737 is done + expect(await viewerToolbar.menu.isMovePresent()).toBe(true, `Move is displayed`); + // TODO: change expect to false when ACA-1737 is done + expect(await viewerToolbar.menu.isDeletePresent()).toBe(true, `Delete is displayed`); + expect(await viewerToolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); + + await viewerToolbar.closeMoreMenu(); + }); }); }); }); diff --git a/e2e/suites/actions/toolbar-multiple-selection.test.ts b/e2e/suites/actions/toolbar-multiple-selection.test.ts index 4969326760..28120420d2 100755 --- a/e2e/suites/actions/toolbar-multiple-selection.test.ts +++ b/e2e/suites/actions/toolbar-multiple-selection.test.ts @@ -32,30 +32,29 @@ import { Utils } from '../../utilities/utils'; describe('Toolbar actions - multiple selection : ', () => { const username = `user-${Utils.random()}`; - const file1 = `my-file1-${Utils.random()}.txt`; - let file1Id; - const file2 = `my-file2-${Utils.random()}.txt`; - let file2Id; - - const folder1 = `my-folder1-${Utils.random()}`; - let folder1Id; - const folder2 = `my-folder2-${Utils.random()}`; - let folder2Id; - - const fileForDelete1 = `file-${Utils.random()}.txt`; - let fileForDelete1Id; - const fileForDelete2 = `file-${Utils.random()}.txt`; - let fileForDelete2Id; - const folderForDelete1 = `folder-${Utils.random()}`; - let folderForDelete1Id; - const folderForDelete2 = `folder-${Utils.random()}`; - let folderForDelete2Id; + const parent = `parent-${Utils.random()}`; let parentId; + + const file1 = `my-file1-${Utils.random()}.txt`; let file1Id; + const file2 = `my-file2-${Utils.random()}.txt`; let file2Id; + + const folder1 = `my-folder1-${Utils.random()}`; let folder1Id; + const folder2 = `my-folder2-${Utils.random()}`; let folder2Id; + + const fileForDelete1 = `file-${Utils.random()}.txt`; let fileForDelete1Id; + const fileForDelete2 = `file-${Utils.random()}.txt`; let fileForDelete2Id; + const folderForDelete1 = `folder-${Utils.random()}`; let folderForDelete1Id; + const folderForDelete2 = `folder-${Utils.random()}`; let folderForDelete2Id; const siteName = `site-${Utils.random()}`; const file1InSite = `my-fileInSite1-${Utils.random()}.txt`; const file2InSite = `my-fileInSite2-${Utils.random()}.txt`; const folder1InSite = `my-folderInSite1-${Utils.random()}`; const folder2InSite = `my-folderInSite2-${Utils.random()}`; + const fileLocked1InSite = `my-fileLockedInSite1-${Utils.random()}.txt`; let fileLocked1InSiteId; + const fileLocked2InSite = `my-fileLockedInSite2-${Utils.random()}.txt`; let fileLocked2InSiteId; + + const fileLocked1 = `my-fileLocked1-${Utils.random()}.txt`; let fileLocked1Id; + const fileLocked2 = `my-fileLocked2-${Utils.random()}.txt`; let fileLocked2Id; const apis = { admin: new RepoClient(), @@ -71,21 +70,27 @@ describe('Toolbar actions - multiple selection : ', () => { beforeAll(async (done) => { await apis.admin.people.createUser({ username }); - file1Id = (await apis.user.nodes.createFiles([file1])).entry.id; - file2Id = (await apis.user.nodes.createFiles([file2])).entry.id; - folder1Id = (await apis.user.nodes.createFolders([folder1])).entry.id; - folder2Id = (await apis.user.nodes.createFolders([folder2])).entry.id; - fileForDelete1Id = (await apis.user.nodes.createFiles([fileForDelete1])).entry.id; - fileForDelete2Id = (await apis.user.nodes.createFiles([fileForDelete2])).entry.id; - folderForDelete1Id = (await apis.user.nodes.createFolders([folderForDelete1])).entry.id; - folderForDelete2Id = (await apis.user.nodes.createFolders([folderForDelete2])).entry.id; - - await apis.user.shared.shareFilesByIds([file1Id, file2Id]); - await apis.user.shared.waitForApi({ expect: 2 }); - - await apis.user.favorites.addFavoritesByIds('file', [file1Id, file2Id]); + parentId = (await apis.user.nodes.createFolder(parent)).entry.id; + + file1Id = (await apis.user.nodes.createFile(file1, parentId)).entry.id; + file2Id = (await apis.user.nodes.createFile(file2, parentId)).entry.id; + folder1Id = (await apis.user.nodes.createFolder(folder1, parentId)).entry.id; + folder2Id = (await apis.user.nodes.createFolder(folder2, parentId)).entry.id; + fileForDelete1Id = (await apis.user.nodes.createFile(fileForDelete1, parentId)).entry.id; + fileForDelete2Id = (await apis.user.nodes.createFile(fileForDelete2, parentId)).entry.id; + folderForDelete1Id = (await apis.user.nodes.createFolder(folderForDelete1, parentId)).entry.id; + folderForDelete2Id = (await apis.user.nodes.createFolder(folderForDelete2, parentId)).entry.id; + fileLocked1Id = (await apis.user.nodes.createFile(fileLocked1, parentId)).entry.id; + fileLocked2Id = (await apis.user.nodes.createFile(fileLocked2, parentId)).entry.id; + await apis.user.nodes.lockFile(fileLocked1Id); + await apis.user.nodes.lockFile(fileLocked2Id); + + await apis.user.shared.shareFilesByIds([file1Id, file2Id, fileLocked1Id, fileLocked2Id]); + await apis.user.shared.waitForApi({ expect: 4 }); + + await apis.user.favorites.addFavoritesByIds('file', [file1Id, file2Id, fileLocked1Id, fileLocked2Id]); await apis.user.favorites.addFavoritesByIds('folder', [folder1Id, folder2Id]); - await apis.user.favorites.waitForApi({ expect: 4 }); + await apis.user.favorites.waitForApi({ expect: 6 }); await apis.user.nodes.deleteNodesById([fileForDelete1Id, fileForDelete2Id, folderForDelete1Id, folderForDelete2Id], false); await apis.user.trashcan.waitForApi({ expect: 4 }); @@ -96,7 +101,13 @@ describe('Toolbar actions - multiple selection : ', () => { await apis.user.nodes.createFile(file2InSite, docLibId); await apis.user.nodes.createFolder(folder1InSite, docLibId); await apis.user.nodes.createFolder(folder2InSite, docLibId); - await apis.user.search.waitForApi(username, { expect: 4 }); + fileLocked1InSiteId = (await apis.user.nodes.createFile(fileLocked1InSite, docLibId)).entry.id; + fileLocked2InSiteId = (await apis.user.nodes.createFile(fileLocked2InSite, docLibId)).entry.id; + + await apis.user.nodes.lockFile(fileLocked1InSiteId); + await apis.user.nodes.lockFile(fileLocked2InSiteId); + + await apis.user.search.waitForApi(username, { expect: 6 }); await loginPage.loginWith(username); done(); @@ -104,7 +115,7 @@ describe('Toolbar actions - multiple selection : ', () => { afterAll(async (done) => { await Promise.all([ - apis.user.nodes.deleteNodesById([file1Id, file2Id, folder1Id, folder2Id]), + apis.user.nodes.deleteNodeById(parentId), apis.user.trashcan.emptyTrash(), apis.user.sites.deleteSite(siteName) ]); @@ -116,13 +127,23 @@ describe('Toolbar actions - multiple selection : ', () => { await Utils.pressEscape(); await dataTable.clearSelection(); await page.clickPersonalFilesAndWait(); + await dataTable.doubleClickOnRowByName(parent); + await dataTable.waitForBody(); + done(); + }); + + afterAll(async (done) => { + await Utils.pressEscape(); done(); }); it('Unselect items with single click - [C280458]', async () => { await dataTable.selectMultipleItems([file1, file2, folder1, folder2]); + expect(await dataTable.countSelectedRows()).toEqual(4, 'incorrect selected rows number'); + await dataTable.selectItem(file1); + expect(await dataTable.countSelectedRows()).toEqual(1, 'incorrect selected rows number'); }); @@ -133,7 +154,9 @@ describe('Toolbar actions - multiple selection : ', () => { await dataTable.selectItem(folder1); await dataTable.selectItem(folder2); await browser.actions().sendKeys(protractor.Key.NULL).perform(); + expect(await dataTable.countSelectedRows()).toEqual(4, 'incorrect selected rows number'); + await browser.actions().sendKeys(protractor.Key.COMMAND).perform(); await dataTable.selectItem(file1); await dataTable.selectItem(file2); @@ -144,40 +167,81 @@ describe('Toolbar actions - multiple selection : ', () => { it('correct actions appear when multiple files are selected - [C217112]', async () => { await dataTable.selectMultipleItems([file1, file2]); + + expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); + expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); + expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); + expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for selected files`); + expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for selected files`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); + + await toolbar.closeMoreMenu(); + }); + + it('correct actions appear when multiple locked files are selected - []', async () => { + await dataTable.selectMultipleItems([fileLocked1, fileLocked2]); + expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await toolbar.isEditPresent()).toBe(false, 'Edit is displayed'); + expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); + await toolbar.openMoreMenu(); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for selected files`); expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for selected files`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); + await toolbar.closeMoreMenu(); }); it('correct actions appear when multiple folders are selected - [C280459]', async () => { await dataTable.selectMultipleItems([folder1, folder2]); + expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await toolbar.isEditPresent()).toBe(false, 'Edit is displayed'); + expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); + await toolbar.openMoreMenu(); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for selected files`); expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for selected files`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); + await toolbar.closeMoreMenu(); }); it('correct actions appear when both files and folders are selected - [C280460]', async () => { await dataTable.selectMultipleItems([file1, file2, folder1, folder2]); + expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await toolbar.isEditPresent()).toBe(false, 'Edit is displayed'); + expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); + await toolbar.openMoreMenu(); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for selected files`); expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for selected files`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); + await toolbar.closeMoreMenu(); }); }); @@ -191,42 +255,88 @@ describe('Toolbar actions - multiple selection : ', () => { done(); }); + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + it('correct actions appear when multiple files are selected - [C280461]', async () => { await dataTable.selectMultipleItems([file1InSite, file2InSite]); + expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed for selected files'); expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed for selected files'); - expect(await toolbar.isEditPresent()).toBe(false, 'Edit is displayed for selected files'); + expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed for selected files'); + await toolbar.openMoreMenu(); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for selected files`); expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for selected files`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); + + await toolbar.closeMoreMenu(); + }); + + it('correct actions appear when multiple locked files are selected - []', async () => { + await dataTable.selectMultipleItems([fileLocked1InSite, fileLocked2InSite]); + + expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed for selected files'); + expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed for selected files'); + expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed for selected files'); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); + expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for selected files`); + expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for selected files`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); + await toolbar.closeMoreMenu(); }); it('correct actions appear when multiple folders are selected - [C280462]', async () => { await dataTable.selectMultipleItems([folder1InSite, folder2InSite]); + expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await toolbar.isEditPresent()).toBe(false, 'Edit is displayed'); + expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); + await toolbar.openMoreMenu(); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for selected files`); expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for selected files`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); + await toolbar.closeMoreMenu(); }); it('correct actions appear when both files and folders are selected - [C280463]', async () => { await dataTable.selectMultipleItems([file1InSite, file2InSite, folder1InSite, folder2InSite]); + expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await toolbar.isEditPresent()).toBe(false, 'Edit is displayed'); + expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); + await toolbar.openMoreMenu(); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for selected files`); expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for selected files`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); + await toolbar.closeMoreMenu(); }); }); @@ -239,16 +349,48 @@ describe('Toolbar actions - multiple selection : ', () => { done(); }); + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + it('correct actions appear when multiple files are selected - [C280467]', async () => { await dataTable.selectMultipleItems([file1, file2]); + expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed for selected files'); - expect(await toolbar.isEditPresent()).toBe(false, 'Edit is displayed for selected files'); + expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed for selected files'); + await toolbar.openMoreMenu(); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for selected files`); expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for selected files`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); + + await toolbar.closeMoreMenu(); + }); + + it('correct actions appear when multiple locked files are selected - []', async () => { + await dataTable.selectMultipleItems([fileLocked1, fileLocked2]); + + expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); + expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed for selected files'); + expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed for selected files'); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); + expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for selected files`); + expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for selected files`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); + await toolbar.closeMoreMenu(); }); }); @@ -261,16 +403,48 @@ describe('Toolbar actions - multiple selection : ', () => { done(); }); + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + it('correct actions appear when multiple files are selected - [C280468]', async () => { await dataTable.selectMultipleItems([file1, file2]); + expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await toolbar.isEditPresent()).toBe(false, 'Edit is displayed'); + expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); + expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for selected files`); + expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for selected files`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); + + await toolbar.closeMoreMenu(); + }); + + it('correct actions appear when multiple locked files are selected - []', async () => { + await dataTable.selectMultipleItems([fileLocked1, fileLocked2]); + + expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); + expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); + expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); + await toolbar.openMoreMenu(); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for selected files`); expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for selected files`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); + await toolbar.closeMoreMenu(); }); }); @@ -283,42 +457,88 @@ describe('Toolbar actions - multiple selection : ', () => { done(); }); + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + it('correct actions appear when multiple files are selected - [C280469]', async () => { await dataTable.selectMultipleItems([file1, file2]); + expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await toolbar.isEditPresent()).toBe(false, 'Edit is displayed'); + expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); + await toolbar.openMoreMenu(); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for selected files`); expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for selected files`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); + + await toolbar.closeMoreMenu(); + }); + + it('correct actions appear when multiple locked files are selected - []', async () => { + await dataTable.selectMultipleItems([fileLocked1, fileLocked2]); + + expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); + expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); + expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); + expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for selected files`); + expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for selected files`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); + await toolbar.closeMoreMenu(); }); it('correct actions appear when multiple folders are selected - [C280470]', async () => { await dataTable.selectMultipleItems([folder1, folder2]); + expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await toolbar.isEditPresent()).toBe(false, 'Edit is displayed'); + expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); + await toolbar.openMoreMenu(); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for selected files`); expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for selected files`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); + await toolbar.closeMoreMenu(); }); it('correct actions appear when both files and folders are selected - [C280471]', async () => { await dataTable.selectMultipleItems([file1, file2, folder1, folder2]); + expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed for selected files'); - expect(await toolbar.isEditPresent()).toBe(false, 'Edit is displayed'); + expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); + await toolbar.openMoreMenu(); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for selected files`); expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for selected files`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); + await toolbar.closeMoreMenu(); }); }); @@ -329,20 +549,28 @@ describe('Toolbar actions - multiple selection : ', () => { done(); }); + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + it('correct actions appear when multiple files are selected - [C280472]', async () => { await dataTable.selectMultipleItems([fileForDelete1, fileForDelete2]); + expect(await toolbar.isButtonPresent('Permanently delete')).toBe(true, 'Permanently delete is displayed'); expect(await toolbar.isButtonPresent('Restore')).toBe(true, 'Restore is not displayed'); }); it('correct actions appear when multiple folders are selected - [C280473]', async () => { await dataTable.selectMultipleItems([folderForDelete1, folderForDelete2]); + expect(await toolbar.isButtonPresent('Permanently delete')).toBe(true, 'Permanently delete is displayed'); expect(await toolbar.isButtonPresent('Restore')).toBe(true, 'Restore is not displayed'); }); it('correct actions appear when both files and folders are selected - [C280474]', async () => { await dataTable.selectMultipleItems([fileForDelete1, fileForDelete2, folderForDelete1, folderForDelete2]); + expect(await toolbar.isButtonPresent('Permanently delete')).toBe(true, 'Permanently delete is displayed'); expect(await toolbar.isButtonPresent('Restore')).toBe(true, 'Restore is not displayed'); }); @@ -355,6 +583,11 @@ describe('Toolbar actions - multiple selection : ', () => { done(); }); + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + it('correct actions appear when multiple files are selected - [C291820]', async () => { await searchInput.clickSearchButton(); await searchInput.checkOnlyFiles(); @@ -363,12 +596,41 @@ describe('Toolbar actions - multiple selection : ', () => { expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed for selected files'); expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed for selected files'); - expect(await toolbar.isEditPresent()).toBe(false, 'Edit is displayed for selected files'); + expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed for selected files'); + await toolbar.openMoreMenu(); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for selected files`); expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for selected files`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); + + await toolbar.closeMoreMenu(); + }); + + it('correct actions appear when multiple locked files are selected - []', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFiles(); + await searchInput.searchForTextAndCloseSearchOptions('my-fileLockedInSite'); + await dataTable.selectMultipleItems([fileLocked1InSite, fileLocked2InSite]); + + expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed for selected files'); + expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed for selected files'); + expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed for selected files'); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); + expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for selected files`); + expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for selected files`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); + await toolbar.closeMoreMenu(); }); @@ -380,12 +642,18 @@ describe('Toolbar actions - multiple selection : ', () => { expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await toolbar.isEditPresent()).toBe(false, 'Edit is displayed'); + expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); + await toolbar.openMoreMenu(); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for selected files`); expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for selected files`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); + await toolbar.closeMoreMenu(); }); @@ -397,12 +665,18 @@ describe('Toolbar actions - multiple selection : ', () => { expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await toolbar.isEditPresent()).toBe(false, 'Edit is displayed'); + expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); + await toolbar.openMoreMenu(); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for selected files`); expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for selected files`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); + await toolbar.closeMoreMenu(); }); }); diff --git a/e2e/suites/actions/toolbar-single-selection.test.ts b/e2e/suites/actions/toolbar-single-selection.test.ts index 57f10ba3fe..7386e3ddeb 100755 --- a/e2e/suites/actions/toolbar-single-selection.test.ts +++ b/e2e/suites/actions/toolbar-single-selection.test.ts @@ -35,9 +35,11 @@ describe('Toolbar actions - single selection : ', () => { const folderUser = `folderUser-${Utils.random()}`; let folderUserId; const fileForDelete = `fileForDelete-${Utils.random()}.txt`; let fileForDeleteId; const folderForDelete = `folderForDelete-${Utils.random()}`; let folderForDeleteId; + const fileLocked = `fileLocked-${Utils.random()}.txt`; let fileLockedId; const siteName = `site-${Utils.random()}`; const fileInSite = `file-site-${Utils.random()}.txt`; + const fileLockedInSite = `file-locked-site-${Utils.random()}.txt`; let fileLockedInSiteId; const folderInSite = `folder-site-${Utils.random()}`; const adminPublic = `admin-public-${Utils.random()}`; @@ -61,19 +63,27 @@ describe('Toolbar actions - single selection : ', () => { fileForDeleteId = (await apis.user.nodes.createFile(fileForDelete)).entry.id; folderForDeleteId = (await apis.user.nodes.createFolder(folderForDelete)).entry.id; folderUserId = (await apis.user.nodes.createFolder(folderUser)).entry.id; + fileLockedId = (await apis.user.nodes.createFile(fileLocked)).entry.id; await apis.user.shared.shareFileById(fileUserId); - await apis.user.shared.waitForApi({ expect: 1 }); + await apis.user.shared.shareFileById(fileLockedId); + await apis.user.shared.waitForApi({ expect: 2 }); await apis.user.favorites.addFavoriteById('file', fileUserId); await apis.user.favorites.addFavoriteById('folder', folderUserId); - await apis.user.favorites.waitForApi({ expect: 2 }); + await apis.user.favorites.addFavoriteById('file', fileLockedId); + await apis.user.favorites.waitForApi({ expect: 3 }); + + await apis.user.nodes.lockFile(fileLockedId); await apis.user.sites.createSite(siteName, SITE_VISIBILITY.PRIVATE); const docLibId = await apis.user.sites.getDocLibId(siteName); await apis.user.nodes.createFile(fileInSite, docLibId); + fileLockedInSiteId = (await apis.user.nodes.createFile(fileLockedInSite, docLibId)).entry.id; await apis.user.nodes.createFolder(folderInSite, docLibId); + await apis.user.nodes.lockFile(fileLockedInSiteId); + await apis.user.nodes.deleteNodeById(fileForDeleteId, false); await apis.user.nodes.deleteNodeById(folderForDeleteId, false); @@ -109,8 +119,14 @@ describe('Toolbar actions - single selection : ', () => { done(); }); + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + it('selected row is marked with a check circle icon - [C213134]', async () => { await dataTable.selectItem(fileUser); + expect(await dataTable.hasCheckMarkIcon(fileUser)).toBe(true, 'check mark missing'); }); @@ -120,29 +136,64 @@ describe('Toolbar actions - single selection : ', () => { it('correct actions appear when a file is selected - [C213122]', async () => { await dataTable.selectItem(fileUser); + expect(await toolbar.isEmpty()).toBe(false, `actions not displayed for ${fileUser}`); expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileUser}`); expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileUser}`); - expect(await toolbar.isEditPresent()).toBe(false, `Edit is displayed for ${fileUser}`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileUser}`); + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed for ${fileUser}`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${fileUser}`); expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileUser}`); expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${fileUser}`); expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for ${fileUser}`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${fileUser}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed for ${fileUser}`); + + await toolbar.closeMoreMenu(); + }); + + it('correct actions appear when a locked file is selected - []', async () => { + await dataTable.selectItem(fileLocked); + + expect(await toolbar.isEmpty()).toBe(false, `actions not displayed for ${fileLocked}`); + expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileLocked}`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLocked}`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLocked}`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileLocked}`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed for ${fileLocked}`); + await toolbar.closeMoreMenu(); }); it('correct actions appear when a folder is selected - [C213123]', async () => { await dataTable.selectItem(folderUser); + expect(await toolbar.isEmpty()).toBe(false, `actions not displayed for ${folderUser}`); expect(await toolbar.isViewPresent()).toBe(false, `View is displayed for ${folderUser}`); expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not enabled for ${folderUser}`); - expect(await toolbar.isEditPresent()).toBe(true, `Edit is not displayed for ${folderUser}`); + expect(await toolbar.isEditFolderPresent()).toBe(true, `Edit folder is not displayed for ${folderUser}`); + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${folderUser}`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${folderUser}`); expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${folderUser}`); expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${folderUser}`); expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for ${folderUser}`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${folderUser}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed for ${folderUser}`); + await toolbar.closeMoreMenu(); }); }); @@ -156,35 +207,75 @@ describe('Toolbar actions - single selection : ', () => { done(); }); + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + it('actions are not displayed when no item is selected - [C280439]', async () => { expect(await toolbar.isEmpty()).toBe(true, `actions displayed though nothing selected`); }); it('correct actions appear when a file is selected - [C280440]', async () => { await dataTable.selectItem(fileInSite); + expect(await toolbar.isEmpty()).toBe(false, `actions not displayed for ${fileInSite}`); expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileInSite}`); expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileInSite}`); - expect(await toolbar.isEditPresent()).toBe(false, `Edit is displayed for ${fileInSite}`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileInSite}`); + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed for ${fileInSite}`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${fileInSite}`); expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileInSite}`); expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${fileInSite}`); expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for ${fileInSite}`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${fileInSite}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed for ${fileInSite}`); + + await toolbar.closeMoreMenu(); + }); + + it('correct actions appear when a locked file is selected - []', async () => { + await dataTable.selectItem(fileLockedInSite); + + expect(await toolbar.isEmpty()).toBe(false, `actions not displayed for ${fileLockedInSite}`); + expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileLockedInSite}`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLockedInSite}`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLockedInSite}`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileLockedInSite}`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed for ${fileLockedInSite}`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLockedInSite}`); + expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${fileLockedInSite}`); + expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for ${fileLockedInSite}`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${fileLockedInSite}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed for ${fileLockedInSite}`); + await toolbar.closeMoreMenu(); }); it('correct actions appear when a folder is selected - [C280441]', async () => { await dataTable.selectItem(folderInSite); + expect(await toolbar.isEmpty()).toBe(false, `actions not displayed for ${folderInSite}`); expect(await toolbar.isViewPresent()).toBe(false, `View is displayed for ${folderInSite}`); expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not enabled for ${folderInSite}`); - expect(await toolbar.isEditPresent()).toBe(true, `Edit is not displayed for ${folderInSite}`); + expect(await toolbar.isEditFolderPresent()).toBe(true, `Edit folder is not displayed for ${folderInSite}`); + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${folderInSite}`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${folderInSite}`); expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${folderInSite}`); expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${folderInSite}`); expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for ${folderInSite}`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${folderInSite}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed for ${folderInSite}`); + await toolbar.closeMoreMenu(); }); }); @@ -196,6 +287,7 @@ describe('Toolbar actions - single selection : ', () => { }); afterAll(async (done) => { + await Utils.pressEscape(); await page.clickPersonalFiles(); done(); }); @@ -203,48 +295,64 @@ describe('Toolbar actions - single selection : ', () => { it('Available actions for a library - My Libraries - [C213135]', async () => { await page.goToMyLibrariesAndWait(); await dataTable.selectItem(siteName); + expect(await toolbar.isEmpty()).toBe(false, 'toolbar not displayed'); expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${siteName}`); expect(await toolbar.isButtonPresent('Leave library')).toBe(true, `Leave is not displayed for ${siteName}`); + await toolbar.openMoreMenu(); + expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${siteName}`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${siteName}`); + await toolbar.closeMoreMenu(); }); it('Available actions for a library - Favorite Libraries - user is a member - [C289892]', async () => { await page.goToFavoriteLibrariesAndWait(); await dataTable.selectItem(siteName); + expect(await toolbar.isEmpty()).toBe(false, 'toolbar not displayed'); expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${siteName}`); expect(await toolbar.isButtonPresent('Leave library')).toBe(true, `Leave is not displayed for ${siteName}`); + await toolbar.openMoreMenu(); + expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${siteName}`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${siteName}`); + await toolbar.closeMoreMenu(); }); it('Available actions for a library - Favorite Libraries - user is not a member - [C290090]', async () => { await page.goToFavoriteLibrariesAndWait(); await dataTable.selectItem(adminPublic); + expect(await toolbar.isEmpty()).toBe(false, 'toolbar not displayed'); expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${adminPublic}`); expect(await toolbar.isButtonPresent('Join')).toBe(true, `Join is not displayed for ${adminPublic}`); + await toolbar.openMoreMenu(); + expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${adminPublic}`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${adminPublic}`); + await toolbar.closeMoreMenu(); }); it('Available actions for a moderated library - Favorite Libraries - user requested to join - [C290091]', async () => { await page.goToFavoriteLibrariesAndWait(); await dataTable.selectItem(adminModerated); + expect(await toolbar.isEmpty()).toBe(false, 'toolbar not displayed'); expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${adminModerated}`); expect(await toolbar.isButtonPresent('Cancel join request')).toBe(true, `Cancel join is not displayed for ${adminModerated}`); + await toolbar.openMoreMenu(); + expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${adminModerated}`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${adminModerated}`); + await toolbar.closeMoreMenu(); }); @@ -257,9 +365,12 @@ describe('Toolbar actions - single selection : ', () => { expect(await toolbar.isEmpty()).toBe(false, 'toolbar not displayed'); expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${siteName}`); expect(await toolbar.isButtonPresent('Leave library')).toBe(true, `Leave is not displayed for ${siteName}`); + await toolbar.openMoreMenu(); + expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${siteName}`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${siteName}`); + await toolbar.closeMoreMenu(); }); @@ -272,9 +383,12 @@ describe('Toolbar actions - single selection : ', () => { expect(await toolbar.isEmpty()).toBe(false, 'toolbar not displayed'); expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${adminPublic}`); expect(await toolbar.isButtonPresent('Join')).toBe(true, `Join is not displayed for ${adminPublic}`); + await toolbar.openMoreMenu(); + expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${adminPublic}`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${adminPublic}`); + await toolbar.closeMoreMenu(); }); @@ -287,9 +401,12 @@ describe('Toolbar actions - single selection : ', () => { expect(await toolbar.isEmpty()).toBe(false, 'toolbar not displayed'); expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${adminModerated}`); expect(await toolbar.isButtonPresent('Cancel join request')).toBe(true, `Cancel join is not displayed for ${adminModerated}`); + await toolbar.openMoreMenu(); + expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${adminModerated}`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${adminModerated}`); + await toolbar.closeMoreMenu(); }); }); @@ -301,22 +418,58 @@ describe('Toolbar actions - single selection : ', () => { done(); }); + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + it('actions are not displayed when no item is selected - [C280445]', async () => { expect(await toolbar.isEmpty()).toBe(true, `actions displayed though nothing selected`); }); it('correct actions appear when a file is selected - [C286265]', async () => { await page.dataTable.selectItem(fileUser); + expect(await toolbar.isEmpty()).toBe(false, `actions not displayed for ${fileUser}`); expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileUser}`); expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileUser}`); - expect(await toolbar.isEditPresent()).toBe(false, `Edit is displayed for ${fileUser}`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileUser}`); expect(await toolbar.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed for ${fileUser}`); + await toolbar.openMoreMenu(); + + // TODO: change expect to true when ACA-2173 is done + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileUser}`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${fileUser}`); expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileUser}`); expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${fileUser}`); expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for ${fileUser}`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${fileUser}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed for ${fileUser}`); + + await toolbar.closeMoreMenu(); + }); + + it('correct actions appear when a locked file is selected - []', async () => { + await page.dataTable.selectItem(fileLocked); + + expect(await toolbar.isEmpty()).toBe(false, `actions not displayed for ${fileLocked}`); + expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileLocked}`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLocked}`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLocked}`); + expect(await toolbar.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed for ${fileLocked}`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileLocked}`); + // TODO: change expect to true when ACA-2173 is done + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${fileLocked}`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed for ${fileLocked}`); + await toolbar.closeMoreMenu(); }); }); @@ -328,21 +481,54 @@ describe('Toolbar actions - single selection : ', () => { done(); }); + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + it('actions are not displayed when no item is selected - [C280447]', async () => { expect(await toolbar.isEmpty()).toBe(true, `actions displayed though nothing selected`); }); it('correct actions appear when a file is selected - [C280448]', async () => { await dataTable.selectItem(fileUser); + expect(await toolbar.isEmpty()).toBe(false, `actions not displayed for ${fileUser}`); expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileUser}`); expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileUser}`); - expect(await toolbar.isEditPresent()).toBe(false, `Edit is displayed for ${fileUser}`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileUser}`); + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed for ${fileUser}`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${fileUser}`); expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileUser}`); expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${fileUser}`); expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for ${fileUser}`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${fileUser}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed for ${fileUser}`); + + await toolbar.closeMoreMenu(); + }); + + it('correct actions appear when a locked file is selected - []', async () => { + await dataTable.selectItem(fileLocked); + + expect(await toolbar.isEmpty()).toBe(false, `actions not displayed for ${fileLocked}`); + expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileLocked}`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLocked}`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLocked}`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileLocked}`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed for ${fileLocked}`); + await toolbar.closeMoreMenu(); }); }); @@ -354,35 +540,77 @@ describe('Toolbar actions - single selection : ', () => { done(); }); + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + it('actions are not displayed when no item is selected - [C280449]', async () => { expect(await toolbar.isEmpty()).toBe(true, `actions displayed though nothing selected`); }); it('correct actions appear when a file is selected - [C280450]', async () => { await dataTable.selectItem(fileUser); + expect(await toolbar.isEmpty()).toBe(false, `actions not displayed for ${fileUser}`); expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileUser}`); expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileUser}`); - expect(await toolbar.isEditPresent()).toBe(false, `Edit is displayed for ${fileUser}`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileUser}`); + await toolbar.openMoreMenu(); + + // TODO: change expect to true when ACA-2174 is done + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileUser}`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${fileUser}`); expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileUser}`); expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${fileUser}`); expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for ${fileUser}`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${fileUser}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed for ${fileUser}`); + + await toolbar.closeMoreMenu(); + }); + + it('correct actions appear when a locked file is selected - []', async () => { + await dataTable.selectItem(fileLocked); + + expect(await toolbar.isEmpty()).toBe(false, `actions not displayed for ${fileLocked}`); + expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileLocked}`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLocked}`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLocked}`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileLocked}`); + // TODO: change expect to true when ACA-2174 is done + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${fileLocked}`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed for ${fileLocked}`); + await toolbar.closeMoreMenu(); }); it('correct actions appear when a folder is selected - [C280451]', async () => { await dataTable.selectItem(folderUser); + expect(await toolbar.isEmpty()).toBe(false, `actions not displayed for ${folderUser}`); expect(await toolbar.isViewPresent()).toBe(false, `View is displayed for ${folderUser}`); expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not enabled for ${folderUser}`); - expect(await toolbar.isEditPresent()).toBe(true, `Edit is not displayed for ${folderUser}`); + expect(await toolbar.isEditFolderPresent()).toBe(true, `Edit folder is not displayed for ${folderUser}`); + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${folderUser}`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${folderUser}`); expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${folderUser}`); expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${folderUser}`); expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for ${folderUser}`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${folderUser}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed for ${folderUser}`); + await toolbar.closeMoreMenu(); }); }); @@ -394,22 +622,29 @@ describe('Toolbar actions - single selection : ', () => { done(); }); + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + it('actions are not displayed when no item is selected - [C280452]', async () => { expect(await toolbar.isEmpty()).toBe(true, `actions displayed though nothing selected`); }); it('correct actions appear when a file is selected - [C280453]', async () => { await dataTable.selectItem(fileForDelete); + expect(await toolbar.isEmpty()).toBe(false, `actions not displayed for ${fileForDelete}`); - expect(await toolbar.isButtonPresent('Permanently delete')).toBe(true, `Permanently delete is not displayed for file`); - expect(await toolbar.isButtonPresent('Restore')).toBe(true, `Restore is not displayed for file`); + expect(await toolbar.isPermanentlyDeletePresent()).toBe(true, `Permanently delete is not displayed for file`); + expect(await toolbar.isRestorePresent()).toBe(true, `Restore is not displayed for file`); }); it('correct actions appear when a folder is selected - [C280454]', async () => { await dataTable.selectItem(folderForDelete); + expect(await toolbar.isEmpty()).toBe(false, `actions not displayed for ${folderForDelete}`); - expect(await toolbar.isButtonPresent('Permanently delete')).toBe(true, `Permanently delete is displayed for folder`); - expect(await toolbar.isButtonPresent('Restore')).toBe(true, `Restore is not enabled for folder`); + expect(await toolbar.isPermanentlyDeletePresent()).toBe(true, `Permanently delete is displayed for folder`); + expect(await toolbar.isRestorePresent()).toBe(true, `Restore is not displayed for folder`); }); }); @@ -420,6 +655,11 @@ describe('Toolbar actions - single selection : ', () => { done(); }); + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + it('actions are not displayed when no item is selected - [C291815]', async () => { await searchInput.clickSearchButton(); await searchInput.checkFilesAndFolders(); @@ -437,12 +677,42 @@ describe('Toolbar actions - single selection : ', () => { expect(await toolbar.isEmpty()).toBe(false, `actions not displayed for ${fileUser}`); expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileUser}`); expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileUser}`); - expect(await toolbar.isEditPresent()).toBe(false, `Edit is displayed for ${fileUser}`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileUser}`); + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed for ${fileUser}`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${fileUser}`); expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileUser}`); expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${fileUser}`); expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${fileUser}`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${fileUser}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed for ${fileUser}`); + + await toolbar.closeMoreMenu(); + }); + + it('correct actions appear when a locked file is selected - []', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFiles(); + await searchInput.searchForTextAndCloseSearchOptions(fileLocked); + await dataTable.selectItem(fileLocked); + + expect(await toolbar.isEmpty()).toBe(false, `actions not displayed for ${fileLocked}`); + expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileLocked}`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLocked}`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLocked}`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileLocked}`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${fileLocked}`); + expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${fileLocked}`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed for ${fileLocked}`); + await toolbar.closeMoreMenu(); }); @@ -455,12 +725,18 @@ describe('Toolbar actions - single selection : ', () => { expect(await toolbar.isEmpty()).toBe(false, `actions not displayed for ${folderUser}`); expect(await toolbar.isViewPresent()).toBe(false, `View is displayed for ${folderUser}`); expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not enabled for ${folderUser}`); - expect(await toolbar.isEditPresent()).toBe(true, `Edit is not displayed for ${folderUser}`); + expect(await toolbar.isEditFolderPresent()).toBe(true, `Edit folder is not displayed for ${folderUser}`); + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${folderUser}`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${folderUser}`); expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${folderUser}`); expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${folderUser}`); expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${folderUser}`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${folderUser}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed for ${folderUser}`); + await toolbar.closeMoreMenu(); }); }); diff --git a/e2e/suites/list-views/tooltips.test.ts b/e2e/suites/list-views/tooltips.test.ts index c9ae1105b8..421e7a6f64 100755 --- a/e2e/suites/list-views/tooltips.test.ts +++ b/e2e/suites/list-views/tooltips.test.ts @@ -166,7 +166,7 @@ describe('File / folder tooltips', () => { }); // disabled until ACA-518 is done - xdescribe('on Shared Files', () => { + describe('on Shared Files', () => { beforeAll(async (done) => { await apis.user.shared.waitForApi({ expect: 8 }); await page.clickSharedFilesAndWait(); diff --git a/e2e/suites/viewer/viewer-actions.test.ts b/e2e/suites/viewer/viewer-actions.test.ts index 40fb5bacd1..43145adb27 100755 --- a/e2e/suites/viewer/viewer-actions.test.ts +++ b/e2e/suites/viewer/viewer-actions.test.ts @@ -58,11 +58,12 @@ describe('Viewer actions', () => { done(); }); - describe('on Personal Files', () => { + describe('file opened from Personal Files', () => { const parent = `parentPF-${Utils.random()}`; let parentId; const destination = `destPF-${Utils.random()}`; let destinationId; const docxPersonalFiles = `docxPF-${Utils.random()}.docx`; let docxFileId; + const docxLockedPersonalFiles = `docxLockedPF-${Utils.random()}.docx`; let docxLockedId; const xlsxPersonalFiles = `xlsxPF-${Utils.random()}.xlsx`; const pdfPersonalFiles = `pdfPF-${Utils.random()}.pdf`; @@ -70,9 +71,12 @@ describe('Viewer actions', () => { parentId = (await apis.user.nodes.createFolder(parent)).entry.id; destinationId = (await apis.user.nodes.createFolder(destination)).entry.id; docxFileId = (await apis.user.upload.uploadFileWithRename(docxFile, parentId, docxPersonalFiles)).entry.id; + docxLockedId = (await apis.user.upload.uploadFileWithRename(docxFile, parentId, docxLockedPersonalFiles)).entry.id; await apis.user.upload.uploadFileWithRename(xlsxFileForMove, parentId, xlsxPersonalFiles); await apis.user.upload.uploadFileWithRename(pdfFileForDelete, parentId, pdfPersonalFiles); + await apis.user.nodes.lockFile(docxLockedId); + await loginPage.loginWith(username); done(); }); @@ -98,7 +102,7 @@ describe('Viewer actions', () => { it('Correct actions appear in the viewer toolbar - [C282025]', async () => { await dataTable.doubleClickOnRowByName(docxPersonalFiles); - expect(await viewer.isViewerOpened()).toBe(true, 'Viewer is not opened'); + await viewer.waitForViewerToOpen(); expect(await toolbar.isEmpty()).toBe(false, `viewer toolbar is empty`); expect(await toolbar.isViewPresent()).toBe(false, `View is displayed`); @@ -107,13 +111,42 @@ describe('Viewer actions', () => { expect(await toolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); expect(await toolbar.isSharePresent()).toBe(true, `Share is not displayed`); expect(await toolbar.isViewDetailsPresent()).toBe(true, `view details is not displayed`); + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed`); expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed`); expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); - expect(await toolbar.menu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed`); + + await toolbar.closeMoreMenu(); + }); + + it('Correct actions appear in the viewer toolbar for a locked file - []', async () => { + await dataTable.doubleClickOnRowByName(docxLockedPersonalFiles); + await viewer.waitForViewerToOpen(); + + expect(await toolbar.isEmpty()).toBe(false, `viewer toolbar is empty`); + expect(await toolbar.isViewPresent()).toBe(false, `View is displayed`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); + expect(await toolbar.isPrintPresent()).toBe(true, `Print is not displayed`); + expect(await toolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); + expect(await toolbar.isSharePresent()).toBe(true, `Share is not displayed`); + expect(await toolbar.isViewDetailsPresent()).toBe(true, `view details is not displayed`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed`); + expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); + await toolbar.closeMoreMenu(); }); @@ -215,7 +248,7 @@ describe('Viewer actions', () => { await manageVersionsDialog.clickClose(); }); - // TODO: enable this once bug is fixed + // TODO: disabled until ACA-2176 is done xit('Pressing ESC in the viewer closes only the action dialog - [C286314]', async () => { await dataTable.doubleClickOnRowByName(docxPersonalFiles); expect(await viewer.isViewerOpened()).toBe(true, 'Viewer is not opened'); @@ -228,11 +261,12 @@ describe('Viewer actions', () => { }); }); - describe('on File Libraries', () => { + describe('file opened from File Libraries', () => { const siteName = `site-${Utils.random()}`; const destination = `destFL-${Utils.random()}`; let destinationId; const docxLibraries = `docxFL-${Utils.random()}.docx`; let docxFileId; + const docxLockedLibraries = `docxLockedFL-${Utils.random()}.docx`; let docxLockedId; const xlsxLibraries = `xlsxFL-${Utils.random()}.xlsx`; const pdfLibraries = `pdfFL-${Utils.random()}.pdf`; @@ -241,6 +275,8 @@ describe('Viewer actions', () => { const docLibId = await apis.user.sites.getDocLibId(siteName); destinationId = (await apis.user.nodes.createFolder(destination)).entry.id; docxFileId = (await apis.user.upload.uploadFileWithRename(docxFile, docLibId, docxLibraries)).entry.id; + docxLockedId = (await apis.user.upload.uploadFileWithRename(docxFile, docLibId, docxLockedLibraries)).entry.id; + await apis.user.nodes.lockFile(docxLockedId); await apis.user.upload.uploadFileWithRename(xlsxFileForMove, docLibId, xlsxLibraries); await apis.user.upload.uploadFileWithRename(pdfFileForDelete, docLibId, pdfLibraries); @@ -267,6 +303,56 @@ describe('Viewer actions', () => { done(); }); + it('Correct actions appear in the viewer toolbar - []', async () => { + await dataTable.doubleClickOnRowByName(docxLibraries); + await viewer.waitForViewerToOpen(); + + expect(await toolbar.isEmpty()).toBe(false, `viewer toolbar is empty`); + expect(await toolbar.isViewPresent()).toBe(false, `View is displayed`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); + expect(await toolbar.isPrintPresent()).toBe(true, `Print is not displayed`); + expect(await toolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); + expect(await toolbar.isSharePresent()).toBe(true, `Share is not displayed`); + expect(await toolbar.isViewDetailsPresent()).toBe(true, `view details is not displayed`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed`); + expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); + + await toolbar.closeMoreMenu(); + }); + + it('Correct actions appear in the viewer toolbar for a locked file - []', async () => { + await dataTable.doubleClickOnRowByName(docxLockedLibraries); + await viewer.waitForViewerToOpen(); + + expect(await toolbar.isEmpty()).toBe(false, `viewer toolbar is empty`); + expect(await toolbar.isViewPresent()).toBe(false, `View is displayed`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); + expect(await toolbar.isPrintPresent()).toBe(true, `Print is not displayed`); + expect(await toolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); + expect(await toolbar.isSharePresent()).toBe(true, `Share is not displayed`); + expect(await toolbar.isViewDetailsPresent()).toBe(true, `view details is not displayed`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed`); + expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); + + await toolbar.closeMoreMenu(); + }); + it('Download action - [C286369]', async () => { await dataTable.doubleClickOnRowByName(docxLibraries); expect(await viewer.isViewerOpened()).toBe(true, 'Viewer is not opened'); @@ -354,11 +440,12 @@ describe('Viewer actions', () => { }); }); - describe('on Recent Files', () => { + describe('file opened from Recent Files', () => { const parent = `parentRF-${Utils.random()}`; let parentId; const destination = `destRF-${Utils.random()}`; let destinationId; const docxRecentFiles = `docxRF-${Utils.random()}.docx`; let docxFileId; + const docxLockedRecentFiles = `docxLockedRF-${Utils.random()}.docx`; let docxLockedId; const xlsxRecentFiles = `xlsxRF-${Utils.random()}.xlsx`; const pdfRecentFiles = `pdfRF-${Utils.random()}.pdf`; @@ -367,10 +454,12 @@ describe('Viewer actions', () => { parentId = (await apis.user.nodes.createFolder(parent)).entry.id; destinationId = (await apis.user.nodes.createFolder(destination)).entry.id; docxFileId = (await apis.user.upload.uploadFileWithRename(docxFile, parentId, docxRecentFiles)).entry.id; + docxLockedId = (await apis.user.upload.uploadFileWithRename(docxFile, parentId, docxLockedRecentFiles)).entry.id; + await apis.user.nodes.lockFile(docxLockedId); await apis.user.upload.uploadFileWithRename(xlsxFileForMove, parentId, xlsxRecentFiles); await apis.user.upload.uploadFileWithRename(pdfFileForDelete, parentId, pdfRecentFiles); - await apis.user.search.waitForApi(username, {expect: 3}); + await apis.user.search.waitForApi(username, {expect: 4}); await loginPage.loginWith(username); done(); @@ -393,6 +482,56 @@ describe('Viewer actions', () => { done(); }); + it('Correct actions appear in the viewer toolbar - []', async () => { + await dataTable.doubleClickOnRowByName(docxRecentFiles); + await viewer.waitForViewerToOpen(); + + expect(await toolbar.isEmpty()).toBe(false, `viewer toolbar is empty`); + expect(await toolbar.isViewPresent()).toBe(false, `View is displayed`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); + expect(await toolbar.isPrintPresent()).toBe(true, `Print is not displayed`); + expect(await toolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); + expect(await toolbar.isSharePresent()).toBe(true, `Share is not displayed`); + expect(await toolbar.isViewDetailsPresent()).toBe(true, `view details is not displayed`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed`); + expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); + + await toolbar.closeMoreMenu(); + }); + + it('Correct actions appear in the viewer toolbar for a locked file - []', async () => { + await dataTable.doubleClickOnRowByName(docxLockedRecentFiles); + await viewer.waitForViewerToOpen(); + + expect(await toolbar.isEmpty()).toBe(false, `viewer toolbar is empty`); + expect(await toolbar.isViewPresent()).toBe(false, `View is displayed`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); + expect(await toolbar.isPrintPresent()).toBe(true, `Print is not displayed`); + expect(await toolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); + expect(await toolbar.isSharePresent()).toBe(true, `Share is not displayed`); + expect(await toolbar.isViewDetailsPresent()).toBe(true, `view details is not displayed`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed`); + expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); + + await toolbar.closeMoreMenu(); + }); + it('Download action - [C286383]', async () => { await dataTable.doubleClickOnRowByName(docxRecentFiles); expect(await viewer.isViewerOpened()).toBe(true, 'Viewer is not opened'); @@ -481,11 +620,12 @@ describe('Viewer actions', () => { }); }); - describe('on Shared Files', () => { + describe('file opened from Shared Files', () => { const parent = `parentSF-${Utils.random()}`; let parentId; const destination = `destSF-${Utils.random()}`; let destinationId; const docxSharedFiles = `docxSF-${Utils.random()}.docx`; let docxFileId; + const docxLockedSharedFiles = `docxLockedSF-${Utils.random()}.docx`; let docxLockedId; const xlsxSharedFiles = `xlsxSF-${Utils.random()}.xlsx`; let xlsxFileId; const pdfSharedFiles = `pdfSF-${Utils.random()}.pdf`; let pdfFileId; @@ -493,11 +633,13 @@ describe('Viewer actions', () => { parentId = (await apis.user.nodes.createFolder(parent)).entry.id; destinationId = (await apis.user.nodes.createFolder(destination)).entry.id; docxFileId = (await apis.user.upload.uploadFileWithRename(docxFile, parentId, docxSharedFiles)).entry.id; + docxLockedId = (await apis.user.upload.uploadFileWithRename(docxFile, parentId, docxLockedSharedFiles)).entry.id; xlsxFileId = (await apis.user.upload.uploadFileWithRename(xlsxFileForMove, parentId, xlsxSharedFiles)).entry.id; pdfFileId = (await apis.user.upload.uploadFileWithRename(pdfFileForDelete, parentId, pdfSharedFiles)).entry.id; + await apis.user.nodes.lockFile(docxLockedId); - await apis.user.shared.shareFilesByIds([docxFileId, xlsxFileId, pdfFileId]) - await apis.user.shared.waitForApi({expect: 3}); + await apis.user.shared.shareFilesByIds([docxFileId, docxLockedId, xlsxFileId, pdfFileId]) + await apis.user.shared.waitForApi({expect: 4}); await loginPage.loginWith(username); done(); @@ -520,6 +662,56 @@ describe('Viewer actions', () => { done(); }); + it('Correct actions appear in the viewer toolbar - []', async () => { + await dataTable.doubleClickOnRowByName(docxSharedFiles); + await viewer.waitForViewerToOpen(); + + expect(await toolbar.isEmpty()).toBe(false, `viewer toolbar is empty`); + expect(await toolbar.isViewPresent()).toBe(false, `View is displayed`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); + expect(await toolbar.isPrintPresent()).toBe(true, `Print is not displayed`); + expect(await toolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); + expect(await toolbar.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed`); + expect(await toolbar.isViewDetailsPresent()).toBe(true, `view details is not displayed`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed`); + expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); + + await toolbar.closeMoreMenu(); + }); + + it('Correct actions appear in the viewer toolbar for a locked file - []', async () => { + await dataTable.doubleClickOnRowByName(docxLockedSharedFiles); + await viewer.waitForViewerToOpen(); + + expect(await toolbar.isEmpty()).toBe(false, `viewer toolbar is empty`); + expect(await toolbar.isViewPresent()).toBe(false, `View is displayed`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); + expect(await toolbar.isPrintPresent()).toBe(true, `Print is not displayed`); + expect(await toolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); + expect(await toolbar.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed`); + expect(await toolbar.isViewDetailsPresent()).toBe(true, `view details is not displayed`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed`); + expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); + + await toolbar.closeMoreMenu(); + }); + it('Download action - [C286376]', async () => { await dataTable.doubleClickOnRowByName(docxSharedFiles); expect(await viewer.isViewerOpened()).toBe(true, 'Viewer is not opened'); @@ -608,13 +800,14 @@ describe('Viewer actions', () => { }); }); - describe('on Favorites', () => { + describe('file opened from Favorites', () => { const parent = `parentFav-${Utils.random()}`; let parentId; const destination = `destFav-${Utils.random()}`; let destinationId; const docxFavorites = `docxFav-${Utils.random()}.docx`; let docxFileId; + const docxLockedFavorites = `docxLockedFav-${Utils.random()}.docx`; let docxLockedId; const xlsxFavorites = `xlsxFav-${Utils.random()}.xlsx`; let xlsxFileId; const pdfFavorites = `pdfFav-${Utils.random()}.pdf`; let pdfFileId; @@ -622,11 +815,13 @@ describe('Viewer actions', () => { parentId = (await apis.user.nodes.createFolder(parent)).entry.id; destinationId = (await apis.user.nodes.createFolder(destination)).entry.id; docxFileId = (await apis.user.upload.uploadFileWithRename(docxFile, parentId, docxFavorites)).entry.id; + docxLockedId = (await apis.user.upload.uploadFileWithRename(docxFile, parentId, docxLockedFavorites)).entry.id; xlsxFileId = (await apis.user.upload.uploadFileWithRename(xlsxFileForMove, parentId, xlsxFavorites)).entry.id; pdfFileId = (await apis.user.upload.uploadFileWithRename(pdfFileForDelete, parentId, pdfFavorites)).entry.id; + await apis.user.nodes.lockFile(docxLockedId); - await apis.user.favorites.addFavoritesByIds('file', [docxFileId, xlsxFileId, pdfFileId]) - await apis.user.favorites.waitForApi({expect: 3}); + await apis.user.favorites.addFavoritesByIds('file', [docxFileId, docxLockedId, xlsxFileId, pdfFileId]) + await apis.user.favorites.waitForApi({expect: 4}); await loginPage.loginWith(username); done(); @@ -649,6 +844,56 @@ describe('Viewer actions', () => { done(); }); + it('Correct actions appear in the viewer toolbar - []', async () => { + await dataTable.doubleClickOnRowByName(docxFavorites); + await viewer.waitForViewerToOpen(); + + expect(await toolbar.isEmpty()).toBe(false, `viewer toolbar is empty`); + expect(await toolbar.isViewPresent()).toBe(false, `View is displayed`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); + expect(await toolbar.isPrintPresent()).toBe(true, `Print is not displayed`); + expect(await toolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); + expect(await toolbar.isSharePresent()).toBe(true, `Share is not displayed`); + expect(await toolbar.isViewDetailsPresent()).toBe(true, `view details is not displayed`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed`); + expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); + + await toolbar.closeMoreMenu(); + }); + + it('Correct actions appear in the viewer toolbar for a locked file - []', async () => { + await dataTable.doubleClickOnRowByName(docxLockedFavorites); + await viewer.waitForViewerToOpen(); + + expect(await toolbar.isEmpty()).toBe(false, `viewer toolbar is empty`); + expect(await toolbar.isViewPresent()).toBe(false, `View is displayed`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); + expect(await toolbar.isPrintPresent()).toBe(true, `Print is not displayed`); + expect(await toolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); + expect(await toolbar.isSharePresent()).toBe(true, `Share is not displayed`); + expect(await toolbar.isViewDetailsPresent()).toBe(true, `view details is not displayed`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed`); + expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed`); + expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); + + await toolbar.closeMoreMenu(); + }); + it('Download action - [C286390]', async () => { await dataTable.doubleClickOnRowByName(docxFavorites); expect(await viewer.isViewerOpened()).toBe(true, 'Viewer is not opened'); diff --git a/e2e/utilities/repo-client/apis/nodes/nodes-api.ts b/e2e/utilities/repo-client/apis/nodes/nodes-api.ts index 63304ea7a8..cc6bb17861 100755 --- a/e2e/utilities/repo-client/apis/nodes/nodes-api.ts +++ b/e2e/utilities/repo-client/apis/nodes/nodes-api.ts @@ -207,10 +207,11 @@ export class NodesApi extends RepoApi { } // lock node - async lockFile(nodeId: string, lockType: string = 'FULL') { + async lockFile(nodeId: string, lockType: string = 'ALLOW_OWNER_CHANGES') { const data = { type: lockType }; + await this.apiAuth(); return await this.nodesApi.lockNode(nodeId, data ); } diff --git a/src/app/extensions/core.extensions.module.ts b/src/app/extensions/core.extensions.module.ts index 885715d12e..4ea8e960dc 100644 --- a/src/app/extensions/core.extensions.module.ts +++ b/src/app/extensions/core.extensions.module.ts @@ -147,6 +147,8 @@ export class CoreExtensionsModule { 'app.navigation.isSearchResults': nav.isSearchResults, 'app.navigation.isNotSearchResults': nav.isNotSearchResults, 'app.navigation.isPreview': nav.isPreview, + 'app.navigation.isSharedPreview': nav.isSharedPreview, + 'app.navigation.isFavoritesPreview': nav.isFavoritesPreview, 'repository.isQuickShareEnabled': repository.hasQuickShareEnabled }); diff --git a/src/app/extensions/evaluators/app.evaluators.ts b/src/app/extensions/evaluators/app.evaluators.ts index 00ae64f596..89a6f532bc 100644 --- a/src/app/extensions/evaluators/app.evaluators.ts +++ b/src/app/extensions/evaluators/app.evaluators.ts @@ -335,8 +335,8 @@ export function canUnlockFile( ): boolean { const { file } = context.selection; return ( - (isWriteLocked(context, ...args) && - context.permissions.check(file.entry, ['delete'])) || - isUserWriteLockOwner(context, ...args) + isWriteLocked(context, ...args) && + (context.permissions.check(file.entry, ['delete']) || + isUserWriteLockOwner(context, ...args)) ); } diff --git a/src/app/extensions/evaluators/navigation.evaluators.ts b/src/app/extensions/evaluators/navigation.evaluators.ts index 23ce69a2b5..5657e7b26d 100644 --- a/src/app/extensions/evaluators/navigation.evaluators.ts +++ b/src/app/extensions/evaluators/navigation.evaluators.ts @@ -140,3 +140,23 @@ export function isPreview( const { url } = context.navigation; return url && url.includes('/preview/'); } + +export function isSharedPreview( + context: RuleContext, + ...args: RuleParameter[] +): boolean { + const { url } = context.navigation; + console.log( + '===== isSharedPreview: ', + url && url.startsWith('/shared/preview/') + ); + return url && url.startsWith('/shared/preview/'); +} + +export function isFavoritesPreview( + context: RuleContext, + ...args: RuleParameter[] +): boolean { + const { url } = context.navigation; + return url && url.startsWith('/favorites/preview/'); +} diff --git a/src/assets/app.extensions.json b/src/assets/app.extensions.json index 97c142fdca..8b9e836292 100644 --- a/src/assets/app.extensions.json +++ b/src/assets/app.extensions.json @@ -231,6 +231,22 @@ "parameters": [ { "type": "rule", "value": "app.selection.file" }, { "type": "rule", "value": "app.navigation.isNotTrashcan" }, + { + "type": "rule", + "value": "core.some", + "parameters": [ + { "type": "rule", "value": "app.navigation.isNotFavorites" }, + { "type": "rule", "value": "app.navigation.isFavoritesPreview" } + ] + }, + { + "type": "rule", + "value": "core.some", + "parameters": [ + { "type": "rule", "value": "app.navigation.isNotSharedFiles" }, + { "type": "rule", "value": "app.navigation.isSharedPreview" } + ] + }, { "type": "rule", "value": "core.some", From 65e0a1138ce439be59639f6c47076d8a2576c226 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Fri, 8 Feb 2019 13:45:39 +0000 Subject: [PATCH 043/259] Keensoft AOS extension (#920) * aos extension * update karma * lint improvements and fixes * update script * update scripts * update scripts * reduce about 56.4 kB of polyfills for modern browsers * deficated aosHost value to have AOS on separate servers * context menu and toolbar * visibility evaluator * code improvements and fixes * support locking, lock checks --- .travis.yml | 2 - angular.json | 57 +++++- package-lock.json | 12 ++ package.json | 17 +- projects/adf-office-services-ext/LICENSE | 165 ++++++++++++++++++ projects/adf-office-services-ext/README.md | 24 +++ .../assets/aos.plugin.json | 70 ++++++++ .../adf-office-services-ext/karma.conf.js | 34 ++++ .../adf-office-services-ext/ng-package.json | 14 ++ projects/adf-office-services-ext/ngi.json | 15 ++ projects/adf-office-services-ext/package.json | 17 ++ .../src/lib/actions/aos.actions.ts | 9 + .../src/lib/aos-extension.module.ts | 20 +++ .../src/lib/aos-extension.service.ts | 131 ++++++++++++++ .../src/lib/effects/aos.effects.ts | 24 +++ .../src/lib/evaluators.ts | 45 +++++ .../adf-office-services-ext/src/lib/utils.ts | 37 ++++ .../adf-office-services-ext/src/public_api.ts | 5 + projects/adf-office-services-ext/src/test.ts | 22 +++ .../adf-office-services-ext/tsconfig.lib.json | 32 ++++ .../tsconfig.spec.json | 17 ++ projects/adf-office-services-ext/tslint.json | 17 ++ src/app.config.json | 1 + src/app/extensions.module.ts | 3 +- src/assets/app.extensions.json | 2 +- tsconfig.json | 9 +- 26 files changed, 781 insertions(+), 20 deletions(-) create mode 100644 projects/adf-office-services-ext/LICENSE create mode 100644 projects/adf-office-services-ext/README.md create mode 100644 projects/adf-office-services-ext/assets/aos.plugin.json create mode 100644 projects/adf-office-services-ext/karma.conf.js create mode 100644 projects/adf-office-services-ext/ng-package.json create mode 100644 projects/adf-office-services-ext/ngi.json create mode 100644 projects/adf-office-services-ext/package.json create mode 100755 projects/adf-office-services-ext/src/lib/actions/aos.actions.ts create mode 100644 projects/adf-office-services-ext/src/lib/aos-extension.module.ts create mode 100644 projects/adf-office-services-ext/src/lib/aos-extension.service.ts create mode 100755 projects/adf-office-services-ext/src/lib/effects/aos.effects.ts create mode 100644 projects/adf-office-services-ext/src/lib/evaluators.ts create mode 100644 projects/adf-office-services-ext/src/lib/utils.ts create mode 100644 projects/adf-office-services-ext/src/public_api.ts create mode 100644 projects/adf-office-services-ext/src/test.ts create mode 100644 projects/adf-office-services-ext/tsconfig.lib.json create mode 100644 projects/adf-office-services-ext/tsconfig.spec.json create mode 100644 projects/adf-office-services-ext/tslint.json diff --git a/.travis.yml b/.travis.yml index a9230e1b16..8cad2d778b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,8 +20,6 @@ jobs: name: 'Code quality checks' script: - npm run lint - - npm run spellcheck - - npm run format:check - stage: test name: 'Unit tests' script: diff --git a/angular.json b/angular.json index 2961f4555b..e7700381c2 100644 --- a/angular.json +++ b/angular.json @@ -45,15 +45,20 @@ "input": "node_modules/pdfjs-dist/build", "output": "/" }, + { + "glob": "extension.schema.json", + "input": ".", + "output": "./assets" + }, { "glob": "**/*.json", - "input": "node_modules/@denysvuika/aca-dev-tools/assets", + "input": "node_modules/@alfresco/adf-office-services-ext/assets", "output": "./assets/plugins" }, { - "glob": "extension.schema.json", - "input": ".", - "output": "./assets" + "glob": "**/*.json", + "input": "projects/adf-office-services-ext/assets", + "output": "./assets/plugins" } ], "styles": [ @@ -62,10 +67,11 @@ "src/styles.scss" ], "scripts": [ - "node_modules/pdfjs-dist/build/pdf.js", - "node_modules/pdfjs-dist/web/pdf_viewer.js", - "node_modules/moment/min/moment.min.js" - ] + "node_modules/pdfjs-dist/build/pdf.js", + "node_modules/pdfjs-dist/web/pdf_viewer.js", + "node_modules/moment/min/moment.min.js" + ], + "es5BrowserSupport": true }, "configurations": { "production": { @@ -222,6 +228,41 @@ } } } + }, + "adf-office-services-ext": { + "root": "projects/adf-office-services-ext", + "sourceRoot": "projects/adf-office-services-ext/src", + "projectType": "library", + "prefix": "lib", + "architect": { + "build": { + "builder": "@angular-devkit/build-ng-packagr:build", + "options": { + "tsConfig": "projects/adf-office-services-ext/tsconfig.lib.json", + "project": "projects/adf-office-services-ext/ng-package.json" + } + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "main": "projects/adf-office-services-ext/src/test.ts", + "tsConfig": "projects/adf-office-services-ext/tsconfig.spec.json", + "karmaConfig": "projects/adf-office-services-ext/karma.conf.js" + } + }, + "lint": { + "builder": "@angular-devkit/build-angular:tslint", + "options": { + "tsConfig": [ + "projects/adf-office-services-ext/tsconfig.lib.json", + "projects/adf-office-services-ext/tsconfig.spec.json" + ], + "exclude": [ + "**/node_modules/**" + ] + } + } + } } }, "defaultProject": "app", diff --git a/package-lock.json b/package-lock.json index 6eb2aff3af..9f2c426827 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3000,6 +3000,18 @@ } } }, + "cpr": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/cpr/-/cpr-3.0.1.tgz", + "integrity": "sha1-uaVQOLfNgaNcF7l2GJW9hJau8eU=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.5", + "minimist": "^1.2.0", + "mkdirp": "~0.5.1", + "rimraf": "^2.5.4" + } + }, "create-ecdh": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", diff --git a/package.json b/package.json index f809c9d4ad..13e678c6e6 100644 --- a/package.json +++ b/package.json @@ -4,14 +4,16 @@ "license": "LGPL-3.0", "scripts": { "ng": "ng", - "start": "ng serve --open", + "start": "npm run build.extensions && ng serve --open", "start:prod": "ng serve --prod --open", - "build": "node --max-old-space-size=8192 node_modules/@angular/cli/bin/ng build app --prod", - "build:dev": "ng build", - "build.e2e": "node --max-old-space-size=8192 node_modules/@angular/cli/bin/ng build app --configuration=e2e", + "build:aos-extension": "rm -rf dist/@alfresco/adf-office-services-ext && ng build adf-office-services-ext && cp projects/adf-office-services-ext/ngi.json dist/@alfresco/adf-office-services-ext && cpr projects/adf-office-services-ext/assets dist/@alfresco/adf-office-services-ext/assets", + "build.extensions": "npm run build:aos-extension", + "build.app": "node --max-old-space-size=8192 node_modules/@angular/cli/bin/ng build app", + "build": "npm run build.extensions && npm run build.app -- --prod", + "build.e2e": "npm run build.extensions && npm run build.app -- --prod --configuration=e2e", "test": "ng test app --code-coverage", - "test:ci": "ng test app --code-coverage --watch=false", - "lint": "ng lint", + "test:ci": "npm run build.extensions && ng test app --code-coverage --watch=false", + "lint": "ng lint && npm run spellcheck && npm run format:check", "wd:update": "webdriver-manager update --gecko=false", "e2e": "npm run wd:update && protractor --baseUrl=http://localhost:4000", "e2e.local": "npm run wd:update && protractor --baseUrl=http://localhost:4200", @@ -23,7 +25,7 @@ "inspect.bundle": "ng build app --prod --stats-json && npx webpack-bundle-analyzer dist/app/stats.json", "format:check": "prettier --check \"src/{app,environments}/**/*.{ts,js,css,scss,html}\"", "format:fix": "prettier --write \"src/{app,environments}/**/*.{ts,js,css,scss,html}\"", - "build.tomcat": "npm run build -- --base-href ./ && jar -cvf docker/tomcat/artifacts/content-app.war -C dist/app/ .", + "build.tomcat": "npm run build.extensions && npm run build.app -- --prod --base-href ./ && jar -cvf docker/tomcat/artifacts/content-app.war -C dist/app/ .", "build.tomcat.e2e": "./build-tomcat-e2e.sh", "e2e.tomcat": "npm run wd:update && protractor --baseUrl=http://localhost:4000/content-app/", "docker.tomcat.start": "cd docker/tomcat && docker-compose up -d --build && npm run wait:app", @@ -78,6 +80,7 @@ "@types/selenium-webdriver": "^3.0.8", "chrome-remote-interface": "^0.26.1", "codelyzer": "^4.5.0", + "cpr": "^3.0.1", "cspell": "^3.1.3", "jasmine-core": "~2.8.0", "jasmine-reporters": "^2.2.1", diff --git a/projects/adf-office-services-ext/LICENSE b/projects/adf-office-services-ext/LICENSE new file mode 100644 index 0000000000..65c5ca88a6 --- /dev/null +++ b/projects/adf-office-services-ext/LICENSE @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/projects/adf-office-services-ext/README.md b/projects/adf-office-services-ext/README.md new file mode 100644 index 0000000000..6d04ec313e --- /dev/null +++ b/projects/adf-office-services-ext/README.md @@ -0,0 +1,24 @@ +# AdfOfficeServicesExt + +This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 7.2.0. + +## Code scaffolding + +Run `ng generate component component-name --project adf-office-services-ext` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project adf-office-services-ext`. +> Note: Don't forget to add `--project adf-office-services-ext` or else it will be added to the default project in your `angular.json` file. + +## Build + +Run `ng build adf-office-services-ext` to build the project. The build artifacts will be stored in the `dist/` directory. + +## Publishing + +After building your library with `ng build adf-office-services-ext`, go to the dist folder `cd dist/adf-office-services-ext` and run `npm publish`. + +## Running unit tests + +Run `ng test adf-office-services-ext` to execute the unit tests via [Karma](https://karma-runner.github.io). + +## Further help + +To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md). diff --git a/projects/adf-office-services-ext/assets/aos.plugin.json b/projects/adf-office-services-ext/assets/aos.plugin.json new file mode 100644 index 0000000000..115574af37 --- /dev/null +++ b/projects/adf-office-services-ext/assets/aos.plugin.json @@ -0,0 +1,70 @@ +{ + "$schema": "../../../extension.schema.json", + "$id": "9a635542-d87a-4558-ae64-ffa199d1a364", + "$version": "1.0.0", + "$name": "keensoft.aos.plugin", + "$description": "Extension that provides Office Edit Online Action", + "$vendor": "Keensoft", + "$license": "LGPL-3.0", + "$runtime": "1.6.0", + + "actions": [ + { + "id": "aos.openWith.office", + "type": "AOS_ACTION", + "payload": "$(context.selection.first.entry)" + } + ], + + "features": { + "toolbar": [ + { + "id": "app.toolbar.more", + "children": [ + { + "id": "aos.toolbar.openWith.office", + "order": 90, + "icon": "adf:application/msword", + "title": "Edit in Microsoft Office™", + "actions": { + "click": "aos.openWith.office" + }, + "rules": { + "visible": "aos.canOpenWithOffice" + } + } + ] + } + ], + "contextMenu": [ + { + "id": "aos.context.openWith.office", + "order": 90, + "icon": "adf:application/msword", + "title": "Edit in Microsoft Office™", + "actions": { + "click": "aos.openWith.office" + }, + "rules": { + "visible": "aos.canOpenWithOffice" + } + } + ], + "viewer": { + "openWith": [ + { + "id": "aos.viewer.openWith.office", + "type": "button", + "icon": "adf:application/msword", + "title": "Microsoft Office™", + "actions": { + "click": "aos.openWith.office" + }, + "rules": { + "visible": "aos.canOpenWithOffice" + } + } + ] + } + } +} diff --git a/projects/adf-office-services-ext/karma.conf.js b/projects/adf-office-services-ext/karma.conf.js new file mode 100644 index 0000000000..dd9b7e664d --- /dev/null +++ b/projects/adf-office-services-ext/karma.conf.js @@ -0,0 +1,34 @@ +// Karma configuration file, see link for more information +// https://karma-runner.github.io/1.0/config/configuration-file.html + +module.exports = function(config) { + config.set({ + basePath: '', + frameworks: ['jasmine', '@angular-devkit/build-angular'], + plugins: [ + require('karma-jasmine'), + require('karma-chrome-launcher'), + require('karma-jasmine-html-reporter'), + require('karma-coverage-istanbul-reporter'), + require('@angular-devkit/build-angular/plugins/karma') + ], + client: { + clearContext: false // leave Jasmine Spec Runner output visible in browser + }, + coverageIstanbulReporter: { + dir: require('path').join( + __dirname, + '../../coverage/adf-office-services-ext' + ), + reports: ['html', 'lcovonly'], + fixWebpackSourcePaths: true + }, + reporters: ['progress', 'kjhtml'], + port: 9876, + colors: true, + logLevel: config.LOG_INFO, + autoWatch: true, + browsers: ['Chrome'], + singleRun: false + }); +}; diff --git a/projects/adf-office-services-ext/ng-package.json b/projects/adf-office-services-ext/ng-package.json new file mode 100644 index 0000000000..c63ea38c6f --- /dev/null +++ b/projects/adf-office-services-ext/ng-package.json @@ -0,0 +1,14 @@ +{ + "$schema": "../../node_modules/ng-packagr/ng-package.schema.json", + "dest": "../../dist/@alfresco/adf-office-services-ext", + "lib": { + "entryFile": "src/public_api.ts", + "flatModuleFile": "adf-office-services-ext", + "umdModuleIds": { + "@alfresco/js-api": "@alfresco/js-api", + "@alfresco/adf-core": "@alfresco/adf-core", + "@alfresco/adf-extensions": "@alfresco/adf-extensions", + "@ngrx/effects": "@ngrx/effects" + } + } +} diff --git a/projects/adf-office-services-ext/ngi.json b/projects/adf-office-services-ext/ngi.json new file mode 100644 index 0000000000..471c8fb4d5 --- /dev/null +++ b/projects/adf-office-services-ext/ngi.json @@ -0,0 +1,15 @@ +{ + "assets": [ + { + "glob": "**/*.json", + "input": "./assets", + "output": "./assets/plugins" + } + ], + "modules": [ + { + "name": "AosExtensionModule", + "namespace": "@alfresco/adf-office-services-ext" + } + ] +} diff --git a/projects/adf-office-services-ext/package.json b/projects/adf-office-services-ext/package.json new file mode 100644 index 0000000000..77d977ebe3 --- /dev/null +++ b/projects/adf-office-services-ext/package.json @@ -0,0 +1,17 @@ +{ + "name": "@alfresco/adf-office-services-ext", + "version": "1.0.0", + "license": "LGPL-3.0", + "author": { + "name": "Keensoft", + "url": "http://www.keensoft.es/en/" + }, + "peerDependencies": { + "@angular/common": "^7.2.0", + "@angular/core": "^7.2.0", + "@ngrx/effects": "^7.2.0", + "@ngrx/store": "^7.2.0", + "@alfresco/adf-extensions": "3.0.0-3a5fe3fb92cdc7397cbfd3d0869833ea1f1fe8d5", + "@alfresco/js-api": "3.0.0-d7850f421268e21861e2cd219441b7343efd27ba" + } +} diff --git a/projects/adf-office-services-ext/src/lib/actions/aos.actions.ts b/projects/adf-office-services-ext/src/lib/actions/aos.actions.ts new file mode 100755 index 0000000000..1a3bd37a0a --- /dev/null +++ b/projects/adf-office-services-ext/src/lib/actions/aos.actions.ts @@ -0,0 +1,9 @@ +import { Action } from '@ngrx/store'; +import { MinimalNodeEntryEntity } from '@alfresco/js-api'; + +export const AOS_ACTION = 'AOS_ACTION'; + +export class AosAction implements Action { + readonly type = AOS_ACTION; + constructor(public payload: MinimalNodeEntryEntity) {} +} diff --git a/projects/adf-office-services-ext/src/lib/aos-extension.module.ts b/projects/adf-office-services-ext/src/lib/aos-extension.module.ts new file mode 100644 index 0000000000..9f6065730a --- /dev/null +++ b/projects/adf-office-services-ext/src/lib/aos-extension.module.ts @@ -0,0 +1,20 @@ +import { ExtensionService } from '@alfresco/adf-extensions'; +import { NgModule } from '@angular/core'; +import { EffectsModule } from '@ngrx/effects'; + +import { AosEditOnlineService } from './aos-extension.service'; +import { AosEffects } from './effects/aos.effects'; + +import { canOpenWithOffice } from './evaluators'; + +@NgModule({ + imports: [EffectsModule.forFeature([AosEffects])], + providers: [AosEditOnlineService] +}) +export class AosExtensionModule { + constructor(extensions: ExtensionService) { + extensions.setEvaluators({ + 'aos.canOpenWithOffice': canOpenWithOffice + }); + } +} diff --git a/projects/adf-office-services-ext/src/lib/aos-extension.service.ts b/projects/adf-office-services-ext/src/lib/aos-extension.service.ts new file mode 100644 index 0000000000..3c89204ccc --- /dev/null +++ b/projects/adf-office-services-ext/src/lib/aos-extension.service.ts @@ -0,0 +1,131 @@ +/* cspell:disable */ +import { + AppConfigService, + AuthenticationService, + NotificationService, + AlfrescoApiService +} from '@alfresco/adf-core'; +import { Injectable } from '@angular/core'; +import { MinimalNodeEntryEntity } from '@alfresco/js-api'; +import { supportedExtensions, getFileExtension } from './utils'; + +@Injectable({ + providedIn: 'root' +}) +export class AosEditOnlineService { + constructor( + private alfrescoAuthenticationService: AuthenticationService, + private appConfigService: AppConfigService, + private notificationService: NotificationService, + private apiService: AlfrescoApiService + ) {} + + onActionEditOnlineAos(node: MinimalNodeEntryEntity): void { + if (node && node.isFile && node.properties) { + if (node.isLocked) { + // const checkedOut = node.aspectNames.find( + // (aspect: string) => aspect === 'cm:checkedOut' + // ); + const checkedOut = node.properties['cm:lockType'] === 'WRITE_LOCK'; + const lockOwner = node.properties['cm:lockOwner']; + const differentLockOwner = + lockOwner.id !== this.alfrescoAuthenticationService.getEcmUsername(); + + if (checkedOut && differentLockOwner) { + this.onAlreadyLockedNotification(node.id, lockOwner); + } else { + this.triggerEditOnlineAos(node); + } + } else { + this.triggerEditOnlineAos(node); + } + } + } + + private getUserAgent(): string { + return navigator.userAgent.toLowerCase(); + } + + private isWindows(): boolean { + return this.getUserAgent().indexOf('win') !== -1 ? true : false; + } + + private isMacOs(): boolean { + return this.getUserAgent().indexOf('mac') !== -1 ? true : false; + } + + private onAlreadyLockedNotification(nodeId: string, lockOwner: string) { + this.notificationService.openSnackMessage( + `Document {nodeId} locked by {lockOwner}`, + 3000 + ); + } + + private getProtocolForFileExtension(fileExtension: string) { + return supportedExtensions[fileExtension]; + } + + private triggerEditOnlineAos(node: MinimalNodeEntryEntity): void { + const aosHost = this.appConfigService.get('aosHost'); + const url = `${aosHost}/_aos_nodeid/${node.id}/${node.name}`; + const fileExtension = getFileExtension(node.name); + const protocolHandler = this.getProtocolForFileExtension(fileExtension); + + if (protocolHandler === undefined) { + this.notificationService.openSnackMessage( + `No protocol handler found for {fileExtension}`, + 3000 + ); + return; + } + + if (!this.isWindows() && !this.isMacOs()) { + this.notificationService.openSnackMessage( + 'Only supported for Windows and Mac', + 3000 + ); + } else { + this.apiService.nodesApi + .lockNode(node.id, { + type: 'ALLOW_OWNER_CHANGES', + lifetime: 'PERSISTENT' + }) + .then( + () => { + this.aos_tryToLaunchOfficeByMsProtocolHandler(protocolHandler, url); + }, + () => { + this.notificationService.openSnackMessage( + 'Cannot lock the node for editing.', + 3000 + ); + } + ); + } + } + + private aos_tryToLaunchOfficeByMsProtocolHandler( + protocolHandler: string, + url: string + ) { + const protocolUrl = protocolHandler + ':ofe%7Cu%7C' + url; + + const input = document.createElement('input'); + const inputTop = document.body.scrollTop + 10; + input.setAttribute( + 'style', + 'z-index: 1000; background-color: rgba(0, 0, 0, 0); ' + + 'border: none; outline: none; position: absolute; left: 10px; top: ' + + inputTop + + 'px;' + ); + document.getElementsByTagName('body')[0].appendChild(input); + input.focus(); + location.href = protocolUrl; + + setTimeout(function() { + input.onblur = null; + input.remove(); + }, 500); + } +} diff --git a/projects/adf-office-services-ext/src/lib/effects/aos.effects.ts b/projects/adf-office-services-ext/src/lib/effects/aos.effects.ts new file mode 100755 index 0000000000..b2fee28429 --- /dev/null +++ b/projects/adf-office-services-ext/src/lib/effects/aos.effects.ts @@ -0,0 +1,24 @@ +import { Injectable } from '@angular/core'; +import { Actions, Effect, ofType } from '@ngrx/effects'; +import { map } from 'rxjs/operators'; + +import { AOS_ACTION, AosAction } from '../actions/aos.actions'; +import { AosEditOnlineService } from '../aos-extension.service'; + +@Injectable() +export class AosEffects { + constructor( + private actions$: Actions, + private aosEditOnlineService: AosEditOnlineService + ) {} + + @Effect({ dispatch: false }) + openOffice$ = this.actions$.pipe( + ofType(AOS_ACTION), + map(action => { + if (action.payload) { + this.aosEditOnlineService.onActionEditOnlineAos(action.payload); + } + }) + ); +} diff --git a/projects/adf-office-services-ext/src/lib/evaluators.ts b/projects/adf-office-services-ext/src/lib/evaluators.ts new file mode 100644 index 0000000000..992e672de2 --- /dev/null +++ b/projects/adf-office-services-ext/src/lib/evaluators.ts @@ -0,0 +1,45 @@ +import { RuleContext, RuleParameter } from '@alfresco/adf-extensions'; +import { getFileExtension, supportedExtensions } from './utils'; + +export function canOpenWithOffice( + context: RuleContext, + ...args: RuleParameter[] +): boolean { + const file = context.selection.file; + + if (!file || !file.entry || !file.entry.properties) { + return false; + } + + if (file.entry.isLocked) { + return false; + } + + const extension = getFileExtension(file.entry.name); + if (!extension || !supportedExtensions[extension]) { + return false; + } + + /* + if (file.entry && file.entry.aspectNames) { + const checkedOut = file.entry.aspectNames.find( + (aspect: string) => aspect === 'cm:checkedOut' + ); + + if (checkedOut) { + return false; + } + } + */ + + if (file.entry.properties['cm:lockType'] === 'WRITE_LOCK') { + return false; + } + + const lockOwner = file.entry.properties['cm:lockOwner']; + if (lockOwner && lockOwner.id !== context.profile.id) { + return false; + } + + return true; +} diff --git a/projects/adf-office-services-ext/src/lib/utils.ts b/projects/adf-office-services-ext/src/lib/utils.ts new file mode 100644 index 0000000000..43bfa0684f --- /dev/null +++ b/projects/adf-office-services-ext/src/lib/utils.ts @@ -0,0 +1,37 @@ +/* cspell:disable */ +export const supportedExtensions = { + doc: 'ms-word', + docx: 'ms-word', + docm: 'ms-word', + dot: 'ms-word', + dotx: 'ms-word', + dotm: 'ms-word', + xls: 'ms-excel', + xlsx: 'ms-excel', + xlsb: 'ms-excel', + xlsm: 'ms-excel', + xlt: 'ms-excel', + xltx: 'ms-excel', + xltm: 'ms-excel', + ppt: 'ms-powerpoint', + pptx: 'ms-powerpoint', + pot: 'ms-powerpoint', + potx: 'ms-powerpoint', + potm: 'ms-powerpoint', + pptm: 'ms-powerpoint', + pps: 'ms-powerpoint', + ppsx: 'ms-powerpoint', + ppam: 'ms-powerpoint', + ppsm: 'ms-powerpoint', + sldx: 'ms-powerpoint', + sldm: 'ms-powerpoint' +}; +/* cspell:enable */ + +export function getFileExtension(fileName: string): string { + if (fileName) { + const match = fileName.match(/\.([^\./\?\#]+)($|\?|\#)/); + return match ? match[1] : null; + } + return null; +} diff --git a/projects/adf-office-services-ext/src/public_api.ts b/projects/adf-office-services-ext/src/public_api.ts new file mode 100644 index 0000000000..af56fbcbee --- /dev/null +++ b/projects/adf-office-services-ext/src/public_api.ts @@ -0,0 +1,5 @@ +export * from './lib/aos-extension.service'; +export * from './lib/actions/aos.actions'; +export * from './lib/effects/aos.effects'; + +export * from './lib/aos-extension.module'; diff --git a/projects/adf-office-services-ext/src/test.ts b/projects/adf-office-services-ext/src/test.ts new file mode 100644 index 0000000000..e11ff1c97b --- /dev/null +++ b/projects/adf-office-services-ext/src/test.ts @@ -0,0 +1,22 @@ +// This file is required by karma.conf.js and loads recursively all the .spec and framework files + +import 'core-js/es7/reflect'; +import 'zone.js/dist/zone'; +import 'zone.js/dist/zone-testing'; +import { getTestBed } from '@angular/core/testing'; +import { + BrowserDynamicTestingModule, + platformBrowserDynamicTesting +} from '@angular/platform-browser-dynamic/testing'; + +declare const require: any; + +// First, initialize the Angular testing environment. +getTestBed().initTestEnvironment( + BrowserDynamicTestingModule, + platformBrowserDynamicTesting() +); +// Then we find all the tests. +const context = require.context('./', true, /\.spec\.ts$/); +// And load the modules. +context.keys().map(context); diff --git a/projects/adf-office-services-ext/tsconfig.lib.json b/projects/adf-office-services-ext/tsconfig.lib.json new file mode 100644 index 0000000000..3fe337fcf5 --- /dev/null +++ b/projects/adf-office-services-ext/tsconfig.lib.json @@ -0,0 +1,32 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "../../out-tsc/lib", + "target": "es2015", + "module": "es2015", + "moduleResolution": "node", + "declaration": true, + "sourceMap": true, + "inlineSources": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "importHelpers": true, + "types": [], + "lib": [ + "dom", + "es2018" + ] + }, + "angularCompilerOptions": { + "annotateForClosureCompiler": true, + "skipTemplateCodegen": true, + "strictMetadataEmit": true, + "fullTemplateTypeCheck": true, + "strictInjectionParameters": true, + "enableResourceInlining": true + }, + "exclude": [ + "src/test.ts", + "**/*.spec.ts" + ] +} diff --git a/projects/adf-office-services-ext/tsconfig.spec.json b/projects/adf-office-services-ext/tsconfig.spec.json new file mode 100644 index 0000000000..16da33db07 --- /dev/null +++ b/projects/adf-office-services-ext/tsconfig.spec.json @@ -0,0 +1,17 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "../../out-tsc/spec", + "types": [ + "jasmine", + "node" + ] + }, + "files": [ + "src/test.ts" + ], + "include": [ + "**/*.spec.ts", + "**/*.d.ts" + ] +} diff --git a/projects/adf-office-services-ext/tslint.json b/projects/adf-office-services-ext/tslint.json new file mode 100644 index 0000000000..124133f849 --- /dev/null +++ b/projects/adf-office-services-ext/tslint.json @@ -0,0 +1,17 @@ +{ + "extends": "../../tslint.json", + "rules": { + "directive-selector": [ + true, + "attribute", + "lib", + "camelCase" + ], + "component-selector": [ + true, + "element", + "lib", + "kebab-case" + ] + } +} diff --git a/src/app.config.json b/src/app.config.json index dc8b4edc82..1295eebeca 100644 --- a/src/app.config.json +++ b/src/app.config.json @@ -1,5 +1,6 @@ { "ecmHost": "{protocol}//{hostname}{:port}", + "aosHost": "{protocol}//{hostname}{:port}/alfresco/aos", "baseShareUrl": null, "providers": "ECM", "authType": "BASIC", diff --git a/src/app/extensions.module.ts b/src/app/extensions.module.ts index 03cebd0282..071595f628 100644 --- a/src/app/extensions.module.ts +++ b/src/app/extensions.module.ts @@ -1,9 +1,10 @@ import { NgModule } from '@angular/core'; +import { AosExtensionModule } from '@alfresco/adf-office-services-ext'; // Main entry point for external extensions only. // For any application-specific code use CoreExtensionsModule instead. @NgModule({ - imports: [] + imports: [AosExtensionModule] }) export class AppExtensionsModule {} diff --git a/src/assets/app.extensions.json b/src/assets/app.extensions.json index 8b9e836292..0c49bb2a95 100644 --- a/src/assets/app.extensions.json +++ b/src/assets/app.extensions.json @@ -7,7 +7,7 @@ "$license": "LGPL-3.0", "$runtime": "1.5.0", "$description": "Core application extensions and features", - "$references": [], + "$references": ["aos.plugin.json"], "rules": [ { diff --git a/tsconfig.json b/tsconfig.json index f06fa76b9b..b6dad6889c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -14,7 +14,14 @@ "lib": ["es2018", "dom"], "module": "es2015", "baseUrl": "./", - "paths": {}, + "paths": { + "@alfresco/adf-office-services-ext": [ + "dist/@alfresco/adf-office-services-ext" + ], + "@alfresco/adf-office-services-ext/*": [ + "dist/@alfresco/adf-office-services-ext/*" + ] + }, "resolveJsonModule": true }, "exclude": ["node_modules"], From 894a92818744c77859963e8ca59c301eaea6503a Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Sun, 10 Feb 2019 15:56:02 +0200 Subject: [PATCH 044/259] [ACA-2193] Lock node - unlock after new version is uploaded (#924) * unlock node api call * unlock action and effect * unlock node after version upload * check if locked * clear version input on dialog cancel event * update viewer on node version upload * update viewer on file upload delete * test * update tests * update tests * rename evaluators * update docs --- docs/extending/application-actions.md | 80 ++++++++++--------- docs/extending/rules.md | 5 ++ .../preview/preview.component.spec.ts | 45 ++++++++++- .../components/preview/preview.component.ts | 20 ++++- src/app/extensions/core.extensions.module.ts | 4 +- src/app/services/content-api.service.ts | 4 + .../content-management.service.spec.ts | 33 +++++++- .../services/content-management.service.ts | 13 ++- src/app/store/actions/node.actions.ts | 6 ++ src/app/store/effects/node.effects.spec.ts | 63 ++++++++++++++- src/app/store/effects/node.effects.ts | 23 +++++- src/app/store/effects/upload.effects.ts | 32 +++++++- src/assets/app.extensions.json | 4 +- 13 files changed, 278 insertions(+), 54 deletions(-) diff --git a/docs/extending/application-actions.md b/docs/extending/application-actions.md index 2494f9e7eb..662c33e86d 100644 --- a/docs/extending/application-actions.md +++ b/docs/extending/application-actions.md @@ -76,42 +76,44 @@ and perform document list reload if needed. Below is the list of public actions types you can use in the plugin definitions as a reference to the action: -| Name | Payload | Description | -| -- | -- | -- | -| SET_CURRENT_FOLDER | Node | Notify components about currently opened folder. | -| SET_CURRENT_URL | string | Notify components about current browser URL. | -| SET_USER_PROFILE | Person | Assign current user profile. | -| TOGGLE_INFO_DRAWER | n/a | Toggle info drawer for the selected node. | -| ADD_FAVORITE | MinimalNodeEntity[] | Add nodes (or selection) to favorites. | -| REMOVE_FAVORITE | MinimalNodeEntity[] | Removes nodes (or selection) from favorites. | -| DELETE_LIBRARY | string | Delete a Library by id. Takes selected node if payload not provided. | -| CREATE_LIBRARY | n/a | Invoke a "Create Library" dialog. | -| SET_SELECTED_NODES | MinimalNodeEntity[] | Notify components about selected nodes. | -| DELETE_NODES | MinimalNodeEntity[] | Delete the nodes (or selection). Supports undo actions. | -| UNDO_DELETE_NODES | any[] | Reverts deletion of nodes (or selection). | -| RESTORE_DELETED_NODES | MinimalNodeEntity[] | Restores deleted nodes (or selection). Typically used with Trashcan. | -| PURGE_DELETED_NODES | MinimalNodeEntity[] | Permanently delete nodes (or selection). Typically used with Trashcan. | -| DOWNLOAD_NODES | MinimalNodeEntity[] | Download nodes (or selections). Creates a ZIP archive for folders or multiple items. | -| CREATE_FOLDER | string | Invoke a "Create Folder" dialog for the opened folder (or the parent folder id in the payload). | -| EDIT_FOLDER | MinimalNodeEntity | Invoke an "Edit Folder" dialog for the node (or selection). | -| SHARE_NODE | MinimalNodeEntity | Invoke a "Share" dialog for the node (or selection). | -| UNSHARE_NODES | MinimalNodeEntity[] | Remove nodes (or selection) from the shared nodes (does not remove content). | -| COPY_NODES | MinimalNodeEntity[] | Invoke a "Copy" dialog for the nodes (or selection). Supports undo actions. | -| MOVE_NODES | MinimalNodeEntity[] | Invoke a "Move" dialog for the nodes (or selection). Supports undo actions. | -| MANAGE_PERMISSIONS | MinimalNodeEntity | Invoke a "Manage Permissions" dialog for the node (or selection). | -| MANAGE_VERSIONS | MinimalNodeEntity | Invoke a "Manage Versions" dialog for the node (or selection). | -| NAVIGATE_URL | string | Navigate to a given route URL within the application. | -| NAVIGATE_ROUTE | any[] | Navigate to a particular Route (supports parameters). | -| NAVIGATE_FOLDER | MinimalNodeEntity | Navigate to a folder based on the Node properties. | -| NAVIGATE_PARENT_FOLDER | MinimalNodeEntity | Navigate to a containing folder based on the Node properties. | -| NAVIGATE_LIBRARY | string | Navigate to library. | -| SEARCH_BY_TERM | string | Perform a simple search by the term and navigate to Search results. | -| SNACKBAR_INFO | string | Show information snackbar with the message provided. | -| SNACKBAR_WARNING | string | Show warning snackbar with the message provided. | -| SNACKBAR_ERROR | string | Show error snackbar with the message provided. | -| UPLOAD_FILES | n/a | Invoke "Upload Files" dialog and upload files to the currently opened folder. | -| UPLOAD_FOLDER | n/a | Invoke "Upload Folder" dialog and upload selected folder to the currently opened one. | -| VIEW_FILE | MinimalNodeEntity | Preview the file (or selection) in the Viewer. | -| PRINT_FILE | MinimalNodeEntity | Print the file opened in the Viewer (or selected). | -| FULLSCREEN_VIEWER | n/a | Enters fullscreen mode to view the file opened in the Viewer. | -| LOGOUT | n/a | Log out and redirect to Login screen. | +| Name | Payload | Description | +| ---------------------- | ------------------- | ----------------------------------------------------------------------------------------------- | +| SET_CURRENT_FOLDER | Node | Notify components about currently opened folder. | +| SET_CURRENT_URL | string | Notify components about current browser URL. | +| SET_USER_PROFILE | Person | Assign current user profile. | +| TOGGLE_INFO_DRAWER | n/a | Toggle info drawer for the selected node. | +| ADD_FAVORITE | MinimalNodeEntity[] | Add nodes (or selection) to favorites. | +| REMOVE_FAVORITE | MinimalNodeEntity[] | Removes nodes (or selection) from favorites. | +| DELETE_LIBRARY | string | Delete a Library by id. Takes selected node if payload not provided. | +| CREATE_LIBRARY | n/a | Invoke a "Create Library" dialog. | +| SET_SELECTED_NODES | MinimalNodeEntity[] | Notify components about selected nodes. | +| DELETE_NODES | MinimalNodeEntity[] | Delete the nodes (or selection). Supports undo actions. | +| UNDO_DELETE_NODES | any[] | Reverts deletion of nodes (or selection). | +| RESTORE_DELETED_NODES | MinimalNodeEntity[] | Restores deleted nodes (or selection). Typically used with Trashcan. | +| PURGE_DELETED_NODES | MinimalNodeEntity[] | Permanently delete nodes (or selection). Typically used with Trashcan. | +| DOWNLOAD_NODES | MinimalNodeEntity[] | Download nodes (or selections). Creates a ZIP archive for folders or multiple items. | +| CREATE_FOLDER | string | Invoke a "Create Folder" dialog for the opened folder (or the parent folder id in the payload). | +| EDIT_FOLDER | MinimalNodeEntity | Invoke an "Edit Folder" dialog for the node (or selection). | +| SHARE_NODE | MinimalNodeEntity | Invoke a "Share" dialog for the node (or selection). | +| UNSHARE_NODES | MinimalNodeEntity[] | Remove nodes (or selection) from the shared nodes (does not remove content). | +| COPY_NODES | MinimalNodeEntity[] | Invoke a "Copy" dialog for the nodes (or selection). Supports undo actions. | +| MOVE_NODES | MinimalNodeEntity[] | Invoke a "Move" dialog for the nodes (or selection). Supports undo actions. | +| MANAGE_PERMISSIONS | MinimalNodeEntity | Invoke a "Manage Permissions" dialog for the node (or selection). | +| MANAGE_VERSIONS | MinimalNodeEntity | Invoke a "Manage Versions" dialog for the node (or selection). | +| NAVIGATE_URL | string | Navigate to a given route URL within the application. | +| NAVIGATE_ROUTE | any[] | Navigate to a particular Route (supports parameters). | +| NAVIGATE_FOLDER | MinimalNodeEntity | Navigate to a folder based on the Node properties. | +| NAVIGATE_PARENT_FOLDER | MinimalNodeEntity | Navigate to a containing folder based on the Node properties. | +| NAVIGATE_LIBRARY | string | Navigate to library. | +| SEARCH_BY_TERM | string | Perform a simple search by the term and navigate to Search results. | +| SNACKBAR_INFO | string | Show information snackbar with the message provided. | +| SNACKBAR_WARNING | string | Show warning snackbar with the message provided. | +| SNACKBAR_ERROR | string | Show error snackbar with the message provided. | +| UPLOAD_FILES | n/a | Invoke "Upload Files" dialog and upload files to the currently opened folder. | +| UPLOAD_FOLDER | n/a | Invoke "Upload Folder" dialog and upload selected folder to the currently opened one. | +| UPLOAD_FILE_VERSION | n/a | Invoke "New File Version" dialog. | +| VIEW_FILE | MinimalNodeEntity | Preview the file (or selection) in the Viewer. | +| UNLOCK_WRITE | NodeEntry | Unlock file from read only mode | +| PRINT_FILE | MinimalNodeEntity | Print the file opened in the Viewer (or selected). | +| FULLSCREEN_VIEWER | n/a | Enters fullscreen mode to view the file opened in the Viewer. | +| LOGOUT | n/a | Log out and redirect to Login screen. | diff --git a/docs/extending/rules.md b/docs/extending/rules.md index 655443ceb8..bfd37b236f 100644 --- a/docs/extending/rules.md +++ b/docs/extending/rules.md @@ -148,6 +148,9 @@ The button will be visible only when the linked rule evaluates to `true`. | app.selection.hasNoLibraryRole | The selected Library node has no role property. | | app.selection.folder | A single Folder node is selected. | | app.selection.folder.canUpdate | User has permissions to update the selected folder. | +| app.selection.folder.canUpdate | User has permissions to update the selected folder. | +| app.selection.file.canLock | User has permissions to lock file. | +| app.selection.file.canUnlock | User has permissions to unlock file. | | repository.isQuickShareEnabled | Whether the quick share repository option is enabled or not. | ## Navigation Evaluators @@ -176,6 +179,8 @@ for example mixing `core.every` and `core.not`. | app.navigation.isNotRecentFiles | Current page is not **Recent Files**. | | app.navigation.isSearchResults | User is using the **Search Results** page. | | app.navigation.isNotSearchResults | Current page is not the **Search Results**. | +| app.navigation.isSharedPreview | Current page is preview **Shared Files** | +| app.navigation.isFavoritesPreview | Current page is preview **Favorites** | **Tip:** See the [Registration](/extending/registration) section for more details on how to register your own entries to be re-used at runtime. diff --git a/src/app/components/preview/preview.component.spec.ts b/src/app/components/preview/preview.component.spec.ts index ea8515d68a..e6898ce5fe 100644 --- a/src/app/components/preview/preview.component.spec.ts +++ b/src/app/components/preview/preview.component.spec.ts @@ -25,11 +25,19 @@ import { NO_ERRORS_SCHEMA } from '@angular/core'; import { Router, ActivatedRoute } from '@angular/router'; -import { TestBed, ComponentFixture } from '@angular/core/testing'; +import { + TestBed, + ComponentFixture, + async, + fakeAsync, + tick +} from '@angular/core/testing'; import { UserPreferencesService, AppConfigPipe, - NodeFavoriteDirective + NodeFavoriteDirective, + UploadService, + AlfrescoApiService } from '@alfresco/adf-core'; import { PreviewComponent } from './preview.component'; import { of, throwError } from 'rxjs'; @@ -38,6 +46,7 @@ import { ExperimentalDirective } from '../../directives/experimental.directive'; import { NodeEffects } from '../../store/effects/node.effects'; import { AppTestingModule } from '../../testing/app-testing.module'; import { ContentApiService } from '../../services/content-api.service'; +import { ContentManagementService } from '../../services/content-management.service'; describe('PreviewComponent', () => { let fixture: ComponentFixture; @@ -46,10 +55,14 @@ describe('PreviewComponent', () => { let route: ActivatedRoute; let preferences: UserPreferencesService; let contentApi: ContentApiService; + let uploadService: UploadService; + let alfrescoApiService: AlfrescoApiService; + let contentManagementService: ContentManagementService; beforeEach(() => { TestBed.configureTestingModule({ imports: [AppTestingModule, EffectsModule.forRoot([NodeEffects])], + providers: [AlfrescoApiService, ContentManagementService], declarations: [ AppConfigPipe, PreviewComponent, @@ -66,6 +79,9 @@ describe('PreviewComponent', () => { route = TestBed.get(ActivatedRoute); preferences = TestBed.get(UserPreferencesService); contentApi = TestBed.get(ContentApiService); + uploadService = TestBed.get(UploadService); + alfrescoApiService = TestBed.get(AlfrescoApiService); + contentManagementService = TestBed.get(ContentManagementService); }); it('should extract the property path root', () => { @@ -697,4 +713,29 @@ describe('PreviewComponent', () => { const ids = await component.getFileIds('recent-files'); expect(ids).toEqual(['node2', 'node1']); }); + + it('should return to parent folder on nodesDeleted event', async(() => { + spyOn(component, 'navigateToFileLocation'); + fixture.detectChanges(); + contentManagementService.nodesDeleted.next(); + + expect(component.navigateToFileLocation).toHaveBeenCalled(); + })); + + it('should return to parent folder on fileUploadDeleted event', async(() => { + spyOn(component, 'navigateToFileLocation'); + fixture.detectChanges(); + uploadService.fileUploadDeleted.next(); + + expect(component.navigateToFileLocation).toHaveBeenCalled(); + })); + + it('should emit nodeUpdated event on fileUploadComplete event', fakeAsync(() => { + spyOn(alfrescoApiService.nodeUpdated, 'next'); + fixture.detectChanges(); + uploadService.fileUploadComplete.next({ data: { entry: {} } }); + tick(300); + + expect(alfrescoApiService.nodeUpdated.next).toHaveBeenCalled(); + })); }); diff --git a/src/app/components/preview/preview.component.ts b/src/app/components/preview/preview.component.ts index 772a0dcbf6..b8db4ab913 100644 --- a/src/app/components/preview/preview.component.ts +++ b/src/app/components/preview/preview.component.ts @@ -38,7 +38,13 @@ import { UrlSegment, PRIMARY_OUTLET } from '@angular/router'; -import { UserPreferencesService, ObjectUtils } from '@alfresco/adf-core'; +import { debounceTime } from 'rxjs/operators'; +import { + UserPreferencesService, + ObjectUtils, + UploadService, + AlfrescoApiService +} from '@alfresco/adf-core'; import { Store } from '@ngrx/store'; import { AppStore } from '../../store/states/app.state'; import { SetSelectedNodesAction } from '../../store/actions'; @@ -84,6 +90,8 @@ export class PreviewComponent extends PageComponent private appDataService: AppDataService, private route: ActivatedRoute, private router: Router, + private apiService: AlfrescoApiService, + private uploadService: UploadService, store: Store, extensions: AppExtensionService, content: ContentManagementService @@ -122,7 +130,15 @@ export class PreviewComponent extends PageComponent this.subscriptions = this.subscriptions.concat([ this.content.nodesDeleted.subscribe(() => this.navigateToFileLocation(true) - ) + ), + + this.uploadService.fileUploadDeleted.subscribe(() => + this.navigateToFileLocation(true) + ), + + this.uploadService.fileUploadComplete + .pipe(debounceTime(300)) + .subscribe(file => this.apiService.nodeUpdated.next(file.data.entry)) ]); this.openWith = this.extensions.openWithActions; diff --git a/src/app/extensions/core.extensions.module.ts b/src/app/extensions/core.extensions.module.ts index 4ea8e960dc..0ac434f4df 100644 --- a/src/app/extensions/core.extensions.module.ts +++ b/src/app/extensions/core.extensions.module.ts @@ -111,8 +111,8 @@ export class CoreExtensionsModule { extensions.setEvaluators({ 'app.selection.canDelete': app.canDeleteSelection, - 'app.selection.canUnlockFile': app.canUnlockFile, - 'app.selection.canLockFile': app.canLockFile, + 'app.selection.file.canUnlock': app.canUnlockFile, + 'app.selection.file.canLock': app.canLockFile, 'app.selection.canDownload': app.canDownloadSelection, 'app.selection.notEmpty': app.hasSelection, 'app.selection.canUnshare': app.canUnshareNodes, diff --git a/src/app/services/content-api.service.ts b/src/app/services/content-api.service.ts index fea3787b8a..36c9822d02 100644 --- a/src/app/services/content-api.service.ts +++ b/src/app/services/content-api.service.ts @@ -281,4 +281,8 @@ export class ContentApiService { ) ); } + + unlockNode(nodeId: string, opts?) { + return this.api.nodesApi.unlockNode(nodeId, opts); + } } diff --git a/src/app/services/content-management.service.spec.ts b/src/app/services/content-management.service.spec.ts index 29845e5e84..c4fb81a6af 100644 --- a/src/app/services/content-management.service.spec.ts +++ b/src/app/services/content-management.service.spec.ts @@ -43,7 +43,8 @@ import { MoveNodesAction, CopyNodesAction, ShareNodeAction, - SetSelectedNodesAction + SetSelectedNodesAction, + UnlockWriteAction } from '../store/actions'; import { map } from 'rxjs/operators'; import { NodeEffects } from '../store/effects/node.effects'; @@ -1567,4 +1568,34 @@ describe('ContentManagementService', () => { ); })); }); + + describe('Unlock Node', () => { + it('should unlock node', fakeAsync(() => { + spyOn(contentApi, 'unlockNode').and.returnValue(Promise.resolve({})); + + store.dispatch(new UnlockWriteAction({ entry: { id: 'node-id' } })); + tick(); + flush(); + + expect(contentApi.unlockNode).toHaveBeenCalled(); + })); + + it('should raise error when unlock node fails', fakeAsync(done => { + spyOn(contentApi, 'unlockNode').and.callFake( + () => new Promise((resolve, reject) => reject('error')) + ); + spyOn(store, 'dispatch').and.callThrough(); + store.dispatch( + new UnlockWriteAction({ entry: { id: 'node-id', name: 'some-file' } }) + ); + tick(); + flush(); + + expect(store.dispatch['calls'].argsFor(1)[0]).toEqual( + new SnackbarErrorAction('APP.MESSAGES.ERRORS.UNLOCK_NODE', { + fileName: 'some-file' + }) + ); + })); + }); }); diff --git a/src/app/services/content-management.service.ts b/src/app/services/content-management.service.ts index d1de29484a..9cfbccc794 100644 --- a/src/app/services/content-management.service.ts +++ b/src/app/services/content-management.service.ts @@ -51,7 +51,8 @@ import { SiteEntry, DeletedNodesPaging, PathInfoEntity, - SiteBody + SiteBody, + NodeEntry } from '@alfresco/js-api'; import { NodePermissionService } from './node-permission.service'; import { NodeInfo, DeletedNodeInfo, DeleteStatus } from '../store/models'; @@ -1217,4 +1218,14 @@ export class ContentManagementService { }) ); } + + unlockNode(node: NodeEntry) { + this.contentApi.unlockNode(node.entry.id).catch(() => { + this.store.dispatch( + new SnackbarErrorAction('APP.MESSAGES.ERRORS.UNLOCK_NODE', { + fileName: node.entry.name + }) + ); + }); + } } diff --git a/src/app/store/actions/node.actions.ts b/src/app/store/actions/node.actions.ts index c97b4e2152..0749f9ee33 100644 --- a/src/app/store/actions/node.actions.ts +++ b/src/app/store/actions/node.actions.ts @@ -43,6 +43,7 @@ export const PRINT_FILE = 'PRINT_FILE'; export const FULLSCREEN_VIEWER = 'FULLSCREEN_VIEWER'; export const MANAGE_VERSIONS = 'MANAGE_VERSIONS'; export const EDIT_OFFLINE = 'EDIT_OFFLINE'; +export const UNLOCK_WRITE = 'UNLOCK_WRITE_LOCK'; export class SetSelectedNodesAction implements Action { readonly type = SET_SELECTED_NODES; @@ -128,3 +129,8 @@ export class EditOfflineAction implements Action { readonly type = EDIT_OFFLINE; constructor(public payload: any) {} } + +export class UnlockWriteAction implements Action { + readonly type = UNLOCK_WRITE; + constructor(public payload: any) {} +} diff --git a/src/app/store/effects/node.effects.spec.ts b/src/app/store/effects/node.effects.spec.ts index cb78022a90..f64a65ef04 100644 --- a/src/app/store/effects/node.effects.spec.ts +++ b/src/app/store/effects/node.effects.spec.ts @@ -42,7 +42,10 @@ import { EditFolderAction, CopyNodesAction, MoveNodesAction, - ManagePermissionsAction + ManagePermissionsAction, + UnlockWriteAction, + FullscreenViewerAction, + PrintFileAction } from '../actions/node.actions'; import { SetCurrentFolderAction } from '../actions/app.actions'; @@ -398,4 +401,62 @@ describe('NodeEffects', () => { expect(contentService.managePermissions).not.toHaveBeenCalled(); }); }); + + describe('printFile$', () => { + it('it should print node content from payload', () => { + spyOn(contentService, 'printFile').and.stub(); + const node: any = { entry: { id: 'node-id' } }; + + store.dispatch(new PrintFileAction(node)); + + expect(contentService.printFile).toHaveBeenCalledWith(node); + }); + + it('it should print node content from store', fakeAsync(() => { + spyOn(contentService, 'printFile').and.stub(); + const node: any = { entry: { isFile: true, id: 'node-id' } }; + + store.dispatch(new SetSelectedNodesAction([node])); + + tick(100); + + store.dispatch(new PrintFileAction(null)); + + expect(contentService.printFile).toHaveBeenCalledWith(node); + })); + }); + + describe('fullscreenViewer$', () => { + it('should call fullscreen viewer', () => { + spyOn(contentService, 'fullscreenViewer').and.stub(); + + store.dispatch(new FullscreenViewerAction(null)); + + expect(contentService.fullscreenViewer).toHaveBeenCalled(); + }); + }); + + describe('unlockWrite$', () => { + it('should unlock node from payload', () => { + spyOn(contentService, 'unlockNode').and.stub(); + const node: any = { entry: { id: 'node-id' } }; + + store.dispatch(new UnlockWriteAction(node)); + + expect(contentService.unlockNode).toHaveBeenCalledWith(node); + }); + + it('should unlock node from store selection', fakeAsync(() => { + spyOn(contentService, 'unlockNode').and.stub(); + const node: any = { entry: { isFile: true, id: 'node-id' } }; + + store.dispatch(new SetSelectedNodesAction([node])); + + tick(100); + + store.dispatch(new UnlockWriteAction(null)); + + expect(contentService.unlockNode).toHaveBeenCalledWith(node); + })); + }); }); diff --git a/src/app/store/effects/node.effects.ts b/src/app/store/effects/node.effects.ts index 10d60f2d7a..8c9adbc215 100644 --- a/src/app/store/effects/node.effects.ts +++ b/src/app/store/effects/node.effects.ts @@ -44,7 +44,9 @@ import { ShareNodeAction, SHARE_NODE, ManageVersionsAction, - MANAGE_VERSIONS + MANAGE_VERSIONS, + UnlockWriteAction, + UNLOCK_WRITE } from '../actions'; import { ContentManagementService } from '../../services/content-management.service'; import { currentFolder, appSelection } from '../selectors/app.selectors'; @@ -316,4 +318,23 @@ export class NodeEffects { this.contentService.fullscreenViewer(); }) ); + + @Effect({ dispatch: false }) + unlockWrite$ = this.actions$.pipe( + ofType(UNLOCK_WRITE), + map(action => { + if (action && action.payload) { + this.contentService.unlockNode(action.payload); + } else { + this.store + .select(appSelection) + .pipe(take(1)) + .subscribe(selection => { + if (selection && selection.file) { + this.contentService.unlockNode(selection.file); + } + }); + } + }) + ); } diff --git a/src/app/store/effects/upload.effects.ts b/src/app/store/effects/upload.effects.ts index 640881a19a..1ab04f69bd 100644 --- a/src/app/store/effects/upload.effects.ts +++ b/src/app/store/effects/upload.effects.ts @@ -34,7 +34,8 @@ import { UPLOAD_FOLDER, UPLOAD_FILE_VERSION, UploadFileVersionAction, - SnackbarErrorAction + SnackbarErrorAction, + UnlockWriteAction } from '../actions'; import { map, @@ -42,7 +43,9 @@ import { flatMap, distinctUntilChanged, catchError, - switchMap + switchMap, + tap, + filter } from 'rxjs/operators'; import { FileUtils, FileModel, UploadService } from '@alfresco/adf-core'; import { currentFolder } from '../selectors/app.selectors'; @@ -114,6 +117,12 @@ export class UploadEffects { return fromEvent(this.fileVersionInput, 'change').pipe( distinctUntilChanged(), flatMap(() => this.contentService.versionUploadDialog().afterClosed()), + tap(form => { + if (!form) { + this.fileVersionInput.value = ''; + } + }), + filter(form => !!form), flatMap(form => forkJoin(of(form), this.contentService.getNodeInfo())), map(([form, node]) => { const file = this.fileVersionInput.files[0]; @@ -134,7 +143,7 @@ export class UploadEffects { ); this.fileVersionInput.value = ''; - this.uploadQueue([fileModel]); + this.uploadVersion(fileModel); }), catchError(error => { this.fileVersionInput.value = ''; @@ -176,4 +185,21 @@ export class UploadEffects { }); } } + + private uploadVersion(file: FileModel) { + this.ngZone.run(() => { + this.uploadService.addToQueue(file); + this.uploadService.uploadFilesInTheQueue(); + + this.uploadService.fileUploadComplete.subscribe(completed => { + if ( + file.data.entry.properties && + file.data.entry.properties['cm:lockType'] === 'WRITE_LOCK' && + completed.data.entry.id === file.data.entry.id + ) { + this.store.dispatch(new UnlockWriteAction(completed.data)); + } + }); + }); + } } diff --git a/src/assets/app.extensions.json b/src/assets/app.extensions.json index 0c49bb2a95..b638879ccf 100644 --- a/src/assets/app.extensions.json +++ b/src/assets/app.extensions.json @@ -251,8 +251,8 @@ "type": "rule", "value": "core.some", "parameters": [ - { "type": "rule", "value": "app.selection.canUnlockFile" }, - { "type": "rule", "value": "app.selection.canLockFile" } + { "type": "rule", "value": "app.selection.file.canUnlock" }, + { "type": "rule", "value": "app.selection.file.canLock" } ] } ] From 85c6eca0908aadf6c6afc1db92d7a99c5764222c Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Sun, 10 Feb 2019 15:16:30 +0000 Subject: [PATCH 045/259] minor script improvements --- docker-compose-keycloak.yml | 2 +- docker-compose.yml | 2 +- docker/{ => proxy}/nginx.conf | 0 package.json | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) rename docker/{ => proxy}/nginx.conf (100%) diff --git a/docker-compose-keycloak.yml b/docker-compose-keycloak.yml index 2391a9ad10..1022769be5 100644 --- a/docker-compose-keycloak.yml +++ b/docker-compose-keycloak.yml @@ -122,7 +122,7 @@ services: depends_on: - content-app volumes: - - ./docker/nginx.conf:/etc/nginx/conf.d/default.conf + - ./docker/proxy/nginx.conf:/etc/nginx/conf.d/default.conf networks: - internal ports: diff --git a/docker-compose.yml b/docker-compose.yml index 523fe41d99..233fdfca63 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -106,7 +106,7 @@ services: depends_on: - content-app volumes: - - ./docker/nginx.conf:/etc/nginx/conf.d/default.conf + - ./docker/proxy/nginx.conf:/etc/nginx/conf.d/default.conf networks: - internal ports: diff --git a/docker/nginx.conf b/docker/proxy/nginx.conf similarity index 100% rename from docker/nginx.conf rename to docker/proxy/nginx.conf diff --git a/package.json b/package.json index 13e678c6e6..3d59cf5ba1 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "scripts": { "ng": "ng", "start": "npm run build.extensions && ng serve --open", - "start:prod": "ng serve --prod --open", + "start:prod": "node --max-old-space-size=8192 node_modules/@angular/cli/bin/ng serve --prod --open", "build:aos-extension": "rm -rf dist/@alfresco/adf-office-services-ext && ng build adf-office-services-ext && cp projects/adf-office-services-ext/ngi.json dist/@alfresco/adf-office-services-ext && cpr projects/adf-office-services-ext/assets dist/@alfresco/adf-office-services-ext/assets", "build.extensions": "npm run build:aos-extension", "build.app": "node --max-old-space-size=8192 node_modules/@angular/cli/bin/ng build app", From ae3658225ab110b01964654fff847feaa302ebf4 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Mon, 11 Feb 2019 12:59:02 +0000 Subject: [PATCH 046/259] update AOS extension docs and version --- projects/adf-office-services-ext/README.md | 35 +++++++++++-------- projects/adf-office-services-ext/package.json | 2 +- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/projects/adf-office-services-ext/README.md b/projects/adf-office-services-ext/README.md index 6d04ec313e..0647c698fd 100644 --- a/projects/adf-office-services-ext/README.md +++ b/projects/adf-office-services-ext/README.md @@ -1,24 +1,31 @@ -# AdfOfficeServicesExt +# Alfresco Office Services Extension -This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 7.2.0. +An extension module for the Alfresco Content Application that enables "Edit in Microsoft Office" feature. -## Code scaffolding +Integrates with: -Run `ng generate component component-name --project adf-office-services-ext` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project adf-office-services-ext`. -> Note: Don't forget to add `--project adf-office-services-ext` or else it will be added to the default project in your `angular.json` file. +- Context Menus +- Toolbars +- Viewer / Open With -## Build +## Installation -Run `ng build adf-office-services-ext` to build the project. The build artifacts will be stored in the `dist/` directory. +Install the `ngi` as a global tool: -## Publishing +```sh +npm i -g @ngstack/install +``` -After building your library with `ng build adf-office-services-ext`, go to the dist folder `cd dist/adf-office-services-ext` and run `npm publish`. +In the project root: -## Running unit tests +```sh +ngi @alfresco/adf-office-services-ext --module=extensions +``` -Run `ng test adf-office-services-ext` to execute the unit tests via [Karma](https://karma-runner.github.io). +Update `app.extensions.json` and append a reference to the plugin definition: -## Further help - -To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md). +```json +{ + "$references": ["aos.plugin.json"] +} +``` diff --git a/projects/adf-office-services-ext/package.json b/projects/adf-office-services-ext/package.json index 77d977ebe3..7e8fabaa8e 100644 --- a/projects/adf-office-services-ext/package.json +++ b/projects/adf-office-services-ext/package.json @@ -1,6 +1,6 @@ { "name": "@alfresco/adf-office-services-ext", - "version": "1.0.0", + "version": "0.0.1", "license": "LGPL-3.0", "author": { "name": "Keensoft", From bc22f17a3c1fd10368d3bc806f99f63047cbd789 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Mon, 11 Feb 2019 14:01:21 +0000 Subject: [PATCH 047/259] update package configuration for AOS ext --- projects/adf-office-services-ext/package.json | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/projects/adf-office-services-ext/package.json b/projects/adf-office-services-ext/package.json index 7e8fabaa8e..2ad41b8f1d 100644 --- a/projects/adf-office-services-ext/package.json +++ b/projects/adf-office-services-ext/package.json @@ -1,11 +1,20 @@ { "name": "@alfresco/adf-office-services-ext", - "version": "0.0.1", + "version": "0.0.2", "license": "LGPL-3.0", "author": { "name": "Keensoft", "url": "http://www.keensoft.es/en/" }, + "contributors": [ + { + "name": "Denys Vuika", + "email": "denys.vuka@gmail.com", + "url": "https://medium.com/@denysvuika" + } + ], + "homepage": "https://github.com/Alfresco/alfresco-content-app", + "keywords": ["Alfresco", "ADF", "ACA", "Content Application"], "peerDependencies": { "@angular/common": "^7.2.0", "@angular/core": "^7.2.0", From ad1d2633c416110e30a913c4dedd3d784ac6936a Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Mon, 11 Feb 2019 16:45:00 +0000 Subject: [PATCH 048/259] update AOS extension details --- projects/adf-office-services-ext/LICENSE | 340 +++++++++--------- projects/adf-office-services-ext/README.md | 43 ++- .../assets/aos.plugin.json | 2 +- projects/adf-office-services-ext/package.json | 4 +- 4 files changed, 221 insertions(+), 168 deletions(-) diff --git a/projects/adf-office-services-ext/LICENSE b/projects/adf-office-services-ext/LICENSE index 65c5ca88a6..430d42bbea 100644 --- a/projects/adf-office-services-ext/LICENSE +++ b/projects/adf-office-services-ext/LICENSE @@ -1,165 +1,177 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS diff --git a/projects/adf-office-services-ext/README.md b/projects/adf-office-services-ext/README.md index 0647c698fd..f8f8cb161e 100644 --- a/projects/adf-office-services-ext/README.md +++ b/projects/adf-office-services-ext/README.md @@ -8,7 +8,7 @@ Integrates with: - Toolbars - Viewer / Open With -## Installation +## Automated Installation Install the `ngi` as a global tool: @@ -29,3 +29,44 @@ Update `app.extensions.json` and append a reference to the plugin definition: "$references": ["aos.plugin.json"] } ``` + +## Manual Installation + +Install the extension library + +```sh +npm i @alfresco/adf-office-services-ext +``` + +Update the `extensions.module.ts` and import corresponding module. + +```ts +import { NgModule } from '@angular/core'; +import { AosExtensionModule } from '@alfresco/adf-office-services-ext'; + +// Main entry point for external extensions only. +// For any application-specific code use CoreExtensionsModule instead. + +@NgModule({ + imports: [AosExtensionModule] +}) +export class AppExtensionsModule {} +``` + +Setup the resource references in the `angular.json` assets section: + +```json +{ + "glob": "**/*.json", + "input": "node_modules/@alfresco/adf-office-services-ext/assets", + "output": "./assets/plugins" +} +``` + +Update `app.extensions.json` and append a reference to the plugin definition: + +```json +{ + "$references": ["aos.plugin.json"] +} +``` diff --git a/projects/adf-office-services-ext/assets/aos.plugin.json b/projects/adf-office-services-ext/assets/aos.plugin.json index 115574af37..4ad920961d 100644 --- a/projects/adf-office-services-ext/assets/aos.plugin.json +++ b/projects/adf-office-services-ext/assets/aos.plugin.json @@ -5,7 +5,7 @@ "$name": "keensoft.aos.plugin", "$description": "Extension that provides Office Edit Online Action", "$vendor": "Keensoft", - "$license": "LGPL-3.0", + "$license": "Apache-2.0", "$runtime": "1.6.0", "actions": [ diff --git a/projects/adf-office-services-ext/package.json b/projects/adf-office-services-ext/package.json index 2ad41b8f1d..3627f7dc12 100644 --- a/projects/adf-office-services-ext/package.json +++ b/projects/adf-office-services-ext/package.json @@ -1,7 +1,7 @@ { "name": "@alfresco/adf-office-services-ext", - "version": "0.0.2", - "license": "LGPL-3.0", + "version": "0.0.3", + "license": "Apache-2.0", "author": { "name": "Keensoft", "url": "http://www.keensoft.es/en/" From aa4f81118ff06052264f68ada6c44e820b24ec5a Mon Sep 17 00:00:00 2001 From: MariusGrunenberg <43036408+MariusGrunenberg@users.noreply.github.com> Date: Tue, 12 Feb 2019 11:37:39 +0100 Subject: [PATCH 049/259] Search on mobile opens Sidemenu (#929) * Added a check for mobile pages to prevent sidemenu opening --- src/app/components/layout/app-layout/app-layout.component.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/app/components/layout/app-layout/app-layout.component.ts b/src/app/components/layout/app-layout/app-layout.component.ts index 7ad898d830..81869ad7d3 100644 --- a/src/app/components/layout/app-layout/app-layout.component.ts +++ b/src/app/components/layout/app-layout/app-layout.component.ts @@ -155,7 +155,9 @@ export class AppLayoutComponent implements OnInit, OnDestroy { private updateState() { if (this.minimizeSidenav && !this.layout.isMenuMinimized) { this.layout.isMenuMinimized = true; - this.layout.container.toggleMenu(); + if (!this.layout.container.isMobileScreenSize) { + this.layout.container.toggleMenu(); + } } if (!this.minimizeSidenav) { From 9ccd43008700e8f49ad7e1273e04217c09f83d59 Mon Sep 17 00:00:00 2001 From: Suzana Dirla Date: Tue, 12 Feb 2019 16:40:05 +0200 Subject: [PATCH 050/259] [ACA-2200] Upgrade to 3.0.0-beta9 ADF (#931) * upgrade to latest ADF 3.0.0-alpha - remove selectedFacetQueries check - renamed hasPermission from ADF ContentService to hasAllowableOperations * update to ADF 3.0.0-beta9 * [ACA-2200] mincount workaround - until we get the fix for the facet update issue (ADF-3401) --- package-lock.json | 196 +++++++++--------- package.json | 8 +- src/app.config.json | 2 + .../search-results.component.ts | 1 - src/app/services/node-actions.service.ts | 6 +- 5 files changed, 107 insertions(+), 106 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9f2c426827..9963fbebe0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,33 +5,33 @@ "requires": true, "dependencies": { "@alfresco/adf-content-services": { - "version": "3.0.0-3a5fe3fb92cdc7397cbfd3d0869833ea1f1fe8d5", - "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-3.0.0-3a5fe3fb92cdc7397cbfd3d0869833ea1f1fe8d5.tgz", - "integrity": "sha512-TVR6PQznEWtrSWqZHaceogd/E32Q1RsQUxcdjysLJvKWwJZ0of3Nkl7PuJkw4l9SLEah85l0O1lZn0la5HgqtQ==", + "version": "3.0.0-beta9", + "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-3.0.0-beta9.tgz", + "integrity": "sha512-3f1xa7v/LpM4uJtrgTFRCWybogq/q2nhX+t50SE7Fqn1kapMEPxgqcEY4e6n+OmivDnehmgqDXPlQ8qCR8AEsg==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/adf-core": { - "version": "3.0.0-3a5fe3fb92cdc7397cbfd3d0869833ea1f1fe8d5", - "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-3.0.0-3a5fe3fb92cdc7397cbfd3d0869833ea1f1fe8d5.tgz", - "integrity": "sha512-XlubGS/9XDsvc0LLmih6t6X/bKq3UI2OfX8O6mZzfTGzztfkqvgvD1T4E8zgVuZg6J0bE8dTyO7RsNZpyQJBdQ==", + "version": "3.0.0-beta9", + "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-3.0.0-beta9.tgz", + "integrity": "sha512-RIut0spc0VWtBZmf+WGsL7ZaaWJho6FQ0zyMtlUm9SZ3Nd7o0oRe9VYBZj13vdBzCiYDqkZqP3+jFYugH5TRSw==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/adf-extensions": { - "version": "3.0.0-3a5fe3fb92cdc7397cbfd3d0869833ea1f1fe8d5", - "resolved": "https://registry.npmjs.org/@alfresco/adf-extensions/-/adf-extensions-3.0.0-3a5fe3fb92cdc7397cbfd3d0869833ea1f1fe8d5.tgz", - "integrity": "sha512-Zq+rBpDqc7BJ+rMKxniXMWYWUex6tUOhW1wdSvh9oP5dgyLlHRgsvoyIDeDei76u0cuVjbZziQzzJGlWKShmrA==", + "version": "3.0.0-beta9", + "resolved": "https://registry.npmjs.org/@alfresco/adf-extensions/-/adf-extensions-3.0.0-beta9.tgz", + "integrity": "sha512-UZwb/nxm9BcbGtFFUW1FHBG5MWBI8ECBffh74fo5LlH6cgBOhWlLxPmIFbIMNwWK0/vMuRGoVMsPpSciDZF6Zw==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/js-api": { - "version": "3.0.0-d7850f421268e21861e2cd219441b7343efd27ba", - "resolved": "https://registry.npmjs.org/@alfresco/js-api/-/js-api-3.0.0-d7850f421268e21861e2cd219441b7343efd27ba.tgz", - "integrity": "sha512-glHDIbJX5xoOT1SBlmryJ1aDEH99a/826KnJK5M/ybLfv5yBg+LFL8aMRRMkz26wzKn9YxRwxh14a+6u2u9o1A==", + "version": "3.0.0-beta9", + "resolved": "https://registry.npmjs.org/@alfresco/js-api/-/js-api-3.0.0-beta9.tgz", + "integrity": "sha512-60J3aH/YZGsJKsgieexBq273r+0moGCOtGw7gXhz1iByFga15IYvrq93NiWf6oxPRG6l6IzMM7m1PAaTM3B9ww==", "requires": { "event-emitter": "0.3.4", "superagent": "3.8.2" @@ -178,7 +178,7 @@ "dependencies": { "source-map": { "version": "0.5.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "resolved": "http://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=", "dev": true }, @@ -492,7 +492,7 @@ }, "load-json-file": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", "dev": true, "requires": { @@ -554,7 +554,7 @@ }, "pify": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true }, @@ -829,7 +829,7 @@ }, "supports-color": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "resolved": "http://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true } @@ -1002,7 +1002,7 @@ }, "@types/q": { "version": "0.0.32", - "resolved": "https://registry.npmjs.org/@types/q/-/q-0.0.32.tgz", + "resolved": "http://registry.npmjs.org/@types/q/-/q-0.0.32.tgz", "integrity": "sha1-vShOV8hPEyXacCur/IKlMoGQwMU=", "dev": true }, @@ -1020,7 +1020,7 @@ }, "@types/strip-bom": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/strip-bom/-/strip-bom-3.0.0.tgz", + "resolved": "http://registry.npmjs.org/@types/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha1-FKjsOVbC6B7bdSB5CuzyHCkK69I=", "dev": true }, @@ -1578,7 +1578,7 @@ }, "util": { "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "resolved": "http://registry.npmjs.org/util/-/util-0.10.3.tgz", "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", "dev": true, "requires": { @@ -1679,7 +1679,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -2135,7 +2135,7 @@ }, "browserify-aes": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", "dev": true, "requires": { @@ -2172,7 +2172,7 @@ }, "browserify-rsa": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "resolved": "http://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", "dev": true, "requires": { @@ -2226,7 +2226,7 @@ }, "buffer": { "version": "4.9.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", + "resolved": "http://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", "dev": true, "requires": { @@ -2301,7 +2301,7 @@ }, "cacache": { "version": "10.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-10.0.4.tgz", + "resolved": "http://registry.npmjs.org/cacache/-/cacache-10.0.4.tgz", "integrity": "sha512-Dph0MzuH+rTQzGPNT9fAnrPmMmjKfST6trxJeK7NQuHRaVw24VzPRWTmg9MpcwOVQZO0E1FBICUlFeNaKPIfHA==", "dev": true, "requires": { @@ -2375,7 +2375,7 @@ }, "camelcase-keys": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "resolved": "http://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", "dev": true, "requires": { @@ -2684,7 +2684,7 @@ }, "colors": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", + "resolved": "http://registry.npmjs.org/colors/-/colors-1.1.2.tgz", "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", "dev": true }, @@ -3033,7 +3033,7 @@ }, "create-hash": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", "dev": true, "requires": { @@ -3046,7 +3046,7 @@ }, "create-hmac": { "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", "dev": true, "requires": { @@ -3548,7 +3548,7 @@ "dependencies": { "globby": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "resolved": "http://registry.npmjs.org/globby/-/globby-6.1.0.tgz", "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", "dev": true, "requires": { @@ -3561,7 +3561,7 @@ "dependencies": { "pify": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true } @@ -3637,7 +3637,7 @@ }, "diffie-hellman": { "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "resolved": "http://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", "dev": true, "requires": { @@ -3830,7 +3830,7 @@ }, "engine.io-client": { "version": "3.2.1", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.2.1.tgz", + "resolved": "http://registry.npmjs.org/engine.io-client/-/engine.io-client-3.2.1.tgz", "integrity": "sha512-y5AbkytWeM4jQr7m/koQLc5AxpRKC1hEVUb/s1FUAWEJq5AzJJ4NLvzuKPuxtDi5Mq755WuDvZ6Iv2rXj4PTzw==", "dev": true, "requires": { @@ -3956,7 +3956,7 @@ }, "es6-promisify": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "resolved": "http://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", "dev": true, "requires": { @@ -4009,7 +4009,7 @@ "dependencies": { "source-map": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", + "resolved": "http://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", "dev": true, "optional": true, @@ -4205,7 +4205,7 @@ }, "expand-range": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-0.1.1.tgz", + "resolved": "http://registry.npmjs.org/expand-range/-/expand-range-0.1.1.tgz", "integrity": "sha1-TLjtoJk8pW+k9B/ELzy7TMrf8EQ=", "dev": true, "requires": { @@ -4279,7 +4279,7 @@ }, "expand-range": { "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "resolved": "http://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", "dev": true, "requires": { @@ -4368,7 +4368,7 @@ "dependencies": { "array-flatten": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "resolved": "http://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", "dev": true }, @@ -4624,7 +4624,7 @@ }, "finalhandler": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", + "resolved": "http://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", "dev": true, "requires": { @@ -4810,7 +4810,7 @@ }, "fs-access": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz", + "resolved": "http://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz", "integrity": "sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o=", "dev": true, "requires": { @@ -5464,7 +5464,7 @@ }, "get-stream": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "resolved": "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", "dev": true }, @@ -5596,7 +5596,7 @@ }, "got": { "version": "6.7.1", - "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", + "resolved": "http://registry.npmjs.org/got/-/got-6.7.1.tgz", "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", "dev": true, "requires": { @@ -5835,7 +5835,7 @@ }, "http-errors": { "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", "dev": true, "requires": { @@ -5891,7 +5891,7 @@ }, "http-proxy-middleware": { "version": "0.18.0", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.18.0.tgz", + "resolved": "http://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.18.0.tgz", "integrity": "sha512-Fs25KVMPAIIcgjMZkVHJoKg9VcXcC1C8yb9JUgeDvVXY0S/zgVIhMb+qVswDIgtJe2DfckMSY2d6TuTEutlk6Q==", "dev": true, "requires": { @@ -6284,7 +6284,7 @@ }, "is-accessor-descriptor": { "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "resolved": "http://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "requires": { @@ -6325,7 +6325,7 @@ }, "is-builtin-module": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "resolved": "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", "dev": true, "requires": { @@ -6343,7 +6343,7 @@ }, "is-data-descriptor": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "resolved": "http://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "requires": { @@ -6484,7 +6484,7 @@ }, "is-obj": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "resolved": "http://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", "dev": true }, @@ -6745,7 +6745,7 @@ }, "fast-deep-equal": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", + "resolved": "http://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", "dev": true }, @@ -6946,7 +6946,7 @@ }, "jsesc": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", + "resolved": "http://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", "dev": true }, @@ -7038,13 +7038,13 @@ "dependencies": { "core-js": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.3.0.tgz", + "resolved": "http://registry.npmjs.org/core-js/-/core-js-2.3.0.tgz", "integrity": "sha1-+rg/uwstjchfpjbEudNMdUIMbWU=", "dev": true }, "es6-promise": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.0.2.tgz", + "resolved": "http://registry.npmjs.org/es6-promise/-/es6-promise-3.0.2.tgz", "integrity": "sha1-AQ1YWEI6XxGJeWZfRkhqlcbuK7Y=", "dev": true }, @@ -7056,7 +7056,7 @@ }, "readable-stream": { "version": "2.0.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", "dev": true, "requires": { @@ -7070,7 +7070,7 @@ }, "string_decoder": { "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true } @@ -7138,7 +7138,7 @@ }, "karma-cli": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/karma-cli/-/karma-cli-1.0.1.tgz", + "resolved": "http://registry.npmjs.org/karma-cli/-/karma-cli-1.0.1.tgz", "integrity": "sha1-rmw8WKMTodALRRZMRVubhs4X+WA=", "dev": true, "requires": { @@ -7163,7 +7163,7 @@ }, "karma-jasmine-html-reporter": { "version": "0.2.2", - "resolved": "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-0.2.2.tgz", + "resolved": "http://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-0.2.2.tgz", "integrity": "sha1-SKjl7xiAdhfuK14zwRlMNbQ5Ukw=", "dev": true, "requires": { @@ -7267,7 +7267,7 @@ "dependencies": { "promise": { "version": "7.0.4", - "resolved": "https://registry.npmjs.org/promise/-/promise-7.0.4.tgz", + "resolved": "http://registry.npmjs.org/promise/-/promise-7.0.4.tgz", "integrity": "sha1-Nj6EpMNsg1a4kP7WLJHOhdAu1Tk=", "dev": true, "requires": { @@ -7502,7 +7502,7 @@ }, "supports-color": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "resolved": "http://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true } @@ -7522,7 +7522,7 @@ }, "load-json-file": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "dev": true, "requires": { @@ -7535,7 +7535,7 @@ "dependencies": { "pify": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true } @@ -7899,7 +7899,7 @@ }, "media-typer": { "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", "dev": true }, @@ -7926,7 +7926,7 @@ }, "meow": { "version": "3.7.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "resolved": "http://registry.npmjs.org/meow/-/meow-3.7.0.tgz", "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", "dev": true, "requires": { @@ -8152,7 +8152,7 @@ }, "mkdirp": { "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "dev": true, "requires": { @@ -8453,7 +8453,7 @@ "dependencies": { "semver": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "resolved": "http://registry.npmjs.org/semver/-/semver-5.3.0.tgz", "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", "dev": true } @@ -8542,7 +8542,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -9037,13 +9037,13 @@ }, "os-homedir": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "resolved": "http://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "dev": true }, "os-locale": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "resolved": "http://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", "dev": true, "requires": { @@ -9058,7 +9058,7 @@ }, "os-tmpdir": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true }, @@ -9380,7 +9380,7 @@ }, "path-browserify": { "version": "0.0.0", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", + "resolved": "http://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", "dev": true }, @@ -9398,7 +9398,7 @@ }, "path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, @@ -9769,7 +9769,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -9797,7 +9797,7 @@ }, "globby": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", + "resolved": "http://registry.npmjs.org/globby/-/globby-5.0.0.tgz", "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", "dev": true, "requires": { @@ -9811,7 +9811,7 @@ }, "pify": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true }, @@ -10108,7 +10108,7 @@ "dependencies": { "pify": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true } @@ -10138,7 +10138,7 @@ }, "pify": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true } @@ -10177,7 +10177,7 @@ }, "readable-stream": { "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "requires": { "core-util-is": "~1.0.0", @@ -10258,7 +10258,7 @@ }, "regexpu-core": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz", + "resolved": "http://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz", "integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=", "dev": true, "requires": { @@ -10288,13 +10288,13 @@ }, "regjsgen": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", + "resolved": "http://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", "dev": true }, "regjsparser": { "version": "0.1.5", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", + "resolved": "http://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", "dev": true, "requires": { @@ -10303,7 +10303,7 @@ "dependencies": { "jsesc": { "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "resolved": "http://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", "dev": true } @@ -10729,7 +10729,7 @@ }, "safe-regex": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "dev": true, "requires": { @@ -10779,7 +10779,7 @@ }, "sax": { "version": "0.5.8", - "resolved": "https://registry.npmjs.org/sax/-/sax-0.5.8.tgz", + "resolved": "http://registry.npmjs.org/sax/-/sax-0.5.8.tgz", "integrity": "sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE=", "dev": true }, @@ -10810,7 +10810,7 @@ "dependencies": { "source-map": { "version": "0.4.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "resolved": "http://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", "dev": true, "requires": { @@ -11033,7 +11033,7 @@ }, "sha.js": { "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", "dev": true, "requires": { @@ -11120,7 +11120,7 @@ }, "slice-ansi": { "version": "0.0.4", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "resolved": "http://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", "dev": true }, @@ -11336,7 +11336,7 @@ }, "socket.io-parser": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.2.0.tgz", + "resolved": "http://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.2.0.tgz", "integrity": "sha512-FYiBx7rc/KORMJlgsXysflWx/RIvtqZbyGLlHZvjfmPTPeuD/I8MaW7cfFrj5tRltICJdgwflhfZ3NVVbVLFQA==", "dev": true, "requires": { @@ -11621,7 +11621,7 @@ }, "sprintf-js": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "resolved": "http://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, @@ -11761,7 +11761,7 @@ }, "string-width": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "resolved": "http://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "requires": { @@ -11772,7 +11772,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "requires": { "safe-buffer": "~5.1.0" @@ -11791,7 +11791,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -11809,7 +11809,7 @@ }, "strip-eof": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "resolved": "http://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", "dev": true }, @@ -11881,7 +11881,7 @@ }, "source-map": { "version": "0.1.43", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", + "resolved": "http://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", "dev": true, "requires": { @@ -11947,7 +11947,7 @@ }, "tar": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", + "resolved": "http://registry.npmjs.org/tar/-/tar-2.2.1.tgz", "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", "dev": true, "requires": { @@ -12186,7 +12186,7 @@ }, "through": { "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", "dev": true }, @@ -12463,7 +12463,7 @@ }, "tty-browserify": { "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "resolved": "http://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", "dev": true }, @@ -12837,7 +12837,7 @@ }, "vm-browserify": { "version": "0.0.4", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", + "resolved": "http://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", "dev": true, "requires": { @@ -12972,7 +12972,7 @@ }, "source-map": { "version": "0.4.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "resolved": "http://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", "dev": true, "requires": { @@ -13460,7 +13460,7 @@ }, "wrap-ansi": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", "dev": true, "requires": { @@ -13522,7 +13522,7 @@ }, "xmlbuilder": { "version": "9.0.7", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", + "resolved": "http://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", "dev": true }, diff --git a/package.json b/package.json index 3d59cf5ba1..093720f8b7 100644 --- a/package.json +++ b/package.json @@ -35,10 +35,10 @@ }, "private": true, "dependencies": { - "@alfresco/adf-content-services": "3.0.0-3a5fe3fb92cdc7397cbfd3d0869833ea1f1fe8d5", - "@alfresco/adf-core": "3.0.0-3a5fe3fb92cdc7397cbfd3d0869833ea1f1fe8d5", - "@alfresco/adf-extensions": "3.0.0-3a5fe3fb92cdc7397cbfd3d0869833ea1f1fe8d5", - "@alfresco/js-api": "3.0.0-d7850f421268e21861e2cd219441b7343efd27ba", + "@alfresco/adf-content-services": "3.0.0-beta9", + "@alfresco/adf-core": "3.0.0-beta9", + "@alfresco/adf-extensions": "3.0.0-beta9", + "@alfresco/js-api": "3.0.0-beta9", "@angular/animations": "7.2.3", "@angular/cdk": "^7.3.0", "@angular/common": "7.2.3", diff --git a/src/app.config.json b/src/app.config.json index 1295eebeca..259970ab00 100644 --- a/src/app.config.json +++ b/src/app.config.json @@ -239,6 +239,8 @@ }, "facetQueries": { "label": "SEARCH.CATEGORIES.MODIFIED_DATE", + "expanded": true, + "mincount": 0, "queries": [ { "label": "Today", "query": "cm:modified:[TODAY to TODAY]" }, { diff --git a/src/app/components/search/search-results/search-results.component.ts b/src/app/components/search/search-results/search-results.component.ts index 350016cc22..dcbb5c35b5 100644 --- a/src/app/components/search/search-results/search-results.component.ts +++ b/src/app/components/search/search-results/search-results.component.ts @@ -140,7 +140,6 @@ export class SearchResultsComponent extends PageComponent implements OnInit { isFiltered(): boolean { return ( - this.searchFilter.selectedFacetQueries.length > 0 || this.searchFilter.selectedBuckets.length > 0 || this.hasCheckedCategories() ); diff --git a/src/app/services/node-actions.service.ts b/src/app/services/node-actions.service.ts index 85db1644d8..69f30edf46 100644 --- a/src/app/services/node-actions.service.ts +++ b/src/app/services/node-actions.service.ts @@ -288,7 +288,7 @@ export class NodeActionsService { } private hasEntityCreatePermission(entry: MinimalNodeEntryEntity): boolean { - return this.contentService.hasPermission(entry, 'create'); + return this.contentService.hasAllowableOperations(entry, 'create'); } private isSite(entry) { @@ -649,7 +649,7 @@ export class NodeActionsService { if (action === 'copy') { return true; } - return this.contentService.hasPermission(node, permission); + return this.contentService.hasAllowableOperations(node, permission); } // todo: review once 1.10-beta6 is out @@ -670,7 +670,7 @@ export class NodeActionsService { col: DataColumn ): string | null { const entry: MinimalNodeEntryEntity = row.node.entry; - if (!this.contentService.hasPermission(entry, 'update')) { + if (!this.contentService.hasAllowableOperations(entry, 'update')) { return this.documentListService.getMimeTypeIcon('disable/folder'); } From 58272f7fbe7366486bdf40043722bb64abf60df3 Mon Sep 17 00:00:00 2001 From: Suzana Dirla Date: Tue, 12 Feb 2019 18:54:35 +0200 Subject: [PATCH 051/259] [ACA-2171] enable copy and move to library tests (#933) --- e2e/suites/actions/copy.test.ts | 12 ++++-------- e2e/suites/actions/move.test.ts | 12 ++++-------- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/e2e/suites/actions/copy.test.ts b/e2e/suites/actions/copy.test.ts index 743dfa5b8b..c1a1c97044 100755 --- a/e2e/suites/actions/copy.test.ts +++ b/e2e/suites/actions/copy.test.ts @@ -239,8 +239,7 @@ describe('Copy content', () => { expect(await dataTable.isItemPresent(file3InFolder)).toBe(true, `${file3InFolder} not present in destination folder`); }); - // TODO disabled until ACA-2171 is fixed - xit('Copy items into a library - [C280282]', async () => { + it('Copy items into a library - [C280282]', async () => { await dataTable.selectMultipleItems([file1, folder1]); await toolbar.clickMoreActionsCopy(); await copyDialog.selectLocation('File Libraries'); @@ -324,8 +323,7 @@ describe('Copy content', () => { expect(await dataTable.isItemPresent(`${existingFile}-1.txt`)).toBe(true, `${existingFile}-1.txt not present in destination folder`); }); - // TODO disabled until ACA-2171 is fixed - xit('Copy items into a library - [C291899]', async () => { + it('Copy items into a library - [C291899]', async () => { await dataTable.selectItem(file1, source); await toolbar.clickMoreActionsCopy(); await copyDialog.selectLocation('File Libraries'); @@ -403,8 +401,7 @@ describe('Copy content', () => { expect(await dataTable.isItemPresent(`${existingFile}-1.txt`)).toBe(true, `${existingFile}-1.txt not present in destination folder`); }); - // TODO disabled until ACA-2171 is fixed - xit('Copy items into a library - [C291900]', async () => { + it('Copy items into a library - [C291900]', async () => { await dataTable.selectItem(file1, source); await toolbar.clickMoreActionsCopy(); await copyDialog.selectLocation('File Libraries'); @@ -529,8 +526,7 @@ describe('Copy content', () => { expect(await dataTable.isItemPresent(file3InFolder)).toBe(true, `${file3InFolder} not present in destination folder`); }); - // TODO disabled until ACA-2171 is fixed - xit('Copy items into a library - [C291901]', async () => { + it('Copy items into a library - [C291901]', async () => { await dataTable.selectMultipleItems([file1, folder1], source); await toolbar.clickMoreActionsCopy(); await copyDialog.selectLocation('File Libraries'); diff --git a/e2e/suites/actions/move.test.ts b/e2e/suites/actions/move.test.ts index c4936326b2..ded079434f 100755 --- a/e2e/suites/actions/move.test.ts +++ b/e2e/suites/actions/move.test.ts @@ -250,8 +250,7 @@ describe('Move content', () => { expect(await dataTable.isItemPresent(file3InFolder)).toBe(true, `${file3InFolder} not present in destination folder`); }); - // TODO disabled until ACA-2171 is fixed - xit('Move items into a library - [C291969]', async () => { + it('Move items into a library - [C291969]', async () => { await dataTable.selectMultipleItems([file4, folder2]); await toolbar.clickMoreActionsMove(); await moveDialog.selectLocation('File Libraries'); @@ -371,8 +370,7 @@ describe('Move content', () => { expect(await dataTable.isItemPresent(`${existingFile}-1.txt`)).toBe(false, `${existingFile}-1.txt is present in destination folder`); }); - // TODO disabled until ACA-2171 is fixed - xit('Move items into a library - [C291971]', async () => { + it('Move items into a library - [C291971]', async () => { await dataTable.selectItem(file4, sourceRF); await toolbar.clickMoreActionsMove(); await moveDialog.selectLocation('File Libraries'); @@ -494,8 +492,7 @@ describe('Move content', () => { expect(await dataTable.isItemPresent(`${existingFile}-1.txt`)).toBe(false, `${existingFile}-1.txt not present in destination folder`); }); - // TODO disabled until ACA-2171 is fixed - xit('Move items into a library - [C291978]', async () => { + it('Move items into a library - [C291978]', async () => { await dataTable.selectItem(file4, sourceSF); await toolbar.clickMoreActionsMove(); await moveDialog.selectLocation('File Libraries'); @@ -685,8 +682,7 @@ describe('Move content', () => { expect(await dataTable.isItemPresent(file3InFolder)).toBe(true, `${file3InFolder} not present in destination folder`); }); - // TODO disabled until ACA-2171 is fixed - xit('Move items into a library - [C291979]', async () => { + it('Move items into a library - [C291979]', async () => { await dataTable.selectMultipleItems([file4, folder2], sourceFav); await toolbar.clickMoreActionsMove(); await moveDialog.selectLocation('File Libraries'); From 25e7f5139e4d5f88740a768158d461b9f491f4a8 Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Wed, 13 Feb 2019 14:41:49 +0200 Subject: [PATCH 052/259] [ACA-2198 ACA-2206] Node version - align dialog with XD (#937) * make comment field not required * make Minor default version option * tests * fix form version options label * test form state on initialization --- .../node-version-form.component.spec.ts | 64 +++++++++++++++++++ .../node-version-form.component.ts | 8 +-- src/assets/i18n/en.json | 4 +- 3 files changed, 70 insertions(+), 6 deletions(-) create mode 100644 src/app/components/node-version/node-version-form.component.spec.ts diff --git a/src/app/components/node-version/node-version-form.component.spec.ts b/src/app/components/node-version/node-version-form.component.spec.ts new file mode 100644 index 0000000000..ffb8caeb73 --- /dev/null +++ b/src/app/components/node-version/node-version-form.component.spec.ts @@ -0,0 +1,64 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2018 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { AppNodeVersionFormComponent } from './node-version-form.component'; +import { setupTestBed, CoreModule } from '@alfresco/adf-core'; +import { TestBed } from '@angular/core/testing'; + +describe('AppNodeVersionFormComponent', () => { + let fixture; + let component; + + setupTestBed({ + imports: [CoreModule, NoopAnimationsModule], + declarations: [AppNodeVersionFormComponent] + }); + + beforeEach(() => { + fixture = TestBed.createComponent(AppNodeVersionFormComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should have minor version option selected', () => { + const isSelected = fixture.debugElement.nativeElement + .querySelectorAll('.form__version--option')[0] + .classList.contains('mat-radio-checked'); + + expect(isSelected).toBe(true); + }); + + it('should emit form state on changes', () => { + spyOn(component.update, 'emit'); + + component.form.valueChanges.next({ test: 'test' }); + expect(component.update.emit).toHaveBeenCalledWith({ test: 'test' }); + }); + + it('form should have valid state upon initialization', () => { + expect(component.form.valid).toBe(true); + }); +}); diff --git a/src/app/components/node-version/node-version-form.component.ts b/src/app/components/node-version/node-version-form.component.ts index 5caed5ac16..85b145e033 100644 --- a/src/app/components/node-version/node-version-form.component.ts +++ b/src/app/components/node-version/node-version-form.component.ts @@ -31,7 +31,7 @@ import { Output, EventEmitter } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { FormBuilder, FormGroup } from '@angular/forms'; import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; @@ -50,15 +50,15 @@ export class AppNodeVersionFormComponent implements OnInit, OnDestroy { private onDestroy$: Subject = new Subject(); private versionOptions = [ - { label: 'VERSION.FORM.VERSION.MAJOR', value: 'major' }, - { label: 'VERSION.FORM.VERSION.MINOR', value: 'minor' } + { label: 'VERSION.FORM.VERSION.MINOR', value: 'minor' }, + { label: 'VERSION.FORM.VERSION.MAJOR', value: 'major' } ]; constructor(private formBuilder: FormBuilder) {} ngOnInit() { this.form = this.formBuilder.group({ - comment: ['', Validators.required], + comment: [''], version: [this.versionOptions[0].value] }); diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index fc8441913a..7f2d60d458 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -373,8 +373,8 @@ "FORM": { "SUBTITLE": "What level of changes were made to this version?", "VERSION": { - "MINOR": "Minor (2.#)", - "MAJOR": "Major (#.1)" + "MINOR": "Minor (#.1)", + "MAJOR": "Major (2.0)" }, "COMMENT": { "PLACEHOLDER": "Add notes describing what changed" From 9b2cbdde49418b887a8a5607494f7af488a3447d Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Wed, 13 Feb 2019 18:29:48 +0200 Subject: [PATCH 053/259] [ACA-2210] Version Dialog - update button text (#939) * dialog action buttons text to uppercase * dialog text Cancel over Close * update translation reference --- .../node-version-upload/node-version-upload.dialog.html | 2 +- .../node-version-upload/node-version-upload.dialog.scss | 4 ++++ src/assets/i18n/en.json | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/app/dialogs/node-version-upload/node-version-upload.dialog.html b/src/app/dialogs/node-version-upload/node-version-upload.dialog.html index fe3def10ed..42a4d0b9a9 100644 --- a/src/app/dialogs/node-version-upload/node-version-upload.dialog.html +++ b/src/app/dialogs/node-version-upload/node-version-upload.dialog.html @@ -8,7 +8,7 @@

+ + + {{ + 'FILE_UPLOAD.MESSAGES.UPLOAD_PROGRESS' + | translate + : { + completed: totalCompleted, + total: filesUploadingList.length + } + }} + + + + {{ 'FILE_UPLOAD.MESSAGES.UPLOAD_CANCELED' | translate }} + + + +
+ {{ + (totalErrors > 1 + ? 'FILE_UPLOAD.MESSAGES.UPLOAD_ERRORS' + : 'FILE_UPLOAD.MESSAGES.UPLOAD_ERROR') + | translate: { total: totalErrors } + }} +
+ +
+ + + + + + + +
+

+ {{ 'ADF_FILE_UPLOAD.CONFIRMATION.MESSAGE.TITLE' | translate }} +

+ +

+ {{ 'ADF_FILE_UPLOAD.CONFIRMATION.MESSAGE.TEXT' | translate }} +

+
+
+ +
+ + + +
+ +
+ + + +
+
diff --git a/src/app/components/upload-dialog/file-uploading-dialog.component.ts b/src/app/components/upload-dialog/file-uploading-dialog.component.ts new file mode 100644 index 0000000000..129ec1f50d --- /dev/null +++ b/src/app/components/upload-dialog/file-uploading-dialog.component.ts @@ -0,0 +1,24 @@ +/*! + * @license + * Copyright 2016 Alfresco Software, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Component } from '@angular/core'; +import { FileUploadingDialogComponent } from '@alfresco/adf-content-services'; +@Component({ + selector: 'app-file-uploading-dialog', + templateUrl: './file-uploading-dialog.component.html' +}) +export class AppFileUploadingDialogComponent extends FileUploadingDialogComponent {} diff --git a/src/app/components/upload-dialog/file-uploading-list-row.component.html b/src/app/components/upload-dialog/file-uploading-list-row.component.html new file mode 100644 index 0000000000..315f70bfde --- /dev/null +++ b/src/app/components/upload-dialog/file-uploading-list-row.component.html @@ -0,0 +1,109 @@ +
+ + + insert_drive_file + + + + + + + {{ file.name }} + + + + {{ + versionNumber + }} + + +
+ + {{ file.progress.loaded | adfFileSize }} / + {{ file.progress.total | adfFileSize }} + + + + clear + +
+ +
+ + check_circle + + + + remove_circle + +
+ +
+ + schedule + + + + remove_circle + +
+ +
+ + report_problem + +
+ +
+ {{ 'ADF_FILE_UPLOAD.STATUS.FILE_CANCELED_STATUS' | translate }} +
+
diff --git a/src/app/components/upload-dialog/file-uploading-list-row.component.ts b/src/app/components/upload-dialog/file-uploading-list-row.component.ts new file mode 100644 index 0000000000..688fc82edf --- /dev/null +++ b/src/app/components/upload-dialog/file-uploading-list-row.component.ts @@ -0,0 +1,48 @@ +/*! + * @license + * Copyright 2016 Alfresco Software, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Component } from '@angular/core'; +import { FileUploadingListRowComponent } from '@alfresco/adf-content-services'; +@Component({ + selector: 'app-file-uploading-list-row', + templateUrl: './file-uploading-list-row.component.html' +}) +export class AppFileUploadingListRowComponent extends FileUploadingListRowComponent { + isUploadVersion() { + return ( + !!this.file.data && + this.file.options && + this.file.options.newVersion && + this.file.data.entry.properties && + this.file.data.entry.properties['cm:versionLabel'] + ); + } + + // todo: move to ADF 3.x.x + get versionNumber() { + return this.file.data.entry.properties['cm:versionLabel']; + } + + // todo: move to ADF 3.x.x + get mimeType(): string { + if (this.file && this.file.file && this.file.file.type) { + return this.file.file.type; + } + + return 'default'; + } +} diff --git a/src/app/components/upload-dialog/file-uploading-list.component.html b/src/app/components/upload-dialog/file-uploading-list.component.html new file mode 100644 index 0000000000..475b084b12 --- /dev/null +++ b/src/app/components/upload-dialog/file-uploading-list.component.html @@ -0,0 +1,4 @@ +
+ + +
diff --git a/src/app/components/upload-dialog/file-uploading-list.component.ts b/src/app/components/upload-dialog/file-uploading-list.component.ts new file mode 100644 index 0000000000..da8ea0add1 --- /dev/null +++ b/src/app/components/upload-dialog/file-uploading-list.component.ts @@ -0,0 +1,224 @@ +/*! + * @license + * Copyright 2016 Alfresco Software, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + FileModel, + FileUploadStatus, + NodesApiService, + AlfrescoApiService, + TranslationService, + UploadService +} from '@alfresco/adf-core'; +import { + Component, + ContentChild, + Input, + Output, + TemplateRef, + EventEmitter +} from '@angular/core'; +import { Observable, forkJoin, of, from } from 'rxjs'; +import { map, catchError } from 'rxjs/operators'; + +@Component({ + selector: 'app-file-uploading-list', + templateUrl: './file-uploading-list.component.html' +}) +export class AppFileUploadingListComponent { + FileUploadStatus = FileUploadStatus; + + @ContentChild(TemplateRef) + template: any; + + @Input() + files: FileModel[] = []; + + /** Emitted when a file in the list has an error. */ + @Output() + error: EventEmitter = new EventEmitter(); + + constructor( + private alfrescoApiService: AlfrescoApiService, + private uploadService: UploadService, + private nodesApi: NodesApiService, + private translateService: TranslationService + ) {} + + /** + * Cancel file upload + * + * @param file File model to cancel upload for. + * + * @memberOf FileUploadingListComponent + */ + cancelFile(file: FileModel): void { + this.uploadService.cancelUpload(file); + } + + // todo: move to ADF 3.x.x + removeFile(file: FileModel): void { + if (file.options && file.options.newVersion) { + this.deleteNodeVersion(file).subscribe(() => { + if (file.status === FileUploadStatus.Error) { + this.notifyError(file); + } + this.uploadService.cancelUpload(file); + }); + } else { + this.deleteNode(file).subscribe(() => { + if (file.status === FileUploadStatus.Error) { + this.notifyError(file); + } + + this.cancelNodeVersionInstances(file); + this.uploadService.cancelUpload(file); + }); + } + } + + /** + * Call the appropriate method for each file, depending on state + */ + cancelAllFiles(): void { + this.getUploadingFiles().forEach(file => + this.uploadService.cancelUpload(file) + ); + + const deletedFiles = this.files + .filter(file => file.status === FileUploadStatus.Complete) + .map(file => this.deleteNode(file)); + + forkJoin(...deletedFiles).subscribe((files: FileModel[]) => { + const errors = files.filter( + file => file.status === FileUploadStatus.Error + ); + + if (errors.length) { + this.notifyError(...errors); + } + + this.uploadService.cancelUpload(...files); + }); + } + + /** + * Checks if all the files are uploaded false if there is at least one file in Progress | Starting | Pending + */ + isUploadCompleted(): boolean { + return ( + !this.isUploadCancelled() && + Boolean(this.files.length) && + !this.files.some( + ({ status }) => + status === FileUploadStatus.Starting || + status === FileUploadStatus.Progress || + status === FileUploadStatus.Pending + ) + ); + } + + /** + * Check if all the files are Cancelled | Aborted | Error. false if there is at least one file in uploading states + */ + isUploadCancelled(): boolean { + return ( + !!this.files.length && + this.files.every( + ({ status }) => + status === FileUploadStatus.Aborted || + status === FileUploadStatus.Cancelled || + status === FileUploadStatus.Deleted + ) + ); + } + + // todo: move to ADF 3.x.x + private deleteNodeVersion(file: FileModel): Observable { + return from( + this.alfrescoApiService.versionsApi.deleteVersion( + file.data.entry.id, + file.data.entry.properties['cm:versionLabel'] + ) + ).pipe( + map(() => { + file.status = FileUploadStatus.Deleted; + return file; + }), + catchError(() => { + file.status = FileUploadStatus.Error; + return of(file); + }) + ); + } + + // todo: move to ADF 3.x.x + private cancelNodeVersionInstances(file) { + this.files + .filter( + item => + item.data.entry.id === file.data.entry.id && item.options.newVersion + ) + .map(item => { + item.status = FileUploadStatus.Deleted; + }); + } + + private deleteNode(file: FileModel): Observable { + const { id } = file.data.entry; + + return this.nodesApi.deleteNode(id, { permanent: true }).pipe( + map(() => { + file.status = FileUploadStatus.Deleted; + return file; + }), + catchError(() => { + file.status = FileUploadStatus.Error; + return of(file); + }) + ); + } + + private notifyError(...files: FileModel[]) { + let messageError: string = null; + + if (files.length === 1) { + messageError = this.translateService.instant( + 'FILE_UPLOAD.MESSAGES.REMOVE_FILE_ERROR', + { fileName: files[0].name } + ); + } else { + messageError = this.translateService.instant( + 'FILE_UPLOAD.MESSAGES.REMOVE_FILES_ERROR', + { total: files.length } + ); + } + + this.error.emit(messageError); + } + + private getUploadingFiles() { + return this.files.filter(item => { + if ( + item.status === FileUploadStatus.Pending || + item.status === FileUploadStatus.Progress || + item.status === FileUploadStatus.Starting + ) { + return item; + } + }); + } +} diff --git a/src/app/components/upload-dialog/upload.module.ts b/src/app/components/upload-dialog/upload.module.ts new file mode 100644 index 0000000000..12e3060d2a --- /dev/null +++ b/src/app/components/upload-dialog/upload.module.ts @@ -0,0 +1,47 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2018 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { CoreModule } from '@alfresco/adf-core'; +import { AppFileUploadingDialogComponent } from './file-uploading-dialog.component'; +import { AppFileUploadingListRowComponent } from './file-uploading-list-row.component'; +import { AppFileUploadingListComponent } from './file-uploading-list.component'; +import { UploadModule } from '@alfresco/adf-content-services'; + +@NgModule({ + imports: [CommonModule, CoreModule.forChild(), UploadModule], + declarations: [ + AppFileUploadingDialogComponent, + AppFileUploadingListRowComponent, + AppFileUploadingListComponent + ], + exports: [ + AppFileUploadingDialogComponent, + AppFileUploadingListRowComponent, + AppFileUploadingListComponent + ] +}) +export class AppUploadingDialogModule {} diff --git a/src/app/ui/overrides/adf-upload-dialog.theme.scss b/src/app/ui/overrides/adf-upload-dialog.theme.scss index 9dca64b86d..364f2f44c4 100644 --- a/src/app/ui/overrides/adf-upload-dialog.theme.scss +++ b/src/app/ui/overrides/adf-upload-dialog.theme.scss @@ -7,6 +7,28 @@ z-index: 999; } + // todo: move to ADF 3.x.x + .adf-file-uploading-row { + &__group, + &__block { + min-width: 100px; + display: flex; + justify-content: flex-end; + } + + &__version { + flex: 0; + + .mat-chip { + padding: 2px 6px; + } + + .mat-chip.mat-chip-disabled { + opacity: 1; + } + } + } + .adf-file-uploading-row { &__status { &--done { diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 6f214673e1..83e55abe51 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -467,6 +467,11 @@ "INFO": "View details" } }, + "FILE_UPLOAD": { + "ERRORS": { + "409": "This name is already in use, try a different name [409]" + } + }, "ADF_VERSION_LIST": { "ACTIONS": { "UPLOAD": { From 9458ce17859166c0b59bea64cc981fcbfc688f0e Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Mon, 25 Feb 2019 16:06:17 +0000 Subject: [PATCH 075/259] [ACA-2212] allow "edit in office" only for basic auth (#971) * allow AOS only for basic auth for now * bump aos extension version --- projects/adf-office-services-ext/package.json | 2 +- projects/adf-office-services-ext/src/lib/evaluators.ts | 7 +++++++ src/app/extensions/app.interface.ts | 2 ++ src/app/extensions/extension.service.ts | 7 ++++--- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/projects/adf-office-services-ext/package.json b/projects/adf-office-services-ext/package.json index 397ccbc9c9..3270785f35 100644 --- a/projects/adf-office-services-ext/package.json +++ b/projects/adf-office-services-ext/package.json @@ -1,6 +1,6 @@ { "name": "@alfresco/adf-office-services-ext", - "version": "0.0.4", + "version": "0.0.5", "license": "Apache-2.0", "author": { "name": "Keensoft", diff --git a/projects/adf-office-services-ext/src/lib/evaluators.ts b/projects/adf-office-services-ext/src/lib/evaluators.ts index 7b39cd5680..e63abdc742 100644 --- a/projects/adf-office-services-ext/src/lib/evaluators.ts +++ b/projects/adf-office-services-ext/src/lib/evaluators.ts @@ -1,10 +1,17 @@ import { RuleContext, RuleParameter } from '@alfresco/adf-extensions'; +import { AuthenticationService } from '@alfresco/adf-core'; import { getFileExtension, supportedExtensions } from './utils'; export function canOpenWithOffice( context: RuleContext, ...args: RuleParameter[] ): boolean { + // todo: needs to have typed access via SDK (1.8) + const auth: AuthenticationService = (context).auth; + if (auth && auth.isOauth()) { + return false; + } + const file = context.selection.file; if (!file || !file.entry || !file.entry.properties) { diff --git a/src/app/extensions/app.interface.ts b/src/app/extensions/app.interface.ts index 8570fb9851..dfae10563d 100644 --- a/src/app/extensions/app.interface.ts +++ b/src/app/extensions/app.interface.ts @@ -24,7 +24,9 @@ */ import { RuleContext, RepositoryState } from '@alfresco/adf-extensions'; +import { AuthenticationService } from '@alfresco/adf-core'; export interface AppRuleContext extends RuleContext { repository: RepositoryState; + auth: AuthenticationService; } diff --git a/src/app/extensions/extension.service.ts b/src/app/extensions/extension.service.ts index d36ed03476..cbd2636608 100644 --- a/src/app/extensions/extension.service.ts +++ b/src/app/extensions/extension.service.ts @@ -35,7 +35,6 @@ import { SelectionState, NavigationState, ExtensionConfig, - RuleContext, RuleEvaluator, ViewerExtensionRef, ContentActionRef, @@ -52,15 +51,16 @@ import { RepositoryState, ExtensionRef } from '@alfresco/adf-extensions'; -import { AppConfigService } from '@alfresco/adf-core'; +import { AppConfigService, AuthenticationService } from '@alfresco/adf-core'; import { DocumentListPresetRef } from './document-list.extensions'; import { BehaviorSubject, Observable } from 'rxjs'; import { IconRef } from './icon.extensions'; +import { AppRuleContext } from './app.interface'; @Injectable({ providedIn: 'root' }) -export class AppExtensionService implements RuleContext { +export class AppExtensionService implements AppRuleContext { private _references = new BehaviorSubject([]); defaults = { @@ -108,6 +108,7 @@ export class AppExtensionService implements RuleContext { references$: Observable; constructor( + public auth: AuthenticationService, protected store: Store, protected loader: ExtensionLoaderService, protected extensions: ExtensionService, From c7328c7caf32572eb01fb718006eeff2608276f5 Mon Sep 17 00:00:00 2001 From: Suzana Dirla Date: Mon, 25 Feb 2019 22:35:17 +0200 Subject: [PATCH 076/259] [ACA-2208] Hide app menu on swipe (#970) --- .../app-layout/app-layout.component.spec.ts | 16 ++++++++++++++++ .../layout/app-layout/app-layout.component.ts | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/app/components/layout/app-layout/app-layout.component.spec.ts b/src/app/components/layout/app-layout/app-layout.component.spec.ts index 14fd42e7e5..987b97a474 100644 --- a/src/app/components/layout/app-layout/app-layout.component.spec.ts +++ b/src/app/components/layout/app-layout/app-layout.component.spec.ts @@ -178,4 +178,20 @@ describe('AppLayoutComponent', () => { expect(component.layout.container.toggleMenu).toHaveBeenCalled(); }); + + it('should close menu on mobile screen size also when minimizeSidenav true', () => { + fixture.detectChanges(); + component.minimizeSidenav = true; + component.layout.container = { + isMobileScreenSize: true, + toggleMenu: () => {} + }; + + spyOn(component.layout.container, 'toggleMenu'); + fixture.detectChanges(); + + component.hideMenu({ preventDefault: () => {} }); + + expect(component.layout.container.toggleMenu).toHaveBeenCalled(); + }); }); diff --git a/src/app/components/layout/app-layout/app-layout.component.ts b/src/app/components/layout/app-layout/app-layout.component.ts index 8538e41149..3732dc3f69 100644 --- a/src/app/components/layout/app-layout/app-layout.component.ts +++ b/src/app/components/layout/app-layout/app-layout.component.ts @@ -153,7 +153,7 @@ export class AppLayoutComponent implements OnInit, OnDestroy { } hideMenu(event: Event) { - if (!this.minimizeSidenav && this.layout.container.isMobileScreenSize) { + if (this.layout.container.isMobileScreenSize) { event.preventDefault(); this.layout.container.toggleMenu(); } From f03eae5317c1e98e219ba50770916b21907ab91d Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Tue, 26 Feb 2019 07:06:43 +0000 Subject: [PATCH 077/259] [ACA-2220] simple "search in fields" support (#972) * simple "search in fields" support * unit tests --- .../search-results.component.spec.ts | 97 +++++++++++++++++-- .../search-results.component.ts | 8 +- 2 files changed, 98 insertions(+), 7 deletions(-) diff --git a/src/app/components/search/search-results/search-results.component.spec.ts b/src/app/components/search/search-results/search-results.component.spec.ts index 55f543f773..3c22a2478a 100644 --- a/src/app/components/search/search-results/search-results.component.spec.ts +++ b/src/app/components/search/search-results/search-results.component.spec.ts @@ -1,24 +1,109 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { SearchResultsComponent } from './search-results.component'; +import { AppTestingModule } from '../../../testing/app-testing.module'; +import { AppSearchResultsModule } from '../search-results.module'; +import { CoreModule, AppConfigService } from '@alfresco/adf-core'; +import { Store } from '@ngrx/store'; +import { NavigateToFolder } from '../../../store/actions'; +import { Pagination } from '@alfresco/js-api'; +import { SearchQueryBuilderService } from '@alfresco/adf-content-services'; describe('SearchComponent', () => { let component: SearchResultsComponent; let fixture: ComponentFixture; + let config: AppConfigService; + let store: Store; + let queryBuilder: SearchQueryBuilderService; beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [SearchResultsComponent] - }).compileComponents(); - })); + imports: [CoreModule.forRoot(), AppTestingModule, AppSearchResultsModule] + }); + + config = TestBed.get(AppConfigService); + store = TestBed.get(Store); + queryBuilder = TestBed.get(SearchQueryBuilderService); - beforeEach(() => { fixture = TestBed.createComponent(SearchResultsComponent); component = fixture.componentInstance; fixture.detectChanges(); + })); + + it('should return null if formatting invalid query', () => { + expect(component.formatSearchQuery(null)).toBeNull(); + expect(component.formatSearchQuery('')).toBeNull(); }); - xit('should create', () => { - expect(component).toBeTruthy(); + it('should use original user input if content contains colons', () => { + const query = 'TEXT:test OR TYPE:folder'; + expect(component.formatSearchQuery(query)).toBe(query); + }); + + it('should format user input according to the configuration fields', () => { + config.config = { + search: { + 'aca:fields': ['cm:name', 'cm:title'] + } + }; + + const query = component.formatSearchQuery('hello'); + expect(query).toBe(`cm:name:"hello*" OR cm:title:"hello*"`); + }); + + it('should format user input as cm:name if configuration not provided', () => { + config.config = { + search: { + 'aca:fields': undefined + } + }; + + const query = component.formatSearchQuery('hello'); + expect(query).toBe(`cm:name:"hello*"`); + }); + + it('should navigate to folder on double click', () => { + const node: any = { + entry: { + isFolder: true + } + }; + + spyOn(store, 'dispatch').and.stub(); + + component.onNodeDoubleClick(node); + + expect(store.dispatch).toHaveBeenCalledWith(new NavigateToFolder(node)); + }); + + it('should preview file node on double click', () => { + const node: any = { + entry: { + isFolder: false + } + }; + + spyOn(component, 'showPreview').and.stub(); + + component.onNodeDoubleClick(node); + + expect(component.showPreview).toHaveBeenCalledWith(node); + }); + + it('should re-run search on pagination change', () => { + const page = new Pagination({ + maxItems: 10, + skipCount: 0 + }); + + spyOn(queryBuilder, 'update').and.stub(); + + component.onPaginationChanged(page); + + expect(queryBuilder.paging).toEqual({ + maxItems: 10, + skipCount: 0 + }); + expect(queryBuilder.update).toHaveBeenCalled(); }); }); diff --git a/src/app/components/search/search-results/search-results.component.ts b/src/app/components/search/search-results/search-results.component.ts index f197c06332..8892cc7c3e 100644 --- a/src/app/components/search/search-results/search-results.component.ts +++ b/src/app/components/search/search-results/search-results.component.ts @@ -114,11 +114,17 @@ export class SearchResultsComponent extends PageComponent implements OnInit { } } - private formatSearchQuery(userInput: string) { + formatSearchQuery(userInput: string) { if (!userInput) { return null; } + userInput = userInput.trim(); + + if (userInput.includes(':')) { + return userInput; + } + const fields = this.config.get('search.aca:fields', ['cm:name']); const query = fields.map(field => `${field}:"${userInput}*"`).join(' OR '); From 2bbab615b01f6dc5065071e03658ba4cf43319aa Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Tue, 26 Feb 2019 11:19:59 +0200 Subject: [PATCH 078/259] add separator (#974) --- src/assets/app.extensions.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/assets/app.extensions.json b/src/assets/app.extensions.json index f2df9b3bc0..ad81825b9f 100644 --- a/src/assets/app.extensions.json +++ b/src/assets/app.extensions.json @@ -1016,6 +1016,11 @@ "visible": "app.toolbar.canViewFile" } }, + { + "id": "app.viewer.separator.2", + "type": "separator", + "order": 450 + }, { "id": "app.viewer.infoDrawer", "type": "custom", From f25eef599d3731845681bc065bb688a75f5817f1 Mon Sep 17 00:00:00 2001 From: Adina Parpalita Date: Tue, 26 Feb 2019 15:55:01 +0200 Subject: [PATCH 079/259] [ACA-2222] add e2e tests for pagination on Favorite Libraries (#969) * add tests for pagination on Favorite Libraries * add TestRail ids add tests for pagination for empty page and single page * Delete package-lock.json * Revert "Delete package-lock.json" This reverts commit 41eba0c57532373d87d454372273b54ba00e880a. * restore package-lock --- e2e/suites/list-views/empty-list.test.ts | 14 +- .../pagination/pag-file-libraries.test.ts | 292 ++++++++++++------ e2e/suites/pagination/pag-single-page.test.ts | 9 +- 3 files changed, 218 insertions(+), 97 deletions(-) diff --git a/e2e/suites/list-views/empty-list.test.ts b/e2e/suites/list-views/empty-list.test.ts index 97ad27f8e7..22fb7b3871 100755 --- a/e2e/suites/list-views/empty-list.test.ts +++ b/e2e/suites/list-views/empty-list.test.ts @@ -106,8 +106,18 @@ describe('Empty list views', () => { expect(await pagination.isNextButtonPresent()).toBe(false, 'Next button is present'); }); - it('File Libraries - pagination controls not displayed - [C280084]', async () => { - await page.clickFileLibraries(); + it('My Libraries - pagination controls not displayed - [C280084]', async () => { + await page.goToMyLibraries(); + expect(await pagination.isRangePresent()).toBe(false, 'Range is present'); + expect(await pagination.isMaxItemsPresent()).toBe(false, 'Max items is present'); + expect(await pagination.isCurrentPagePresent()).toBe(false, 'Current page is present'); + expect(await pagination.isTotalPagesPresent()).toBe(false, 'Total pages is present'); + expect(await pagination.isPreviousButtonPresent()).toBe(false, 'Previous button is present'); + expect(await pagination.isNextButtonPresent()).toBe(false, 'Next button is present'); + }); + + it('Favorite Libraries - pagination controls not displayed - [C291873]', async () => { + await page.goToFavoriteLibraries(); expect(await pagination.isRangePresent()).toBe(false, 'Range is present'); expect(await pagination.isMaxItemsPresent()).toBe(false, 'Max items is present'); expect(await pagination.isCurrentPagePresent()).toBe(false, 'Current page is present'); diff --git a/e2e/suites/pagination/pag-file-libraries.test.ts b/e2e/suites/pagination/pag-file-libraries.test.ts index 64433da0a0..ec439de265 100755 --- a/e2e/suites/pagination/pag-file-libraries.test.ts +++ b/e2e/suites/pagination/pag-file-libraries.test.ts @@ -28,7 +28,7 @@ import { LoginPage, BrowsingPage } from '../../pages/pages'; import { Utils } from '../../utilities/utils'; import { RepoClient } from '../../utilities/repo-client/repo-client'; -describe('Pagination on multiple pages on File Libraries', () => { +describe('Pagination on multiple pages', () => { const username = `user-${Utils.random()}`; const apis = { @@ -51,109 +51,215 @@ describe('Pagination on multiple pages on File Libraries', () => { done(); }); - beforeEach(async (done) => { - await page.goToMyLibrariesAndWait(); - done(); - }); - - afterEach(async (done) => { - await Utils.pressEscape(); - done(); - }); - afterAll(async (done) => { await apis.user.sites.deleteSites(sites); done(); }) - it('Pagination control default values - [C280086]', async () => { - expect(await pagination.getRange()).toContain('1-25 of 101'); - expect(await pagination.getMaxItems()).toContain('25'); - expect(await pagination.getCurrentPage()).toContain('Page 1'); - expect(await pagination.getTotalPages()).toContain('of 5'); - expect(await pagination.isPreviousEnabled()).toBe(false, 'Previous button is enabled'); - expect(await pagination.isNextEnabled()).toBe(true, 'Next button is not enabled'); - }); + describe('on My Libraries', () => { + beforeEach(async (done) => { + await page.goToMyLibrariesAndWait(); + done(); + }); - it('Items per page values - [C280087]', async () => { - await pagination.openMaxItemsMenu(); - const [ first, second, third ] = [1, 2, 3] - .map(async nth => await pagination.menu.getNthItem(nth).getText()); - expect(first).toBe('25'); - expect(second).toBe('50'); - expect(third).toBe('100'); - await pagination.menu.closeMenu(); - }); + afterEach(async (done) => { + await Utils.pressEscape(); + done(); + }); - it('current page menu items - [C280088]', async () => { - await pagination.openMaxItemsMenu(); - await pagination.menu.clickMenuItem('25'); - expect(await pagination.getMaxItems()).toContain('25'); - expect(await pagination.getTotalPages()).toContain('of 5'); - await pagination.openCurrentPageMenu(); - expect(await pagination.menu.getItemsCount()).toBe(5); - await pagination.menu.closeMenu(); - - await pagination.openMaxItemsMenu(); - await pagination.menu.clickMenuItem('50'); - expect(await pagination.getMaxItems()).toContain('50'); - expect(await pagination.getTotalPages()).toContain('of 3'); - await pagination.openCurrentPageMenu(); - expect(await pagination.menu.getItemsCount()).toBe(3); - await pagination.menu.closeMenu(); - - await pagination.openMaxItemsMenu(); - await pagination.menu.clickMenuItem('100'); - expect(await pagination.getMaxItems()).toContain('100'); - expect(await pagination.getTotalPages()).toContain('of 2'); - await pagination.openCurrentPageMenu(); - expect(await pagination.menu.getItemsCount()).toBe(2); - await pagination.menu.closeMenu(); - - await pagination.resetToDefaultPageSize(); - }); + it('Pagination control default values - [C280086]', async () => { + expect(await pagination.getRange()).toContain('1-25 of 101'); + expect(await pagination.getMaxItems()).toContain('25'); + expect(await pagination.getCurrentPage()).toContain('Page 1'); + expect(await pagination.getTotalPages()).toContain('of 5'); + expect(await pagination.isPreviousEnabled()).toBe(false, 'Previous button is enabled'); + expect(await pagination.isNextEnabled()).toBe(true, 'Next button is not enabled'); + }); - it('change the current page from menu - [C280089]', async () => { - await pagination.openCurrentPageMenu(); - await pagination.menu.clickNthItem(3); - await dataTable.waitForHeader(); - expect(await pagination.getRange()).toContain('51-75 of 101'); - expect(await pagination.getCurrentPage()).toContain('Page 3'); - expect(await pagination.isPreviousEnabled()).toBe(true, 'Previous button is not enabled'); - expect(await pagination.isNextEnabled()).toBe(true, 'Next button is not enabled'); - expect(await dataTable.isItemPresent('site-60')).toBe(true, 'Site-60 not found on page'); - - await pagination.resetToDefaultPageNumber(); - }); + it('Items per page values - [C280087]', async () => { + await pagination.openMaxItemsMenu(); + const [ first, second, third ] = [1, 2, 3] + .map(async nth => await pagination.menu.getNthItem(nth).getText()); + expect(first).toBe('25'); + expect(second).toBe('50'); + expect(third).toBe('100'); + await pagination.menu.closeMenu(); + }); - it('navigate to next and previous pages - [C280092]', async () => { - await pagination.clickNext(); - await dataTable.waitForHeader(); - expect(await pagination.getRange()).toContain('26-50 of 101'); - expect(await dataTable.isItemPresent('site-31')).toBe(true, 'Site-31 not found on page'); - await pagination.resetToDefaultPageNumber(); - - await pagination.openCurrentPageMenu(); - await pagination.menu.clickNthItem(2); - await dataTable.waitForHeader(); - await pagination.clickPrevious(); - await dataTable.waitForHeader(); - expect(await pagination.getRange()).toContain('1-25 of 101'); - expect(await dataTable.isItemPresent('site-12')).toBe(true, 'Site-12 not found on page'); - - await pagination.resetToDefaultPageNumber(); - }); + it('current page menu items - [C280088]', async () => { + await pagination.openMaxItemsMenu(); + await pagination.menu.clickMenuItem('25'); + expect(await pagination.getMaxItems()).toContain('25'); + expect(await pagination.getTotalPages()).toContain('of 5'); + await pagination.openCurrentPageMenu(); + expect(await pagination.menu.getItemsCount()).toBe(5); + await pagination.menu.closeMenu(); + + await pagination.openMaxItemsMenu(); + await pagination.menu.clickMenuItem('50'); + expect(await pagination.getMaxItems()).toContain('50'); + expect(await pagination.getTotalPages()).toContain('of 3'); + await pagination.openCurrentPageMenu(); + expect(await pagination.menu.getItemsCount()).toBe(3); + await pagination.menu.closeMenu(); + + await pagination.openMaxItemsMenu(); + await pagination.menu.clickMenuItem('100'); + expect(await pagination.getMaxItems()).toContain('100'); + expect(await pagination.getTotalPages()).toContain('of 2'); + await pagination.openCurrentPageMenu(); + expect(await pagination.menu.getItemsCount()).toBe(2); + await pagination.menu.closeMenu(); + + await pagination.resetToDefaultPageSize(); + }); + + it('change the current page from menu - [C280089]', async () => { + await pagination.openCurrentPageMenu(); + await pagination.menu.clickNthItem(3); + await dataTable.waitForHeader(); + expect(await pagination.getRange()).toContain('51-75 of 101'); + expect(await pagination.getCurrentPage()).toContain('Page 3'); + expect(await pagination.isPreviousEnabled()).toBe(true, 'Previous button is not enabled'); + expect(await pagination.isNextEnabled()).toBe(true, 'Next button is not enabled'); + expect(await dataTable.isItemPresent('site-60')).toBe(true, 'Site-60 not found on page'); + + await pagination.resetToDefaultPageNumber(); + }); + + it('navigate to next and previous pages - [C280092]', async () => { + await pagination.clickNext(); + await dataTable.waitForHeader(); + expect(await pagination.getRange()).toContain('26-50 of 101'); + expect(await dataTable.isItemPresent('site-31')).toBe(true, 'Site-31 not found on page'); + await pagination.resetToDefaultPageNumber(); + + await pagination.openCurrentPageMenu(); + await pagination.menu.clickNthItem(2); + await dataTable.waitForHeader(); + await pagination.clickPrevious(); + await dataTable.waitForHeader(); + expect(await pagination.getRange()).toContain('1-25 of 101'); + expect(await dataTable.isItemPresent('site-12')).toBe(true, 'Site-12 not found on page'); - it('Previous button is disabled on first page - [C280090]', async () => { - expect(await pagination.getCurrentPage()).toContain('Page 1'); - expect(await pagination.isPreviousEnabled()).toBe(false, 'Previous button is enabled on first page'); + await pagination.resetToDefaultPageNumber(); + }); + + it('Previous button is disabled on first page - [C280090]', async () => { + expect(await pagination.getCurrentPage()).toContain('Page 1'); + expect(await pagination.isPreviousEnabled()).toBe(false, 'Previous button is enabled on first page'); + }); + + it('Next button is disabled on last page - [C280091]', async () => { + await pagination.openCurrentPageMenu(); + await pagination.menu.clickNthItem(5); + expect(await dataTable.countRows()).toBe(1, 'Incorrect number of items on the last page'); + expect(await pagination.getCurrentPage()).toContain('Page 5'); + expect(await pagination.isNextEnabled()).toBe(false, 'Next button is enabled on last page'); + }); }); - it('Next button is disabled on last page - [C280091]', async () => { - await pagination.openCurrentPageMenu(); - await pagination.menu.clickNthItem(5); - expect(await dataTable.countRows()).toBe(1, 'Incorrect number of items on the last page'); - expect(await pagination.getCurrentPage()).toContain('Page 5'); - expect(await pagination.isNextEnabled()).toBe(false, 'Next button is enabled on last page'); + describe('on Favorite Libraries', () => { + beforeEach(async (done) => { + await page.goToFavoriteLibrariesAndWait(); + done(); + }); + + afterEach(async (done) => { + await Utils.pressEscape(); + done(); + }); + + it('Pagination control default values - [C291875]', async () => { + expect(await pagination.getRange()).toContain('1-25 of 101'); + expect(await pagination.getMaxItems()).toContain('25'); + expect(await pagination.getCurrentPage()).toContain('Page 1'); + expect(await pagination.getTotalPages()).toContain('of 5'); + expect(await pagination.isPreviousEnabled()).toBe(false, 'Previous button is enabled'); + expect(await pagination.isNextEnabled()).toBe(true, 'Next button is not enabled'); + }); + + it('Items per page values - [C291876]', async () => { + await pagination.openMaxItemsMenu(); + const [ first, second, third ] = [1, 2, 3] + .map(async nth => await pagination.menu.getNthItem(nth).getText()); + expect(first).toBe('25'); + expect(second).toBe('50'); + expect(third).toBe('100'); + await pagination.menu.closeMenu(); + }); + + it('current page menu items - [C291877]', async () => { + await pagination.openMaxItemsMenu(); + await pagination.menu.clickMenuItem('25'); + expect(await pagination.getMaxItems()).toContain('25'); + expect(await pagination.getTotalPages()).toContain('of 5'); + await pagination.openCurrentPageMenu(); + expect(await pagination.menu.getItemsCount()).toBe(5); + await pagination.menu.closeMenu(); + + await pagination.openMaxItemsMenu(); + await pagination.menu.clickMenuItem('50'); + expect(await pagination.getMaxItems()).toContain('50'); + expect(await pagination.getTotalPages()).toContain('of 3'); + await pagination.openCurrentPageMenu(); + expect(await pagination.menu.getItemsCount()).toBe(3); + await pagination.menu.closeMenu(); + + await pagination.openMaxItemsMenu(); + await pagination.menu.clickMenuItem('100'); + expect(await pagination.getMaxItems()).toContain('100'); + expect(await pagination.getTotalPages()).toContain('of 2'); + await pagination.openCurrentPageMenu(); + expect(await pagination.menu.getItemsCount()).toBe(2); + await pagination.menu.closeMenu(); + + await pagination.resetToDefaultPageSize(); + }); + + it('change the current page from menu - [C291878]', async () => { + await pagination.openCurrentPageMenu(); + await pagination.menu.clickNthItem(3); + await dataTable.waitForHeader(); + expect(await pagination.getRange()).toContain('51-75 of 101'); + expect(await pagination.getCurrentPage()).toContain('Page 3'); + expect(await pagination.isPreviousEnabled()).toBe(true, 'Previous button is not enabled'); + expect(await pagination.isNextEnabled()).toBe(true, 'Next button is not enabled'); + expect(await dataTable.isItemPresent('site-40')).toBe(true, 'Site-60 not found on page'); + + await pagination.resetToDefaultPageNumber(); + }); + + it('navigate to next and previous pages - [C291881]', async () => { + await pagination.clickNext(); + await dataTable.waitForHeader(); + expect(await pagination.getRange()).toContain('26-50 of 101'); + expect(await dataTable.isItemPresent('site-70')).toBe(true, 'Site-31 not found on page'); + await pagination.resetToDefaultPageNumber(); + + await pagination.openCurrentPageMenu(); + await pagination.menu.clickNthItem(2); + await dataTable.waitForHeader(); + await pagination.clickPrevious(); + await dataTable.waitForHeader(); + expect(await pagination.getRange()).toContain('1-25 of 101'); + expect(await dataTable.isItemPresent('site-88')).toBe(true, 'Site-12 not found on page'); + + await pagination.resetToDefaultPageNumber(); + }); + + it('Previous button is disabled on first page - [C291879]', async () => { + expect(await pagination.getCurrentPage()).toContain('Page 1'); + expect(await pagination.isPreviousEnabled()).toBe(false, 'Previous button is enabled on first page'); + }); + + it('Next button is disabled on last page - [C291880]', async () => { + await pagination.openCurrentPageMenu(); + await pagination.menu.clickNthItem(5); + expect(await dataTable.countRows()).toBe(1, 'Incorrect number of items on the last page'); + expect(await pagination.getCurrentPage()).toContain('Page 5'); + expect(await pagination.isNextEnabled()).toBe(false, 'Next button is enabled on last page'); + }); }); + }); diff --git a/e2e/suites/pagination/pag-single-page.test.ts b/e2e/suites/pagination/pag-single-page.test.ts index 00fb699c35..8014b6cc6a 100755 --- a/e2e/suites/pagination/pag-single-page.test.ts +++ b/e2e/suites/pagination/pag-single-page.test.ts @@ -84,8 +84,13 @@ describe('Pagination on single page', () => { expect(await pagination.isPagesButtonPresent()).toBe(false, 'page selector displayed'); }); - it('page selector not displayed on File Libraries - [C280085]', async () => { - await page.clickFileLibrariesAndWait(); + it('page selector not displayed on My Libraries - [C280085]', async () => { + await page.goToMyLibrariesAndWait(); + expect(await pagination.isPagesButtonPresent()).toBe(false, 'page selector displayed'); + }); + + it('page selector not displayed on Favorite Libraries - [C291874]', async () => { + await page.goToFavoriteLibrariesAndWait(); expect(await pagination.isPagesButtonPresent()).toBe(false, 'page selector displayed'); }); From f58b6e5a9fccaa20128461d7d4d574834f0ba5e1 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Wed, 27 Feb 2019 04:25:50 +0000 Subject: [PATCH 080/259] [ACA-2219] support more precise searching (#976) * support more precise searching * exact term matching * remove fdescribe * update docs --- docs/features/search-results.md | 31 ++++++++ src/app.config.json | 4 - .../search-results.component.spec.ts | 79 ++++++++++++++++++- .../search-results.component.ts | 47 ++++++++++- 4 files changed, 151 insertions(+), 10 deletions(-) diff --git a/docs/features/search-results.md b/docs/features/search-results.md index 45b3817511..848dbd003d 100644 --- a/docs/features/search-results.md +++ b/docs/features/search-results.md @@ -18,3 +18,34 @@ This page consists of the following ADF components: - [Toolbar with basic actions](/features/document-list-layout#actions-and-the-actions-toolbar) like `Preview`, `Download`, `Favorite`, `Copy`, etc. And also the Info Drawer, Toolbar and Node Selector dialogs for copy and move operations. + +## Alfresco Full Text Search + +The following table describes current support of the +[Alfresco Full Text Search](http://docs.alfresco.com/6.0/concepts/rm-searchsyntax-intro.html) (FTS) syntax +in the Content Application when using **Search Input** component. + +| Feature | Full | Partial | N/A | Details | +| ---------------------------------------------------------------- | ---- | ------- | --- | ---------------------------------------------------------------------------------- | +| Search for a single term | X | | | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-single.html) | +| Search for a phrase | | X | | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-phrase.html) | +| Search for an exact term | X | | | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-exact.html) | +| Search for term expansion | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-term.html) | +| Search for conjunctions | X | | | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-conjunct.html) | +| Search for disjunctions | X | | | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-disjunct.html) | +| Search for negation | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-negate.html) | +| Search for optional, mandatory, and excluded elements of a query | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-optional.html) | +| Search in fields | | X | | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-fields.html) | +| Search for wildcards | | X | | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-wildcards.html) | +| Search for ranges | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-ranges.html) | +| Search for fuzzy matching | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-fuzzy.html) | +| Search for proximity | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-proximity.html) | +| Search for boosts | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-boosts.html) | +| Search for grouping | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-grouping.html) | +| Search for spans and positions | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-spans.html) | +| Escaping characters | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-escaping.html) | +| Mixed FTS ID behavior | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-ftsid.html) | +| Search for operator precedence | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-precedence.html) | +| Search query templates | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-querytemplates.html) | +| Search query literals | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-literals.html) | +| Search using date math | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-datemaths.html) | diff --git a/src/app.config.json b/src/app.config.json index c3de27da70..ae20341516 100644 --- a/src/app.config.json +++ b/src/app.config.json @@ -119,10 +119,6 @@ "cm:name", "cm:title", "cm:description", - "ia:whatEvent", - "ia:descriptionEvent", - "lnk:title", - "lnk:description", "TEXT", "TAG" ], diff --git a/src/app/components/search/search-results/search-results.component.spec.ts b/src/app/components/search/search-results/search-results.component.spec.ts index 3c22a2478a..754005081d 100644 --- a/src/app/components/search/search-results/search-results.component.spec.ts +++ b/src/app/components/search/search-results/search-results.component.spec.ts @@ -35,11 +35,16 @@ describe('SearchComponent', () => { expect(component.formatSearchQuery('')).toBeNull(); }); - it('should use original user input if content contains colons', () => { + it('should use original user input if text contains colons', () => { const query = 'TEXT:test OR TYPE:folder'; expect(component.formatSearchQuery(query)).toBe(query); }); + it('should use original user input if text contains quotes', () => { + const query = `"Hello World"`; + expect(component.formatSearchQuery(query)).toBe(query); + }); + it('should format user input according to the configuration fields', () => { config.config = { search: { @@ -48,7 +53,7 @@ describe('SearchComponent', () => { }; const query = component.formatSearchQuery('hello'); - expect(query).toBe(`cm:name:"hello*" OR cm:title:"hello*"`); + expect(query).toBe(`(cm:name:"hello*" OR cm:title:"hello*")`); }); it('should format user input as cm:name if configuration not provided', () => { @@ -59,7 +64,75 @@ describe('SearchComponent', () => { }; const query = component.formatSearchQuery('hello'); - expect(query).toBe(`cm:name:"hello*"`); + expect(query).toBe(`(cm:name:"hello*")`); + }); + + it('should use AND operator when conjunction has no operators', () => { + config.config = { + search: { + 'aca:fields': ['cm:name'] + } + }; + + const query = component.formatSearchQuery('big yellow banana'); + + expect(query).toBe( + `(cm:name:"big*") AND (cm:name:"yellow*") AND (cm:name:"banana*")` + ); + }); + + it('should support conjunctions with AND operator', () => { + config.config = { + search: { + 'aca:fields': ['cm:name', 'cm:title'] + } + }; + + const query = component.formatSearchQuery('big AND yellow AND banana'); + + expect(query).toBe( + `(cm:name:"big*" OR cm:title:"big*") AND (cm:name:"yellow*" OR cm:title:"yellow*") AND (cm:name:"banana*" OR cm:title:"banana*")` + ); + }); + + it('should support conjunctions with OR operator', () => { + config.config = { + search: { + 'aca:fields': ['cm:name', 'cm:title'] + } + }; + + const query = component.formatSearchQuery('big OR yellow OR banana'); + + expect(query).toBe( + `(cm:name:"big*" OR cm:title:"big*") OR (cm:name:"yellow*" OR cm:title:"yellow*") OR (cm:name:"banana*" OR cm:title:"banana*")` + ); + }); + + it('should support exact term matching with default fields', () => { + config.config = { + search: { + 'aca:fields': ['cm:name', 'cm:title'] + } + }; + + const query = component.formatSearchQuery('=orange'); + + expect(query).toBe(`(=cm:name:"orange" OR =cm:title:"orange")`); + }); + + it('should support exact term matching with operators', () => { + config.config = { + search: { + 'aca:fields': ['cm:name', 'cm:title'] + } + }; + + const query = component.formatSearchQuery('=test1.pdf or =test2.pdf'); + + expect(query).toBe( + `(=cm:name:"test1.pdf" OR =cm:title:"test1.pdf") or (=cm:name:"test2.pdf" OR =cm:title:"test2.pdf")` + ); }); it('should navigate to folder on double click', () => { diff --git a/src/app/components/search/search-results/search-results.component.ts b/src/app/components/search/search-results/search-results.component.ts index 8892cc7c3e..6b4d552a7a 100644 --- a/src/app/components/search/search-results/search-results.component.ts +++ b/src/app/components/search/search-results/search-results.component.ts @@ -114,6 +114,33 @@ export class SearchResultsComponent extends PageComponent implements OnInit { } } + private isOperator(input: string): boolean { + if (input) { + input = input.trim().toUpperCase(); + + const operators = ['AND', 'OR']; + return operators.includes(input); + } + return false; + } + + private formatFields(fields: string[], term: string): string { + let prefix = ''; + let suffix = '*'; + + if (term.startsWith('=')) { + prefix = '='; + suffix = ''; + term = term.substring(1); + } + + return ( + '(' + + fields.map(field => `${prefix}${field}:"${term}${suffix}"`).join(' OR ') + + ')' + ); + } + formatSearchQuery(userInput: string) { if (!userInput) { return null; @@ -121,14 +148,28 @@ export class SearchResultsComponent extends PageComponent implements OnInit { userInput = userInput.trim(); - if (userInput.includes(':')) { + if (userInput.includes(':') || userInput.includes('"')) { return userInput; } const fields = this.config.get('search.aca:fields', ['cm:name']); - const query = fields.map(field => `${field}:"${userInput}*"`).join(' OR '); + const words = userInput.split(' '); + + if (words.length > 1) { + const separator = words.some(this.isOperator) ? ' ' : ' AND '; + + return words + .map(term => { + if (this.isOperator(term)) { + return term; + } + + return this.formatFields(fields, term); + }) + .join(separator); + } - return query; + return this.formatFields(fields, userInput); } onSearchResultLoaded(nodePaging: NodePaging) { From 0b5555d2fcd684c5f9094d05d5f501bbfa667aac Mon Sep 17 00:00:00 2001 From: Adina Parpalita Date: Wed, 27 Feb 2019 10:40:44 +0200 Subject: [PATCH 081/259] [ACA-1259] automate remaining tests for sidebar (#977) * automate remaining tests for sidebar * formatting --- e2e/components/header/header.ts | 35 ++++- e2e/components/sidenav/sidenav.ts | 42 ++--- e2e/suites/navigation/sidebar.test.ts | 144 ++++++++++++++---- .../app-layout/app-layout.component.html | 7 +- .../components/sidenav/sidenav.component.html | 20 ++- 5 files changed, 196 insertions(+), 52 deletions(-) diff --git a/e2e/components/header/header.ts b/e2e/components/header/header.ts index 38cc412f4a..dbb8d70f02 100755 --- a/e2e/components/header/header.ts +++ b/e2e/components/header/header.ts @@ -23,23 +23,29 @@ * along with Alfresco. If not, see . */ -import { ElementFinder, by, browser } from 'protractor'; +import { ElementFinder, by, browser, until } from 'protractor'; import { Component } from '../component'; import { UserInfo } from './user-info'; import { Menu } from '../menu/menu'; import { Toolbar } from './../toolbar/toolbar'; import { SearchInput } from '../search/search-input'; +import { BROWSER_WAIT_TIMEOUT } from '../../configs'; export class Header extends Component { private static selectors = { root: 'app-header', logoLink: by.css('.app-menu__title'), userInfo: by.css('aca-current-user'), - moreActions: by.id('app.header.more') + moreActions: by.id('app.header.more'), + + sidenavToggle: `[id='adf-sidebar-toggle-start']`, + expandedSidenav: by.css(`[data-automation-id='expanded']`), + collapsedSidenav: by.css(`[data-automation-id='collapsed']`) }; logoLink: ElementFinder = this.component.element(Header.selectors.logoLink); moreActions: ElementFinder = browser.element(Header.selectors.moreActions); + sidenavToggle: ElementFinder = this.component.element(by.css(Header.selectors.sidenavToggle)); userInfo: UserInfo = new UserInfo(this.component); menu: Menu = new Menu(); @@ -58,5 +64,30 @@ export class Header extends Component { async isSignOutDisplayed() { return await this.userInfo.menu.isMenuItemPresent('Sign out'); } + + async clickSidenavToggle() { + await this.sidenavToggle.click(); + } + + async isExpandedSidenav() { + return await browser.isElementPresent(Header.selectors.expandedSidenav); + } + + async expandSideNav() { + const expanded = await this.isExpandedSidenav(); + if ( !expanded ) { + await this.clickSidenavToggle(); + await browser.wait(until.elementLocated(Header.selectors.expandedSidenav), BROWSER_WAIT_TIMEOUT, '--- timeout waiting for expanded sidenav' ); + } + } + + async collapseSideNav() { + const expanded = await this.isExpandedSidenav(); + if ( expanded ) { + await this.clickSidenavToggle(); + await browser.wait(until.elementLocated(Header.selectors.collapsedSidenav), BROWSER_WAIT_TIMEOUT, '--- timeout waiting for collapsed sidenav') + } + } + } diff --git a/e2e/components/sidenav/sidenav.ts b/e2e/components/sidenav/sidenav.ts index c363c47fba..f8b2a9d8cb 100755 --- a/e2e/components/sidenav/sidenav.ts +++ b/e2e/components/sidenav/sidenav.ts @@ -23,8 +23,8 @@ * along with Alfresco. If not, see . */ -import { ElementFinder, ElementArrayFinder, by, element } from 'protractor'; -import { SIDEBAR_LABELS } from '../../configs'; +import { ElementFinder, ElementArrayFinder, by, element, browser } from 'protractor'; +import { SIDEBAR_LABELS, BROWSER_WAIT_TIMEOUT } from '../../configs'; import { Menu } from '../menu/menu'; import { Component } from '../component'; import { Utils } from '../../utilities/utils'; @@ -37,28 +37,29 @@ export class Sidenav extends Component { expansion_panel: ".mat-expansion-panel-header", expansion_panel_content: ".mat-expansion-panel-body", active: 'mat-accent', - activeLink: '.mat-accent', + activeClass: '.item--active', activeChild: 'item--active', + newButton: '[data-automation-id="create-button"]', - personalFiles: `[id='app.navbar.personalFiles']`, - fileLibraries: `[id='app.navbar.libraries.menu']`, - myLibraries: `[id='app.navbar.libraries.files']`, - favoriteLibraries: `[id='app.navbar.libraries.favorite']`, - shared: `[id='app.navbar.shared']`, - recentFiles: `[id='app.navbar.recentFiles']`, - favorites: `[id='app.navbar.favorites']`, - trash: `[id='app.navbar.trashcan']` + personalFiles: `[data-automation-id='app.navbar.personalFiles']`, + fileLibraries: `[data-automation-id='app.navbar.libraries.menu']`, + myLibraries: `[data-automation-id='app.navbar.libraries.files']`, + favoriteLibraries: `[data-automation-id='app.navbar.libraries.favorite']`, + shared: `[data-automation-id='app.navbar.shared']`, + recentFiles: `[data-automation-id='app.navbar.recentFiles']`, + favorites: `[data-automation-id='app.navbar.favorites']`, + trash: `[data-automation-id='app.navbar.trashcan']` }; links: ElementArrayFinder = this.component.all(by.css(Sidenav.selectors.link)); - activeLink: ElementFinder = this.component.element(by.css(Sidenav.selectors.activeLink)); + activeLink: ElementFinder = this.component.element(by.css(Sidenav.selectors.activeClass)); newButton: ElementArrayFinder = this.component.all(by.css(Sidenav.selectors.newButton)); personalFiles: ElementFinder = this.component.element(by.css(Sidenav.selectors.personalFiles)); fileLibraries: ElementFinder = this.component.element(by.css(Sidenav.selectors.fileLibraries)); - myLibraries: ElementFinder = this.component.element(by.css(Sidenav.selectors.myLibraries)); - favoriteLibraries: ElementFinder = this.component.element(by.css(Sidenav.selectors.favoriteLibraries)); + myLibraries: ElementFinder = browser.element(by.css(Sidenav.selectors.myLibraries)); + favoriteLibraries: ElementFinder = browser.element(by.css(Sidenav.selectors.favoriteLibraries)); shared: ElementFinder = this.component.element(by.css(Sidenav.selectors.shared)); recentFiles: ElementFinder = this.component.element(by.css(Sidenav.selectors.recentFiles)); favorites: ElementFinder = this.component.element(by.css(Sidenav.selectors.favorites)); @@ -105,8 +106,7 @@ export class Sidenav extends Component { } async isActive(name: string) { - const className = await this.getLinkLabel(name).getAttribute('class'); - return className.includes(Sidenav.selectors.active); + return await this.getLinkLabel(name).isElementPresent(by.css(Sidenav.selectors.activeClass)); } async childIsActive(name: string) { @@ -137,7 +137,15 @@ export class Sidenav extends Component { } async getLinkTooltip(name: string) { - return await this.getLink(name).getAttribute('title'); + const link = this.getLinkLabel(name); + + const condition = () => link.getAttribute('title').then(value => value && value.length > 0); + + await browser.actions().mouseMove(link).perform(); + + await browser.wait(condition, BROWSER_WAIT_TIMEOUT); + + return await link.getAttribute('title'); } async clickLink(name: string) { diff --git a/e2e/suites/navigation/sidebar.test.ts b/e2e/suites/navigation/sidebar.test.ts index bbc585fa63..65384a45c9 100755 --- a/e2e/suites/navigation/sidebar.test.ts +++ b/e2e/suites/navigation/sidebar.test.ts @@ -24,20 +24,28 @@ */ import { browser } from 'protractor'; - import { APP_ROUTES, SIDEBAR_LABELS } from '../../configs'; -import { LoginPage, BrowsingPage } from '../../pages/pages'; +import { LoginPage, BrowsingPage, SearchResultsPage } from '../../pages/pages'; +import { Utils } from '../../utilities/utils'; describe('Sidebar', () => { const loginPage = new LoginPage(); const page = new BrowsingPage(); - const { sidenav } = page; + const { sidenav, header } = page; + const searchResultsPage = new SearchResultsPage(); + const { searchInput } = searchResultsPage.header; beforeAll(async (done) => { await loginPage.loginWithAdmin(); done(); }); + beforeEach(async (done) => { + await Utils.pressEscape(); + await header.expandSideNav(); + done(); + }); + it('has "Personal Files" as default - [C217149]', async () => { expect(await browser.getCurrentUrl()).toContain(APP_ROUTES.PERSONAL_FILES); expect(await sidenav.isActive(SIDEBAR_LABELS.PERSONAL_FILES)).toBe(true, 'Default active link'); @@ -51,7 +59,7 @@ describe('Sidebar', () => { }); it('My Libraries is automatically selected on expanding File Libraries - [C289900]', async () => { - await page.clickFileLibraries(); + await sidenav.expandFileLibraries(); expect(await browser.getCurrentUrl()).toContain(APP_ROUTES.MY_LIBRARIES); expect(await sidenav.isActive(SIDEBAR_LABELS.FILE_LIBRARIES)).toBe(false, 'File Libraries link is active'); expect(await sidenav.childIsActive(SIDEBAR_LABELS.MY_LIBRARIES)).toBe(true, 'My Libraries link not active'); @@ -71,12 +79,6 @@ describe('Sidebar', () => { expect(await sidenav.childIsActive(SIDEBAR_LABELS.MY_LIBRARIES)).toBe(true, 'My Libraries link not active'); }); - it('navigates to "Personal Files" - [C280409]', async () => { - await page.clickPersonalFiles(); - expect(await browser.getCurrentUrl()).toContain(APP_ROUTES.PERSONAL_FILES); - expect(await sidenav.isActive(SIDEBAR_LABELS.PERSONAL_FILES)).toBe(true, 'Personal Files link not active'); - }); - it('navigates to "Shared Files" - [C213110]', async () => { await page.clickSharedFiles(); expect(await browser.getCurrentUrl()).toContain(APP_ROUTES.SHARED_FILES); @@ -101,51 +103,135 @@ describe('Sidebar', () => { expect(await sidenav.isActive(SIDEBAR_LABELS.TRASH)).toBe(true, 'Trash link not active'); }); - // TODO: incomplete test + it('navigates to "Personal Files" - [C280409]', async () => { + await page.clickPersonalFiles(); + expect(await browser.getCurrentUrl()).toContain(APP_ROUTES.PERSONAL_FILES); + expect(await sidenav.isActive(SIDEBAR_LABELS.PERSONAL_FILES)).toBe(true, 'Personal Files link not active'); + }); + it('Personal Files tooltip - [C217151]', async () => { await page.clickPersonalFiles(); expect(await sidenav.getLinkTooltip(SIDEBAR_LABELS.PERSONAL_FILES)).toContain('View your Personal Files'); + + await header.collapseSideNav(); + expect(await sidenav.getLinkTooltip(SIDEBAR_LABELS.PERSONAL_FILES)).toContain('View your Personal Files'); + }); + + it('Shared Files tooltip - [C213111]', async () => { + await page.clickSharedFiles(); + expect(await sidenav.getLinkTooltip(SIDEBAR_LABELS.SHARED_FILES)).toContain('View files that have been shared'); + + await header.collapseSideNav(); + expect(await sidenav.getLinkTooltip(SIDEBAR_LABELS.SHARED_FILES)).toContain('View files that have been shared'); + }); + + it('Recent Files tooltip - [C213167]', async () => { + await page.clickRecentFiles(); + expect(await sidenav.getLinkTooltip(SIDEBAR_LABELS.RECENT_FILES)).toContain('View files you recently edited'); + + await header.collapseSideNav(); + expect(await sidenav.getLinkTooltip(SIDEBAR_LABELS.RECENT_FILES)).toContain('View files you recently edited'); + }); + + it('Favorites tooltip - [C217153]', async () => { + await page.clickFavorites(); + expect(await sidenav.getLinkTooltip(SIDEBAR_LABELS.FAVORITES)).toContain('View your favorite files and folders'); + + await header.collapseSideNav(); + expect(await sidenav.getLinkTooltip(SIDEBAR_LABELS.FAVORITES)).toContain('View your favorite files and folders'); + }); + + it('Trash tooltip - [C217154]', async () => { + await page.clickTrash(); + expect(await sidenav.getLinkTooltip(SIDEBAR_LABELS.TRASH)).toContain('View deleted files in the trash'); + + await header.collapseSideNav(); + expect(await sidenav.getLinkTooltip(SIDEBAR_LABELS.TRASH)).toContain('View deleted files in the trash'); }); - // TODO: incomplete test it('File Libraries tooltip - [C217152]', async () => { await page.clickFileLibraries(); expect(await sidenav.getLinkTooltip(SIDEBAR_LABELS.FILE_LIBRARIES)).toContain('File Libraries'); + + await header.collapseSideNav(); + expect(await sidenav.getLinkTooltip(SIDEBAR_LABELS.FILE_LIBRARIES)).toContain('File Libraries'); }); - // TODO: incomplete test it('My Libraries tooltip - [C289916]', async () => { await page.goToMyLibraries(); expect(await sidenav.getLinkTooltip(SIDEBAR_LABELS.MY_LIBRARIES)).toContain('Access my libraries'); + + await header.collapseSideNav(); + await sidenav.clickLink(SIDEBAR_LABELS.FILE_LIBRARIES); + expect(await sidenav.getLinkTooltip(SIDEBAR_LABELS.MY_LIBRARIES)).toContain('Access my libraries'); }); - // TODO: incomplete test it('Favorite Libraries tooltip - [C289917]', async () => { await page.goToFavoriteLibraries(); expect(await sidenav.getLinkTooltip(SIDEBAR_LABELS.FAVORITE_LIBRARIES)).toContain('Access my favorite libraries'); + + await header.collapseSideNav(); + await sidenav.clickLink(SIDEBAR_LABELS.FILE_LIBRARIES); + expect(await sidenav.getLinkTooltip(SIDEBAR_LABELS.FAVORITE_LIBRARIES)).toContain('Access my favorite libraries'); }); - // TODO: incomplete test - it('Shared Files tooltip - [C213111]', async () => { - await page.clickSharedFiles(); - expect(await sidenav.getLinkTooltip(SIDEBAR_LABELS.SHARED_FILES)).toContain('View files that have been shared'); + it('default state is expanded - [C269095]', async () => { + expect(await header.isExpandedSidenav()).toBe(true, 'Sidebar not expanded'); }); - // TODO: incomplete test - it('Recent Files tooltip - [C213167]', async () => { - await page.clickRecentFiles(); - expect(await sidenav.getLinkTooltip(SIDEBAR_LABELS.RECENT_FILES)).toContain('View files you recently edited'); + it('sidebar toggle - [C269096]', async () => { + await header.collapseSideNav(); + expect(await header.isExpandedSidenav()).toBe(false, 'Sidebar not collapsed'); + + await header.expandSideNav(); + expect(await header.isExpandedSidenav()).toBe(true, 'Sidebar not expanded'); }); - // TODO: incomplete test - it('Favorites tooltip - [C217153]', async () => { + it('sidebar state is preserved on page refresh - [C269100]', async () => { + expect(await header.isExpandedSidenav()).toBe(true, 'Sidebar not expanded'); + await page.refresh(); + expect(await header.isExpandedSidenav()).toBe(true, 'Sidebar not expanded'); + + await header.collapseSideNav(); + expect(await header.isExpandedSidenav()).toBe(false, 'Sidebar not collapsed'); + await page.refresh(); + expect(await header.isExpandedSidenav()).toBe(false, 'Sidebar not collapsed'); + }); + + it('sidebar state is preserved after logout / login - [C269102]', async () => { + await header.collapseSideNav(); + await page.signOut(); + await loginPage.loginWithAdmin(); + + expect(await header.isExpandedSidenav()).toBe(false, 'Sidebar not collapsed'); + }); + + it('sidebar is collapsed automatically when Search Results opens - [C277223]', async () => { + await searchInput.clickSearchButton(); + /* cspell:disable-next-line */ + await searchInput.searchForTextAndCloseSearchOptions('qwertyuiop'); + await searchResultsPage.waitForResults(); + + expect(await header.isExpandedSidenav()).toBe(false, 'Sidebar not collapsed'); + }); + + it('sidenav returns to the default state when navigating away from the Search Results page - [C277224]', async () => { + await searchInput.clickSearchButton(); + /* cspell:disable-next-line */ + await searchInput.searchForTextAndCloseSearchOptions('qwertyuiop'); + await searchResultsPage.waitForResults(); await page.clickFavorites(); - expect(await sidenav.getLinkTooltip(SIDEBAR_LABELS.FAVORITES)).toContain('View your favorite files and folders'); + + expect(await header.isExpandedSidenav()).toBe(true, 'Sidebar not expanded'); }); - // TODO: incomplete test - it('Trash tooltip - [C217154]', async () => { - await page.clickTrash(); - expect(await sidenav.getLinkTooltip(SIDEBAR_LABELS.TRASH)).toContain('View deleted files in the trash'); + it('sidenav can be expanded when search results page is displayed - [C277230]', async () => { + await searchInput.clickSearchButton(); + /* cspell:disable-next-line */ + await searchInput.searchForTextAndCloseSearchOptions('qwertyuiop'); + await searchResultsPage.waitForResults(); + await header.expandSideNav(); + + expect(await header.isExpandedSidenav()).toBe(true, 'Sidebar not expanded'); }); }); diff --git a/src/app/components/layout/app-layout/app-layout.component.html b/src/app/components/layout/app-layout/app-layout.component.html index 2988e1ecbb..6348de3705 100644 --- a/src/app/components/layout/app-layout/app-layout.component.html +++ b/src/app/components/layout/app-layout/app-layout.component.html @@ -22,13 +22,18 @@ - + + + diff --git a/src/app/components/sidenav/sidenav.component.html b/src/app/components/sidenav/sidenav.component.html index 04cd19d84c..a86acb8771 100644 --- a/src/app/components/sidenav/sidenav.component.html +++ b/src/app/components/sidenav/sidenav.component.html @@ -12,7 +12,11 @@ > - diff --git a/src/app/components/sidenav/sidenav.component.ts b/src/app/components/sidenav/sidenav.component.ts index 3de3241488..9c2a8c3a12 100755 --- a/src/app/components/sidenav/sidenav.component.ts +++ b/src/app/components/sidenav/sidenav.component.ts @@ -38,9 +38,9 @@ import { AppExtensionService } from '../../extensions/extension.service'; import { NavBarGroupRef } from '@alfresco/adf-extensions'; import { Store } from '@ngrx/store'; import { AppStore } from '../../store/states'; -import { ruleContext } from '../../store/selectors/app.selectors'; +import { sidenavState } from '../../store/selectors/app.selectors'; import { Subject } from 'rxjs'; -import { takeUntil, distinctUntilChanged, map } from 'rxjs/operators'; +import { takeUntil, distinctUntilChanged, debounceTime } from 'rxjs/operators'; @Component({ selector: 'app-sidenav', @@ -68,9 +68,9 @@ export class SidenavComponent implements OnInit, OnDestroy { ngOnInit() { this.store - .select(ruleContext) + .select(sidenavState) .pipe( - map(rules => rules.repository), + debounceTime(300), distinctUntilChanged(), takeUntil(this.onDestroy$) ) diff --git a/src/app/components/sidenav/sidenav.module.ts b/src/app/components/sidenav/sidenav.module.ts index 427f0b02ca..79f0d9f42a 100644 --- a/src/app/components/sidenav/sidenav.module.ts +++ b/src/app/components/sidenav/sidenav.module.ts @@ -28,6 +28,8 @@ import { AppCreateMenuModule } from '../create-menu/create-menu.module'; import { CommonModule } from '@angular/common'; import { CoreModule } from '@alfresco/adf-core'; import { RouterModule } from '@angular/router'; +import { ExtensionsModule } from '@alfresco/adf-extensions'; +import { CoreExtensionsModule } from '../../extensions/core.extensions.module'; import { ExpansionPanelDirective } from './directives/expansion-panel.directive'; import { MenuPanelDirective } from './directives/menu-panel.directive'; import { CollapsedTemplateDirective } from './directives/collapsed-template.directive'; @@ -41,6 +43,8 @@ import { ActionDirective } from './directives/action.directive'; imports: [ CommonModule, CoreModule.forChild(), + CoreExtensionsModule.forChild(), + ExtensionsModule.forChild(), RouterModule, AppCreateMenuModule ], diff --git a/src/app/extensions/extension.service.ts b/src/app/extensions/extension.service.ts index 5a058aa129..380f9eff9c 100644 --- a/src/app/extensions/extension.service.ts +++ b/src/app/extensions/extension.service.ts @@ -244,6 +244,12 @@ export class AppExtensionService implements RuleContext { .filter(child => this.filterVisible(child)) .sort(sortByOrder) .map(child => { + if (child.component) { + return { + ...child + }; + } + if (!child.click) { const childRouteRef = this.extensions.getRouteById( child.route @@ -268,6 +274,10 @@ export class AppExtensionService implements RuleContext { }; } + if (item.component) { + return { ...item }; + } + if (!item.click) { const routeRef = this.extensions.getRouteById(item.route); const url = `/${routeRef ? routeRef.path : item.route}`; diff --git a/src/app/store/selectors/app.selectors.ts b/src/app/store/selectors/app.selectors.ts index d7d0c241ab..baaa7aad4f 100644 --- a/src/app/store/selectors/app.selectors.ts +++ b/src/app/store/selectors/app.selectors.ts @@ -103,6 +103,17 @@ export const isAdmin = createSelector( state => state.user.isAdmin ); +export const sidenavState = createSelector( + appSelection, + appNavigation, + (selection, navigation) => { + return { + selection, + navigation + }; + } +); + export const ruleContext = createSelector( appSelection, appNavigation, From c83f78f801282feb50375ac8e518167156d08291 Mon Sep 17 00:00:00 2001 From: Martin Muller Date: Fri, 12 Apr 2019 15:06:49 +0100 Subject: [PATCH 169/259] Feature/ACA-1633 parallel tests (#1064) * [ACA-1633] create test suites. update protractor to use suites. update travis to split in to test suite groups. * disable tomcat tests * exclude failing expect --- .travis.yml | 37 +++++++++++++++++++------ e2e/suites/info-drawer/comments.test.ts | 3 +- package.json | 6 ++-- protractor.conf.js | 13 +++++++++ 4 files changed, 46 insertions(+), 13 deletions(-) diff --git a/.travis.yml b/.travis.yml index 76225ff54b..8c1953e933 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,27 +7,46 @@ addons: language: node_js node_js: - '10' + +env: + matrix: + - DEPLOYMENT=Nginx SUITES=authentication + - DEPLOYMENT=Nginx SUITES=listViews + - DEPLOYMENT=Nginx SUITES=application + - DEPLOYMENT=Nginx SUITES=navigation + - DEPLOYMENT=Nginx SUITES=pagination + - DEPLOYMENT=Nginx SUITES=search + - DEPLOYMENT=Nginx SUITES=actions + - DEPLOYMENT=Nginx SUITES=viewer + - DEPLOYMENT=Nginx SUITES=infoDrawer + - DEPLOYMENT=Nginx SUITES=extensions + before_script: - sudo /etc/init.d/postgresql stop + before_install: - npm install -g npm@latest - export DISPLAY=:99.0 - sh -e /etc/init.d/xvfb start - sleep 3 + +script: | + if [ "$DEPLOYMENT" == "Nginx" ]; then + npm run build.e2e && SUITE="--suite $SUITES" npm run e2e:docker + else + npm run build.tomcat.e2e && SUITE="--suite $SUITES" npm run docker.tomcat.e2e + fi + +stages: + - name: Quality and Unit tests + jobs: include: - - stage: test + - stage: Quality and Unit tests name: 'Code quality checks' script: - npm run lint - - stage: test - name: 'Unit tests' + - name: 'Unit tests' script: - npm run test:ci - bash <(curl -s https://codecov.io/bash) -X gcov - - stage: e2e - name: 'Nginx' - script: npm run build.e2e && npm run e2e:docker - - stage: e2e - name: 'Tomcat' - script: npm run build.tomcat.e2e && npm run docker.tomcat.e2e diff --git a/e2e/suites/info-drawer/comments.test.ts b/e2e/suites/info-drawer/comments.test.ts index d2f0ced841..1bd8c446f3 100755 --- a/e2e/suites/info-drawer/comments.test.ts +++ b/e2e/suites/info-drawer/comments.test.ts @@ -220,7 +220,8 @@ describe('Comments', () => { expect(await infoDrawer.isCommentDisplayed(commentFile1Entry.id)).toBe(true, `Comment with id: ${commentFile1Entry.id} not displayed`); expect(await infoDrawer.getCommentText(commentFile1Entry.id)).toBe(commentFile1Entry.content, 'Incorrect comment text'); expect(await infoDrawer.getCommentUserName(commentFile1Entry.id)).toBe(`${username} ${username}`, 'Incorrect comment user'); - expect(await infoDrawer.getCommentTime(commentFile1Entry.id)).toBe(moment(commentFile1Entry.createdAt).fromNow(), 'Incorrect comment created time'); + // ACA-2348 expect broken because of parallel test suites + // expect(await infoDrawer.getCommentTime(commentFile1Entry.id)).toBe(moment(commentFile1Entry.createdAt).fromNow(), 'Incorrect comment created time'); expect(await infoDrawer.isCommentUserAvatarDisplayed(commentFile1Entry.id)).toBe(true, 'User avatar not displayed'); }); diff --git a/package.json b/package.json index 97c38c02cd..7e09f0fb3e 100644 --- a/package.json +++ b/package.json @@ -16,8 +16,8 @@ "lint": "ng lint && npm run spellcheck && npm run format:check && npm run e2e.typecheck", "wd:update": "webdriver-manager update --gecko=false", "e2e.typecheck": "tsc -p ./e2e/tsconfig.e2e.typecheck.json", - "e2e": "npm run wd:update && protractor --baseUrl=http://localhost:4000", - "e2e.local": "npm run wd:update && protractor --baseUrl=http://localhost:4200", + "e2e": "npm run wd:update && protractor --baseUrl=http://localhost:4000 $SUITE", + "e2e.local": "npm run wd:update && protractor --baseUrl=http://localhost:4200 $SUITE", "wait:app": "wait-on http://localhost:8080 && wait-on http://localhost:4000", "start:docker": "docker-compose up -d --build && npm run wait:app", "stop:docker": "docker-compose stop", @@ -28,7 +28,7 @@ "format:fix": "prettier --write \"src/{app,environments}/**/*.{ts,js,css,scss,html}\"", "build.tomcat": "npm run build.extensions && npm run build.app -- --prod --base-href ./ && jar -cvf docker/tomcat/artifacts/content-app.war -C dist/app/ .", "build.tomcat.e2e": "./build-tomcat-e2e.sh", - "e2e.tomcat": "npm run wd:update && protractor --baseUrl=http://localhost:4000/content-app/", + "e2e.tomcat": "npm run wd:update && protractor --baseUrl=http://localhost:4000/content-app/ $SUITE", "docker.tomcat.start": "cd docker/tomcat && docker-compose up -d --build && npm run wait:app", "docker.tomcat.stop": "cd docker/tomcat && docker-compose stop", "docker.tomcat.e2e": "npm run docker.tomcat.start && npm run e2e.tomcat", diff --git a/protractor.conf.js b/protractor.conf.js index e977659bfa..67a32ef025 100755 --- a/protractor.conf.js +++ b/protractor.conf.js @@ -49,6 +49,19 @@ exports.config = { './e2e/suites/extensions/*.test.ts' ], + suites: { + authentication: './e2e/suites/authentication/*.test.ts', + listViews: './e2e/suites/list-views/*.test.ts', + application: './e2e/suites/application/*.test.ts', + navigation: './e2e/suites/navigation/*.test.ts', + pagination: './e2e/suites/pagination/*.test.ts', + search: './e2e/suites/search/*.test.ts', + actions: './e2e/suites/actions/*.test.ts', + viewer: './e2e/suites/viewer/*.test.ts', + infoDrawer: './e2e/suites/info-drawer/*.test.ts', + extensions: './e2e/suites/extensions/*.test.ts' + }, + SELENIUM_PROMISE_MANAGER: false, capabilities: { From 2001bcd447c5b68505ccaca018efd993941a6c7b Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Fri, 12 Apr 2019 15:26:32 +0100 Subject: [PATCH 170/259] [ACA-2327] rule and evaluator optimisations (#1065) * reduce imports * canCopyNode rule * simplify naming * improve canShareFile rule * canToggleJoinLibrary rule * canEditFolder rule * improve canUploadVersion rule * isTrashcanItemSelected rule * improve canDelete usage * simplify canDownload usage * canViewFile rule * canLeaveLibrary rule * rule usage improvements * canToggleSharedLink rule * canShowInfoDrawer rule * canManageFileVersions rule * canManagePermissions rule * canToggleEditOffline rule * canToggleFavorite rule * minor polishing * fix test * fix evaluator * code and test fixes * fix evaluator --- docs/extending/application-actions.md | 2 +- docs/extending/rules.md | 115 +++--- src/app/extensions/core.extensions.module.ts | 13 + .../evaluators/app.evaluators.spec.ts | 10 + .../extensions/evaluators/app.evaluators.ts | 221 ++++++++++-- src/assets/app.extensions.json | 340 +++--------------- 6 files changed, 327 insertions(+), 374 deletions(-) diff --git a/docs/extending/application-actions.md b/docs/extending/application-actions.md index b0ba5e08c5..122f28ec1a 100644 --- a/docs/extending/application-actions.md +++ b/docs/extending/application-actions.md @@ -113,7 +113,6 @@ Below is the list of public actions types you can use in the plugin definitions | 1.7.0 | UPLOAD_FOLDER | n/a | Invoke "Upload Folder" dialog and upload selected folder to the currently opened one. | | 1.7.0 | UPLOAD_FILE_VERSION | n/a | Invoke "New File Version" dialog. | | 1.7.0 | VIEW_FILE | MinimalNodeEntity | Preview the file (or selection) in the Viewer. | -| 1.8.0 | VIEW_NODE | string | Lightweight preview of a node by id. Can be invoked from extensions. | | 1.7.0 | UNLOCK_WRITE | NodeEntry | Unlock file from read only mode | | 1.7.0 | PRINT_FILE | MinimalNodeEntity | Print the file opened in the Viewer (or selected). | | 1.7.0 | FULLSCREEN_VIEWER | n/a | Enters fullscreen mode to view the file opened in the Viewer. | @@ -122,3 +121,4 @@ Below is the list of public actions types you can use in the plugin definitions | 1.7.0 | TOGGLE_SEARCH_FILTER | n/a | Toggle Filter component visibility in Search Results. | | 1.7.0 | SHOW_SEARCH_FILTER | n/a | Show Filter component in Search Results. | | 1.7.0 | HIDE_SEARCH_FILTER | n/a | Hide Filter component in Search Results | +| 1.8.0 | VIEW_NODE | string | Lightweight preview of a node by id. Can be invoked from extensions. | diff --git a/docs/extending/rules.md b/docs/extending/rules.md index b8ce11fcac..2cbf2f3506 100644 --- a/docs/extending/rules.md +++ b/docs/extending/rules.md @@ -56,11 +56,11 @@ in case you do not need providing extra parameters, or chaining multiple rules t You can create new rules by chaining other rules and evaluators. -| Key | Description | -| ---------- | ----------------------------------------------------------------------------- | -| core.every | Evaluates to `true` if all chained rules evaluate to `true`. | -| core.some | Evaluates to `true` if at least one of the chained rules evaluates to `true`. | -| core.not | Evaluates to `true` if all chained rules evaluate to `false`. | +| Version | Key | Description | +| ------- | ---------- | ----------------------------------------------------------------------------- | +| 1.7.0 | core.every | Evaluates to `true` if all chained rules evaluate to `true`. | +| 1.7.0 | core.some | Evaluates to `true` if at least one of the chained rules evaluates to `true`. | +| 1.7.0 | core.not | Evaluates to `true` if all chained rules evaluate to `false`. | Below is an example of the composite rule definition that combines the following conditions: @@ -129,31 +129,42 @@ The button will be visible only when the linked rule evaluates to `true`. ## Application Evaluators -| Key | Description | -| ----------------------------------- | ------------------------------------------------------------ | -| app.selection.canDelete | User has permission to delete selected node(s). | -| app.selection.canDownload | User can download selected node(s). | -| app.selection.notEmpty | At least one node is selected. | -| app.selection.canUnshare | User is able to remove selected node(s) from public sharing. | -| app.selection.canAddFavorite | User can add selected node(s) to favorites. | -| app.selection.canRemoveFavorite | User can remove selected node(s) from favorites. | -| app.selection.first.canUpdate | User has permission to update selected node(s). | -| app.selection.file | A single File node is selected. | -| app.selection.file.canShare | User is able to share the selected file. | -| app.selection.file.isShared | A shared node is selected. | -| app.selection.file.isLocked | File is locked for editing. | -| app.selection.file.isLockOwner | File is locked and current user is the lock owner. | -| app.selection.file.canUploadVersion | User can update file version. | -| app.selection.library | A single Library node is selected. | -| app.selection.isPrivateLibrary | A private Library node is selected. | -| app.selection.hasLibraryRole | The selected Library node has a role property. | -| app.selection.hasNoLibraryRole | The selected Library node has no role property. | -| app.selection.folder | A single Folder node is selected. | -| app.selection.folder.canUpdate | User has permissions to update the selected folder. | -| app.selection.folder.canUpdate | User has permissions to update the selected folder. | -| app.selection.file.canLock | User has permissions to lock file. | -| app.selection.file.canUnlock | User has permissions to unlock file. | -| repository.isQuickShareEnabled | Whether the quick share repository option is enabled or not. | +| Ver. | Key | Description | +| ----- | ----------------------------------- | ------------------------------------------------------------------------ | +| 1.7.0 | app.selection.canDelete | User has permission to delete selected node(s). | +| 1.7.0 | app.selection.canDownload | User can download selected node(s). | +| 1.7.0 | app.selection.notEmpty | At least one node is selected. | +| 1.7.0 | app.selection.canUnshare | User is able to remove selected node(s) from public sharing. | +| 1.7.0 | app.selection.canAddFavorite | User can add selected node(s) to favorites. | +| 1.7.0 | app.selection.canRemoveFavorite | User can remove selected node(s) from favorites. | +| 1.7.0 | app.selection.first.canUpdate | User has permission to update selected node(s). | +| 1.7.0 | app.selection.file | A single File node is selected. | +| 1.7.0 | app.selection.file.canShare | User is able to share the selected file. | +| 1.7.0 | app.selection.file.isShared | A shared node is selected. | +| 1.7.0 | app.selection.file.isLocked | File is locked for editing. | +| 1.7.0 | app.selection.file.isLockOwner | File is locked and current user is the lock owner. | +| 1.7.0 | app.selection.file.canUploadVersion | User can update file version. | +| 1.7.0 | app.selection.library | A single Library node is selected. | +| 1.7.0 | app.selection.isPrivateLibrary | A private Library node is selected. | +| 1.7.0 | app.selection.hasLibraryRole | The selected Library node has a role property. | +| 1.7.0 | app.selection.hasNoLibraryRole | The selected Library node has no role property. | +| 1.7.0 | app.selection.folder | A single Folder node is selected. | +| 1.7.0 | app.selection.folder.canUpdate | User has permissions to update the selected folder. | +| 1.7.0 | app.selection.folder.canUpdate | User has permissions to update the selected folder. | +| 1.7.0 | app.selection.file.canLock | User has permissions to lock file. | +| 1.7.0 | app.selection.file.canUnlock | User has permissions to unlock file. | +| 1.7.0 | repository.isQuickShareEnabled | Whether the quick share repository option is enabled or not. | +| 1.8.0 | canCopyNode | Checks if user can copy selected node. | +| 1.8.0 | canToggleJoinLibrary | Checks if user can perform "Join" or "Cancel Join Request" on a library. | +| 1.8.0 | canEditFolder | Checks if user can edit the selected folder. | +| 1.8.0 | isTrashcanItemSelected | Checks if user has trashcan item selected. | +| 1.8.0 | canViewFile | Checks if user can view the file. | +| 1.8.0 | canLeaveLibrary | Checks if user can **Leave** selected library. | +| 1.8.0 | canToggleSharedLink | Checks if user can toggle shared link mode. | +| 1.8.0 | canShowInfoDrawer | Checks if user can show **Info Drawer** for the selected node. | +| 1.8.0 | canManageFileVersions | Checks if user can manage file versions for the selected node. | +| 1.8.0 | canManagePermissions | Checks if user can manage permissions for the selected node. | +| 1.8.0 | canToggleEditOffline | Checks if user can toggle **Edit Offline** mode for selected node. | ## Navigation Evaluators @@ -165,28 +176,28 @@ for example mixing `core.every` and `core.not`. **Tip:** You can also negate any rule by utilizing a `!` prefix: `!app.navigation.isTrashcan` is the opposite of the `app.navigation.isTrashcan`. -| Key | Description | -| --------------------------------- | ---------------------------------------------------------------- | -| app.navigation.folder.canCreate | User can create content in the currently opened folder. | -| app.navigation.folder.canUpload | User can upload content to the currently opened folder. | -| app.navigation.isTrashcan | User is using the **Trashcan** page. | -| app.navigation.isNotTrashcan | Current page is not a **Trashcan**. | -| app.navigation.isLibraries | User is using a **Libraries** or **Library Search Result** page. | -| app.navigation.isNotLibraries | Current page is not a **Libraries** page. | -| app.navigation.isSharedFiles | User is using the **Shared Files** page. | -| app.navigation.isNotSharedFiles | Current page is not **Shared Files**. | -| app.navigation.isFavorites | User is using the **Favorites** page. | -| app.navigation.isNotFavorites | Current page is not **Favorites**. | -| app.navigation.isRecentFiles | User is using the **Recent Files** page. | -| app.navigation.isNotRecentFiles | Current page is not **Recent Files**. | -| app.navigation.isSearchResults | User is using the **Search Results** page. | -| app.navigation.isNotSearchResults | Current page is not the **Search Results**. | -| app.navigation.isSharedPreview | Current page is preview **Shared Files**. | -| app.navigation.isFavoritesPreview | Current page is preview **Favorites**. | -| app.navigation.isSharedFileViewer | Current page is shared file preview page. | -| app.navigation.isPreview | Current page is **Preview**. | -| app.navigation.isPersonalFiles | Current page is **Personal Files**. | -| app.navigation.isLibraryFiles | Current page is **Library Files**. | +| Version | Key | Description | +| ------- | --------------------------------- | ---------------------------------------------------------------- | +| 1.7.0 | app.navigation.folder.canCreate | User can create content in the currently opened folder. | +| 1.7.0 | app.navigation.folder.canUpload | User can upload content to the currently opened folder. | +| 1.7.0 | app.navigation.isTrashcan | User is using the **Trashcan** page. | +| 1.7.0 | app.navigation.isNotTrashcan | Current page is not a **Trashcan**. | +| 1.7.0 | app.navigation.isLibraries | User is using a **Libraries** or **Library Search Result** page. | +| 1.7.0 | app.navigation.isNotLibraries | Current page is not a **Libraries** page. | +| 1.7.0 | app.navigation.isSharedFiles | User is using the **Shared Files** page. | +| 1.7.0 | app.navigation.isNotSharedFiles | Current page is not **Shared Files**. | +| 1.7.0 | app.navigation.isFavorites | User is using the **Favorites** page. | +| 1.7.0 | app.navigation.isNotFavorites | Current page is not **Favorites**. | +| 1.7.0 | app.navigation.isRecentFiles | User is using the **Recent Files** page. | +| 1.7.0 | app.navigation.isNotRecentFiles | Current page is not **Recent Files**. | +| 1.7.0 | app.navigation.isSearchResults | User is using the **Search Results** page. | +| 1.7.0 | app.navigation.isNotSearchResults | Current page is not the **Search Results**. | +| 1.7.0 | app.navigation.isSharedPreview | Current page is preview **Shared Files**. | +| 1.7.0 | app.navigation.isFavoritesPreview | Current page is preview **Favorites**. | +| 1.7.0 | app.navigation.isSharedFileViewer | Current page is shared file preview page. | +| 1.7.0 | app.navigation.isPreview | Current page is **Preview**. | +| 1.7.0 | app.navigation.isPersonalFiles | Current page is **Personal Files**. | +| 1.7.0 | app.navigation.isLibraryFiles | Current page is **Library Files**. | **Tip:** See the [Registration](/extending/registration) section for more details on how to register your own entries to be re-used at runtime. diff --git a/src/app/extensions/core.extensions.module.ts b/src/app/extensions/core.extensions.module.ts index b72ee28991..6baca9af59 100644 --- a/src/app/extensions/core.extensions.module.ts +++ b/src/app/extensions/core.extensions.module.ts @@ -109,6 +109,19 @@ export class CoreExtensionsModule { }); extensions.setEvaluators({ + canCopyNode: app.canCopyNode, + canToggleJoinLibrary: app.canToggleJoinLibrary, + canEditFolder: app.canEditFolder, + isTrashcanItemSelected: app.isTrashcanItemSelected, + canViewFile: app.canViewFile, + canLeaveLibrary: app.canLeaveLibrary, + canToggleSharedLink: app.canToggleSharedLink, + canShowInfoDrawer: app.canShowInfoDrawer, + canManageFileVersions: app.canManageFileVersions, + canManagePermissions: app.canManagePermissions, + canToggleEditOffline: app.canToggleEditOffline, + canToggleFavorite: app.canToggleFavorite, + 'app.selection.canDelete': app.canDeleteSelection, 'app.selection.file.canUnlock': app.canUnlockFile, 'app.selection.file.canLock': app.canLockFile, diff --git a/src/app/extensions/evaluators/app.evaluators.spec.ts b/src/app/extensions/evaluators/app.evaluators.spec.ts index 1b9860cf27..781ed2ef59 100644 --- a/src/app/extensions/evaluators/app.evaluators.spec.ts +++ b/src/app/extensions/evaluators/app.evaluators.spec.ts @@ -302,6 +302,7 @@ describe('app.evaluators', () => { check: () => (checked = true) }, selection: { + file: {}, isEmpty: false, nodes: [ { @@ -324,6 +325,9 @@ describe('app.evaluators', () => { it('should return [true] if route is `/favorites`', () => { const context: any = { + selection: { + file: {} + }, navigation: { url: '/favorites' } @@ -334,6 +338,9 @@ describe('app.evaluators', () => { it('should return [true] if route is `/favorites`', () => { const context: any = { + selection: { + file: {} + }, navigation: { url: '/favorites' } @@ -344,6 +351,9 @@ describe('app.evaluators', () => { it('should return [true] if route is `/shared`', () => { const context: any = { + selection: { + file: {} + }, navigation: { url: '/shared' } diff --git a/src/app/extensions/evaluators/app.evaluators.ts b/src/app/extensions/evaluators/app.evaluators.ts index b5b243e6a4..74ad483836 100644 --- a/src/app/extensions/evaluators/app.evaluators.ts +++ b/src/app/extensions/evaluators/app.evaluators.ts @@ -24,16 +24,21 @@ */ import { RuleContext } from '@alfresco/adf-extensions'; -import { - isNotTrashcan, - isNotLibraries, - isFavorites, - isLibraries, - isTrashcan, - isSharedFiles, - isNotSearchResults, - isPreview -} from './navigation.evaluators'; +import * as navigation from './navigation.evaluators'; +import * as repository from './repository.evaluators'; + +/** + * Checks if user can copy selected node. + * JSON ref: `app.canCopyNode` + * @param context Rule execution context + */ +export function canCopyNode(context: RuleContext): boolean { + return [ + hasSelection(context), + navigation.isNotTrashcan(context), + navigation.isNotLibraries(context) + ].every(Boolean); +} /** * Checks if user can mark selected nodes as **Favorite**. @@ -41,7 +46,11 @@ import { */ export function canAddFavorite(context: RuleContext): boolean { if (!context.selection.isEmpty) { - if (isFavorites(context) || isLibraries(context) || isTrashcan(context)) { + if ( + navigation.isFavorites(context) || + navigation.isLibraries(context) || + navigation.isTrashcan(context) + ) { return false; } return context.selection.nodes.some(node => !node.entry.isFavorite); @@ -54,8 +63,8 @@ export function canAddFavorite(context: RuleContext): boolean { * JSON ref: `app.selection.canRemoveFavorite` */ export function canRemoveFavorite(context: RuleContext): boolean { - if (!context.selection.isEmpty && !isTrashcan(context)) { - if (isFavorites(context)) { + if (!context.selection.isEmpty && !navigation.isTrashcan(context)) { + if (navigation.isFavorites(context)) { return true; } return context.selection.nodes.every(node => node.entry.isFavorite); @@ -68,10 +77,36 @@ export function canRemoveFavorite(context: RuleContext): boolean { * JSON ref: `app.selection.file.canShare` */ export function canShareFile(context: RuleContext): boolean { - if (isNotTrashcan(context) && context.selection.file) { - return true; - } - return false; + return [ + context.selection.file, + navigation.isNotTrashcan(context), + repository.hasQuickShareEnabled(context), + !isShared(context) + ].every(Boolean); +} + +/** + * Checks if user can perform "Join" or "Cancel Join Request" on a library. + * JSON ref: `canToggleJoinLibrary` + */ +export function canToggleJoinLibrary(context: RuleContext): boolean { + return [ + hasLibrarySelected(context), + !isPrivateLibrary(context), + hasNoLibraryRole(context) + ].every(Boolean); +} + +/** + * Checks if user can edit the selected folder. + * JSON ref: `canEditFolder` + * @param context Rule execution context + */ +export function canEditFolder(context: RuleContext): boolean { + return [ + canUpdateSelectedFolder(context), + navigation.isNotTrashcan(context) + ].every(Boolean); } /** @@ -79,12 +114,12 @@ export function canShareFile(context: RuleContext): boolean { * JSON ref: `app.selection.file.isShared` */ export function isShared(context: RuleContext): boolean { - if (isSharedFiles(context) && !context.selection.isEmpty) { + if (navigation.isSharedFiles(context) && !context.selection.isEmpty) { return true; } if ( - (isNotTrashcan(context), + (navigation.isNotTrashcan(context), !context.selection.isEmpty && context.selection.file) ) { return !!( @@ -103,9 +138,9 @@ export function isShared(context: RuleContext): boolean { */ export function canDeleteSelection(context: RuleContext): boolean { if ( - isNotTrashcan(context) && - isNotLibraries(context) && - isNotSearchResults(context) && + navigation.isNotTrashcan(context) && + navigation.isNotLibraries(context) && + navigation.isNotSearchResults(context) && !context.selection.isEmpty ) { if (hasLockedFiles(context)) { @@ -113,16 +148,16 @@ export function canDeleteSelection(context: RuleContext): boolean { } // temp workaround for Search api - if (isFavorites(context)) { + if (navigation.isFavorites(context)) { return true; } - if (isPreview(context)) { + if (navigation.isPreview(context)) { return context.permissions.check(context.selection.nodes, ['delete']); } // workaround for Shared Files - if (isSharedFiles(context)) { + if (navigation.isSharedFiles(context)) { return context.permissions.check(context.selection.nodes, ['delete'], { target: 'allowableOperationsOnTarget' }); @@ -183,7 +218,7 @@ export function canUpload(context: RuleContext): boolean { * JSON ref: `app.selection.canDownload` */ export function canDownloadSelection(context: RuleContext): boolean { - if (!context.selection.isEmpty) { + if (!context.selection.isEmpty && navigation.isNotTrashcan(context)) { return context.selection.nodes.every((node: any) => { return ( node.entry && @@ -249,8 +284,10 @@ export function hasNoLibraryRole(context: RuleContext): boolean { * JSON ref: `app.selection.file` */ export function hasFileSelected(context: RuleContext): boolean { - const file = context.selection.file; - return file ? true : false; + if (context && context.selection && context.selection.file) { + return true; + } + return false; } /** @@ -279,7 +316,7 @@ export function canUpdateSelectedFolder(context: RuleContext): boolean { if (folder) { return ( // workaround for Favorites Api - isFavorites(context) || + navigation.isFavorites(context) || context.permissions.check(folder.entry, ['update']) ); } @@ -365,11 +402,127 @@ export function canUnlockFile(context: RuleContext): boolean { * JSON ref: `app.selection.file.canUploadVersion` */ export function canUploadVersion(context: RuleContext): boolean { - if (isFavorites(context) || isSharedFiles(context)) { - return true; + if (navigation.isFavorites(context) || navigation.isSharedFiles(context)) { + return hasFileSelected(context); } - return isWriteLocked(context) - ? isUserWriteLockOwner(context) - : canUpdateSelectedNode(context); + return [ + hasFileSelected(context), + navigation.isNotTrashcan(context), + isWriteLocked(context) + ? isUserWriteLockOwner(context) + : canUpdateSelectedNode(context) + ].every(Boolean); +} + +/** + * Checks if user has trashcan item selected. + * JSON ref: `isTrashcanItemSelected` + * @param context Rule execution context + */ +export function isTrashcanItemSelected(context: RuleContext): boolean { + return [navigation.isTrashcan(context), hasSelection(context)].every(Boolean); +} + +/** + * Checks if user can view the file. + * JSON ref: `canViewFile` + * @param context Rule execution context + */ +export function canViewFile(context: RuleContext): boolean { + return [hasFileSelected(context), navigation.isNotTrashcan(context)].every( + Boolean + ); +} + +/** + * Checks if user can **Leave** selected library. + * JSON ref: `canLeaveLibrary` + * @param context Rule execution context + */ +export function canLeaveLibrary(context: RuleContext): boolean { + return [hasLibrarySelected(context), hasLibraryRole(context)].every(Boolean); +} + +/** + * Checks if user can toggle shared link mode. + * JSON ref: `canToggleSharedLink` + * @param context Rule execution context + */ +export function canToggleSharedLink(context: RuleContext): boolean { + return [ + hasFileSelected(context), + [canShareFile(context), isShared(context)].some(Boolean) + ].every(Boolean); +} + +/** + * Checks if user can show **Info Drawer** for the selected node. + * JSON ref: `canShowInfoDrawer` + * @param context Rule execution context + */ +export function canShowInfoDrawer(context: RuleContext): boolean { + return [ + hasSelection(context), + navigation.isNotLibraries(context), + navigation.isNotTrashcan(context) + ].every(Boolean); +} + +/** + * Checks if user can manage file versions for the selected node. + * JSON ref: `canManageFileVersions` + * @param context Rule execution context + */ +export function canManageFileVersions(context: RuleContext): boolean { + return [ + hasFileSelected(context), + navigation.isNotTrashcan(context), + !hasLockedFiles(context) + ].every(Boolean); +} + +/** + * Checks if user can manage permissions for the selected node. + * JSON ref: `canManagePermissions` + * @param context Rule execution context + */ +export function canManagePermissions(context: RuleContext): boolean { + return [ + canUpdateSelectedNode(context), + navigation.isNotTrashcan(context) + ].every(Boolean); +} + +/** + * Checks if user can toggle **Edit Offline** mode for selected node. + * JSON ref: `canToggleEditOffline` + * @param context Rule execution context + */ +export function canToggleEditOffline(context: RuleContext): boolean { + return [ + hasFileSelected(context), + navigation.isNotTrashcan(context), + navigation.isNotFavorites(context) || + navigation.isFavoritesPreview(context), + navigation.isNotSharedFiles(context) || navigation.isSharedPreview(context), + canLockFile(context) || canUnlockFile(context) + ].every(Boolean); +} + +/** + * @deprecated Uses workarounds for for recent files and search api issues. + * Checks if user can toggle **Favorite** state for a node. + * @param context Rule execution context + */ +export function canToggleFavorite(context: RuleContext): boolean { + return [ + [canAddFavorite(context), canRemoveFavorite(context)].some(Boolean), + [ + navigation.isRecentFiles(context), + navigation.isSharedFiles(context), + navigation.isSearchResults(context), + navigation.isFavorites(context) + ].some(Boolean) + ].every(Boolean); } diff --git a/src/assets/app.extensions.json b/src/assets/app.extensions.json index 3ee04c578c..ebda8ffc42 100644 --- a/src/assets/app.extensions.json +++ b/src/assets/app.extensions.json @@ -10,72 +10,6 @@ "$references": ["aos.plugin.json"], "rules": [ - { - "id": "app.toolbar.favorite.canToggle", - "comment": "workaround for recent files and search api issue", - "type": "core.every", - "parameters": [ - { - "type": "rule", - "value": "core.some", - "parameters": [ - { - "type": "rule", - "value": "app.selection.canAddFavorite" - }, - { - "type": "rule", - "value": "app.selection.canRemoveFavorite" - } - ] - }, - { - "type": "rule", - "value": "core.some", - "parameters": [ - { - "type": "rule", - "value": "app.navigation.isRecentFiles" - }, - { - "type": "rule", - "value": "app.navigation.isSharedFiles" - }, - { - "type": "rule", - "value": "app.navigation.isSearchResults" - }, - { - "type": "rule", - "value": "app.navigation.isFavorites" - } - ] - } - ] - }, - { - "id": "app.context.canShare", - "type": "core.every", - "parameters": [ - { "type": "rule", "value": "app.selection.file.canShare" }, - { "type": "rule", "value": "repository.isQuickShareEnabled" } - ] - }, - { - "id": "app.toolbar.canShare", - "type": "core.every", - "parameters": [ - { "type": "rule", "value": "app.selection.file.canShare" }, - { "type": "rule", "value": "repository.isQuickShareEnabled" }, - { - "type": "rule", - "value": "core.not", - "parameters": [ - { "type": "rule", "value": "app.selection.file.isShared" } - ] - } - ] - }, { "id": "app.toolbar.favorite.canAdd", "type": "core.every", @@ -83,10 +17,7 @@ { "type": "rule", "value": "app.selection.canAddFavorite" }, { "type": "rule", "value": "app.navigation.isNotRecentFiles" }, { "type": "rule", "value": "app.navigation.isNotSharedFiles" }, - { - "type": "rule", - "value": "app.navigation.isNotSearchResults" - }, + { "type": "rule", "value": "app.navigation.isNotSearchResults" }, { "type": "rule", "value": "app.navigation.isNotFavorites" } ] }, @@ -97,174 +28,9 @@ { "type": "rule", "value": "app.selection.canRemoveFavorite" }, { "type": "rule", "value": "app.navigation.isNotRecentFiles" }, { "type": "rule", "value": "app.navigation.isNotSharedFiles" }, - { - "type": "rule", - "value": "app.navigation.isNotSearchResults" - }, + { "type": "rule", "value": "app.navigation.isNotSearchResults" }, { "type": "rule", "value": "app.navigation.isNotFavorites" } ] - }, - { - "id": "app.toolbar.info", - "type": "core.every", - "parameters": [ - { "type": "rule", "value": "app.selection.notEmpty" }, - { "type": "rule", "value": "app.navigation.isNotLibraries" }, - { "type": "rule", "value": "app.navigation.isNotTrashcan" } - ] - }, - { - "id": "app.libraries.toolbar", - "type": "core.every", - "parameters": [ - { "type": "rule", "value": "app.selection.notEmpty" }, - { "type": "rule", "value": "app.selection.library" } - ] - }, - { - "id": "app.libraries.toolbar.canToggleJoin", - "type": "core.every", - "parameters": [ - { "type": "rule", "value": "app.selection.library" }, - { "type": "rule", - "value": "core.not", - "parameters": [ - { "type": "rule", "value": "app.selection.isPrivateLibrary" } - ] - }, - { "type": "rule", "value": "app.selection.hasNoLibraryRole" } - ] - }, - { - "id": "app.libraries.toolbar.canLeaveLibrary", - "type": "core.every", - "parameters": [ - { "type": "rule", "value": "app.selection.library" }, - { "type": "rule", "value": "app.selection.hasLibraryRole" } - ] - }, - { - "id": "app.toolbar.canCopyNode", - "type": "core.every", - "parameters": [ - { "type": "rule", "value": "app.selection.notEmpty" }, - { "type": "rule", "value": "app.navigation.isNotTrashcan" }, - { "type": "rule", "value": "app.navigation.isNotLibraries" } - ] - }, - { - "id": "app.toolbar.permissions", - "type": "core.every", - "parameters": [ - { "type": "rule", "value": "app.selection.first.canUpdate" }, - { "type": "rule", "value": "app.navigation.isNotTrashcan" } - ] - }, - { - "id": "app.toolbar.versions", - "type": "core.every", - "parameters": [ - { "type": "rule", "value": "app.selection.file" }, - { "type": "rule", "value": "app.navigation.isNotTrashcan" }, - { - "type": "rule", - "value": "core.not", - "parameters": [ - { "type": "rule", "value": "app.selection.file.isLocked" } - ] - } - ] - }, - { - "id": "app.trashcan.hasSelection", - "type": "core.every", - "parameters": [ - { "type": "rule", "value": "app.selection.notEmpty" }, - { "type": "rule", "value": "app.navigation.isTrashcan" } - ] - }, - { - "id": "app.toolbar.canEditFolder", - "type": "core.every", - "parameters": [ - { "type": "rule", "value": "app.selection.folder" }, - { "type": "rule", "value": "app.selection.folder.canUpdate" }, - { "type": "rule", "value": "app.navigation.isNotTrashcan" } - ] - }, - { - "id": "app.toolbar.canViewFile", - "type": "core.every", - "parameters": [ - { - "type": "rule", - "value": "app.selection.file" - }, - { - "type": "rule", - "value": "core.not", - "parameters": [ - { "type": "rule", "value": "app.navigation.isTrashcan" } - ] - } - ] - }, - { - "id": "app.toolbar.canDownload", - "type": "core.every", - "parameters": [ - { "type": "rule", "value": "app.selection.canDownload" }, - { "type": "rule", "value": "app.navigation.isNotTrashcan" } - ] - }, - { - "id": "app.toolbar.canDelete", - "type": "core.every", - "parameters": [ - { "type": "rule", "value": "app.selection.canDelete" }, - { "type": "rule", "value": "app.navigation.isNotTrashcan" } - ] - }, - { - "id": "app.toolbar.canToggleLock", - "type": "core.every", - "parameters": [ - { "type": "rule", "value": "app.selection.file" }, - { "type": "rule", "value": "app.navigation.isNotTrashcan" }, - { - "type": "rule", - "value": "core.some", - "parameters": [ - { "type": "rule", "value": "app.navigation.isNotFavorites" }, - { "type": "rule", "value": "app.navigation.isFavoritesPreview" } - ] - }, - { - "type": "rule", - "value": "core.some", - "parameters": [ - { "type": "rule", "value": "app.navigation.isNotSharedFiles" }, - { "type": "rule", "value": "app.navigation.isSharedPreview" } - ] - }, - { - "type": "rule", - "value": "core.some", - "parameters": [ - { "type": "rule", "value": "app.selection.file.canUnlock" }, - { "type": "rule", "value": "app.selection.file.canLock" } - ] - } - ] - }, - { - "id": "app.toolbar.canUploadNewVersion", - "type": "core.every", - "parameters": [ - { "type": "rule", "value": "app.selection.file" }, - { "type": "rule", "value": "app.navigation.isNotTrashcan" }, - { "type": "rule", "value": "app.selection.file.canUploadVersion" } - ] } ], @@ -438,7 +204,7 @@ "click": "SHARE_NODE" }, "rules": { - "visible": "app.toolbar.canShare" + "visible": "app.selection.file.canShare" } }, { @@ -462,7 +228,7 @@ "click": "VIEW_FILE" }, "rules": { - "visible": "app.toolbar.canViewFile" + "visible": "canViewFile" } }, { @@ -474,7 +240,7 @@ "click": "DOWNLOAD_NODES" }, "rules": { - "visible": "app.toolbar.canDownload" + "visible": "app.selection.canDownload" } }, { @@ -486,7 +252,7 @@ "click": "PURGE_DELETED_NODES" }, "rules": { - "visible": "app.trashcan.hasSelection" + "visible": "isTrashcanItemSelected" } }, { @@ -498,7 +264,7 @@ "click": "RESTORE_DELETED_NODES" }, "rules": { - "visible": "app.trashcan.hasSelection" + "visible": "isTrashcanItemSelected" } }, { @@ -507,7 +273,7 @@ "order": 600, "component": "app.toolbar.toggleJoinLibrary", "rules": { - "visible": "app.libraries.toolbar.canToggleJoin" + "visible": "canToggleJoinLibrary" } }, { @@ -519,7 +285,7 @@ "click": "LEAVE_LIBRARY" }, "rules": { - "visible": "app.libraries.toolbar.canLeaveLibrary" + "visible": "canLeaveLibrary" } }, { @@ -533,7 +299,7 @@ "order": 700, "component": "app.toolbar.toggleInfoDrawer", "rules": { - "visible": "app.toolbar.info" + "visible": "canShowInfoDrawer" } }, { @@ -542,7 +308,7 @@ "order": 800, "component": "app.toolbar.toggleInfoDrawer", "rules": { - "visible": "app.libraries.toolbar" + "visible": "app.selection.library" } }, { @@ -558,7 +324,7 @@ "type": "custom", "component": "app.toolbar.toggleEditOffline", "rules": { - "visible": "app.toolbar.canToggleLock" + "visible": "canToggleEditOffline" } }, { @@ -570,7 +336,7 @@ "click": "UPLOAD_FILE_VERSION" }, "rules": { - "visible": "app.toolbar.canUploadNewVersion" + "visible": "app.selection.file.canUploadVersion" } }, { @@ -585,7 +351,7 @@ "order": 400, "component": "app.toolbar.toggleFavorite", "rules": { - "visible": "app.toolbar.favorite.canToggle" + "visible": "canToggleFavorite" } }, { @@ -594,7 +360,7 @@ "order": 401, "component": "app.toolbar.toggleFavoriteLibrary", "rules": { - "visible": "app.libraries.toolbar" + "visible": "app.selection.library" } }, { @@ -630,7 +396,7 @@ "click": "EDIT_FOLDER" }, "rules": { - "visible": "app.toolbar.canEditFolder" + "visible": "canEditFolder" } }, { @@ -647,7 +413,7 @@ "click": "COPY_NODES" }, "rules": { - "visible": "app.toolbar.canCopyNode" + "visible": "canCopyNode" } }, { @@ -659,7 +425,7 @@ "click": "MOVE_NODES" }, "rules": { - "visible": "app.toolbar.canDelete" + "visible": "app.selection.canDelete" } }, { @@ -671,7 +437,7 @@ "click": "DELETE_NODES" }, "rules": { - "visible": "app.toolbar.canDelete" + "visible": "app.selection.canDelete" } }, { @@ -688,7 +454,7 @@ "click": "MANAGE_VERSIONS" }, "rules": { - "visible": "app.toolbar.versions" + "visible": "canManageFileVersions" } }, { @@ -700,7 +466,7 @@ "click": "MANAGE_PERMISSIONS" }, "rules": { - "visible": "app.toolbar.permissions" + "visible": "canManagePermissions" } }, { @@ -725,7 +491,7 @@ "type": "custom", "component": "app.toolbar.toggleEditOffline", "rules": { - "visible": "app.toolbar.canToggleLock" + "visible": "canToggleEditOffline" } }, { @@ -737,7 +503,7 @@ "click": "UPLOAD_FILE_VERSION" }, "rules": { - "visible": "app.toolbar.canUploadNewVersion" + "visible": "app.selection.file.canUploadVersion" } }, { @@ -751,7 +517,7 @@ "order": 400, "component": "app.shared-link.toggleSharedLink", "rules": { - "visible": "app.context.canShare" + "visible": "canToggleSharedLink" } }, { @@ -763,7 +529,7 @@ "click": "DOWNLOAD_NODES" }, "rules": { - "visible": "app.toolbar.canDownload" + "visible": "app.selection.canDownload" } }, { @@ -775,7 +541,7 @@ "click": "VIEW_FILE" }, "rules": { - "visible": "app.toolbar.canViewFile" + "visible": "canViewFile" } }, { @@ -809,7 +575,7 @@ "order": 702, "component": "app.toolbar.toggleFavorite", "rules": { - "visible": "app.toolbar.favorite.canToggle" + "visible": "canToggleFavorite" } }, { @@ -818,7 +584,7 @@ "order": 703, "component": "app.toolbar.toggleFavoriteLibrary", "rules": { - "visible": "app.libraries.toolbar" + "visible": "app.selection.library" } }, { @@ -830,7 +596,7 @@ "click": "EDIT_FOLDER" }, "rules": { - "visible": "app.toolbar.canEditFolder" + "visible": "canEditFolder" } }, { @@ -847,7 +613,7 @@ "click": "COPY_NODES" }, "rules": { - "visible": "app.toolbar.canCopyNode" + "visible": "canCopyNode" } }, { @@ -859,7 +625,7 @@ "click": "MOVE_NODES" }, "rules": { - "visible": "app.toolbar.canDelete" + "visible": "app.selection.canDelete" } }, { @@ -871,7 +637,7 @@ "click": "DELETE_NODES" }, "rules": { - "visible": "app.toolbar.canDelete" + "visible": "app.selection.canDelete" } }, { @@ -888,7 +654,7 @@ "click": "MANAGE_VERSIONS" }, "rules": { - "visible": "app.toolbar.versions" + "visible": "canManageFileVersions" } }, { @@ -900,7 +666,7 @@ "click": "MANAGE_PERMISSIONS" }, "rules": { - "visible": "app.toolbar.permissions" + "visible": "canManagePermissions" } }, { @@ -909,7 +675,7 @@ "order": 100, "component": "app.menu.toggleJoinLibrary", "rules": { - "visible": "app.libraries.toolbar.canToggleJoin" + "visible": "canToggleJoinLibrary" } }, { @@ -921,7 +687,7 @@ "click": "LEAVE_LIBRARY" }, "rules": { - "visible": "app.libraries.toolbar.canLeaveLibrary" + "visible": "canLeaveLibrary" } }, { @@ -933,7 +699,7 @@ "click": "DELETE_LIBRARY" }, "rules": { - "visible": "app.libraries.toolbar" + "visible": "app.selection.library" } }, { @@ -945,7 +711,7 @@ "click": "PURGE_DELETED_NODES" }, "rules": { - "visible": "app.trashcan.hasSelection" + "visible": "isTrashcanItemSelected" } }, { @@ -957,7 +723,7 @@ "click": "RESTORE_DELETED_NODES" }, "rules": { - "visible": "app.trashcan.hasSelection" + "visible": "isTrashcanItemSelected" } } ], @@ -972,7 +738,7 @@ "click": "FULLSCREEN_VIEWER" }, "rules": { - "visible": "app.toolbar.canViewFile" + "visible": "canViewFile" } }, { @@ -989,7 +755,7 @@ "click": "SHARE_NODE" }, "rules": { - "visible": "app.toolbar.canShare" + "visible": "app.selection.file.canShare" } }, { @@ -1013,7 +779,7 @@ "click": "DOWNLOAD_NODES" }, "rules": { - "visible": "app.toolbar.canDownload" + "visible": "app.selection.canDownload" } }, { @@ -1025,7 +791,7 @@ "click": "PRINT_FILE" }, "rules": { - "visible": "app.toolbar.canViewFile" + "visible": "canViewFile" } }, { @@ -1039,7 +805,7 @@ "order": 500, "component": "app.toolbar.toggleInfoDrawer", "rules": { - "visible": "app.toolbar.info" + "visible": "canShowInfoDrawer" } }, { @@ -1055,7 +821,7 @@ "type": "custom", "component": "app.toolbar.toggleEditOffline", "rules": { - "visible": "app.toolbar.canToggleLock" + "visible": "canToggleEditOffline" } }, { @@ -1067,7 +833,7 @@ "click": "UPLOAD_FILE_VERSION" }, "rules": { - "visible": "app.toolbar.canUploadNewVersion" + "visible": "app.selection.file.canUploadVersion" } }, { @@ -1106,7 +872,7 @@ "order": 402, "component": "app.toolbar.toggleFavorite", "rules": { - "visible": "app.toolbar.favorite.canToggle" + "visible": "canToggleFavorite" } }, { @@ -1123,7 +889,7 @@ "click": "COPY_NODES" }, "rules": { - "visible": "app.toolbar.canCopyNode" + "visible": "canCopyNode" } }, { @@ -1135,7 +901,7 @@ "click": "MOVE_NODES" }, "rules": { - "visible": "app.toolbar.canDelete" + "visible": "app.selection.canDelete" } }, { @@ -1147,7 +913,7 @@ "click": "DELETE_NODES" }, "rules": { - "visible": "app.toolbar.canDelete" + "visible": "app.selection.canDelete" } }, { @@ -1165,7 +931,7 @@ "click": "MANAGE_VERSIONS" }, "rules": { - "visible": "app.toolbar.versions" + "visible": "canManageFileVersions" } }, { @@ -1177,7 +943,7 @@ "click": "MANAGE_PERMISSIONS" }, "rules": { - "visible": "app.toolbar.permissions" + "visible": "canManagePermissions" } } ] @@ -1255,7 +1021,7 @@ "title": "APP.INFO_DRAWER.TABS.LIBRARY_PROPERTIES", "component": "app.components.tabs.library.metadata", "rules": { - "visible": "app.libraries.toolbar" + "visible": "app.selection.library" } } ], From 59fa28f6831fd358596252ef896d5278531e8682 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Fri, 12 Apr 2019 15:26:49 +0100 Subject: [PATCH 171/259] upgrade to latest ADF 3.2 alpha (#1069) --- package-lock.json | 59 ++++++--- package.json | 6 +- src/app/app.module.ts | 5 +- .../components/preview/preview.component.ts | 28 ++++- src/app/services/data.service.ts | 119 ------------------ 5 files changed, 68 insertions(+), 149 deletions(-) delete mode 100644 src/app/services/data.service.ts diff --git a/package-lock.json b/package-lock.json index 04bd52e3ec..6ead01c2bc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,25 +5,25 @@ "requires": true, "dependencies": { "@alfresco/adf-content-services": { - "version": "3.2.0-a87d1ef002cf53e1592ed984a5bce0038eda6fad", - "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-3.2.0-a87d1ef002cf53e1592ed984a5bce0038eda6fad.tgz", - "integrity": "sha512-X/5oQdWxdV1ij8yIwim5LHEj2gIFywHBZ3/PBBSlk1TAiY2lWt/QIJ3fPbqIGrXarp5vezA/NCiXPI1BPTyNvw==", + "version": "3.2.0-6ad63055b35b43eb305359b6f47851facd672476", + "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-3.2.0-6ad63055b35b43eb305359b6f47851facd672476.tgz", + "integrity": "sha512-em9lmfsdco7q6nQrvBsnnyxZhxYFgqsjnrPUJkF30U20HVbLn9C0PQpqch24qoJGF//qMzvnIR+DmkeUmYntbA==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/adf-core": { - "version": "3.2.0-a87d1ef002cf53e1592ed984a5bce0038eda6fad", - "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-3.2.0-a87d1ef002cf53e1592ed984a5bce0038eda6fad.tgz", - "integrity": "sha512-Z3DSR/gu9vlmczmXJHt07p49e6cl9aJ4Xu3Xj/MGlrveUG333v4wCwaTMfSaVv80Ca5QhKqR+P/vHLjvJuoAhw==", + "version": "3.2.0-dac3bed09f5e8235868555c24102f91dcae9c6e1", + "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-3.2.0-dac3bed09f5e8235868555c24102f91dcae9c6e1.tgz", + "integrity": "sha512-GwSkh42tUvTRjfnkZ8kJiuF8wB0C4137cm/JA11raT5mihrCzTBwH3GutmnWRZuxLXE4wwKRquTD5s0Bbh4K1w==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/adf-extensions": { - "version": "3.2.0-a87d1ef002cf53e1592ed984a5bce0038eda6fad", - "resolved": "https://registry.npmjs.org/@alfresco/adf-extensions/-/adf-extensions-3.2.0-a87d1ef002cf53e1592ed984a5bce0038eda6fad.tgz", - "integrity": "sha512-eVL1O1yZFQJdvOfrHwD+NW7kox2lkhldX/5FOUD7X70my6MGQjXPtPupwhruvda94LFgjM8FDmbSr8ahns+KQw==", + "version": "3.2.0-6ad63055b35b43eb305359b6f47851facd672476", + "resolved": "https://registry.npmjs.org/@alfresco/adf-extensions/-/adf-extensions-3.2.0-6ad63055b35b43eb305359b6f47851facd672476.tgz", + "integrity": "sha512-YIFi8iZg8/2/e866a9KXb3sOlzbjd1MePp7L0bA2YLQE+gOw7Xka4e++ieZtLA6Oo7SWZt1l6wkdfscx+WS/cQ==", "requires": { "tslib": "^1.9.0" } @@ -4959,7 +4959,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -4980,12 +4981,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": 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" @@ -5000,17 +5003,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -5127,7 +5133,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -5139,6 +5146,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -5153,6 +5161,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -5160,12 +5169,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -5184,6 +5195,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -5264,7 +5276,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -5276,6 +5289,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -5361,7 +5375,8 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -5397,6 +5412,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -5416,6 +5432,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -5459,12 +5476,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, diff --git a/package.json b/package.json index 7e09f0fb3e..dcc15e88c0 100644 --- a/package.json +++ b/package.json @@ -36,9 +36,9 @@ }, "private": true, "dependencies": { - "@alfresco/adf-content-services": "3.2.0-a87d1ef002cf53e1592ed984a5bce0038eda6fad", - "@alfresco/adf-core": "3.2.0-a87d1ef002cf53e1592ed984a5bce0038eda6fad", - "@alfresco/adf-extensions": "3.2.0-a87d1ef002cf53e1592ed984a5bce0038eda6fad", + "@alfresco/adf-content-services": "3.2.0-6ad63055b35b43eb305359b6f47851facd672476", + "@alfresco/adf-core": "3.2.0-dac3bed09f5e8235868555c24102f91dcae9c6e1", + "@alfresco/adf-extensions": "3.2.0-6ad63055b35b43eb305359b6f47851facd672476", "@alfresco/js-api": "3.1.0-2c7e78d49c51ba0966d4e6c4dedf2b64da83d630", "@angular/animations": "7.2.12", "@angular/cdk": "^7.3.7", diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 639f0ccc74..c8068b0347 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -39,8 +39,7 @@ import { } from '@alfresco/adf-core'; import { LibraryDialogComponent, - ContentModule, - CustomResourcesService + ContentModule } from '@alfresco/adf-content-services'; import { AppComponent } from './app.component'; @@ -76,7 +75,6 @@ import { AppLoginModule } from './components/login/login.module'; import { AppHeaderModule } from './components/header/header.module'; import { AppNodeVersionModule } from './components/node-version/node-version.module'; import { environment } from '../environments/environment'; -import { AppDataService } from './services/data.service'; @NgModule({ imports: [ @@ -124,7 +122,6 @@ import { AppDataService } from './services/data.service'; providers: [ { provide: RouteReuseStrategy, useClass: AppRouteReuseStrategy }, { provide: AppConfigService, useClass: DebugAppConfigService }, - { provide: CustomResourcesService, useClass: AppDataService }, { provide: TRANSLATION_PROVIDER, multi: true, diff --git a/src/app/components/preview/preview.component.ts b/src/app/components/preview/preview.component.ts index 98d3eff000..376ebbd13c 100644 --- a/src/app/components/preview/preview.component.ts +++ b/src/app/components/preview/preview.component.ts @@ -54,7 +54,6 @@ import { AppExtensionService } from '../../extensions/extension.service'; import { ContentManagementService } from '../../services/content-management.service'; import { ContentActionRef, ViewerExtensionRef } from '@alfresco/adf-extensions'; import { SearchRequest } from '@alfresco/js-api'; -import { AppDataService } from '../../services/data.service'; import { from } from 'rxjs'; @Component({ @@ -85,10 +84,33 @@ export class PreviewComponent extends PageComponent contentExtensions: Array = []; showRightSide = false; + recentFileFilters = [ + 'TYPE:"content"', + '-PNAME:"0/wiki"', + '-TYPE:"app:filelink"', + '-TYPE:"fm:post"', + '-TYPE:"cm:thumbnail"', + '-TYPE:"cm:failedThumbnail"', + '-TYPE:"cm:rating"', + '-TYPE:"dl:dataList"', + '-TYPE:"dl:todoList"', + '-TYPE:"dl:issue"', + '-TYPE:"dl:contact"', + '-TYPE:"dl:eventAgenda"', + '-TYPE:"dl:event"', + '-TYPE:"dl:task"', + '-TYPE:"dl:simpletask"', + '-TYPE:"dl:meetingAgenda"', + '-TYPE:"dl:location"', + '-TYPE:"fm:topic"', + '-TYPE:"fm:post"', + '-TYPE:"ia:calendarEvent"', + '-TYPE:"lnk:link"' + ]; + constructor( private contentApi: ContentApiService, private preferences: UserPreferencesService, - private appDataService: AppDataService, private route: ActivatedRoute, private router: Router, private apiService: AlfrescoApiService, @@ -370,7 +392,7 @@ export class PreviewComponent extends PageComponent { query: `cm:modified:[NOW/DAY-30DAYS TO NOW/DAY+1DAY]` }, { query: `cm:modifier:${username} OR cm:creator:${username}` }, { - query: this.appDataService.recentFileFilters.join(' AND ') + query: this.recentFileFilters.join(' AND ') } ], fields: ['id', this.getRootField(sortingKey)], diff --git a/src/app/services/data.service.ts b/src/app/services/data.service.ts deleted file mode 100644 index a8ce3404f2..0000000000 --- a/src/app/services/data.service.ts +++ /dev/null @@ -1,119 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2019 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { Injectable } from '@angular/core'; -import { CustomResourcesService } from '@alfresco/adf-content-services'; -import { - PaginationModel, - LogService, - AlfrescoApiService -} from '@alfresco/adf-core'; -import { Observable } from 'rxjs'; -import { PersonEntry, SearchRequest, ResultSetPaging } from '@alfresco/js-api'; - -@Injectable({ - providedIn: 'root' -}) -export class AppDataService extends CustomResourcesService { - recentFileFilters = [ - 'TYPE:"content"', - '-PNAME:"0/wiki"', - '-TYPE:"app:filelink"', - '-TYPE:"fm:post"', - '-TYPE:"cm:thumbnail"', - '-TYPE:"cm:failedThumbnail"', - '-TYPE:"cm:rating"', - '-TYPE:"dl:dataList"', - '-TYPE:"dl:todoList"', - '-TYPE:"dl:issue"', - '-TYPE:"dl:contact"', - '-TYPE:"dl:eventAgenda"', - '-TYPE:"dl:event"', - '-TYPE:"dl:task"', - '-TYPE:"dl:simpletask"', - '-TYPE:"dl:meetingAgenda"', - '-TYPE:"dl:location"', - '-TYPE:"fm:topic"', - '-TYPE:"fm:post"', - '-TYPE:"ia:calendarEvent"', - '-TYPE:"lnk:link"' - ]; - - constructor(private api: AlfrescoApiService, logService: LogService) { - super(api, logService); - } - - getRecentFiles( - personId: string, - pagination: PaginationModel - ): Observable { - return new Observable(observer => { - this.api.peopleApi.getPerson(personId).then( - (person: PersonEntry) => { - const username = person.entry.id; - const query: SearchRequest = { - query: { - query: '*', - language: 'afts' - }, - filterQueries: [ - { query: `cm:modified:[NOW/DAY-30DAYS TO NOW/DAY+1DAY]` }, - { query: `cm:modifier:${username} OR cm:creator:${username}` }, - { - query: this.recentFileFilters.join(' AND ') - } - ], - include: ['path', 'properties', 'allowableOperations'], - sort: [ - { - type: 'FIELD', - field: 'cm:modified', - ascending: false - } - ], - paging: { - maxItems: pagination.maxItems, - skipCount: pagination.skipCount - } - }; - return this.api.searchApi.search(query).then( - searchResult => { - observer.next(searchResult); - observer.complete(); - }, - err => { - observer.error(err); - observer.complete(); - } - ); - }, - err => { - observer.error(err); - observer.complete(); - } - ); - }); - } -} From fcb077d80315504ffe3ef9af8f4ae8fa50d31e4e Mon Sep 17 00:00:00 2001 From: Adina Parpalita Date: Sat, 13 Apr 2019 08:56:49 +0300 Subject: [PATCH 172/259] add automated tests for password protected files (#1073) --- e2e/components/components.ts | 1 + e2e/components/dialog/password-dialog.ts | 109 ++++++++++++++++ e2e/components/viewer/viewer.ts | 13 +- e2e/configs.ts | 6 +- e2e/resources/test-files/protected.pdf | Bin 0 -> 18052 bytes .../viewer/viewer-protected-file.test.ts | 119 ++++++++++++++++++ 6 files changed, 244 insertions(+), 4 deletions(-) create mode 100755 e2e/components/dialog/password-dialog.ts create mode 100644 e2e/resources/test-files/protected.pdf create mode 100755 e2e/suites/viewer/viewer-protected-file.test.ts diff --git a/e2e/components/components.ts b/e2e/components/components.ts index a1440fa843..252410cb30 100755 --- a/e2e/components/components.ts +++ b/e2e/components/components.ts @@ -29,6 +29,7 @@ export * from './header/user-info'; export * from './data-table/data-table'; export * from './dialog/confirm-dialog'; export * from './dialog/create-edit-folder-dialog'; +export * from './dialog/password-dialog'; export * from './pagination/pagination'; export * from './sidenav/sidenav'; export * from './toolbar/toolbar'; diff --git a/e2e/components/dialog/password-dialog.ts b/e2e/components/dialog/password-dialog.ts new file mode 100755 index 0000000000..c5bdc8a063 --- /dev/null +++ b/e2e/components/dialog/password-dialog.ts @@ -0,0 +1,109 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2019 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { ElementFinder, by, browser, ExpectedConditions as EC, until } from 'protractor'; +import { BROWSER_WAIT_TIMEOUT } from '../../configs'; +import { Component } from '../component'; + +export class PasswordDialog extends Component { + private static selectors = { + root: 'adf-pdf-viewer-password-dialog', + + title: '.mat-dialog-title', + content: '.mat-dialog-content', + passwordInput: 'input[type="Password"]', + actionButtons: '.mat-dialog-actions', + errorMessage: '.mat-error' + }; + + title: ElementFinder = this.component.element(by.css(PasswordDialog.selectors.title)); + content: ElementFinder = this.component.element(by.css(PasswordDialog.selectors.content)); + passwordInput: ElementFinder = this.component.element(by.css(PasswordDialog.selectors.passwordInput)); + errorMessage: ElementFinder = this.component.element(by.css(PasswordDialog.selectors.errorMessage)); + closeButton: ElementFinder = this.component.element(by.buttonText('Close')); + submitButton: ElementFinder = this.component.element(by.buttonText('Submit')); + + constructor(ancestor?: ElementFinder) { + super(PasswordDialog.selectors.root, ancestor); + } + + async waitForDialogToClose() { + await browser.wait(EC.stalenessOf(this.title), BROWSER_WAIT_TIMEOUT); + } + + async waitForDialogToOpen() { + await browser.wait(EC.presenceOf(this.title), BROWSER_WAIT_TIMEOUT); + } + + async isDialogOpen() { + return await browser.isElementPresent(by.css(PasswordDialog.selectors.root)); + } + + async getTitle() { + return await this.title.getText(); + } + + async isCloseEnabled() { + return await this.closeButton.isEnabled(); + } + + async isSubmitEnabled() { + return await this.submitButton.isEnabled(); + } + + async clickClose() { + return await this.closeButton.click(); + } + + async clickSubmit() { + return await this.submitButton.click(); + } + + async isPasswordInputDisplayed() { + const present = await browser.isElementPresent(this.passwordInput); + if (present) { + return await this.passwordInput.isDisplayed(); + } else { + return false; + } + } + + async isErrorDisplayed() { + const elem = await browser.wait(until.elementLocated(by.css(PasswordDialog.selectors.errorMessage)), BROWSER_WAIT_TIMEOUT, '------- timeout waiting for error message to appear') + return await browser.isElementPresent(elem); + } + + async getErrorMessage() { + if (await this.isErrorDisplayed()) { + return await this.errorMessage.getText(); + } + return ''; + } + + async enterPassword(password: string) { + await this.passwordInput.clear(); + await this.passwordInput.sendKeys(password); + } +} diff --git a/e2e/components/viewer/viewer.ts b/e2e/components/viewer/viewer.ts index d687c3bce9..944aa928eb 100755 --- a/e2e/components/viewer/viewer.ts +++ b/e2e/components/viewer/viewer.ts @@ -23,7 +23,7 @@ * along with Alfresco. If not, see . */ -import { ElementFinder, by, browser, ExpectedConditions as EC } from 'protractor'; +import { ElementFinder, by, browser, ExpectedConditions as EC, ElementArrayFinder } from 'protractor'; import { Component } from '../component'; import { BROWSER_WAIT_TIMEOUT } from '../../configs'; import { Toolbar } from '../toolbar/toolbar'; @@ -37,7 +37,9 @@ export class Viewer extends Component { closeBtn: '.adf-viewer-close-button', fileTitle: '.adf-viewer__file-title', - viewerExtensionContent: 'adf-preview-extension' + viewerExtensionContent: 'adf-preview-extension', + + pdfViewerContentPage: '.adf-pdf-viewer__content .page' }; root: ElementFinder = browser.$(Viewer.selectors.root); @@ -46,6 +48,7 @@ export class Viewer extends Component { closeButton: ElementFinder = this.component.element(by.css(Viewer.selectors.closeBtn)); fileTitle: ElementFinder = this.component.element(by.css(Viewer.selectors.fileTitle)); viewerExtensionContent: ElementFinder = this.component.element(by.css(Viewer.selectors.viewerExtensionContent)); + pdfViewerContentPages: ElementArrayFinder = this.component.all(by.css(Viewer.selectors.pdfViewerContentPage)); toolbar = new Toolbar(this.component); @@ -63,7 +66,6 @@ export class Viewer extends Component { async isViewerOpened() { return await browser.isElementPresent(this.viewerLayout); - // return await this.viewerLayout.isPresent(); } async isViewerContentDisplayed() { @@ -103,4 +105,9 @@ export class Viewer extends Component { return await this.viewerExtensionContent.getAttribute('data-automation-id'); } } + + async isPdfViewerContentDisplayed() { + const count = await this.pdfViewerContentPages.count(); + return count > 0; + } } diff --git a/e2e/configs.ts b/e2e/configs.ts index c663f1c017..542be231cf 100755 --- a/e2e/configs.ts +++ b/e2e/configs.ts @@ -113,7 +113,11 @@ export const FILES = { xlsxFile: 'file-xlsx.xlsx', xlsxFile2: 'file2-xlsx.xlsx', pdfFile: 'file-pdf.pdf', - unsupportedFile: 'file_unsupported.3DS' + unsupportedFile: 'file_unsupported.3DS', + protectedFile: { + name: 'protected.pdf', + password: '0000' + } }; export const EXTENSIBILITY_CONFIGS = { diff --git a/e2e/resources/test-files/protected.pdf b/e2e/resources/test-files/protected.pdf new file mode 100644 index 0000000000000000000000000000000000000000..d0d083f114898f160cad4b07fdb57046a46cfdf8 GIT binary patch literal 18052 zcmcJ11yo$i(k>)82_6Cj83+(uXBgZqxVyt(!QGt@NPwUrKnU*c?m>fFAhdS(VT6pHqhgO#nU!{ovC4iq4O31Dqt zj>63iV3dMbnK+mNKv0qbfKk-U!U19j{kG6|fCxhjt&Jc6US1S?2Rn$qB}&m|oYkri zx+6j~&2_Z02+3r})%!a2(8C%g-cJTyf;|Su&&|yrGQVN;jYlKRr$cUN|H3ooDZ96u z$yA{y{v|dgE~qT3Q;_R$zS!2V>3gXf@?@Y_a{Nn@YQ%2k8)D|EVvUPs^izA$yq?60 z-8f0Y0U&|c8LDte#g$NdVyJbVaE2=K5%9rMlcQq^$i8V>-@wEs$f1clJi{a2B=75# zDkq;oJD=K7)-yaTfO#H07sKRvN_Fdt(|Hay%Ub1E5Z@2^g1Co25=2h&C=2pq$s%4m z4_z-$xF`yYmu!9Bv5I(t3*frq;?eTQ_RV~8A*UIi*I&r~fpEG_RVt(t1!86N$5cSC z?q=|A+U~wtKx}t6?=Sx}xk|1!5CEf`zRCT6JBXD7fc57@D?se69qkMu_5ik@1R-lH z2k3o!z}@0NS3(+MWTr1@?E=tbf)YR+AOJg%MH>aW7=P%w>-TFB{{Cu?%#c83pcq+3Lit~%q+=k|E4dG7)qan?`Tv}=}jfeiWbvbMUe3}^= zFG&(dl~^emZpvXKJidbmm?C znue3KpisIh^6G|-uAI|ecAM!985Ms6srpt3_V=AAB_#w@bh9D! zr{jysahS6t3yN2`b6o@Kk2dAM8D@nn5~iy%tl@*T_GpS@ly8P7U1en1d<`xbwD#9f z@;RgVr5XaL4= zX)9O2*3GHJSJyJDjd5v+UY81npS+%Qbb19R;tP2Qan9@)A)9ifl~kvAT1KgkIz1#z zt?_1=QrnyMko|r;TS9_I+#F6Oign`_9~97X=F986pYu!=Oz`gJ%}tlyD3BuJq3Rwv zNp&7JX|C+dE>G|vXV2xza{6;ql{TjH&I4L;ulFu^?^IOVXdLUjD?61haj+M%Z%HF1 z6b%4DZw5Lat+|>8<8jlmgWG2689sh-22so+F}$F|6qxMAAI0{2k@*<>>Rl0I+mnjo zUULRTKQ+hVFiw50IF)@YR!ZjRxz+E5(cU@S)O z0aGq%v76e+G|;1^q^H>|=#8MuvXxRTFY(7Uoe33ZIoF4jwQ8O~XG`6h+g#&Yfhu zS{NPtlJfAF!Eb0J7n1w(a}vK(E>(Cr%H@$ifBaY;Pl4WO1H2w(`G$@8kWgDA-jNaP zwBe$~%ym~MZcWnl;%j23s;w&<7WI~W3nmE#50cSaZoaCpm?M>&WF+-$Px%tlTQtL+ z5Zx1?@YjluAvP#
0mRLnIFdUVyv5bQk|_}X>br3b2-$w=={Kf4)*?_ZD5B!-%& zmR8u?*w)5W+=xqR`Fk_IM)RvD(0U=no$%14B1Eit@S0b*`XkQtfkw!{t1u)|g5fZr zZ%Xc&MFK@%bTa$aQ)KHEzaB5Ii81yI_#pS%(;qA6+ zCZ&w_k8$tRg=62(xh$Kb?GuI%KIC(J*%2?PjUktJ+%x@Y z>_h#$-J3&un+8|g!4DIm+dHFkO^}%4#R-(vp>wz&KyGzzpZR>ZZT_=CTAih6OH`_g zr|%60JIJ2A-MV>+5xWkLFrR$h(EC!5uSGIh?yWo`(WKP_WsDctzWV(zWs={Y*Z#n% z_$adItq6Z|=nX!G{0LOfx27-mWbpdzNu^47N9<=* zbFiM#kYXQpL&)KCcVtUy=XaP{!v!yH3-3XF!T)L$df$^eUqzG2V+!+6VvnWDPHIAgM<^QQ{CJVDgdf z53)Mb;d-7?#HHyU5HfX7a(Deh`IbJc>pe|bNY~SOv>F_$EYgzSsd6s8 z)!MxX?0z!c{qo$+n=N4NfZIEyaOv$$R%jq)2e}82QlQc{A=TWXe_4}%Qd+7;4?Uem z0uW^p)=Mz+Nrp1HBA6^XeIyEw-9RcBIW~lhBgKth8ImJ5u-AIPUUqpxJ6O%n_2^kC zUh{lR*1jJuEUMHu4QW>dxeD=)fM7nwL6!?JGfGGk(CyZKH|+UjTQ;-#>%+qbN=(#z zz8&cwT_P2*)iSQkTGHI%KQ8mk%H8rTt+T)o%mv;cS3LjfnTIQM3;&}&Bj$#1@s+V9 zoSVXU&6_7LQky3HLd@~^8BFYJZ-|TdZ>g#<+PXa{43+8K^N-(090b}J_nC!fjy4xy zT)Pg0Hi}qGm48!u#>yd|wA;&%gi0HNLEeWg?M?YI3GEU6_pJHW#xpu=se>rUfTazV zY?pbCfgAI~A=ogv=nedEU;@Mq91@?;YM*?&Mv{BlPp#prkGXn*=WnvK{FvQ9;bK8V zTA4X_*f-cKQ?$wfWL|ZQJ!{voZg*QgCy{tE=o|8&C9zo&z{mRBbr840f%oyZ^PaQX z*oJjIp&Hu6%R-LRkvf7CI(})mP3{$*g}x^L)Mzx-7@;_agPBpfh=S(8Xikl@b>|<| zFq`k5J5EHjR5Z!kEO^dFZe!skG{KEN3C5b7Mj?e|WqWpAZaT;J{lWIsiEQDrGxzCh zlG>v{Mu}~Vk9K=H0v|KgN;Bk3R^o+o1CAe6q3?4*2oHsOHcoxl)_=TnOl!lN^c_b52}1n@~ZAmBBh>3=IU?<|p-@x5iZvvfZT(^S#HUQwzTT2iUm7D{x{r0*nw5K6o~JMmK^jj^v+?b8=9j*{f2Gjx_hAq=RB)EL zRPU6|HqK&NCOgSs%tm3+;Sd~HdD~4BX)-N&y?YQi+Z0ZumPEV zZRYQG<##mb2L7dxkf6Rj#0bFrGZWDM#l!rI=}&1JGyBi&_@q@styUcgi@p_NeW`V#9)(x@16u>tHU9{Q~|f z&E@{2g5@rm`laHJq@3lCeC)qlT{1>=7XOC#zY*n)#K2_WTQXJ*1d(9{c@sHSg`ZUrn}uJpn9tY3?uk|2M12@<%59uhqPt!T-%_-uL{a>i^Gb z-i_^-hTq26|EIM6E>m~BKOA6`G&8b?=J7vQ{@%qE0QYmFfTI0pclmSj`%{CEzJtDn zwaL%(2K!$J4Jr^jdoyb*03-Ai=uiFcbN9cF@ZLok6&(#6?oTb0pgH4=S?X! zAq8o9S|NQ4GXp!bpC<#t5PL&AGaCnMJLoA0)NJSqC|N68ncbfqvHWqmA!=r4?;vEV zZwFw7CgxK5zZx6>MpZK-2h)3#q0Att2v!be6d;%bz{&&y0Kv@nw7;1C=jZ;{lk)Re zK=-?xnlq`LG&ub=`+CG>A+Glwm zZc09RwCd|Q9T#wYMEV*w-5X{%qiU(l9SZ-%Hk!~!*c9S=9+f+8MQlUJ^%SwC$P0Cy zVe>$h!$#KQ+3t8NYA4~EFFftV5(l|;N#DNHGgvbev{wAS<);9FBF7;mzRLXPI zj=f~ptMOK*;3rp609Aru)3fk@^Q8WI=diG|{|biptNc&b`RxZk{X$0H5_<6R50A0X zH@Q3Gx<6DByg%Qf2Qje%=vkqMK+G&aCIB-N3!63y<4dSBn;8mNnOH!ePQ@r-Z+Lfl z#sOlvJIwjnpl4x&`j3#ljX1>2#MA-6#tOZu=m4=)x$B|!lZpalgK86SGP(CNs53D` zA3}YXpDkuq7WSV*freNJ3jo@>bKu{B|DN#6)?dE%$7|$g6M9kx27#f9|GOZ)z1EB? zy)uXa2}DV47@Dak0(d|A;?1egw3PLJuxc?PYcXca&*rLpT`9QAAhsX4`B72pF-)qV zfHM5%w@b#y4{&}Q?8rtLq1AlH45yyQis>Da1b4e7USsAXW@|5Mq0U&()oi>XF#+kH zAJfk>QZ#Sumxf8qh`^p(PkLc|Kx!RG*gB`GRxzg)CG*^}h95BDuIOoN`MBGv61Q4ynywQM;1D*94wRJpt~VD111 z7gYyHhp8o(QH906NFR$t!OU^;YPy)Phu<3u-zBHkU$KKuyh69F_oQCGg#I=%A$PJm z-ysLy4}b1tO{uwR176-6l1orR*^dxfBbPn5V|zFZ`C(%FQgTmF$An8{2eQc0D$}cm z)#@*w$xm;$-xU@+o998puW-x7koV5MwuSUklH)aI@}rm>wq0kMoNtC$Yvudk_V6pP zYIWDTtxlk)=$c@ezl~c{U9{@eEJf>L55tF7to(v6&z#?_R;uddp1gUO>zw6jb?aL^ zT#((i6N>(AqiT?Ph38G6-Nz@@ZS>cBv~{^!o)i6>2>7V{`OA+M1`l5j^2#E_!*J5% zmt-H!T|Z{Pl!vbn!nA7>!F8djn7VSS!n}9}gV!vE7r;ei8mOl@uYAr-Y-jL>Zrkwb zA?lC%gUE(-+$`)stT|_KeoD^nN(Ojf1?RPPX+X!;I?(`ohSNdqg}$Epsn~^2_M3)j zhU^cK4=_D6$#Qg3dh<5}=#qUXoljr`+F&lZ+jSUw`+S?YKA5i7Dv`*nhQ5SbM?G%( zpr~oV)!&RdpvC#h1tAsQ*Ssv}Y0r_K18MB_y1Ds0Dh`^T`AwNX)I)po-Iz-K>q!bz zNB%Oe%HF}$HeU43nxrpAFED5d(mTn$YrjD_sS(`~1WJ~9Cxn71mVmw6&!17yg1M#@ z9pCRhjC2V9hyzO=ULbcm5nPS)2wc*y-&L>#r&KhrXOMQ-CIAqvC-&^^%})t(pdc*Ig)CS zIxpUz0<)%!UlMLugxCH0Feq3TX@L9$_JK#**%=}K0PWffDr2UGsv@Bqz$}F|UdoEA z;DZKEuH*wQ*;pnF$025-2co!)vg;mcwlHRfm|IPyooHLjK&Iud%h5qIGerC@dZw=} z&^{SQSz!56IXrj;km_u&9bgb*(#YPBB^qMh&K5~>ns#7ufrHd1uDPoXv}4MdpueqC zD-V}f5&vv*@87d=(uGTU< zm}>P`q*w|_!%Rz=br4UCvE$bt3OWN$aK+Bu_e@+--eB`;r8hW4*m5d~dak5}{$K*y zCO;Ik!!>t8-rWD5{lb>QfUgP{SeGzn9$Rj*#h(+9h`_o#u0SC6$W3ea>%25M!Pg)< z-+>)XA|Z&!sJK3D!~_I4t1(+aW|!;*-!T{O@?bQxjQ9o7*Wx%gGmnyFfl?t`kW$Hr zJJEu0OAylbQ%%> zK_2BJGYW2^1k(+x>BGM6!-yS{M>;OBGF)Qj#Oj9Sq8&nnKrR`=&{CLBrwxvcWzC_g zo5iVoFCZV(rWaeQqMjeFR{LQVRLm82gD+K?i3+Q)>j2j-9Hq27L5r91W%DQKA_Tfo zLsa{MYG-7xpS3rK$psD}$>OBFSLeBsR^S*Fb~&fNnl#xuZE$LrtY>o>Kd(!}&-}c< z#D*92J#1nL9@qPXL}n)VWgpE{xV8_GeEnB31iL1HuZ%422oq;W=|r95RD?Q*Y$4Lu zFGsJI@Xge?{79{uM$BJHboi@|#6T%zHe14^AbpR}juevM*C$>_) zTKraGL7kP>E+JAZ`{unGe?H=t)~R0F`$KcL{F|2vF@ciD#{EpD4b-lbrfD)K$>td& zl0$yx7TD$SMJpl-k+5~OjZa|vq|P@5dwd8H70X`EJs`=o zhswIPGaY!9NTT&!$v#m=zo?mP>9u&>#|Qfd{ln`wn`*|{^I||b?lRu+iKsv{w;hWq zP3L($K*vReVcqv!{v)!U$mjt(>QC%N(;o^JtC!GZS%35dO*(N?Ana>|&OGE914%Qk zbxU*xwlkRDx~q9pal)sDaS(A335tLhf6xam5gH99*C&3JV#HTjeTLdgTPnHp#UCf- z<_LR%E+qzzOg|0oZHT<<8@fsNeLHnLDn*q@d!GU1ho+5O;vG8NWO<7OIgGUBGo*&D zSq!+Rl@+)P#s+izj#;gwJlUyl-@Ceib^XJ)UQ~F2FQOasFm9f1*i<{RtHE6Dogfm> zL=1gHjV~hO2_~njhjHr3d5r!DGiG?;u*M`-l{hWMGWr`WqwDuXL^=n<{>ob0vKy>3 zFQ9;G8&$j9gHQ4}nVoAgc-+3ZZ?#_*Zk@Y*e%q%TnHB$r@&_DU6mN>Oy zXs+Xu)Jwm~Gp%n!KEr!spwzk%*&W9PXF%~4{e_PaQJnK)VyJ0e)ChG!eekxbW?$m` z`KR)Cle)R~^6W8h0^#a|pNm@sU?%PX4HpC}$?^sh011gL&#F^}F@-=11D|<-pWIgM zv7aEmGU>I+v}_J9%Dyfet?*m+G@c|3-Dp*%EW|0D#c3;-*oFxoIG!8B?g+{dg0BZz zgtxao4DQ^mwE-laup>e;#S(+bW34+r0p_XB!R^NoqpB)GbjSTpH1n^jYf|&75h!^0b)}|)fz?ix7Ttg5|5K9rz%X; zI3jooockRbt1nb9L>o|30;Mtu*|eqEjT)H z8Jf}!q)i0l`O(OSg@KWX2T;A%2vbqiltgUD3F==*bgG|?!CP#ZyO*h;6rZg=A_@QU zVlxtPuBY+&MuC*QN O}w`r4V-MkIEf*J=(*@pEgF|Y7X5ipvjS|QRy4kcyjY2f z&P#!s{mK#H(>>FrR-;V@?>4z({X3LIk7ux9c3JglQ#z5yRsI>`W+ zTx1)kG}F{^<-2<{Vh*pj^HX9hk}nU0UWjtPc2&_>V74qc-S$$qU1TrzyD`G=X@h7+ z!L3wOr#dq|;2{=+6SmUOk7RPz$aS9~zdTL!(`mdBGKLc*408(rmCdT(Cii-ix=Oul zQ%~xeiKuxc6v_1pQzf~%M_?MIq1BJcQE@D+6xXjk;VW$YarANWg8Q-MAY z<_BkN_;E=_S3@p-FKNsw>p4-a+0xW5JVVwSGrZEM1Hff9QPpN&YF^DXu{r7440#df z@p2~bH(U?c#64(21W!2>E=rXYMYZD?l+Yc%HdFeHq4XtE1uewDmUt0GwmwV_cE)Vl zJ6l$jQLJdUsNYCf=W3cW7g^3ND7~SB#V%0z@Y}(uNX=p17)*P;y(S4I^6}4l1`dgU-SztfK0j&!$yIQ*7>IwEH9?$z;O=P z-iu#P-C9mY)sx?Zj!GI}NPL(Yn2Lnw#a!ybRyXd@VwDu57NAGLi`;YW+c=-bZ_d+= z3~%qL`-f^F)NQ&1k^HnPB~N=?h_EDzVtC*bT&|YCo_W+LBcL=V-gXO zE8eY8Y?{B}xec3nGgq>vk~0zStFwe8R(mGuxtYlL27h#0OPbG7X`l+uhYXToi zvX%-*&A++Iy}`PO*IQH$=A&P5HlAOFr9&@fxm3#(VVr`LdB4x|kM$Ifr{|r+8N%@B zAK#5hKH2S1iZqW&@8h$+e3D&7F9S*I{se*-{6Wsjk^_??T{&Z3Xk!7oEHVguw#%iW zmNQH83?9y2V(oJ)KAE7)t9p`?nks}xa(GjDeyO^ZWadMhu-<{`U`JS0rHhpi! zR*a9mQu=(hSY5x`EQ#<$6T@%3FEtN&?(cZpNV5gi!>OBX-N!Cl?KqTG~x88xYR#6D4)GBR^(oK#@O+dt>3yD@4fKV zQ==y~ewCLnfr_^0GxDFG2dyvpFB>!ZZatnMx{X4=kZ@osZR)YenM3hDIh%l6i*S-l zRCYkaw2vNg5-9~=Y9~IFOU>{X!P^Fn{g}>-M zygAHVYe!`Pkuo5?k`@_CX?pvD9vql=3tq7|(rl?xPtyIqiV1HhZ`>e@S)D+<5?eEv zSp~a8(Y~5qt%K3%f0GJ(PS5u8Z97{&v9Drty{9aCjC~#dYfk-=;^OFOdpY4%UMCJ- zIqBsQ{x9cQSjATxZ;kz})zv_G#y39_V_!R6^vRTKgP%xn90uxtY$wCj3(U2ceT+s# z)D?ub-&kKb%YXfxx=$%%q+aQWLA6XQp%KJVymQ#Ie<7nw4!20!K=Gs$pQxn1W&VQ_ z8bZCUcfQiXPVjtim)w{J)5+VzhbhQwKjKFHMHnR2)Ey!m*NAVmK(Cn>VAjt@Qd5(K z&(Ljn^GH3qYM#G7alsHO%4$`-rPG<>y3mxmw2Ti~_eUZUbAMQwxXY?Ob{(URo71!FZwd<`r7iFXP!ny!F>UN3K$fqX{idndopelMt(Ag zxESc25?1r;NU%Z~*OcSE4u1Th#H;b4cvA$qLO1oz2IaMtm8G~SzMy+WUPwFTbASP< z{^G55(*cq52MV`3`fi2!c}nsOpGUL>*bcGJK3(E2z)^^$nESPHrRf-#+tj$tLBcw| zGvejJceWey($eX?r&o}fr6U}Q7BMG-OLoTlHiQX&CTFiBZaazZDe0B!ZVV!tf*%MOggmKcRHrFt4QY}l3-=XMRm;J$wahFtAR zK~S(UKgPnI=I6b|wnM{o@*8602np8EJ+6IvmA+*{&S@PP;RqZ0{4?dsNy8J)G~CTZ zC!){mJyeG|fcbJv>VpwlP{fpnz`%hW8qciMhezps6;OzjlBWa|YTy6eU>p>OabTf=qK3gY`7vVSOBHXWP zEKz%)4v-XVa&QXFpD!9@a_n7+c9ugfaaFtRq(}+$5iyXIkV08F3B8#<2L&5m2SYw= zoKPvjgoTgCXW5CEsM@~hLjH)HKIVue;a})9LZSQM%%u`*yh!3&b`CHj(`=usphGV& z?0OyV`)S{;-Y+=3eMt*$ojUg`JkY38{8QA7OPtQpb6sl;++!RJM@P9;&Ylk(DeGVd zSkJDw*6^89*GF(6%uj|9N5$lNTCC#gn%;JzoDTQAdzrfVwe~7-sNvIdz9@&Y@Z%00 z)~;ZLDP%$vwXc`mO(*fPhuGz`>kT$=>y=b}#a|RoOUgt@*vk*8V-A-+5nOR=zb7P7 z?bb)BN$f31Ci58L7Ph4x`LaRc+BYw)0lascNltN0hy~f>n8BMVWz0{ z2}{q*7c
_5M@JcDqAyz0RoACd2Q%yx!l%ZI*~IYq`+8L^Xh&i)eC$Zyv++xn}0 z@#(`ZyE=@Co-Vwk_RFS=@%UkUF1jCORL62tO`5eaMM)OxrJ6+4J{g1!7TRdm4EvHO zFNNCDxNC?A63w_VcUoLzB5Nld3;XnatErPbn>h;@HY-1(7g)9qWS;79y)x?V8$DeB zVYB;yWkc4g2?A3icIfGs3iTA0ZYlC*%qG%RQ|h1J6sit;h+2CmBd>~g!Hc^My{SLB-bzA+`sH&hUs_d*V`Y6tDD&F%r(*$~{<& zffnv4^TfEXujv9O=>h^;HmN0dEfY;-?164T6sIc7#v_kTSo}1vLi_%h(OMTyj0Qnx z6OSiwum=HUCoT#?L$L@!q{<+ZGf_SZxxJxEh)}NDET%+{8_my*IVi{B4sXB!JF_Mhl^AxW%n@?I7<%tB*eZe?6vA% z{8@+m?QnOdB=7glJVwHxNgxM#R5N`AZ1)WkhJyWW_w+Nuqoe)@8osZo1|E`V&jzG7*kn=dTvg+4J&YUyIxgS-Aswm`G+N78E02<$7Liy^xFiRfQ?dCp8n*l;Q|-( zQNM9_88YL$BO{I*5*jj_fKx;B>b!H16JXjch7h6_*usY9^J7`dr$URqyR(4r_9?h+ z_?Nl89?Q65ne2Z9SOhV1lA0hFPCLRVlFGbw}pT z<5uo%Yeg#y2F9ALw)3n`BO+f0*K0i#MKZ>aq%)4bZL3Kz;9= z4L_ZjjSFMOO&bw8n(69pEI=oFj#%QRXY)pac(;Z@ybv~2=37zMGG&pO+AJe|s?hPf zEVSiKW*OSFG0|$DfZODZ#>KqKcaIn00*uk<24!y_d`664yzDwxMcwD&XG})6$sCg1E`pTfQ?VMJqehXX z6)<+U?@Ejw9uP?19#jURJlZ`_0&1kD+(aET! zb+PNzTJ1Z!pRRN`R%MjC8OvuVxJY#Fv!gktuQ$0BFo@mzg)*hBS+MXN0a7Ne_E zoDw&srZkBcnIgi*=f+YB^Hdi;lf�n$D2q#UC*S2dlsX7xdxaRXh03)Na4ql`!)% zgvLb(r}Ti0$Eg%A)~+@@KGTj6;%tI$*?_OY2Bi(6{u7}d#l4k}^JD=h zy)y9jaIf9QF;n!sQ7m_97em6P_+XTNcukClMG-gY?nu4>>9p_YvEofef7CSJF9DPm zn5{-$mpKokM+Gc<4P8>#MyM($m zNM;z}!euj+AWs)AJCCza9vnCi9v&MRggjr+{t(BgkyVM@u3PK_K#Nl|ur_%h%li2Z zMbDy^tLx58nY6yAV%DHIVYdz8?OQ~{+~*eT%t0JHTcsp>>bP&kcj!~X)sgufIm+(s3FK8oW6L6bcv%rIIRYT;z?@UVsZl3OQ+SpYaTCq#9SKD@i&o~3gN5+|;LBnh zY}X_^<;+>RVq&tbriULXqi4$`#Yz7S)aDn)kR8nOFI3zw+8yNcCm8F0fzpx?k&~7e zp%t(*)3=aT`iXD(jm|+~y+hjl1*OIMvycl4VfptcEht9jUnng$HZTALVuRwiSW)i2 zS)gD(7BD-s+Uz%K=3d_4P%}_$&b`+E4kn|}br|S>?f^>>a(H2~7DbbH5>0+mR@@6q z(ZtF*(u!{HNR8&+FY>{|TXW zzrw%f|F_%x_JN;1@e`r-4{!N52rV`?5EP*W1%9zGG2J1wSULVPLJNx8`x8P7S`YXq zgccYIX#9=Pl7i?PnOT{j+(82WKx+X&P>}9#v=$KfXSCM6@_XRePqY@a-(S&M_k>?| z|AE$G{iB}p7g~!03a0!ov06DId|Fn4m5^aXn_Gs#%~?WT(a_qlz=T>mv60K z?yZpcpw;aT@>FhemNw2)LwM9oUW!^FGQ~<-*wGc__}%spJ=Wslb9EDb#GBS1HVGf4 zUwIj>RhH2ATo`F@ESMN+>l3x29D+3oMPb%vt`7)ve0uM8?CTeY9-~e(8eewfTwwpf z4{tmvWej!shr%!RH}OdwrIzY2H8TkTa>aTd-DS|yN!!$zzxcdR0E-^REWeg5?}~jG z-KX39;3dk1vRI8?mB3JMw*4XJXMtBM#8NqBn?ojsr22z9Fzzl z;hC~Y_qz3in1NMYY;vJ+;yRuXotX?G%^z>$v;zIN(3RE40*-zN#J1*@er}VVa?iN_ zs@*^1HZ4pECm(sfEMmL(6d5sFUvc9Am3|$4rf+M2+)d;0xQ8QY=X#r5>$FFj`V}b5 z;UOwSc<@JANU^*^cuHr%c4GvaoX^vZkK7xs!cY0xLqULH)LS!&$~fOoy7P_I;#L3vF>G1u1Q-f`;~5TP7E3m)i$amhpo%D2iu#k?Qe> zSXLXzVTAZlH4w2EJg4+rh1*_}C!;%USZhtd>SBh#&9LjpB>_+N(XXtFBw+-{nE8`n z3=`_OMbzJ!Et5PjTPEToh_UzS64r3<`jXZ}#WbJ-=D~GkplQO)HIB@{PnCh#9|fMX zeXmQo#WJrzekH}$6`#G;)ZHp5JbP_M{N$ZccaMRpHL~vbcBZRixNjoKgzbxlHI^{j zY;BhzIA`*7dUFCdykyID8nfOMwF~a^cvQ`&o=pIXi5}7F0&0bKA&3j9Wge#$4=M+g zYHh+Wlk`U%a<;qDU7E%WbGpB<+8$;-(3n_~4symI=}$HFHu@w(HX=>TSjL4pZjQMmrU7;f za#lw|tjkXyrCKk~1m5}b3J9W0r4A6VP2_6mAy5ymv-+F$5 zR{yh}jJq*HJ2SnHi`^)&<$;Q0W8q%igvw{m$jaVfdp8kOe>hn4{TONj3+T7#Uv&uo zS#+mH?VYrcu#Z4?s0Ow%rmC)&&AWl>sZ+B6vi$pT7vEGjJ>myFYCqc!QH*=?*g$V;CK1TAEf)OjF|%z)_dph8v1NH-{KPE9HNJaT%cqeIrLh=&us6{sATzg8mr69o(Gt4~&enENZ2i4;cUtdi(SK1WLrc18e3l{*Zx!ri|=-ZRX1NMa$;`#O0=2cti(?o1PLx+CZ#OpiI(G z?IMaQ&{yNH&UeuKyFcj5(Gps}|5E_;%kFnW7QoG6#14Y6F|$HI5D0|BfLWh~gVm7P zfQiXip9#pp!odt?=KvdW09iShSXo#>#w=_g2-tvw#lS${fQiEp#EZhH4B*yhVr2%g z16i5$*+GUzENq7C`i3lEAjE)`&Bzcc7y63-zkZ;jlmpNM|MXJ?E_M)O6ea)=i1NE5 zfDHtKF0e7+Cykj6bXRt9_W@Y_L1TitCDhgaN&^C+VCuiopwGcSX{=Bv_}}?}U}%u~ zt2|a92h?r;O1p3UmBtKY`FDDuqx~x%6Oiq0mvJxQw;gPEnE1cbpqt{q)4+GTwZHPQ z{<|@=GeHCJ-}pfPrZ1TNpL`s5r5%6m3uIyY#~c8m!SA1Zz<=_wg8yMJ5CjF@|4j#o z<)32)vfov%{BK|@)}$Y literal 0 HcmV?d00001 diff --git a/e2e/suites/viewer/viewer-protected-file.test.ts b/e2e/suites/viewer/viewer-protected-file.test.ts new file mode 100755 index 0000000000..b6ecebd466 --- /dev/null +++ b/e2e/suites/viewer/viewer-protected-file.test.ts @@ -0,0 +1,119 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2019 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { LoginPage, BrowsingPage } from '../../pages/pages'; +import { FILES } from '../../configs'; +import { RepoClient } from '../../utilities/repo-client/repo-client'; +import { Utils } from '../../utilities/utils'; +import { Viewer } from '../../components/viewer/viewer'; +import { PasswordDialog } from './../../components/dialog/password-dialog'; + +describe('Viewer - password protected file', () => { + const username = `user-${Utils.random()}`; + + const parent = `parent-${Utils.random()}`; let parentId; + + const protectedFile = FILES.protectedFile; + + const apis = { + admin: new RepoClient(), + user: new RepoClient(username, username) + }; + + const loginPage = new LoginPage(); + const page = new BrowsingPage(); + const { dataTable } = page; + const viewer = new Viewer(); + const passwordDialog = new PasswordDialog(); + + beforeAll(async (done) => { + await apis.admin.people.createUser({ username }); + parentId = (await apis.user.nodes.createFolder(parent)).entry.id; + await apis.user.upload.uploadFile(protectedFile.name, parentId); + + await loginPage.loginWith(username); + done(); + }); + + beforeEach(async (done) => { + await page.header.expandSideNav(); + await page.clickPersonalFilesAndWait(); + await dataTable.doubleClickOnRowByName(parent); + await dataTable.waitForHeader(); + await dataTable.doubleClickOnRowByName(protectedFile.name); + await viewer.waitForViewerToOpen(); + await page.waitForDialog(); + done(); + }); + + afterEach(async (done) => { + if (await passwordDialog.isDialogOpen()) { + await passwordDialog.clickClose(); + } + await Utils.pressEscape(); + done(); + }); + + afterAll(async (done) => { + await apis.user.nodes.deleteNodeById(parentId); + done(); + }); + + it('Password dialog appears when opening a protected file - [C268958]', async () => { + expect(await passwordDialog.isDialogOpen()).toBe(true, 'Password dialog not open'); + expect(await passwordDialog.isPasswordInputDisplayed()).toBe(true, 'Password input not displayed'); + expect(await passwordDialog.isSubmitEnabled()).toBe(false, 'Submit button not disabled'); + expect(await passwordDialog.isCloseEnabled()).toBe(true, 'Close button not enabled'); + expect(await viewer.isPdfViewerContentDisplayed()).toBe(false, 'file content is displayed'); + }); + + it('File content is displayed when entering the correct password - [C268959]', async () => { + await passwordDialog.enterPassword(protectedFile.password); + expect(await passwordDialog.isSubmitEnabled()).toBe(true, 'Submit button not enabled'); + + await passwordDialog.clickSubmit(); + await passwordDialog.waitForDialogToClose(); + + expect(await viewer.isPdfViewerContentDisplayed()).toBe(true, 'file content not displayed'); + }); + + it('Error appears when entering an incorrect password - [C268960]', async () => { + await passwordDialog.enterPassword('incorrect'); + expect(await passwordDialog.isSubmitEnabled()).toBe(true, 'Submit button not enabled'); + await passwordDialog.clickSubmit(); + + expect(await passwordDialog.getErrorMessage()).toBe('Password is wrong'); + expect(await viewer.isPdfViewerContentDisplayed()).toBe(false, 'file content is displayed'); + }); + + it('Refresh the page while Password dialog is open - [C268961]', async () => { + await passwordDialog.enterPassword(protectedFile.password); + await page.refresh(); + await viewer.waitForViewerToOpen(); + + expect(await viewer.isPdfViewerContentDisplayed()).toBe(false, 'file content is displayed'); + expect(await passwordDialog.isDialogOpen()).toBe(true, 'Password dialog not open'); + }); +}); From 802360db1768344582beee9c720760b0b4c9a8b5 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Sat, 13 Apr 2019 07:45:58 +0100 Subject: [PATCH 173/259] [ACA-2351] allow rules access user group membership (#1071) --- src/app/app.component.ts | 17 +++++++++++++---- src/app/store/actions/app.actions.ts | 4 ++-- src/app/store/reducers/app.reducer.ts | 9 ++++++--- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/app/app.component.ts b/src/app/app.component.ts index f2a9db21e1..f78f01bd7d 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -50,7 +50,7 @@ import { } from './store/states/app.state'; import { filter, takeUntil } from 'rxjs/operators'; import { ContentApiService } from './services/content-api.service'; -import { DiscoveryEntry } from '@alfresco/js-api'; +import { DiscoveryEntry, GroupsApi, Group } from '@alfresco/js-api'; import { AppService } from './services/app.service'; import { Subject } from 'rxjs'; @@ -129,7 +129,6 @@ export class AppComponent implements OnInit, OnDestroy { if (isReady) { this.loadRepositoryStatus(); this.loadUserProfile(); - // todo: load external auth-enabled plugins here } }); } @@ -149,9 +148,19 @@ export class AppComponent implements OnInit, OnDestroy { }); } - private loadUserProfile() { + private async loadUserProfile() { + const groupsApi = new GroupsApi(this.alfrescoApiService.getInstance()); + const paging = await groupsApi.listGroupMembershipsForPerson('-me-'); + const groups: Group[] = []; + + if (paging && paging.list && paging.list.entries) { + groups.push(...paging.list.entries.map(obj => obj.entry)); + } + this.contentApi.getPerson('-me-').subscribe(person => { - this.store.dispatch(new SetUserProfileAction(person.entry)); + this.store.dispatch( + new SetUserProfileAction({ person: person.entry, groups }) + ); }); } diff --git a/src/app/store/actions/app.actions.ts b/src/app/store/actions/app.actions.ts index f11c4eb76a..a45dafa25a 100644 --- a/src/app/store/actions/app.actions.ts +++ b/src/app/store/actions/app.actions.ts @@ -24,7 +24,7 @@ */ import { Action } from '@ngrx/store'; -import { Node, Person } from '@alfresco/js-api'; +import { Node, Person, Group } from '@alfresco/js-api'; import { AppState } from '../states'; export const SET_INITIAL_STATE = 'SET_INITIAL_STATE'; @@ -59,7 +59,7 @@ export class SetCurrentUrlAction implements Action { export class SetUserProfileAction implements Action { readonly type = SET_USER_PROFILE; - constructor(public payload: Person) {} + constructor(public payload: { person: Person; groups: Group[] }) {} } export class ToggleInfoDrawerAction implements Action { diff --git a/src/app/store/reducers/app.reducer.ts b/src/app/store/reducers/app.reducer.ts index 7bbcdfb244..4f376f50cc 100644 --- a/src/app/store/reducers/app.reducer.ts +++ b/src/app/store/reducers/app.reducer.ts @@ -131,7 +131,8 @@ function updateLanguagePicker( function updateUser(state: AppState, action: SetUserProfileAction): AppState { const newState = Object.assign({}, state); - const user = action.payload; + const user = action.payload.person; + const groups = [...(action.payload.groups || [])]; const id = user.id; const firstName = user.firstName || ''; @@ -142,13 +143,15 @@ function updateUser(state: AppState, action: SetUserProfileAction): AppState { const capabilities = (user).capabilities; const isAdmin = capabilities ? capabilities.isAdmin : true; - newState.user = { + // todo: remove + newState.user = { firstName, lastName, userName, initials, isAdmin, - id + id, + groups }; return newState; From 02fcf26aa4ec5eec591f6f78edd4909a69bc13c6 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Mon, 15 Apr 2019 11:21:47 +0100 Subject: [PATCH 174/259] update angular core libs --- package-lock.json | 70 +++++++++++++++++++++++------------------------ package.json | 22 +++++++-------- 2 files changed, 46 insertions(+), 46 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6ead01c2bc..142ab50919 100644 --- a/package-lock.json +++ b/package-lock.json @@ -352,9 +352,9 @@ } }, "@angular/animations": { - "version": "7.2.12", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-7.2.12.tgz", - "integrity": "sha512-J7d9hYXNqNz2kVxKEZlAAn4iojjF63WfGenEnMCtFgXU26ok03EAiR+VaiIqIvcevxvvR+iDrCHb+Hub0C212w==", + "version": "7.2.13", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-7.2.13.tgz", + "integrity": "sha512-Z0g0DthJnxTZ0dUc5BlojMq/0XIikhWzTqq0ym8w3G6jqBJD0OJ0jRCIfV0Leqlgzq6Jzvdrx0/JngBiKi5+uA==", "requires": { "tslib": "^1.9.0" } @@ -436,25 +436,25 @@ } }, "@angular/common": { - "version": "7.2.12", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-7.2.12.tgz", - "integrity": "sha512-JzcysRDfx2dvvcZ4uwgn+6gFDYlbH9j2Uyz6fWOSinAA0kcleOu/Gb77XbCI5M3Xvh1hxHVyz0Zxv/Pi0Y1O1g==", + "version": "7.2.13", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-7.2.13.tgz", + "integrity": "sha512-NYlzUkFVgjLg9VB6/lkd8ZV0ZezSiv9vlg+26wOyw7x+gahRrm5WMAGF7eBLrXoZPEaoOO0uhKWKo7oiA0aufA==", "requires": { "tslib": "^1.9.0" } }, "@angular/compiler": { - "version": "7.2.12", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-7.2.12.tgz", - "integrity": "sha512-B1N+/ECqIQz7PD2Zjb/21OOCmrXkl8DSXCBGNMXOSng+uYJM4dFPWkYkaAeHj8gcLDHvIPWlsapJ6JqyB3RPxA==", + "version": "7.2.13", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-7.2.13.tgz", + "integrity": "sha512-k0IvaozNIlrPKUNF3M/NXMb/jfHBCDO9uRYA6h+84FFY4Y9po40c7YXfsfUxGKwouTWyemaxy9iXlLEnd3ELSQ==", "requires": { "tslib": "^1.9.0" } }, "@angular/compiler-cli": { - "version": "7.2.12", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-7.2.12.tgz", - "integrity": "sha512-EXJuN9XuYjO9gwe5JWfatb64ljPjItZh5bd1MQtntMJONS4ntOtwiCd9RuNVK2ZXM7Co9PcvzE1qynB6tMseCw==", + "version": "7.2.13", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-7.2.13.tgz", + "integrity": "sha512-UpA6V+GCY9qKj5j6tvzun2DJNjqRKjCrQgJqD5BIf4FTAKjVgqOvh++d23tbdltdjXlbHqUVRgfeXltbO91fWg==", "dev": true, "requires": { "canonical-path": "1.0.0", @@ -536,7 +536,7 @@ }, "load-json-file": { "version": "2.0.0", - "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", "dev": true, "requires": { @@ -583,7 +583,7 @@ }, "pify": { "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true }, @@ -690,9 +690,9 @@ } }, "@angular/core": { - "version": "7.2.12", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-7.2.12.tgz", - "integrity": "sha512-E5BtJPL4Fz1xyGTsoE4LELoZ33x0S0lJ0iUKqLRFeKKYM/fJ8l8mVNSZ7LnURTwpcjCiHcCRMcaCfuXWj7Kqhw==", + "version": "7.2.13", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-7.2.13.tgz", + "integrity": "sha512-vHD69xxDDSQaE8KfHeY2STJSd3xgfsz3/meBCAnT+Bpq9LqxL8DuPlrkC0kyBa2vyj/BwPR3CJNTaQrZcszJ/w==", "requires": { "tslib": "^1.9.0" } @@ -706,25 +706,25 @@ } }, "@angular/forms": { - "version": "7.2.12", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-7.2.12.tgz", - "integrity": "sha512-gQU8663C9LOyuza87XDkEQ2HXbaLt3LY8X45swUNfe+BvpKNhF5ZwwY22d93wuzvm/vFrCTPK7949ImfUW0XnA==", + "version": "7.2.13", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-7.2.13.tgz", + "integrity": "sha512-dBz7kYa8XoCKxZ+3EvYt6CxHZhM9Qbn3uYkLMsPA+NC6GtIt/tmYn1kNn+YWgVWZtWLvYRaOtYiCuMUJaRNQQw==", "requires": { "tslib": "^1.9.0" } }, "@angular/http": { - "version": "7.2.12", - "resolved": "https://registry.npmjs.org/@angular/http/-/http-7.2.12.tgz", - "integrity": "sha512-cceU+SWIQFOL3gRKqm5SYHQM3VoKbXne2XQRSY2Fdoc3XsipOzTEvJQPLm5ZcTEXdmRFlfianDoDaWEIvGbXkw==", + "version": "7.2.13", + "resolved": "https://registry.npmjs.org/@angular/http/-/http-7.2.13.tgz", + "integrity": "sha512-MlaN7ugCLVH4B7hVasucbcdoSm3UzhP5JgGtcd9d9fQW0hzrn3FXQEZ75NJ/F0YYoGkr5ysAjpeknCjq/elTsg==", "requires": { "tslib": "^1.9.0" } }, "@angular/language-service": { - "version": "7.2.12", - "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-7.2.12.tgz", - "integrity": "sha512-dHHcAtCQ+ECoZa/bkm1diMZuxy/e+x2/qzClfKquO47EPqOIXYKCKZRqgGNHxdbUSRpmIEanfj/li4S7doCHZw==", + "version": "7.2.13", + "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-7.2.13.tgz", + "integrity": "sha512-1bNWJpwH9wB0JybkbjdQp9J4bGmGxJX6BG7Mz3188Wc4J+aNy696Gc6IaJs7tFK8VXAdJrTJ5jGr9Oiu+ATe8w==", "dev": true }, "@angular/material": { @@ -744,25 +744,25 @@ } }, "@angular/platform-browser": { - "version": "7.2.12", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-7.2.12.tgz", - "integrity": "sha512-rhKxUtWM6LfM0cK0kVzQpdnzfGeL3KImk6kNn+RrZiXLk2N/pnwbrzfd6VUtm+zdg54S4BO8ui1NahwIC/PSKw==", + "version": "7.2.13", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-7.2.13.tgz", + "integrity": "sha512-4n9De4sOwVoYHh6IGO2+UQIjABqGAXk4RdrEGpXqPBHCNO4sF43c2JsXbPTU4kjPVwTwposfLlKEOjTXfwxGow==", "requires": { "tslib": "^1.9.0" } }, "@angular/platform-browser-dynamic": { - "version": "7.2.12", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-7.2.12.tgz", - "integrity": "sha512-maKmjCTaS+jrXnor9qVJZfkWAKrt6neIlYrjvcr9v2YUqv9vdMcd5WRaODvIXBqwh65gpMxk3hbZ48Yjh8EbBQ==", + "version": "7.2.13", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-7.2.13.tgz", + "integrity": "sha512-3+/BzrNLQ/Tn1hoPal3fvIeB3S/P3e00gHcH3oK+hfACYgWxLE1oIHL+w4NE2eTIJbHfphKhuascMaOH5WNlkg==", "requires": { "tslib": "^1.9.0" } }, "@angular/router": { - "version": "7.2.12", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-7.2.12.tgz", - "integrity": "sha512-n7EFKuOa6YDDvGZT/t7mXfQMuomkTVPJcWkpfPrViAKi4mcUnaU5IqYiBnv/WJfDDqocVD/Yf9YQD9zAajthEw==", + "version": "7.2.13", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-7.2.13.tgz", + "integrity": "sha512-pTdJT9TXk1A9YMa6C2zRRqLB4GPGMSik838P7n+yGrzhdybiudZU9T3egcxDRCWQMjsobVBRKLEUn405n3Hjgg==", "requires": { "tslib": "^1.9.0" } diff --git a/package.json b/package.json index dcc15e88c0..0c9426a0f7 100644 --- a/package.json +++ b/package.json @@ -40,19 +40,19 @@ "@alfresco/adf-core": "3.2.0-dac3bed09f5e8235868555c24102f91dcae9c6e1", "@alfresco/adf-extensions": "3.2.0-6ad63055b35b43eb305359b6f47851facd672476", "@alfresco/js-api": "3.1.0-2c7e78d49c51ba0966d4e6c4dedf2b64da83d630", - "@angular/animations": "7.2.12", + "@angular/animations": "7.2.13", "@angular/cdk": "^7.3.7", - "@angular/common": "7.2.12", - "@angular/compiler": "7.2.12", - "@angular/core": "7.2.12", + "@angular/common": "7.2.13", + "@angular/compiler": "7.2.13", + "@angular/core": "7.2.13", "@angular/flex-layout": "^7.0.0-beta.24", - "@angular/forms": "7.2.12", - "@angular/http": "7.2.12", + "@angular/forms": "7.2.13", + "@angular/http": "7.2.13", "@angular/material": "^7.3.7", "@angular/material-moment-adapter": "^7.3.7", - "@angular/platform-browser": "7.2.12", - "@angular/platform-browser-dynamic": "7.2.12", - "@angular/router": "7.2.12", + "@angular/platform-browser": "7.2.13", + "@angular/platform-browser-dynamic": "7.2.13", + "@angular/router": "7.2.13", "@mat-datetimepicker/core": "^3.0.0-beta.0", "@mat-datetimepicker/moment": "^3.0.0-beta.0", "@ngrx/effects": "^7.4.0", @@ -73,8 +73,8 @@ "@angular-devkit/build-angular": "~0.13.0", "@angular-devkit/build-ng-packagr": "~0.13.0", "@angular/cli": "^7.3.8", - "@angular/compiler-cli": "7.2.12", - "@angular/language-service": "7.2.12", + "@angular/compiler-cli": "7.2.13", + "@angular/language-service": "7.2.13", "@types/jasmine": "^2.5.53", "@types/jasminewd2": "^2.0.2", "@types/node": "9.3.0", From 3f4dd6d81e4a24a497bd433b900460cdbd297c2c Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Mon, 15 Apr 2019 20:58:58 +0100 Subject: [PATCH 175/259] add plint configuration file --- .github/plint.yml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .github/plint.yml diff --git a/.github/plint.yml b/.github/plint.yml new file mode 100644 index 0000000000..1a9de3c5c0 --- /dev/null +++ b/.github/plint.yml @@ -0,0 +1,2 @@ +modules: + - pr.prettier From 2a4be64bcc8ba5e258d70a8c3b3f4c7a3ff5058d Mon Sep 17 00:00:00 2001 From: Adina Parpalita Date: Tue, 16 Apr 2019 12:01:39 +0300 Subject: [PATCH 176/259] [ACA-823] refactoring (#1077) --- .travis.yml | 1 + .../context-menu-multiple-selection.test.ts | 0 .../context-menu-single-selection.test.ts | 0 ...cial-permissions-available-actions.test.ts | 0 .../toolbar-multiple-selection.test.ts | 0 .../toolbar-single-selection.test.ts | 0 e2e/suites/actions/copy.test.ts | 489 +++++++++--------- .../repo-client/apis/nodes/nodes-api.ts | 11 +- protractor.conf.js | 2 + 9 files changed, 271 insertions(+), 232 deletions(-) rename e2e/suites/{actions => actions-available}/context-menu-multiple-selection.test.ts (100%) rename e2e/suites/{actions => actions-available}/context-menu-single-selection.test.ts (100%) rename e2e/suites/{actions => actions-available}/special-permissions-available-actions.test.ts (100%) rename e2e/suites/{actions => actions-available}/toolbar-multiple-selection.test.ts (100%) rename e2e/suites/{actions => actions-available}/toolbar-single-selection.test.ts (100%) diff --git a/.travis.yml b/.travis.yml index 8c1953e933..ba313e7efe 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,6 +16,7 @@ env: - DEPLOYMENT=Nginx SUITES=navigation - DEPLOYMENT=Nginx SUITES=pagination - DEPLOYMENT=Nginx SUITES=search + - DEPLOYMENT=Nginx SUITES=actionsAvailable - DEPLOYMENT=Nginx SUITES=actions - DEPLOYMENT=Nginx SUITES=viewer - DEPLOYMENT=Nginx SUITES=infoDrawer diff --git a/e2e/suites/actions/context-menu-multiple-selection.test.ts b/e2e/suites/actions-available/context-menu-multiple-selection.test.ts similarity index 100% rename from e2e/suites/actions/context-menu-multiple-selection.test.ts rename to e2e/suites/actions-available/context-menu-multiple-selection.test.ts diff --git a/e2e/suites/actions/context-menu-single-selection.test.ts b/e2e/suites/actions-available/context-menu-single-selection.test.ts similarity index 100% rename from e2e/suites/actions/context-menu-single-selection.test.ts rename to e2e/suites/actions-available/context-menu-single-selection.test.ts diff --git a/e2e/suites/actions/special-permissions-available-actions.test.ts b/e2e/suites/actions-available/special-permissions-available-actions.test.ts similarity index 100% rename from e2e/suites/actions/special-permissions-available-actions.test.ts rename to e2e/suites/actions-available/special-permissions-available-actions.test.ts diff --git a/e2e/suites/actions/toolbar-multiple-selection.test.ts b/e2e/suites/actions-available/toolbar-multiple-selection.test.ts similarity index 100% rename from e2e/suites/actions/toolbar-multiple-selection.test.ts rename to e2e/suites/actions-available/toolbar-multiple-selection.test.ts diff --git a/e2e/suites/actions/toolbar-single-selection.test.ts b/e2e/suites/actions-available/toolbar-single-selection.test.ts similarity index 100% rename from e2e/suites/actions/toolbar-single-selection.test.ts rename to e2e/suites/actions-available/toolbar-single-selection.test.ts diff --git a/e2e/suites/actions/copy.test.ts b/e2e/suites/actions/copy.test.ts index 03b58ba0f4..aa1b0267d9 100755 --- a/e2e/suites/actions/copy.test.ts +++ b/e2e/suites/actions/copy.test.ts @@ -41,18 +41,31 @@ describe('Copy content', () => { const file1 = `file1-${Utils.random()}.txt`; let file1Id; const folder1 = `folder1-${Utils.random()}`; let folder1Id; - const folder2 = `folder2-${Utils.random()}`; let folder2Id; const fileInFolder = `fileInFolder-${Utils.random()}.txt`; let fileInFolderId; + + const folder2 = `folder2-${Utils.random()}`; let folder2Id; const fileInFolder2 = fileInFolder; + const folderExisting = `folder-existing-${Utils.random()}`; let folderExistingId; + const file1InFolderExisting = `file1InFolderExisting-${Utils.random()}.txt`; + const file2InFolderExisting = `file2InFolderExisting-${Utils.random()}.txt`; + const file2 = `file2-${Utils.random()}.txt`; let file2Id; const file3 = `file3-${Utils.random()}.txt`; let file3Id; const file4 = `file4-${Utils.random()}.txt`; let file4Id; - const existingFile = `existing-${Utils.random()}.txt`; let existingFileId; + const fileLocked1 = `file-locked1-${Utils.random()}.txt`; let fileLocked1Id; + + const folderWithLockedFiles = `folder-locked1-${Utils.random()}`; let folderWithLockedFilesId; + const fileLockedInFolder = `file-locked-${Utils.random()}`; let fileLockedInFolderId; + + const existingFile = `existing-${Utils.random()}.txt`; let existingFileToCopyId; + + const existingFolder = `existing-${Utils.random()}`; let existingFolderToCopyId; + + let existingIdPF, existingIdFav, existingIdSearch; + let folderExistingPFId, folderExistingFavId, folderExistingSearchId; - const existingFolder = `existing-${Utils.random()}`; - let existingId1, existingId2, existingId2RF, existingId2SF, existingId2Fav, existingId2Search; const file2InFolder = `file2InFolder-${Utils.random()}.txt`; const file3InFolder = `file3InFolder-${Utils.random()}.txt`; @@ -63,6 +76,8 @@ describe('Copy content', () => { const folderSiteFav = `folderSiteFav-${Utils.random()}`; const folderSiteSearch = `folderSiteSearch-${Utils.random()}`; + let locationId, destinationId; + const apis = { admin: new RepoClient(), user: new RepoClient(username, username) @@ -84,51 +99,80 @@ describe('Copy content', () => { destinationIdFav = (await apis.user.nodes.createFolder(destinationFav)).entry.id; destinationIdSearch = (await apis.user.nodes.createFolder(destinationSearch)).entry.id; - existingFileId = (await apis.user.nodes.createFile(existingFile, sourceId)).entry.id; - await apis.user.shared.shareFileById(existingFileId); - await apis.user.favorites.addFavoriteById('file', existingFileId); + existingFileToCopyId = (await apis.user.nodes.createFile(existingFile, sourceId)).entry.id; + await apis.user.shared.shareFileById(existingFileToCopyId); + await apis.user.favorites.addFavoriteById('file', existingFileToCopyId); + await apis.user.nodes.createFile(existingFile, destinationIdPF); await apis.user.nodes.createFile(existingFile, destinationIdRF); await apis.user.nodes.createFile(existingFile, destinationIdSF); await apis.user.nodes.createFile(existingFile, destinationIdFav); await apis.user.nodes.createFile(existingFile, destinationIdSearch); - existingId1 = (await apis.user.nodes.createFolder(existingFolder, sourceId)).entry.id; - existingId2 = (await apis.user.nodes.createFolder(existingFolder, destinationIdPF)).entry.id; - existingId2RF = (await apis.user.nodes.createFolder(existingFolder, destinationIdRF)).entry.id; - existingId2SF = (await apis.user.nodes.createFolder(existingFolder, destinationIdSF)).entry.id; - existingId2Fav = (await apis.user.nodes.createFolder(existingFolder, destinationIdFav)).entry.id; - existingId2Search = (await apis.user.nodes.createFolder(existingFolder, destinationIdSearch)).entry.id; - await apis.user.nodes.createFile(file2InFolder, existingId1); - await apis.user.nodes.createFile(file3InFolder, existingId2); - await apis.user.nodes.createFile(file3InFolder, existingId2RF); - await apis.user.nodes.createFile(file3InFolder, existingId2SF); - await apis.user.nodes.createFile(file3InFolder, existingId2Fav); - await apis.user.nodes.createFile(file3InFolder, existingId2Search); - await apis.user.favorites.addFavoriteById('folder', existingId1); + existingFolderToCopyId = (await apis.user.nodes.createFolder(existingFolder, sourceId)).entry.id; + + existingIdPF = (await apis.user.nodes.createFolder(existingFolder, destinationIdPF)).entry.id; + await apis.user.nodes.createFolder(existingFolder, destinationIdRF); + await apis.user.nodes.createFolder(existingFolder, destinationIdSF); + existingIdFav = (await apis.user.nodes.createFolder(existingFolder, destinationIdFav)).entry.id; + existingIdSearch = (await apis.user.nodes.createFolder(existingFolder, destinationIdSearch)).entry.id; + await apis.user.nodes.createFile(file2InFolder, existingFolderToCopyId); + + await apis.user.nodes.createFile(file3InFolder, existingIdPF); + await apis.user.nodes.createFile(file3InFolder, existingIdFav); + await apis.user.nodes.createFile(file3InFolder, existingIdSearch); + + await apis.user.favorites.addFavoriteById('folder', existingFolderToCopyId); folder1Id = (await apis.user.nodes.createFolder(folder1, sourceId)).entry.id; - folder2Id = (await apis.user.nodes.createFolder(folder2, sourceId)).entry.id; fileInFolderId = (await apis.user.nodes.createFile(fileInFolder, folder1Id)).entry.id; - await apis.user.favorites.addFavoriteById('file', fileInFolderId); await apis.user.favorites.addFavoriteById('folder', folder1Id); - await apis.user.favorites.addFavoriteById('folder', folder2Id); + await apis.user.favorites.addFavoriteById('file', fileInFolderId); + await apis.user.shared.shareFileById(fileInFolderId); + + folderExistingId = (await apis.user.nodes.createFolder(folderExisting, sourceId)).entry.id; + await apis.user.favorites.addFavoriteById('folder', folderExistingId); + await apis.user.nodes.createFile(file1InFolderExisting, folderExistingId); + + folderExistingPFId = (await apis.user.nodes.createFolder(folderExisting, destinationIdPF)).entry.id; + await apis.user.nodes.createFile(file2InFolderExisting, folderExistingPFId); + + folderExistingFavId = (await apis.user.nodes.createFolder(folderExisting, destinationIdFav)).entry.id; + await apis.user.nodes.createFile(file2InFolderExisting, folderExistingFavId); + + folderExistingSearchId = (await apis.user.nodes.createFolder(folderExisting, destinationIdSearch)).entry.id; + await apis.user.nodes.createFile(file2InFolderExisting, folderExistingSearchId); + folder2Id = (await apis.user.nodes.createFolder(folder2, sourceId)).entry.id; await apis.user.nodes.createFile(fileInFolder2, folder2Id); + await apis.user.favorites.addFavoriteById('folder', folder2Id); + + fileLocked1Id = (await apis.user.nodes.createFile(fileLocked1, sourceId)).entry.id; + await apis.user.nodes.lockFile(fileLocked1Id); + + folderWithLockedFilesId = (await apis.user.nodes.createFolder(folderWithLockedFiles, sourceId)).entry.id; + fileLockedInFolderId = (await apis.user.nodes.createFile(fileLockedInFolder, folderWithLockedFilesId)).entry.id; + await apis.user.nodes.lockFile(fileLockedInFolderId); + await apis.user.favorites.addFavoriteById('folder', folderWithLockedFilesId); file1Id = (await apis.user.nodes.createFile(file1, sourceId)).entry.id; file2Id = (await apis.user.nodes.createFile(file2, sourceId)).entry.id; file3Id = (await apis.user.nodes.createFile(file3, sourceId)).entry.id; file4Id = (await apis.user.nodes.createFile(file4, sourceId)).entry.id; + await apis.user.shared.shareFileById(file1Id); await apis.user.shared.shareFileById(file2Id); await apis.user.shared.shareFileById(file3Id); await apis.user.shared.shareFileById(file4Id); + await apis.user.shared.shareFileById(fileLocked1Id); + await apis.user.favorites.addFavoriteById('file', file1Id); await apis.user.favorites.addFavoriteById('file', file2Id); await apis.user.favorites.addFavoriteById('file', file3Id); await apis.user.favorites.addFavoriteById('file', file4Id); + await apis.user.favorites.addFavoriteById('file', fileLocked1Id); + await apis.user.sites.createSite(siteName); const docLibId = await apis.user.sites.getDocLibId(siteName); await apis.user.nodes.createFolder(folderSitePF, docLibId); @@ -137,8 +181,8 @@ describe('Copy content', () => { await apis.user.nodes.createFolder(folderSiteFav, docLibId); await apis.user.nodes.createFolder(folderSiteSearch, docLibId); - await apis.user.shared.waitForApi({ expect: 5 }); - await apis.user.favorites.waitForApi({ expect: 10 }); + await apis.user.shared.waitForApi({ expect: 7 }); + await apis.user.favorites.waitForApi({ expect: 13 }); await loginPage.loginWith(username); done(); @@ -157,22 +201,25 @@ describe('Copy content', () => { done(); }); - afterAll(async done => { + afterAll(async (done) => { await apis.user.nodes.deleteNodeById(destinationIdRF); done(); }); - it('Copy a file - [C280194]', async () => copyAFile(destinationRF, source)); + it('Copy a file - [C280194]', async () => copyFile(file1, source, destinationRF)); - it('Copy multiple items - [C280201]', async () => copyMultipleItems(destinationRF, source)); + it('Copy multiple items - [C280201]', async () => copyMultipleItems([file2, file3], source, destinationRF)); - it('Copy a file with a name that already exists on the destination - [C280196]', async () => copyAFileWithANameThatAlreadyExists(destinationRF, source)); + it('Copy a file with a name that already exists on the destination - [C280196]', async () => copyFileWithNameThatAlreadyExists(existingFile, source, destinationRF)); - it('Copy items into a library - [C291899]', async () => copyItemsIntoALibrary([file1], folderSiteRF, source)); + it('Copy items into a library - [C291899]', async () => copyItemsIntoLibrary([file1, file2], source, folderSiteRF)); - it('Copy locked file - [C280198]', async () => copyLockedFile(destinationRF, source)); + it('Copy locked file - [C280198]', async () => copyLockedFile(fileLocked1, source, destinationRF, () => { + locationId = sourceId; + destinationId = destinationIdRF; + })); - it('Undo copy of files - [C280202]', async () => undoCopyOfFiles(destinationRF)); + it('Undo copy of files - [C280202]', async () => undoCopyFile(file4, source, destinationRF)); }); @@ -184,34 +231,43 @@ describe('Copy content', () => { done(); }); - afterAll(async done => { + afterAll(async (done) => { await apis.user.nodes.deleteNodeById(destinationIdPF); done(); }); - it('Copy a file - [C217135]', async () => copyAFile(destinationPF)); + it('Copy a file - [C217135]', async () => copyFile(file1, '', destinationPF)); - it('Copy a folder with content - [C291888]', async () => copyAFolderWithContent(destinationPF)); + it('Copy a folder with content - [C291888]', async () => copyFolderWithContent(folder1, '', destinationPF)); - it('Copy multiple items - [C291889]', async () => copyMultipleItems(destinationPF)); + it('Copy multiple items - [C291889]', async () => copyMultipleItems([file2, file3], '', destinationPF)); - it('Copy a file with a name that already exists on the destination - [C217137]', async () => copyAFileWithANameThatAlreadyExists(destinationPF)); + it('Copy a file with a name that already exists on the destination - [C217137]', async () => copyFileWithNameThatAlreadyExists(existingFile, '', destinationPF)); - it('Copy a folder with a name that already exists on the destination - [C217138]', async () => copyAFileWithANameThatAlreadyExists(destinationPF)); + it('Copy a folder with a name that already exists on the destination - [C217138]', async () => copyFolderWithNameThatAlreadyExists(existingFolder, '', destinationPF)); - it('Copy items into a library - [C280282]', async () => copyItemsIntoALibrary([file1, folder1], folderSitePF)); + it('Copy items into a library - [C280282]', async () => copyItemsIntoLibrary([file1, folder1], '', folderSitePF)); - it('Copy locked file - [C217139]', async () => copyLockedFile(destinationPF)); + it('Copy locked file - [C217139]', async () => copyLockedFile(fileLocked1, '', destinationPF, () => { + locationId = sourceId; + destinationId = destinationIdPF; + })); - it('Copy folder that contains locked file - [C217140]', async () => copyFolderThatContainsLockedFile(destinationPF)); + it('Copy folder that contains locked file - [C217140]', async () => copyFolderThatContainsLockedFile(folderWithLockedFiles, '', destinationPF, () => { + locationId = folderWithLockedFilesId; + destinationId = destinationIdPF; + })); - it('Undo copy of files - [C217171]', async () => undoCopyOfFiles(destinationPF)); + it('Undo copy of files - [C217171]', async () => undoCopyFile(file4, '', destinationPF)); - it('Undo copy of folders - [C217172]', async () => undoCopyOfFolders(destinationPF)); + it('Undo copy of folders - [C217172]', async () => undoCopyFolder(folder2, '', destinationPF)); - it('Undo copy of a file when a file with same name already exists on the destination - [C217173]', async () => undoCopyOfAFile()); + it('Undo copy of a file when a file with same name already exists on the destination - [C217173]', async () => undoCopyFileWithExistingName(fileInFolder, '', folder2, async () => { + await dataTable.doubleClickOnRowByName(folder1); + await dataTable.waitForHeader(); + })); - it('Undo copy of a folder when a folder with same name already exists on the destination - [C217174]', async () => undoCopyOfAFolder()); + it('Undo copy of a folder when a folder with same name already exists on the destination - [C217174]', async () => undoCopyFolderWithExistingName(folderExisting, '', destinationPF)); }); @@ -222,22 +278,25 @@ describe('Copy content', () => { done(); }); - afterAll(async done => { + afterAll(async (done) => { await apis.user.nodes.deleteNodeById(destinationIdSF); done(); }); - it('Copy a file - [C280206]', async () => copyAFile(destinationSF)); + it('Copy a file - [C280206]', async () => copyFile(file1, source, destinationSF)); - it('Copy multiple items - [C280213]', async () => copyMultipleItems(destinationSF, source)); + it('Copy multiple items - [C280213]', async () => copyMultipleItems([file2, file3], source, destinationSF)); - it('Copy a file with a name that already exists on the destination - [C280208]', async () => copyAFileWithANameThatAlreadyExists(destinationSF)); + it('Copy a file with a name that already exists on the destination - [C280208]', async () => copyFileWithNameThatAlreadyExists(existingFile, source, destinationSF)); - it('Copy items into a library - [C291900]', async () => copyItemsIntoALibrary([file1], folderSiteSF, source)); + it('Copy items into a library - [C291900]', async () => copyItemsIntoLibrary([file1, file2], source, folderSiteSF)); - it('Copy locked file - [C280210]', async () => copyLockedFile(destinationSF)); + it('Copy locked file - [C280210]', async () => copyLockedFile(fileLocked1, source, destinationSF, () => { + locationId = sourceId; + destinationId = destinationIdSF; + })); - it('Undo copy of files - [C280214]', async () => undoCopyOfFiles(destinationSF)); + it('Undo copy of files - [C280214]', async () => undoCopyFile(file4, source, destinationSF)); }); @@ -248,34 +307,40 @@ describe('Copy content', () => { done(); }); - afterAll(async done => { + afterAll(async (done) => { await apis.user.nodes.deleteNodeById(destinationIdFav); done(); }); - it('Copy a file - [C280218]', async () => copyAFile(destinationFav)); + it('Copy a file - [C280218]', async () => copyFile(file1, source, destinationFav)); - it('Copy a folder with content - [C280219]', async () => copyAFolderWithContent(destinationFav, source)); + it('Copy a folder with content - [C280219]', async () => copyFolderWithContent(folder1, source, destinationFav)); - it('Copy multiple items - [C280225]', async () => copyMultipleItems(destinationFav)); + it('Copy multiple items - [C280225]', async () => copyMultipleItems([file2, file3], source, destinationFav)); - it('Copy a file with a name that already exists on the destination - [C280220]', async () => copyAFileWithANameThatAlreadyExists(destinationFav)); + it('Copy a file with a name that already exists on the destination - [C280220]', async () => copyFileWithNameThatAlreadyExists(existingFile, source, destinationFav)); - it('Copy a folder with a name that already exists on the destination - [C280221]', async () => copyAFolderWithANameThatAlreadyExists(destinationFav)); + it('Copy a folder with a name that already exists on the destination - [C280221]', async () => copyFolderWithNameThatAlreadyExists(existingFolder, source, destinationFav)); - it('Copy items into a library - [C291901]', async () => copyItemsIntoALibrary([file1, folder1], folderSiteFav, source)); + it('Copy items into a library - [C291901]', async () => copyItemsIntoLibrary([file1, folder1], source, folderSiteFav)); - it('Copy locked file - [C280222]', async () => copyLockedFile(destinationFav)); + it('Copy locked file - [C280222]', async () => copyLockedFile(fileLocked1, source, destinationFav, () => { + locationId = sourceId; + destinationId = destinationIdFav; + })); - it('Copy folder that contains locked file - [C280223]', async () => copyFolderThatContainsLockedFile(destinationFav, source)); + it('Copy folder that contains locked file - [C280223]', async () => copyFolderThatContainsLockedFile(folderWithLockedFiles, source, destinationFav, () => { + locationId = folderWithLockedFilesId; + destinationId = destinationIdFav; + })); - it('Undo copy of files - [C280226]', async () => undoCopyOfFiles(destinationFav)); + it('Undo copy of files - [C280226]', async () => undoCopyFile(file4, source, destinationFav)); - it('Undo copy of folders - [C280227]', async () => undoCopyOfFolders(destinationFav)); + it('Undo copy of folders - [C280227]', async () => undoCopyFolder(folder2, source, destinationFav)); - it('Undo copy of a file when a file with same name already exists on the destination - [C280228]', async () => undoCopyOfAFile(source)); + it('Undo copy of a file when a file with same name already exists on the destination - [C280228]', async () => undoCopyFileWithExistingName(fileInFolder, folder1, folder2)); - it('Undo copy of a folder when a folder with same name already exists on the destination - [C280229]', async () => undoCopyOfAFolder(source)); + it('Undo copy of a folder when a folder with same name already exists on the destination - [C280229]', async () => undoCopyFolderWithExistingName(folderExisting, source, destinationFav)); }); @@ -287,103 +352,81 @@ describe('Copy content', () => { done(); }); - afterAll(async done => { + afterAll(async (done) => { await apis.user.nodes.deleteNodeById(destinationIdSearch); done(); }); - it('Copy a file - [C306932]', async () => copyAFile(destinationSearch, source, async () => { - await searchInput.searchFor(file1); - await dataTable.waitForBody(); - }) - ); - - it('Copy a folder with content - [C306943]', async () => copyAFolderWithContent(destinationSearch, source, async () => { - await searchInput.searchFor(folder1); - await dataTable.waitForBody(); - }) - ); - - it('Copy multiple items - [C306944]', async () => copyMultipleItems(destinationSearch, source, async () => { - await searchInput.searchFor('file'); - await dataTable.waitForBody(); - }) - ); - - it('Copy a file with a name that already exists on the destination - [C306933]', async () => copyAFileWithANameThatAlreadyExists(destinationSearch, source, async () => { - await searchInput.searchFor(existingFile); - await dataTable.waitForBody(); - }) - ); - - it('Copy a folder with a name that already exists on the destination - [C306934]', async () => copyAFolderWithANameThatAlreadyExists(destinationSearch, source, async () => { - await searchInput.searchFor(existingFolder); - await dataTable.waitForBody(); - }) - ); - - it('Copy items into a library - [C306942]', async () => copyItemsIntoALibrary([file1, file2], folderSiteSearch, source, async () => { - await searchInput.searchFor('file'); - await dataTable.waitForBody(); - }) - ); - - it('Copy locked file - [C306935]', async () => copyLockedFile(destinationSearch, source, async () => { - await searchInput.searchFor(file1); - await dataTable.waitForBody(); - }) - ); - - it('Copy folder that contains locked file - [C306936]', async () => copyFolderThatContainsLockedFile(destinationSearch, source, async () => { - await searchInput.searchFor(folder1); - await dataTable.waitForBody(); - }) - ); - - it('Undo copy of files - [C306938]', async () => undoCopyOfFiles(destinationSearch, '', async () => { - await searchInput.searchFor('file'); - await dataTable.waitForBody(); - }) - ); - - it('Undo copy of folders - [C306939]', async () => undoCopyOfFolders(destinationSearch, source, async () => { - await searchInput.searchFor('folder'); - await dataTable.waitForBody(); - }) - ); - - it('Undo copy of a file when a file with same name already exists on the destination - [C306940]', async () => { + it('Copy a file - [C306932]', async () => copyFile(file1, source, destinationSearch, async () => { + await searchInput.searchFor(file1); + await dataTable.waitForBody(); + })); + + it('Copy a folder with content - [C306943]', async () => copyFolderWithContent(folder1, source, destinationSearch, async () => { + await searchInput.searchFor(folder1); + await dataTable.waitForBody(); + })); + + it('Copy multiple items - [C306944]', async () => copyMultipleItems([file2, file3], source, destinationSearch, async () => { + await searchInput.searchFor('file'); + await dataTable.waitForBody(); + })); + + it('Copy a file with a name that already exists on the destination - [C306933]', async () => copyFileWithNameThatAlreadyExists(existingFile, source, destinationSearch, async () => { await searchInput.searchFor(existingFile); await dataTable.waitForBody(); + })); + + it('Copy a folder with a name that already exists on the destination - [C306934]', async () => copyFolderWithNameThatAlreadyExists(existingFolder, source, destinationSearch, async () => { + await searchInput.searchFor(existingFolder); + await dataTable.waitForBody(); + })); - await dataTable.selectItem(existingFile, source); - await toolbar.clickMoreActionsCopy(); - await copyDialog.selectLocation('Personal Files'); - await copyDialog.selectDestination(destinationSearch); - await copyDialog.clickCopy(); - const msg = await page.getSnackBarMessage(); - expect(msg).toContain('Copied 1 item'); - expect(msg).toContain('Undo'); + it('Copy items into a library - [C306942]', async () => copyItemsIntoLibrary([file1, file2], source, folderSiteSearch, async () => { + await searchInput.searchFor('file'); + await dataTable.waitForBody(); + })); - await copyDialog.waitForDialogToClose(); - await page.clickPersonalFilesAndWait(); - await dataTable.doubleClickOnRowByName(destinationSearch); - expect(await dataTable.isItemPresent(existingFile)).toBe(true, `${existingFile} not present in destination folder`); - }); + it('Copy locked file - [C306935]', async () => copyLockedFile(fileLocked1, source, destinationSearch, async () => { + locationId = sourceId; + destinationId = destinationIdSearch; + await searchInput.searchFor(fileLocked1); + await dataTable.waitForBody(); + })); - it('Undo copy of a folder when a folder with same name already exists on the destination - [C306941]', async () => undoCopyOfAFolder(source, async () => { - await searchInput.searchFor(folder1); - await dataTable.waitForBody(); - }) - ); + it('Copy folder that contains locked file - [C306936]', async () => copyFolderThatContainsLockedFile(folderWithLockedFiles, source, destinationSearch, async () => { + locationId = folderWithLockedFilesId; + destinationId = destinationIdSearch; + await searchInput.searchFor(folderWithLockedFiles); + await dataTable.waitForBody(); + })); + it('Undo copy of files - [C306938]', async () => undoCopyFile(file4, source, destinationSearch, async () => { + await searchInput.searchFor(file4); + await dataTable.waitForBody(); + })); + + it('Undo copy of folders - [C306939]', async () => undoCopyFolder(folder2, source, destinationSearch, async () => { + await searchInput.searchFor(folder2); + await dataTable.waitForBody(); + })); + + it('Undo copy of a file when a file with same name already exists on the destination - [C306940]', async () => undoCopyFileWithExistingName(fileInFolder, folder1, folder2, async () => { + await searchInput.searchFor(fileInFolder); + await dataTable.waitForBody(); + })); + + it('Undo copy of a folder when a folder with same name already exists on the destination - [C306941]', async () => undoCopyFolderWithExistingName(folderExisting, source, destinationSearch, async () => { + await searchInput.searchFor(folderExisting); + await dataTable.waitForBody(); + })); }); - async function copyAFile(destination, location = '', doBefore = null) { + async function copyFile(fileName: string, location: string = '', destination: string, doBefore = null) { if (doBefore) { await doBefore(); } - await dataTable.selectItem(file1, location); + await dataTable.selectItem(fileName, location); await toolbar.clickMoreActionsCopy(); await copyDialog.selectLocation('Personal Files'); await copyDialog.selectDestination(destination); @@ -393,17 +436,17 @@ describe('Copy content', () => { expect(msg).toContain('Undo'); await copyDialog.waitForDialogToClose(); - expect(await dataTable.isItemPresent(file1)).toBe(true, `${file1} not present in source folder`); + expect(await dataTable.isItemPresent(fileName)).toBe(true, `${fileName} not present in source folder`); await page.clickPersonalFilesAndWait(); await dataTable.doubleClickOnRowByName(destination); - expect(await dataTable.isItemPresent(file1)).toBe(true, `${file1} not present in destination folder`); + expect(await dataTable.isItemPresent(fileName)).toBe(true, `${fileName} not present in ${destination} folder`); } - async function copyAFolderWithContent(destination, location = '', doBefore = null) { + async function copyFolderWithContent(folderName: string, location: string = '', destination: string, doBefore = null) { if (doBefore) { await doBefore(); } - await dataTable.selectItem(folder1, location); + await dataTable.selectItem(folderName, location); await toolbar.clickMoreActionsCopy(); await copyDialog.selectLocation('Personal Files'); await copyDialog.selectDestination(destination); @@ -413,21 +456,21 @@ describe('Copy content', () => { expect(msg).toContain('Undo'); await copyDialog.waitForDialogToClose(); - expect(await dataTable.isItemPresent(folder1)).toBe(true, `${folder1} not present in source folder`); + expect(await dataTable.isItemPresent(folderName)).toBe(true, `${folderName} not present in source folder`); await page.clickPersonalFilesAndWait(); await dataTable.doubleClickOnRowByName(destination); - expect(await dataTable.isItemPresent(folder1)).toBe(true, `${folder1} not present in destination folder`); - expect(await dataTable.isItemPresent(fileInFolder)).toBe(false, `${fileInFolder} is present in destination`); + expect(await dataTable.isItemPresent(folderName)).toBe(true, `${folderName} not present in ${destination} folder`); + expect(await dataTable.isItemPresent(fileInFolder)).toBe(false, `${fileInFolder} is present in ${destination}`); - await dataTable.doubleClickOnRowByName(folder1); - expect(await dataTable.isItemPresent(fileInFolder)).toBe(true, `${fileInFolder} is not present in parent folder`); + await dataTable.doubleClickOnRowByName(folderName); + expect(await dataTable.isItemPresent(fileInFolder)).toBe(true, `${fileInFolder} is not present in ${folderName} folder in ${destination}`); } - async function copyMultipleItems(destination, location = '', doBefore = null) { + async function copyMultipleItems(items: string[], location: string = '', destination: string, doBefore = null) { if (doBefore) { await doBefore(); } - await dataTable.selectMultipleItems([file2, file3], location); + await dataTable.selectMultipleItems(items, location); await toolbar.clickMoreActionsCopy(); await copyDialog.selectLocation('Personal Files'); await copyDialog.selectDestination(destination); @@ -437,19 +480,19 @@ describe('Copy content', () => { expect(msg).toContain('Undo'); await copyDialog.waitForDialogToClose(); - expect(await dataTable.isItemPresent(file2)).toBe(true, `${file2} not present in source folder`); - expect(await dataTable.isItemPresent(file3)).toBe(true, `${file3} not present in source folder`); + expect(await dataTable.isItemPresent(items[0])).toBe(true, `${items[0]} not present in source folder`); + expect(await dataTable.isItemPresent(items[1])).toBe(true, `${items[1]} not present in source folder`); await page.clickPersonalFilesAndWait(); await dataTable.doubleClickOnRowByName(destination); - expect(await dataTable.isItemPresent(file2)).toBe(true, `${file2} not present in destination folder`); - expect(await dataTable.isItemPresent(file3)).toBe(true, `${file3} not present in destination folder`); + expect(await dataTable.isItemPresent(items[0])).toBe(true, `${items[0]} not present in ${destination} folder`); + expect(await dataTable.isItemPresent(items[1])).toBe(true, `${items[1]} not present in ${destination} folder`); } - async function copyAFileWithANameThatAlreadyExists(destination, location = '', doBefore = null) { + async function copyFileWithNameThatAlreadyExists(fileName: string, location: string = '', destination: string, doBefore = null) { if (doBefore) { await doBefore(); } - await dataTable.selectItem(existingFile, location); + await dataTable.selectItem(fileName, location); await toolbar.clickMoreActionsCopy(); await copyDialog.selectLocation('Personal Files'); await copyDialog.selectDestination(destination); @@ -459,17 +502,17 @@ describe('Copy content', () => { expect(msg).toContain('Undo'); await copyDialog.waitForDialogToClose(); - expect(await dataTable.isItemPresent(existingFile)).toBe(true, `${existingFile}.txt not present in source folder`); + expect(await dataTable.isItemPresent(fileName)).toBe(true, `${fileName}.txt not present in source folder`); await page.clickPersonalFilesAndWait(); await dataTable.doubleClickOnRowByName(destination); - expect(await dataTable.isItemPresent(existingFile)).toBe(true, `${existingFile}.txt not present in destination folder`); + expect(await dataTable.isItemPresent(fileName)).toBe(true, `${fileName}.txt not present in ${destination} folder`); } - async function copyAFolderWithANameThatAlreadyExists(destination, location = '', doBefore = null) { + async function copyFolderWithNameThatAlreadyExists(folderName: string, location: string = '', destination: string, doBefore = null) { if (doBefore) { await doBefore(); } - await dataTable.selectItem(existingFolder, location); + await dataTable.selectItem(folderName, location); await toolbar.clickMoreActionsCopy(); await copyDialog.selectLocation('Personal Files'); await copyDialog.selectDestination(destination); @@ -479,19 +522,20 @@ describe('Copy content', () => { expect(msg).toContain('Undo'); await copyDialog.waitForDialogToClose(); - expect(await dataTable.isItemPresent(existingFolder)).toBe(true, `${existingFolder} not present in source folder`); + expect(await dataTable.isItemPresent(folderName)).toBe(true, `${folderName} not present in source folder`); await page.clickPersonalFilesAndWait(); await dataTable.doubleClickOnRowByName(destination); - expect(await dataTable.isItemPresent(existingFolder)).toBe(true, `${existingFolder} not present in destination folder`); - await dataTable.doubleClickOnRowByName(existingFolder); - expect(await dataTable.isItemPresent(file2InFolder)).toBe(true, `${file2InFolder} not present in destination folder`); - expect(await dataTable.isItemPresent(file3InFolder)).toBe(true, `${file3InFolder} not present in destination folder`); + expect(await dataTable.isItemPresent(folderName)).toBe(true, `${folderName} not present in ${destination} folder`); + await dataTable.doubleClickOnRowByName(folderName); + expect(await dataTable.isItemPresent(file2InFolder)).toBe(true, `${file2InFolder} not present in ${destination} folder in ${folderName}`); + expect(await dataTable.isItemPresent(file3InFolder)).toBe(true, `${file3InFolder} not present in ${destination} folder in ${folderName}`); } - async function copyItemsIntoALibrary(items, destination, location = '', doBefore = null) { + async function copyItemsIntoLibrary(items: string[], location: string = '', destination: string, doBefore = null) { if (doBefore) { await doBefore(); } + const noOfItems = items.length; await dataTable.selectMultipleItems(items, location); await toolbar.clickMoreActionsCopy(); await copyDialog.selectLocation('File Libraries'); @@ -500,11 +544,11 @@ describe('Copy content', () => { await copyDialog.selectDestination(destination); await copyDialog.clickCopy(); const msg = await page.getSnackBarMessage(); - expect(msg).toContain('Copied ' + items.length + ' item'); + expect(msg).toContain(`Copied ${noOfItems} ${ noOfItems === 1 ? 'item' : 'items'}`); expect(msg).toContain('Undo'); await copyDialog.waitForDialogToClose(); - for (const item of Object.keys(items)) { + for (const item of items) { expect(await dataTable.isItemPresent(item)).toBe(true, `${item} not present in source folder`); } @@ -512,18 +556,17 @@ describe('Copy content', () => { await dataTable.doubleClickOnRowByName(siteName); await dataTable.doubleClickOnRowByName(destination); - for (const item of Object.keys(items)) { - expect(await dataTable.isItemPresent(item)).toBe(true, `${item} not present in destination folder`); + for (const item of items) { + expect(await dataTable.isItemPresent(item)).toBe(true, `${item} not present in ${destination} folder`); } } - async function copyLockedFile(destination, location = '', doBefore = null) { + async function copyLockedFile(fileName: string, location: string = '', destination: string, doBefore = null) { if (doBefore) { await doBefore(); } - await apis.user.nodes.lockFile(file1Id); - await dataTable.selectItem(file1, location); + await dataTable.selectItem(fileName, location); await toolbar.clickMoreActionsCopy(); await copyDialog.selectLocation('Personal Files'); await copyDialog.selectDestination(destination); @@ -533,19 +576,20 @@ describe('Copy content', () => { expect(msg).toContain('Undo'); await copyDialog.waitForDialogToClose(); - expect(await dataTable.isItemPresent(file1)).toBe(true, `${file1} not present in source folder`); + expect(await dataTable.isItemPresent(fileName)).toBe(true, `${fileName} not present in source folder`); + expect(await apis.user.nodes.isFileLockedByName(fileName, locationId)).toBe(true, `${fileName} not locked in ${location}`); await page.clickPersonalFilesAndWait(); await dataTable.doubleClickOnRowByName(destination); - expect(await dataTable.isItemPresent(file1)).toBe(true, `${file1} not present in destination folder`); + expect(await dataTable.isItemPresent(fileName)).toBe(true, `${fileName} not present in ${destination} folder`); + expect(await apis.user.nodes.isFileLockedByName(fileName, destinationId)).toBe(false, `${fileName} is locked in ${destination}`); } - async function copyFolderThatContainsLockedFile(destination, location = '', doBefore = null) { + async function copyFolderThatContainsLockedFile(folderName: string, location: string = '', destination: string, doBefore = null) { if (doBefore) { await doBefore(); } - await apis.user.nodes.lockFile(fileInFolderId); - await dataTable.selectItem(folder1, location); + await dataTable.selectItem(folderName, location); await toolbar.clickMoreActionsCopy(); await copyDialog.selectLocation('Personal Files'); await copyDialog.selectDestination(destination); @@ -555,21 +599,23 @@ describe('Copy content', () => { expect(msg).toContain('Undo'); await copyDialog.waitForDialogToClose(); - expect(await dataTable.isItemPresent(folder1)).toBe(true, `${folder1} not present in source folder`); + expect(await dataTable.isItemPresent(folderName)).toBe(true, `${folderName} not present in source folder`); await page.clickPersonalFilesAndWait(); await dataTable.doubleClickOnRowByName(destination); - expect(await dataTable.isItemPresent(folder1)).toBe(true, `${folder1} not present in destination folder`); - expect(await dataTable.isItemPresent(fileInFolder)).toBe(false, `${fileInFolder} is present in destination`); + expect(await dataTable.isItemPresent(folderName)).toBe(true, `${folderName} not present in ${destination} folder`); + expect(await dataTable.isItemPresent(fileLockedInFolder)).toBe(false, `${fileLockedInFolder} is present in ${destination}`); + expect(await apis.user.nodes.isFileLockedByName(fileLockedInFolder, locationId)).toBe(true, `${fileLockedInFolder} not locked in ${location}`); - await dataTable.doubleClickOnRowByName(folder1); - expect(await dataTable.isItemPresent(fileInFolder)).toBe(true, `${fileInFolder} is not present in parent folder`); + await dataTable.doubleClickOnRowByName(folderName); + expect(await dataTable.isItemPresent(fileLockedInFolder)).toBe(true, `${fileLockedInFolder} is not present in ${folderName} folder from ${destination}`); + expect(await apis.user.nodes.isFileLockedByName(fileLockedInFolder, (await apis.user.nodes.getNodeIdFromParent(folderWithLockedFiles, destinationId)))).toBe(false, `${fileLockedInFolder} is locked in ${destination}`); } - async function undoCopyOfFiles(destination, location = '', doBefore = null) { + async function undoCopyFile(fileName: string, location: string = '', destination: string, doBefore = null) { if (doBefore) { await doBefore(); } - await dataTable.selectItem(file4, location); + await dataTable.selectItem(fileName, location); await toolbar.clickMoreActionsCopy(); await copyDialog.selectLocation('Personal Files'); await copyDialog.selectDestination(destination); @@ -580,20 +626,19 @@ describe('Copy content', () => { await page.clickSnackBarAction(); - expect(await dataTable.isItemPresent(file4)).toBe(true, `${file4} not present in source folder`); await page.clickPersonalFilesAndWait(); await dataTable.doubleClickOnRowByName(destination); - expect(await dataTable.isItemPresent(file4)).toBe(false, `${file4} present in destination folder`); + expect(await dataTable.isItemPresent(fileName)).toBe(false, `${fileName} present in ${destination} folder`); await page.clickTrash(); expect(await dataTable.isEmptyList()).toBe(true, 'Trash is not empty'); } - async function undoCopyOfFolders(destination, location = '', doBefore = null) { + async function undoCopyFolder(folderName: string, location: string = '', destination: string, doBefore = null) { if (doBefore) { await doBefore(); } - await dataTable.selectItem(folder2, location); + await dataTable.selectItem(folderName, location); await toolbar.clickMoreActionsCopy(); await copyDialog.selectLocation('Personal Files'); await copyDialog.selectDestination(destination); @@ -606,22 +651,22 @@ describe('Copy content', () => { await page.clickPersonalFilesAndWait(); await dataTable.doubleClickOnRowByName(destination); - expect(await dataTable.isItemPresent(folder2)).toBe(false, `${folder2} present in destination folder`); + expect(await dataTable.isItemPresent(folderName)).toBe(false, `${folderName} present in ${destination} folder`); await page.clickTrash(); expect(await dataTable.isEmptyList()).toBe(true, 'Trash is not empty'); } - async function undoCopyOfAFile(location = '', doBefore = null) { + async function undoCopyFileWithExistingName(fileName: string, location: string = '', destination: string, doBefore = null) { if (doBefore) { await doBefore(); } - await dataTable.doubleClickOnRowByName(folder1, location); - await dataTable.selectItem(fileInFolder); + + await dataTable.selectItem(fileName, location); await toolbar.clickMoreActionsCopy(); await copyDialog.selectLocation('Personal Files'); await copyDialog.doubleClickOnRow(source); - await copyDialog.selectDestination(folder2); + await copyDialog.selectDestination(destination); await copyDialog.clickCopy(); const msg = await page.getSnackBarMessage(); expect(msg).toContain('Copied 1 item'); @@ -629,41 +674,25 @@ describe('Copy content', () => { await page.clickSnackBarAction(); - expect(await dataTable.isItemPresent(fileInFolder)).toBe(true, `${fileInFolder} not present in source folder`); await page.clickPersonalFilesAndWait(); await dataTable.doubleClickOnRowByName(source); await dataTable.doubleClickOnRowByName(folder2); - expect(await dataTable.isItemPresent(fileInFolder2)).toBe(true, `${fileInFolder2} not present in destination folder`); - expect(await dataTable.isItemPresent(fileInFolder2 + '-1')).toBe(false, `${fileInFolder2}-1 present in destination folder`); + expect(await dataTable.isItemPresent(fileInFolder2)).toBe(true, `${fileInFolder2} not present in ${destination} folder`); + expect(await dataTable.isItemPresent(`${fileInFolder2}-1`)).toBe(false, `${fileInFolder2}-1 is present in ${destination} folder`); await page.clickTrash(); expect(await dataTable.isEmptyList()).toBe(true, 'Trash is not empty'); } - async function undoCopyOfAFolder(location = '', doBefore = null) { + async function undoCopyFolderWithExistingName(folderName: string, location: string = '', destination: string, doBefore = null) { if (doBefore) { await doBefore(); } - // create folder1/my-folder-x/file1-y.txt - const folderInFolder1 = `my-folder-${Utils.random()}`; let folderInFolder1Id; - folderInFolder1Id = (await apis.user.nodes.createFolder(folderInFolder1, folder1Id)).entry.id; - const fileInFolderInFolder1 = `f1-${Utils.random()}.txt`; - await apis.user.nodes.createFile(fileInFolderInFolder1, folderInFolder1Id); - - // create folder2/my-folder-x/file2-y.txt - const f2 = `f2-${Utils.random()}`; let f2Id; - f2Id = (await apis.user.nodes.createFolder(f2, sourceId)).entry.id; - const folderInFolder2 = folderInFolder1; let folderInFolder2Id; - folderInFolder2Id = (await apis.user.nodes.createFolder(folderInFolder2, f2Id)).entry.id; - const fileInFolderInFolder2 = `f2-${Utils.random()}.txt`; - await apis.user.nodes.createFile(fileInFolderInFolder2, folderInFolder2Id); - - await dataTable.doubleClickOnRowByName(folder1, location); - await dataTable.selectItem(folderInFolder1); + + await dataTable.selectItem(folderName, location); await toolbar.clickMoreActionsCopy(); await copyDialog.selectLocation('Personal Files'); - await copyDialog.doubleClickOnRow(source); - await copyDialog.selectDestination(f2); + await copyDialog.doubleClickOnRow(destination); await copyDialog.clickCopy(); const msg = await page.getSnackBarMessage(); expect(msg).toContain('Copied 1 item'); @@ -671,14 +700,12 @@ describe('Copy content', () => { await page.clickSnackBarAction(); - expect(await dataTable.isItemPresent(fileInFolder)).toBe(true, `${fileInFolder} not present in source folder`); await page.clickPersonalFilesAndWait(); - await dataTable.doubleClickOnRowByName(source); - await dataTable.doubleClickOnRowByName(f2); - expect(await dataTable.isItemPresent(folderInFolder2)).toBe(true, `${folderInFolder2} not present in destination folder`); - await dataTable.doubleClickOnRowByName(folderInFolder2); - expect(await dataTable.isItemPresent(fileInFolderInFolder2)).toBe(true, `${fileInFolderInFolder2} not present in destination folder`); - expect(await dataTable.isItemPresent(fileInFolderInFolder1)).toBe(false, `${fileInFolderInFolder1} present in destination folder`); + await dataTable.doubleClickOnRowByName(destination); + expect(await dataTable.isItemPresent(folderName)).toBe(true, `${folderName} not present in ${destination} folder`); + await dataTable.doubleClickOnRowByName(folderName); + expect(await dataTable.isItemPresent(file2InFolderExisting)).toBe(true, `${file2InFolderExisting} not present in ${folderName} in ${destination} folder`); + expect(await dataTable.isItemPresent(file1InFolderExisting)).toBe(false, `${file1InFolderExisting} present in ${folderName} in ${destination} folder`); await page.clickTrash(); expect(await dataTable.isEmptyList()).toBe(true, 'Trash is not empty'); diff --git a/e2e/utilities/repo-client/apis/nodes/nodes-api.ts b/e2e/utilities/repo-client/apis/nodes/nodes-api.ts index d60bcd661c..db6b346eb1 100755 --- a/e2e/utilities/repo-client/apis/nodes/nodes-api.ts +++ b/e2e/utilities/repo-client/apis/nodes/nodes-api.ts @@ -45,6 +45,11 @@ export class NodesApi extends RepoApi { return await this.nodesApi.getNode(id); } + async getNodeIdFromParent(name: string, parentId: string) { + const children = (await this.getNodeChildren(parentId)).list.entries; + return children.find(elem => elem.entry.name === name).entry.id; + } + async getNodeDescription(name: string, parentId: string) { const children = (await this.getNodeChildren(parentId)).list.entries; return children.find(elem => elem.entry.name === name).entry.properties['cm:description']; @@ -245,7 +250,11 @@ export class NodesApi extends RepoApi { } async isFileLockedWrite(nodeId: string) { - await this.apiAuth(); return (await this.getLockType(nodeId)) === 'WRITE_LOCK'; } + + async isFileLockedByName(fileName: string, parentId: string) { + const id = await this.getNodeIdFromParent(fileName, parentId); + return await this.isFileLockedWrite(id); + } } diff --git a/protractor.conf.js b/protractor.conf.js index 67a32ef025..ad1a191232 100755 --- a/protractor.conf.js +++ b/protractor.conf.js @@ -43,6 +43,7 @@ exports.config = { './e2e/suites/navigation/*.test.ts', './e2e/suites/pagination/*.test.ts', './e2e/suites/search/*.test.ts', + './e2e/suites/actions-available/*.test.ts', './e2e/suites/actions/*.test.ts', './e2e/suites/viewer/*.test.ts', './e2e/suites/info-drawer/*.test.ts', @@ -56,6 +57,7 @@ exports.config = { navigation: './e2e/suites/navigation/*.test.ts', pagination: './e2e/suites/pagination/*.test.ts', search: './e2e/suites/search/*.test.ts', + actionsAvailable: './e2e/suites/actions-available/*.test.ts', actions: './e2e/suites/actions/*.test.ts', viewer: './e2e/suites/viewer/*.test.ts', infoDrawer: './e2e/suites/info-drawer/*.test.ts', From 380a5f0cb025d7cb5d99ff9b318e1ffd3f665a93 Mon Sep 17 00:00:00 2001 From: Martin Muller Date: Tue, 16 Apr 2019 12:08:17 +0100 Subject: [PATCH 177/259] Feature/ACA-1633 travis dist cache (#1074) * ACA-1633 add new test stage e2 * cache dist --- .travis.yml | 57 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 25 deletions(-) diff --git a/.travis.yml b/.travis.yml index ba313e7efe..d14ee485c8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,46 +8,53 @@ language: node_js node_js: - '10' -env: - matrix: - - DEPLOYMENT=Nginx SUITES=authentication - - DEPLOYMENT=Nginx SUITES=listViews - - DEPLOYMENT=Nginx SUITES=application - - DEPLOYMENT=Nginx SUITES=navigation - - DEPLOYMENT=Nginx SUITES=pagination - - DEPLOYMENT=Nginx SUITES=search - - DEPLOYMENT=Nginx SUITES=actionsAvailable - - DEPLOYMENT=Nginx SUITES=actions - - DEPLOYMENT=Nginx SUITES=viewer - - DEPLOYMENT=Nginx SUITES=infoDrawer - - DEPLOYMENT=Nginx SUITES=extensions - -before_script: - - sudo /etc/init.d/postgresql stop +cache: + directories: + - node_modules + - dist before_install: + - sudo /etc/init.d/postgresql stop - npm install -g npm@latest - export DISPLAY=:99.0 - sh -e /etc/init.d/xvfb start - sleep 3 -script: | - if [ "$DEPLOYMENT" == "Nginx" ]; then - npm run build.e2e && SUITE="--suite $SUITES" npm run e2e:docker - else - npm run build.tomcat.e2e && SUITE="--suite $SUITES" npm run docker.tomcat.e2e - fi - stages: - name: Quality and Unit tests + - name: e2e jobs: include: - stage: Quality and Unit tests name: 'Code quality checks' - script: - - npm run lint + script: npm run lint - name: 'Unit tests' script: - npm run test:ci - bash <(curl -s https://codecov.io/bash) -X gcov + - name: 'Prepare dist cache' + script: npm run build.e2e + - stage: e2e + name: Test Suite authentication + script: SUITE="--suite authentication" npm run e2e:docker + - name: Test Suite listViews + script: SUITE="--suite listViews" npm run e2e:docker + - name: Test Suite application + script: SUITE="--suite application" npm run e2e:docker + - name: Test Suite navigation + script: SUITE="--suite navigation" npm run e2e:docker + - name: Test Suite pagination + script: SUITE="--suite pagination" npm run e2e:docker + - name: Test Suite search + script: SUITE="--suite search" npm run e2e:docker + - name: Test Suite actionsAvailable + script: SUITE="--suite actionsAvailable" npm run e2e:docker + - name: Test Suite actions + script: SUITE="--suite actions" npm run e2e:docker + - name: Test Suite viewer + script: SUITE="--suite viewer" npm run e2e:docker + - name: Test Suite infoDrawer + script: SUITE="--suite infoDrawer" npm run e2e:docker + - name: Test Suite extensions + script: SUITE="--suite extensions" npm run e2e:docker From b2b234c3cb2dcd13d0d83fbca0c09ef887c00ae8 Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Wed, 17 Apr 2019 11:57:30 +0300 Subject: [PATCH 178/259] [ACA-2345] Metadata - edit button is not displayed for folders (#1078) * remove node type check * tests --- .../metadata-tab.component.spec.ts | 62 ++++++++++++++++++- .../metadata-tab/metadata-tab.component.ts | 2 +- 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/src/app/components/info-drawer/metadata-tab/metadata-tab.component.spec.ts b/src/app/components/info-drawer/metadata-tab/metadata-tab.component.spec.ts index 6e5b7d7143..4a11314387 100644 --- a/src/app/components/info-drawer/metadata-tab/metadata-tab.component.spec.ts +++ b/src/app/components/info-drawer/metadata-tab/metadata-tab.component.spec.ts @@ -24,9 +24,67 @@ */ import { MetadataTabComponent } from './metadata-tab.component'; +import { NodePermissionService } from '../../../services/node-permission.service'; +import { Node } from '@alfresco/js-api'; describe('MetadataTabComponent', () => { - it('should be defined', () => { - expect(MetadataTabComponent).toBeDefined(); + let nodePermissionService: NodePermissionService; + let component: MetadataTabComponent; + + beforeEach(() => { + nodePermissionService = new NodePermissionService(); + const appConfig = { config: { 'content-metadata': {} } }; + const extension = { contentMetadata: {} }; + + component = new MetadataTabComponent( + nodePermissionService, + extension, + appConfig + ); + }); + + describe('canUpdateNode()', () => { + it('should return true if node is not locked and has update permission', () => { + const node = { + isLocked: false, + allowableOperations: ['update'] + }; + + component.node = node; + expect(component.canUpdateNode).toBe(true); + }); + + it('should return false if node is locked', () => { + const node = { + isLocked: true, + allowableOperations: ['update'] + }; + + component.node = node; + expect(component.canUpdateNode).toBe(false); + }); + + it('should return false if node has no update permission', () => { + const node = { + isLocked: false, + allowableOperations: ['other'] + }; + + component.node = node; + expect(component.canUpdateNode).toBe(false); + }); + + it('should return false if node has read only property', () => { + const node = { + isLocked: false, + allowableOperations: ['update'], + properties: { + 'cm:lockType': 'WRITE_LOCK' + } + }; + + component.node = node; + expect(component.canUpdateNode).toBe(false); + }); }); }); diff --git a/src/app/components/info-drawer/metadata-tab/metadata-tab.component.ts b/src/app/components/info-drawer/metadata-tab/metadata-tab.component.ts index 8aafc76eea..1183249f01 100644 --- a/src/app/components/info-drawer/metadata-tab/metadata-tab.component.ts +++ b/src/app/components/info-drawer/metadata-tab/metadata-tab.component.ts @@ -65,7 +65,7 @@ export class MetadataTabComponent { } get canUpdateNode(): boolean { - if (this.node && this.node.isFile && !isLocked({ entry: this.node })) { + if (this.node && !isLocked({ entry: this.node })) { return this.permission.check(this.node, ['update']); } From 91eaa3c305dffc0ee5b259cba68f5bce498bdd71 Mon Sep 17 00:00:00 2001 From: Suzana Dirla Date: Wed, 17 Apr 2019 12:01:43 +0300 Subject: [PATCH 179/259] [ACA-2350] fix ellipsis on DL and the context-menu issue (#1070) * add adf-no-grow-cell & min-width on columns * [ACA-2350] fix ellipsis on DL and the context-menu issue - issues were caused by nested items with the same classname: 'adf-datatable-cell' * [ACA-2350] fix unit test * [ACA-2350] remove deprecated classname - mention 'adf-datatable-cell--text' example container class for elements that have context menu * [ACA-2350] small fixes on search-results display * [ACA-2350] fix location check * [ACA-2350] should clean-up code once [ADF-4401] issue is fixed * [ACA-2350] change e2e expect to check match * [plint] fix code formatting * [plint] fix code formatting --- .../search-results-files-folders.test.ts | 118 +++++++++++++----- .../location-link/location-link.component.ts | 9 +- .../context-menu/context-menu.directive.ts | 12 +- .../context-menu.directives.spec.ts | 3 +- .../name-column/name-column.component.scss | 4 +- .../name-column/name-column.component.ts | 2 +- .../search-results.component.scss | 1 + .../ui/overrides/adf-document-list.theme.scss | 57 ++++++--- src/assets/app.extensions.json | 36 ++++-- 9 files changed, 179 insertions(+), 63 deletions(-) diff --git a/e2e/suites/search/search-results-files-folders.test.ts b/e2e/suites/search/search-results-files-folders.test.ts index a1d2cd440c..db589b1970 100644 --- a/e2e/suites/search/search-results-files-folders.test.ts +++ b/e2e/suites/search/search-results-files-folders.test.ts @@ -31,14 +31,17 @@ import * as moment from 'moment'; describe('Search results - files and folders', () => { const username = `user-${Utils.random()}`; - const file = `test-file-${Utils.random()}.txt`; let fileId; + const file = `test-file-${Utils.random()}.txt`; + let fileId; const fileTitle = 'file title'; const fileDescription = 'file description'; /* cspell:disable-next-line */ - const fileRussian = `любимый-сайт-${Utils.random()}`; let fileRussianId; + const fileRussian = `любимый-сайт-${Utils.random()}`; + let fileRussianId; - const folder = `test-folder-${Utils.random()}`; let folderId; + const folder = `test-folder-${Utils.random()}`; + let folderId; const folderTitle = 'folder title'; const folderDescription = 'folder description'; @@ -54,12 +57,22 @@ describe('Search results - files and folders', () => { const { searchInput } = page.header; const { dataTable, breadcrumb } = page; - beforeAll(async (done) => { + beforeAll(async done => { await apis.admin.people.createUser({ username }); - fileId = (await apis.user.nodes.createFile(file, '-my-', fileTitle, fileDescription)).entry.id; + fileId = (await apis.user.nodes.createFile( + file, + '-my-', + fileTitle, + fileDescription + )).entry.id; await apis.user.nodes.editNodeContent(fileId, 'edited by user'); - folderId = (await apis.user.nodes.createFolder(folder, '-my-', folderTitle, folderDescription)).entry.id; + folderId = (await apis.user.nodes.createFolder( + folder, + '-my-', + folderTitle, + folderDescription + )).entry.id; fileRussianId = (await apis.user.nodes.createFile(fileRussian)).entry.id; await apis.user.sites.createSite(site); @@ -70,7 +83,7 @@ describe('Search results - files and folders', () => { done(); }); - afterAll(async (done) => { + afterAll(async done => { await Promise.all([ apis.user.nodes.deleteNodeById(fileId), apis.user.nodes.deleteNodeById(fileRussianId), @@ -80,7 +93,7 @@ describe('Search results - files and folders', () => { done(); }); - beforeEach(async (done) => { + beforeEach(async done => { await page.refresh(); done(); }); @@ -91,7 +104,9 @@ describe('Search results - files and folders', () => { await searchInput.searchFor('test-'); await dataTable.waitForBody(); - expect(await page.breadcrumb.getCurrentItemName()).toEqual('Search Results'); + expect(await page.breadcrumb.getCurrentItemName()).toEqual( + 'Search Results' + ); }); it('File information - [C279183]', async () => { @@ -101,19 +116,38 @@ describe('Search results - files and folders', () => { await dataTable.waitForBody(); const fileEntry = await apis.user.nodes.getNodeById(fileId); - const modifiedDate = moment(fileEntry.entry.modifiedAt).format("MMM D, YYYY, h:mm:ss A"); + const modifiedDate = moment(fileEntry.entry.modifiedAt).format( + 'MMM D, YYYY, h:mm:ss A' + ); const modifiedBy = fileEntry.entry.modifiedByUser.displayName; const size = fileEntry.entry.content.sizeInBytes; - expect(await dataTable.isItemPresent(file)).toBe(true, `${file} is not displayed`); - - expect(await dataTable.getRowCellsCount(file)).toEqual(2, 'incorrect number of columns'); - - expect(await dataTable.getSearchResultLinesCount(file)).toEqual(4, 'incorrect number of lines for search result'); - expect(await dataTable.getSearchResultNameAndTitle(file)).toBe(`${file} ( ${fileTitle} )`); - expect(await dataTable.getSearchResultDescription(file)).toBe(fileDescription); - expect(await dataTable.getSearchResultModified(file)).toBe(`Modified: ${modifiedDate} by ${modifiedBy} | Size: ${size} Bytes`); - expect(await dataTable.getSearchResultLocation(file)).toBe('Location: Personal Files'); + expect(await dataTable.isItemPresent(file)).toBe( + true, + `${file} is not displayed` + ); + + expect(await dataTable.getRowCellsCount(file)).toEqual( + 2, + 'incorrect number of columns' + ); + + expect(await dataTable.getSearchResultLinesCount(file)).toEqual( + 4, + 'incorrect number of lines for search result' + ); + expect(await dataTable.getSearchResultNameAndTitle(file)).toBe( + `${file} ( ${fileTitle} )` + ); + expect(await dataTable.getSearchResultDescription(file)).toBe( + fileDescription + ); + expect(await dataTable.getSearchResultModified(file)).toBe( + `Modified: ${modifiedDate} by ${modifiedBy} | Size: ${size} Bytes` + ); + expect(await dataTable.getSearchResultLocation(file)).toMatch( + /Location:\s+Personal Files/ + ); }); it('Folder information - [C306867]', async () => { @@ -123,18 +157,37 @@ describe('Search results - files and folders', () => { await dataTable.waitForBody(); const folderEntry = await apis.user.nodes.getNodeById(folderId); - const modifiedDate = moment(folderEntry.entry.modifiedAt).format("MMM D, YYYY, h:mm:ss A"); + const modifiedDate = moment(folderEntry.entry.modifiedAt).format( + 'MMM D, YYYY, h:mm:ss A' + ); const modifiedBy = folderEntry.entry.modifiedByUser.displayName; - expect(await dataTable.isItemPresent(folder)).toBe(true, `${folder} is not displayed`); - - expect(await dataTable.getRowCellsCount(folder)).toEqual(2, 'incorrect number of columns'); - - expect(await dataTable.getSearchResultLinesCount(folder)).toEqual(4, 'incorrect number of lines for search result'); - expect(await dataTable.getSearchResultNameAndTitle(folder)).toBe(`${folder} ( ${folderTitle} )`); - expect(await dataTable.getSearchResultDescription(folder)).toBe(folderDescription); - expect(await dataTable.getSearchResultModified(folder)).toBe(`Modified: ${modifiedDate} by ${modifiedBy}`); - expect(await dataTable.getSearchResultLocation(folder)).toBe('Location: Personal Files'); + expect(await dataTable.isItemPresent(folder)).toBe( + true, + `${folder} is not displayed` + ); + + expect(await dataTable.getRowCellsCount(folder)).toEqual( + 2, + 'incorrect number of columns' + ); + + expect(await dataTable.getSearchResultLinesCount(folder)).toEqual( + 4, + 'incorrect number of lines for search result' + ); + expect(await dataTable.getSearchResultNameAndTitle(folder)).toBe( + `${folder} ( ${folderTitle} )` + ); + expect(await dataTable.getSearchResultDescription(folder)).toBe( + folderDescription + ); + expect(await dataTable.getSearchResultModified(folder)).toBe( + `Modified: ${modifiedDate} by ${modifiedBy}` + ); + expect(await dataTable.getSearchResultLocation(folder)).toMatch( + /Location:\s+Personal Files/ + ); }); it('Search file with special characters - [C290029]', async () => { @@ -143,7 +196,10 @@ describe('Search results - files and folders', () => { await searchInput.searchFor(fileRussian); await dataTable.waitForBody(); - expect(await dataTable.isItemPresent(fileRussian)).toBe(true, `${fileRussian} is not displayed`); + expect(await dataTable.isItemPresent(fileRussian)).toBe( + true, + `${fileRussian} is not displayed` + ); }); it('Location column redirect - file in user Home - [C279177]', async () => { @@ -153,6 +209,6 @@ describe('Search results - files and folders', () => { await dataTable.waitForBody(); await dataTable.clickItemLocation(file); - expect(await breadcrumb.getAllItems()).toEqual([ 'Personal Files' ]); + expect(await breadcrumb.getAllItems()).toEqual(['Personal Files']); }); }); diff --git a/src/app/components/common/location-link/location-link.component.ts b/src/app/components/common/location-link/location-link.component.ts index 317f474d8a..0d4601d4e1 100644 --- a/src/app/components/common/location-link/location-link.component.ts +++ b/src/app/components/common/location-link/location-link.component.ts @@ -43,13 +43,18 @@ import { TranslationService } from '@alfresco/adf-core'; @Component({ selector: 'aca-location-link', template: ` - + {{ displayText | async | translate }} `, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, - host: { class: 'aca-location-link adf-location-cell' } + host: { class: 'aca-location-link adf-location-cell aca-column-content' } }) export class LocationLinkComponent implements OnInit { private _path: PathInfo; diff --git a/src/app/components/context-menu/context-menu.directive.ts b/src/app/components/context-menu/context-menu.directive.ts index dd1dbafbe8..53b580ee56 100644 --- a/src/app/components/context-menu/context-menu.directive.ts +++ b/src/app/components/context-menu/context-menu.directive.ts @@ -100,7 +100,8 @@ export class ContextActionsDirective implements OnInit, OnDestroy { } private getTarget(event: MouseEvent): Element { - return this.findAncestor(event.target, 'adf-datatable-cell'); + // change back to 'adf-datatable-cell' once the [ADF-4401] issue is fixed + return this.findAncestor(event.target, 'adf-datatable-cell--'); } private isSelected(target: Element): boolean { @@ -113,12 +114,15 @@ export class ContextActionsDirective implements OnInit, OnDestroy { ); } - private findAncestor(el: Element, className: string): Element { - if (el.classList.contains(className)) { + private findAncestor(el: Element, classNameString: string): Element { + if (el.classList.value.includes(classNameString)) { return el; } // tslint:disable-next-line:curly - while ((el = el.parentElement) && !el.classList.contains(className)); + while ( + (el = el.parentElement) && + !el.classList.value.includes(classNameString) + ); return el; } } diff --git a/src/app/components/context-menu/context-menu.directives.spec.ts b/src/app/components/context-menu/context-menu.directives.spec.ts index 57da3015ed..3add678bd0 100644 --- a/src/app/components/context-menu/context-menu.directives.spec.ts +++ b/src/app/components/context-menu/context-menu.directives.spec.ts @@ -45,7 +45,8 @@ describe('ContextActionsDirective', () => { it('should call service to render context menu', fakeAsync(() => { const el = document.createElement('div'); - el.className = 'adf-data-table-cell adf-datatable-cell adf-datatable-row'; + el.className = + 'adf-datatable-cell adf-datatable-cell--text adf-datatable-row'; const fragment = document.createDocumentFragment(); fragment.appendChild(el); diff --git a/src/app/components/dl-custom-components/name-column/name-column.component.scss b/src/app/components/dl-custom-components/name-column/name-column.component.scss index a4a19dd080..434e6cbf7f 100644 --- a/src/app/components/dl-custom-components/name-column/name-column.component.scss +++ b/src/app/components/dl-custom-components/name-column/name-column.component.scss @@ -1,8 +1,8 @@ .aca-name-column-container { aca-locked-by { position: absolute; - top: 35px; - left: 13px; + top: 17px; + left: 7px; display: flex; align-items: center; color: rgba(0, 0, 0, 0.54); diff --git a/src/app/components/dl-custom-components/name-column/name-column.component.ts b/src/app/components/dl-custom-components/name-column/name-column.component.ts index 8baf7719e0..5548e6eebe 100644 --- a/src/app/components/dl-custom-components/name-column/name-column.component.ts +++ b/src/app/components/dl-custom-components/name-column/name-column.component.ts @@ -36,7 +36,7 @@ import { isLocked } from '../../../utils/node.utils'; templateUrl: './name-column.component.html', styleUrls: ['name-column.component.scss'], encapsulation: ViewEncapsulation.None, - host: { class: 'adf-datatable-cell adf-datatable-link adf-name-column' } + host: { class: ' aca-column-content adf-datatable-link adf-name-column' } }) export class CustomNameColumnComponent extends NameColumnComponent implements OnInit, OnDestroy { diff --git a/src/app/components/search/search-results/search-results.component.scss b/src/app/components/search/search-results/search-results.component.scss index 271984e08e..a8f4c74306 100644 --- a/src/app/components/search/search-results/search-results.component.scss +++ b/src/app/components/search/search-results/search-results.component.scss @@ -31,6 +31,7 @@ .adf-search-filter { min-width: 260px; + max-width: 320px; padding: 5px; height: 100%; overflow: scroll; diff --git a/src/app/ui/overrides/adf-document-list.theme.scss b/src/app/ui/overrides/adf-document-list.theme.scss index 6f0717fea3..91d1f3eecf 100644 --- a/src/app/ui/overrides/adf-document-list.theme.scss +++ b/src/app/ui/overrides/adf-document-list.theme.scss @@ -15,23 +15,42 @@ .adf-datatable-list { border: none; - .adf-datatable-link { - &.adf-name-column, - &.adf-library-name-column { - color: $document-list-name-text-color; - - &:hover { - color: $document-list-selection-color; + .adf-datatable-cell-container { + .aca-column-content, + .adf-name-column, + .adf-library-name-column, + .adf-trashcan-name-column { + position: absolute; + max-width: calc(100% - 0px); + + // remove this style once the [ADF-4401] issue is fixed: + &.adf-datatable-cell { + .adf-datatable-cell-value { + position: static; + width: auto; + } } + } - .adf-datatable-cell-value { - position: static; - max-width: 35vw; + .adf-library-name-column { + // same as on top comment + &.adf-datatable-cell { + color: $document-list-name-text-color; + + &:hover { + color: $document-list-selection-color; + } } } } + .adf-datatable-cell-value { + display: block; + } + .adf-datatable-cell--image { + min-width: $document-list-thumbnail-width; + width: $document-list-thumbnail-width; max-width: $document-list-thumbnail-width; } } @@ -53,13 +72,18 @@ .adf-datatable-cell { padding: 0 2px; box-sizing: border-box; + min-width: 100px; - &:focus { - outline: none !important; + &.adf-no-grow-cell { + min-width: 120px; } - .adf-datatable-cell-value { - width: 100% !important; + &:first-child { + min-width: $document-list-thumbnail-width; + } + + &:focus { + outline: none !important; } } @@ -88,4 +112,9 @@ } } } + + .adf-search-results .adf-datatable .adf-datatable-cell { + padding-top: 12px; + padding-bottom: 12px; + } } diff --git a/src/assets/app.extensions.json b/src/assets/app.extensions.json index ebda8ffc42..e6e1962bd6 100644 --- a/src/assets/app.extensions.json +++ b/src/assets/app.extensions.json @@ -452,10 +452,10 @@ "icon": "history", "actions": { "click": "MANAGE_VERSIONS" - }, - "rules": { - "visible": "canManageFileVersions" - } + }, + "rules": { + "visible": "canManageFileVersions" + } }, { "id": "app.toolbar.permissions", @@ -1080,6 +1080,7 @@ "key": "content.sizeInBytes", "title": "APP.DOCUMENT_LIST.COLUMNS.SIZE", "type": "fileSize", + "class": "adf-no-grow-cell", "sortable": true, "desktopOnly": true }, @@ -1089,6 +1090,7 @@ "title": "APP.DOCUMENT_LIST.COLUMNS.MODIFIED_ON", "type": "date", "format": "timeAgo", + "class": "adf-ellipsis-cell adf-no-grow-cell", "sortable": true, "desktopOnly": true }, @@ -1097,7 +1099,7 @@ "key": "modifiedByUser.displayName", "title": "APP.DOCUMENT_LIST.COLUMNS.MODIFIED_BY", "type": "text", - "class": "adf-ellipsis-cell", + "class": "adf-ellipsis-cell adf-no-grow-cell", "sortable": true, "desktopOnly": true } @@ -1125,6 +1127,7 @@ "key": "role", "title": "APP.DOCUMENT_LIST.COLUMNS.ROLE", "type": "text", + "class": "adf-no-grow-cell", "sortable": true, "template": "app.columns.libraryRole", "desktopOnly": false @@ -1134,6 +1137,7 @@ "key": "visibility", "title": "APP.DOCUMENT_LIST.COLUMNS.VISIBILITY", "type": "text", + "class": "adf-no-grow-cell", "sortable": true, "template": "app.columns.libraryStatus", "desktopOnly": true @@ -1162,6 +1166,7 @@ "key": "role", "title": "APP.DOCUMENT_LIST.COLUMNS.ROLE", "type": "text", + "class": "adf-no-grow-cell", "sortable": true, "template": "app.columns.libraryRole", "desktopOnly": false @@ -1171,6 +1176,7 @@ "key": "visibility", "title": "APP.DOCUMENT_LIST.COLUMNS.VISIBILITY", "type": "text", + "class": "adf-no-grow-cell", "sortable": true, "template": "app.columns.libraryStatus", "desktopOnly": true @@ -1199,6 +1205,7 @@ "key": "path.name", "title": "APP.DOCUMENT_LIST.COLUMNS.LOCATION", "type": "text", + "class": "adf-ellipsis-cell adf-no-grow-cell", "sortable": true, "template": "app.columns.location", "desktopOnly": true @@ -1208,6 +1215,7 @@ "key": "content.sizeInBytes", "title": "APP.DOCUMENT_LIST.COLUMNS.SIZE", "type": "fileSize", + "class": "adf-no-grow-cell", "sortable": true, "desktopOnly": true }, @@ -1216,6 +1224,7 @@ "key": "modifiedAt", "title": "APP.DOCUMENT_LIST.COLUMNS.MODIFIED_ON", "type": "date", + "class": "adf-ellipsis-cell adf-no-grow-cell", "format": "timeAgo", "sortable": true, "desktopOnly": true @@ -1225,7 +1234,7 @@ "key": "modifiedByUser.displayName", "title": "APP.DOCUMENT_LIST.COLUMNS.MODIFIED_BY", "type": "text", - "class": "adf-ellipsis-cell", + "class": "adf-ellipsis-cell adf-no-grow-cell", "sortable": true, "desktopOnly": true }, @@ -1234,7 +1243,7 @@ "key": "sharedByUser.displayName", "title": "APP.DOCUMENT_LIST.COLUMNS.SHARED_BY", "type": "text", - "class": "adf-ellipsis-cell", + "class": "adf-ellipsis-cell adf-no-grow-cell", "sortable": true, "desktopOnly": true } @@ -1262,6 +1271,7 @@ "key": "path.name", "title": "APP.DOCUMENT_LIST.COLUMNS.LOCATION", "type": "text", + "class": "adf-ellipsis-cell adf-no-grow-cell", "sortable": true, "template": "app.columns.location", "desktopOnly": true @@ -1271,6 +1281,7 @@ "key": "content.sizeInBytes", "title": "APP.DOCUMENT_LIST.COLUMNS.SIZE", "type": "fileSize", + "class": "adf-no-grow-cell", "sortable": true, "desktopOnly": true }, @@ -1280,6 +1291,7 @@ "title": "APP.DOCUMENT_LIST.COLUMNS.MODIFIED_ON", "type": "date", "format": "timeAgo", + "class": "adf-ellipsis-cell adf-no-grow-cell", "sortable": true, "desktopOnly": true } @@ -1307,6 +1319,7 @@ "key": "path.name", "title": "APP.DOCUMENT_LIST.COLUMNS.LOCATION", "type": "text", + "class": "adf-ellipsis-cell adf-no-grow-cell", "sortable": true, "template": "app.columns.location", "desktopOnly": true @@ -1316,6 +1329,7 @@ "key": "sizeInBytes", "title": "APP.DOCUMENT_LIST.COLUMNS.SIZE", "type": "fileSize", + "class": "adf-no-grow-cell", "sortable": true, "desktopOnly": true }, @@ -1325,6 +1339,7 @@ "title": "APP.DOCUMENT_LIST.COLUMNS.MODIFIED_ON", "type": "date", "format": "timeAgo", + "class": "adf-ellipsis-cell adf-no-grow-cell", "sortable": true, "desktopOnly": true }, @@ -1333,7 +1348,7 @@ "key": "modifiedByUser.displayName", "title": "APP.DOCUMENT_LIST.COLUMNS.MODIFIED_BY", "type": "text", - "class": "adf-ellipsis-cell", + "class": "adf-ellipsis-cell adf-no-grow-cell", "sortable": true, "desktopOnly": true } @@ -1361,6 +1376,7 @@ "key": "path.name", "title": "APP.DOCUMENT_LIST.COLUMNS.LOCATION", "type": "text", + "class": "adf-ellipsis-cell adf-no-grow-cell", "sortable": true, "template": "app.columns.location", "desktopOnly": true @@ -1370,6 +1386,7 @@ "key": "content.sizeInBytes", "title": "APP.DOCUMENT_LIST.COLUMNS.SIZE", "type": "fileSize", + "class": "adf-no-grow-cell", "sortable": true, "desktopOnly": true }, @@ -1379,6 +1396,7 @@ "title": "APP.DOCUMENT_LIST.COLUMNS.DELETED_ON", "type": "date", "format": "timeAgo", + "class": "adf-ellipsis-cell adf-no-grow-cell", "sortable": true, "desktopOnly": true } @@ -1406,6 +1424,7 @@ "key": "role", "title": "APP.DOCUMENT_LIST.COLUMNS.ROLE", "type": "text", + "class": "adf-no-grow-cell", "sortable": true, "template": "app.columns.libraryRole", "desktopOnly": false @@ -1415,6 +1434,7 @@ "key": "visibility", "title": "APP.DOCUMENT_LIST.COLUMNS.VISIBILITY", "type": "text", + "class": "adf-no-grow-cell", "sortable": true, "template": "app.columns.libraryStatus", "desktopOnly": true From 1519008de25a8a508e60803f27d118245ec146f2 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Wed, 17 Apr 2019 16:15:59 +0100 Subject: [PATCH 180/259] update plint-bot settings --- .github/plint.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/plint.yml b/.github/plint.yml index 1a9de3c5c0..63c57da92a 100644 --- a/.github/plint.yml +++ b/.github/plint.yml @@ -1,2 +1,7 @@ modules: - pr.prettier + - pr.spellcheck + +spellcheck: + words: + - plint From 434ab8a655e5933b4954987e723835621dae4ddb Mon Sep 17 00:00:00 2001 From: Suzana Dirla Date: Wed, 17 Apr 2019 22:15:39 +0300 Subject: [PATCH 181/259] Update to latest ADF alpha (#1079) * update to latest ADF alpha version * better date column display - ellipsis fix * renaming to prepare to clean-up document-list scss overrides * fix ellipsis display & cells min-width * update to a more latest ADF alpha --- package-lock.json | 69 +++++++------------ package.json | 8 +-- .../location-link/location-link.component.ts | 4 +- .../name-column/name-column.component.ts | 4 +- src/app/ui/custom-theme.scss | 2 +- .../ui/overrides/adf-document-list.theme.scss | 26 ++++--- src/assets/app.extensions.json | 10 +-- 7 files changed, 57 insertions(+), 66 deletions(-) diff --git a/package-lock.json b/package-lock.json index 142ab50919..7ad193243c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,33 +5,33 @@ "requires": true, "dependencies": { "@alfresco/adf-content-services": { - "version": "3.2.0-6ad63055b35b43eb305359b6f47851facd672476", - "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-3.2.0-6ad63055b35b43eb305359b6f47851facd672476.tgz", - "integrity": "sha512-em9lmfsdco7q6nQrvBsnnyxZhxYFgqsjnrPUJkF30U20HVbLn9C0PQpqch24qoJGF//qMzvnIR+DmkeUmYntbA==", + "version": "3.2.0-bcdfcee39750ffcee85a78c6f099a5a8b6ece0c2", + "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-3.2.0-bcdfcee39750ffcee85a78c6f099a5a8b6ece0c2.tgz", + "integrity": "sha512-nOQtKpX32HV8FFgxdgN/ifwCGdnI7o1/8CeMGEE5bubekjghYRknJYwQyp1nA+NsiJJncoctL+q9PRqQ/Z4G4A==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/adf-core": { - "version": "3.2.0-dac3bed09f5e8235868555c24102f91dcae9c6e1", - "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-3.2.0-dac3bed09f5e8235868555c24102f91dcae9c6e1.tgz", - "integrity": "sha512-GwSkh42tUvTRjfnkZ8kJiuF8wB0C4137cm/JA11raT5mihrCzTBwH3GutmnWRZuxLXE4wwKRquTD5s0Bbh4K1w==", + "version": "3.2.0-bcdfcee39750ffcee85a78c6f099a5a8b6ece0c2", + "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-3.2.0-bcdfcee39750ffcee85a78c6f099a5a8b6ece0c2.tgz", + "integrity": "sha512-GRdiKRAH9PJUnmGWOvODms64NEXRMtkbcJ6W/6WujEupmL+/b+2cbDEBsUWHh88X4NScvGAA0R7A3opwiMFO/w==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/adf-extensions": { - "version": "3.2.0-6ad63055b35b43eb305359b6f47851facd672476", - "resolved": "https://registry.npmjs.org/@alfresco/adf-extensions/-/adf-extensions-3.2.0-6ad63055b35b43eb305359b6f47851facd672476.tgz", - "integrity": "sha512-YIFi8iZg8/2/e866a9KXb3sOlzbjd1MePp7L0bA2YLQE+gOw7Xka4e++ieZtLA6Oo7SWZt1l6wkdfscx+WS/cQ==", + "version": "3.2.0-bcdfcee39750ffcee85a78c6f099a5a8b6ece0c2", + "resolved": "https://registry.npmjs.org/@alfresco/adf-extensions/-/adf-extensions-3.2.0-bcdfcee39750ffcee85a78c6f099a5a8b6ece0c2.tgz", + "integrity": "sha512-JH42ew6qcrPWjQfhFKR/PYZ2efQOOMxIscfLUhBu9nT5D8wCShG0wvkqrSD3tPm9+CkOxDOSDIbuLxpn1Bhusw==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/js-api": { - "version": "3.1.0-2c7e78d49c51ba0966d4e6c4dedf2b64da83d630", - "resolved": "https://registry.npmjs.org/@alfresco/js-api/-/js-api-3.1.0-2c7e78d49c51ba0966d4e6c4dedf2b64da83d630.tgz", - "integrity": "sha512-7KNSCMq4/8Bluhm5DzdGRNg36H7ZE9Ei9s6JY1yWrYgGH/ObOCYnJKx4kyAetqFbktD+C/1LHCHyPsF+0qkZ2g==", + "version": "3.2.0-fa5916ff413131513c3e382d7f27dd9b4cfa0e7e", + "resolved": "https://registry.npmjs.org/@alfresco/js-api/-/js-api-3.2.0-fa5916ff413131513c3e382d7f27dd9b4cfa0e7e.tgz", + "integrity": "sha512-3fhNh0+jqDzO6JavRhhYhGr2RZTLwSFIDF+uY2mcGCLWEiI0t81kyv4cYhO1hOHayfwXd6cn6hB7GZIChKrCZw==", "requires": { "event-emitter": "0.3.4", "superagent": "3.8.2" @@ -536,7 +536,7 @@ }, "load-json-file": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", "dev": true, "requires": { @@ -583,7 +583,7 @@ }, "pify": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true }, @@ -4959,8 +4959,7 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "aproba": { "version": "1.2.0", @@ -4981,14 +4980,12 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -5003,20 +5000,17 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -5133,8 +5127,7 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -5146,7 +5139,6 @@ "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -5161,7 +5153,6 @@ "version": "3.0.4", "bundled": true, "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -5169,14 +5160,12 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -5195,7 +5184,6 @@ "version": "0.5.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -5276,8 +5264,7 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -5289,7 +5276,6 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -5375,8 +5361,7 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "safer-buffer": { "version": "2.1.2", @@ -5412,7 +5397,6 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -5432,7 +5416,6 @@ "version": "3.0.1", "bundled": true, "dev": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -5476,14 +5459,12 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true } } }, diff --git a/package.json b/package.json index 0c9426a0f7..820dc15bc2 100644 --- a/package.json +++ b/package.json @@ -36,10 +36,10 @@ }, "private": true, "dependencies": { - "@alfresco/adf-content-services": "3.2.0-6ad63055b35b43eb305359b6f47851facd672476", - "@alfresco/adf-core": "3.2.0-dac3bed09f5e8235868555c24102f91dcae9c6e1", - "@alfresco/adf-extensions": "3.2.0-6ad63055b35b43eb305359b6f47851facd672476", - "@alfresco/js-api": "3.1.0-2c7e78d49c51ba0966d4e6c4dedf2b64da83d630", + "@alfresco/adf-content-services": "3.2.0-bcdfcee39750ffcee85a78c6f099a5a8b6ece0c2", + "@alfresco/adf-core": "3.2.0-bcdfcee39750ffcee85a78c6f099a5a8b6ece0c2", + "@alfresco/adf-extensions": "3.2.0-bcdfcee39750ffcee85a78c6f099a5a8b6ece0c2", + "@alfresco/js-api": "3.2.0-fa5916ff413131513c3e382d7f27dd9b4cfa0e7e", "@angular/animations": "7.2.13", "@angular/cdk": "^7.3.7", "@angular/common": "7.2.13", diff --git a/src/app/components/common/location-link/location-link.component.ts b/src/app/components/common/location-link/location-link.component.ts index 0d4601d4e1..5e9839d95d 100644 --- a/src/app/components/common/location-link/location-link.component.ts +++ b/src/app/components/common/location-link/location-link.component.ts @@ -54,7 +54,9 @@ import { TranslationService } from '@alfresco/adf-core'; `, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, - host: { class: 'aca-location-link adf-location-cell aca-column-content' } + host: { + class: 'aca-location-link adf-location-cell adf-datatable-content-cell' + } }) export class LocationLinkComponent implements OnInit { private _path: PathInfo; diff --git a/src/app/components/dl-custom-components/name-column/name-column.component.ts b/src/app/components/dl-custom-components/name-column/name-column.component.ts index 5548e6eebe..6c24c8e9da 100644 --- a/src/app/components/dl-custom-components/name-column/name-column.component.ts +++ b/src/app/components/dl-custom-components/name-column/name-column.component.ts @@ -36,7 +36,9 @@ import { isLocked } from '../../../utils/node.utils'; templateUrl: './name-column.component.html', styleUrls: ['name-column.component.scss'], encapsulation: ViewEncapsulation.None, - host: { class: ' aca-column-content adf-datatable-link adf-name-column' } + host: { + class: ' adf-datatable-content-cell adf-datatable-link adf-name-column' + } }) export class CustomNameColumnComponent extends NameColumnComponent implements OnInit, OnDestroy { diff --git a/src/app/ui/custom-theme.scss b/src/app/ui/custom-theme.scss index 8d9c2b8e80..fd430f4027 100644 --- a/src/app/ui/custom-theme.scss +++ b/src/app/ui/custom-theme.scss @@ -95,7 +95,7 @@ $foreground: map-get($custom-theme, foreground); //Custom variables - ACA specific styling: $document-list-selection-color: mat-color($alfresco-ecm-blue, 500); $document-list-background: white; -$document-list-thumbnail-width: 35px; +$data-table-thumbnail-width: 35px; $adf-pagination--border: 1px solid mat-color($foreground, text, 0.07); $adf-pagination__empty--height: 0; diff --git a/src/app/ui/overrides/adf-document-list.theme.scss b/src/app/ui/overrides/adf-document-list.theme.scss index 91d1f3eecf..647b8b374d 100644 --- a/src/app/ui/overrides/adf-document-list.theme.scss +++ b/src/app/ui/overrides/adf-document-list.theme.scss @@ -10,19 +10,25 @@ $document-list-background: mat-color($background, background) !default; $document-list-text-color: mat-color($foreground, text, 0.54) !default; $document-list-name-text-color: mat-color($foreground, text) !default; - $document-list-thumbnail-width: 50px !default; + $data-table-thumbnail-width: 50px !default; .adf-datatable-list { border: none; .adf-datatable-cell-container { - .aca-column-content, + .adf-datatable-content-cell, .adf-name-column, .adf-library-name-column, - .adf-trashcan-name-column { + .adf-trashcan-name-column, + .adf-name-location-cell { position: absolute; max-width: calc(100% - 0px); + .adf-datatable-cell-value { + text-overflow: ellipsis; + overflow: hidden; + } + // remove this style once the [ADF-4401] issue is fixed: &.adf-datatable-cell { .adf-datatable-cell-value { @@ -49,9 +55,9 @@ } .adf-datatable-cell--image { - min-width: $document-list-thumbnail-width; - width: $document-list-thumbnail-width; - max-width: $document-list-thumbnail-width; + min-width: $data-table-thumbnail-width; + width: $data-table-thumbnail-width; + max-width: $data-table-thumbnail-width; } } @@ -72,14 +78,14 @@ .adf-datatable-cell { padding: 0 2px; box-sizing: border-box; - min-width: 100px; + min-width: 120px; - &.adf-no-grow-cell { - min-width: 120px; + &.adf-datatable-cell--fileSize { + min-width: 80px; } &:first-child { - min-width: $document-list-thumbnail-width; + min-width: $data-table-thumbnail-width; } &:focus { diff --git a/src/assets/app.extensions.json b/src/assets/app.extensions.json index e6e1962bd6..fddd265f9c 100644 --- a/src/assets/app.extensions.json +++ b/src/assets/app.extensions.json @@ -1090,7 +1090,7 @@ "title": "APP.DOCUMENT_LIST.COLUMNS.MODIFIED_ON", "type": "date", "format": "timeAgo", - "class": "adf-ellipsis-cell adf-no-grow-cell", + "class": "adf-ellipsis-cell", "sortable": true, "desktopOnly": true }, @@ -1224,7 +1224,7 @@ "key": "modifiedAt", "title": "APP.DOCUMENT_LIST.COLUMNS.MODIFIED_ON", "type": "date", - "class": "adf-ellipsis-cell adf-no-grow-cell", + "class": "adf-ellipsis-cell", "format": "timeAgo", "sortable": true, "desktopOnly": true @@ -1291,7 +1291,7 @@ "title": "APP.DOCUMENT_LIST.COLUMNS.MODIFIED_ON", "type": "date", "format": "timeAgo", - "class": "adf-ellipsis-cell adf-no-grow-cell", + "class": "adf-ellipsis-cell", "sortable": true, "desktopOnly": true } @@ -1339,7 +1339,7 @@ "title": "APP.DOCUMENT_LIST.COLUMNS.MODIFIED_ON", "type": "date", "format": "timeAgo", - "class": "adf-ellipsis-cell adf-no-grow-cell", + "class": "adf-ellipsis-cell", "sortable": true, "desktopOnly": true }, @@ -1396,7 +1396,7 @@ "title": "APP.DOCUMENT_LIST.COLUMNS.DELETED_ON", "type": "date", "format": "timeAgo", - "class": "adf-ellipsis-cell adf-no-grow-cell", + "class": "adf-ellipsis-cell", "sortable": true, "desktopOnly": true } From 5788d1e7c40699baebf19913b3fa7a2503db8e40 Mon Sep 17 00:00:00 2001 From: Suzana Dirla Date: Fri, 19 Apr 2019 10:19:12 +0300 Subject: [PATCH 182/259] Clean up css overrides (#1081) * fix height on search-libraries DL * [ACA-2141] deleted adf-info-drawer css overrides - already moved to ADF * [ACA-2151] deleted adf-version-manager css overrides - already moved to ADF * [ACA-2144] deleted adf-search-filter css overrides - already moved to ADF * [ACA-2145] deleted adf-search-sorting-picker css overrides - already moved to ADF * [ACA-2147] partial clean-up of adf-toolbar-theme css overrides - need to fix the colors schema to be able to remove it completely * [ACA-2149] deleted adf-upload-dialog-theme css overrides - already moved to ADF * [ACA-2146] clean-up of adf-sidenav-layout-theme css overrides - might need to make another change on ADF side for height value * [ACA-2150] deleted adf-upload-drag-area-theme css overrides - already moved to ADF * [ACA-2146] prepare to move to corresponding ADF component theme --- src/app/ui/custom-theme.scss | 25 +++--- .../ui/overrides/adf-document-list.theme.scss | 5 +- .../ui/overrides/adf-info-drawer.theme.scss | 42 --------- .../overrides/adf-layout-container.theme.scss | 10 +++ .../ui/overrides/adf-search-filter.theme.scss | 15 ---- .../adf-search-sorting-picker.theme.scss | 9 -- .../overrides/adf-sidenav-layout.theme.scss | 30 ------- src/app/ui/overrides/adf-toolbar.theme.scss | 28 +----- .../ui/overrides/adf-upload-dialog.theme.scss | 41 --------- .../overrides/adf-upload-drag-area.theme.scss | 90 ------------------- .../overrides/adf-version-manager.theme.scss | 19 ---- 11 files changed, 25 insertions(+), 289 deletions(-) delete mode 100644 src/app/ui/overrides/adf-info-drawer.theme.scss create mode 100644 src/app/ui/overrides/adf-layout-container.theme.scss delete mode 100644 src/app/ui/overrides/adf-search-filter.theme.scss delete mode 100644 src/app/ui/overrides/adf-search-sorting-picker.theme.scss delete mode 100644 src/app/ui/overrides/adf-sidenav-layout.theme.scss delete mode 100644 src/app/ui/overrides/adf-upload-dialog.theme.scss delete mode 100644 src/app/ui/overrides/adf-upload-drag-area.theme.scss delete mode 100644 src/app/ui/overrides/adf-version-manager.theme.scss diff --git a/src/app/ui/custom-theme.scss b/src/app/ui/custom-theme.scss index fd430f4027..097475f518 100644 --- a/src/app/ui/custom-theme.scss +++ b/src/app/ui/custom-theme.scss @@ -15,14 +15,8 @@ @import '../components/shared/content-node-share/content-node-share.dialog.scss'; @import './overrides/adf-toolbar.theme'; -@import './overrides/adf-search-filter.theme'; -@import './overrides/adf-info-drawer.theme'; -@import './overrides/adf-upload-dialog.theme'; -@import './overrides/adf-sidenav-layout.theme'; +@import 'overrides/adf-layout-container.theme'; @import './overrides/adf-document-list.theme'; -@import './overrides/adf-upload-drag-area.theme'; -@import './overrides/adf-search-sorting-picker.theme'; -@import './overrides/adf-version-manager.theme'; @import 'snackbar'; @@ -68,14 +62,8 @@ $custom-theme: mat-light-theme($custom-theme-primary, $custom-theme-accent); $foreground: map-get($custom-theme, foreground); @mixin custom-theme($theme) { - @include adf-toolbar-theme($theme); - @include adf-search-filter-theme($theme); - @include adf-info-drawer-theme($theme); - @include adf-sidenav-layout-theme($theme); + @include custom-adf-toolbar-theme($theme); @include adf-document-list-theme($theme); - @include adf-upload-drag-area-theme($theme); - @include adf-search-sorting-picker-theme($theme); - @include adf-version-manager-theme($theme); @include layout-theme($theme); @include aca-search-input-theme($theme); @@ -99,3 +87,12 @@ $data-table-thumbnail-width: 35px; $adf-pagination--border: 1px solid mat-color($foreground, text, 0.07); $adf-pagination__empty--height: 0; + +$adf-toolbar-single-row-height: 48px; +$adf-toolbar-padding: 14px; + +$adf-upload-dragging-color: unset; +$adf-upload-dragging-border: 1px solid #00bcd4; +$adf-upload-dragging-background: #e0f7fa; +$adf-upload-dragging-level1-color: unset; +$adf-upload-dragging-level1-border: none; diff --git a/src/app/ui/overrides/adf-document-list.theme.scss b/src/app/ui/overrides/adf-document-list.theme.scss index 647b8b374d..84225436a7 100644 --- a/src/app/ui/overrides/adf-document-list.theme.scss +++ b/src/app/ui/overrides/adf-document-list.theme.scss @@ -120,7 +120,8 @@ } .adf-search-results .adf-datatable .adf-datatable-cell { - padding-top: 12px; - padding-bottom: 12px; + padding-top: 9px; + padding-bottom: 9px; + min-height: auto; } } diff --git a/src/app/ui/overrides/adf-info-drawer.theme.scss b/src/app/ui/overrides/adf-info-drawer.theme.scss deleted file mode 100644 index 034300640c..0000000000 --- a/src/app/ui/overrides/adf-info-drawer.theme.scss +++ /dev/null @@ -1,42 +0,0 @@ -@import 'mixins'; - -@mixin adf-info-drawer-theme($theme) { - $foreground: map-get($theme, foreground); - $accent: map-get($theme, accent); - $icon-size: 48px; - - .adf-info-drawer { - @include flex-column; - - .adf-info-drawer-layout { - @include flex-column; - overflow: auto; - - .mat-tab-label { - // cannot move this color style to ADF, but: - // check if this is still needed after ADF upgrades @angular/material version to be > 7.1.0 - color: mat-color($accent); - } - - .adf-info-drawer-layout-content - .adf-info-drawer-tabs - .mat-tab-body-content { - .adf-manage-versions-empty, - .adf-manage-versions-no-permission { - margin: 24px; - color: mat-color($foreground, text, 0.54); - text-align: justify; - display: flex; - flex-direction: column; - - &-icon { - width: $icon-size; - height: $icon-size; - font-size: $icon-size; - margin: auto; - } - } - } - } - } -} diff --git a/src/app/ui/overrides/adf-layout-container.theme.scss b/src/app/ui/overrides/adf-layout-container.theme.scss new file mode 100644 index 0000000000..d40af3d35d --- /dev/null +++ b/src/app/ui/overrides/adf-layout-container.theme.scss @@ -0,0 +1,10 @@ +@mixin adf-layout-container-theme($theme) { + $adf-layout-container-height: 100% !default; + + adf-layout-container { + .mat-drawer-content > div, + .mat-drawer-content > div > div { + height: $adf-layout-container-height; + } + } +} diff --git a/src/app/ui/overrides/adf-search-filter.theme.scss b/src/app/ui/overrides/adf-search-filter.theme.scss deleted file mode 100644 index 0d0bf72aa3..0000000000 --- a/src/app/ui/overrides/adf-search-filter.theme.scss +++ /dev/null @@ -1,15 +0,0 @@ -@mixin adf-search-filter-theme($theme) { - $foreground: map-get($theme, foreground); - - .adf-search-filter { - .mat-expansion-panel-header-title { - font-size: 14px; - color: mat-color($foreground, text, 0.87); - } - - .mat-checkbox-label, - .mat-radio-label { - color: mat-color($foreground, text, 0.54); - } - } -} diff --git a/src/app/ui/overrides/adf-search-sorting-picker.theme.scss b/src/app/ui/overrides/adf-search-sorting-picker.theme.scss deleted file mode 100644 index 1f774c1381..0000000000 --- a/src/app/ui/overrides/adf-search-sorting-picker.theme.scss +++ /dev/null @@ -1,9 +0,0 @@ -@mixin adf-search-sorting-picker-theme($theme) { - $foreground: map-get($theme, foreground); - - .adf-search-sorting-picker { - .mat-icon-button { - color: mat-color($foreground, text, 0.54); - } - } -} diff --git a/src/app/ui/overrides/adf-sidenav-layout.theme.scss b/src/app/ui/overrides/adf-sidenav-layout.theme.scss deleted file mode 100644 index 2c4416cf7a..0000000000 --- a/src/app/ui/overrides/adf-sidenav-layout.theme.scss +++ /dev/null @@ -1,30 +0,0 @@ -@import 'mixins'; - -@mixin adf-sidenav-layout-theme($theme) { - adf-sidenav-layout { - @include flex-column; - - // TODO: move to ADF - @media screen and ($mat-xsmall) { - .mat-drawer { - width: calc(-50px + 100vw) !important; - max-width: 320px !important; - } - } - - .mat-drawer-content { - @include flex-column; - overflow: auto; - } - } - - .adf-sidenav-layout { - @include flex-column; - } - - .mat-drawer-content > div, - .mat-drawer-content > div > div { - @include flex-column; - overflow: auto; - } -} diff --git a/src/app/ui/overrides/adf-toolbar.theme.scss b/src/app/ui/overrides/adf-toolbar.theme.scss index 123ec34847..85e16b2142 100644 --- a/src/app/ui/overrides/adf-toolbar.theme.scss +++ b/src/app/ui/overrides/adf-toolbar.theme.scss @@ -1,31 +1,5 @@ -$adf-toolbar-single-row-height: 48px; -$adf-toolbar-padding: 14px; - -@mixin adf-toolbar-theme($theme) { - $foreground: map-get($theme, foreground); - - .adf-viewer { - .adf-toolbar { - .mat-toolbar { - color: mat-color($foreground, text, 0.54); - } - } - } - +@mixin custom-adf-toolbar-theme($theme) { .adf-toolbar { @include angular-material-theme($theme); - - .mat-toolbar-single-row { - padding: 0 $adf-toolbar-padding; - height: $adf-toolbar-single-row-height; - } - - &.adf-toolbar--inline { - .mat-toolbar { - background-color: inherit; - border: none !important; - padding: 0; - } - } } } diff --git a/src/app/ui/overrides/adf-upload-dialog.theme.scss b/src/app/ui/overrides/adf-upload-dialog.theme.scss deleted file mode 100644 index 7cdee1ebd8..0000000000 --- a/src/app/ui/overrides/adf-upload-dialog.theme.scss +++ /dev/null @@ -1,41 +0,0 @@ -@mixin adf-upload-dialog-theme($theme) { - $primary: map-get($theme, primary); - $accent: map-get($theme, accent); - $warn: map-get($theme, warn); - - .adf-upload-dialog { - z-index: 999; - } - - // todo: move to ADF 3.x.x - .adf-file-uploading-row { - &__group, - &__block { - min-width: 100px; - display: flex; - justify-content: flex-end; - } - } - - .adf-file-uploading-row { - &__status { - &--done { - color: mat-color($accent); - } - - &--error { - color: mat-color($warn); - } - } - - &__action { - &--cancel { - color: mat-color($warn); - } - - &--remove { - color: mat-color($warn); - } - } - } -} diff --git a/src/app/ui/overrides/adf-upload-drag-area.theme.scss b/src/app/ui/overrides/adf-upload-drag-area.theme.scss deleted file mode 100644 index 8b666b07d4..0000000000 --- a/src/app/ui/overrides/adf-upload-drag-area.theme.scss +++ /dev/null @@ -1,90 +0,0 @@ -@import 'mixins'; - -$adf-upload-dragging-color: unset !default; -$adf-upload-dragging-border: 1px solid #00bcd4 !default; -$adf-upload-dragging-background: #e0f7fa !default; -$adf-upload-dragging-level1-color: unset !default; -$adf-upload-dragging-level1-border: none !default; - -@mixin file-draggable__input-focus($text-color, $border) { - color: $text-color; - border: $border !important; - margin-left: 0 !important; -} - -@mixin adf-upload-drag-area-theme($theme) { - adf-upload-drag-area { - @include flex-column; - - .adf-upload-border { - @include flex-column; - vertical-align: unset; - text-align: unset; - width: 100%; - box-sizing: border-box; - } - - .adf-file-draggable__input-focus { - color: $adf-upload-dragging-color; - border: $adf-upload-dragging-border; - - adf-document-list { - background: $adf-upload-dragging-background; - adf-datatable > table { - background: inherit; - } - } - } - - .adf-upload__dragging { - background: $adf-upload-dragging-background; - color: $adf-upload-dragging-color; - } - - .adf-upload__dragging td { - border-top: $adf-upload-dragging-border !important; - border-bottom: $adf-upload-dragging-border !important; - - &:first-child { - border-left: $adf-upload-dragging-border !important; - } - - &:last-child { - border-right: $adf-upload-dragging-border !important; - } - } - - &:first-child { - & > div { - adf-upload-drag-area { - .adf-file-draggable__input-focus { - @include file-draggable__input-focus( - $adf-upload-dragging-color, - $adf-upload-dragging-border - ); - } - } - } - - .adf-upload-border { - vertical-align: inherit !important; - text-align: inherit !important; - } - - .adf-file-draggable__input-focus { - color: $adf-upload-dragging-level1-color !important; - border: $adf-upload-dragging-level1-border !important; - margin-left: 0 !important; - - adf-upload-drag-area { - & > div { - @include file-draggable__input-focus( - $adf-upload-dragging-color, - $adf-upload-dragging-border - ); - } - } - } - } - } -} diff --git a/src/app/ui/overrides/adf-version-manager.theme.scss b/src/app/ui/overrides/adf-version-manager.theme.scss deleted file mode 100644 index afedfb9e38..0000000000 --- a/src/app/ui/overrides/adf-version-manager.theme.scss +++ /dev/null @@ -1,19 +0,0 @@ -@mixin adf-version-manager-theme($theme) { - adf-version-manager { - .mat-list .mat-3-line { - height: auto !important; - width: 100% !important; - } - - .mat-list-item-content { - padding: 16px 0 !important; - } - - .adf-version-list-item-comment.mat-line { - height: 100%; - word-break: break-all; - white-space: unset !important; - overflow: unset !important; - } - } -} From 3f5e8815c36684b6326f18ccfc386c542b817c7c Mon Sep 17 00:00:00 2001 From: Suzana Dirla Date: Tue, 23 Apr 2019 14:57:48 +0300 Subject: [PATCH 183/259] Upgrade to latest ADF beta & UI fixes (#1082) * [ACA-2359] upgrade ADF to 3.2.0-beta7 version * [ACA-2359] revert temporary fix because no more nested 'adf-datatable-cell' items coming from ADF * [ACA-2359] remove no more needed styles related to [ADF-4401] issue * [ACA-2359] clean-up unneeded styles - coming from new ADF version * [ACA-2363] fix issue with text being visible underneath the info drawer * [ACA-2359] fix ellipsis on locked_by text * [ACA-2359] increase item select area * [ACA-2331] fix destination picker custom source title * [ACA-2331] fix destination picker column display * min-width for adf-no-grow-cell --- package-lock.json | 24 +++--- package.json | 8 +- .../context-menu/context-menu.directive.ts | 12 +-- .../name-column/name-column.component.scss | 12 ++- src/app/services/node-actions.service.ts | 8 +- .../ui/overrides/adf-document-list.theme.scss | 76 +++++++++---------- 6 files changed, 70 insertions(+), 70 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7ad193243c..4a8738dd2c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,33 +5,33 @@ "requires": true, "dependencies": { "@alfresco/adf-content-services": { - "version": "3.2.0-bcdfcee39750ffcee85a78c6f099a5a8b6ece0c2", - "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-3.2.0-bcdfcee39750ffcee85a78c6f099a5a8b6ece0c2.tgz", - "integrity": "sha512-nOQtKpX32HV8FFgxdgN/ifwCGdnI7o1/8CeMGEE5bubekjghYRknJYwQyp1nA+NsiJJncoctL+q9PRqQ/Z4G4A==", + "version": "3.2.0-beta7", + "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-3.2.0-beta7.tgz", + "integrity": "sha512-GQLAtCOB0Q4GY+0W2YFB8W5JWh519U0RTshpaqs9Bi9JbpbbfSR50+EA4M6w1AQLm9rWy/9LCeQ819CyOpMRpw==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/adf-core": { - "version": "3.2.0-bcdfcee39750ffcee85a78c6f099a5a8b6ece0c2", - "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-3.2.0-bcdfcee39750ffcee85a78c6f099a5a8b6ece0c2.tgz", - "integrity": "sha512-GRdiKRAH9PJUnmGWOvODms64NEXRMtkbcJ6W/6WujEupmL+/b+2cbDEBsUWHh88X4NScvGAA0R7A3opwiMFO/w==", + "version": "3.2.0-beta7", + "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-3.2.0-beta7.tgz", + "integrity": "sha512-hSSJCK+Rezur7CWQjeT0uihzSuq+3cUR/qQEVGehNVte0y/bw6ceJWW+00sKS6ICU0byQDDAjsOqPuEMshqchg==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/adf-extensions": { - "version": "3.2.0-bcdfcee39750ffcee85a78c6f099a5a8b6ece0c2", - "resolved": "https://registry.npmjs.org/@alfresco/adf-extensions/-/adf-extensions-3.2.0-bcdfcee39750ffcee85a78c6f099a5a8b6ece0c2.tgz", - "integrity": "sha512-JH42ew6qcrPWjQfhFKR/PYZ2efQOOMxIscfLUhBu9nT5D8wCShG0wvkqrSD3tPm9+CkOxDOSDIbuLxpn1Bhusw==", + "version": "3.2.0-beta7", + "resolved": "https://registry.npmjs.org/@alfresco/adf-extensions/-/adf-extensions-3.2.0-beta7.tgz", + "integrity": "sha512-2KxNnnCDXu619jV3eslX685j/CkZl2C+BfwEHNP7v5q9eCh4tJ4r5LALvRHnJ44BsRojvJrNG23VND/X4tS2Ng==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/js-api": { - "version": "3.2.0-fa5916ff413131513c3e382d7f27dd9b4cfa0e7e", - "resolved": "https://registry.npmjs.org/@alfresco/js-api/-/js-api-3.2.0-fa5916ff413131513c3e382d7f27dd9b4cfa0e7e.tgz", - "integrity": "sha512-3fhNh0+jqDzO6JavRhhYhGr2RZTLwSFIDF+uY2mcGCLWEiI0t81kyv4cYhO1hOHayfwXd6cn6hB7GZIChKrCZw==", + "version": "3.2.0-beta7", + "resolved": "https://registry.npmjs.org/@alfresco/js-api/-/js-api-3.2.0-beta7.tgz", + "integrity": "sha512-8vWkFdi7qeSBjtk4ogEwEO1ApemcXAckPcPKmWWb2thbCyuW4JhDNa7+csPezuxYgIrhrEk+awRXN+b4xVDmaw==", "requires": { "event-emitter": "0.3.4", "superagent": "3.8.2" diff --git a/package.json b/package.json index 820dc15bc2..cac2ba9387 100644 --- a/package.json +++ b/package.json @@ -36,10 +36,10 @@ }, "private": true, "dependencies": { - "@alfresco/adf-content-services": "3.2.0-bcdfcee39750ffcee85a78c6f099a5a8b6ece0c2", - "@alfresco/adf-core": "3.2.0-bcdfcee39750ffcee85a78c6f099a5a8b6ece0c2", - "@alfresco/adf-extensions": "3.2.0-bcdfcee39750ffcee85a78c6f099a5a8b6ece0c2", - "@alfresco/js-api": "3.2.0-fa5916ff413131513c3e382d7f27dd9b4cfa0e7e", + "@alfresco/adf-content-services": "3.2.0-beta7", + "@alfresco/adf-core": "3.2.0-beta7", + "@alfresco/adf-extensions": "3.2.0-beta7", + "@alfresco/js-api": "3.2.0-beta7", "@angular/animations": "7.2.13", "@angular/cdk": "^7.3.7", "@angular/common": "7.2.13", diff --git a/src/app/components/context-menu/context-menu.directive.ts b/src/app/components/context-menu/context-menu.directive.ts index 53b580ee56..dd1dbafbe8 100644 --- a/src/app/components/context-menu/context-menu.directive.ts +++ b/src/app/components/context-menu/context-menu.directive.ts @@ -100,8 +100,7 @@ export class ContextActionsDirective implements OnInit, OnDestroy { } private getTarget(event: MouseEvent): Element { - // change back to 'adf-datatable-cell' once the [ADF-4401] issue is fixed - return this.findAncestor(event.target, 'adf-datatable-cell--'); + return this.findAncestor(event.target, 'adf-datatable-cell'); } private isSelected(target: Element): boolean { @@ -114,15 +113,12 @@ export class ContextActionsDirective implements OnInit, OnDestroy { ); } - private findAncestor(el: Element, classNameString: string): Element { - if (el.classList.value.includes(classNameString)) { + private findAncestor(el: Element, className: string): Element { + if (el.classList.contains(className)) { return el; } // tslint:disable-next-line:curly - while ( - (el = el.parentElement) && - !el.classList.value.includes(classNameString) - ); + while ((el = el.parentElement) && !el.classList.contains(className)); return el; } } diff --git a/src/app/components/dl-custom-components/name-column/name-column.component.scss b/src/app/components/dl-custom-components/name-column/name-column.component.scss index 434e6cbf7f..c2e16905ed 100644 --- a/src/app/components/dl-custom-components/name-column/name-column.component.scss +++ b/src/app/components/dl-custom-components/name-column/name-column.component.scss @@ -1,15 +1,19 @@ .aca-name-column-container { aca-locked-by { - position: absolute; - top: 17px; - left: 7px; display: flex; align-items: center; color: rgba(0, 0, 0, 0.54); + max-width: 100%; + padding: 0 10px; + + .locked_by--name { + overflow: hidden; + text-overflow: ellipsis; + } } } .aca-custom-name-column { - display: flex; + display: block; align-items: center; } diff --git a/src/app/services/node-actions.service.ts b/src/app/services/node-actions.service.ts index 593787e0eb..f5a1a08a6c 100644 --- a/src/app/services/node-actions.service.ts +++ b/src/app/services/node-actions.service.ts @@ -233,13 +233,17 @@ export class NodeActionsService { { entry: { guid: '-my-', - title: 'APP.BROWSE.PERSONAL.SIDENAV_LINK.LABEL' + title: this.translation.instant( + 'APP.BROWSE.PERSONAL.SIDENAV_LINK.LABEL' + ) } }, { entry: { guid: '-mysites-', - title: 'APP.BROWSE.LIBRARIES.SIDENAV_LINK.LABEL' + title: this.translation.instant( + 'APP.BROWSE.LIBRARIES.SIDENAV_LINK.LABEL' + ) } } ] diff --git a/src/app/ui/overrides/adf-document-list.theme.scss b/src/app/ui/overrides/adf-document-list.theme.scss index 84225436a7..8b5bc7ed62 100644 --- a/src/app/ui/overrides/adf-document-list.theme.scss +++ b/src/app/ui/overrides/adf-document-list.theme.scss @@ -15,49 +15,23 @@ .adf-datatable-list { border: none; - .adf-datatable-cell-container { - .adf-datatable-content-cell, - .adf-name-column, - .adf-library-name-column, - .adf-trashcan-name-column, - .adf-name-location-cell { - position: absolute; - max-width: calc(100% - 0px); - - .adf-datatable-cell-value { - text-overflow: ellipsis; - overflow: hidden; - } - - // remove this style once the [ADF-4401] issue is fixed: - &.adf-datatable-cell { - .adf-datatable-cell-value { - position: static; - width: auto; - } - } - } + .adf-ellipsis-cell { + overflow: hidden; + } - .adf-library-name-column { - // same as on top comment - &.adf-datatable-cell { - color: $document-list-name-text-color; + .adf-dynamic-column .adf-datatable-link:hover { + text-decoration: none; - &:hover { - color: $document-list-selection-color; - } - } + .adf-datatable-cell-value { + text-decoration: underline; } } - .adf-datatable-cell-value { - display: block; - } - - .adf-datatable-cell--image { - min-width: $data-table-thumbnail-width; - width: $data-table-thumbnail-width; - max-width: $data-table-thumbnail-width; + .adf-datatable-cell, + .adf-datatable-cell-header { + .adf-datatable-link .adf-datatable-cell-value { + padding: 0 10px; + } } } @@ -76,10 +50,12 @@ .adf-datatable-cell-header, .adf-datatable-cell { - padding: 0 2px; - box-sizing: border-box; min-width: 120px; + &.adf-no-grow-cell { + min-width: 120px; + } + &.adf-datatable-cell--fileSize { min-width: 80px; } @@ -123,5 +99,25 @@ padding-top: 9px; padding-bottom: 9px; min-height: auto; + + .adf-datatable-cell-value { + display: inline-block; + padding-left: 0; + } + } + + .adf-content-node-selector-content-list .adf-datatable-list { + .adf-datatable-cell { + flex: 0 1 auto; + min-width: 1px; + + &:nth-child(2) { + flex: 1 0 200px; + } + + &.adf-content-selector-visibility-cell { + display: initial; + } + } } } From f3c5ffb9775791c731f5940690b087c2b968d8e0 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Thu, 25 Apr 2019 11:30:46 +0100 Subject: [PATCH 184/259] update test setup --- .../search/search-results/search-results.component.spec.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/app/components/search/search-results/search-results.component.spec.ts b/src/app/components/search/search-results/search-results.component.spec.ts index cb195a7614..e7e5c71b9e 100644 --- a/src/app/components/search/search-results/search-results.component.spec.ts +++ b/src/app/components/search/search-results/search-results.component.spec.ts @@ -1,5 +1,4 @@ import { - async, ComponentFixture, TestBed, fakeAsync, @@ -31,7 +30,7 @@ describe('SearchComponent', () => { let alfrescoApi: AlfrescoApiService; let translate: TranslationService; - beforeEach(async(() => { + beforeEach(() => { TestBed.configureTestingModule({ imports: [CoreModule.forRoot(), AppTestingModule, AppSearchResultsModule], providers: [ @@ -70,7 +69,7 @@ describe('SearchComponent', () => { spyOn(queryBuilder, 'update').and.stub(); fixture.detectChanges(); - })); + }); it('should raise an error if search fails', fakeAsync(() => { spyOn(alfrescoApi.searchApi, 'search').and.returnValue( From 9db1c2989f134ed2ae9cb9585b50a408fbc24b3d Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Thu, 25 Apr 2019 14:56:54 +0100 Subject: [PATCH 185/259] shared library (#1080) * shared project scaffold * rules package * move evaluators to shared lib * add rxjs peer dependency * use dedicated material namespaces * create store package, move actions * move selectors to shared library * move generic effects to shared lib * move routing extensions * minor code reorg * fix unit tests * move content-api service * move permission service * update tests * update plint config * move page layout * css variables * use dedicated css property * move generic error component to shared lib * fix test --- .github/plint.yml | 3 + angular.json | 35 ++++++ docs/extending/tutorials.md | 4 +- docs/tutorials/dialog-actions.md | 4 +- package-lock.json | 41 +++++-- package.json | 11 +- projects/aca-shared/README.md | 24 ++++ projects/aca-shared/karma.conf.js | 32 +++++ projects/aca-shared/ng-package.json | 17 +++ projects/aca-shared/package.json | 15 +++ projects/aca-shared/rules/package.json | 3 + .../aca-shared/rules/src/app.rules.spec.ts | 2 +- .../aca-shared/rules/src/app.rules.ts | 4 +- .../rules/src/navigation.rules.spec.ts | 2 +- .../aca-shared/rules/src/navigation.rules.ts | 0 .../aca-shared/rules/src/public_api.ts | 4 +- .../aca-shared/rules/src/repository.rules.ts | 0 .../generic-error.component.html | 2 +- .../generic-error.component.scss | 22 ++++ .../generic-error.component.spec.ts | 0 .../generic-error/generic-error.component.ts | 9 +- .../generic-error/generic-error.module.ts | 18 +-- .../page-layout-content.component.ts | 4 +- .../page-layout-error.component.ts | 4 +- .../page-layout-header.component.ts | 4 +- .../page-layout/page-layout.component.html | 3 + .../page-layout/page-layout.component.scss | 44 +++++++ .../page-layout/page-layout.component.ts | 5 +- .../page-layout/page-layout.module.ts | 48 ++++++++ .../lib/routing}/app.routes.strategy.spec.ts | 2 - .../src/lib/routing}/app.routes.strategy.ts | 0 .../src/lib/routing}/shared.guard.ts | 3 +- .../src/lib}/services/app.service.spec.ts | 6 +- .../src/lib}/services/app.service.ts | 2 +- .../lib}/services/content-api.service.spec.ts | 0 .../src/lib}/services/content-api.service.ts | 0 .../services/node-permission.service.spec.ts | 0 .../lib}/services/node-permission.service.ts | 0 .../aca-shared/src/lib/shared.module.ts | 18 ++- .../aca-shared/src/lib/styles/mixins.scss | 16 +++ projects/aca-shared/src/public-api.ts | 42 +++++++ projects/aca-shared/store/package.json | 3 + .../store/src}/actions/app.actions.ts | 69 +++++++---- .../store/src}/actions/library.actions.ts | 27 +++-- .../store/src}/actions/node.actions.ts | 105 ++++++++++------ .../store/src}/actions/router.actions.ts | 22 ++-- .../store/src}/actions/search.actions.ts | 20 ++-- .../store/src}/actions/snackbar.actions.ts | 14 ++- .../store/src}/actions/upload.actions.ts | 16 ++- .../store/src}/actions/viewer.actions.ts | 19 ++- .../store/src/effects/dialog.effects.ts | 11 +- .../store/src}/effects/router.effects.ts | 25 ++-- .../store/src}/effects/snackbar.effects.ts | 20 ++-- .../store/src}/models/delete-status.model.ts | 0 .../src}/models/deleted-node-info.model.ts | 0 .../store/src}/models/node-info.model.ts | 0 .../store/src/models/search-option.model.ts | 0 .../aca-shared/store/src/public_api.ts | 26 ++-- .../store/src}/selectors/app.selectors.ts | 56 ++++----- .../aca-shared/store/src/states/app.state.ts | 32 +++-- .../aca-shared/store/src/store.module.ts | 19 +-- projects/aca-shared/test.ts | 22 ++++ projects/aca-shared/tsconfig.lib.json | 29 +++++ projects/aca-shared/tsconfig.spec.json | 9 ++ projects/aca-shared/tslint.json | 7 ++ projects/adf-office-services-ext/package.json | 11 -- src/app/app.component.spec.ts | 2 +- src/app/app.component.ts | 19 ++- src/app/app.module.ts | 3 +- src/app/app.routes.ts | 6 +- src/app/components/about/about.component.html | 8 +- src/app/components/about/about.component.ts | 2 +- src/app/components/about/about.module.ts | 2 +- src/app/components/common/common.module.ts | 17 ++- .../generic-error.component.theme.scss | 27 ----- .../location-link/location-link.component.ts | 5 +- .../context-menu/context-menu.component.ts | 7 +- .../context-menu/context-menu.module.ts | 23 ++-- .../create-menu/create-menu.component.ts | 5 +- .../current-user/current-user.component.ts | 18 +-- .../name-column/name-column.component.ts | 4 +- .../favorite-libraries.component.html | 12 +- .../favorite-libraries.component.spec.ts | 5 +- .../favorite-libraries.component.ts | 7 +- .../favorites/favorites.component.html | 12 +- .../favorites/favorites.component.spec.ts | 2 +- .../favorites/favorites.component.ts | 18 +-- src/app/components/files/files.component.html | 16 +-- .../components/files/files.component.spec.ts | 2 +- src/app/components/files/files.component.ts | 7 +- src/app/components/header/header.component.ts | 18 +-- .../comments-tab.component.spec.ts | 2 +- .../comments-tab/comments-tab.component.ts | 2 +- .../info-drawer/info-drawer.component.spec.ts | 4 +- .../info-drawer/info-drawer.component.ts | 4 +- .../library-metadata-form.component.spec.ts | 2 +- .../library-metadata-form.component.ts | 3 +- .../metadata-tab.component.spec.ts | 2 +- .../metadata-tab/metadata-tab.component.ts | 2 +- .../app-layout/app-layout.component.spec.ts | 12 +- .../layout/app-layout/app-layout.component.ts | 12 +- src/app/components/layout/layout.module.ts | 24 +--- src/app/components/layout/layout.theme.scss | 2 - .../page-layout/page-layout.component.html | 3 - .../layout/page-layout/page-layout.theme.scss | 46 ------- .../libraries/libraries.component.html | 12 +- .../libraries/libraries.component.ts | 5 +- src/app/components/page.component.ts | 27 +++-- .../node-permissions.dialog.ts | 2 +- .../permission-manager.component.ts | 9 +- .../preview/preview.component.spec.ts | 2 +- .../components/preview/preview.component.ts | 6 +- .../recent-files/recent-files.component.html | 12 +- .../recent-files/recent-files.component.ts | 2 +- .../search-input.component.spec.ts | 13 +- .../search-input/search-input.component.ts | 22 ++-- .../search-libraries-results.component.html | 12 +- .../search-libraries-results.component.ts | 10 +- .../search-results-row.component.ts | 3 +- .../search-results.component.html | 12 +- .../search-results.component.spec.ts | 5 +- .../search-results.component.ts | 10 +- .../components/settings/settings.component.ts | 24 ++-- .../shared-files/shared-files.component.html | 12 +- .../shared-files/shared-files.component.ts | 3 +- .../shared-link-view.component.spec.ts | 2 +- .../shared-link-view.component.ts | 49 ++++++-- .../content-node-share.dialog.spec.ts | 6 +- .../content-node-share.dialog.ts | 9 +- .../toggle-shared/toggle-shared.component.ts | 10 +- .../sidenav/directives/action.directive.ts | 15 +-- .../directives/expansion-panel.directive.ts | 3 +- .../directives/menu-panel.directive.ts | 3 +- .../components/sidenav/sidenav.component.ts | 5 +- .../document-display-mode.component.ts | 10 +- .../toggle-edit-offline.component.spec.ts | 2 +- .../toggle-edit-offline.component.ts | 14 +-- .../toggle-favorite-library.component.ts | 5 +- .../toggle-favorite.component.ts | 10 +- .../toggle-info-drawer.component.ts | 11 +- .../toggle-join-library-button.component.ts | 24 ++-- .../toggle-join-library-menu.component.ts | 2 +- .../toggle-join-library.component.spec.ts | 2 +- .../trashcan/trashcan.component.html | 12 +- .../components/trashcan/trashcan.component.ts | 15 ++- src/app/components/viewer/viewer.component.ts | 26 ++-- .../node-versions/node-versions.dialog.ts | 12 +- src/app/directives/document-list.directive.ts | 2 +- src/app/extensions/core.extensions.module.ts | 112 +++++++++--------- src/app/extensions/extension.service.spec.ts | 2 +- src/app/extensions/extension.service.ts | 9 +- src/app/material.module.ts | 14 +-- .../content-management.service.spec.ts | 61 +++++----- .../services/content-management.service.ts | 105 ++++++---------- src/app/services/node-actions.service.spec.ts | 4 +- src/app/services/node-actions.service.ts | 4 +- src/app/store/app-store.module.ts | 14 +-- src/app/store/effects.ts | 3 - src/app/store/effects/app.effects.ts | 11 +- src/app/store/effects/download.effects.ts | 23 ++-- src/app/store/effects/favorite.effects.ts | 17 ++- src/app/store/effects/library.effects.ts | 46 ++++--- src/app/store/effects/node.effects.spec.ts | 52 +++++--- src/app/store/effects/node.effects.ts | 110 ++++++++--------- src/app/store/effects/search.effects.spec.ts | 6 +- src/app/store/effects/search.effects.ts | 9 +- src/app/store/effects/upload.effects.spec.ts | 2 +- src/app/store/effects/upload.effects.ts | 46 ++++--- src/app/store/effects/viewer.effects.ts | 48 ++++++-- .../{states/app.state.ts => initial-state.ts} | 28 +---- src/app/store/models.ts | 28 ----- src/app/store/reducers/app.reducer.ts | 53 ++++----- src/app/testing/app-testing.module.ts | 2 +- src/app/ui/custom-theme.scss | 18 ++- tsconfig.json | 4 +- 175 files changed, 1532 insertions(+), 1133 deletions(-) create mode 100644 projects/aca-shared/README.md create mode 100644 projects/aca-shared/karma.conf.js create mode 100644 projects/aca-shared/ng-package.json create mode 100644 projects/aca-shared/package.json create mode 100644 projects/aca-shared/rules/package.json rename src/app/extensions/evaluators/app.evaluators.spec.ts => projects/aca-shared/rules/src/app.rules.spec.ts (99%) rename src/app/extensions/evaluators/app.evaluators.ts => projects/aca-shared/rules/src/app.rules.ts (99%) rename src/app/extensions/evaluators/navigation.evaluators.spec.ts => projects/aca-shared/rules/src/navigation.rules.spec.ts (99%) rename src/app/extensions/evaluators/navigation.evaluators.ts => projects/aca-shared/rules/src/navigation.rules.ts (100%) rename src/app/store/states.ts => projects/aca-shared/rules/src/public_api.ts (91%) rename src/app/extensions/evaluators/repository.evaluators.ts => projects/aca-shared/rules/src/repository.rules.ts (100%) rename {src/app/components/common => projects/aca-shared/src/lib/components}/generic-error/generic-error.component.html (53%) create mode 100644 projects/aca-shared/src/lib/components/generic-error/generic-error.component.scss rename {src/app/components/common => projects/aca-shared/src/lib/components}/generic-error/generic-error.component.spec.ts (100%) rename {src/app/components/common => projects/aca-shared/src/lib/components}/generic-error/generic-error.component.ts (88%) rename src/app/store/actions/modals.actions.ts => projects/aca-shared/src/lib/components/generic-error/generic-error.module.ts (70%) rename {src/app/components/layout => projects/aca-shared/src/lib/components}/page-layout/page-layout-content.component.ts (94%) rename {src/app/components/layout => projects/aca-shared/src/lib/components}/page-layout/page-layout-error.component.ts (94%) rename {src/app/components/layout => projects/aca-shared/src/lib/components}/page-layout/page-layout-header.component.ts (94%) create mode 100644 projects/aca-shared/src/lib/components/page-layout/page-layout.component.html create mode 100644 projects/aca-shared/src/lib/components/page-layout/page-layout.component.scss rename {src/app/components/layout => projects/aca-shared/src/lib/components}/page-layout/page-layout.component.ts (92%) create mode 100644 projects/aca-shared/src/lib/components/page-layout/page-layout.module.ts rename {src/app => projects/aca-shared/src/lib/routing}/app.routes.strategy.spec.ts (96%) rename {src/app => projects/aca-shared/src/lib/routing}/app.routes.strategy.ts (100%) rename {src/app/guards => projects/aca-shared/src/lib/routing}/shared.guard.ts (93%) rename {src/app => projects/aca-shared/src/lib}/services/app.service.spec.ts (94%) rename {src/app => projects/aca-shared/src/lib}/services/app.service.ts (96%) rename {src/app => projects/aca-shared/src/lib}/services/content-api.service.spec.ts (100%) rename {src/app => projects/aca-shared/src/lib}/services/content-api.service.ts (100%) rename {src/app => projects/aca-shared/src/lib}/services/node-permission.service.spec.ts (100%) rename {src/app => projects/aca-shared/src/lib}/services/node-permission.service.ts (100%) rename src/app/store/actions/info-drawer.actions.ts => projects/aca-shared/src/lib/shared.module.ts (70%) create mode 100644 projects/aca-shared/src/lib/styles/mixins.scss create mode 100644 projects/aca-shared/src/public-api.ts create mode 100644 projects/aca-shared/store/package.json rename {src/app/store => projects/aca-shared/store/src}/actions/app.actions.ts (55%) rename {src/app/store => projects/aca-shared/store/src}/actions/library.actions.ts (79%) rename {src/app/store => projects/aca-shared/store/src}/actions/node.actions.ts (63%) rename {src/app/store => projects/aca-shared/store/src}/actions/router.actions.ts (80%) rename {src/app/store => projects/aca-shared/store/src}/actions/search.actions.ts (76%) rename {src/app/store => projects/aca-shared/store/src}/actions/snackbar.actions.ts (88%) rename {src/app/store => projects/aca-shared/store/src}/actions/upload.actions.ts (82%) rename {src/app/store => projects/aca-shared/store/src}/actions/viewer.actions.ts (79%) rename src/app/store/effects/modals.effects.ts => projects/aca-shared/store/src/effects/dialog.effects.ts (85%) rename {src/app/store => projects/aca-shared/store/src}/effects/router.effects.ts (91%) rename {src/app/store => projects/aca-shared/store/src}/effects/snackbar.effects.ts (90%) rename {src/app/store => projects/aca-shared/store/src}/models/delete-status.model.ts (100%) rename {src/app/store => projects/aca-shared/store/src}/models/deleted-node-info.model.ts (100%) rename {src/app/store => projects/aca-shared/store/src}/models/node-info.model.ts (100%) rename src/app/store/models/searchOption.model.ts => projects/aca-shared/store/src/models/search-option.model.ts (100%) rename src/app/store/actions.ts => projects/aca-shared/store/src/public_api.ts (77%) rename {src/app/store => projects/aca-shared/store/src}/selectors/app.selectors.ts (74%) rename src/app/store/actions/favorite.actions.ts => projects/aca-shared/store/src/states/app.state.ts (67%) rename src/app/store/actions/repository.actions.ts => projects/aca-shared/store/src/store.module.ts (73%) create mode 100644 projects/aca-shared/test.ts create mode 100644 projects/aca-shared/tsconfig.lib.json create mode 100644 projects/aca-shared/tsconfig.spec.json create mode 100644 projects/aca-shared/tslint.json delete mode 100644 src/app/components/common/generic-error/generic-error.component.theme.scss delete mode 100644 src/app/components/layout/page-layout/page-layout.component.html delete mode 100644 src/app/components/layout/page-layout/page-layout.theme.scss rename src/app/store/{states/app.state.ts => initial-state.ts} (74%) delete mode 100644 src/app/store/models.ts diff --git a/.github/plint.yml b/.github/plint.yml index 63c57da92a..84ed3336b1 100644 --- a/.github/plint.yml +++ b/.github/plint.yml @@ -5,3 +5,6 @@ modules: spellcheck: words: - plint + - ngrx + - qshare + - snackbar diff --git a/angular.json b/angular.json index a2dafd68db..6cf5af0d3c 100644 --- a/angular.json +++ b/angular.json @@ -273,6 +273,41 @@ } } } + }, + "aca-shared": { + "root": "projects/aca-shared", + "sourceRoot": "projects/aca-shared/src", + "projectType": "library", + "prefix": "lib", + "architect": { + "build": { + "builder": "@angular-devkit/build-ng-packagr:build", + "options": { + "tsConfig": "projects/aca-shared/tsconfig.lib.json", + "project": "projects/aca-shared/ng-package.json" + } + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "main": "projects/aca-shared/test.ts", + "tsConfig": "projects/aca-shared/tsconfig.spec.json", + "karmaConfig": "projects/aca-shared/karma.conf.js" + } + }, + "lint": { + "builder": "@angular-devkit/build-angular:tslint", + "options": { + "tsConfig": [ + "projects/aca-shared/tsconfig.lib.json", + "projects/aca-shared/tsconfig.spec.json" + ], + "exclude": [ + "**/node_modules/**" + ] + } + } + } } }, "defaultProject": "app", diff --git a/docs/extending/tutorials.md b/docs/extending/tutorials.md index 49c0d6bbca..74fa1270bd 100644 --- a/docs/extending/tutorials.md +++ b/docs/extending/tutorials.md @@ -161,7 +161,7 @@ Update `my-extension-dialog.component.ts`: ```ts import { Component } from '@angular/core'; -import { MatDialogRef } from '@angular/material'; +import { MatDialogRef } from '@angular/material/dialog'; @Component({ selector: 'aca-my-extension-dialog', @@ -229,7 +229,7 @@ See also: Update to raise a dialog ```ts -import { MatDialog } from '@angular/material'; +import { MatDialog } from '@angular/material/dialog'; import { MyExtensionDialogComponent } from '../../dialogs/my-extension-dialog/my-extension-dialog.component'; @Injectable() diff --git a/docs/tutorials/dialog-actions.md b/docs/tutorials/dialog-actions.md index 6d82285874..f762733b6f 100644 --- a/docs/tutorials/dialog-actions.md +++ b/docs/tutorials/dialog-actions.md @@ -36,7 +36,7 @@ Update `my-extension-dialog.component.ts`: ```ts import { Component } from '@angular/core'; -import { MatDialogRef } from '@angular/material'; +import { MatDialogRef } from '@angular/material/dialog'; @Component({ selector: 'aca-my-extension-dialog', @@ -104,7 +104,7 @@ See also: Update to raise a dialog ```ts -import { MatDialog } from '@angular/material'; +import { MatDialog } from '@angular/material/dialog'; import { MyExtensionDialogComponent } from '../../dialogs/my-extension-dialog/my-extension-dialog.component'; @Injectable() diff --git a/package-lock.json b/package-lock.json index 4a8738dd2c..88eb950280 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4959,7 +4959,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -4980,12 +4981,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": 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" @@ -5000,17 +5003,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -5127,7 +5133,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -5139,6 +5146,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -5153,6 +5161,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -5160,12 +5169,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -5184,6 +5195,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -5264,7 +5276,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -5276,6 +5289,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -5361,7 +5375,8 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -5397,6 +5412,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -5416,6 +5432,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -5459,12 +5476,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, diff --git a/package.json b/package.json index cac2ba9387..d1af1f3325 100644 --- a/package.json +++ b/package.json @@ -4,15 +4,16 @@ "license": "LGPL-3.0", "scripts": { "ng": "ng", - "start": "npm run build.extensions && ng serve --open", + "start": "npm run build.shared && npm run build.extensions && ng serve --open", "start:prod": "node --max-old-space-size=8192 node_modules/@angular/cli/bin/ng serve --prod --open", "build:aos-extension": "npx rimraf dist/@alfresco/adf-office-services-ext && ng build adf-office-services-ext && cpr projects/adf-office-services-ext/ngi.json dist/@alfresco/adf-office-services-ext/ngi.json && cpr projects/adf-office-services-ext/assets dist/@alfresco/adf-office-services-ext/assets", + "build.shared": "ng build aca-shared", "build.extensions": "npm run build:aos-extension", "build.app": "node --max-old-space-size=8192 node_modules/@angular/cli/bin/ng build app", - "build": "npm run build.extensions && npm run build.app -- --prod", - "build.e2e": "npm run build.extensions && npm run build.app -- --prod --configuration=e2e", + "build": "npm run build.shared && npm run build.extensions && npm run build.app -- --prod", + "build.e2e": "npm run build.shared && npm run build.extensions && npm run build.app -- --prod --configuration=e2e", "test": "ng test app --code-coverage", - "test:ci": "npm run build.extensions && ng test adf-office-services-ext --watch=false && ng test app --code-coverage --watch=false", + "test:ci": "npm run build.shared && npm run build.extensions && ng test adf-office-services-ext --watch=false && ng test app --code-coverage --watch=false", "lint": "ng lint && npm run spellcheck && npm run format:check && npm run e2e.typecheck", "wd:update": "webdriver-manager update --gecko=false", "e2e.typecheck": "tsc -p ./e2e/tsconfig.e2e.typecheck.json", @@ -26,7 +27,7 @@ "inspect.bundle": "ng build app --prod --stats-json && npx webpack-bundle-analyzer dist/app/stats.json", "format:check": "prettier --check \"src/{app,environments}/**/*.{ts,js,css,scss,html}\"", "format:fix": "prettier --write \"src/{app,environments}/**/*.{ts,js,css,scss,html}\"", - "build.tomcat": "npm run build.extensions && npm run build.app -- --prod --base-href ./ && jar -cvf docker/tomcat/artifacts/content-app.war -C dist/app/ .", + "build.tomcat": "npm run build.shared && npm run build.extensions && npm run build.app -- --prod --base-href ./ && jar -cvf docker/tomcat/artifacts/content-app.war -C dist/app/ .", "build.tomcat.e2e": "./build-tomcat-e2e.sh", "e2e.tomcat": "npm run wd:update && protractor --baseUrl=http://localhost:4000/content-app/ $SUITE", "docker.tomcat.start": "cd docker/tomcat && docker-compose up -d --build && npm run wait:app", diff --git a/projects/aca-shared/README.md b/projects/aca-shared/README.md new file mode 100644 index 0000000000..336cad5cdd --- /dev/null +++ b/projects/aca-shared/README.md @@ -0,0 +1,24 @@ +# AcaShared + +This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 7.2.0. + +## Code scaffolding + +Run `ng generate component component-name --project aca-shared` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project aca-shared`. +> Note: Don't forget to add `--project aca-shared` or else it will be added to the default project in your `angular.json` file. + +## Build + +Run `ng build aca-shared` to build the project. The build artifacts will be stored in the `dist/` directory. + +## Publishing + +After building your library with `ng build aca-shared`, go to the dist folder `cd dist/aca-shared` and run `npm publish`. + +## Running unit tests + +Run `ng test aca-shared` to execute the unit tests via [Karma](https://karma-runner.github.io). + +## Further help + +To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md). diff --git a/projects/aca-shared/karma.conf.js b/projects/aca-shared/karma.conf.js new file mode 100644 index 0000000000..391854077f --- /dev/null +++ b/projects/aca-shared/karma.conf.js @@ -0,0 +1,32 @@ +// Karma configuration file, see link for more information +// https://karma-runner.github.io/1.0/config/configuration-file.html + +module.exports = function(config) { + config.set({ + basePath: '', + frameworks: ['jasmine', '@angular-devkit/build-angular'], + plugins: [ + require('karma-jasmine'), + require('karma-chrome-launcher'), + require('karma-jasmine-html-reporter'), + require('karma-coverage-istanbul-reporter'), + require('@angular-devkit/build-angular/plugins/karma') + ], + client: { + clearContext: false // leave Jasmine Spec Runner output visible in browser + }, + coverageIstanbulReporter: { + dir: require('path').join(__dirname, '../../coverage/aca-shared'), + reports: ['html', 'lcovonly'], + fixWebpackSourcePaths: true + }, + reporters: ['progress', 'kjhtml'], + port: 9876, + colors: true, + logLevel: config.LOG_INFO, + autoWatch: true, + browsers: ['Chrome'], + singleRun: false, + restartOnFileChange: true + }); +}; diff --git a/projects/aca-shared/ng-package.json b/projects/aca-shared/ng-package.json new file mode 100644 index 0000000000..240cc4a74d --- /dev/null +++ b/projects/aca-shared/ng-package.json @@ -0,0 +1,17 @@ +{ + "$schema": "../../node_modules/ng-packagr/ng-package.schema.json", + "dest": "../../dist/@alfresco/aca-shared", + "lib": { + "entryFile": "src/public-api.ts", + "umdModuleIds": { + "rxjs": "rxjs", + "@alfresco/js-api": "@alfresco/js-api", + "@alfresco/adf-core": "@alfresco/adf-core", + "@alfresco/adf-extensions": "@alfresco/adf-extensions", + "@ngrx/store": "@ngrx/store", + "@ngrx/effects": "@ngrx/effects", + "@angular/material": "@angular/material", + "@ngx-translate/core": "@ngx-translate/core" + } + } +} diff --git a/projects/aca-shared/package.json b/projects/aca-shared/package.json new file mode 100644 index 0000000000..942ab68574 --- /dev/null +++ b/projects/aca-shared/package.json @@ -0,0 +1,15 @@ +{ + "name": "@alfresco/aca-shared", + "version": "1.8.0", + "peerDependencies": { + "@angular/common": "^7.2.0", + "@angular/core": "^7.2.0", + "@angular/material": "^7.3.7", + "@ngrx/effects": "^7.4.0", + "@ngrx/store": "^7.4.0", + "@alfresco/adf-extensions": "^3.1.0", + "@alfresco/js-api": "^3.1.0", + "rxjs": "^6.4.0", + "@ngx-translate/core": "^11.0.1" + } +} diff --git a/projects/aca-shared/rules/package.json b/projects/aca-shared/rules/package.json new file mode 100644 index 0000000000..4bbd7d0f7b --- /dev/null +++ b/projects/aca-shared/rules/package.json @@ -0,0 +1,3 @@ +{ + "ngPackage": {} +} diff --git a/src/app/extensions/evaluators/app.evaluators.spec.ts b/projects/aca-shared/rules/src/app.rules.spec.ts similarity index 99% rename from src/app/extensions/evaluators/app.evaluators.spec.ts rename to projects/aca-shared/rules/src/app.rules.spec.ts index 781ed2ef59..1f37fd3426 100644 --- a/src/app/extensions/evaluators/app.evaluators.spec.ts +++ b/projects/aca-shared/rules/src/app.rules.spec.ts @@ -23,7 +23,7 @@ * along with Alfresco. If not, see . */ -import * as app from './app.evaluators'; +import * as app from './app.rules'; describe('app.evaluators', () => { describe('isWriteLocked', () => { diff --git a/src/app/extensions/evaluators/app.evaluators.ts b/projects/aca-shared/rules/src/app.rules.ts similarity index 99% rename from src/app/extensions/evaluators/app.evaluators.ts rename to projects/aca-shared/rules/src/app.rules.ts index 74ad483836..129c4d5851 100644 --- a/src/app/extensions/evaluators/app.evaluators.ts +++ b/projects/aca-shared/rules/src/app.rules.ts @@ -24,8 +24,8 @@ */ import { RuleContext } from '@alfresco/adf-extensions'; -import * as navigation from './navigation.evaluators'; -import * as repository from './repository.evaluators'; +import * as navigation from './navigation.rules'; +import * as repository from './repository.rules'; /** * Checks if user can copy selected node. diff --git a/src/app/extensions/evaluators/navigation.evaluators.spec.ts b/projects/aca-shared/rules/src/navigation.rules.spec.ts similarity index 99% rename from src/app/extensions/evaluators/navigation.evaluators.spec.ts rename to projects/aca-shared/rules/src/navigation.rules.spec.ts index 23b5e6df05..c89e6026e1 100644 --- a/src/app/extensions/evaluators/navigation.evaluators.spec.ts +++ b/projects/aca-shared/rules/src/navigation.rules.spec.ts @@ -23,7 +23,7 @@ * along with Alfresco. If not, see . */ -import * as app from './navigation.evaluators'; +import * as app from './navigation.rules'; describe('navigation.evaluators', () => { describe('isPreview', () => { diff --git a/src/app/extensions/evaluators/navigation.evaluators.ts b/projects/aca-shared/rules/src/navigation.rules.ts similarity index 100% rename from src/app/extensions/evaluators/navigation.evaluators.ts rename to projects/aca-shared/rules/src/navigation.rules.ts diff --git a/src/app/store/states.ts b/projects/aca-shared/rules/src/public_api.ts similarity index 91% rename from src/app/store/states.ts rename to projects/aca-shared/rules/src/public_api.ts index b39538649c..542beb99a7 100644 --- a/src/app/store/states.ts +++ b/projects/aca-shared/rules/src/public_api.ts @@ -23,4 +23,6 @@ * along with Alfresco. If not, see . */ -export * from './states/app.state'; +export * from './app.rules'; +export * from './navigation.rules'; +export * from './repository.rules'; diff --git a/src/app/extensions/evaluators/repository.evaluators.ts b/projects/aca-shared/rules/src/repository.rules.ts similarity index 100% rename from src/app/extensions/evaluators/repository.evaluators.ts rename to projects/aca-shared/rules/src/repository.rules.ts diff --git a/src/app/components/common/generic-error/generic-error.component.html b/projects/aca-shared/src/lib/components/generic-error/generic-error.component.html similarity index 53% rename from src/app/components/common/generic-error/generic-error.component.html rename to projects/aca-shared/src/lib/components/generic-error/generic-error.component.html index 8b0419bc1b..4ab4542a19 100644 --- a/src/app/components/common/generic-error/generic-error.component.html +++ b/projects/aca-shared/src/lib/components/generic-error/generic-error.component.html @@ -1,4 +1,4 @@ ic_error

- {{ 'APP.MESSAGES.ERRORS.MISSING_CONTENT' | translate }} + {{ text | translate }}

diff --git a/projects/aca-shared/src/lib/components/generic-error/generic-error.component.scss b/projects/aca-shared/src/lib/components/generic-error/generic-error.component.scss new file mode 100644 index 0000000000..efba7b28dc --- /dev/null +++ b/projects/aca-shared/src/lib/components/generic-error/generic-error.component.scss @@ -0,0 +1,22 @@ +.aca-generic-error { + color: var(--theme-text-color, rgba(0, 0, 0, 0.54)); + + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; + width: 100%; + height: 100%; + + &__title { + font-size: 16px; + } + + mat-icon { + color: var(--theme-warn-color, #f44336); + direction: rtl; + font-size: 52px; + height: 52px; + width: 52px; + } +} diff --git a/src/app/components/common/generic-error/generic-error.component.spec.ts b/projects/aca-shared/src/lib/components/generic-error/generic-error.component.spec.ts similarity index 100% rename from src/app/components/common/generic-error/generic-error.component.spec.ts rename to projects/aca-shared/src/lib/components/generic-error/generic-error.component.spec.ts diff --git a/src/app/components/common/generic-error/generic-error.component.ts b/projects/aca-shared/src/lib/components/generic-error/generic-error.component.ts similarity index 88% rename from src/app/components/common/generic-error/generic-error.component.ts rename to projects/aca-shared/src/lib/components/generic-error/generic-error.component.ts index 755cc3df96..bdcfdd912f 100644 --- a/src/app/components/common/generic-error/generic-error.component.ts +++ b/projects/aca-shared/src/lib/components/generic-error/generic-error.component.ts @@ -26,14 +26,19 @@ import { Component, ViewEncapsulation, - ChangeDetectionStrategy + ChangeDetectionStrategy, + Input } from '@angular/core'; @Component({ selector: 'aca-generic-error', templateUrl: './generic-error.component.html', + styleUrls: ['./generic-error.component.scss'], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'aca-generic-error' } }) -export class GenericErrorComponent {} +export class GenericErrorComponent { + @Input() + text = 'APP.MESSAGES.ERRORS.MISSING_CONTENT'; +} diff --git a/src/app/store/actions/modals.actions.ts b/projects/aca-shared/src/lib/components/generic-error/generic-error.module.ts similarity index 70% rename from src/app/store/actions/modals.actions.ts rename to projects/aca-shared/src/lib/components/generic-error/generic-error.module.ts index b2c9afc253..819ade5ba5 100644 --- a/src/app/store/actions/modals.actions.ts +++ b/projects/aca-shared/src/lib/components/generic-error/generic-error.module.ts @@ -23,11 +23,15 @@ * along with Alfresco. If not, see . */ -import { Action } from '@ngrx/store'; +import { NgModule } from '@angular/core'; +import { GenericErrorComponent } from './generic-error.component'; +import { MatIconModule } from '@angular/material/icon'; +import { CommonModule } from '@angular/common'; +import { TranslateModule } from '@ngx-translate/core'; -export const CLOSE_MODAL_DIALOGS = 'CLOSE_MODAL_DIALOGS'; - -export class CloseModalDialogsAction implements Action { - readonly type = CLOSE_MODAL_DIALOGS; - constructor() {} -} +@NgModule({ + imports: [CommonModule, MatIconModule, TranslateModule.forChild()], + declarations: [GenericErrorComponent], + exports: [GenericErrorComponent] +}) +export class GenericErrorModule {} diff --git a/src/app/components/layout/page-layout/page-layout-content.component.ts b/projects/aca-shared/src/lib/components/page-layout/page-layout-content.component.ts similarity index 94% rename from src/app/components/layout/page-layout/page-layout-content.component.ts rename to projects/aca-shared/src/lib/components/page-layout/page-layout-content.component.ts index 48015a48c5..375f2c746d 100644 --- a/src/app/components/layout/page-layout/page-layout-content.component.ts +++ b/projects/aca-shared/src/lib/components/page-layout/page-layout-content.component.ts @@ -32,13 +32,13 @@ import { } from '@angular/core'; @Component({ - selector: 'app-page-layout-content', + selector: 'aca-page-layout-content', template: ` `, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, - host: { class: 'app-page-layout-content' } + host: { class: 'aca-page-layout-content' } }) export class PageLayoutContentComponent { @Input() diff --git a/src/app/components/layout/page-layout/page-layout-error.component.ts b/projects/aca-shared/src/lib/components/page-layout/page-layout-error.component.ts similarity index 94% rename from src/app/components/layout/page-layout/page-layout-error.component.ts rename to projects/aca-shared/src/lib/components/page-layout/page-layout-error.component.ts index 7c5f1d0085..a171d52190 100644 --- a/src/app/components/layout/page-layout/page-layout-error.component.ts +++ b/projects/aca-shared/src/lib/components/page-layout/page-layout-error.component.ts @@ -30,12 +30,12 @@ import { } from '@angular/core'; @Component({ - selector: 'app-page-layout-error', + selector: 'aca-page-layout-error', template: ` `, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, - host: { class: 'app-page-layout-error' } + host: { class: 'aca-page-layout-error' } }) export class PageLayoutErrorComponent {} diff --git a/src/app/components/layout/page-layout/page-layout-header.component.ts b/projects/aca-shared/src/lib/components/page-layout/page-layout-header.component.ts similarity index 94% rename from src/app/components/layout/page-layout/page-layout-header.component.ts rename to projects/aca-shared/src/lib/components/page-layout/page-layout-header.component.ts index 788a094c4d..2890c40480 100644 --- a/src/app/components/layout/page-layout/page-layout-header.component.ts +++ b/projects/aca-shared/src/lib/components/page-layout/page-layout-header.component.ts @@ -30,10 +30,10 @@ import { } from '@angular/core'; @Component({ - selector: 'app-page-layout-header', + selector: 'aca-page-layout-header', template: '', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, - host: { class: 'app-page-layout-header' } + host: { class: 'aca-page-layout-header' } }) export class PageLayoutHeaderComponent {} diff --git a/projects/aca-shared/src/lib/components/page-layout/page-layout.component.html b/projects/aca-shared/src/lib/components/page-layout/page-layout.component.html new file mode 100644 index 0000000000..966402c252 --- /dev/null +++ b/projects/aca-shared/src/lib/components/page-layout/page-layout.component.html @@ -0,0 +1,3 @@ + + + diff --git a/projects/aca-shared/src/lib/components/page-layout/page-layout.component.scss b/projects/aca-shared/src/lib/components/page-layout/page-layout.component.scss new file mode 100644 index 0000000000..79670dfcce --- /dev/null +++ b/projects/aca-shared/src/lib/components/page-layout/page-layout.component.scss @@ -0,0 +1,44 @@ +@import '../../styles/mixins.scss'; + +.aca-page-layout { + @include flex-column; + + .aca-page-layout-header { + display: flex; + align-items: center; + flex: 0 0 65px; + flex-basis: 48px; + background: #fafafa; + border-bottom: 1px solid var(--theme-border-color, rgba(0, 0, 0, 0.07)); + padding: 0 24px; + } + + .aca-page-layout-content { + @include flex-row; + } + + .aca-page-layout-error { + @include flex-row; + } + + .main-content { + @include flex-column; + border-right: 1px solid var(--theme-border-color, rgba(0, 0, 0, 0.07)); + } + + .scrollable { + overflow: auto !important; + + .main-content { + overflow: auto !important; + } + } + + .sidebar { + display: block; + height: 100%; + overflow-y: scroll; + max-width: 350px; + width: 350px; + } +} diff --git a/src/app/components/layout/page-layout/page-layout.component.ts b/projects/aca-shared/src/lib/components/page-layout/page-layout.component.ts similarity index 92% rename from src/app/components/layout/page-layout/page-layout.component.ts rename to projects/aca-shared/src/lib/components/page-layout/page-layout.component.ts index 7919848129..cc378408d7 100644 --- a/src/app/components/layout/page-layout/page-layout.component.ts +++ b/projects/aca-shared/src/lib/components/page-layout/page-layout.component.ts @@ -31,10 +31,11 @@ import { } from '@angular/core'; @Component({ - selector: 'app-page-layout', + selector: 'aca-page-layout', templateUrl: 'page-layout.component.html', + styleUrls: ['./page-layout.component.scss'], encapsulation: ViewEncapsulation.None, - host: { class: 'app-page-layout' }, + host: { class: 'aca-page-layout' }, changeDetection: ChangeDetectionStrategy.OnPush }) export class PageLayoutComponent { diff --git a/projects/aca-shared/src/lib/components/page-layout/page-layout.module.ts b/projects/aca-shared/src/lib/components/page-layout/page-layout.module.ts new file mode 100644 index 0000000000..defead0234 --- /dev/null +++ b/projects/aca-shared/src/lib/components/page-layout/page-layout.module.ts @@ -0,0 +1,48 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2019 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { NgModule } from '@angular/core'; +import { PageLayoutContentComponent } from './page-layout-content.component'; +import { PageLayoutErrorComponent } from './page-layout-error.component'; +import { PageLayoutHeaderComponent } from './page-layout-header.component'; +import { PageLayoutComponent } from './page-layout.component'; +import { CommonModule } from '@angular/common'; + +@NgModule({ + imports: [CommonModule], + declarations: [ + PageLayoutContentComponent, + PageLayoutErrorComponent, + PageLayoutHeaderComponent, + PageLayoutComponent + ], + exports: [ + PageLayoutContentComponent, + PageLayoutErrorComponent, + PageLayoutHeaderComponent, + PageLayoutComponent + ] +}) +export class PageLayoutModule {} diff --git a/src/app/app.routes.strategy.spec.ts b/projects/aca-shared/src/lib/routing/app.routes.strategy.spec.ts similarity index 96% rename from src/app/app.routes.strategy.spec.ts rename to projects/aca-shared/src/lib/routing/app.routes.strategy.spec.ts index 674e430a50..cd6fd61efd 100644 --- a/src/app/app.routes.strategy.spec.ts +++ b/projects/aca-shared/src/lib/routing/app.routes.strategy.spec.ts @@ -25,14 +25,12 @@ import { AppRouteReuseStrategy } from './app.routes.strategy'; import { TestBed } from '@angular/core/testing'; -import { AppTestingModule } from './testing/app-testing.module'; describe('AppRouteReuseStrategy', () => { let appRouteReuse: AppRouteReuseStrategy; beforeEach(() => { TestBed.configureTestingModule({ - imports: [AppTestingModule], providers: [AppRouteReuseStrategy] }); diff --git a/src/app/app.routes.strategy.ts b/projects/aca-shared/src/lib/routing/app.routes.strategy.ts similarity index 100% rename from src/app/app.routes.strategy.ts rename to projects/aca-shared/src/lib/routing/app.routes.strategy.ts diff --git a/src/app/guards/shared.guard.ts b/projects/aca-shared/src/lib/routing/shared.guard.ts similarity index 93% rename from src/app/guards/shared.guard.ts rename to projects/aca-shared/src/lib/routing/shared.guard.ts index 3da19f4ec4..bb491f7c4a 100644 --- a/src/app/guards/shared.guard.ts +++ b/projects/aca-shared/src/lib/routing/shared.guard.ts @@ -28,8 +28,7 @@ import { CanActivate } from '@angular/router'; import { Observable } from 'rxjs'; import { ActivatedRouteSnapshot } from '@angular/router'; import { Store } from '@ngrx/store'; -import { AppStore } from '../store/states/app.state'; -import { isQuickShareEnabled } from '../store/selectors/app.selectors'; +import { AppStore, isQuickShareEnabled } from '@alfresco/aca-shared/store'; @Injectable({ providedIn: 'root' diff --git a/src/app/services/app.service.spec.ts b/projects/aca-shared/src/lib/services/app.service.spec.ts similarity index 94% rename from src/app/services/app.service.spec.ts rename to projects/aca-shared/src/lib/services/app.service.spec.ts index a41aa215d0..440289ee46 100644 --- a/src/app/services/app.service.spec.ts +++ b/projects/aca-shared/src/lib/services/app.service.spec.ts @@ -25,10 +25,10 @@ import { AppService } from './app.service'; import { TestBed } from '@angular/core/testing'; -import { AppTestingModule } from '../testing/app-testing.module'; import { AuthenticationService, AppConfigService } from '@alfresco/adf-core'; -import { AppRouteReuseStrategy } from '../app.routes.strategy'; import { Subject } from 'rxjs'; +import { HttpClientModule } from '@angular/common/http'; +import { AppRouteReuseStrategy } from '../routing/app.routes.strategy'; describe('AppService', () => { let service: AppService; @@ -38,7 +38,7 @@ describe('AppService', () => { beforeEach(() => { TestBed.configureTestingModule({ - imports: [AppTestingModule], + imports: [HttpClientModule], providers: [ AppRouteReuseStrategy, { diff --git a/src/app/services/app.service.ts b/projects/aca-shared/src/lib/services/app.service.ts similarity index 96% rename from src/app/services/app.service.ts rename to projects/aca-shared/src/lib/services/app.service.ts index 0b02eb10b2..5c097d937f 100644 --- a/src/app/services/app.service.ts +++ b/projects/aca-shared/src/lib/services/app.service.ts @@ -26,8 +26,8 @@ import { Injectable, Inject } from '@angular/core'; import { AuthenticationService, AppConfigService } from '@alfresco/adf-core'; import { Observable, BehaviorSubject } from 'rxjs'; -import { AppRouteReuseStrategy } from '../app.routes.strategy'; import { RouteReuseStrategy } from '@angular/router'; +import { AppRouteReuseStrategy } from '../routing/app.routes.strategy'; @Injectable({ providedIn: 'root' diff --git a/src/app/services/content-api.service.spec.ts b/projects/aca-shared/src/lib/services/content-api.service.spec.ts similarity index 100% rename from src/app/services/content-api.service.spec.ts rename to projects/aca-shared/src/lib/services/content-api.service.spec.ts diff --git a/src/app/services/content-api.service.ts b/projects/aca-shared/src/lib/services/content-api.service.ts similarity index 100% rename from src/app/services/content-api.service.ts rename to projects/aca-shared/src/lib/services/content-api.service.ts diff --git a/src/app/services/node-permission.service.spec.ts b/projects/aca-shared/src/lib/services/node-permission.service.spec.ts similarity index 100% rename from src/app/services/node-permission.service.spec.ts rename to projects/aca-shared/src/lib/services/node-permission.service.spec.ts diff --git a/src/app/services/node-permission.service.ts b/projects/aca-shared/src/lib/services/node-permission.service.ts similarity index 100% rename from src/app/services/node-permission.service.ts rename to projects/aca-shared/src/lib/services/node-permission.service.ts diff --git a/src/app/store/actions/info-drawer.actions.ts b/projects/aca-shared/src/lib/shared.module.ts similarity index 70% rename from src/app/store/actions/info-drawer.actions.ts rename to projects/aca-shared/src/lib/shared.module.ts index 9db0e7e13f..327fe0b8bd 100644 --- a/src/app/store/actions/info-drawer.actions.ts +++ b/projects/aca-shared/src/lib/shared.module.ts @@ -23,11 +23,17 @@ * along with Alfresco. If not, see . */ -import { Action } from '@ngrx/store'; +import { NgModule, ModuleWithProviders } from '@angular/core'; +import { ContentApiService } from './services/content-api.service'; +import { NodePermissionService } from './services/node-permission.service'; +import { AppService } from './services/app.service'; -export const SET_INFO_DRAWER_STATE = 'SET_INFO_DRAWER_STATE'; - -export class SetInfoDrawerStateAction implements Action { - readonly type = SET_INFO_DRAWER_STATE; - constructor(public payload: boolean) {} +@NgModule({}) +export class SharedModule { + static forRoot(): ModuleWithProviders { + return { + ngModule: SharedModule, + providers: [ContentApiService, NodePermissionService, AppService] + }; + } } diff --git a/projects/aca-shared/src/lib/styles/mixins.scss b/projects/aca-shared/src/lib/styles/mixins.scss new file mode 100644 index 0000000000..946c3b5683 --- /dev/null +++ b/projects/aca-shared/src/lib/styles/mixins.scss @@ -0,0 +1,16 @@ +@mixin flex-column { + display: flex; + flex-direction: column; + flex: 1; + height: 100%; + overflow: hidden; + min-height: 0; +} + +@mixin flex-row { + display: flex; + flex-direction: row; + flex: 1; + height: 100%; + overflow: hidden; +} diff --git a/projects/aca-shared/src/public-api.ts b/projects/aca-shared/src/public-api.ts new file mode 100644 index 0000000000..0d87b45024 --- /dev/null +++ b/projects/aca-shared/src/public-api.ts @@ -0,0 +1,42 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2019 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +export * from './lib/components/page-layout/page-layout-content.component'; +export * from './lib/components/page-layout/page-layout-error.component'; +export * from './lib/components/page-layout/page-layout-header.component'; +export * from './lib/components/page-layout/page-layout.component'; +export * from './lib/components/page-layout/page-layout.module'; + +export * from './lib/routing/app.routes.strategy'; +export * from './lib/routing/shared.guard'; + +export * from './lib/services/app.service'; +export * from './lib/services/content-api.service'; +export * from './lib/services/node-permission.service'; + +export * from './lib/components/generic-error/generic-error.component'; +export * from './lib/components/generic-error/generic-error.module'; + +export * from './lib/shared.module'; diff --git a/projects/aca-shared/store/package.json b/projects/aca-shared/store/package.json new file mode 100644 index 0000000000..4bbd7d0f7b --- /dev/null +++ b/projects/aca-shared/store/package.json @@ -0,0 +1,3 @@ +{ + "ngPackage": {} +} diff --git a/src/app/store/actions/app.actions.ts b/projects/aca-shared/store/src/actions/app.actions.ts similarity index 55% rename from src/app/store/actions/app.actions.ts rename to projects/aca-shared/store/src/actions/app.actions.ts index a45dafa25a..864fae83c7 100644 --- a/src/app/store/actions/app.actions.ts +++ b/projects/aca-shared/store/src/actions/app.actions.ts @@ -24,57 +24,84 @@ */ import { Action } from '@ngrx/store'; -import { Node, Person, Group } from '@alfresco/js-api'; -import { AppState } from '../states'; - -export const SET_INITIAL_STATE = 'SET_INITIAL_STATE'; -export const SET_LANGUAGE_PICKER = 'SET_LANGUAGE_PICKER'; -export const SET_CURRENT_FOLDER = 'SET_CURRENT_FOLDER'; -export const SET_CURRENT_URL = 'SET_CURRENT_URL'; -export const SET_USER_PROFILE = 'SET_USER_PROFILE'; -export const TOGGLE_INFO_DRAWER = 'TOGGLE_INFO_DRAWER'; -export const TOGGLE_DOCUMENT_DISPLAY_MODE = 'TOGGLE_DOCUMENT_DISPLAY_MODE'; -export const LOGOUT = 'LOGOUT'; -export const RELOAD_DOCUMENT_LIST = 'RELOAD_DOCUMENT_LIST'; +import { Node, Person, Group, RepositoryInfo } from '@alfresco/js-api'; +import { AppState } from '../states/app.state'; + +export enum AppActionTypes { + SetInitialState = 'SET_INITIAL_STATE', + SetLanguagePicker = 'SET_LANGUAGE_PICKER', + SetCurrentFolder = 'SET_CURRENT_FOLDER', + SetCurrentUrl = 'SET_CURRENT_URL', + SetUserProfile = 'SET_USER_PROFILE', + SetRepositoryInfo = 'SET_REPOSITORY_INFO', + ToggleInfoDrawer = 'TOGGLE_INFO_DRAWER', + ToggleDocumentDisplayMode = 'TOGGLE_DOCUMENT_DISPLAY_MODE', + Logout = 'LOGOUT', + ReloadDocumentList = 'RELOAD_DOCUMENT_LIST', + SetInfoDrawerState = 'SET_INFO_DRAWER_STATE', + CloseModalDialogs = 'CLOSE_MODAL_DIALOGS' +} export class SetInitialStateAction implements Action { - readonly type = SET_INITIAL_STATE; + readonly type = AppActionTypes.SetInitialState; + constructor(public payload: AppState) {} } export class SetLanguagePickerAction implements Action { - readonly type = SET_LANGUAGE_PICKER; + readonly type = AppActionTypes.SetLanguagePicker; + constructor(public payload: boolean) {} } export class SetCurrentFolderAction implements Action { - readonly type = SET_CURRENT_FOLDER; + readonly type = AppActionTypes.SetCurrentFolder; + constructor(public payload: Node) {} } export class SetCurrentUrlAction implements Action { - readonly type = SET_CURRENT_URL; + readonly type = AppActionTypes.SetCurrentUrl; + constructor(public payload: string) {} } export class SetUserProfileAction implements Action { - readonly type = SET_USER_PROFILE; + readonly type = AppActionTypes.SetUserProfile; + constructor(public payload: { person: Person; groups: Group[] }) {} } export class ToggleInfoDrawerAction implements Action { - readonly type = TOGGLE_INFO_DRAWER; + readonly type = AppActionTypes.ToggleInfoDrawer; } export class ToggleDocumentDisplayMode implements Action { - readonly type = TOGGLE_DOCUMENT_DISPLAY_MODE; + readonly type = AppActionTypes.ToggleDocumentDisplayMode; } export class LogoutAction implements Action { - readonly type = LOGOUT; + readonly type = AppActionTypes.Logout; } export class ReloadDocumentListAction implements Action { - readonly type = RELOAD_DOCUMENT_LIST; + readonly type = AppActionTypes.ReloadDocumentList; + constructor(public payload?: any) {} } + +export class SetInfoDrawerStateAction implements Action { + readonly type = AppActionTypes.SetInfoDrawerState; + + constructor(public payload: boolean) {} +} + +export class CloseModalDialogsAction implements Action { + readonly type = AppActionTypes.CloseModalDialogs; +} + +export class SetRepositoryInfoAction implements Action { + readonly type = AppActionTypes.SetRepositoryInfo; + + constructor(public payload: RepositoryInfo) {} +} diff --git a/src/app/store/actions/library.actions.ts b/projects/aca-shared/store/src/actions/library.actions.ts similarity index 79% rename from src/app/store/actions/library.actions.ts rename to projects/aca-shared/store/src/actions/library.actions.ts index 9801f13a15..fc3e34c9b7 100644 --- a/src/app/store/actions/library.actions.ts +++ b/projects/aca-shared/store/src/actions/library.actions.ts @@ -26,33 +26,38 @@ import { Action } from '@ngrx/store'; import { SiteBody } from '@alfresco/js-api'; -export const DELETE_LIBRARY = 'DELETE_LIBRARY'; -export const CREATE_LIBRARY = 'CREATE_LIBRARY'; -export const NAVIGATE_LIBRARY = 'NAVIGATE_LIBRARY'; -export const UPDATE_LIBRARY = 'UPDATE_LIBRARY'; -export const LEAVE_LIBRARY = 'LEAVE_LIBRARY'; +export enum LibraryActionTypes { + Delete = 'DELETE_LIBRARY', + Create = 'CREATE_LIBRARY', + Navigate = 'NAVIGATE_LIBRARY', + Update = 'UPDATE_LIBRARY', + Leave = 'LEAVE_LIBRARY' +} export class DeleteLibraryAction implements Action { - readonly type = DELETE_LIBRARY; + readonly type = LibraryActionTypes.Delete; + constructor(public payload?: string) {} } export class CreateLibraryAction implements Action { - readonly type = CREATE_LIBRARY; - constructor() {} + readonly type = LibraryActionTypes.Create; } export class NavigateLibraryAction implements Action { - readonly type = NAVIGATE_LIBRARY; + readonly type = LibraryActionTypes.Navigate; + constructor(public payload?: string) {} } export class UpdateLibraryAction implements Action { - readonly type = UPDATE_LIBRARY; + readonly type = LibraryActionTypes.Update; + constructor(public payload?: SiteBody) {} } export class LeaveLibraryAction implements Action { - readonly type = LEAVE_LIBRARY; + readonly type = LibraryActionTypes.Leave; + constructor(public payload?: string) {} } diff --git a/src/app/store/actions/node.actions.ts b/projects/aca-shared/store/src/actions/node.actions.ts similarity index 63% rename from src/app/store/actions/node.actions.ts rename to projects/aca-shared/store/src/actions/node.actions.ts index bd03557ae4..7fdf132c3f 100644 --- a/src/app/store/actions/node.actions.ts +++ b/projects/aca-shared/store/src/actions/node.actions.ts @@ -26,111 +26,138 @@ import { Action } from '@ngrx/store'; import { MinimalNodeEntity } from '@alfresco/js-api'; -export const SET_SELECTED_NODES = 'SET_SELECTED_NODES'; -export const DELETE_NODES = 'DELETE_NODES'; -export const UNDO_DELETE_NODES = 'UNDO_DELETE_NODES'; -export const RESTORE_DELETED_NODES = 'RESTORE_DELETED_NODES'; -export const PURGE_DELETED_NODES = 'PURGE_DELETED_NODES'; -export const DOWNLOAD_NODES = 'DOWNLOAD_NODES'; -export const CREATE_FOLDER = 'CREATE_FOLDER'; -export const EDIT_FOLDER = 'EDIT_FOLDER'; -export const SHARE_NODE = 'SHARE_NODE'; -export const UNSHARE_NODES = 'UNSHARE_NODES'; -export const COPY_NODES = 'COPY_NODES'; -export const MOVE_NODES = 'MOVE_NODES'; -export const MANAGE_PERMISSIONS = 'MANAGE_PERMISSIONS'; -export const PRINT_FILE = 'PRINT_FILE'; -export const FULLSCREEN_VIEWER = 'FULLSCREEN_VIEWER'; -export const MANAGE_VERSIONS = 'MANAGE_VERSIONS'; -export const EDIT_OFFLINE = 'EDIT_OFFLINE'; -export const UNLOCK_WRITE = 'UNLOCK_WRITE_LOCK'; +export enum NodeActionTypes { + SetSelection = 'SET_SELECTED_NODES', + Delete = 'DELETE_NODES', + UndoDelete = 'UNDO_DELETE_NODES', + RestoreDeleted = 'RESTORE_DELETED_NODES', + PurgeDeleted = 'PURGE_DELETED_NODES', + Download = 'DOWNLOAD_NODES', + CreateFolder = 'CREATE_FOLDER', + EditFolder = 'EDIT_FOLDER', + Share = 'SHARE_NODE', + Unshare = 'UNSHARE_NODES', + Copy = 'COPY_NODES', + Move = 'MOVE_NODES', + ManagePermissions = 'MANAGE_PERMISSIONS', + PrintFile = 'PRINT_FILE', + ManageVersions = 'MANAGE_VERSIONS', + EditOffline = 'EDIT_OFFLINE', + UnlockForWriting = 'UNLOCK_WRITE_LOCK', + AddFavorite = 'ADD_FAVORITE', + RemoveFavorite = 'REMOVE_FAVORITE' +} export class SetSelectedNodesAction implements Action { - readonly type = SET_SELECTED_NODES; + readonly type = NodeActionTypes.SetSelection; + constructor(public payload: MinimalNodeEntity[] = []) {} } export class DeleteNodesAction implements Action { - readonly type = DELETE_NODES; + readonly type = NodeActionTypes.Delete; + constructor(public payload: MinimalNodeEntity[] = []) {} } export class UndoDeleteNodesAction implements Action { - readonly type = UNDO_DELETE_NODES; + readonly type = NodeActionTypes.UndoDelete; + constructor(public payload: any[] = []) {} } export class RestoreDeletedNodesAction implements Action { - readonly type = RESTORE_DELETED_NODES; + readonly type = NodeActionTypes.RestoreDeleted; + constructor(public payload: Array) {} } export class PurgeDeletedNodesAction implements Action { - readonly type = PURGE_DELETED_NODES; + readonly type = NodeActionTypes.PurgeDeleted; + constructor(public payload: Array) {} } export class DownloadNodesAction implements Action { - readonly type = DOWNLOAD_NODES; + readonly type = NodeActionTypes.Download; + constructor(public payload: MinimalNodeEntity[] = []) {} } export class CreateFolderAction implements Action { - readonly type = CREATE_FOLDER; + readonly type = NodeActionTypes.CreateFolder; + constructor(public payload: string) {} } export class EditFolderAction implements Action { - readonly type = EDIT_FOLDER; + readonly type = NodeActionTypes.EditFolder; + constructor(public payload: MinimalNodeEntity) {} } export class ShareNodeAction implements Action { - readonly type = SHARE_NODE; + readonly type = NodeActionTypes.Share; + constructor(public payload: MinimalNodeEntity) {} } export class UnshareNodesAction implements Action { - readonly type = UNSHARE_NODES; + readonly type = NodeActionTypes.Unshare; + constructor(public payload: Array) {} } export class CopyNodesAction implements Action { - readonly type = COPY_NODES; + readonly type = NodeActionTypes.Copy; + constructor(public payload: Array) {} } export class MoveNodesAction implements Action { - readonly type = MOVE_NODES; + readonly type = NodeActionTypes.Move; + constructor(public payload: Array) {} } export class ManagePermissionsAction implements Action { - readonly type = MANAGE_PERMISSIONS; + readonly type = NodeActionTypes.ManagePermissions; + constructor(public payload: MinimalNodeEntity) {} } export class PrintFileAction implements Action { - readonly type = PRINT_FILE; - constructor(public payload: MinimalNodeEntity) {} -} + readonly type = NodeActionTypes.PrintFile; -export class FullscreenViewerAction implements Action { - readonly type = FULLSCREEN_VIEWER; constructor(public payload: MinimalNodeEntity) {} } export class ManageVersionsAction implements Action { - readonly type = MANAGE_VERSIONS; + readonly type = NodeActionTypes.ManageVersions; + constructor(public payload: MinimalNodeEntity) {} } export class EditOfflineAction implements Action { - readonly type = EDIT_OFFLINE; + readonly type = NodeActionTypes.EditOffline; + constructor(public payload: any) {} } export class UnlockWriteAction implements Action { - readonly type = UNLOCK_WRITE; + readonly type = NodeActionTypes.UnlockForWriting; + constructor(public payload: any) {} } + +export class AddFavoriteAction implements Action { + readonly type = NodeActionTypes.AddFavorite; + + constructor(public payload: Array) {} +} + +export class RemoveFavoriteAction implements Action { + readonly type = NodeActionTypes.RemoveFavorite; + + constructor(public payload: Array) {} +} diff --git a/src/app/store/actions/router.actions.ts b/projects/aca-shared/store/src/actions/router.actions.ts similarity index 80% rename from src/app/store/actions/router.actions.ts rename to projects/aca-shared/store/src/actions/router.actions.ts index a29575c762..0bf984ddd4 100644 --- a/src/app/store/actions/router.actions.ts +++ b/projects/aca-shared/store/src/actions/router.actions.ts @@ -26,27 +26,33 @@ import { Action } from '@ngrx/store'; import { MinimalNodeEntity } from '@alfresco/js-api'; -export const NAVIGATE_URL = 'NAVIGATE_URL'; -export const NAVIGATE_ROUTE = 'NAVIGATE_ROUTE'; -export const NAVIGATE_FOLDER = 'NAVIGATE_FOLDER'; -export const NAVIGATE_PARENT_FOLDER = 'NAVIGATE_PARENT_FOLDER'; +export enum RouterActionTypes { + NavigateUrl = 'NAVIGATE_URL', + NavigateRoute = 'NAVIGATE_ROUTE', + NavigateFolder = 'NAVIGATE_FOLDER', + NavigateParentFolder = 'NAVIGATE_PARENT_FOLDER' +} export class NavigateUrlAction implements Action { - readonly type = NAVIGATE_URL; + readonly type = RouterActionTypes.NavigateUrl; + constructor(public payload: string) {} } export class NavigateRouteAction implements Action { - readonly type = NAVIGATE_ROUTE; + readonly type = RouterActionTypes.NavigateRoute; + constructor(public payload: any[]) {} } export class NavigateToFolder implements Action { - readonly type = NAVIGATE_FOLDER; + readonly type = RouterActionTypes.NavigateFolder; + constructor(public payload: MinimalNodeEntity) {} } export class NavigateToParentFolder implements Action { - readonly type = NAVIGATE_PARENT_FOLDER; + readonly type = RouterActionTypes.NavigateParentFolder; + constructor(public payload: MinimalNodeEntity) {} } diff --git a/src/app/store/actions/search.actions.ts b/projects/aca-shared/store/src/actions/search.actions.ts similarity index 76% rename from src/app/store/actions/search.actions.ts rename to projects/aca-shared/store/src/actions/search.actions.ts index 2dc82c123e..0f9fbf5f6c 100644 --- a/src/app/store/actions/search.actions.ts +++ b/projects/aca-shared/store/src/actions/search.actions.ts @@ -24,15 +24,17 @@ */ import { Action } from '@ngrx/store'; -import { SearchOptionModel } from '../models/searchOption.model'; +import { SearchOptionModel } from '../models/search-option.model'; -export const SEARCH_BY_TERM = 'SEARCH_BY_TERM'; -export const TOGGLE_SEARCH_FILTER = 'TOGGLE_SEARCH_FILTER'; -export const SHOW_SEARCH_FILTER = 'SHOW_SEARCH_FILTER'; -export const HIDE_SEARCH_FILTER = 'HIDE_SEARCH_FILTER'; +export enum SearchActionTypes { + SearchByTerm = 'SEARCH_BY_TERM', + ToggleFilter = 'TOGGLE_SEARCH_FILTER', + ShowFilter = 'SHOW_SEARCH_FILTER', + HideFilter = 'HIDE_SEARCH_FILTER' +} export class SearchByTermAction implements Action { - readonly type = SEARCH_BY_TERM; + readonly type = SearchActionTypes.SearchByTerm; constructor( public payload: string, public searchOptions?: SearchOptionModel[] @@ -40,13 +42,13 @@ export class SearchByTermAction implements Action { } export class ToggleSearchFilterAction implements Action { - readonly type = TOGGLE_SEARCH_FILTER; + readonly type = SearchActionTypes.ToggleFilter; } export class ShowSearchFilterAction implements Action { - readonly type = SHOW_SEARCH_FILTER; + readonly type = SearchActionTypes.ShowFilter; } export class HideSearchFilterAction implements Action { - readonly type = HIDE_SEARCH_FILTER; + readonly type = SearchActionTypes.HideFilter; } diff --git a/src/app/store/actions/snackbar.actions.ts b/projects/aca-shared/store/src/actions/snackbar.actions.ts similarity index 88% rename from src/app/store/actions/snackbar.actions.ts rename to projects/aca-shared/store/src/actions/snackbar.actions.ts index 8e95c7f99b..4a65997af8 100644 --- a/src/app/store/actions/snackbar.actions.ts +++ b/projects/aca-shared/store/src/actions/snackbar.actions.ts @@ -25,9 +25,11 @@ import { Action } from '@ngrx/store'; -export const SNACKBAR_INFO = 'SNACKBAR_INFO'; -export const SNACKBAR_WARNING = 'SNACKBAR_WARNING'; -export const SNACKBAR_ERROR = 'SNACKBAR_ERROR'; +export enum SnackbarActionTypes { + Info = 'SNACKBAR_INFO', + Warning = 'SNACKBAR_WARNING', + Error = 'SNACKBAR_ERROR' +} export interface SnackbarAction extends Action { payload: string; @@ -41,7 +43,7 @@ export class SnackbarUserAction { } export class SnackbarInfoAction implements SnackbarAction { - readonly type = SNACKBAR_INFO; + readonly type = SnackbarActionTypes.Info; userAction?: SnackbarUserAction; duration = 4000; @@ -50,7 +52,7 @@ export class SnackbarInfoAction implements SnackbarAction { } export class SnackbarWarningAction implements SnackbarAction { - readonly type = SNACKBAR_WARNING; + readonly type = SnackbarActionTypes.Warning; userAction?: SnackbarUserAction; duration = 4000; @@ -59,7 +61,7 @@ export class SnackbarWarningAction implements SnackbarAction { } export class SnackbarErrorAction implements SnackbarAction { - readonly type = SNACKBAR_ERROR; + readonly type = SnackbarActionTypes.Error; userAction?: SnackbarUserAction; duration = 4000; diff --git a/src/app/store/actions/upload.actions.ts b/projects/aca-shared/store/src/actions/upload.actions.ts similarity index 82% rename from src/app/store/actions/upload.actions.ts rename to projects/aca-shared/store/src/actions/upload.actions.ts index 061c824c22..6d8780b831 100644 --- a/src/app/store/actions/upload.actions.ts +++ b/projects/aca-shared/store/src/actions/upload.actions.ts @@ -25,20 +25,24 @@ import { Action } from '@ngrx/store'; -export const UPLOAD_FILES = 'UPLOAD_FILES'; -export const UPLOAD_FOLDER = 'UPLOAD_FOLDER'; -export const UPLOAD_FILE_VERSION = 'UPLOAD_FILE_VERSION'; +export enum UploadActionTypes { + UploadFiles = 'UPLOAD_FILES', + UploadFolder = 'UPLOAD_FOLDER', + UploadFileVersion = 'UPLOAD_FILE_VERSION' +} export class UploadFilesAction implements Action { - readonly type = UPLOAD_FILES; + readonly type = UploadActionTypes.UploadFiles; + constructor(public payload: any) {} } export class UploadFolderAction implements Action { - readonly type = UPLOAD_FOLDER; + readonly type = UploadActionTypes.UploadFolder; + constructor(public payload: any) {} } export class UploadFileVersionAction implements Action { - readonly type = UPLOAD_FILE_VERSION; + readonly type = UploadActionTypes.UploadFileVersion; } diff --git a/src/app/store/actions/viewer.actions.ts b/projects/aca-shared/store/src/actions/viewer.actions.ts similarity index 79% rename from src/app/store/actions/viewer.actions.ts rename to projects/aca-shared/store/src/actions/viewer.actions.ts index dea6c81e32..1e878b13a4 100644 --- a/src/app/store/actions/viewer.actions.ts +++ b/projects/aca-shared/store/src/actions/viewer.actions.ts @@ -26,15 +26,26 @@ import { Action } from '@ngrx/store'; import { MinimalNodeEntity } from '@alfresco/js-api'; -export const VIEW_FILE = 'VIEW_FILE'; -export const VIEW_NODE = 'VIEW_NODE'; +export enum ViewerActionTypes { + ViewFile = 'VIEW_FILE', + ViewNode = 'VIEW_NODE', + FullScreen = 'FULLSCREEN_VIEWER' +} export class ViewFileAction implements Action { - readonly type = VIEW_FILE; + readonly type = ViewerActionTypes.ViewFile; + constructor(public payload: MinimalNodeEntity, public parentId?: string) {} } export class ViewNodeAction implements Action { - readonly type = VIEW_NODE; + readonly type = ViewerActionTypes.ViewNode; + constructor(public nodeId: string, public location?: string) {} } + +export class FullscreenViewerAction implements Action { + readonly type = ViewerActionTypes.FullScreen; + + constructor(public payload: MinimalNodeEntity) {} +} diff --git a/src/app/store/effects/modals.effects.ts b/projects/aca-shared/store/src/effects/dialog.effects.ts similarity index 85% rename from src/app/store/effects/modals.effects.ts rename to projects/aca-shared/store/src/effects/dialog.effects.ts index 9eb338181f..64ef99ef73 100644 --- a/src/app/store/effects/modals.effects.ts +++ b/projects/aca-shared/store/src/effects/dialog.effects.ts @@ -26,16 +26,19 @@ import { Effect, Actions, ofType } from '@ngrx/effects'; import { Injectable } from '@angular/core'; import { map } from 'rxjs/operators'; -import { CloseModalDialogsAction, CLOSE_MODAL_DIALOGS } from '../actions'; -import { MatDialog } from '@angular/material'; +import { MatDialog } from '@angular/material/dialog'; +import { + CloseModalDialogsAction, + AppActionTypes +} from '../actions/app.actions'; @Injectable() -export class ModalsEffects { +export class DialogEffects { constructor(private actions$: Actions, private matDialog: MatDialog) {} @Effect({ dispatch: false }) closeAll$ = this.actions$.pipe( - ofType(CLOSE_MODAL_DIALOGS), + ofType(AppActionTypes.CloseModalDialogs), map(() => this.matDialog.closeAll()) ); } diff --git a/src/app/store/effects/router.effects.ts b/projects/aca-shared/store/src/effects/router.effects.ts similarity index 91% rename from src/app/store/effects/router.effects.ts rename to projects/aca-shared/store/src/effects/router.effects.ts index 482cc190b2..f39f36985e 100644 --- a/src/app/store/effects/router.effects.ts +++ b/projects/aca-shared/store/src/effects/router.effects.ts @@ -28,19 +28,16 @@ import { Router } from '@angular/router'; import { Actions, Effect, ofType } from '@ngrx/effects'; import { MinimalNodeEntryEntity, PathInfoEntity } from '@alfresco/js-api'; import { map } from 'rxjs/operators'; +import { Store } from '@ngrx/store'; +import { AppStore } from '../states/app.state'; import { + NavigateUrlAction, + RouterActionTypes, NavigateRouteAction, - NavigateToParentFolder, - NAVIGATE_PARENT_FOLDER, - NAVIGATE_ROUTE, NavigateToFolder, - NAVIGATE_FOLDER, - NavigateUrlAction, - NAVIGATE_URL, - SnackbarErrorAction -} from '../actions'; -import { AppStore } from '../states/app.state'; -import { Store } from '@ngrx/store'; + NavigateToParentFolder +} from '../actions/router.actions'; +import { SnackbarErrorAction } from '../actions/snackbar.actions'; @Injectable() export class RouterEffects { @@ -52,7 +49,7 @@ export class RouterEffects { @Effect({ dispatch: false }) navigateUrl$ = this.actions$.pipe( - ofType(NAVIGATE_URL), + ofType(RouterActionTypes.NavigateUrl), map(action => { if (action.payload) { this.router.navigateByUrl(action.payload); @@ -62,7 +59,7 @@ export class RouterEffects { @Effect({ dispatch: false }) navigateRoute$ = this.actions$.pipe( - ofType(NAVIGATE_ROUTE), + ofType(RouterActionTypes.NavigateRoute), map(action => { this.router.navigate(action.payload); }) @@ -70,7 +67,7 @@ export class RouterEffects { @Effect({ dispatch: false }) navigateToFolder$ = this.actions$.pipe( - ofType(NAVIGATE_FOLDER), + ofType(RouterActionTypes.NavigateFolder), map(action => { if (action.payload && action.payload.entry) { this.navigateToFolder(action.payload.entry); @@ -80,7 +77,7 @@ export class RouterEffects { @Effect({ dispatch: false }) navigateToParentFolder$ = this.actions$.pipe( - ofType(NAVIGATE_PARENT_FOLDER), + ofType(RouterActionTypes.NavigateParentFolder), map(action => { if (action.payload && action.payload.entry) { this.navigateToParentFolder(action.payload.entry); diff --git a/src/app/store/effects/snackbar.effects.ts b/projects/aca-shared/store/src/effects/snackbar.effects.ts similarity index 90% rename from src/app/store/effects/snackbar.effects.ts rename to projects/aca-shared/store/src/effects/snackbar.effects.ts index 4f9e476f68..e81fd42cfa 100644 --- a/src/app/store/effects/snackbar.effects.ts +++ b/projects/aca-shared/store/src/effects/snackbar.effects.ts @@ -25,20 +25,18 @@ import { TranslationService } from '@alfresco/adf-core'; import { Injectable } from '@angular/core'; -import { MatSnackBar } from '@angular/material'; +import { MatSnackBar } from '@angular/material/snack-bar'; import { Actions, Effect, ofType } from '@ngrx/effects'; import { Store } from '@ngrx/store'; import { map } from 'rxjs/operators'; +import { AppStore } from '../states/app.state'; import { - SnackbarAction, - SnackbarErrorAction, SnackbarInfoAction, + SnackbarActionTypes, SnackbarWarningAction, - SNACKBAR_ERROR, - SNACKBAR_INFO, - SNACKBAR_WARNING -} from '../actions'; -import { AppStore } from '../states/app.state'; + SnackbarErrorAction, + SnackbarAction +} from '../actions/snackbar.actions'; @Injectable() export class SnackbarEffects { @@ -51,7 +49,7 @@ export class SnackbarEffects { @Effect({ dispatch: false }) infoEffect = this.actions$.pipe( - ofType(SNACKBAR_INFO), + ofType(SnackbarActionTypes.Info), map((action: SnackbarInfoAction) => { this.showSnackBar(action, 'info-snackbar'); }) @@ -59,7 +57,7 @@ export class SnackbarEffects { @Effect({ dispatch: false }) warningEffect = this.actions$.pipe( - ofType(SNACKBAR_WARNING), + ofType(SnackbarActionTypes.Warning), map((action: SnackbarWarningAction) => { this.showSnackBar(action, 'warning-snackbar'); }) @@ -67,7 +65,7 @@ export class SnackbarEffects { @Effect({ dispatch: false }) errorEffect = this.actions$.pipe( - ofType(SNACKBAR_ERROR), + ofType(SnackbarActionTypes.Error), map((action: SnackbarErrorAction) => { this.showSnackBar(action, 'error-snackbar'); }) diff --git a/src/app/store/models/delete-status.model.ts b/projects/aca-shared/store/src/models/delete-status.model.ts similarity index 100% rename from src/app/store/models/delete-status.model.ts rename to projects/aca-shared/store/src/models/delete-status.model.ts diff --git a/src/app/store/models/deleted-node-info.model.ts b/projects/aca-shared/store/src/models/deleted-node-info.model.ts similarity index 100% rename from src/app/store/models/deleted-node-info.model.ts rename to projects/aca-shared/store/src/models/deleted-node-info.model.ts diff --git a/src/app/store/models/node-info.model.ts b/projects/aca-shared/store/src/models/node-info.model.ts similarity index 100% rename from src/app/store/models/node-info.model.ts rename to projects/aca-shared/store/src/models/node-info.model.ts diff --git a/src/app/store/models/searchOption.model.ts b/projects/aca-shared/store/src/models/search-option.model.ts similarity index 100% rename from src/app/store/models/searchOption.model.ts rename to projects/aca-shared/store/src/models/search-option.model.ts diff --git a/src/app/store/actions.ts b/projects/aca-shared/store/src/public_api.ts similarity index 77% rename from src/app/store/actions.ts rename to projects/aca-shared/store/src/public_api.ts index 07a23b8dae..0a8d248323 100644 --- a/src/app/store/actions.ts +++ b/projects/aca-shared/store/src/public_api.ts @@ -24,15 +24,25 @@ */ export * from './actions/app.actions'; -export * from './actions/favorite.actions'; +export * from './actions/library.actions'; export * from './actions/node.actions'; -export * from './actions/snackbar.actions'; export * from './actions/router.actions'; -export * from './actions/viewer.actions'; export * from './actions/search.actions'; -export * from './actions/library.actions'; -export * from './actions/upload.actions'; -export * from './actions/modals.actions'; -export * from './actions/repository.actions'; -export * from './actions/info-drawer.actions'; +export * from './actions/snackbar.actions'; export * from './actions/upload.actions'; +export * from './actions/viewer.actions'; + +export * from './effects/dialog.effects'; +export * from './effects/router.effects'; +export * from './effects/snackbar.effects'; + +export * from './models/delete-status.model'; +export * from './models/deleted-node-info.model'; +export * from './models/node-info.model'; +export * from './models/search-option.model'; + +export * from './selectors/app.selectors'; + +export * from './states/app.state'; + +export * from './store.module'; diff --git a/src/app/store/selectors/app.selectors.ts b/projects/aca-shared/store/src/selectors/app.selectors.ts similarity index 74% rename from src/app/store/selectors/app.selectors.ts rename to projects/aca-shared/store/src/selectors/app.selectors.ts index baaa7aad4f..fb027a4d53 100644 --- a/src/app/store/selectors/app.selectors.ts +++ b/projects/aca-shared/store/src/selectors/app.selectors.ts @@ -23,57 +23,57 @@ * along with Alfresco. If not, see . */ -import { createSelector } from '@ngrx/store'; import { AppStore } from '../states/app.state'; +import { createSelector } from '@ngrx/store'; export const selectApp = (state: AppStore) => state.app; -export const selectHeaderColor = createSelector( +export const getHeaderColor = createSelector( selectApp, state => state.headerColor ); -export const selectAppName = createSelector( +export const getAppName = createSelector( selectApp, state => state.appName ); -export const selectLogoPath = createSelector( +export const getLogoPath = createSelector( selectApp, state => state.logoPath ); -export const appSelection = createSelector( +export const getLanguagePickerState = createSelector( selectApp, - state => state.selection + state => state.languagePicker ); -export const appLanguagePicker = createSelector( +export const getUserProfile = createSelector( selectApp, - state => state.languagePicker + state => state.user ); -export const selectUser = createSelector( +export const getCurrentFolder = createSelector( selectApp, - state => state.user + state => state.navigation.currentFolder ); -export const sharedUrl = createSelector( +export const getAppSelection = createSelector( selectApp, - state => state.sharedUrl + state => state.selection ); -export const appNavigation = createSelector( +export const getSharedUrl = createSelector( selectApp, - state => state.navigation + state => state.sharedUrl ); -export const currentFolder = createSelector( +export const getNavigationState = createSelector( selectApp, - state => state.navigation.currentFolder + state => state.navigation ); -export const infoDrawerOpened = createSelector( +export const isInfoDrawerOpened = createSelector( selectApp, state => state.infoDrawerOpened ); @@ -83,18 +83,18 @@ export const showFacetFilter = createSelector( state => state.showFacetFilter ); -export const documentDisplayMode = createSelector( +export const getDocumentDisplayMode = createSelector( selectApp, state => state.documentDisplayMode ); -export const repositoryStatus = createSelector( +export const getRepositoryStatus = createSelector( selectApp, state => state.repository ); export const isQuickShareEnabled = createSelector( - repositoryStatus, + getRepositoryStatus, info => info.status.isQuickShareEnabled ); @@ -103,9 +103,9 @@ export const isAdmin = createSelector( state => state.user.isAdmin ); -export const sidenavState = createSelector( - appSelection, - appNavigation, +export const getSideNavState = createSelector( + getAppSelection, + getNavigationState, (selection, navigation) => { return { selection, @@ -114,11 +114,11 @@ export const sidenavState = createSelector( } ); -export const ruleContext = createSelector( - appSelection, - appNavigation, - selectUser, - repositoryStatus, +export const getRuleContext = createSelector( + getAppSelection, + getNavigationState, + getUserProfile, + getRepositoryStatus, (selection, navigation, profile, repository) => { return { selection, diff --git a/src/app/store/actions/favorite.actions.ts b/projects/aca-shared/store/src/states/app.state.ts similarity index 67% rename from src/app/store/actions/favorite.actions.ts rename to projects/aca-shared/store/src/states/app.state.ts index 1c4a23e1d7..763920c435 100644 --- a/src/app/store/actions/favorite.actions.ts +++ b/projects/aca-shared/store/src/states/app.state.ts @@ -23,18 +23,28 @@ * along with Alfresco. If not, see . */ -import { Action } from '@ngrx/store'; -import { MinimalNodeEntity } from '@alfresco/js-api'; +import { + SelectionState, + ProfileState, + NavigationState +} from '@alfresco/adf-extensions'; +import { RepositoryInfo } from '@alfresco/js-api'; -export const ADD_FAVORITE = 'ADD_FAVORITE'; -export const REMOVE_FAVORITE = 'REMOVE_FAVORITE'; - -export class AddFavoriteAction implements Action { - readonly type = ADD_FAVORITE; - constructor(public payload: Array) {} +export interface AppState { + appName: string; + headerColor: string; + logoPath: string; + languagePicker: boolean; + sharedUrl: string; + selection: SelectionState; + user: ProfileState; + navigation: NavigationState; + infoDrawerOpened: boolean; + showFacetFilter: boolean; + documentDisplayMode: string; + repository: RepositoryInfo; } -export class RemoveFavoriteAction implements Action { - readonly type = REMOVE_FAVORITE; - constructor(public payload: Array) {} +export interface AppStore { + app: AppState; } diff --git a/src/app/store/actions/repository.actions.ts b/projects/aca-shared/store/src/store.module.ts similarity index 73% rename from src/app/store/actions/repository.actions.ts rename to projects/aca-shared/store/src/store.module.ts index cc32083410..9e49250699 100644 --- a/src/app/store/actions/repository.actions.ts +++ b/projects/aca-shared/store/src/store.module.ts @@ -23,12 +23,15 @@ * along with Alfresco. If not, see . */ -import { Action } from '@ngrx/store'; -import { RepositoryInfo } from '@alfresco/js-api'; +import { NgModule } from '@angular/core'; +import { EffectsModule } from '@ngrx/effects'; +import { SnackbarEffects } from './effects/snackbar.effects'; +import { DialogEffects } from './effects/dialog.effects'; +import { RouterEffects } from './effects/router.effects'; -export const SET_REPOSITORY_INFO = 'SET_REPOSITORY_INFO'; - -export class SetRepositoryInfoAction implements Action { - readonly type = SET_REPOSITORY_INFO; - constructor(public payload: RepositoryInfo) {} -} +@NgModule({ + imports: [ + EffectsModule.forFeature([SnackbarEffects, DialogEffects, RouterEffects]) + ] +}) +export class SharedStoreModule {} diff --git a/projects/aca-shared/test.ts b/projects/aca-shared/test.ts new file mode 100644 index 0000000000..e11ff1c97b --- /dev/null +++ b/projects/aca-shared/test.ts @@ -0,0 +1,22 @@ +// This file is required by karma.conf.js and loads recursively all the .spec and framework files + +import 'core-js/es7/reflect'; +import 'zone.js/dist/zone'; +import 'zone.js/dist/zone-testing'; +import { getTestBed } from '@angular/core/testing'; +import { + BrowserDynamicTestingModule, + platformBrowserDynamicTesting +} from '@angular/platform-browser-dynamic/testing'; + +declare const require: any; + +// First, initialize the Angular testing environment. +getTestBed().initTestEnvironment( + BrowserDynamicTestingModule, + platformBrowserDynamicTesting() +); +// Then we find all the tests. +const context = require.context('./', true, /\.spec\.ts$/); +// And load the modules. +context.keys().map(context); diff --git a/projects/aca-shared/tsconfig.lib.json b/projects/aca-shared/tsconfig.lib.json new file mode 100644 index 0000000000..f407ef6a41 --- /dev/null +++ b/projects/aca-shared/tsconfig.lib.json @@ -0,0 +1,29 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "../../out-tsc/lib", + "target": "es2015", + "module": "es2015", + "moduleResolution": "node", + "declaration": true, + "sourceMap": true, + "inlineSources": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "importHelpers": true, + "types": [], + "lib": ["dom", "es2018"], + "paths": { + "@alfresco/aca-shared/*": ["./*"] + } + }, + "angularCompilerOptions": { + "annotateForClosureCompiler": true, + "skipTemplateCodegen": true, + "strictMetadataEmit": true, + "fullTemplateTypeCheck": true, + "strictInjectionParameters": true, + "enableResourceInlining": true + }, + "exclude": ["test.ts", "**/*.spec.ts"] +} diff --git a/projects/aca-shared/tsconfig.spec.json b/projects/aca-shared/tsconfig.spec.json new file mode 100644 index 0000000000..c1d29e83b6 --- /dev/null +++ b/projects/aca-shared/tsconfig.spec.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "../../out-tsc/spec", + "types": ["jasmine", "node"] + }, + "files": ["test.ts"], + "include": ["**/*.spec.ts", "**/*.d.ts"] +} diff --git a/projects/aca-shared/tslint.json b/projects/aca-shared/tslint.json new file mode 100644 index 0000000000..fdc7ace612 --- /dev/null +++ b/projects/aca-shared/tslint.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tslint.json", + "rules": { + "directive-selector": [true, "attribute", "aca", "camelCase"], + "component-selector": [true, "element", "aca", "kebab-case"] + } +} diff --git a/projects/adf-office-services-ext/package.json b/projects/adf-office-services-ext/package.json index 849fd06b6e..2d4e11c5ff 100644 --- a/projects/adf-office-services-ext/package.json +++ b/projects/adf-office-services-ext/package.json @@ -2,17 +2,6 @@ "name": "@alfresco/adf-office-services-ext", "version": "0.0.6", "license": "Apache-2.0", - "author": { - "name": "Keensoft", - "url": "http://www.keensoft.es/en/" - }, - "contributors": [ - { - "name": "Denys Vuika", - "email": "denys.vuka@gmail.com", - "url": "https://medium.com/@denysvuika" - } - ], "homepage": "https://github.com/Alfresco/alfresco-content-app", "keywords": ["Alfresco", "ADF", "ACA", "Content Application"], "peerDependencies": { diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts index 368016e760..b5c55f0bc6 100644 --- a/src/app/app.component.spec.ts +++ b/src/app/app.component.spec.ts @@ -24,7 +24,7 @@ */ import { AppComponent } from './app.component'; -import { SetInitialStateAction } from './store/actions'; +import { SetInitialStateAction } from '@alfresco/aca-shared/store'; describe('AppComponent', () => { let component: AppComponent; diff --git a/src/app/app.component.ts b/src/app/app.component.ts index f78f01bd7d..0295f27022 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -36,23 +36,20 @@ import { ActivatedRoute, NavigationEnd, Router } from '@angular/router'; import { Store } from '@ngrx/store'; import { AppExtensionService } from './extensions/extension.service'; import { - SnackbarErrorAction, + AppStore, + AppState, SetCurrentUrlAction, SetInitialStateAction, + SetUserProfileAction, + SnackbarErrorAction, CloseModalDialogsAction, - SetRepositoryInfoAction, - SetUserProfileAction -} from './store/actions'; -import { - AppStore, - AppState, - INITIAL_APP_STATE -} from './store/states/app.state'; + SetRepositoryInfoAction +} from '@alfresco/aca-shared/store'; import { filter, takeUntil } from 'rxjs/operators'; -import { ContentApiService } from './services/content-api.service'; +import { AppService, ContentApiService } from '@alfresco/aca-shared'; import { DiscoveryEntry, GroupsApi, Group } from '@alfresco/js-api'; -import { AppService } from './services/app.service'; import { Subject } from 'rxjs'; +import { INITIAL_APP_STATE } from './store/initial-state'; @Component({ selector: 'app-root', diff --git a/src/app/app.module.ts b/src/app/app.module.ts index c8068b0347..d74c500035 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -41,6 +41,7 @@ import { LibraryDialogComponent, ContentModule } from '@alfresco/adf-content-services'; +import { AppRouteReuseStrategy, SharedModule } from '@alfresco/aca-shared'; import { AppComponent } from './app.component'; import { APP_ROUTES } from './app.routes'; @@ -55,7 +56,6 @@ import { AppStoreModule } from './store/app-store.module'; import { MaterialModule } from './material.module'; import { AppExtensionsModule } from './extensions.module'; import { CoreExtensionsModule } from './extensions/core.extensions.module'; -import { AppRouteReuseStrategy } from './app.routes.strategy'; import { AppInfoDrawerModule } from './components/info-drawer/info.drawer.module'; import { DirectivesModule } from './directives/directives.module'; import { ContextMenuModule } from './components/context-menu/context-menu.module'; @@ -89,6 +89,7 @@ import { environment } from '../environments/environment'; MaterialModule, CoreModule.forRoot(), ContentModule.forRoot(), + SharedModule.forRoot(), AppStoreModule, CoreExtensionsModule.forRoot(), ExtensionsModule, diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index 0fa7814d4d..92da4e42f4 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -28,11 +28,13 @@ import { AppLayoutComponent } from './components/layout/app-layout/app-layout.co import { FilesComponent } from './components/files/files.component'; import { LibrariesComponent } from './components/libraries/libraries.component'; import { FavoriteLibrariesComponent } from './components/favorite-libraries/favorite-libraries.component'; -import { GenericErrorComponent } from './components/common/generic-error/generic-error.component'; import { SearchResultsComponent } from './components/search/search-results/search-results.component'; import { SearchLibrariesResultsComponent } from './components/search/search-libraries-results/search-libraries-results.component'; import { LoginComponent } from './components/login/login.component'; -import { AppSharedRuleGuard } from './guards/shared.guard'; +import { + AppSharedRuleGuard, + GenericErrorComponent +} from '@alfresco/aca-shared'; import { AuthGuardEcm } from '@alfresco/adf-core'; export const APP_ROUTES: Routes = [ diff --git a/src/app/components/about/about.component.html b/src/app/components/about/about.component.html index 80891c6d25..643e33c9c3 100644 --- a/src/app/components/about/about.component.html +++ b/src/app/components/about/about.component.html @@ -1,5 +1,5 @@ - - + +
{{ 'application.name' | adfAppConfig }}
@@ -43,5 +43,5 @@
-
-
+ + diff --git a/src/app/components/about/about.component.ts b/src/app/components/about/about.component.ts index c6e1720991..eb28b814ec 100644 --- a/src/app/components/about/about.component.ts +++ b/src/app/components/about/about.component.ts @@ -29,7 +29,7 @@ import { RepositoryInfo } from '@alfresco/js-api'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; import { AppExtensionService } from '../../extensions/extension.service'; -import { ContentApiService } from '../../services/content-api.service'; +import { ContentApiService } from '@alfresco/aca-shared'; import { version, dependencies } from '../../../../package.json'; @Component({ selector: 'app-about', diff --git a/src/app/components/about/about.module.ts b/src/app/components/about/about.module.ts index aa2fd1beac..2af7d50871 100644 --- a/src/app/components/about/about.module.ts +++ b/src/app/components/about/about.module.ts @@ -29,7 +29,7 @@ import { AboutComponent } from './about.component'; import { CommonModule } from '@angular/common'; import { CoreModule } from '@alfresco/adf-core'; import { AppLayoutModule } from '../layout/layout.module'; -import { MatTableModule } from '@angular/material'; +import { MatTableModule } from '@angular/material/table'; import { PackageListComponent } from './package-list/package-list.component'; import { ExtensionListComponent } from './extension-list/extension-list.component'; import { StatusListComponent } from './status-list/status-list.component'; diff --git a/src/app/components/common/common.module.ts b/src/app/components/common/common.module.ts index c1a0973e76..fbda679d47 100644 --- a/src/app/components/common/common.module.ts +++ b/src/app/components/common/common.module.ts @@ -23,23 +23,22 @@ * along with Alfresco. If not, see . */ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { GenericErrorComponent } from './generic-error/generic-error.component'; import { CoreModule } from '@alfresco/adf-core'; -import { LocationLinkComponent } from './location-link/location-link.component'; -import { MatIconModule } from '@angular/material'; import { ExtensionsModule } from '@alfresco/adf-extensions'; +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { GenericErrorModule } from '@alfresco/aca-shared'; +import { LocationLinkComponent } from './location-link/location-link.component'; @NgModule({ imports: [ CommonModule, CoreModule.forChild(), - MatIconModule, - ExtensionsModule + ExtensionsModule, + GenericErrorModule ], - declarations: [GenericErrorComponent, LocationLinkComponent], - exports: [ExtensionsModule, GenericErrorComponent, LocationLinkComponent], + declarations: [LocationLinkComponent], + exports: [ExtensionsModule, LocationLinkComponent, GenericErrorModule], entryComponents: [LocationLinkComponent] }) export class AppCommonModule {} diff --git a/src/app/components/common/generic-error/generic-error.component.theme.scss b/src/app/components/common/generic-error/generic-error.component.theme.scss deleted file mode 100644 index d921cc072a..0000000000 --- a/src/app/components/common/generic-error/generic-error.component.theme.scss +++ /dev/null @@ -1,27 +0,0 @@ -@mixin aca-generic-error-theme($theme) { - $warn: map-get($theme, warn); - $foreground: map-get($theme, foreground); - - .aca-generic-error { - color: mat-color($foreground, text, 0.54); - - display: flex; - align-items: center; - justify-content: center; - flex-direction: column; - width: 100%; - height: 100%; - - &__title { - font-size: 16px; - } - - mat-icon { - color: mat-color($warn); - direction: rtl; - font-size: 52px; - height: 52px; - width: 52px; - } - } -} diff --git a/src/app/components/common/location-link/location-link.component.ts b/src/app/components/common/location-link/location-link.component.ts index 5e9839d95d..147dca68ea 100644 --- a/src/app/components/common/location-link/location-link.component.ts +++ b/src/app/components/common/location-link/location-link.component.ts @@ -35,9 +35,8 @@ import { PathInfo, MinimalNodeEntity } from '@alfresco/js-api'; import { Observable, BehaviorSubject, of } from 'rxjs'; import { Store } from '@ngrx/store'; -import { AppStore } from '../../../store/states/app.state'; -import { NavigateToParentFolder } from '../../../store/actions'; -import { ContentApiService } from '../../../services/content-api.service'; +import { AppStore, NavigateToParentFolder } from '@alfresco/aca-shared/store'; +import { ContentApiService } from '@alfresco/aca-shared'; import { TranslationService } from '@alfresco/adf-core'; @Component({ diff --git a/src/app/components/context-menu/context-menu.component.ts b/src/app/components/context-menu/context-menu.component.ts index c657770e00..4fae5f5383 100644 --- a/src/app/components/context-menu/context-menu.component.ts +++ b/src/app/components/context-menu/context-menu.component.ts @@ -32,11 +32,10 @@ import { ViewChild, AfterViewInit } from '@angular/core'; -import { MatMenuTrigger } from '@angular/material'; +import { MatMenuTrigger } from '@angular/material/menu'; import { AppExtensionService } from '../../extensions/extension.service'; -import { AppStore } from '../../store/states'; -import { appSelection } from '../../store/selectors/app.selectors'; +import { AppStore, getAppSelection } from '@alfresco/aca-shared/store'; import { Store } from '@ngrx/store'; import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; @@ -91,7 +90,7 @@ export class ContextMenuComponent implements OnInit, OnDestroy, AfterViewInit { ngOnInit() { this.store - .select(appSelection) + .select(getAppSelection) .pipe(takeUntil(this.onDestroy$)) .subscribe(selection => { if (selection.count) { diff --git a/src/app/components/context-menu/context-menu.module.ts b/src/app/components/context-menu/context-menu.module.ts index 90b203d424..a6f298bd92 100644 --- a/src/app/components/context-menu/context-menu.module.ts +++ b/src/app/components/context-menu/context-menu.module.ts @@ -23,22 +23,19 @@ * along with Alfresco. If not, see . */ -import { NgModule } from '@angular/core'; -import { - MatMenuModule, - MatListModule, - MatIconModule, - MatButtonModule -} from '@angular/material'; import { CoreModule } from '@alfresco/adf-core'; -import { CoreExtensionsModule } from '../../extensions/core.extensions.module'; - -import { ContextActionsDirective } from './context-menu.directive'; -import { ContextMenuComponent } from './context-menu.component'; import { ExtensionsModule } from '@alfresco/adf-extensions'; -import { OutsideEventDirective } from './context-menu-outside-event.directive'; -import { ContextMenuItemComponent } from './context-menu-item.component'; +import { NgModule } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { MatIconModule } from '@angular/material/icon'; +import { MatListModule } from '@angular/material/list'; +import { MatMenuModule } from '@angular/material/menu'; +import { CoreExtensionsModule } from '../../extensions/core.extensions.module'; import { AppCommonModule } from '../common/common.module'; +import { ContextMenuItemComponent } from './context-menu-item.component'; +import { OutsideEventDirective } from './context-menu-outside-event.directive'; +import { ContextMenuComponent } from './context-menu.component'; +import { ContextActionsDirective } from './context-menu.directive'; @NgModule({ imports: [ diff --git a/src/app/components/create-menu/create-menu.component.ts b/src/app/components/create-menu/create-menu.component.ts index a57b6dfd82..158c953316 100644 --- a/src/app/components/create-menu/create-menu.component.ts +++ b/src/app/components/create-menu/create-menu.component.ts @@ -31,10 +31,9 @@ import { ViewEncapsulation } from '@angular/core'; import { ContentActionRef } from '@alfresco/adf-extensions'; -import { AppStore } from '../../store/states'; +import { AppStore, getCurrentFolder } from '@alfresco/aca-shared/store'; import { AppExtensionService } from '../../extensions/extension.service'; import { Store } from '@ngrx/store'; -import { currentFolder } from '../../store/selectors/app.selectors'; import { takeUntil } from 'rxjs/operators'; import { Subject } from 'rxjs'; @@ -62,7 +61,7 @@ export class CreateMenuComponent implements OnInit, OnDestroy { ngOnInit() { this.store - .select(currentFolder) + .select(getCurrentFolder) .pipe(takeUntil(this.onDestroy$)) .subscribe(() => { this.createActions = this.extensions.getCreateActions(); diff --git a/src/app/components/current-user/current-user.component.ts b/src/app/components/current-user/current-user.component.ts index 64750e9ab8..8016bc6a68 100644 --- a/src/app/components/current-user/current-user.component.ts +++ b/src/app/components/current-user/current-user.component.ts @@ -26,14 +26,14 @@ import { Component, ViewEncapsulation } from '@angular/core'; import { Store } from '@ngrx/store'; import { Observable } from 'rxjs'; -import { - selectUser, - appLanguagePicker -} from '../../store/selectors/app.selectors'; -import { AppStore } from '../../store/states'; import { ProfileState } from '@alfresco/adf-extensions'; -import { SetSelectedNodesAction } from '../../store/actions'; -import { AppService } from '../../services/app.service'; +import { + AppStore, + SetSelectedNodesAction, + getUserProfile, + getLanguagePickerState +} from '@alfresco/aca-shared/store'; +import { AppService } from '@alfresco/aca-shared'; @Component({ selector: 'aca-current-user', @@ -50,8 +50,8 @@ export class CurrentUserComponent { } constructor(private store: Store, private appService: AppService) { - this.profile$ = this.store.select(selectUser); - this.languagePicker$ = store.select(appLanguagePicker); + this.profile$ = this.store.select(getUserProfile); + this.languagePicker$ = store.select(getLanguagePickerState); } onLogoutEvent() { diff --git a/src/app/components/dl-custom-components/name-column/name-column.component.ts b/src/app/components/dl-custom-components/name-column/name-column.component.ts index 6c24c8e9da..574ff07ed1 100644 --- a/src/app/components/dl-custom-components/name-column/name-column.component.ts +++ b/src/app/components/dl-custom-components/name-column/name-column.component.ts @@ -28,7 +28,7 @@ import { import { Actions, ofType } from '@ngrx/effects'; import { Subject } from 'rxjs'; import { filter, takeUntil } from 'rxjs/operators'; -import { EDIT_OFFLINE } from '../../../store/actions'; +import { NodeActionTypes } from '@alfresco/aca-shared/store'; import { isLocked } from '../../../utils/node.utils'; @Component({ @@ -75,7 +75,7 @@ export class CustomNameColumnComponent extends NameColumnComponent this.actions$ .pipe( - ofType(EDIT_OFFLINE), + ofType(NodeActionTypes.EditOffline), filter(val => { return this.node.entry.id === val.payload.entry.id; }), diff --git a/src/app/components/favorite-libraries/favorite-libraries.component.html b/src/app/components/favorite-libraries/favorite-libraries.component.html index dc5a8606ed..bfd55f129f 100644 --- a/src/app/components/favorite-libraries/favorite-libraries.component.html +++ b/src/app/components/favorite-libraries/favorite-libraries.component.html @@ -1,5 +1,5 @@ - - + + @@ -8,9 +8,9 @@ - + - +
-
-
+ + diff --git a/src/app/components/favorite-libraries/favorite-libraries.component.spec.ts b/src/app/components/favorite-libraries/favorite-libraries.component.spec.ts index 25c9d64e4a..3671bb482a 100644 --- a/src/app/components/favorite-libraries/favorite-libraries.component.spec.ts +++ b/src/app/components/favorite-libraries/favorite-libraries.component.spec.ts @@ -36,11 +36,12 @@ import { import { DocumentListComponent } from '@alfresco/adf-content-services'; import { FavoriteLibrariesComponent } from './favorite-libraries.component'; import { AppTestingModule } from '../../testing/app-testing.module'; -import { ContentApiService } from '../../services/content-api.service'; +import { ContentApiService } from '@alfresco/aca-shared'; import { ContentManagementService } from '../../services/content-management.service'; import { EffectsModule } from '@ngrx/effects'; -import { LibraryEffects, RouterEffects } from '../../store/effects'; +import { RouterEffects } from '@alfresco/aca-shared/store'; import { of, throwError } from 'rxjs'; +import { LibraryEffects } from '../../store/effects'; describe('FavoriteLibrariesComponent', () => { let fixture: ComponentFixture; diff --git a/src/app/components/favorite-libraries/favorite-libraries.component.ts b/src/app/components/favorite-libraries/favorite-libraries.component.ts index dbeb309751..aad1a83fd6 100644 --- a/src/app/components/favorite-libraries/favorite-libraries.component.ts +++ b/src/app/components/favorite-libraries/favorite-libraries.component.ts @@ -29,9 +29,8 @@ import { Store } from '@ngrx/store'; import { SiteEntry, FavoritePaging, Pagination } from '@alfresco/js-api'; import { AppExtensionService } from '../../extensions/extension.service'; import { ContentManagementService } from '../../services/content-management.service'; -import { ContentApiService } from '../../services/content-api.service'; -import { NavigateLibraryAction } from '../../store/actions'; -import { AppStore } from '../../store/states/app.state'; +import { ContentApiService } from '@alfresco/aca-shared'; +import { NavigateLibraryAction } from '@alfresco/aca-shared/store'; import { PageComponent } from '../page.component'; import { UserPreferencesService } from '@alfresco/adf-core'; @Component({ @@ -47,7 +46,7 @@ export class FavoriteLibrariesComponent extends PageComponent constructor( content: ContentManagementService, - store: Store, + store: Store, extensions: AppExtensionService, private contentApiService: ContentApiService, private breakpointObserver: BreakpointObserver, diff --git a/src/app/components/favorites/favorites.component.html b/src/app/components/favorites/favorites.component.html index 264653ba6e..bcad87fe73 100644 --- a/src/app/components/favorites/favorites.component.html +++ b/src/app/components/favorites/favorites.component.html @@ -1,5 +1,5 @@ - - + + @@ -7,9 +7,9 @@ - + - +
-
-
+ + diff --git a/src/app/components/favorites/favorites.component.spec.ts b/src/app/components/favorites/favorites.component.spec.ts index c2e3efe17a..36c4bcfe03 100644 --- a/src/app/components/favorites/favorites.component.spec.ts +++ b/src/app/components/favorites/favorites.component.spec.ts @@ -36,7 +36,7 @@ import { DocumentListComponent } from '@alfresco/adf-content-services'; import { of } from 'rxjs'; import { FavoritesComponent } from './favorites.component'; import { AppTestingModule } from '../../testing/app-testing.module'; -import { ContentApiService } from '../../services/content-api.service'; +import { ContentApiService } from '@alfresco/aca-shared'; describe('FavoritesComponent', () => { let fixture: ComponentFixture; diff --git a/src/app/components/favorites/favorites.component.ts b/src/app/components/favorites/favorites.component.ts index 6cedd515d8..b95691714d 100644 --- a/src/app/components/favorites/favorites.component.ts +++ b/src/app/components/favorites/favorites.component.ts @@ -23,23 +23,23 @@ * along with Alfresco. If not, see . */ -import { Component, OnInit } from '@angular/core'; -import { Router } from '@angular/router'; -import { Store } from '@ngrx/store'; -import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout'; +import { ContentApiService } from '@alfresco/aca-shared'; +import { AppStore } from '@alfresco/aca-shared/store'; +import { UploadService } from '@alfresco/adf-core'; import { MinimalNodeEntity, MinimalNodeEntryEntity, PathElementEntity, PathInfo } from '@alfresco/js-api'; +import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout'; +import { Component, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; +import { Store } from '@ngrx/store'; +import { debounceTime, map } from 'rxjs/operators'; +import { AppExtensionService } from '../../extensions/extension.service'; import { ContentManagementService } from '../../services/content-management.service'; -import { AppStore } from '../../store/states/app.state'; import { PageComponent } from '../page.component'; -import { ContentApiService } from '../../services/content-api.service'; -import { AppExtensionService } from '../../extensions/extension.service'; -import { map, debounceTime } from 'rxjs/operators'; -import { UploadService } from '@alfresco/adf-core'; @Component({ templateUrl: './favorites.component.html' diff --git a/src/app/components/files/files.component.html b/src/app/components/files/files.component.html index d830a3bc7a..6fb5b6a3b0 100644 --- a/src/app/components/files/files.component.html +++ b/src/app/components/files/files.component.html @@ -1,5 +1,5 @@ - - + + - + - + - + - +
-
-
+ + diff --git a/src/app/components/files/files.component.spec.ts b/src/app/components/files/files.component.spec.ts index 114e642e92..4f34863727 100644 --- a/src/app/components/files/files.component.spec.ts +++ b/src/app/components/files/files.component.spec.ts @@ -41,7 +41,7 @@ import { DocumentListComponent } from '@alfresco/adf-content-services'; import { NodeActionsService } from '../../services/node-actions.service'; import { FilesComponent } from './files.component'; import { AppTestingModule } from '../../testing/app-testing.module'; -import { ContentApiService } from '../../services/content-api.service'; +import { ContentApiService } from '@alfresco/aca-shared'; import { of, throwError } from 'rxjs'; describe('FilesComponent', () => { diff --git a/src/app/components/files/files.component.ts b/src/app/components/files/files.component.ts index 4aaa12f79e..7aedc31dd0 100644 --- a/src/app/components/files/files.component.ts +++ b/src/app/components/files/files.component.ts @@ -35,14 +35,13 @@ import { } from '@alfresco/js-api'; import { ContentManagementService } from '../../services/content-management.service'; import { NodeActionsService } from '../../services/node-actions.service'; -import { AppStore } from '../../store/states/app.state'; +import { AppStore } from '@alfresco/aca-shared/store'; import { PageComponent } from '../page.component'; -import { ContentApiService } from '../../services/content-api.service'; +import { ContentApiService } from '@alfresco/aca-shared'; import { AppExtensionService } from '../../extensions/extension.service'; -import { SetCurrentFolderAction } from '../../store/actions'; +import { SetCurrentFolderAction, isAdmin } from '@alfresco/aca-shared/store'; import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout'; import { debounceTime, takeUntil } from 'rxjs/operators'; -import { isAdmin } from '../../store/selectors/app.selectors'; import { ShareDataRow } from '@alfresco/adf-content-services'; @Component({ diff --git a/src/app/components/header/header.component.ts b/src/app/components/header/header.component.ts index b22cfd55b1..c592a9ecc8 100644 --- a/src/app/components/header/header.component.ts +++ b/src/app/components/header/header.component.ts @@ -32,14 +32,14 @@ import { } from '@angular/core'; import { Store } from '@ngrx/store'; import { Observable } from 'rxjs'; -import { - selectHeaderColor, - selectAppName, - selectLogoPath -} from '../../store/selectors/app.selectors'; import { ContentActionRef } from '@alfresco/adf-extensions'; import { AppExtensionService } from '../../extensions/extension.service'; -import { AppStore } from '../../store/states'; +import { + AppStore, + getHeaderColor, + getAppName, + getLogoPath +} from '@alfresco/aca-shared/store'; @Component({ selector: 'app-header', @@ -61,9 +61,9 @@ export class AppHeaderComponent implements OnInit { store: Store, private appExtensions: AppExtensionService ) { - this.headerColor$ = store.select(selectHeaderColor); - this.appName$ = store.select(selectAppName); - this.logo$ = store.select(selectLogoPath); + this.headerColor$ = store.select(getHeaderColor); + this.appName$ = store.select(getAppName); + this.logo$ = store.select(getLogoPath); } ngOnInit() { diff --git a/src/app/components/info-drawer/comments-tab/comments-tab.component.spec.ts b/src/app/components/info-drawer/comments-tab/comments-tab.component.spec.ts index 64a45ccbfb..35a502ff1e 100644 --- a/src/app/components/info-drawer/comments-tab/comments-tab.component.spec.ts +++ b/src/app/components/info-drawer/comments-tab/comments-tab.component.spec.ts @@ -27,7 +27,7 @@ import { CommentsTabComponent } from './comments-tab.component'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { AppTestingModule } from '../../../testing/app-testing.module'; import { NO_ERRORS_SCHEMA } from '@angular/core'; -import { NodePermissionService } from '../../../services/node-permission.service'; +import { NodePermissionService } from '@alfresco/aca-shared'; describe('CommentsTabComponent', () => { let component: CommentsTabComponent; diff --git a/src/app/components/info-drawer/comments-tab/comments-tab.component.ts b/src/app/components/info-drawer/comments-tab/comments-tab.component.ts index ec43ea1cd9..aef6adb6ed 100644 --- a/src/app/components/info-drawer/comments-tab/comments-tab.component.ts +++ b/src/app/components/info-drawer/comments-tab/comments-tab.component.ts @@ -25,7 +25,7 @@ import { Component, Input } from '@angular/core'; import { MinimalNodeEntryEntity } from '@alfresco/js-api'; -import { NodePermissionService } from '../../../services/node-permission.service'; +import { NodePermissionService } from '@alfresco/aca-shared'; import { isLocked } from '../../../utils/node.utils'; @Component({ diff --git a/src/app/components/info-drawer/info-drawer.component.spec.ts b/src/app/components/info-drawer/info-drawer.component.spec.ts index 35ab269b51..57a4426052 100644 --- a/src/app/components/info-drawer/info-drawer.component.spec.ts +++ b/src/app/components/info-drawer/info-drawer.component.spec.ts @@ -26,10 +26,10 @@ import { NO_ERRORS_SCHEMA } from '@angular/core'; import { InfoDrawerComponent } from './info-drawer.component'; import { TestBed, ComponentFixture, async } from '@angular/core/testing'; import { Store } from '@ngrx/store'; -import { SetInfoDrawerStateAction } from '../../store/actions'; +import { SetInfoDrawerStateAction } from '@alfresco/aca-shared/store'; import { AppTestingModule } from '../../testing/app-testing.module'; import { AppExtensionService } from '../../extensions/extension.service'; -import { ContentApiService } from '../../services/content-api.service'; +import { ContentApiService } from '@alfresco/aca-shared'; import { of } from 'rxjs'; describe('InfoDrawerComponent', () => { diff --git a/src/app/components/info-drawer/info-drawer.component.ts b/src/app/components/info-drawer/info-drawer.component.ts index d182ebfa36..55c3b80d2c 100644 --- a/src/app/components/info-drawer/info-drawer.component.ts +++ b/src/app/components/info-drawer/info-drawer.component.ts @@ -29,11 +29,11 @@ import { MinimalNodeEntryEntity, SiteEntry } from '@alfresco/js-api'; -import { ContentApiService } from '../../services/content-api.service'; +import { ContentApiService } from '@alfresco/aca-shared'; import { AppExtensionService } from '../../extensions/extension.service'; import { SidebarTabRef } from '@alfresco/adf-extensions'; import { Store } from '@ngrx/store'; -import { SetInfoDrawerStateAction } from '../../store/actions'; +import { SetInfoDrawerStateAction } from '@alfresco/aca-shared/store'; @Component({ selector: 'aca-info-drawer', diff --git a/src/app/components/info-drawer/library-metadata-tab/library-metadata-form.component.spec.ts b/src/app/components/info-drawer/library-metadata-tab/library-metadata-form.component.spec.ts index 3449c7a621..a35a7c1c5a 100644 --- a/src/app/components/info-drawer/library-metadata-tab/library-metadata-form.component.spec.ts +++ b/src/app/components/info-drawer/library-metadata-tab/library-metadata-form.component.spec.ts @@ -30,7 +30,7 @@ import { tick } from '@angular/core/testing'; import { Store } from '@ngrx/store'; -import { UpdateLibraryAction } from '../../../store/actions'; +import { UpdateLibraryAction } from '@alfresco/aca-shared/store'; import { AppTestingModule } from '../../../testing/app-testing.module'; import { NO_ERRORS_SCHEMA } from '@angular/core'; import { Site, SiteBody } from '@alfresco/js-api'; diff --git a/src/app/components/info-drawer/library-metadata-tab/library-metadata-form.component.ts b/src/app/components/info-drawer/library-metadata-tab/library-metadata-form.component.ts index 9b0f995026..f9eb73ea17 100644 --- a/src/app/components/info-drawer/library-metadata-tab/library-metadata-form.component.ts +++ b/src/app/components/info-drawer/library-metadata-tab/library-metadata-form.component.ts @@ -27,8 +27,7 @@ import { Component, Input, OnInit, OnChanges, OnDestroy } from '@angular/core'; import { FormGroup, FormControl, Validators } from '@angular/forms'; import { SiteEntry, SitePaging } from '@alfresco/js-api'; import { Store } from '@ngrx/store'; -import { UpdateLibraryAction } from '../../../store/actions'; -import { AppStore } from '../../../store/states/app.state'; +import { AppStore, UpdateLibraryAction } from '@alfresco/aca-shared/store'; import { debounceTime, mergeMap, takeUntil } from 'rxjs/operators'; import { AlfrescoApiService } from '@alfresco/adf-core'; import { Observable, from, Subject } from 'rxjs'; diff --git a/src/app/components/info-drawer/metadata-tab/metadata-tab.component.spec.ts b/src/app/components/info-drawer/metadata-tab/metadata-tab.component.spec.ts index 4a11314387..614658e4a3 100644 --- a/src/app/components/info-drawer/metadata-tab/metadata-tab.component.spec.ts +++ b/src/app/components/info-drawer/metadata-tab/metadata-tab.component.spec.ts @@ -24,7 +24,7 @@ */ import { MetadataTabComponent } from './metadata-tab.component'; -import { NodePermissionService } from '../../../services/node-permission.service'; +import { NodePermissionService } from '@alfresco/aca-shared'; import { Node } from '@alfresco/js-api'; describe('MetadataTabComponent', () => { diff --git a/src/app/components/info-drawer/metadata-tab/metadata-tab.component.ts b/src/app/components/info-drawer/metadata-tab/metadata-tab.component.ts index 1183249f01..040ed7fa37 100644 --- a/src/app/components/info-drawer/metadata-tab/metadata-tab.component.ts +++ b/src/app/components/info-drawer/metadata-tab/metadata-tab.component.ts @@ -25,7 +25,7 @@ import { Component, Input, ViewEncapsulation } from '@angular/core'; import { MinimalNodeEntryEntity } from '@alfresco/js-api'; -import { NodePermissionService } from '../../../services/node-permission.service'; +import { NodePermissionService } from '@alfresco/aca-shared'; import { AppExtensionService } from '../../../extensions/extension.service'; import { AppConfigService } from '@alfresco/adf-core'; import { isLocked } from '../../../utils/node.utils'; diff --git a/src/app/components/layout/app-layout/app-layout.component.spec.ts b/src/app/components/layout/app-layout/app-layout.component.spec.ts index a5386f56e1..7e52c3ad38 100644 --- a/src/app/components/layout/app-layout/app-layout.component.spec.ts +++ b/src/app/components/layout/app-layout/app-layout.component.spec.ts @@ -29,10 +29,12 @@ import { AppConfigService, UserPreferencesService } from '@alfresco/adf-core'; import { AppLayoutComponent } from './app-layout.component'; import { AppTestingModule } from '../../../testing/app-testing.module'; import { Store } from '@ngrx/store'; -import { AppStore } from '../../../store/states'; -import { SetSelectedNodesAction } from '../../../store/actions'; +import { + AppStore, + SetSelectedNodesAction, + getAppSelection +} from '@alfresco/aca-shared/store'; import { Router, NavigationStart } from '@angular/router'; -import { appSelection } from '../../../store/selectors/app.selectors'; import { Subject } from 'rxjs'; class MockRouter { @@ -145,7 +147,7 @@ describe('AppLayoutComponent', () => { router.navigateByUrl('somewhere/over/the/rainbow'); fixture.detectChanges(); - store.select(appSelection).subscribe(state => { + store.select(getAppSelection).subscribe(state => { expect(state.isEmpty).toBe(true); done(); }); @@ -158,7 +160,7 @@ describe('AppLayoutComponent', () => { router.navigateByUrl('/search;q='); fixture.detectChanges(); - store.select(appSelection).subscribe(state => { + store.select(getAppSelection).subscribe(state => { expect(state.isEmpty).toBe(false); done(); }); diff --git a/src/app/components/layout/app-layout/app-layout.component.ts b/src/app/components/layout/app-layout/app-layout.component.ts index 1dbe0aa32e..9fb1ea3b66 100644 --- a/src/app/components/layout/app-layout/app-layout.component.ts +++ b/src/app/components/layout/app-layout/app-layout.component.ts @@ -39,11 +39,13 @@ import { NavigationEnd, Router, NavigationStart } from '@angular/router'; import { Store } from '@ngrx/store'; import { Subject, Observable } from 'rxjs'; import { filter, takeUntil, map, withLatestFrom } from 'rxjs/operators'; -import { NodePermissionService } from '../../../services/node-permission.service'; -import { currentFolder } from '../../../store/selectors/app.selectors'; -import { AppStore } from '../../../store/states'; +import { NodePermissionService } from '@alfresco/aca-shared'; import { BreakpointObserver } from '@angular/cdk/layout'; -import { SetSelectedNodesAction } from '../../../store/actions'; +import { + AppStore, + SetSelectedNodesAction, + getCurrentFolder +} from '@alfresco/aca-shared/store'; @Component({ selector: 'app-layout', @@ -97,7 +99,7 @@ export class AppLayoutComponent implements OnInit, OnDestroy { } this.store - .select(currentFolder) + .select(getCurrentFolder) .pipe(takeUntil(this.onDestroy$)) .subscribe(node => { this.currentFolderId = node ? node.id : null; diff --git a/src/app/components/layout/layout.module.ts b/src/app/components/layout/layout.module.ts index cace44c97a..5464a73b1d 100644 --- a/src/app/components/layout/layout.module.ts +++ b/src/app/components/layout/layout.module.ts @@ -33,11 +33,8 @@ import { AppSidenavModule } from '../sidenav/sidenav.module'; import { AppUploadingDialogModule } from '../upload-dialog/upload.module'; import { AppCommonModule } from '../common/common.module'; import { AppHeaderModule } from '../header/header.module'; -import { PageLayoutComponent } from './page-layout/page-layout.component'; -import { PageLayoutHeaderComponent } from './page-layout/page-layout-header.component'; -import { PageLayoutContentComponent } from './page-layout/page-layout-content.component'; -import { PageLayoutErrorComponent } from './page-layout/page-layout-error.component'; import { HttpClientModule } from '@angular/common/http'; +import { PageLayoutModule } from '@alfresco/aca-shared'; @NgModule({ imports: [ @@ -49,21 +46,10 @@ import { HttpClientModule } from '@angular/common/http'; AppSidenavModule, AppHeaderModule, HttpClientModule, - AppUploadingDialogModule + AppUploadingDialogModule, + PageLayoutModule ], - declarations: [ - AppLayoutComponent, - PageLayoutComponent, - PageLayoutHeaderComponent, - PageLayoutContentComponent, - PageLayoutErrorComponent - ], - exports: [ - AppLayoutComponent, - PageLayoutComponent, - PageLayoutHeaderComponent, - PageLayoutContentComponent, - PageLayoutErrorComponent - ] + declarations: [AppLayoutComponent], + exports: [AppLayoutComponent, PageLayoutModule] }) export class AppLayoutModule {} diff --git a/src/app/components/layout/layout.theme.scss b/src/app/components/layout/layout.theme.scss index e9914e6103..bc73d98efe 100644 --- a/src/app/components/layout/layout.theme.scss +++ b/src/app/components/layout/layout.theme.scss @@ -1,7 +1,5 @@ @import './app-layout/app-layout.theme.scss'; -@import './page-layout/page-layout.theme.scss'; @mixin layout-theme($theme) { @include app-layout-theme($theme); - @include app-page-layout-theme($theme); } diff --git a/src/app/components/layout/page-layout/page-layout.component.html b/src/app/components/layout/page-layout/page-layout.component.html deleted file mode 100644 index cee7682aca..0000000000 --- a/src/app/components/layout/page-layout/page-layout.component.html +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/app/components/layout/page-layout/page-layout.theme.scss b/src/app/components/layout/page-layout/page-layout.theme.scss deleted file mode 100644 index 4571bd774e..0000000000 --- a/src/app/components/layout/page-layout/page-layout.theme.scss +++ /dev/null @@ -1,46 +0,0 @@ -@mixin app-page-layout-theme($theme) { - $foreground: map-get($theme, foreground); - - .app-page-layout { - @include flex-column; - - .app-page-layout-header { - display: flex; - align-items: center; - flex: 0 0 65px; - flex-basis: 48px; - background: #fafafa; - border-bottom: 1px solid mat-color($foreground, text, 0.07); - padding: 0 24px; - } - - .app-page-layout-content { - @include flex-row; - } - - .app-page-layout-error { - @include flex-row; - } - - .main-content { - @include flex-column; - border-right: 1px solid mat-color($foreground, text, 0.07); - } - - .scrollable { - overflow: auto !important; - - .main-content { - overflow: auto !important; - } - } - - .sidebar { - display: block; - height: 100%; - overflow-y: scroll; - max-width: 350px; - width: 350px; - } - } -} diff --git a/src/app/components/libraries/libraries.component.html b/src/app/components/libraries/libraries.component.html index 03833f5f62..d76c9054a5 100644 --- a/src/app/components/libraries/libraries.component.html +++ b/src/app/components/libraries/libraries.component.html @@ -1,5 +1,5 @@ - - + + @@ -8,9 +8,9 @@ - + - +
-
-
+ + diff --git a/src/app/components/libraries/libraries.component.ts b/src/app/components/libraries/libraries.component.ts index f22b2ad9b2..a5747ddb19 100644 --- a/src/app/components/libraries/libraries.component.ts +++ b/src/app/components/libraries/libraries.component.ts @@ -23,14 +23,13 @@ * along with Alfresco. If not, see . */ +import { AppStore, NavigateLibraryAction } from '@alfresco/aca-shared/store'; +import { SiteEntry } from '@alfresco/js-api'; import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout'; import { Component, OnInit } from '@angular/core'; import { Store } from '@ngrx/store'; -import { SiteEntry } from '@alfresco/js-api'; import { AppExtensionService } from '../../extensions/extension.service'; import { ContentManagementService } from '../../services/content-management.service'; -import { NavigateLibraryAction } from '../../store/actions'; -import { AppStore } from '../../store/states/app.state'; import { PageComponent } from '../page.component'; @Component({ diff --git a/src/app/components/page.component.ts b/src/app/components/page.component.ts index 42b979be76..62879bc51a 100644 --- a/src/app/components/page.component.ts +++ b/src/app/components/page.component.ts @@ -35,15 +35,16 @@ import { Observable, Subject, Subscription } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; import { AppExtensionService } from '../extensions/extension.service'; import { ContentManagementService } from '../services/content-management.service'; -import { ViewFileAction, ReloadDocumentListAction } from '../store/actions'; import { - appSelection, - currentFolder, - documentDisplayMode, - infoDrawerOpened, - sharedUrl -} from '../store/selectors/app.selectors'; -import { AppStore } from '../store/states/app.state'; + AppStore, + ViewFileAction, + ReloadDocumentListAction, + getCurrentFolder, + getAppSelection, + getDocumentDisplayMode, + isInfoDrawerOpened, + getSharedUrl +} from '@alfresco/aca-shared/store'; import { isLocked, isLibrary } from '../utils/node.utils'; export abstract class PageComponent implements OnInit, OnDestroy { @@ -72,12 +73,12 @@ export abstract class PageComponent implements OnInit, OnDestroy { ) {} ngOnInit() { - this.sharedPreviewUrl$ = this.store.select(sharedUrl); - this.infoDrawerOpened$ = this.store.select(infoDrawerOpened); - this.documentDisplayMode$ = this.store.select(documentDisplayMode); + this.sharedPreviewUrl$ = this.store.select(getSharedUrl); + this.infoDrawerOpened$ = this.store.select(isInfoDrawerOpened); + this.documentDisplayMode$ = this.store.select(getDocumentDisplayMode); this.store - .select(appSelection) + .select(getAppSelection) .pipe(takeUntil(this.onDestroy$)) .subscribe(selection => { this.selection = selection; @@ -89,7 +90,7 @@ export abstract class PageComponent implements OnInit, OnDestroy { }); this.store - .select(currentFolder) + .select(getCurrentFolder) .pipe(takeUntil(this.onDestroy$)) .subscribe(node => { this.canUpload = node && this.content.canUploadContent(node); diff --git a/src/app/components/permissions/permission-dialog/node-permissions.dialog.ts b/src/app/components/permissions/permission-dialog/node-permissions.dialog.ts index 7692e0471b..21964cf2eb 100644 --- a/src/app/components/permissions/permission-dialog/node-permissions.dialog.ts +++ b/src/app/components/permissions/permission-dialog/node-permissions.dialog.ts @@ -24,7 +24,7 @@ */ import { Component, Inject, ViewEncapsulation } from '@angular/core'; -import { MAT_DIALOG_DATA } from '@angular/material'; +import { MAT_DIALOG_DATA } from '@angular/material/dialog'; @Component({ templateUrl: './node-permissions.dialog.html', diff --git a/src/app/components/permissions/permission-manager/permission-manager.component.ts b/src/app/components/permissions/permission-manager/permission-manager.component.ts index 3dd7d02fed..90586a6cf3 100644 --- a/src/app/components/permissions/permission-manager/permission-manager.component.ts +++ b/src/app/components/permissions/permission-manager/permission-manager.component.ts @@ -23,17 +23,16 @@ * along with Alfresco. If not, see . */ +import { AppStore, SnackbarErrorAction } from '@alfresco/aca-shared/store'; import { NodePermissionDialogService, PermissionListComponent } from '@alfresco/adf-content-services'; +import { MinimalNodeEntryEntity } from '@alfresco/js-api'; import { Component, Input, OnInit, ViewChild } from '@angular/core'; -import { MatDialog } from '@angular/material'; +import { MatDialog } from '@angular/material/dialog'; import { Store } from '@ngrx/store'; -import { MinimalNodeEntryEntity } from '@alfresco/js-api'; -import { ContentApiService } from '../../../services/content-api.service'; -import { SnackbarErrorAction } from '../../../store/actions/snackbar.actions'; -import { AppStore } from '../../../store/states/app.state'; +import { ContentApiService } from '@alfresco/aca-shared'; import { NodePermissionsDialogComponent } from '../permission-dialog/node-permissions.dialog'; @Component({ diff --git a/src/app/components/preview/preview.component.spec.ts b/src/app/components/preview/preview.component.spec.ts index 3812d12056..fcac4d2f47 100644 --- a/src/app/components/preview/preview.component.spec.ts +++ b/src/app/components/preview/preview.component.spec.ts @@ -44,7 +44,7 @@ import { of, throwError } from 'rxjs'; import { EffectsModule } from '@ngrx/effects'; import { NodeEffects } from '../../store/effects/node.effects'; import { AppTestingModule } from '../../testing/app-testing.module'; -import { ContentApiService } from '../../services/content-api.service'; +import { ContentApiService } from '@alfresco/aca-shared'; import { ContentManagementService } from '../../services/content-management.service'; describe('PreviewComponent', () => { diff --git a/src/app/components/preview/preview.component.ts b/src/app/components/preview/preview.component.ts index 376ebbd13c..97fdf7f935 100644 --- a/src/app/components/preview/preview.component.ts +++ b/src/app/components/preview/preview.component.ts @@ -46,10 +46,10 @@ import { AlfrescoApiService } from '@alfresco/adf-core'; import { Store } from '@ngrx/store'; -import { AppStore } from '../../store/states/app.state'; -import { SetSelectedNodesAction } from '../../store/actions'; +import { AppStore } from '@alfresco/aca-shared/store'; +import { SetSelectedNodesAction } from '@alfresco/aca-shared/store'; import { PageComponent } from '../page.component'; -import { ContentApiService } from '../../services/content-api.service'; +import { ContentApiService } from '@alfresco/aca-shared'; import { AppExtensionService } from '../../extensions/extension.service'; import { ContentManagementService } from '../../services/content-management.service'; import { ContentActionRef, ViewerExtensionRef } from '@alfresco/adf-extensions'; diff --git a/src/app/components/recent-files/recent-files.component.html b/src/app/components/recent-files/recent-files.component.html index 02e53c2cfc..cfe0a2036f 100644 --- a/src/app/components/recent-files/recent-files.component.html +++ b/src/app/components/recent-files/recent-files.component.html @@ -1,5 +1,5 @@ - - + + @@ -7,9 +7,9 @@ - + - +
-
-
+ + diff --git a/src/app/components/recent-files/recent-files.component.ts b/src/app/components/recent-files/recent-files.component.ts index d51203eca3..9731088dff 100644 --- a/src/app/components/recent-files/recent-files.component.ts +++ b/src/app/components/recent-files/recent-files.component.ts @@ -29,7 +29,7 @@ import { MinimalNodeEntity } from '@alfresco/js-api'; import { ContentManagementService } from '../../services/content-management.service'; import { PageComponent } from '../page.component'; import { Store } from '@ngrx/store'; -import { AppStore } from '../../store/states/app.state'; +import { AppStore } from '@alfresco/aca-shared/store'; import { AppExtensionService } from '../../extensions/extension.service'; import { UploadService } from '@alfresco/adf-core'; import { debounceTime } from 'rxjs/operators'; diff --git a/src/app/components/search/search-input/search-input.component.spec.ts b/src/app/components/search/search-input/search-input.component.spec.ts index 785e254b23..184ce28f58 100644 --- a/src/app/components/search/search-input/search-input.component.spec.ts +++ b/src/app/components/search/search-input/search-input.component.spec.ts @@ -35,7 +35,10 @@ import { import { SearchInputComponent } from './search-input.component'; import { AppTestingModule } from '../../../testing/app-testing.module'; import { Actions, ofType } from '@ngrx/effects'; -import { SEARCH_BY_TERM, SearchByTermAction } from '../../../store/actions'; +import { + SearchByTermAction, + SearchActionTypes +} from '@alfresco/aca-shared/store'; import { map } from 'rxjs/operators'; import { SearchQueryBuilderService } from '@alfresco/adf-content-services'; import { SearchLibrariesQueryBuilderService } from '../search-libraries-results/search-libraries-query-builder.service'; @@ -90,7 +93,7 @@ describe('SearchInputComponent', () => { const searchedTerm = 's'; const currentSearchOptions = [{ key: 'test' }]; actions$.pipe( - ofType(SEARCH_BY_TERM), + ofType(SearchActionTypes.SearchByTerm), map(action => { expect(action.searchOptions[0].key).toBe(currentSearchOptions[0].key); done(); @@ -103,7 +106,7 @@ describe('SearchInputComponent', () => { it('should call search action with correct searched term', fakeAsync(done => { const searchedTerm = 's'; actions$.pipe( - ofType(SEARCH_BY_TERM), + ofType(SearchActionTypes.SearchByTerm), map(action => { expect(action.payload).toBe(searchedTerm); done(); @@ -119,7 +122,7 @@ describe('SearchInputComponent', () => { const searchedTerm = 's'; const currentSearchOptions = [{ key: 'test' }]; actions$.pipe( - ofType(SEARCH_BY_TERM), + ofType(SearchActionTypes.SearchByTerm), map(action => { expect(action.searchOptions[0].key).toBe(currentSearchOptions[0].key); done(); @@ -132,7 +135,7 @@ describe('SearchInputComponent', () => { it('should call search action with correct searched term', fakeAsync(done => { const searchedTerm = 's'; actions$.pipe( - ofType(SEARCH_BY_TERM), + ofType(SearchActionTypes.SearchByTerm), map(action => { expect(action.payload).toBe(searchedTerm); done(); diff --git a/src/app/components/search/search-input/search-input.component.ts b/src/app/components/search/search-input/search-input.component.ts index 83e563af94..bb9b0c71e1 100644 --- a/src/app/components/search/search-input/search-input.component.ts +++ b/src/app/components/search/search-input/search-input.component.ts @@ -23,6 +23,14 @@ * along with Alfresco. If not, see . */ +import { + AppStore, + SearchByTermAction, + SearchOptionIds, + SearchOptionModel +} from '@alfresco/aca-shared/store'; +import { SearchQueryBuilderService } from '@alfresco/adf-content-services'; +import { AppConfigService } from '@alfresco/adf-core'; import { Component, OnDestroy, @@ -30,6 +38,7 @@ import { ViewChild, ViewEncapsulation } from '@angular/core'; +import { MatMenuTrigger } from '@angular/material/menu'; import { NavigationEnd, PRIMARY_OUTLET, @@ -39,21 +48,12 @@ import { UrlSegmentGroup, UrlTree } from '@angular/router'; -import { SearchInputControlComponent } from '../search-input-control/search-input-control.component'; import { Store } from '@ngrx/store'; -import { AppStore } from '../../../store/states/app.state'; -import { SearchByTermAction } from '../../../store/actions'; +import { Subject } from 'rxjs'; import { filter, takeUntil } from 'rxjs/operators'; -import { SearchQueryBuilderService } from '@alfresco/adf-content-services'; import { ContentManagementService } from '../../../services/content-management.service'; -import { Subject } from 'rxjs'; +import { SearchInputControlComponent } from '../search-input-control/search-input-control.component'; import { SearchLibrariesQueryBuilderService } from '../search-libraries-results/search-libraries-query-builder.service'; -import { MatMenuTrigger } from '@angular/material'; -import { AppConfigService } from '@alfresco/adf-core'; -import { - SearchOptionModel, - SearchOptionIds -} from '../../../store/models/searchOption.model'; @Component({ selector: 'aca-search-input', diff --git a/src/app/components/search/search-libraries-results/search-libraries-results.component.html b/src/app/components/search/search-libraries-results/search-libraries-results.component.html index f00954e45d..bbeb1ca05c 100644 --- a/src/app/components/search/search-libraries-results/search-libraries-results.component.html +++ b/src/app/components/search/search-libraries-results/search-libraries-results.component.html @@ -1,14 +1,14 @@ - - + + - + - +
@@ -123,5 +123,5 @@ - - + + diff --git a/src/app/components/search/search-libraries-results/search-libraries-results.component.ts b/src/app/components/search/search-libraries-results/search-libraries-results.component.ts index 4b7ecdb6a2..87afb85138 100644 --- a/src/app/components/search/search-libraries-results/search-libraries-results.component.ts +++ b/src/app/components/search/search-libraries-results/search-libraries-results.component.ts @@ -23,17 +23,17 @@ * along with Alfresco. If not, see . */ -import { Component, OnInit } from '@angular/core'; +import { NavigateLibraryAction } from '@alfresco/aca-shared/store'; import { NodePaging, Pagination, SiteEntry } from '@alfresco/js-api'; +import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout'; +import { Component, OnInit } from '@angular/core'; import { ActivatedRoute, Params } from '@angular/router'; -import { PageComponent } from '../../page.component'; import { Store } from '@ngrx/store'; -import { AppStore } from '../../../store/states/app.state'; -import { NavigateLibraryAction } from '../../../store/actions'; import { AppExtensionService } from '../../../extensions/extension.service'; import { ContentManagementService } from '../../../services/content-management.service'; +import { AppStore } from '@alfresco/aca-shared/store'; +import { PageComponent } from '../../page.component'; import { SearchLibrariesQueryBuilderService } from './search-libraries-query-builder.service'; -import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout'; @Component({ selector: 'aca-search-results', diff --git a/src/app/components/search/search-results-row/search-results-row.component.ts b/src/app/components/search/search-results-row/search-results-row.component.ts index bdc72dffc9..7cdb41f696 100644 --- a/src/app/components/search/search-results-row/search-results-row.component.ts +++ b/src/app/components/search/search-results-row/search-results-row.component.ts @@ -32,9 +32,8 @@ import { OnDestroy } from '@angular/core'; import { MinimalNodeEntity } from '@alfresco/js-api'; -import { ViewFileAction } from '../../../store/actions'; +import { ViewFileAction, NavigateToFolder } from '@alfresco/aca-shared/store'; import { Store } from '@ngrx/store'; -import { NavigateToFolder } from '../../../store/actions'; import { BehaviorSubject, Subject } from 'rxjs'; import { AlfrescoApiService } from '@alfresco/adf-core'; import { takeUntil } from 'rxjs/operators'; diff --git a/src/app/components/search/search-results/search-results.component.html b/src/app/components/search/search-results/search-results.component.html index 824ec2513d..7e5cee9c21 100644 --- a/src/app/components/search/search-results/search-results.component.html +++ b/src/app/components/search/search-results/search-results.component.html @@ -1,14 +1,14 @@ - - + + - + - +
- - + + diff --git a/src/app/components/search/search-results/search-results.component.spec.ts b/src/app/components/search/search-results/search-results.component.spec.ts index e7e5c71b9e..cca5ed600f 100644 --- a/src/app/components/search/search-results/search-results.component.spec.ts +++ b/src/app/components/search/search-results/search-results.component.spec.ts @@ -16,7 +16,10 @@ import { TranslationService } from '@alfresco/adf-core'; import { Store } from '@ngrx/store'; -import { NavigateToFolder, SnackbarErrorAction } from '../../../store/actions'; +import { + NavigateToFolder, + SnackbarErrorAction +} from '@alfresco/aca-shared/store'; import { Pagination } from '@alfresco/js-api'; import { SearchQueryBuilderService } from '@alfresco/adf-content-services'; import { ActivatedRoute } from '@angular/router'; diff --git a/src/app/components/search/search-results/search-results.component.ts b/src/app/components/search/search-results/search-results.component.ts index 2b419dd446..bef44362f0 100644 --- a/src/app/components/search/search-results/search-results.component.ts +++ b/src/app/components/search/search-results/search-results.component.ts @@ -32,14 +32,16 @@ import { } from '@alfresco/adf-content-services'; import { PageComponent } from '../../page.component'; import { Store } from '@ngrx/store'; -import { AppStore } from '../../../store/states/app.state'; -import { NavigateToFolder } from '../../../store/actions'; +import { + AppStore, + NavigateToFolder, + SnackbarErrorAction, + showFacetFilter +} from '@alfresco/aca-shared/store'; import { AppExtensionService } from '../../../extensions/extension.service'; import { ContentManagementService } from '../../../services/content-management.service'; import { AppConfigService, TranslationService } from '@alfresco/adf-core'; import { Observable } from 'rxjs'; -import { showFacetFilter } from '../../../store/selectors/app.selectors'; -import { SnackbarErrorAction } from '../../../store/actions'; @Component({ selector: 'aca-search-results', diff --git a/src/app/components/settings/settings.component.ts b/src/app/components/settings/settings.component.ts index c0e6f1733f..157b03ca98 100644 --- a/src/app/components/settings/settings.component.ts +++ b/src/app/components/settings/settings.component.ts @@ -32,15 +32,15 @@ import { import { Validators, FormGroup, FormBuilder } from '@angular/forms'; import { Observable, BehaviorSubject } from 'rxjs'; import { Store } from '@ngrx/store'; -import { AppStore } from '../../store/states'; +import { MatCheckboxChange } from '@angular/material/checkbox'; import { - appLanguagePicker, - selectHeaderColor, - selectAppName, - selectUser -} from '../../store/selectors/app.selectors'; -import { MatCheckboxChange } from '@angular/material'; -import { SetLanguagePickerAction } from '../../store/actions'; + AppStore, + SetLanguagePickerAction, + getHeaderColor, + getAppName, + getUserProfile, + getLanguagePickerState +} from '@alfresco/aca-shared/store'; import { ProfileState } from '@alfresco/adf-extensions'; interface RepositoryConfig { @@ -72,10 +72,10 @@ export class SettingsComponent implements OnInit { private storage: StorageService, private fb: FormBuilder ) { - this.profile$ = store.select(selectUser); - this.appName$ = store.select(selectAppName); - this.languagePicker$ = store.select(appLanguagePicker); - this.headerColor$ = store.select(selectHeaderColor); + this.profile$ = store.select(getUserProfile); + this.appName$ = store.select(getAppName); + this.languagePicker$ = store.select(getLanguagePickerState); + this.headerColor$ = store.select(getHeaderColor); } get logo() { diff --git a/src/app/components/shared-files/shared-files.component.html b/src/app/components/shared-files/shared-files.component.html index 2d748e83a5..98a1114320 100644 --- a/src/app/components/shared-files/shared-files.component.html +++ b/src/app/components/shared-files/shared-files.component.html @@ -1,5 +1,5 @@ - - + + @@ -7,9 +7,9 @@ - + - +
-
-
+ + diff --git a/src/app/components/shared-files/shared-files.component.ts b/src/app/components/shared-files/shared-files.component.ts index 3229cb4019..ba5d3c7a55 100644 --- a/src/app/components/shared-files/shared-files.component.ts +++ b/src/app/components/shared-files/shared-files.component.ts @@ -28,7 +28,6 @@ import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout'; import { ContentManagementService } from '../../services/content-management.service'; import { PageComponent } from '../page.component'; import { Store } from '@ngrx/store'; -import { AppStore } from '../../store/states/app.state'; import { AppExtensionService } from '../../extensions/extension.service'; import { debounceTime } from 'rxjs/operators'; import { UploadService } from '@alfresco/adf-core'; @@ -42,7 +41,7 @@ export class SharedFilesComponent extends PageComponent implements OnInit { columns: any[] = []; constructor( - store: Store, + store: Store, extensions: AppExtensionService, content: ContentManagementService, private uploadService: UploadService, diff --git a/src/app/components/shared-link-view/shared-link-view.component.spec.ts b/src/app/components/shared-link-view/shared-link-view.component.spec.ts index 0cb20d044b..6b622c51c2 100644 --- a/src/app/components/shared-link-view/shared-link-view.component.spec.ts +++ b/src/app/components/shared-link-view/shared-link-view.component.spec.ts @@ -36,7 +36,7 @@ import { ActivatedRoute } from '@angular/router'; import { of } from 'rxjs'; import { NO_ERRORS_SCHEMA } from '@angular/core'; import { AlfrescoApiService } from '@alfresco/adf-core'; -import { SetSelectedNodesAction } from '../../store/actions'; +import { SetSelectedNodesAction } from '@alfresco/aca-shared/store'; import { AppExtensionService } from '../../extensions/extension.service'; describe('SharedLinkViewComponent', () => { diff --git a/src/app/components/shared-link-view/shared-link-view.component.ts b/src/app/components/shared-link-view/shared-link-view.component.ts index b77aacd9ce..f7c4edec1e 100644 --- a/src/app/components/shared-link-view/shared-link-view.component.ts +++ b/src/app/components/shared-link-view/shared-link-view.component.ts @@ -1,15 +1,42 @@ -import { Component, ViewEncapsulation, OnInit } from '@angular/core'; -import { ActivatedRoute } from '@angular/router'; -import { ContentActionRef } from '@alfresco/adf-extensions'; -import { AppExtensionService } from '../../extensions/extension.service'; -import { Store } from '@ngrx/store'; -import { AppStore } from '../../store/states/app.state'; +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2019 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { + AppStore, + SetSelectedNodesAction, + getAppSelection +} from '@alfresco/aca-shared/store'; import { AlfrescoApiService } from '@alfresco/adf-core'; +import { ContentActionRef } from '@alfresco/adf-extensions'; import { SharedLinkEntry } from '@alfresco/js-api'; -import { SetSelectedNodesAction } from '../../store/actions'; -import { flatMap, catchError } from 'rxjs/operators'; -import { forkJoin, of, from } from 'rxjs'; -import { appSelection } from '../../store/selectors/app.selectors'; +import { Component, OnInit, ViewEncapsulation } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { Store } from '@ngrx/store'; +import { forkJoin, from, of } from 'rxjs'; +import { catchError, flatMap } from 'rxjs/operators'; +import { AppExtensionService } from '../../extensions/extension.service'; @Component({ selector: 'app-shared-link-view', @@ -48,7 +75,7 @@ export class SharedLinkViewComponent implements OnInit { this.sharedLinkId = sharedId; }); - this.store.select(appSelection).subscribe(selection => { + this.store.select(getAppSelection).subscribe(selection => { if (!selection.isEmpty) this.viewerToolbarActions = this.extensions.getSharedLinkViewerToolbarActions(); }); diff --git a/src/app/components/shared/content-node-share/content-node-share.dialog.spec.ts b/src/app/components/shared/content-node-share/content-node-share.dialog.spec.ts index 873aad1793..3f3a3af580 100644 --- a/src/app/components/shared/content-node-share/content-node-share.dialog.spec.ts +++ b/src/app/components/shared/content-node-share/content-node-share.dialog.spec.ts @@ -17,7 +17,11 @@ import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { TestBed, fakeAsync, async, tick } from '@angular/core/testing'; -import { MatDialogRef, MAT_DIALOG_DATA, MatDialog } from '@angular/material'; +import { + MatDialogRef, + MAT_DIALOG_DATA, + MatDialog +} from '@angular/material/dialog'; import { of } from 'rxjs'; import { setupTestBed, diff --git a/src/app/components/shared/content-node-share/content-node-share.dialog.ts b/src/app/components/shared/content-node-share/content-node-share.dialog.ts index ecdf01365f..43455dfa25 100644 --- a/src/app/components/shared/content-node-share/content-node-share.dialog.ts +++ b/src/app/components/shared/content-node-share/content-node-share.dialog.ts @@ -23,11 +23,14 @@ import { ViewChild, OnDestroy } from '@angular/core'; -import { MAT_DIALOG_DATA, MatDialogRef, MatDialog } from '@angular/material'; +import { + MAT_DIALOG_DATA, + MatDialogRef, + MatDialog +} from '@angular/material/dialog'; import { FormGroup, FormControl } from '@angular/forms'; import { Subscription, Observable, throwError } from 'rxjs'; -import { SnackbarErrorAction } from '../../../store/actions'; -import { AppStore } from '../../../store/states/app.state'; +import { AppStore, SnackbarErrorAction } from '@alfresco/aca-shared/store'; import { Store } from '@ngrx/store'; import { skip, diff --git a/src/app/components/shared/toggle-shared/toggle-shared.component.ts b/src/app/components/shared/toggle-shared/toggle-shared.component.ts index e61821454c..ca39688590 100644 --- a/src/app/components/shared/toggle-shared/toggle-shared.component.ts +++ b/src/app/components/shared/toggle-shared/toggle-shared.component.ts @@ -26,10 +26,12 @@ import { Component, OnInit } from '@angular/core'; import { Observable } from 'rxjs'; import { Store } from '@ngrx/store'; -import { AppStore } from '../../../store/states/app.state'; -import { appSelection } from '../../../store/selectors/app.selectors'; import { SelectionState } from '@alfresco/adf-extensions'; -import { ShareNodeAction } from '../../../store/actions'; +import { + AppStore, + ShareNodeAction, + getAppSelection +} from '@alfresco/aca-shared/store'; @Component({ selector: 'app-toggle-shared', @@ -41,7 +43,7 @@ export class ToggleSharedComponent implements OnInit { constructor(private store: Store) {} ngOnInit() { - this.selection$ = this.store.select(appSelection); + this.selection$ = this.store.select(getAppSelection); } isShared(selection: SelectionState) { diff --git a/src/app/components/sidenav/directives/action.directive.ts b/src/app/components/sidenav/directives/action.directive.ts index bc201ea8ea..7ca148891f 100644 --- a/src/app/components/sidenav/directives/action.directive.ts +++ b/src/app/components/sidenav/directives/action.directive.ts @@ -26,7 +26,6 @@ import { Directive, Input, HostListener } from '@angular/core'; import { PRIMARY_OUTLET, Router } from '@angular/router'; import { Store } from '@ngrx/store'; -import { AppStore } from '../../../store/states/app.state'; @Directive({ /* tslint:disable-next-line */ @@ -41,18 +40,14 @@ export class ActionDirective { if (this.action.route) { this.router.navigate(this.getNavigationCommands(this.action.route)); } else if (this.action.click) { - this.dispatchAction(this.action.click); + this.store.dispatch({ + type: this.action.click.action, + payload: this.getNavigationCommands(this.action.click.payload) + }); } } - constructor(private router: Router, private store: Store) {} - - private dispatchAction(action) { - this.store.dispatch({ - type: action.action, - payload: this.getNavigationCommands(action.payload) - }); - } + constructor(private router: Router, private store: Store) {} private getNavigationCommands(url: string): any[] { const urlTree = this.router.parseUrl(url); diff --git a/src/app/components/sidenav/directives/expansion-panel.directive.ts b/src/app/components/sidenav/directives/expansion-panel.directive.ts index 86640f308b..693d131136 100644 --- a/src/app/components/sidenav/directives/expansion-panel.directive.ts +++ b/src/app/components/sidenav/directives/expansion-panel.directive.ts @@ -35,7 +35,6 @@ import { filter, takeUntil } from 'rxjs/operators'; import { Subject } from 'rxjs'; import { MatExpansionPanel } from '@angular/material/expansion'; import { Store } from '@ngrx/store'; -import { AppStore } from '../../../store/states/app.state'; @Directive({ selector: '[acaExpansionPanel]', @@ -63,7 +62,7 @@ export class ExpansionPanelDirective implements OnInit, OnDestroy { } constructor( - private store: Store, + private store: Store, private router: Router, private expansionPanel: MatExpansionPanel ) {} diff --git a/src/app/components/sidenav/directives/menu-panel.directive.ts b/src/app/components/sidenav/directives/menu-panel.directive.ts index 154bfbd76d..956297cacc 100644 --- a/src/app/components/sidenav/directives/menu-panel.directive.ts +++ b/src/app/components/sidenav/directives/menu-panel.directive.ts @@ -34,7 +34,6 @@ import { Router, NavigationEnd, PRIMARY_OUTLET } from '@angular/router'; import { filter, takeUntil } from 'rxjs/operators'; import { Subject } from 'rxjs'; import { Store } from '@ngrx/store'; -import { AppStore } from '../../../store/states/app.state'; @Directive({ selector: '[acaMenuPanel]', @@ -61,7 +60,7 @@ export class MenuPanelDirective implements OnInit, OnDestroy { } } - constructor(private store: Store, private router: Router) {} + constructor(private store: Store, private router: Router) {} hasActiveLinks() { if (this.acaMenuPanel && this.acaMenuPanel.children) { diff --git a/src/app/components/sidenav/sidenav.component.ts b/src/app/components/sidenav/sidenav.component.ts index 9c2a8c3a12..83179b5346 100755 --- a/src/app/components/sidenav/sidenav.component.ts +++ b/src/app/components/sidenav/sidenav.component.ts @@ -37,8 +37,7 @@ import { ExpandedTemplateDirective } from './directives/expanded-template.direct import { AppExtensionService } from '../../extensions/extension.service'; import { NavBarGroupRef } from '@alfresco/adf-extensions'; import { Store } from '@ngrx/store'; -import { AppStore } from '../../store/states'; -import { sidenavState } from '../../store/selectors/app.selectors'; +import { AppStore, getSideNavState } from '@alfresco/aca-shared/store'; import { Subject } from 'rxjs'; import { takeUntil, distinctUntilChanged, debounceTime } from 'rxjs/operators'; @@ -68,7 +67,7 @@ export class SidenavComponent implements OnInit, OnDestroy { ngOnInit() { this.store - .select(sidenavState) + .select(getSideNavState) .pipe( debounceTime(300), distinctUntilChanged(), diff --git a/src/app/components/toolbar/document-display-mode/document-display-mode.component.ts b/src/app/components/toolbar/document-display-mode/document-display-mode.component.ts index 5a241c655b..124a9a7dc7 100644 --- a/src/app/components/toolbar/document-display-mode/document-display-mode.component.ts +++ b/src/app/components/toolbar/document-display-mode/document-display-mode.component.ts @@ -26,9 +26,11 @@ import { Component, ViewEncapsulation } from '@angular/core'; import { Observable } from 'rxjs'; import { Store } from '@ngrx/store'; -import { AppStore } from '../../../store/states'; -import { documentDisplayMode } from '../../../store/selectors/app.selectors'; -import { ToggleDocumentDisplayMode } from '../../../store/actions'; +import { + AppStore, + ToggleDocumentDisplayMode, + getDocumentDisplayMode +} from '@alfresco/aca-shared/store'; @Component({ selector: 'app-document-display-mode', @@ -45,7 +47,7 @@ export class DocumentDisplayModeComponent { displayMode$: Observable; constructor(private store: Store) { - this.displayMode$ = store.select(documentDisplayMode); + this.displayMode$ = store.select(getDocumentDisplayMode); } onClick() { diff --git a/src/app/components/toolbar/toggle-edit-offline/toggle-edit-offline.component.spec.ts b/src/app/components/toolbar/toggle-edit-offline/toggle-edit-offline.component.spec.ts index 119e80a622..0f089ca922 100644 --- a/src/app/components/toolbar/toggle-edit-offline/toggle-edit-offline.component.spec.ts +++ b/src/app/components/toolbar/toggle-edit-offline/toggle-edit-offline.component.spec.ts @@ -33,7 +33,7 @@ import { DownloadNodesAction, EditOfflineAction, SnackbarErrorAction -} from '../../../store/actions'; +} from '@alfresco/aca-shared/store'; describe('ToggleEditOfflineComponent', () => { let fixture; diff --git a/src/app/components/toolbar/toggle-edit-offline/toggle-edit-offline.component.ts b/src/app/components/toolbar/toggle-edit-offline/toggle-edit-offline.component.ts index 26f4c81574..bead7cbde0 100644 --- a/src/app/components/toolbar/toggle-edit-offline/toggle-edit-offline.component.ts +++ b/src/app/components/toolbar/toggle-edit-offline/toggle-edit-offline.component.ts @@ -23,16 +23,16 @@ * along with Alfresco. If not, see . */ -import { Component, ViewEncapsulation, OnInit } from '@angular/core'; -import { Store } from '@ngrx/store'; -import { AppStore } from '../../../store/states'; -import { appSelection } from '../../../store/selectors/app.selectors'; import { + AppStore, DownloadNodesAction, EditOfflineAction, - SnackbarErrorAction -} from '../../../store/actions'; + SnackbarErrorAction, + getAppSelection +} from '@alfresco/aca-shared/store'; import { MinimalNodeEntity } from '@alfresco/js-api'; +import { Component, OnInit, ViewEncapsulation } from '@angular/core'; +import { Store } from '@ngrx/store'; @Component({ selector: 'app-toggle-edit-offline', @@ -70,7 +70,7 @@ export class ToggleEditOfflineComponent implements OnInit { constructor(private store: Store) {} ngOnInit() { - this.store.select(appSelection).subscribe(({ file }) => { + this.store.select(getAppSelection).subscribe(({ file }) => { this.selection = file; }); } diff --git a/src/app/components/toolbar/toggle-favorite-library/toggle-favorite-library.component.ts b/src/app/components/toolbar/toggle-favorite-library/toggle-favorite-library.component.ts index df77598283..d2c0d734f4 100644 --- a/src/app/components/toolbar/toggle-favorite-library/toggle-favorite-library.component.ts +++ b/src/app/components/toolbar/toggle-favorite-library/toggle-favorite-library.component.ts @@ -25,8 +25,7 @@ import { Component, ViewEncapsulation, OnInit } from '@angular/core'; import { Store } from '@ngrx/store'; -import { AppStore } from '../../../store/states'; -import { appSelection } from '../../../store/selectors/app.selectors'; +import { AppStore, getAppSelection } from '@alfresco/aca-shared/store'; import { Observable } from 'rxjs'; import { SelectionState } from '@alfresco/adf-extensions'; import { ContentManagementService } from '../../../services/content-management.service'; @@ -73,7 +72,7 @@ export class ToggleFavoriteLibraryComponent implements OnInit { '/favorite/libraries' ); - this.selection$ = this.store.select(appSelection).pipe( + this.selection$ = this.store.select(getAppSelection).pipe( distinctUntilChanged(), map(selection => { // favorite libraries list should already be marked as favorite diff --git a/src/app/components/toolbar/toggle-favorite/toggle-favorite.component.ts b/src/app/components/toolbar/toggle-favorite/toggle-favorite.component.ts index 37ae414fef..32498c979c 100644 --- a/src/app/components/toolbar/toggle-favorite/toggle-favorite.component.ts +++ b/src/app/components/toolbar/toggle-favorite/toggle-favorite.component.ts @@ -25,11 +25,13 @@ import { Component, ViewEncapsulation } from '@angular/core'; import { Store } from '@ngrx/store'; -import { AppStore } from '../../../store/states'; -import { appSelection } from '../../../store/selectors/app.selectors'; import { Observable } from 'rxjs'; import { SelectionState } from '@alfresco/adf-extensions'; -import { ReloadDocumentListAction } from '../../../store/actions'; +import { + AppStore, + ReloadDocumentListAction, + getAppSelection +} from '@alfresco/aca-shared/store'; @Component({ selector: 'app-toggle-favorite', @@ -56,7 +58,7 @@ export class ToggleFavoriteComponent { selection$: Observable; constructor(private store: Store) { - this.selection$ = this.store.select(appSelection); + this.selection$ = this.store.select(getAppSelection); } onToggleEvent() { diff --git a/src/app/components/toolbar/toggle-info-drawer/toggle-info-drawer.component.ts b/src/app/components/toolbar/toggle-info-drawer/toggle-info-drawer.component.ts index 174df9090d..2c268e305e 100644 --- a/src/app/components/toolbar/toggle-info-drawer/toggle-info-drawer.component.ts +++ b/src/app/components/toolbar/toggle-info-drawer/toggle-info-drawer.component.ts @@ -26,9 +26,10 @@ import { Component, ViewEncapsulation } from '@angular/core'; import { Observable } from 'rxjs'; import { Store } from '@ngrx/store'; -import { AppStore } from '../../../store/states'; -import { infoDrawerOpened } from '../../../store/selectors/app.selectors'; -import { ToggleInfoDrawerAction } from '../../../store/actions'; +import { + ToggleInfoDrawerAction, + isInfoDrawerOpened +} from '@alfresco/aca-shared/store'; @Component({ selector: 'app-toggle-info-drawer', @@ -48,8 +49,8 @@ import { ToggleInfoDrawerAction } from '../../../store/actions'; export class ToggleInfoDrawerComponent { infoDrawerOpened$: Observable; - constructor(private store: Store) { - this.infoDrawerOpened$ = this.store.select(infoDrawerOpened); + constructor(private store: Store) { + this.infoDrawerOpened$ = this.store.select(isInfoDrawerOpened); } onClick() { diff --git a/src/app/components/toolbar/toggle-join-library/toggle-join-library-button.component.ts b/src/app/components/toolbar/toggle-join-library/toggle-join-library-button.component.ts index 44d015269a..a5313da099 100644 --- a/src/app/components/toolbar/toggle-join-library/toggle-join-library-button.component.ts +++ b/src/app/components/toolbar/toggle-join-library/toggle-join-library-button.component.ts @@ -23,22 +23,22 @@ * along with Alfresco. If not, see . */ +import { + AppStore, + SetSelectedNodesAction, + SnackbarErrorAction, + SnackbarInfoAction, + getAppSelection +} from '@alfresco/aca-shared/store'; +import { SelectionState } from '@alfresco/adf-extensions'; import { Component, ViewEncapsulation } from '@angular/core'; import { Store } from '@ngrx/store'; -import { AppStore } from '../../../store/states'; -import { appSelection } from '../../../store/selectors/app.selectors'; import { Observable } from 'rxjs'; -import { SelectionState } from '@alfresco/adf-extensions'; -import { ContentManagementService } from '../../../services/content-management.service'; -import { - SnackbarErrorAction, - SnackbarInfoAction -} from '../../../store/actions/snackbar.actions'; -import { SetSelectedNodesAction } from '../../../store/actions/node.actions'; import { - LibraryMembershipToggleEvent, - LibraryMembershipErrorEvent + LibraryMembershipErrorEvent, + LibraryMembershipToggleEvent } from '../../../directives/library-membership.directive'; +import { ContentManagementService } from '../../../services/content-management.service'; @Component({ selector: 'app-toggle-join-library-button', @@ -73,7 +73,7 @@ export class ToggleJoinLibraryButtonComponent { private store: Store, private content: ContentManagementService ) { - this.selection$ = this.store.select(appSelection); + this.selection$ = this.store.select(getAppSelection); } onToggleEvent(event: LibraryMembershipToggleEvent) { diff --git a/src/app/components/toolbar/toggle-join-library/toggle-join-library-menu.component.ts b/src/app/components/toolbar/toggle-join-library/toggle-join-library-menu.component.ts index 2c90969c08..57281e1952 100644 --- a/src/app/components/toolbar/toggle-join-library/toggle-join-library-menu.component.ts +++ b/src/app/components/toolbar/toggle-join-library/toggle-join-library-menu.component.ts @@ -25,7 +25,7 @@ import { Component, ViewEncapsulation } from '@angular/core'; import { Store } from '@ngrx/store'; -import { AppStore } from '../../../store/states'; +import { AppStore } from '@alfresco/aca-shared/store'; import { ContentManagementService } from '../../../services/content-management.service'; import { ToggleJoinLibraryButtonComponent } from './toggle-join-library-button.component'; diff --git a/src/app/components/toolbar/toggle-join-library/toggle-join-library.component.spec.ts b/src/app/components/toolbar/toggle-join-library/toggle-join-library.component.spec.ts index 753495afb2..a0c9c9c104 100644 --- a/src/app/components/toolbar/toggle-join-library/toggle-join-library.component.spec.ts +++ b/src/app/components/toolbar/toggle-join-library/toggle-join-library.component.spec.ts @@ -32,7 +32,7 @@ import { NO_ERRORS_SCHEMA } from '@angular/core'; import { SnackbarErrorAction, SnackbarInfoAction -} from '../../../store/actions/snackbar.actions'; +} from '@alfresco/aca-shared/store'; import { AppTestingModule } from '../../../testing/app-testing.module'; import { ContentManagementService } from '../../../services/content-management.service'; import { ToggleJoinLibraryButtonComponent } from './toggle-join-library-button.component'; diff --git a/src/app/components/trashcan/trashcan.component.html b/src/app/components/trashcan/trashcan.component.html index 032009ebfb..37f87576ba 100644 --- a/src/app/components/trashcan/trashcan.component.html +++ b/src/app/components/trashcan/trashcan.component.html @@ -1,5 +1,5 @@ - - + + @@ -7,9 +7,9 @@ - + - +
-
-
+ + diff --git a/src/app/components/trashcan/trashcan.component.ts b/src/app/components/trashcan/trashcan.component.ts index 0e0e6aa4db..b830c55550 100644 --- a/src/app/components/trashcan/trashcan.component.ts +++ b/src/app/components/trashcan/trashcan.component.ts @@ -23,16 +23,15 @@ * along with Alfresco. If not, see . */ -import { Component, OnInit } from '@angular/core'; +import { AppStore, getUserProfile } from '@alfresco/aca-shared/store'; +import { ProfileState } from '@alfresco/adf-extensions'; import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout'; -import { ContentManagementService } from '../../services/content-management.service'; -import { PageComponent } from '../page.component'; +import { Component, OnInit } from '@angular/core'; import { Store } from '@ngrx/store'; -import { selectUser } from '../../store/selectors/app.selectors'; -import { AppStore } from '../../store/states/app.state'; -import { AppExtensionService } from '../../extensions/extension.service'; import { Observable } from 'rxjs'; -import { ProfileState } from '@alfresco/adf-extensions'; +import { AppExtensionService } from '../../extensions/extension.service'; +import { ContentManagementService } from '../../services/content-management.service'; +import { PageComponent } from '../page.component'; @Component({ templateUrl: './trashcan.component.html' @@ -50,7 +49,7 @@ export class TrashcanComponent extends PageComponent implements OnInit { private breakpointObserver: BreakpointObserver ) { super(store, extensions, content); - this.user$ = this.store.select(selectUser); + this.user$ = this.store.select(getUserProfile); } ngOnInit() { diff --git a/src/app/components/viewer/viewer.component.ts b/src/app/components/viewer/viewer.component.ts index c50d28ceee..3a08068e27 100644 --- a/src/app/components/viewer/viewer.component.ts +++ b/src/app/components/viewer/viewer.component.ts @@ -23,21 +23,21 @@ * along with Alfresco. If not, see . */ -import { Component, OnInit, OnDestroy, ViewEncapsulation } from '@angular/core'; -import { ActivatedRoute } from '@angular/router'; +import { ContentApiService } from '@alfresco/aca-shared'; +import { + AppStore, + getAppSelection, + isInfoDrawerOpened, + SetSelectedNodesAction +} from '@alfresco/aca-shared/store'; import { ContentActionRef, SelectionState } from '@alfresco/adf-extensions'; +import { MinimalNodeEntryEntity } from '@alfresco/js-api'; +import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; import { Store } from '@ngrx/store'; -import { AppStore } from '../../store/states'; -import { - appSelection, - infoDrawerOpened -} from '../../store/selectors/app.selectors'; +import { from, Observable, Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; -import { Subject, Observable, from } from 'rxjs'; import { AppExtensionService } from '../../extensions/extension.service'; -import { MinimalNodeEntryEntity } from '@alfresco/js-api'; -import { ContentApiService } from '../../services/content-api.service'; -import { SetSelectedNodesAction } from '../../store/actions'; @Component({ selector: 'app-viewer', @@ -66,7 +66,7 @@ export class AppViewerComponent implements OnInit, OnDestroy { ) {} ngOnInit() { - this.infoDrawerOpened$ = this.store.select(infoDrawerOpened); + this.infoDrawerOpened$ = this.store.select(isInfoDrawerOpened); from(this.infoDrawerOpened$) .pipe(takeUntil(this.onDestroy$)) @@ -75,7 +75,7 @@ export class AppViewerComponent implements OnInit, OnDestroy { }); this.store - .select(appSelection) + .select(getAppSelection) .pipe(takeUntil(this.onDestroy$)) .subscribe(selection => { this.selection = selection; diff --git a/src/app/dialogs/node-versions/node-versions.dialog.ts b/src/app/dialogs/node-versions/node-versions.dialog.ts index 1a7935794d..d882925205 100644 --- a/src/app/dialogs/node-versions/node-versions.dialog.ts +++ b/src/app/dialogs/node-versions/node-versions.dialog.ts @@ -23,12 +23,11 @@ * along with Alfresco. If not, see . */ -import { Component, Inject, ViewEncapsulation } from '@angular/core'; -import { MAT_DIALOG_DATA } from '@angular/material'; +import { SnackbarErrorAction } from '@alfresco/aca-shared/store'; import { MinimalNodeEntryEntity } from '@alfresco/js-api'; +import { Component, Inject, ViewEncapsulation } from '@angular/core'; +import { MAT_DIALOG_DATA } from '@angular/material/dialog'; import { Store } from '@ngrx/store'; -import { AppStore } from '../../store/states/app.state'; -import { SnackbarErrorAction } from '../../store/actions'; @Component({ templateUrl: './node-versions.dialog.html', @@ -38,10 +37,7 @@ import { SnackbarErrorAction } from '../../store/actions'; export class NodeVersionsDialogComponent { node: MinimalNodeEntryEntity; - constructor( - @Inject(MAT_DIALOG_DATA) data: any, - private store: Store - ) { + constructor(@Inject(MAT_DIALOG_DATA) data: any, private store: Store) { this.node = data.node; } diff --git a/src/app/directives/document-list.directive.ts b/src/app/directives/document-list.directive.ts index ae0d64137f..4468561ce4 100644 --- a/src/app/directives/document-list.directive.ts +++ b/src/app/directives/document-list.directive.ts @@ -29,7 +29,7 @@ import { ActivatedRoute, Router } from '@angular/router'; import { UserPreferencesService } from '@alfresco/adf-core'; import { Subject } from 'rxjs'; import { Store } from '@ngrx/store'; -import { SetSelectedNodesAction } from '../store/actions'; +import { SetSelectedNodesAction } from '@alfresco/aca-shared/store'; import { takeUntil } from 'rxjs/operators'; import { ContentManagementService } from '../services/content-management.service'; diff --git a/src/app/extensions/core.extensions.module.ts b/src/app/extensions/core.extensions.module.ts index 6baca9af59..f7332d8ec8 100644 --- a/src/app/extensions/core.extensions.module.ts +++ b/src/app/extensions/core.extensions.module.ts @@ -27,9 +27,7 @@ import { CoreModule, AuthGuardEcm } from '@alfresco/adf-core'; import { CommonModule } from '@angular/common'; import { APP_INITIALIZER, ModuleWithProviders, NgModule } from '@angular/core'; import { AppLayoutComponent } from '../components/layout/app-layout/app-layout.component'; -import * as repository from './evaluators/repository.evaluators'; -import * as app from './evaluators/app.evaluators'; -import * as nav from './evaluators/navigation.evaluators'; +import * as rules from '@alfresco/aca-shared/rules'; import { AppExtensionService } from './extension.service'; import { ToggleInfoDrawerComponent } from '../components/toolbar/toggle-info-drawer/toggle-info-drawer.component'; import { ToggleFavoriteComponent } from '../components/toolbar/toggle-favorite/toggle-favorite.component'; @@ -109,63 +107,63 @@ export class CoreExtensionsModule { }); extensions.setEvaluators({ - canCopyNode: app.canCopyNode, - canToggleJoinLibrary: app.canToggleJoinLibrary, - canEditFolder: app.canEditFolder, - isTrashcanItemSelected: app.isTrashcanItemSelected, - canViewFile: app.canViewFile, - canLeaveLibrary: app.canLeaveLibrary, - canToggleSharedLink: app.canToggleSharedLink, - canShowInfoDrawer: app.canShowInfoDrawer, - canManageFileVersions: app.canManageFileVersions, - canManagePermissions: app.canManagePermissions, - canToggleEditOffline: app.canToggleEditOffline, - canToggleFavorite: app.canToggleFavorite, + canCopyNode: rules.canCopyNode, + canToggleJoinLibrary: rules.canToggleJoinLibrary, + canEditFolder: rules.canEditFolder, + isTrashcanItemSelected: rules.isTrashcanItemSelected, + canViewFile: rules.canViewFile, + canLeaveLibrary: rules.canLeaveLibrary, + canToggleSharedLink: rules.canToggleSharedLink, + canShowInfoDrawer: rules.canShowInfoDrawer, + canManageFileVersions: rules.canManageFileVersions, + canManagePermissions: rules.canManagePermissions, + canToggleEditOffline: rules.canToggleEditOffline, + canToggleFavorite: rules.canToggleFavorite, - 'app.selection.canDelete': app.canDeleteSelection, - 'app.selection.file.canUnlock': app.canUnlockFile, - 'app.selection.file.canLock': app.canLockFile, - 'app.selection.canDownload': app.canDownloadSelection, - 'app.selection.notEmpty': app.hasSelection, - 'app.selection.canUnshare': app.canUnshareNodes, - 'app.selection.canAddFavorite': app.canAddFavorite, - 'app.selection.canRemoveFavorite': app.canRemoveFavorite, - 'app.selection.first.canUpdate': app.canUpdateSelectedNode, - 'app.selection.file': app.hasFileSelected, - 'app.selection.file.canShare': app.canShareFile, - 'app.selection.file.isShared': app.isShared, - 'app.selection.file.isLocked': app.hasLockedFiles, - 'app.selection.file.isLockOwner': app.isUserWriteLockOwner, - 'app.selection.file.canUploadVersion': app.canUploadVersion, - 'app.selection.library': app.hasLibrarySelected, - 'app.selection.isPrivateLibrary': app.isPrivateLibrary, - 'app.selection.hasLibraryRole': app.hasLibraryRole, - 'app.selection.hasNoLibraryRole': app.hasNoLibraryRole, - 'app.selection.folder': app.hasFolderSelected, - 'app.selection.folder.canUpdate': app.canUpdateSelectedFolder, + 'app.selection.canDelete': rules.canDeleteSelection, + 'app.selection.file.canUnlock': rules.canUnlockFile, + 'app.selection.file.canLock': rules.canLockFile, + 'app.selection.canDownload': rules.canDownloadSelection, + 'app.selection.notEmpty': rules.hasSelection, + 'app.selection.canUnshare': rules.canUnshareNodes, + 'app.selection.canAddFavorite': rules.canAddFavorite, + 'app.selection.canRemoveFavorite': rules.canRemoveFavorite, + 'app.selection.first.canUpdate': rules.canUpdateSelectedNode, + 'app.selection.file': rules.hasFileSelected, + 'app.selection.file.canShare': rules.canShareFile, + 'app.selection.file.isShared': rules.isShared, + 'app.selection.file.isLocked': rules.hasLockedFiles, + 'app.selection.file.isLockOwner': rules.isUserWriteLockOwner, + 'app.selection.file.canUploadVersion': rules.canUploadVersion, + 'app.selection.library': rules.hasLibrarySelected, + 'app.selection.isPrivateLibrary': rules.isPrivateLibrary, + 'app.selection.hasLibraryRole': rules.hasLibraryRole, + 'app.selection.hasNoLibraryRole': rules.hasNoLibraryRole, + 'app.selection.folder': rules.hasFolderSelected, + 'app.selection.folder.canUpdate': rules.canUpdateSelectedFolder, - 'app.navigation.folder.canCreate': app.canCreateFolder, - 'app.navigation.folder.canUpload': app.canUpload, - 'app.navigation.isTrashcan': nav.isTrashcan, - 'app.navigation.isNotTrashcan': nav.isNotTrashcan, - 'app.navigation.isLibraries': nav.isLibraries, - 'app.navigation.isLibraryFiles': nav.isLibraryFiles, - 'app.navigation.isPersonalFiles': nav.isPersonalFiles, - 'app.navigation.isNotLibraries': nav.isNotLibraries, - 'app.navigation.isSharedFiles': nav.isSharedFiles, - 'app.navigation.isNotSharedFiles': nav.isNotSharedFiles, - 'app.navigation.isFavorites': nav.isFavorites, - 'app.navigation.isNotFavorites': nav.isNotFavorites, - 'app.navigation.isRecentFiles': nav.isRecentFiles, - 'app.navigation.isNotRecentFiles': nav.isNotRecentFiles, - 'app.navigation.isSearchResults': nav.isSearchResults, - 'app.navigation.isNotSearchResults': nav.isNotSearchResults, - 'app.navigation.isPreview': nav.isPreview, - 'app.navigation.isSharedPreview': nav.isSharedPreview, - 'app.navigation.isFavoritesPreview': nav.isFavoritesPreview, - 'app.navigation.isSharedFileViewer': nav.isSharedFileViewer, + 'app.navigation.folder.canCreate': rules.canCreateFolder, + 'app.navigation.folder.canUpload': rules.canUpload, + 'app.navigation.isTrashcan': rules.isTrashcan, + 'app.navigation.isNotTrashcan': rules.isNotTrashcan, + 'app.navigation.isLibraries': rules.isLibraries, + 'app.navigation.isLibraryFiles': rules.isLibraryFiles, + 'app.navigation.isPersonalFiles': rules.isPersonalFiles, + 'app.navigation.isNotLibraries': rules.isNotLibraries, + 'app.navigation.isSharedFiles': rules.isSharedFiles, + 'app.navigation.isNotSharedFiles': rules.isNotSharedFiles, + 'app.navigation.isFavorites': rules.isFavorites, + 'app.navigation.isNotFavorites': rules.isNotFavorites, + 'app.navigation.isRecentFiles': rules.isRecentFiles, + 'app.navigation.isNotRecentFiles': rules.isNotRecentFiles, + 'app.navigation.isSearchResults': rules.isSearchResults, + 'app.navigation.isNotSearchResults': rules.isNotSearchResults, + 'app.navigation.isPreview': rules.isPreview, + 'app.navigation.isSharedPreview': rules.isSharedPreview, + 'app.navigation.isFavoritesPreview': rules.isFavoritesPreview, + 'app.navigation.isSharedFileViewer': rules.isSharedFileViewer, - 'repository.isQuickShareEnabled': repository.hasQuickShareEnabled + 'repository.isQuickShareEnabled': rules.hasQuickShareEnabled }); } } diff --git a/src/app/extensions/extension.service.spec.ts b/src/app/extensions/extension.service.spec.ts index 085ab7df40..cd23575f28 100644 --- a/src/app/extensions/extension.service.spec.ts +++ b/src/app/extensions/extension.service.spec.ts @@ -27,7 +27,7 @@ import { TestBed } from '@angular/core/testing'; import { AppTestingModule } from '../testing/app-testing.module'; import { AppExtensionService } from './extension.service'; import { Store } from '@ngrx/store'; -import { AppStore } from '../store/states'; +import { AppStore } from '@alfresco/aca-shared/store'; import { ContentActionType, mergeArrays, diff --git a/src/app/extensions/extension.service.ts b/src/app/extensions/extension.service.ts index 380f9eff9c..d8cba20843 100644 --- a/src/app/extensions/extension.service.ts +++ b/src/app/extensions/extension.service.ts @@ -26,11 +26,10 @@ import { Injectable, Type } from '@angular/core'; import { Store } from '@ngrx/store'; import { Route } from '@angular/router'; -import { MatIconRegistry } from '@angular/material'; +import { MatIconRegistry } from '@angular/material/icon'; import { DomSanitizer } from '@angular/platform-browser'; -import { AppStore } from '../store/states'; -import { ruleContext } from '../store/selectors/app.selectors'; -import { NodePermissionService } from '../services/node-permission.service'; +import { AppStore, getRuleContext } from '@alfresco/aca-shared/store'; +import { NodePermissionService } from '@alfresco/aca-shared'; import { SelectionState, NavigationState, @@ -117,7 +116,7 @@ export class AppExtensionService implements RuleContext { ) { this.references$ = this._references.asObservable(); - this.store.select(ruleContext).subscribe(result => { + this.store.select(getRuleContext).subscribe(result => { this.selection = result.selection; this.navigation = result.navigation; this.profile = result.profile; diff --git a/src/app/material.module.ts b/src/app/material.module.ts index 397e6d2225..2caa533266 100644 --- a/src/app/material.module.ts +++ b/src/app/material.module.ts @@ -24,16 +24,16 @@ */ import { NgModule } from '@angular/core'; +import { MatMenuModule } from '@angular/material/menu'; +import { MatIconModule } from '@angular/material/icon'; +import { MatButtonModule } from '@angular/material/button'; import { - MatMenuModule, - MatIconModule, - MatButtonModule, MatDialogModule, - MatInputModule, - MatSnackBarModule, - MatProgressBarModule, MAT_DIALOG_DEFAULT_OPTIONS -} from '@angular/material'; +} from '@angular/material/dialog'; +import { MatInputModule } from '@angular/material/input'; +import { MatSnackBarModule } from '@angular/material/snack-bar'; +import { MatProgressBarModule } from '@angular/material/progress-bar'; @NgModule({ imports: [ diff --git a/src/app/services/content-management.service.spec.ts b/src/app/services/content-management.service.spec.ts index c190b6d18e..2c33097f35 100644 --- a/src/app/services/content-management.service.spec.ts +++ b/src/app/services/content-management.service.spec.ts @@ -25,36 +25,37 @@ import { TestBed, fakeAsync, tick, flush } from '@angular/core/testing'; import { of, throwError } from 'rxjs'; -import { MatDialog, MatSnackBar } from '@angular/material'; import { Actions, ofType, EffectsModule } from '@ngrx/effects'; import { - SNACKBAR_INFO, + AppStore, SnackbarWarningAction, SnackbarInfoAction, SnackbarErrorAction, - SNACKBAR_ERROR, - SNACKBAR_WARNING, PurgeDeletedNodesAction, RestoreDeletedNodesAction, NavigateToParentFolder, NavigateRouteAction, - NAVIGATE_ROUTE, DeleteNodesAction, MoveNodesAction, CopyNodesAction, ShareNodeAction, SetSelectedNodesAction, UnlockWriteAction -} from '../store/actions'; +} from '@alfresco/aca-shared/store'; import { map } from 'rxjs/operators'; import { NodeEffects } from '../store/effects/node.effects'; import { AppTestingModule } from '../testing/app-testing.module'; -import { ContentApiService } from '../services/content-api.service'; +import { ContentApiService } from '@alfresco/aca-shared'; import { Store } from '@ngrx/store'; -import { AppStore } from '../store/states'; import { ContentManagementService } from './content-management.service'; import { NodeActionsService } from './node-actions.service'; import { TranslationService } from '@alfresco/adf-core'; +import { MatDialog } from '@angular/material/dialog'; +import { MatSnackBar } from '@angular/material/snack-bar'; +import { + SnackbarActionTypes, + RouterActionTypes +} from '../../../projects/aca-shared/store/src/public_api'; describe('ContentManagementService', () => { let dialog: MatDialog; @@ -773,7 +774,7 @@ describe('ContentManagementService', () => { spyOn(contentApi, 'restoreNode').and.returnValue(throwError(null)); actions$.pipe( - ofType(SNACKBAR_ERROR), + ofType(SnackbarActionTypes.Error), map(action => done()) ); @@ -815,7 +816,7 @@ describe('ContentManagementService', () => { ); actions$.pipe( - ofType(SNACKBAR_ERROR), + ofType(SnackbarActionTypes.Error), map(action => done()) ); @@ -848,7 +849,7 @@ describe('ContentManagementService', () => { ); actions$.pipe( - ofType(SNACKBAR_ERROR), + ofType(SnackbarActionTypes.Error), map(action => done()) ); @@ -882,7 +883,7 @@ describe('ContentManagementService', () => { spyOn(contentApi, 'deleteNode').and.returnValue(of(null)); actions$.pipe( - ofType(SNACKBAR_INFO), + ofType(SnackbarActionTypes.Info), map(action => { done(); }) @@ -897,7 +898,7 @@ describe('ContentManagementService', () => { spyOn(contentApi, 'deleteNode').and.returnValue(throwError(null)); actions$.pipe( - ofType(SNACKBAR_ERROR), + ofType(SnackbarActionTypes.Error), map(action => { done(); }) @@ -912,7 +913,7 @@ describe('ContentManagementService', () => { spyOn(contentApi, 'deleteNode').and.returnValue(of(null)); actions$.pipe( - ofType(SNACKBAR_INFO), + ofType(SnackbarActionTypes.Info), map(action => { done(); }) @@ -930,7 +931,7 @@ describe('ContentManagementService', () => { spyOn(contentApi, 'deleteNode').and.returnValue(throwError(null)); actions$.pipe( - ofType(SNACKBAR_ERROR), + ofType(SnackbarActionTypes.Error), map(action => { done(); }) @@ -954,7 +955,7 @@ describe('ContentManagementService', () => { }); actions$.pipe( - ofType(SNACKBAR_WARNING), + ofType(SnackbarActionTypes.Warning), map(action => { done(); }) @@ -984,7 +985,7 @@ describe('ContentManagementService', () => { }); actions$.pipe( - ofType(SNACKBAR_WARNING), + ofType(SnackbarActionTypes.Warning), map(action => { done(); }) @@ -1028,7 +1029,7 @@ describe('ContentManagementService', () => { describe('notification', () => { it('raises warning on multiple fail and one success', fakeAsync(done => { actions$.pipe( - ofType(SNACKBAR_WARNING), + ofType(SnackbarActionTypes.Warning), map((action: SnackbarWarningAction) => { done(); }) @@ -1059,7 +1060,7 @@ describe('ContentManagementService', () => { it('raises warning on multiple success and multiple fail', fakeAsync(done => { actions$.pipe( - ofType(SNACKBAR_WARNING), + ofType(SnackbarActionTypes.Warning), map((action: SnackbarWarningAction) => { done(); }) @@ -1095,7 +1096,7 @@ describe('ContentManagementService', () => { it('raises info on one selected node success', fakeAsync(done => { actions$.pipe( - ofType(SNACKBAR_INFO), + ofType(SnackbarActionTypes.Info), map((action: SnackbarInfoAction) => { done(); }) @@ -1110,7 +1111,7 @@ describe('ContentManagementService', () => { it('raises error on one selected node fail', fakeAsync(done => { actions$.pipe( - ofType(SNACKBAR_ERROR), + ofType(SnackbarActionTypes.Error), map((action: SnackbarErrorAction) => { done(); }) @@ -1125,7 +1126,7 @@ describe('ContentManagementService', () => { it('raises info on all nodes success', fakeAsync(done => { actions$.pipe( - ofType(SNACKBAR_INFO), + ofType(SnackbarActionTypes.Info), map((action: SnackbarInfoAction) => { done(); }) @@ -1150,7 +1151,7 @@ describe('ContentManagementService', () => { it('raises error on all nodes fail', fakeAsync(done => { actions$.pipe( - ofType(SNACKBAR_ERROR), + ofType(SnackbarActionTypes.Error), map((action: SnackbarErrorAction) => { done(); }) @@ -1278,7 +1279,7 @@ describe('ContentManagementService', () => { const error = { message: '{ "error": {} }' }; actions$.pipe( - ofType(SNACKBAR_ERROR), + ofType(SnackbarActionTypes.Error), map(action => done()) ); @@ -1319,7 +1320,7 @@ describe('ContentManagementService', () => { spyOn(contentApi, 'restoreNode').and.returnValue(throwError(error)); actions$.pipe( - ofType(SNACKBAR_ERROR), + ofType(SnackbarActionTypes.Error), map(action => done()) ); @@ -1343,7 +1344,7 @@ describe('ContentManagementService', () => { spyOn(contentApi, 'restoreNode').and.returnValue(throwError(error)); actions$.pipe( - ofType(SNACKBAR_ERROR), + ofType(SnackbarActionTypes.Error), map(action => done()) ); @@ -1367,7 +1368,7 @@ describe('ContentManagementService', () => { spyOn(contentApi, 'restoreNode').and.returnValue(throwError(error)); actions$.pipe( - ofType(SNACKBAR_ERROR), + ofType(SnackbarActionTypes.Error), map(action => done()) ); @@ -1397,7 +1398,7 @@ describe('ContentManagementService', () => { }); actions$.pipe( - ofType(SNACKBAR_INFO), + ofType(SnackbarActionTypes.Info), map(action => done()) ); @@ -1422,7 +1423,7 @@ describe('ContentManagementService', () => { spyOn(contentApi, 'restoreNode').and.returnValue(of({})); actions$.pipe( - ofType(SNACKBAR_INFO), + ofType(SnackbarActionTypes.Info), map(action => done()) ); @@ -1444,7 +1445,7 @@ describe('ContentManagementService', () => { spyOn(contentApi, 'restoreNode').and.returnValue(of({})); actions$.pipe( - ofType(NAVIGATE_ROUTE), + ofType(RouterActionTypes.NavigateRoute), map(action => done()) ); diff --git a/src/app/services/content-management.service.ts b/src/app/services/content-management.service.ts index 1e80db29ad..91ec3c779b 100644 --- a/src/app/services/content-management.service.ts +++ b/src/app/services/content-management.service.ts @@ -23,49 +23,53 @@ * along with Alfresco. If not, see . */ -import { Subject, Observable, forkJoin, of, zip } from 'rxjs'; -import { Injectable } from '@angular/core'; -import { MatDialog, MatSnackBar } from '@angular/material'; -import { - FolderDialogComponent, - ConfirmDialogComponent, - LibraryDialogComponent -} from '@alfresco/adf-content-services'; +import { ContentApiService } from '@alfresco/aca-shared'; import { - SnackbarErrorAction, - SnackbarInfoAction, - SnackbarAction, - SnackbarWarningAction, + AppStore, + DeletedNodeInfo, + DeleteStatus, + getAppSelection, + getSharedUrl, NavigateRouteAction, NavigateToParentFolder, - SnackbarUserAction, - UndoDeleteNodesAction, + NodeInfo, + ReloadDocumentListAction, SetSelectedNodesAction, - ReloadDocumentListAction -} from '../store/actions'; -import { Store } from '@ngrx/store'; -import { AppStore } from '../store/states'; + SnackbarAction, + SnackbarErrorAction, + SnackbarInfoAction, + SnackbarUserAction, + SnackbarWarningAction, + UndoDeleteNodesAction +} from '@alfresco/aca-shared/store'; import { + ConfirmDialogComponent, + FolderDialogComponent, + LibraryDialogComponent +} from '@alfresco/adf-content-services'; +import { TranslationService } from '@alfresco/adf-core'; +import { + DeletedNodesPaging, MinimalNodeEntity, MinimalNodeEntryEntity, Node, - SiteEntry, - DeletedNodesPaging, + NodeEntry, PathInfoEntity, SiteBody, - NodeEntry + SiteEntry } from '@alfresco/js-api'; -import { NodePermissionService } from './node-permission.service'; -import { NodeInfo, DeletedNodeInfo, DeleteStatus } from '../store/models'; -import { ContentApiService } from './content-api.service'; -import { sharedUrl, appSelection } from '../store/selectors/app.selectors'; -import { NodeActionsService } from './node-actions.service'; -import { TranslationService, ViewUtilService } from '@alfresco/adf-core'; +import { Injectable } from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; +import { MatSnackBar } from '@angular/material/snack-bar'; +import { Store } from '@ngrx/store'; +import { forkJoin, Observable, of, Subject, zip } from 'rxjs'; +import { catchError, flatMap, map, mergeMap, take, tap } from 'rxjs/operators'; +import { NodePermissionsDialogComponent } from '../components/permissions/permission-dialog/node-permissions.dialog'; +import { ShareDialogComponent } from '../components/shared/content-node-share/content-node-share.dialog'; import { NodeVersionUploadDialogComponent } from '../dialogs/node-version-upload/node-version-upload.dialog'; import { NodeVersionsDialogComponent } from '../dialogs/node-versions/node-versions.dialog'; -import { ShareDialogComponent } from '../components/shared/content-node-share/content-node-share.dialog'; -import { take, map, tap, mergeMap, catchError, flatMap } from 'rxjs/operators'; -import { NodePermissionsDialogComponent } from '../components/permissions/permission-dialog/node-permissions.dialog'; +import { NodeActionsService } from './node-actions.service'; +import { NodePermissionService } from '@alfresco/aca-shared'; interface RestoredNode { status: number; @@ -96,8 +100,7 @@ export class ContentManagementService { private dialogRef: MatDialog, private nodeActionsService: NodeActionsService, private translation: TranslationService, - private snackBar: MatSnackBar, - private viewUtils: ViewUtilService + private snackBar: MatSnackBar ) {} addFavorite(nodes: Array) { @@ -197,7 +200,7 @@ export class ContentManagementService { openShareLinkDialog(node) { this.store - .select(sharedUrl) + .select(getSharedUrl) .pipe(take(1)) .subscribe(baseShareUrl => { this.dialogRef @@ -1164,42 +1167,8 @@ export class ContentManagementService { return i18nMessageString; } - printFile(node: any) { - if (node && node.entry) { - // shared and favorite - const id = node.entry.nodeId || node.entry.guid || node.entry.id; - const mimeType = node.entry.content.mimeType; - - if (id) { - this.viewUtils.printFileGeneric(id, mimeType); - } - } - } - - /** - * Triggers full screen mode with a main content area displayed. - */ - fullscreenViewer() { - const container = ( - document.documentElement.querySelector( - '.adf-viewer__fullscreen-container' - ) - ); - if (container) { - if (container.requestFullscreen) { - container.requestFullscreen(); - } else if (container.webkitRequestFullscreen) { - container.webkitRequestFullscreen(); - } else if (container.mozRequestFullScreen) { - container.mozRequestFullScreen(); - } else if (container.msRequestFullscreen) { - container.msRequestFullscreen(); - } - } - } - getNodeInfo() { - return this.store.select(appSelection).pipe( + return this.store.select(getAppSelection).pipe( take(1), flatMap(({ file }) => { const id = (file).entry.nodeId || (file).entry.guid; diff --git a/src/app/services/node-actions.service.spec.ts b/src/app/services/node-actions.service.spec.ts index a2326c0f00..17518dc61f 100644 --- a/src/app/services/node-actions.service.spec.ts +++ b/src/app/services/node-actions.service.spec.ts @@ -24,14 +24,14 @@ */ import { TestBed, async } from '@angular/core/testing'; -import { MatDialog } from '@angular/material'; +import { MatDialog } from '@angular/material/dialog'; import { of, throwError } from 'rxjs'; import { AlfrescoApiService, TranslationService } from '@alfresco/adf-core'; import { DocumentListService } from '@alfresco/adf-content-services'; import { NodeActionsService } from './node-actions.service'; import { MinimalNodeEntryEntity } from '@alfresco/js-api'; import { AppTestingModule } from '../testing/app-testing.module'; -import { ContentApiService } from '../services/content-api.service'; +import { ContentApiService } from '@alfresco/aca-shared'; class TestNode { entry?: MinimalNodeEntryEntity; diff --git a/src/app/services/node-actions.service.ts b/src/app/services/node-actions.service.ts index f5a1a08a6c..ada1b39376 100644 --- a/src/app/services/node-actions.service.ts +++ b/src/app/services/node-actions.service.ts @@ -24,7 +24,7 @@ */ import { Injectable } from '@angular/core'; -import { MatDialog } from '@angular/material'; +import { MatDialog } from '@angular/material/dialog'; import { Observable, Subject, of, zip, from } from 'rxjs'; import { @@ -48,7 +48,7 @@ import { Site, NodeChildAssociationPaging } from '@alfresco/js-api'; -import { ContentApiService } from '../services/content-api.service'; +import { ContentApiService } from '@alfresco/aca-shared'; import { catchError, map, mergeMap } from 'rxjs/operators'; export enum BatchOperationType { diff --git a/src/app/store/app-store.module.ts b/src/app/store/app-store.module.ts index 1d39ce07e7..4ea9aae32f 100644 --- a/src/app/store/app-store.module.ts +++ b/src/app/store/app-store.module.ts @@ -26,41 +26,37 @@ import { NgModule } from '@angular/core'; import { StoreModule } from '@ngrx/store'; import { appReducer } from './reducers/app.reducer'; -import { INITIAL_STATE } from './states'; import { StoreRouterConnectingModule } from '@ngrx/router-store'; import { EffectsModule } from '@ngrx/effects'; import { environment } from '../../environments/environment'; import { StoreDevtoolsModule } from '@ngrx/store-devtools'; +import { SharedStoreModule } from '@alfresco/aca-shared/store'; import { AppEffects, - SnackbarEffects, NodeEffects, - RouterEffects, DownloadEffects, ViewerEffects, SearchEffects, LibraryEffects, UploadEffects, - FavoriteEffects, - ModalsEffects + FavoriteEffects } from './effects'; +import { INITIAL_STATE } from './initial-state'; @NgModule({ imports: [ StoreModule.forRoot({ app: appReducer }, { initialState: INITIAL_STATE }), StoreRouterConnectingModule.forRoot({ stateKey: 'router' }), + SharedStoreModule, EffectsModule.forRoot([ AppEffects, - SnackbarEffects, NodeEffects, - RouterEffects, DownloadEffects, ViewerEffects, SearchEffects, LibraryEffects, UploadEffects, - FavoriteEffects, - ModalsEffects + FavoriteEffects ]), !environment.production ? StoreDevtoolsModule.instrument({ maxAge: 25 }) diff --git a/src/app/store/effects.ts b/src/app/store/effects.ts index 421da1919c..29bee57734 100644 --- a/src/app/store/effects.ts +++ b/src/app/store/effects.ts @@ -27,11 +27,8 @@ export * from './effects/app.effects'; export * from './effects/download.effects'; export * from './effects/favorite.effects'; export * from './effects/node.effects'; -export * from './effects/router.effects'; -export * from './effects/snackbar.effects'; export * from './effects/viewer.effects'; export * from './effects/search.effects'; export * from './effects/library.effects'; export * from './effects/upload.effects'; -export * from './effects/modals.effects'; export * from './effects/upload.effects'; diff --git a/src/app/store/effects/app.effects.ts b/src/app/store/effects/app.effects.ts index 528602d743..682798aacb 100644 --- a/src/app/store/effects/app.effects.ts +++ b/src/app/store/effects/app.effects.ts @@ -27,11 +27,10 @@ import { Effect, Actions, ofType } from '@ngrx/effects'; import { Injectable } from '@angular/core'; import { map } from 'rxjs/operators'; import { + AppActionTypes, LogoutAction, - LOGOUT, - ReloadDocumentListAction, - RELOAD_DOCUMENT_LIST -} from '../actions/app.actions'; + ReloadDocumentListAction +} from '@alfresco/aca-shared/store'; import { AuthenticationService } from '@alfresco/adf-core'; import { Router } from '@angular/router'; import { ContentManagementService } from '../../services/content-management.service'; @@ -47,7 +46,7 @@ export class AppEffects { @Effect({ dispatch: false }) reload = this.actions$.pipe( - ofType(RELOAD_DOCUMENT_LIST), + ofType(AppActionTypes.ReloadDocumentList), map(action => { this.content.reload.next(action); }) @@ -55,7 +54,7 @@ export class AppEffects { @Effect({ dispatch: false }) logout$ = this.actions$.pipe( - ofType(LOGOUT), + ofType(AppActionTypes.Logout), map(() => { this.auth .logout() diff --git a/src/app/store/effects/download.effects.ts b/src/app/store/effects/download.effects.ts index d94651dc4b..3a53e54489 100644 --- a/src/app/store/effects/download.effects.ts +++ b/src/app/store/effects/download.effects.ts @@ -23,18 +23,21 @@ * along with Alfresco. If not, see . */ +import { + AppStore, + DownloadNodesAction, + NodeActionTypes, + NodeInfo, + getAppSelection +} from '@alfresco/aca-shared/store'; import { DownloadZipDialogComponent } from '@alfresco/adf-core'; +import { MinimalNodeEntity } from '@alfresco/js-api'; import { Injectable } from '@angular/core'; -import { MatDialog } from '@angular/material'; +import { MatDialog } from '@angular/material/dialog'; import { Actions, Effect, ofType } from '@ngrx/effects'; -import { map, take } from 'rxjs/operators'; -import { DownloadNodesAction, DOWNLOAD_NODES } from '../actions'; -import { NodeInfo } from '../models'; -import { ContentApiService } from '../../services/content-api.service'; -import { MinimalNodeEntity } from '@alfresco/js-api'; import { Store } from '@ngrx/store'; -import { AppStore } from '../states'; -import { appSelection } from '../selectors/app.selectors'; +import { map, take } from 'rxjs/operators'; +import { ContentApiService } from '@alfresco/aca-shared'; @Injectable() export class DownloadEffects { @@ -47,13 +50,13 @@ export class DownloadEffects { @Effect({ dispatch: false }) downloadNode$ = this.actions$.pipe( - ofType(DOWNLOAD_NODES), + ofType(NodeActionTypes.Download), map(action => { if (action.payload && action.payload.length > 0) { this.downloadNodes(action.payload); } else { this.store - .select(appSelection) + .select(getAppSelection) .pipe(take(1)) .subscribe(selection => { if (selection && !selection.isEmpty) { diff --git a/src/app/store/effects/favorite.effects.ts b/src/app/store/effects/favorite.effects.ts index 1c73888816..2b57eed91c 100644 --- a/src/app/store/effects/favorite.effects.ts +++ b/src/app/store/effects/favorite.effects.ts @@ -27,14 +27,13 @@ import { Effect, Actions, ofType } from '@ngrx/effects'; import { Injectable } from '@angular/core'; import { map, take } from 'rxjs/operators'; import { - ADD_FAVORITE, + AppStore, + NodeActionTypes, AddFavoriteAction, RemoveFavoriteAction, - REMOVE_FAVORITE -} from '../actions/favorite.actions'; + getAppSelection +} from '@alfresco/aca-shared/store'; import { Store } from '@ngrx/store'; -import { AppStore } from '../states'; -import { appSelection } from '../selectors/app.selectors'; import { ContentManagementService } from '../../services/content-management.service'; @Injectable() @@ -47,13 +46,13 @@ export class FavoriteEffects { @Effect({ dispatch: false }) addFavorite$ = this.actions$.pipe( - ofType(ADD_FAVORITE), + ofType(NodeActionTypes.AddFavorite), map(action => { if (action.payload && action.payload.length > 0) { this.content.addFavorite(action.payload); } else { this.store - .select(appSelection) + .select(getAppSelection) .pipe(take(1)) .subscribe(selection => { if (selection && !selection.isEmpty) { @@ -66,13 +65,13 @@ export class FavoriteEffects { @Effect({ dispatch: false }) removeFavorite$ = this.actions$.pipe( - ofType(REMOVE_FAVORITE), + ofType(NodeActionTypes.RemoveFavorite), map(action => { if (action.payload && action.payload.length > 0) { this.content.removeFavorite(action.payload); } else { this.store - .select(appSelection) + .select(getAppSelection) .pipe(take(1)) .subscribe(selection => { if (selection && !selection.isEmpty) { diff --git a/src/app/store/effects/library.effects.ts b/src/app/store/effects/library.effects.ts index 2350d759a3..c496cd3bff 100644 --- a/src/app/store/effects/library.effects.ts +++ b/src/app/store/effects/library.effects.ts @@ -23,28 +23,24 @@ * along with Alfresco. If not, see . */ -import { Effect, Actions, ofType } from '@ngrx/effects'; -import { Injectable } from '@angular/core'; -import { map, take, mergeMap } from 'rxjs/operators'; import { - DeleteLibraryAction, - DELETE_LIBRARY, + AppStore, CreateLibraryAction, - CREATE_LIBRARY, + DeleteLibraryAction, + LeaveLibraryAction, + LibraryActionTypes, NavigateLibraryAction, - NAVIGATE_LIBRARY, + NavigateRouteAction, + SnackbarErrorAction, UpdateLibraryAction, - UPDATE_LIBRARY, - LeaveLibraryAction, - LEAVE_LIBRARY, - NavigateRouteAction -} from '../actions'; -import { ContentManagementService } from '../../services/content-management.service'; + getAppSelection +} from '@alfresco/aca-shared/store'; +import { Injectable } from '@angular/core'; +import { Actions, Effect, ofType } from '@ngrx/effects'; import { Store } from '@ngrx/store'; -import { AppStore } from '../states'; -import { appSelection } from '../selectors/app.selectors'; -import { ContentApiService } from '../../services/content-api.service'; -import { SnackbarErrorAction } from '../actions/snackbar.actions'; +import { map, mergeMap, take } from 'rxjs/operators'; +import { ContentApiService } from '@alfresco/aca-shared'; +import { ContentManagementService } from '../../services/content-management.service'; @Injectable() export class LibraryEffects { @@ -57,13 +53,13 @@ export class LibraryEffects { @Effect({ dispatch: false }) deleteLibrary$ = this.actions$.pipe( - ofType(DELETE_LIBRARY), + ofType(LibraryActionTypes.Delete), map(action => { if (action.payload) { this.content.deleteLibrary(action.payload); } else { this.store - .select(appSelection) + .select(getAppSelection) .pipe(take(1)) .subscribe(selection => { if (selection && selection.library) { @@ -76,13 +72,13 @@ export class LibraryEffects { @Effect({ dispatch: false }) leaveLibrary$ = this.actions$.pipe( - ofType(LEAVE_LIBRARY), + ofType(LibraryActionTypes.Leave), map(action => { if (action.payload) { this.content.leaveLibrary(action.payload); } else { this.store - .select(appSelection) + .select(getAppSelection) .pipe(take(1)) .subscribe(selection => { if (selection && selection.library) { @@ -95,14 +91,14 @@ export class LibraryEffects { @Effect() createLibrary$ = this.actions$.pipe( - ofType(CREATE_LIBRARY), + ofType(LibraryActionTypes.Create), mergeMap(() => this.content.createLibrary()), map(libraryId => new NavigateLibraryAction(libraryId)) ); @Effect({ dispatch: false }) navigateLibrary$ = this.actions$.pipe( - ofType(NAVIGATE_LIBRARY), + ofType(LibraryActionTypes.Navigate), map(action => { const libraryId = action.payload; if (libraryId) { @@ -125,10 +121,10 @@ export class LibraryEffects { @Effect({ dispatch: false }) updateLibrary$ = this.actions$.pipe( - ofType(UPDATE_LIBRARY), + ofType(LibraryActionTypes.Update), map(action => { this.store - .select(appSelection) + .select(getAppSelection) .pipe(take(1)) .subscribe(selection => { if (selection && selection.library) { diff --git a/src/app/store/effects/node.effects.spec.ts b/src/app/store/effects/node.effects.spec.ts index f5e2325235..cab0701c6c 100644 --- a/src/app/store/effects/node.effects.spec.ts +++ b/src/app/store/effects/node.effects.spec.ts @@ -30,6 +30,7 @@ import { EffectsModule } from '@ngrx/effects'; import { Store } from '@ngrx/store'; import { ContentManagementService } from '../../services/content-management.service'; import { + SharedStoreModule, ShareNodeAction, SetSelectedNodesAction, UnshareNodesAction, @@ -44,25 +45,34 @@ import { ManagePermissionsAction, UnlockWriteAction, FullscreenViewerAction, - PrintFileAction -} from '../actions/node.actions'; -import { SetCurrentFolderAction } from '../actions/app.actions'; + PrintFileAction, + SetCurrentFolderAction +} from '@alfresco/aca-shared/store'; +import { ViewUtilService } from '@alfresco/adf-core'; +import { ViewerEffects } from './viewer.effects'; describe('NodeEffects', () => { let store: Store; - // let actions$: Actions; let contentService: ContentManagementService; + let viewUtilService: ViewUtilService; + let viewerEffects: ViewerEffects; beforeEach(() => { TestBed.configureTestingModule({ - imports: [AppTestingModule, EffectsModule.forRoot([NodeEffects])], + imports: [ + AppTestingModule, + SharedStoreModule, + EffectsModule.forRoot([NodeEffects, ViewerEffects]) + ], declarations: [], - providers: [] + providers: [ViewUtilService] }); // actions$ = TestBed.get(Actions); store = TestBed.get(Store); contentService = TestBed.get(ContentManagementService); + viewUtilService = TestBed.get(ViewUtilService); + viewerEffects = TestBed.get(ViewerEffects); }); describe('shareNode$', () => { @@ -403,17 +413,28 @@ describe('NodeEffects', () => { describe('printFile$', () => { it('it should print node content from payload', () => { - spyOn(contentService, 'printFile').and.stub(); - const node: any = { entry: { id: 'node-id' } }; + spyOn(viewUtilService, 'printFileGeneric').and.stub(); + const node: any = { + entry: { id: 'node-id', content: { mimeType: 'text/json' } } + }; store.dispatch(new PrintFileAction(node)); - expect(contentService.printFile).toHaveBeenCalledWith(node); + expect(viewUtilService.printFileGeneric).toHaveBeenCalledWith( + 'node-id', + 'text/json' + ); }); it('it should print node content from store', fakeAsync(() => { - spyOn(contentService, 'printFile').and.stub(); - const node: any = { entry: { isFile: true, id: 'node-id' } }; + spyOn(viewUtilService, 'printFileGeneric').and.stub(); + const node: any = { + entry: { + isFile: true, + id: 'node-id', + content: { mimeType: 'text/json' } + } + }; store.dispatch(new SetSelectedNodesAction([node])); @@ -421,17 +442,20 @@ describe('NodeEffects', () => { store.dispatch(new PrintFileAction(null)); - expect(contentService.printFile).toHaveBeenCalledWith(node); + expect(viewUtilService.printFileGeneric).toHaveBeenCalledWith( + 'node-id', + 'text/json' + ); })); }); describe('fullscreenViewer$', () => { it('should call fullscreen viewer', () => { - spyOn(contentService, 'fullscreenViewer').and.stub(); + spyOn(viewerEffects, 'enterFullScreen').and.stub(); store.dispatch(new FullscreenViewerAction(null)); - expect(contentService.fullscreenViewer).toHaveBeenCalled(); + expect(viewerEffects.enterFullScreen).toHaveBeenCalled(); }); }); diff --git a/src/app/store/effects/node.effects.ts b/src/app/store/effects/node.effects.ts index 3128edfea2..dd90baf393 100644 --- a/src/app/store/effects/node.effects.ts +++ b/src/app/store/effects/node.effects.ts @@ -27,61 +27,47 @@ import { Effect, Actions, ofType } from '@ngrx/effects'; import { Injectable } from '@angular/core'; import { map, take } from 'rxjs/operators'; import { Store } from '@ngrx/store'; -import { AppStore } from '../states/app.state'; import { + AppStore, + NodeActionTypes, PurgeDeletedNodesAction, - PURGE_DELETED_NODES, DeleteNodesAction, - DELETE_NODES, UndoDeleteNodesAction, - UNDO_DELETE_NODES, CreateFolderAction, - CREATE_FOLDER, EditFolderAction, - EDIT_FOLDER, RestoreDeletedNodesAction, - RESTORE_DELETED_NODES, ShareNodeAction, - SHARE_NODE, ManageVersionsAction, - MANAGE_VERSIONS, UnlockWriteAction, - UNLOCK_WRITE -} from '../actions'; -import { ContentManagementService } from '../../services/content-management.service'; -import { currentFolder, appSelection } from '../selectors/app.selectors'; -import { UnshareNodesAction, - UNSHARE_NODES, CopyNodesAction, - COPY_NODES, MoveNodesAction, - MOVE_NODES, ManagePermissionsAction, - MANAGE_PERMISSIONS, - PRINT_FILE, PrintFileAction, - FULLSCREEN_VIEWER, - FullscreenViewerAction -} from '../actions/node.actions'; + getCurrentFolder, + getAppSelection +} from '@alfresco/aca-shared/store'; +import { ContentManagementService } from '../../services/content-management.service'; +import { ViewUtilService } from '@alfresco/adf-core'; @Injectable() export class NodeEffects { constructor( private store: Store, private actions$: Actions, - private contentService: ContentManagementService + private contentService: ContentManagementService, + private viewUtils: ViewUtilService ) {} @Effect({ dispatch: false }) shareNode$ = this.actions$.pipe( - ofType(SHARE_NODE), + ofType(NodeActionTypes.Share), map(action => { if (action.payload) { this.contentService.shareNode(action.payload); } else { this.store - .select(appSelection) + .select(getAppSelection) .pipe(take(1)) .subscribe(selection => { if (selection && selection.file) { @@ -94,13 +80,13 @@ export class NodeEffects { @Effect({ dispatch: false }) unshareNodes$ = this.actions$.pipe( - ofType(UNSHARE_NODES), + ofType(NodeActionTypes.Unshare), map(action => { if (action && action.payload && action.payload.length > 0) { this.contentService.unshareNodes(action.payload); } else { this.store - .select(appSelection) + .select(getAppSelection) .pipe(take(1)) .subscribe(selection => { if (selection && !selection.isEmpty) { @@ -113,13 +99,13 @@ export class NodeEffects { @Effect({ dispatch: false }) purgeDeletedNodes$ = this.actions$.pipe( - ofType(PURGE_DELETED_NODES), + ofType(NodeActionTypes.PurgeDeleted), map(action => { if (action && action.payload && action.payload.length > 0) { this.contentService.purgeDeletedNodes(action.payload); } else { this.store - .select(appSelection) + .select(getAppSelection) .pipe(take(1)) .subscribe(selection => { if (selection && selection.count > 0) { @@ -132,13 +118,13 @@ export class NodeEffects { @Effect({ dispatch: false }) restoreDeletedNodes$ = this.actions$.pipe( - ofType(RESTORE_DELETED_NODES), + ofType(NodeActionTypes.RestoreDeleted), map(action => { if (action && action.payload && action.payload.length > 0) { this.contentService.restoreDeletedNodes(action.payload); } else { this.store - .select(appSelection) + .select(getAppSelection) .pipe(take(1)) .subscribe(selection => { if (selection && selection.count > 0) { @@ -151,13 +137,13 @@ export class NodeEffects { @Effect({ dispatch: false }) deleteNodes$ = this.actions$.pipe( - ofType(DELETE_NODES), + ofType(NodeActionTypes.Delete), map(action => { if (action && action.payload && action.payload.length > 0) { this.contentService.deleteNodes(action.payload); } else { this.store - .select(appSelection) + .select(getAppSelection) .pipe(take(1)) .subscribe(selection => { if (selection && selection.count > 0) { @@ -170,7 +156,7 @@ export class NodeEffects { @Effect({ dispatch: false }) undoDeleteNodes$ = this.actions$.pipe( - ofType(UNDO_DELETE_NODES), + ofType(NodeActionTypes.UndoDelete), map(action => { if (action.payload.length > 0) { this.contentService.undoDeleteNodes(action.payload); @@ -180,13 +166,13 @@ export class NodeEffects { @Effect({ dispatch: false }) createFolder$ = this.actions$.pipe( - ofType(CREATE_FOLDER), + ofType(NodeActionTypes.CreateFolder), map(action => { if (action.payload) { this.contentService.createFolder(action.payload); } else { this.store - .select(currentFolder) + .select(getCurrentFolder) .pipe(take(1)) .subscribe(node => { if (node && node.id) { @@ -199,13 +185,13 @@ export class NodeEffects { @Effect({ dispatch: false }) editFolder$ = this.actions$.pipe( - ofType(EDIT_FOLDER), + ofType(NodeActionTypes.EditFolder), map(action => { if (action.payload) { this.contentService.editFolder(action.payload); } else { this.store - .select(appSelection) + .select(getAppSelection) .pipe(take(1)) .subscribe(selection => { if (selection && selection.folder) { @@ -218,13 +204,13 @@ export class NodeEffects { @Effect({ dispatch: false }) copyNodes$ = this.actions$.pipe( - ofType(COPY_NODES), + ofType(NodeActionTypes.Copy), map(action => { if (action.payload && action.payload.length > 0) { this.contentService.copyNodes(action.payload); } else { this.store - .select(appSelection) + .select(getAppSelection) .pipe(take(1)) .subscribe(selection => { if (selection && !selection.isEmpty) { @@ -237,13 +223,13 @@ export class NodeEffects { @Effect({ dispatch: false }) moveNodes$ = this.actions$.pipe( - ofType(MOVE_NODES), + ofType(NodeActionTypes.Move), map(action => { if (action.payload && action.payload.length > 0) { this.contentService.moveNodes(action.payload); } else { this.store - .select(appSelection) + .select(getAppSelection) .pipe(take(1)) .subscribe(selection => { if (selection && !selection.isEmpty) { @@ -256,13 +242,13 @@ export class NodeEffects { @Effect({ dispatch: false }) managePermissions$ = this.actions$.pipe( - ofType(MANAGE_PERMISSIONS), + ofType(NodeActionTypes.ManagePermissions), map(action => { if (action && action.payload) { this.contentService.managePermissions(action.payload); } else { this.store - .select(appSelection) + .select(getAppSelection) .pipe(take(1)) .subscribe(selection => { if (selection && !selection.isEmpty) { @@ -275,13 +261,13 @@ export class NodeEffects { @Effect({ dispatch: false }) manageVersions$ = this.actions$.pipe( - ofType(MANAGE_VERSIONS), + ofType(NodeActionTypes.ManageVersions), map(action => { if (action && action.payload) { this.contentService.manageVersions(action.payload); } else { this.store - .select(appSelection) + .select(getAppSelection) .pipe(take(1)) .subscribe(selection => { if (selection && selection.file) { @@ -294,40 +280,32 @@ export class NodeEffects { @Effect({ dispatch: false }) printFile$ = this.actions$.pipe( - ofType(PRINT_FILE), + ofType(NodeActionTypes.PrintFile), map(action => { if (action && action.payload) { - this.contentService.printFile(action.payload); + this.printFile(action.payload); } else { this.store - .select(appSelection) + .select(getAppSelection) .pipe(take(1)) .subscribe(selection => { if (selection && selection.file) { - this.contentService.printFile(selection.file); + this.printFile(selection.file); } }); } }) ); - @Effect({ dispatch: false }) - fullscreenViewer$ = this.actions$.pipe( - ofType(FULLSCREEN_VIEWER), - map(() => { - this.contentService.fullscreenViewer(); - }) - ); - @Effect({ dispatch: false }) unlockWrite$ = this.actions$.pipe( - ofType(UNLOCK_WRITE), + ofType(NodeActionTypes.UnlockForWriting), map(action => { if (action && action.payload) { this.contentService.unlockNode(action.payload); } else { this.store - .select(appSelection) + .select(getAppSelection) .pipe(take(1)) .subscribe(selection => { if (selection && selection.file) { @@ -337,4 +315,16 @@ export class NodeEffects { } }) ); + + printFile(node: any) { + if (node && node.entry) { + // shared and favorite + const id = node.entry.nodeId || node.entry.guid || node.entry.id; + const mimeType = node.entry.content.mimeType; + + if (id) { + this.viewUtils.printFileGeneric(id, mimeType); + } + } + } } diff --git a/src/app/store/effects/search.effects.spec.ts b/src/app/store/effects/search.effects.spec.ts index 08eacc76be..4667cf0bdc 100644 --- a/src/app/store/effects/search.effects.spec.ts +++ b/src/app/store/effects/search.effects.spec.ts @@ -28,9 +28,11 @@ import { AppTestingModule } from '../../testing/app-testing.module'; import { SearchEffects } from './search.effects'; import { EffectsModule } from '@ngrx/effects'; import { Store } from '@ngrx/store'; -import { SearchByTermAction } from '../actions/search.actions'; import { Router } from '@angular/router'; -import { SearchOptionIds } from '../models/searchOption.model'; +import { + SearchOptionIds, + SearchByTermAction +} from '@alfresco/aca-shared/store'; describe('SearchEffects', () => { let store: Store; diff --git a/src/app/store/effects/search.effects.ts b/src/app/store/effects/search.effects.ts index a6037ae119..477f73eeb2 100644 --- a/src/app/store/effects/search.effects.ts +++ b/src/app/store/effects/search.effects.ts @@ -26,9 +26,12 @@ import { Effect, Actions, ofType } from '@ngrx/effects'; import { Injectable } from '@angular/core'; import { map } from 'rxjs/operators'; -import { SEARCH_BY_TERM, SearchByTermAction } from '../actions/search.actions'; +import { + SearchActionTypes, + SearchByTermAction, + SearchOptionIds +} from '@alfresco/aca-shared/store'; import { Router } from '@angular/router'; -import { SearchOptionIds } from '../models/searchOption.model'; @Injectable() export class SearchEffects { @@ -36,7 +39,7 @@ export class SearchEffects { @Effect({ dispatch: false }) searchByTerm$ = this.actions$.pipe( - ofType(SEARCH_BY_TERM), + ofType(SearchActionTypes.SearchByTerm), map(action => { const query = action.payload .replace(/[(]/g, '%28') diff --git a/src/app/store/effects/upload.effects.spec.ts b/src/app/store/effects/upload.effects.spec.ts index a5d094b731..8a4992f9e4 100644 --- a/src/app/store/effects/upload.effects.spec.ts +++ b/src/app/store/effects/upload.effects.spec.ts @@ -34,7 +34,7 @@ import { FileUploadCompleteEvent, FileModel } from '@alfresco/adf-core'; -import { UnlockWriteAction } from '../actions'; +import { UnlockWriteAction } from '@alfresco/aca-shared/store'; describe('UploadEffects', () => { let store: Store; diff --git a/src/app/store/effects/upload.effects.ts b/src/app/store/effects/upload.effects.ts index 4b8d5b6000..e53e8a471a 100644 --- a/src/app/store/effects/upload.effects.ts +++ b/src/app/store/effects/upload.effects.ts @@ -23,33 +23,31 @@ * along with Alfresco. If not, see . */ -import { Injectable, RendererFactory2, NgZone } from '@angular/core'; -import { Actions, Effect, ofType } from '@ngrx/effects'; -import { Store } from '@ngrx/store'; -import { AppStore } from '../states'; import { + AppStore, + SnackbarErrorAction, + UnlockWriteAction, + UploadActionTypes, UploadFilesAction, - UPLOAD_FILES, - UploadFolderAction, - UPLOAD_FOLDER, - UPLOAD_FILE_VERSION, UploadFileVersionAction, - SnackbarErrorAction, - UnlockWriteAction -} from '../actions'; + UploadFolderAction, + getCurrentFolder +} from '@alfresco/aca-shared/store'; +import { FileModel, FileUtils, UploadService } from '@alfresco/adf-core'; +import { Injectable, NgZone, RendererFactory2 } from '@angular/core'; +import { Actions, Effect, ofType } from '@ngrx/effects'; +import { Store } from '@ngrx/store'; +import { forkJoin, fromEvent, of } from 'rxjs'; import { - map, - take, - flatMap, - distinctUntilChanged, catchError, + distinctUntilChanged, + filter, + flatMap, + map, switchMap, - tap, - filter + take, + tap } from 'rxjs/operators'; -import { FileUtils, FileModel, UploadService } from '@alfresco/adf-core'; -import { currentFolder } from '../selectors/app.selectors'; -import { fromEvent, of, forkJoin } from 'rxjs'; import { ContentManagementService } from '../../services/content-management.service'; @Injectable() @@ -95,7 +93,7 @@ export class UploadEffects { @Effect({ dispatch: false }) uploadFiles$ = this.actions$.pipe( - ofType(UPLOAD_FILES), + ofType(UploadActionTypes.UploadFiles), map(() => { this.fileInput.click(); }) @@ -103,7 +101,7 @@ export class UploadEffects { @Effect({ dispatch: false }) uploadFolder$ = this.actions$.pipe( - ofType(UPLOAD_FOLDER), + ofType(UploadActionTypes.UploadFolder), map(() => { this.folderInput.click(); }) @@ -111,7 +109,7 @@ export class UploadEffects { @Effect({ dispatch: false }) uploadVersion$ = this.actions$.pipe( - ofType(UPLOAD_FILE_VERSION), + ofType(UploadActionTypes.UploadFileVersion), switchMap(() => { this.fileVersionInput.click(); return fromEvent(this.fileVersionInput, 'change').pipe( @@ -155,7 +153,7 @@ export class UploadEffects { private upload(event: any): void { this.store - .select(currentFolder) + .select(getCurrentFolder) .pipe(take(1)) .subscribe(node => { if (node && node.id) { diff --git a/src/app/store/effects/viewer.effects.ts b/src/app/store/effects/viewer.effects.ts index fc7be8f103..31ccc90cc0 100644 --- a/src/app/store/effects/viewer.effects.ts +++ b/src/app/store/effects/viewer.effects.ts @@ -26,16 +26,21 @@ import { Effect, Actions, ofType } from '@ngrx/effects'; import { Injectable } from '@angular/core'; import { map, take } from 'rxjs/operators'; -import { VIEW_FILE, ViewFileAction } from '../actions'; +import { + AppStore, + ViewerActionTypes, + ViewFileAction, + ViewNodeAction, + getCurrentFolder, + getAppSelection, + FullscreenViewerAction +} from '@alfresco/aca-shared/store'; import { Router } from '@angular/router'; import { Store, createSelector } from '@ngrx/store'; -import { AppStore } from '../states'; -import { appSelection, currentFolder } from '../selectors/app.selectors'; -import { ViewNodeAction, VIEW_NODE } from '../actions/viewer.actions'; export const fileToPreview = createSelector( - appSelection, - currentFolder, + getAppSelection, + getCurrentFolder, (selection, folder) => { return { selection, @@ -52,9 +57,17 @@ export class ViewerEffects { private router: Router ) {} + @Effect({ dispatch: false }) + fullscreenViewer$ = this.actions$.pipe( + ofType(ViewerActionTypes.FullScreen), + map(() => { + this.enterFullScreen(); + }) + ); + @Effect({ dispatch: false }) viewNode$ = this.actions$.pipe( - ofType(VIEW_NODE), + ofType(ViewerActionTypes.ViewNode), map(action => { if (action.location) { this.router.navigate( @@ -76,7 +89,7 @@ export class ViewerEffects { @Effect({ dispatch: false }) viewFile$ = this.actions$.pipe( - ofType(VIEW_FILE), + ofType(ViewerActionTypes.ViewFile), map(action => { if (action.payload && action.payload.entry) { const { id, nodeId, isFile } = action.payload.entry; @@ -123,4 +136,23 @@ export class ViewerEffects { path.push('preview', nodeId); this.router.navigateByUrl(path.join('/')); } + + enterFullScreen() { + const container = ( + document.documentElement.querySelector( + '.adf-viewer__fullscreen-container' + ) + ); + if (container) { + if (container.requestFullscreen) { + container.requestFullscreen(); + } else if (container.webkitRequestFullscreen) { + container.webkitRequestFullscreen(); + } else if (container.mozRequestFullScreen) { + container.mozRequestFullScreen(); + } else if (container.msRequestFullscreen) { + container.msRequestFullscreen(); + } + } + } } diff --git a/src/app/store/states/app.state.ts b/src/app/store/initial-state.ts similarity index 74% rename from src/app/store/states/app.state.ts rename to src/app/store/initial-state.ts index f1356549d2..7af49305d9 100644 --- a/src/app/store/states/app.state.ts +++ b/src/app/store/initial-state.ts @@ -23,30 +23,10 @@ * along with Alfresco. If not, see . */ -import { - SelectionState, - ProfileState, - NavigationState -} from '@alfresco/adf-extensions'; -import { RepositoryInfo } from '@alfresco/js-api'; - -export interface AppState { - appName: string; - headerColor: string; - logoPath: string; - languagePicker: boolean; - sharedUrl: string; - selection: SelectionState; - user: ProfileState; - navigation: NavigationState; - infoDrawerOpened: boolean; - showFacetFilter: boolean; - documentDisplayMode: string; - repository: RepositoryInfo; -} +import { AppState, AppStore } from '@alfresco/aca-shared/store'; export const INITIAL_APP_STATE: AppState = { - appName: 'Alfresco Example Content Application', + appName: 'Alfresco Content Application', headerColor: '#2196F3', logoPath: 'assets/images/alfresco-logo-white.svg', languagePicker: false, @@ -76,10 +56,6 @@ export const INITIAL_APP_STATE: AppState = { } }; -export interface AppStore { - app: AppState; -} - export const INITIAL_STATE: AppStore = { app: INITIAL_APP_STATE }; diff --git a/src/app/store/models.ts b/src/app/store/models.ts deleted file mode 100644 index 9aea5f541f..0000000000 --- a/src/app/store/models.ts +++ /dev/null @@ -1,28 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2019 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -export * from './models/delete-status.model'; -export * from './models/deleted-node-info.model'; -export * from './models/node-info.model'; diff --git a/src/app/store/reducers/app.reducer.ts b/src/app/store/reducers/app.reducer.ts index 4f376f50cc..04dd554656 100644 --- a/src/app/store/reducers/app.reducer.ts +++ b/src/app/store/reducers/app.reducer.ts @@ -24,30 +24,21 @@ */ import { Action } from '@ngrx/store'; -import { AppState, INITIAL_APP_STATE } from '../states/app.state'; import { - SET_SELECTED_NODES, - SetSelectedNodesAction, - SET_USER_PROFILE, + AppState, + AppActionTypes, + NodeActionTypes, + SearchActionTypes, SetUserProfileAction, - SET_REPOSITORY_INFO, - SetRepositoryInfoAction, - SET_LANGUAGE_PICKER, SetLanguagePickerAction, - SET_CURRENT_FOLDER, SetCurrentFolderAction, - SET_CURRENT_URL, SetCurrentUrlAction, - SET_INFO_DRAWER_STATE, - SetInfoDrawerStateAction, - TOGGLE_INFO_DRAWER, - TOGGLE_DOCUMENT_DISPLAY_MODE, - SET_INITIAL_STATE, SetInitialStateAction, - TOGGLE_SEARCH_FILTER, - SHOW_SEARCH_FILTER, - HIDE_SEARCH_FILTER -} from '../actions'; + SetSelectedNodesAction, + SetRepositoryInfoAction, + SetInfoDrawerStateAction +} from '@alfresco/aca-shared/store'; +import { INITIAL_APP_STATE } from '../initial-state'; export function appReducer( state: AppState = INITIAL_APP_STATE, @@ -56,43 +47,43 @@ export function appReducer( let newState: AppState; switch (action.type) { - case SET_INITIAL_STATE: + case AppActionTypes.SetInitialState: newState = Object.assign({}, (action).payload); break; - case SET_SELECTED_NODES: + case NodeActionTypes.SetSelection: newState = updateSelectedNodes(state, action); break; - case SET_USER_PROFILE: + case AppActionTypes.SetUserProfile: newState = updateUser(state, action); break; - case SET_LANGUAGE_PICKER: + case AppActionTypes.SetLanguagePicker: newState = updateLanguagePicker(state, action); break; - case SET_CURRENT_FOLDER: + case AppActionTypes.SetCurrentFolder: newState = updateCurrentFolder(state, action); break; - case SET_CURRENT_URL: + case AppActionTypes.SetCurrentUrl: newState = updateCurrentUrl(state, action); break; - case TOGGLE_INFO_DRAWER: + case AppActionTypes.ToggleInfoDrawer: newState = toggleInfoDrawer(state); break; - case SET_INFO_DRAWER_STATE: + case AppActionTypes.SetInfoDrawerState: newState = setInfoDrawer(state, action); break; - case TOGGLE_DOCUMENT_DISPLAY_MODE: + case AppActionTypes.ToggleDocumentDisplayMode: newState = toggleDocumentDisplayMode(state); break; - case SET_REPOSITORY_INFO: + case AppActionTypes.SetRepositoryInfo: newState = updateRepositoryStatus(state, action); break; - case TOGGLE_SEARCH_FILTER: + case SearchActionTypes.ToggleFilter: newState = toggleSearchFilter(state); break; - case SHOW_SEARCH_FILTER: + case SearchActionTypes.ShowFilter: newState = showSearchFilter(state); break; - case HIDE_SEARCH_FILTER: + case SearchActionTypes.HideFilter: newState = hideSearchFilter(state); break; default: diff --git a/src/app/testing/app-testing.module.ts b/src/app/testing/app-testing.module.ts index d13f2767fe..3e8bf6b0f5 100644 --- a/src/app/testing/app-testing.module.ts +++ b/src/app/testing/app-testing.module.ts @@ -48,7 +48,6 @@ import { HttpClientModule } from '@angular/common/http'; import { TranslateServiceMock } from './translation.service'; import { StoreModule } from '@ngrx/store'; import { appReducer } from '../store/reducers/app.reducer'; -import { INITIAL_STATE } from '../store/states/app.state'; import { RouterTestingModule } from '@angular/router/testing'; import { EffectsModule } from '@ngrx/effects'; import { @@ -56,6 +55,7 @@ import { DocumentListService } from '@alfresco/adf-content-services'; import { MaterialModule } from '../material.module'; +import { INITIAL_STATE } from '../store/initial-state'; @NgModule({ imports: [ diff --git a/src/app/ui/custom-theme.scss b/src/app/ui/custom-theme.scss index 097475f518..e970dd835b 100644 --- a/src/app/ui/custom-theme.scss +++ b/src/app/ui/custom-theme.scss @@ -3,7 +3,6 @@ @import '../components/sidenav/sidenav.component.theme'; @import '../components/about/about.component.theme'; -@import '../components/common/generic-error/generic-error.component.theme'; @import '../components/search/search-input/search-input.component.theme'; @import '../components/settings/settings.component.theme'; @import '../components/current-user/current-user.component.theme'; @@ -60,6 +59,7 @@ $custom-theme-accent: mat-palette($alfresco-accent-orange); $custom-theme-warn: mat-palette($alfresco-warn); $custom-theme: mat-light-theme($custom-theme-primary, $custom-theme-accent); $foreground: map-get($custom-theme, foreground); +$warn: map-get($custom-theme, warn); @mixin custom-theme($theme) { @include custom-adf-toolbar-theme($theme); @@ -67,7 +67,6 @@ $foreground: map-get($custom-theme, foreground); @include layout-theme($theme); @include aca-search-input-theme($theme); - @include aca-generic-error-theme($theme); @include app-permission-manager-theme($theme); @include aca-node-versions-dialog-theme($theme); @include aca-settings-theme($theme); @@ -96,3 +95,18 @@ $adf-upload-dragging-border: 1px solid #00bcd4; $adf-upload-dragging-background: #e0f7fa; $adf-upload-dragging-level1-color: unset; $adf-upload-dragging-level1-border: none; + +$defaults: ( + --theme-warn-color: mat-color($warn), + --theme-text-color: mat-color($foreground, text, 0.54), + --theme-title-color: mat-color($foreground, text, 0.87), + --theme-text-disabled-color: mat-color($foreground, text, 0.38), + --theme-border-color: mat-color($foreground, text, 0.07) +); + +// defaults +:root { + @each $name, $value in $defaults { + #{$name}: #{$value}; + } +} diff --git a/tsconfig.json b/tsconfig.json index b6dad6889c..a0b9424f80 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -20,7 +20,9 @@ ], "@alfresco/adf-office-services-ext/*": [ "dist/@alfresco/adf-office-services-ext/*" - ] + ], + "@alfresco/aca-shared": ["dist/@alfresco/aca-shared"], + "@alfresco/aca-shared/*": ["dist/@alfresco/aca-shared/*"] }, "resolveJsonModule": true }, From 39d3ccb7aca2329b502a9fa55e6dd963977af517 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Tue, 30 Apr 2019 10:23:31 +0100 Subject: [PATCH 186/259] fix generic error icon styling --- .../lib/components/generic-error/generic-error.component.html | 2 +- .../lib/components/generic-error/generic-error.component.scss | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/projects/aca-shared/src/lib/components/generic-error/generic-error.component.html b/projects/aca-shared/src/lib/components/generic-error/generic-error.component.html index 4ab4542a19..457f3475a0 100644 --- a/projects/aca-shared/src/lib/components/generic-error/generic-error.component.html +++ b/projects/aca-shared/src/lib/components/generic-error/generic-error.component.html @@ -1,4 +1,4 @@ -ic_error +error

{{ text | translate }}

diff --git a/projects/aca-shared/src/lib/components/generic-error/generic-error.component.scss b/projects/aca-shared/src/lib/components/generic-error/generic-error.component.scss index efba7b28dc..4081d9b737 100644 --- a/projects/aca-shared/src/lib/components/generic-error/generic-error.component.scss +++ b/projects/aca-shared/src/lib/components/generic-error/generic-error.component.scss @@ -14,7 +14,6 @@ mat-icon { color: var(--theme-warn-color, #f44336); - direction: rtl; font-size: 52px; height: 52px; width: 52px; From f45145f3a604fae644319c07904b860a328d2d26 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Tue, 30 Apr 2019 14:41:48 +0100 Subject: [PATCH 187/259] [ACA-2367] default header actions (#1088) * enable header actions by default * exclude app.extensions from spellcheck --- .github/plint.yml | 2 ++ src/assets/app.extensions.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/plint.yml b/.github/plint.yml index 84ed3336b1..9972c50036 100644 --- a/.github/plint.yml +++ b/.github/plint.yml @@ -8,3 +8,5 @@ spellcheck: - ngrx - qshare - snackbar + exclude: + - src/assets/app.extensions.json diff --git a/src/assets/app.extensions.json b/src/assets/app.extensions.json index fddd265f9c..b6b0f71093 100644 --- a/src/assets/app.extensions.json +++ b/src/assets/app.extensions.json @@ -7,7 +7,7 @@ "$license": "LGPL-3.0", "$runtime": "1.7.0", "$description": "Core application extensions and features", - "$references": ["aos.plugin.json"], + "$references": ["aos.plugin.json", "app.header.json"], "rules": [ { From 6d3b6407bcd44071dfe4ae2458640624819b0fa9 Mon Sep 17 00:00:00 2001 From: dhrn <14145706+dhrn@users.noreply.github.com> Date: Wed, 1 May 2019 18:52:11 +0530 Subject: [PATCH 188/259] [ACA-2365] infodrawer metadata in expanded card (#1090) * feat(info-drawer):- infodrawer default metadata in expanded card * * test added * * initial state fixed * * package updated with beta --- package-lock.json | 65 +++++++------------ package.json | 8 +-- .../store/src/actions/app.actions.ts | 1 + .../src/actions/metadata-aspect.actions.ts | 34 ++++++++++ projects/aca-shared/store/src/public_api.ts | 1 + .../store/src/selectors/app.selectors.ts | 5 ++ .../aca-shared/store/src/states/app.state.ts | 1 + .../metadata-tab.component.spec.ts | 54 ++++++++++++--- .../metadata-tab/metadata-tab.component.ts | 10 ++- src/app/store/initial-state.ts | 1 + src/app/store/reducers/app.reducer.ts | 17 ++++- 11 files changed, 139 insertions(+), 58 deletions(-) create mode 100644 projects/aca-shared/store/src/actions/metadata-aspect.actions.ts diff --git a/package-lock.json b/package-lock.json index 88eb950280..52a5074cae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,33 +5,33 @@ "requires": true, "dependencies": { "@alfresco/adf-content-services": { - "version": "3.2.0-beta7", - "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-3.2.0-beta7.tgz", - "integrity": "sha512-GQLAtCOB0Q4GY+0W2YFB8W5JWh519U0RTshpaqs9Bi9JbpbbfSR50+EA4M6w1AQLm9rWy/9LCeQ819CyOpMRpw==", + "version": "3.2.0-beta8", + "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-3.2.0-beta8.tgz", + "integrity": "sha512-K/IY00t2MR84MujVlDPnBLOCq7zklqoDeRa8+dEf6DhHgdfwTOK2aUGObITdlQ1rhTbSSl0llVAUkkHdtgCYmg==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/adf-core": { - "version": "3.2.0-beta7", - "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-3.2.0-beta7.tgz", - "integrity": "sha512-hSSJCK+Rezur7CWQjeT0uihzSuq+3cUR/qQEVGehNVte0y/bw6ceJWW+00sKS6ICU0byQDDAjsOqPuEMshqchg==", + "version": "3.2.0-beta8", + "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-3.2.0-beta8.tgz", + "integrity": "sha512-WC1m5HaFCrLbJQBnqrlGeb1UJ3MRHb1F0Ok7HgXmT7FSQwltBO54bJ5Ve2ttQ4xQJnJGMsHpzVncjmmV0LTiiA==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/adf-extensions": { - "version": "3.2.0-beta7", - "resolved": "https://registry.npmjs.org/@alfresco/adf-extensions/-/adf-extensions-3.2.0-beta7.tgz", - "integrity": "sha512-2KxNnnCDXu619jV3eslX685j/CkZl2C+BfwEHNP7v5q9eCh4tJ4r5LALvRHnJ44BsRojvJrNG23VND/X4tS2Ng==", + "version": "3.2.0-beta8", + "resolved": "https://registry.npmjs.org/@alfresco/adf-extensions/-/adf-extensions-3.2.0-beta8.tgz", + "integrity": "sha512-PCv5zPo94O753s+SPLzzlzW9SJ1mRw4CwN8hY8xCTGGIQuSbaHnrTmgUIBHwp0gYVxcbQEULGymNSOz3e0Nslw==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/js-api": { - "version": "3.2.0-beta7", - "resolved": "https://registry.npmjs.org/@alfresco/js-api/-/js-api-3.2.0-beta7.tgz", - "integrity": "sha512-8vWkFdi7qeSBjtk4ogEwEO1ApemcXAckPcPKmWWb2thbCyuW4JhDNa7+csPezuxYgIrhrEk+awRXN+b4xVDmaw==", + "version": "3.2.0-beta8", + "resolved": "https://registry.npmjs.org/@alfresco/js-api/-/js-api-3.2.0-beta8.tgz", + "integrity": "sha512-bXxBrP86akor52Fdse3Oj8Z1cS8RZsAlQrldSF3+HvgBhofEigldas7qYvK4RibkFw5tWBJhKVfd1LMfDuaVbg==", "requires": { "event-emitter": "0.3.4", "superagent": "3.8.2" @@ -4959,8 +4959,7 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "aproba": { "version": "1.2.0", @@ -4981,14 +4980,12 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -5003,20 +5000,17 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -5133,8 +5127,7 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -5146,7 +5139,6 @@ "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -5161,7 +5153,6 @@ "version": "3.0.4", "bundled": true, "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -5169,14 +5160,12 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -5195,7 +5184,6 @@ "version": "0.5.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -5276,8 +5264,7 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -5289,7 +5276,6 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -5375,8 +5361,7 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "safer-buffer": { "version": "2.1.2", @@ -5412,7 +5397,6 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -5432,7 +5416,6 @@ "version": "3.0.1", "bundled": true, "dev": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -5476,14 +5459,12 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true } } }, diff --git a/package.json b/package.json index d1af1f3325..48264d579f 100644 --- a/package.json +++ b/package.json @@ -37,10 +37,10 @@ }, "private": true, "dependencies": { - "@alfresco/adf-content-services": "3.2.0-beta7", - "@alfresco/adf-core": "3.2.0-beta7", - "@alfresco/adf-extensions": "3.2.0-beta7", - "@alfresco/js-api": "3.2.0-beta7", + "@alfresco/adf-content-services": "3.2.0-beta8", + "@alfresco/adf-core": "3.2.0-beta8", + "@alfresco/adf-extensions": "3.2.0-beta8", + "@alfresco/js-api": "3.2.0-beta8", "@angular/animations": "7.2.13", "@angular/cdk": "^7.3.7", "@angular/common": "7.2.13", diff --git a/projects/aca-shared/store/src/actions/app.actions.ts b/projects/aca-shared/store/src/actions/app.actions.ts index 864fae83c7..8ccfcc4a1e 100644 --- a/projects/aca-shared/store/src/actions/app.actions.ts +++ b/projects/aca-shared/store/src/actions/app.actions.ts @@ -39,6 +39,7 @@ export enum AppActionTypes { Logout = 'LOGOUT', ReloadDocumentList = 'RELOAD_DOCUMENT_LIST', SetInfoDrawerState = 'SET_INFO_DRAWER_STATE', + SetInfoDrawerMetadataAspect = 'SET_INFO_DRAWER_METADATA_ASPECT', CloseModalDialogs = 'CLOSE_MODAL_DIALOGS' } diff --git a/projects/aca-shared/store/src/actions/metadata-aspect.actions.ts b/projects/aca-shared/store/src/actions/metadata-aspect.actions.ts new file mode 100644 index 0000000000..1668b89c53 --- /dev/null +++ b/projects/aca-shared/store/src/actions/metadata-aspect.actions.ts @@ -0,0 +1,34 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2019 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { Action } from '@ngrx/store'; + +export const SET_INFO_DRAWER_METADATA_ASPECT = + 'SET_INFO_DRAWER_METADATA_ASPECT'; + +export class SetInfoDrawerMetadataAspectAction implements Action { + readonly type = SET_INFO_DRAWER_METADATA_ASPECT; + constructor(public payload: string) {} +} diff --git a/projects/aca-shared/store/src/public_api.ts b/projects/aca-shared/store/src/public_api.ts index 0a8d248323..c7695c5b91 100644 --- a/projects/aca-shared/store/src/public_api.ts +++ b/projects/aca-shared/store/src/public_api.ts @@ -31,6 +31,7 @@ export * from './actions/search.actions'; export * from './actions/snackbar.actions'; export * from './actions/upload.actions'; export * from './actions/viewer.actions'; +export * from './actions/metadata-aspect.actions'; export * from './effects/dialog.effects'; export * from './effects/router.effects'; diff --git a/projects/aca-shared/store/src/selectors/app.selectors.ts b/projects/aca-shared/store/src/selectors/app.selectors.ts index fb027a4d53..378ca20d48 100644 --- a/projects/aca-shared/store/src/selectors/app.selectors.ts +++ b/projects/aca-shared/store/src/selectors/app.selectors.ts @@ -128,3 +128,8 @@ export const getRuleContext = createSelector( }; } ); + +export const infoDrawerMetadataAspect = createSelector( + selectApp, + state => state.infoDrawerMetadataAspect +); diff --git a/projects/aca-shared/store/src/states/app.state.ts b/projects/aca-shared/store/src/states/app.state.ts index 763920c435..a0509c1ff5 100644 --- a/projects/aca-shared/store/src/states/app.state.ts +++ b/projects/aca-shared/store/src/states/app.state.ts @@ -40,6 +40,7 @@ export interface AppState { user: ProfileState; navigation: NavigationState; infoDrawerOpened: boolean; + infoDrawerMetadataAspect: string; showFacetFilter: boolean; documentDisplayMode: string; repository: RepositoryInfo; diff --git a/src/app/components/info-drawer/metadata-tab/metadata-tab.component.spec.ts b/src/app/components/info-drawer/metadata-tab/metadata-tab.component.spec.ts index 614658e4a3..e77ebc585f 100644 --- a/src/app/components/info-drawer/metadata-tab/metadata-tab.component.spec.ts +++ b/src/app/components/info-drawer/metadata-tab/metadata-tab.component.spec.ts @@ -24,23 +24,36 @@ */ import { MetadataTabComponent } from './metadata-tab.component'; -import { NodePermissionService } from '@alfresco/aca-shared'; import { Node } from '@alfresco/js-api'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { AppTestingModule } from '../../../testing/app-testing.module'; +import { setupTestBed } from '@alfresco/adf-core'; +import { ContentMetadataModule } from '@alfresco/adf-content-services'; +import { Store } from '@ngrx/store'; +import { + SetInfoDrawerMetadataAspectAction, + AppState +} from '@alfresco/aca-shared/store'; +import { By } from '@angular/platform-browser'; describe('MetadataTabComponent', () => { - let nodePermissionService: NodePermissionService; + let fixture: ComponentFixture; let component: MetadataTabComponent; + let store: Store; + + setupTestBed({ + imports: [AppTestingModule, ContentMetadataModule], + declarations: [MetadataTabComponent] + }); beforeEach(() => { - nodePermissionService = new NodePermissionService(); - const appConfig = { config: { 'content-metadata': {} } }; - const extension = { contentMetadata: {} }; + fixture = TestBed.createComponent(MetadataTabComponent); + store = TestBed.get(Store); + component = fixture.componentInstance; + }); - component = new MetadataTabComponent( - nodePermissionService, - extension, - appConfig - ); + afterEach(() => { + fixture.destroy(); }); describe('canUpdateNode()', () => { @@ -87,4 +100,25 @@ describe('MetadataTabComponent', () => { expect(component.canUpdateNode).toBe(false); }); }); + + describe('displayAspect', () => { + it('show pass empty when store is in initial state', () => { + const initialState = fixture.debugElement.query( + By.css('adf-content-metadata-card') + ); + expect(initialState.componentInstance.displayAspect).toBeFalsy(); + }); + + it('should update the exif if store got updated', () => { + store.dispatch(new SetInfoDrawerMetadataAspectAction('EXIF')); + component.displayAspect$.subscribe(aspect => { + expect(aspect).toBe('EXIF'); + }); + fixture.detectChanges(); + const initialState = fixture.debugElement.query( + By.css('adf-content-metadata-card') + ); + expect(initialState.componentInstance.displayAspect).toBe('EXIF'); + }); + }); }); diff --git a/src/app/components/info-drawer/metadata-tab/metadata-tab.component.ts b/src/app/components/info-drawer/metadata-tab/metadata-tab.component.ts index 040ed7fa37..f394d25a42 100644 --- a/src/app/components/info-drawer/metadata-tab/metadata-tab.component.ts +++ b/src/app/components/info-drawer/metadata-tab/metadata-tab.component.ts @@ -26,9 +26,12 @@ import { Component, Input, ViewEncapsulation } from '@angular/core'; import { MinimalNodeEntryEntity } from '@alfresco/js-api'; import { NodePermissionService } from '@alfresco/aca-shared'; +import { AppStore, infoDrawerMetadataAspect } from '@alfresco/aca-shared/store'; import { AppExtensionService } from '../../../extensions/extension.service'; import { AppConfigService } from '@alfresco/adf-core'; import { isLocked } from '../../../utils/node.utils'; +import { Observable } from 'rxjs'; +import { Store } from '@ngrx/store'; @Component({ selector: 'app-metadata-tab', @@ -37,6 +40,7 @@ import { isLocked } from '../../../utils/node.utils'; [readOnly]="!canUpdateNode" [preset]="'custom'" [node]="node" + [displayAspect]="displayAspect$ | async" > `, @@ -47,10 +51,13 @@ export class MetadataTabComponent { @Input() node: MinimalNodeEntryEntity; + displayAspect$: Observable; + constructor( private permission: NodePermissionService, protected extensions: AppExtensionService, - private appConfig: AppConfigService + private appConfig: AppConfigService, + private store: Store ) { try { this.appConfig.config[ @@ -62,6 +69,7 @@ export class MetadataTabComponent { '- could not change content-metadata from app.config' ); } + this.displayAspect$ = this.store.select(infoDrawerMetadataAspect); } get canUpdateNode(): boolean { diff --git a/src/app/store/initial-state.ts b/src/app/store/initial-state.ts index 7af49305d9..9a54f7fb98 100644 --- a/src/app/store/initial-state.ts +++ b/src/app/store/initial-state.ts @@ -47,6 +47,7 @@ export const INITIAL_APP_STATE: AppState = { currentFolder: null }, infoDrawerOpened: false, + infoDrawerMetadataAspect: '', showFacetFilter: true, documentDisplayMode: 'list', repository: { diff --git a/src/app/store/reducers/app.reducer.ts b/src/app/store/reducers/app.reducer.ts index 04dd554656..2a6b4ef05e 100644 --- a/src/app/store/reducers/app.reducer.ts +++ b/src/app/store/reducers/app.reducer.ts @@ -36,7 +36,8 @@ import { SetInitialStateAction, SetSelectedNodesAction, SetRepositoryInfoAction, - SetInfoDrawerStateAction + SetInfoDrawerStateAction, + SetInfoDrawerMetadataAspectAction } from '@alfresco/aca-shared/store'; import { INITIAL_APP_STATE } from '../initial-state'; @@ -71,6 +72,11 @@ export function appReducer( case AppActionTypes.SetInfoDrawerState: newState = setInfoDrawer(state, action); break; + case AppActionTypes.SetInfoDrawerMetadataAspect: + newState = setInfoDrawerAspect(state, ( + action + )); + break; case AppActionTypes.ToggleDocumentDisplayMode: newState = toggleDocumentDisplayMode(state); break; @@ -245,6 +251,15 @@ function setInfoDrawer(state: AppState, action: SetInfoDrawerStateAction) { return newState; } +function setInfoDrawerAspect( + state: AppState, + action: SetInfoDrawerMetadataAspectAction +) { + const newState = Object.assign({}, state); + newState.infoDrawerMetadataAspect = action.payload; + return newState; +} + function updateRepositoryStatus( state: AppState, action: SetRepositoryInfoAction From 0b3d19695baf5e616205f5c37059ee80fa7176a7 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Wed, 1 May 2019 14:23:37 +0100 Subject: [PATCH 189/259] bump shared lib version --- projects/aca-shared/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/aca-shared/package.json b/projects/aca-shared/package.json index 942ab68574..ce18997cee 100644 --- a/projects/aca-shared/package.json +++ b/projects/aca-shared/package.json @@ -1,6 +1,6 @@ { "name": "@alfresco/aca-shared", - "version": "1.8.0", + "version": "1.8.1", "peerDependencies": { "@angular/common": "^7.2.0", "@angular/core": "^7.2.0", From f3d8171579f3f0af7ea58501c41e8d1f1de7bc99 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Thu, 2 May 2019 21:02:06 +0100 Subject: [PATCH 190/259] upgrade to latest ADF and Angular libs (#1092) * upgrade to latest ADF and Angular libs * disable e2e tests for libaries * [ACA-2130] fix a11y for header * disable e2e tests * sticky header, layout fixes * switch to ADF upload dialog * disable broken test * disable broken test * disable test --- .../pagination/pag-file-libraries.test.ts | 4 +- e2e/suites/viewer/viewer-actions.test.ts | 10 +- package-lock.json | 483 ++++++++++-------- package.json | 34 +- .../app-layout/app-layout.component.html | 4 +- src/app/components/layout/layout.module.ts | 2 - .../file-uploading-dialog.component.html | 133 ----- .../file-uploading-dialog.component.ts | 24 - .../file-uploading-list-row.component.html | 109 ---- .../file-uploading-list-row.component.scss | 11 - .../file-uploading-list-row.component.ts | 50 -- .../file-uploading-list.component.html | 4 - .../file-uploading-list.component.ts | 224 -------- .../components/upload-dialog/upload.module.ts | 47 -- src/app/directives/document-list.directive.ts | 1 + 15 files changed, 295 insertions(+), 845 deletions(-) delete mode 100644 src/app/components/upload-dialog/file-uploading-dialog.component.html delete mode 100644 src/app/components/upload-dialog/file-uploading-dialog.component.ts delete mode 100644 src/app/components/upload-dialog/file-uploading-list-row.component.html delete mode 100644 src/app/components/upload-dialog/file-uploading-list-row.component.scss delete mode 100644 src/app/components/upload-dialog/file-uploading-list-row.component.ts delete mode 100644 src/app/components/upload-dialog/file-uploading-list.component.html delete mode 100644 src/app/components/upload-dialog/file-uploading-list.component.ts delete mode 100644 src/app/components/upload-dialog/upload.module.ts diff --git a/e2e/suites/pagination/pag-file-libraries.test.ts b/e2e/suites/pagination/pag-file-libraries.test.ts index 91edddffcb..2a267e9ab3 100755 --- a/e2e/suites/pagination/pag-file-libraries.test.ts +++ b/e2e/suites/pagination/pag-file-libraries.test.ts @@ -56,7 +56,7 @@ describe('Pagination on multiple pages', () => { done(); }) - describe('on My Libraries', () => { + xdescribe('on My Libraries', () => { beforeEach(async (done) => { await page.goToMyLibrariesAndWait(); done(); @@ -157,7 +157,7 @@ describe('Pagination on multiple pages', () => { }); }); - describe('on Favorite Libraries', () => { + xdescribe('on Favorite Libraries', () => { beforeEach(async (done) => { await page.goToFavoriteLibrariesAndWait(); done(); diff --git a/e2e/suites/viewer/viewer-actions.test.ts b/e2e/suites/viewer/viewer-actions.test.ts index 6228f0ff47..36054d0e8d 100755 --- a/e2e/suites/viewer/viewer-actions.test.ts +++ b/e2e/suites/viewer/viewer-actions.test.ts @@ -246,7 +246,7 @@ describe('Viewer actions', () => { expect(await viewer.isViewerOpened()).toBe(true, 'Viewer is not open'); }); - it('Cancel Editing action - [C297585]', async () => { + xit('Cancel Editing action - [C297585]', async () => { await dataTable.doubleClickOnRowByName(fileForCancelEditing); await viewer.waitForViewerToOpen(); await toolbar.clickMoreActionsCancelEditing(); @@ -501,7 +501,7 @@ describe('Viewer actions', () => { expect(await viewer.isViewerOpened()).toBe(true, 'Viewer is not open'); }); - it('Cancel Editing action - [C297590]', async () => { + xit('Cancel Editing action - [C297590]', async () => { await dataTable.doubleClickOnRowByName(fileForCancelEditing); await viewer.waitForViewerToOpen(); await toolbar.clickMoreActionsCancelEditing(); @@ -734,7 +734,7 @@ describe('Viewer actions', () => { expect(await viewer.isViewerOpened()).toBe(true, 'Viewer is not open'); }); - it('Cancel Editing action - [C297595]', async () => { + xit('Cancel Editing action - [C297595]', async () => { await dataTable.doubleClickOnRowByName(fileForCancelEditing); await viewer.waitForViewerToOpen(); await toolbar.clickMoreActionsCancelEditing(); @@ -966,7 +966,7 @@ describe('Viewer actions', () => { expect(await viewer.isViewerOpened()).toBe(true, 'Viewer is not open'); }); - it('Cancel Editing action - [C297602]', async () => { + xit('Cancel Editing action - [C297602]', async () => { await dataTable.doubleClickOnRowByName(fileForCancelEditing); await viewer.waitForViewerToOpen(); await toolbar.clickMoreActionsCancelEditing(); @@ -1200,7 +1200,7 @@ describe('Viewer actions', () => { expect(await viewer.isViewerOpened()).toBe(true, 'Viewer is not open'); }); - it('Cancel Editing action - [C297605]', async () => { + xit('Cancel Editing action - [C297605]', async () => { await dataTable.doubleClickOnRowByName(fileForCancelEditing); await viewer.waitForViewerToOpen(); await toolbar.clickMoreActionsCancelEditing(); diff --git a/package-lock.json b/package-lock.json index 52a5074cae..269c48f168 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,33 +5,33 @@ "requires": true, "dependencies": { "@alfresco/adf-content-services": { - "version": "3.2.0-beta8", - "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-3.2.0-beta8.tgz", - "integrity": "sha512-K/IY00t2MR84MujVlDPnBLOCq7zklqoDeRa8+dEf6DhHgdfwTOK2aUGObITdlQ1rhTbSSl0llVAUkkHdtgCYmg==", + "version": "3.2.0-2f126fe7fd4bcb111f5aad788e01465d10c1d7d3", + "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-3.2.0-2f126fe7fd4bcb111f5aad788e01465d10c1d7d3.tgz", + "integrity": "sha512-9/iMz5vKwWXHSjfF+RONVlztwmsW6H6rBI1/o5n5l2cShnSYFxLvViMj11F0rNzXLQWhDSC6sjNaJhl0Yuj/wA==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/adf-core": { - "version": "3.2.0-beta8", - "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-3.2.0-beta8.tgz", - "integrity": "sha512-WC1m5HaFCrLbJQBnqrlGeb1UJ3MRHb1F0Ok7HgXmT7FSQwltBO54bJ5Ve2ttQ4xQJnJGMsHpzVncjmmV0LTiiA==", + "version": "3.2.0-2f126fe7fd4bcb111f5aad788e01465d10c1d7d3", + "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-3.2.0-2f126fe7fd4bcb111f5aad788e01465d10c1d7d3.tgz", + "integrity": "sha512-7RSGgP25uT900qvIHJabzwMcA4rJTUDnrmNIzyg3hogZRYUN8kMt5fV3nf8vs2rKUkfHDpO12+EVlAwJ0dXsXQ==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/adf-extensions": { - "version": "3.2.0-beta8", - "resolved": "https://registry.npmjs.org/@alfresco/adf-extensions/-/adf-extensions-3.2.0-beta8.tgz", - "integrity": "sha512-PCv5zPo94O753s+SPLzzlzW9SJ1mRw4CwN8hY8xCTGGIQuSbaHnrTmgUIBHwp0gYVxcbQEULGymNSOz3e0Nslw==", + "version": "3.2.0-2f126fe7fd4bcb111f5aad788e01465d10c1d7d3", + "resolved": "https://registry.npmjs.org/@alfresco/adf-extensions/-/adf-extensions-3.2.0-2f126fe7fd4bcb111f5aad788e01465d10c1d7d3.tgz", + "integrity": "sha512-uGKUotJLyqvizh8yEn28Iuj8hw4xD+UBvYbhUUvqAD/v1vG3LEwrYW0aXvFsBaj+1Sh10PvKp16kg1Z9WNpoJA==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/js-api": { - "version": "3.2.0-beta8", - "resolved": "https://registry.npmjs.org/@alfresco/js-api/-/js-api-3.2.0-beta8.tgz", - "integrity": "sha512-bXxBrP86akor52Fdse3Oj8Z1cS8RZsAlQrldSF3+HvgBhofEigldas7qYvK4RibkFw5tWBJhKVfd1LMfDuaVbg==", + "version": "3.2.0-fa5916ff413131513c3e382d7f27dd9b4cfa0e7e", + "resolved": "https://registry.npmjs.org/@alfresco/js-api/-/js-api-3.2.0-fa5916ff413131513c3e382d7f27dd9b4cfa0e7e.tgz", + "integrity": "sha512-3fhNh0+jqDzO6JavRhhYhGr2RZTLwSFIDF+uY2mcGCLWEiI0t81kyv4cYhO1hOHayfwXd6cn6hB7GZIChKrCZw==", "requires": { "event-emitter": "0.3.4", "superagent": "3.8.2" @@ -59,17 +59,17 @@ } }, "@angular-devkit/build-angular": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-0.13.1.tgz", - "integrity": "sha512-vkKwMVQ+NNCcVR3HFMffS+Mq4b2afXeUjI+02N38hBuFTppnC83uivUB6Uu2NUk5NTSQA4BnJlG5CbMs6N4QYg==", + "version": "0.13.8", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-0.13.8.tgz", + "integrity": "sha512-uRb8CKC0hUdcE+Fv2Ov9LJNelyjsiMuddBpo8pdTKCIHVVC6hvip9S/Z18Tvb207kKI3k7Dn+Ji1J63mCqmQzA==", "dev": true, "requires": { - "@angular-devkit/architect": "0.13.1", - "@angular-devkit/build-optimizer": "0.13.1", - "@angular-devkit/build-webpack": "0.13.1", - "@angular-devkit/core": "7.3.1", - "@ngtools/webpack": "7.3.1", - "ajv": "6.7.0", + "@angular-devkit/architect": "0.13.8", + "@angular-devkit/build-optimizer": "0.13.8", + "@angular-devkit/build-webpack": "0.13.8", + "@angular-devkit/core": "7.3.8", + "@ngtools/webpack": "7.3.8", + "ajv": "6.9.1", "autoprefixer": "9.4.6", "circular-dependency-plugin": "5.0.2", "clean-css": "4.2.1", @@ -85,7 +85,7 @@ "mini-css-extract-plugin": "0.5.0", "minimatch": "3.0.4", "node-sass": "4.11.0", - "opn": "5.4.0", + "open": "6.0.0", "parse5": "4.0.0", "postcss": "7.0.14", "postcss-import": "12.0.1", @@ -96,7 +96,7 @@ "semver": "5.6.0", "source-map-loader": "0.2.4", "source-map-support": "0.5.10", - "speed-measure-webpack-plugin": "1.3.0", + "speed-measure-webpack-plugin": "1.3.1", "stats-webpack-plugin": "0.7.0", "style-loader": "0.23.1", "stylus": "0.54.5", @@ -112,22 +112,22 @@ }, "dependencies": { "@angular-devkit/architect": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.13.1.tgz", - "integrity": "sha512-QDmIbqde75ZZSEFbw6Q6kQWq4cY6C7D67yujXw6XTyubDNAs1tyXJyxTIB8vjSlEKwRizTTDd/B0ZXVcke3Mvw==", + "version": "0.13.8", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.13.8.tgz", + "integrity": "sha512-gxUs5rhnP576T8ZclKqxlspiChrqRtqaJo54wqNVFvYKEjRZKyMa+1AK6p0oD9zcIToEkcjknj3BbtQa27lLHg==", "dev": true, "requires": { - "@angular-devkit/core": "7.3.1", + "@angular-devkit/core": "7.3.8", "rxjs": "6.3.3" } }, "@angular-devkit/core": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.3.1.tgz", - "integrity": "sha512-56XDWWfIzOAkEk69lBLgmCYybPUA4yjunhmMlCk7vVdb7gbQUyzNjFD04Uj0GjlejatAQ5F76tRwygD9C+3RXQ==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.3.8.tgz", + "integrity": "sha512-3X9uzaZXFpm5o2TSzhD6wEOtVU32CgeytKjD1Scxj+uMMVo48SWLlKiFh312T+smI9ko7tOT8VqxglwYkWosgg==", "dev": true, "requires": { - "ajv": "6.7.0", + "ajv": "6.9.1", "chokidar": "2.0.4", "fast-json-stable-stringify": "2.0.0", "rxjs": "6.3.3", @@ -135,9 +135,9 @@ } }, "ajv": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.7.0.tgz", - "integrity": "sha512-RZXPviBTtfmtka9n9sy1N5M5b82CbxWIR6HIis4s3WQTXDJamc/0gpCWNGz6EWdWp4DOfjzJfhz/AS9zVPjjWg==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.9.1.tgz", + "integrity": "sha512-XDN92U311aINL77ieWHmqCcNlwjoP5cHXDxIxbf2MaPYuCXOHS7gHH8jktxeK5omgd52XbSTX6a4Piwd1pQmzA==", "dev": true, "requires": { "fast-deep-equal": "^2.0.1", @@ -187,9 +187,9 @@ } }, "@angular-devkit/build-optimizer": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.13.1.tgz", - "integrity": "sha512-LmvHiI3H451aVWY5Ac6Fqz0i1eX/mUfWN+uJvo8NaL6Jc0HKYX2o3l4ODr8UUECWWctUC9AMD522ZMwAvnvsKQ==", + "version": "0.13.8", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.13.8.tgz", + "integrity": "sha512-RvYxtsdYuvpFb1iivVixylSVN/Q8LsQ449uYuqEe3OsDjQBvUVG2fMLPOQjmKWhi0NC9WSsNiUluxLDNdvd0Vw==", "dev": true, "requires": { "loader-utils": "1.2.3", @@ -203,43 +203,37 @@ "resolved": "http://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=", "dev": true - }, - "typescript": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.2.4.tgz", - "integrity": "sha512-0RNDbSdEokBeEAkgNbxJ+BLwSManFy9TeXz8uW+48j/xhEXv1ePME60olyzw2XzUqUBNAYFeJadIqAgNqIACwg==", - "dev": true } } }, "@angular-devkit/build-webpack": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.13.1.tgz", - "integrity": "sha512-OGwC7bAl3u+w7Glw+OqIrN7OD1BkDXgrWbeQSpKAmsx6VdNPCnI4NPS+JldWNp70LVlE2nQlJUhtEqMVfBMnlg==", + "version": "0.13.8", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.13.8.tgz", + "integrity": "sha512-WMyn1vUHyx+VfJKgYuEHrICwQzPMDTaUNB1zlvzZt9gX/9H+XnetrebeWBZCITPXHBw/377oA6wmiHWJ0yaZRw==", "dev": true, "requires": { - "@angular-devkit/architect": "0.13.1", - "@angular-devkit/core": "7.3.1", + "@angular-devkit/architect": "0.13.8", + "@angular-devkit/core": "7.3.8", "rxjs": "6.3.3" }, "dependencies": { "@angular-devkit/architect": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.13.1.tgz", - "integrity": "sha512-QDmIbqde75ZZSEFbw6Q6kQWq4cY6C7D67yujXw6XTyubDNAs1tyXJyxTIB8vjSlEKwRizTTDd/B0ZXVcke3Mvw==", + "version": "0.13.8", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.13.8.tgz", + "integrity": "sha512-gxUs5rhnP576T8ZclKqxlspiChrqRtqaJo54wqNVFvYKEjRZKyMa+1AK6p0oD9zcIToEkcjknj3BbtQa27lLHg==", "dev": true, "requires": { - "@angular-devkit/core": "7.3.1", + "@angular-devkit/core": "7.3.8", "rxjs": "6.3.3" } }, "@angular-devkit/core": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.3.1.tgz", - "integrity": "sha512-56XDWWfIzOAkEk69lBLgmCYybPUA4yjunhmMlCk7vVdb7gbQUyzNjFD04Uj0GjlejatAQ5F76tRwygD9C+3RXQ==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.3.8.tgz", + "integrity": "sha512-3X9uzaZXFpm5o2TSzhD6wEOtVU32CgeytKjD1Scxj+uMMVo48SWLlKiFh312T+smI9ko7tOT8VqxglwYkWosgg==", "dev": true, "requires": { - "ajv": "6.7.0", + "ajv": "6.9.1", "chokidar": "2.0.4", "fast-json-stable-stringify": "2.0.0", "rxjs": "6.3.3", @@ -247,9 +241,9 @@ } }, "ajv": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.7.0.tgz", - "integrity": "sha512-RZXPviBTtfmtka9n9sy1N5M5b82CbxWIR6HIis4s3WQTXDJamc/0gpCWNGz6EWdWp4DOfjzJfhz/AS9zVPjjWg==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.9.1.tgz", + "integrity": "sha512-XDN92U311aINL77ieWHmqCcNlwjoP5cHXDxIxbf2MaPYuCXOHS7gHH8jktxeK5omgd52XbSTX6a4Piwd1pQmzA==", "dev": true, "requires": { "fast-deep-equal": "^2.0.1", @@ -352,9 +346,9 @@ } }, "@angular/animations": { - "version": "7.2.13", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-7.2.13.tgz", - "integrity": "sha512-Z0g0DthJnxTZ0dUc5BlojMq/0XIikhWzTqq0ym8w3G6jqBJD0OJ0jRCIfV0Leqlgzq6Jzvdrx0/JngBiKi5+uA==", + "version": "7.2.14", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-7.2.14.tgz", + "integrity": "sha512-K+wdq7TslmvDhrbwy65x7owE8wezI0fDdO+8SO9RU4m/w6R6vo4QS3uSdc5I2pxwm4QSXSc5eKhoWJkq0muTbQ==", "requires": { "tslib": "^1.9.0" } @@ -436,25 +430,25 @@ } }, "@angular/common": { - "version": "7.2.13", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-7.2.13.tgz", - "integrity": "sha512-NYlzUkFVgjLg9VB6/lkd8ZV0ZezSiv9vlg+26wOyw7x+gahRrm5WMAGF7eBLrXoZPEaoOO0uhKWKo7oiA0aufA==", + "version": "7.2.14", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-7.2.14.tgz", + "integrity": "sha512-c2QBhVpbQhg1FDhOQkyVdFvU11mfvYHW5ZaXzxdCpq2rZXCureYiCSnlv++EsIAKqi22+2a6GACHF9Gh8kBmSg==", "requires": { "tslib": "^1.9.0" } }, "@angular/compiler": { - "version": "7.2.13", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-7.2.13.tgz", - "integrity": "sha512-k0IvaozNIlrPKUNF3M/NXMb/jfHBCDO9uRYA6h+84FFY4Y9po40c7YXfsfUxGKwouTWyemaxy9iXlLEnd3ELSQ==", + "version": "7.2.14", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-7.2.14.tgz", + "integrity": "sha512-Idhs+5HIzx+1+hrXIDaRpSqobMB7UvSvPlvCvtb3EDYjmltTNG68TtwMzGM8W2jdayliYuFOjFrnw1wCTkK3Ag==", "requires": { "tslib": "^1.9.0" } }, "@angular/compiler-cli": { - "version": "7.2.13", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-7.2.13.tgz", - "integrity": "sha512-UpA6V+GCY9qKj5j6tvzun2DJNjqRKjCrQgJqD5BIf4FTAKjVgqOvh++d23tbdltdjXlbHqUVRgfeXltbO91fWg==", + "version": "7.2.14", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-7.2.14.tgz", + "integrity": "sha512-w5qn1nIPjiCP3WdbqicofpKpiRlh6NMYjWhe6mJysSBnVd34aSuGisYW/gVPQrmD46E1gmfpWTnWPeABVnjj6w==", "dev": true, "requires": { "canonical-path": "1.0.0", @@ -690,9 +684,9 @@ } }, "@angular/core": { - "version": "7.2.13", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-7.2.13.tgz", - "integrity": "sha512-vHD69xxDDSQaE8KfHeY2STJSd3xgfsz3/meBCAnT+Bpq9LqxL8DuPlrkC0kyBa2vyj/BwPR3CJNTaQrZcszJ/w==", + "version": "7.2.14", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-7.2.14.tgz", + "integrity": "sha512-XeZZJCyBKSKo0E/7Ef0SfJejmn+E7uBXa5cR1QapafS0Hnrq/hZu/NI039IDU/51NoycMDH2vTV19SmKu9Mkow==", "requires": { "tslib": "^1.9.0" } @@ -706,25 +700,25 @@ } }, "@angular/forms": { - "version": "7.2.13", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-7.2.13.tgz", - "integrity": "sha512-dBz7kYa8XoCKxZ+3EvYt6CxHZhM9Qbn3uYkLMsPA+NC6GtIt/tmYn1kNn+YWgVWZtWLvYRaOtYiCuMUJaRNQQw==", + "version": "7.2.14", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-7.2.14.tgz", + "integrity": "sha512-jL5YbTk7VZmz4l0++iFVUNa1vGM+nnALjHKi1Ub8VWioRDRboYUsHyxzlgWW9gZRbHpnLEXFiUz1td+v7TouJw==", "requires": { "tslib": "^1.9.0" } }, "@angular/http": { - "version": "7.2.13", - "resolved": "https://registry.npmjs.org/@angular/http/-/http-7.2.13.tgz", - "integrity": "sha512-MlaN7ugCLVH4B7hVasucbcdoSm3UzhP5JgGtcd9d9fQW0hzrn3FXQEZ75NJ/F0YYoGkr5ysAjpeknCjq/elTsg==", + "version": "7.2.14", + "resolved": "https://registry.npmjs.org/@angular/http/-/http-7.2.14.tgz", + "integrity": "sha512-rSdH2JojApDU83qVm7RabIlNo3Ni3yr2gwsmQWs4XZ7SC8jLNnDkzdUbQ6T0vfuVX3v/FtAuMJl0yaVcG3EUJg==", "requires": { "tslib": "^1.9.0" } }, "@angular/language-service": { - "version": "7.2.13", - "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-7.2.13.tgz", - "integrity": "sha512-1bNWJpwH9wB0JybkbjdQp9J4bGmGxJX6BG7Mz3188Wc4J+aNy696Gc6IaJs7tFK8VXAdJrTJ5jGr9Oiu+ATe8w==", + "version": "7.2.14", + "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-7.2.14.tgz", + "integrity": "sha512-YTU4ePAKikbIxNae9Qta8qaDArPgek7nhLEW9QfvrUAnpF7BkVboEI+7yLX5+NTfGf9cQ9cUfQ0TEreV+tMs7A==", "dev": true }, "@angular/material": { @@ -744,25 +738,25 @@ } }, "@angular/platform-browser": { - "version": "7.2.13", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-7.2.13.tgz", - "integrity": "sha512-4n9De4sOwVoYHh6IGO2+UQIjABqGAXk4RdrEGpXqPBHCNO4sF43c2JsXbPTU4kjPVwTwposfLlKEOjTXfwxGow==", + "version": "7.2.14", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-7.2.14.tgz", + "integrity": "sha512-yAq2+3W4J4B48HEmZYQucdEb9AHwRnv72q9CC/SxU7g59vaLhl1nv7cAWGJ4XFaJTbB7aB4Y4rLffuR+Gxkn7A==", "requires": { "tslib": "^1.9.0" } }, "@angular/platform-browser-dynamic": { - "version": "7.2.13", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-7.2.13.tgz", - "integrity": "sha512-3+/BzrNLQ/Tn1hoPal3fvIeB3S/P3e00gHcH3oK+hfACYgWxLE1oIHL+w4NE2eTIJbHfphKhuascMaOH5WNlkg==", + "version": "7.2.14", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-7.2.14.tgz", + "integrity": "sha512-lmTCBiDRbOPtniIqBjm1n5jl1TdyQM0qWQdBcoCsKpMNS/6/RacRcQsJZApAMdWm6gIVuLgmRQzaCLkSoekfYA==", "requires": { "tslib": "^1.9.0" } }, "@angular/router": { - "version": "7.2.13", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-7.2.13.tgz", - "integrity": "sha512-pTdJT9TXk1A9YMa6C2zRRqLB4GPGMSik838P7n+yGrzhdybiudZU9T3egcxDRCWQMjsobVBRKLEUn405n3Hjgg==", + "version": "7.2.14", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-7.2.14.tgz", + "integrity": "sha512-uqg0SKy79voEOIOvzVbCzFDD9XOAfZWkYt01ca2qLFXMx+6jWeVQIDuXc8Dmz5udIXNK5Ae//9R+nt5UZUZrSA==", "requires": { "tslib": "^1.9.0" } @@ -999,12 +993,12 @@ "dev": true }, "@ngtools/webpack": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-7.3.1.tgz", - "integrity": "sha512-EGQRjgDf5XP+Fm1MdZNRFiPd9e1vhl11BhjkwqkAsewic4eoz6fqXfj/Osz1hQy8xU+2dPPf/byQ/+nY3E02Zg==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-7.3.8.tgz", + "integrity": "sha512-gfjSKz+F/2T4tZHpnQ1XqelKP/CIfI87XdoHsOI53ceTUrAkVKsOb3ULmEfkcdsdQZ/HhmCiLivcutHcW8xkhQ==", "dev": true, "requires": { - "@angular-devkit/core": "7.3.1", + "@angular-devkit/core": "7.3.8", "enhanced-resolve": "4.1.0", "rxjs": "6.3.3", "tree-kill": "1.2.1", @@ -1012,12 +1006,12 @@ }, "dependencies": { "@angular-devkit/core": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.3.1.tgz", - "integrity": "sha512-56XDWWfIzOAkEk69lBLgmCYybPUA4yjunhmMlCk7vVdb7gbQUyzNjFD04Uj0GjlejatAQ5F76tRwygD9C+3RXQ==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.3.8.tgz", + "integrity": "sha512-3X9uzaZXFpm5o2TSzhD6wEOtVU32CgeytKjD1Scxj+uMMVo48SWLlKiFh312T+smI9ko7tOT8VqxglwYkWosgg==", "dev": true, "requires": { - "ajv": "6.7.0", + "ajv": "6.9.1", "chokidar": "2.0.4", "fast-json-stable-stringify": "2.0.0", "rxjs": "6.3.3", @@ -1025,9 +1019,9 @@ } }, "ajv": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.7.0.tgz", - "integrity": "sha512-RZXPviBTtfmtka9n9sy1N5M5b82CbxWIR6HIis4s3WQTXDJamc/0gpCWNGz6EWdWp4DOfjzJfhz/AS9zVPjjWg==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.9.1.tgz", + "integrity": "sha512-XDN92U311aINL77ieWHmqCcNlwjoP5cHXDxIxbf2MaPYuCXOHS7gHH8jktxeK5omgd52XbSTX6a4Piwd1pQmzA==", "dev": true, "requires": { "fast-deep-equal": "^2.0.1", @@ -1453,9 +1447,9 @@ } }, "acorn": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.0.tgz", - "integrity": "sha512-MW/FjM+IvU9CgBzjO3UIPCE2pyEwUsoFl+VGdczOPEdxfGFjuKny/gN54mOuX7Qxmb9Rg9MCn2oKiSUeW+pjrw==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", + "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==", "dev": true }, "acorn-dynamic-import": { @@ -1565,9 +1559,9 @@ } }, "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", + "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", "dev": true }, "ansi-escapes": { @@ -2931,25 +2925,33 @@ "dev": true }, "compressible": { - "version": "2.0.15", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.15.tgz", - "integrity": "sha512-4aE67DL33dSW9gw4CI2H/yTxqHLNcxp0yS6jB+4h+wr3e43+1z7vm0HU9qXOH8j+qjKuL8+UtkOxYQSMq60Ylw==", + "version": "2.0.17", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.17.tgz", + "integrity": "sha512-BGHeLCK1GV7j1bSmQQAi26X+GgWcTjLr/0tzSvMCl3LH1w1IJ4PFSPoV5316b30cneTziC+B1a+3OjoSUcQYmw==", "dev": true, "requires": { - "mime-db": ">= 1.36.0 < 2" + "mime-db": ">= 1.40.0 < 2" + }, + "dependencies": { + "mime-db": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==", + "dev": true + } } }, "compression": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.3.tgz", - "integrity": "sha512-HSjyBG5N1Nnz7tF2+O7A9XUhyjru71/fwgNb7oIsEVHR0WShfs2tIS/EySLgiTe98aOK18YDlMXpzjCXY/n9mg==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", "dev": true, "requires": { "accepts": "~1.3.5", "bytes": "3.0.0", - "compressible": "~2.0.14", + "compressible": "~2.0.16", "debug": "2.6.9", - "on-headers": "~1.0.1", + "on-headers": "~1.0.2", "safe-buffer": "5.1.2", "vary": "~1.1.2" }, @@ -4108,9 +4110,9 @@ } }, "es5-ext": { - "version": "0.10.49", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.49.tgz", - "integrity": "sha512-3NMEhi57E31qdzmYp2jwRArIUsj1HI/RxbQ4bgnSB+AIKIxsAmTiK83bYMifIcpWvEc3P1X30DhUKOqEtF/kvg==", + "version": "0.10.50", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.50.tgz", + "integrity": "sha512-KMzZTPBkeQV/JcSQhI5/z6d9VWJ3EnQ194USTUwIYZ2ZbpN8+SGXQKt1h68EX44+qt+Fzr8DO17vnxrw7c3agw==", "requires": { "es6-iterator": "~2.0.3", "es6-symbol": "~3.1.1", @@ -4184,9 +4186,9 @@ "dev": true }, "eslint-scope": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.0.tgz", - "integrity": "sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", "dev": true, "requires": { "esrecurse": "^4.1.0", @@ -4959,7 +4961,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -4980,12 +4983,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": 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" @@ -5000,17 +5005,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -5127,7 +5135,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -5139,6 +5148,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -5153,6 +5163,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -5160,12 +5171,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -5184,6 +5197,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -5264,7 +5278,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -5276,6 +5291,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -5361,7 +5377,8 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -5397,6 +5414,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -5416,6 +5434,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -5459,12 +5478,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, @@ -6015,9 +6036,9 @@ } }, "ieee754": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz", - "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", "dev": true }, "iferr": { @@ -6118,9 +6139,9 @@ } }, "p-limit": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz", - "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", + "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", "dev": true, "requires": { "p-try": "^2.0.0" @@ -6136,9 +6157,9 @@ } }, "p-try": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", - "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, "pkg-dir": { @@ -6323,9 +6344,9 @@ "dev": true }, "ipaddr.js": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz", - "integrity": "sha1-6qM9bd16zo9/b+DJygRA5wZzix4=", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", + "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==", "dev": true }, "is-accessor-descriptor": { @@ -7951,14 +7972,22 @@ "dev": true }, "mem": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-4.1.0.tgz", - "integrity": "sha512-I5u6Q1x7wxO0kdOpYBB28xueHADYps5uty/zg936CiG8NTe5sJL8EjrCuLneuDW3PlMdZBGDIn8BirEVdovZvg==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", + "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", "dev": true, "requires": { "map-age-cleaner": "^0.1.1", - "mimic-fn": "^1.0.0", + "mimic-fn": "^2.0.0", "p-is-promise": "^2.0.0" + }, + "dependencies": { + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + } } }, "memory-fs": { @@ -8875,9 +8904,9 @@ } }, "on-headers": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz", - "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", "dev": true }, "once": { @@ -9036,9 +9065,9 @@ } }, "opn": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-5.4.0.tgz", - "integrity": "sha512-YF9MNdVy/0qvJvDtunAOzFw9iasOQHpVthTCvGzxt61Il64AYSGdK+rYwld7NAfk9qJ7dt+hymBNSc9LNYS+Sw==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", + "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", "dev": true, "requires": { "is-wsl": "^1.1.0" @@ -9133,9 +9162,9 @@ "dev": true }, "p-is-promise": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.0.0.tgz", - "integrity": "sha512-pzQPhYMCAgLAKPWD2jC3Se9fEfrD9npNos0y150EeqZll7akhEgGhTW/slB6lHku8AvYGiJ+YJ5hfHKePPgFWg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", + "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", "dev": true }, "p-limit": { @@ -9946,13 +9975,13 @@ } }, "proxy-addr": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz", - "integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", + "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", "dev": true, "requires": { "forwarded": "~0.1.2", - "ipaddr.js": "1.8.0" + "ipaddr.js": "1.9.0" } }, "prr": { @@ -10043,9 +10072,9 @@ "dev": true }, "querystringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.0.tgz", - "integrity": "sha512-sluvZZ1YiTLD5jsqZcDmFyV2EwToyXZBfpoVOmktMmW+VEnhgakFHnasVph65fOjGPTWN0Nw3+XQaSeMayr0kg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", + "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", "dev": true }, "randomatic": { @@ -10068,9 +10097,9 @@ } }, "randombytes": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", - "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, "requires": { "safe-buffer": "^5.1.0" @@ -10718,9 +10747,9 @@ "dev": true }, "rxjs": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz", - "integrity": "sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw==", + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.1.tgz", + "integrity": "sha512-y0j31WJc83wPu31vS1VlAFW5JGrnGC+j+TtGAa1fRQphy48+fDYiDmX8tjGloToEsMkxnouOg/1IzXGKkJnZMg==", "requires": { "tslib": "^1.9.0" } @@ -10993,9 +11022,9 @@ } }, "serialize-javascript": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.6.1.tgz", - "integrity": "sha512-A5MOagrPFga4YaKQSWHryl7AXvbQkEqpw4NNYMTNYUNV51bA8ABHgYFpqKx+YFFrw59xMV1qGH1R4AgoNIVgCw==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.7.0.tgz", + "integrity": "sha512-ke8UG8ulpFOxO8f8gRYabHQe/ZntKlcig2Mp+8+URDP1D8vJZ0KUt7LYo07q25Z/+JVSgpr/cui9PIp5H6/+nA==", "dev": true }, "serve-index": { @@ -11630,9 +11659,9 @@ } }, "readable-stream": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.1.1.tgz", - "integrity": "sha512-DkN66hPyqDhnIQ6Jcsvx9bFjhw214O4poMBcIMgPVpQvNy9a0e0Uhg5SqySyDKAmUlwt8LonTBz1ezOnM8pUdA==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.3.0.tgz", + "integrity": "sha512-EsI+s3k3XsW+fU8fQACLN59ky34AZ14LoeVZpYwmZvldCFo0r0gnelwF2TcMjLor/BTL5aDJVBMkss0dthToPw==", "dev": true, "requires": { "inherits": "^2.0.3", @@ -11643,9 +11672,9 @@ } }, "speed-measure-webpack-plugin": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/speed-measure-webpack-plugin/-/speed-measure-webpack-plugin-1.3.0.tgz", - "integrity": "sha512-b9Yd0TrzceMVYSbuamM1sFsGM1oVfyFTM22gOoyLhymNvBVApuYpkdFOgYkKJpN/KhTpcCYcTGHg7X+FJ33Vvw==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/speed-measure-webpack-plugin/-/speed-measure-webpack-plugin-1.3.1.tgz", + "integrity": "sha512-qVIkJvbtS9j/UeZumbdfz0vg+QfG/zxonAjzefZrqzkr7xOncLVXkeGbTpzd1gjCBM4PmVNkWlkeTVhgskAGSQ==", "dev": true, "requires": { "chalk": "^2.0.1" @@ -11982,9 +12011,9 @@ "dev": true }, "tapable": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.1.tgz", - "integrity": "sha512-9I2ydhj8Z9veORCw5PRm4u9uebCn0mcCa6scWoNcbZ6dAtoo2618u9UUzxgmsCOreJpqDDuv61LvwofW7hLcBA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", "dev": true }, "tar": { @@ -12036,16 +12065,22 @@ } }, "terser": { - "version": "3.16.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-3.16.1.tgz", - "integrity": "sha512-JDJjgleBROeek2iBcSNzOHLKsB/MdDf+E/BOAJ0Tk9r7p9/fVobfv7LMJ/g/k3v9SXdmjZnIlFd5nfn/Rt0Xow==", + "version": "3.17.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-3.17.0.tgz", + "integrity": "sha512-/FQzzPJmCpjAH9Xvk2paiWrFq+5M6aVOf+2KRbwhByISDX/EujxsK+BAvrhb6H+2rtrLCHK9N01wO014vrIwVQ==", "dev": true, "requires": { - "commander": "~2.17.1", + "commander": "^2.19.0", "source-map": "~0.6.1", - "source-map-support": "~0.5.9" + "source-map-support": "~0.5.10" }, "dependencies": { + "commander": { + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", + "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", + "dev": true + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -12093,13 +12128,13 @@ } }, "find-cache-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.0.0.tgz", - "integrity": "sha512-LDUY6V1Xs5eFskUVYtIwatojt6+9xC9Chnlk/jYOOvn3FAFfSaWddxahDGyNHh0b2dMXa6YW2m0tk8TdVaXHlA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", "dev": true, "requires": { "commondir": "^1.0.1", - "make-dir": "^1.0.0", + "make-dir": "^2.0.0", "pkg-dir": "^3.0.0" } }, @@ -12131,6 +12166,16 @@ "yallist": "^3.0.2" } }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, "mississippi": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", @@ -12150,9 +12195,9 @@ } }, "p-limit": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz", - "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", + "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", "dev": true, "requires": { "p-try": "^2.0.0" @@ -12168,9 +12213,15 @@ } }, "p-try": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", - "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true }, "pkg-dir": { @@ -12744,12 +12795,12 @@ } }, "url-parse": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.4.tgz", - "integrity": "sha512-/92DTTorg4JjktLNLe6GPS2/RvAd/RGr6LuktmWSMLEOa6rjnlrFXNgSbSmkNvCoL2T028A0a1JaJLzRMlFoHg==", + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", + "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", "dev": true, "requires": { - "querystringify": "^2.0.0", + "querystringify": "^2.1.1", "requires-port": "^1.0.0" } }, @@ -12999,9 +13050,9 @@ }, "dependencies": { "mime": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.0.tgz", - "integrity": "sha512-ikBcWwyqXQSHKtciCcctu9YfPbFYZ4+gbHEmE0Q8jzcTYQg5dHCr3g2wwAZjPoJfQVXZq6KXAjpXOTf5/cjT7w==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.2.tgz", + "integrity": "sha512-zJBfZDkwRu+j3Pdd2aHsR5GfH2jIWhmL1ZzBoc+X+3JEti2hbArWcyJ+1laC1D2/U/W1a/+Cegj0/OnEU2ybjg==", "dev": true } } @@ -13165,9 +13216,9 @@ } }, "mime": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.0.tgz", - "integrity": "sha512-ikBcWwyqXQSHKtciCcctu9YfPbFYZ4+gbHEmE0Q8jzcTYQg5dHCr3g2wwAZjPoJfQVXZq6KXAjpXOTf5/cjT7w==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.2.tgz", + "integrity": "sha512-zJBfZDkwRu+j3Pdd2aHsR5GfH2jIWhmL1ZzBoc+X+3JEti2hbArWcyJ+1laC1D2/U/W1a/+Cegj0/OnEU2ybjg==", "dev": true }, "os-locale": { @@ -13182,9 +13233,9 @@ } }, "p-limit": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz", - "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", + "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", "dev": true, "requires": { "p-try": "^2.0.0" @@ -13200,9 +13251,9 @@ } }, "p-try": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", - "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, "pump": { diff --git a/package.json b/package.json index 48264d579f..55fa794063 100644 --- a/package.json +++ b/package.json @@ -37,23 +37,23 @@ }, "private": true, "dependencies": { - "@alfresco/adf-content-services": "3.2.0-beta8", - "@alfresco/adf-core": "3.2.0-beta8", - "@alfresco/adf-extensions": "3.2.0-beta8", - "@alfresco/js-api": "3.2.0-beta8", - "@angular/animations": "7.2.13", + "@alfresco/adf-content-services": "3.2.0-2f126fe7fd4bcb111f5aad788e01465d10c1d7d3", + "@alfresco/adf-core": "3.2.0-2f126fe7fd4bcb111f5aad788e01465d10c1d7d3", + "@alfresco/adf-extensions": "3.2.0-2f126fe7fd4bcb111f5aad788e01465d10c1d7d3", + "@alfresco/js-api": "3.2.0-fa5916ff413131513c3e382d7f27dd9b4cfa0e7e", + "@angular/animations": "7.2.14", "@angular/cdk": "^7.3.7", - "@angular/common": "7.2.13", - "@angular/compiler": "7.2.13", - "@angular/core": "7.2.13", + "@angular/common": "7.2.14", + "@angular/compiler": "7.2.14", + "@angular/core": "7.2.14", "@angular/flex-layout": "^7.0.0-beta.24", - "@angular/forms": "7.2.13", - "@angular/http": "7.2.13", + "@angular/forms": "7.2.14", + "@angular/http": "7.2.14", "@angular/material": "^7.3.7", "@angular/material-moment-adapter": "^7.3.7", - "@angular/platform-browser": "7.2.13", - "@angular/platform-browser-dynamic": "7.2.13", - "@angular/router": "7.2.13", + "@angular/platform-browser": "7.2.14", + "@angular/platform-browser-dynamic": "7.2.14", + "@angular/router": "7.2.14", "@mat-datetimepicker/core": "^3.0.0-beta.0", "@mat-datetimepicker/moment": "^3.0.0-beta.0", "@ngrx/effects": "^7.4.0", @@ -67,15 +67,15 @@ "moment": "^2.24.0", "moment-es6": "1.0.0", "pdfjs-dist": "^2.0.489", - "rxjs": "^6.4.0", + "rxjs": "^6.5.1", "zone.js": "0.8.29" }, "devDependencies": { - "@angular-devkit/build-angular": "~0.13.0", + "@angular-devkit/build-angular": "~0.13.8", "@angular-devkit/build-ng-packagr": "~0.13.0", "@angular/cli": "^7.3.8", - "@angular/compiler-cli": "7.2.13", - "@angular/language-service": "7.2.13", + "@angular/compiler-cli": "7.2.14", + "@angular/language-service": "7.2.14", "@types/jasmine": "^2.5.53", "@types/jasminewd2": "^2.0.2", "@types/node": "9.3.0", diff --git a/src/app/components/layout/app-layout/app-layout.component.html b/src/app/components/layout/app-layout/app-layout.component.html index 056d5b5820..b114dc453a 100644 --- a/src/app/components/layout/app-layout/app-layout.component.html +++ b/src/app/components/layout/app-layout/app-layout.component.html @@ -11,6 +11,8 @@ @@ -38,7 +40,7 @@ - + diff --git a/src/app/components/layout/layout.module.ts b/src/app/components/layout/layout.module.ts index 5464a73b1d..b543026b9f 100644 --- a/src/app/components/layout/layout.module.ts +++ b/src/app/components/layout/layout.module.ts @@ -30,7 +30,6 @@ import { AppLayoutComponent } from './app-layout/app-layout.component'; import { ContentModule } from '@alfresco/adf-content-services'; import { RouterModule } from '@angular/router'; import { AppSidenavModule } from '../sidenav/sidenav.module'; -import { AppUploadingDialogModule } from '../upload-dialog/upload.module'; import { AppCommonModule } from '../common/common.module'; import { AppHeaderModule } from '../header/header.module'; import { HttpClientModule } from '@angular/common/http'; @@ -46,7 +45,6 @@ import { PageLayoutModule } from '@alfresco/aca-shared'; AppSidenavModule, AppHeaderModule, HttpClientModule, - AppUploadingDialogModule, PageLayoutModule ], declarations: [AppLayoutComponent], diff --git a/src/app/components/upload-dialog/file-uploading-dialog.component.html b/src/app/components/upload-dialog/file-uploading-dialog.component.html deleted file mode 100644 index 266df0a80e..0000000000 --- a/src/app/components/upload-dialog/file-uploading-dialog.component.html +++ /dev/null @@ -1,133 +0,0 @@ -
-
- - - - {{ - 'FILE_UPLOAD.MESSAGES.UPLOAD_PROGRESS' - | translate - : { - completed: totalCompleted, - total: filesUploadingList.length - } - }} - - - - {{ 'FILE_UPLOAD.MESSAGES.UPLOAD_CANCELED' | translate }} - -
- -
- {{ - (totalErrors > 1 - ? 'FILE_UPLOAD.MESSAGES.UPLOAD_ERRORS' - : 'FILE_UPLOAD.MESSAGES.UPLOAD_ERROR') - | translate: { total: totalErrors } - }} -
- -
- - - - - - - -
-

- {{ 'ADF_FILE_UPLOAD.CONFIRMATION.MESSAGE.TITLE' | translate }} -

- -

- {{ 'ADF_FILE_UPLOAD.CONFIRMATION.MESSAGE.TEXT' | translate }} -

-
-
- -
- - - -
- -
- - - -
-
diff --git a/src/app/components/upload-dialog/file-uploading-dialog.component.ts b/src/app/components/upload-dialog/file-uploading-dialog.component.ts deleted file mode 100644 index 849953cefb..0000000000 --- a/src/app/components/upload-dialog/file-uploading-dialog.component.ts +++ /dev/null @@ -1,24 +0,0 @@ -/*! - * @license - * Copyright 2019 Alfresco Software, Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Component } from '@angular/core'; -import { FileUploadingDialogComponent } from '@alfresco/adf-content-services'; -@Component({ - selector: 'app-file-uploading-dialog', - templateUrl: './file-uploading-dialog.component.html' -}) -export class AppFileUploadingDialogComponent extends FileUploadingDialogComponent {} diff --git a/src/app/components/upload-dialog/file-uploading-list-row.component.html b/src/app/components/upload-dialog/file-uploading-list-row.component.html deleted file mode 100644 index 315f70bfde..0000000000 --- a/src/app/components/upload-dialog/file-uploading-list-row.component.html +++ /dev/null @@ -1,109 +0,0 @@ -
- - - insert_drive_file - - - - - - - {{ file.name }} - - - - {{ - versionNumber - }} - - -
- - {{ file.progress.loaded | adfFileSize }} / - {{ file.progress.total | adfFileSize }} - - - - clear - -
- -
- - check_circle - - - - remove_circle - -
- -
- - schedule - - - - remove_circle - -
- -
- - report_problem - -
- -
- {{ 'ADF_FILE_UPLOAD.STATUS.FILE_CANCELED_STATUS' | translate }} -
-
diff --git a/src/app/components/upload-dialog/file-uploading-list-row.component.scss b/src/app/components/upload-dialog/file-uploading-list-row.component.scss deleted file mode 100644 index ee1a302c5f..0000000000 --- a/src/app/components/upload-dialog/file-uploading-list-row.component.scss +++ /dev/null @@ -1,11 +0,0 @@ -.adf-file-uploading-row__version { - flex: 0; - - .mat-chip { - padding: 2px 6px; - } - - .mat-chip.mat-chip-disabled { - opacity: 1; - } -} diff --git a/src/app/components/upload-dialog/file-uploading-list-row.component.ts b/src/app/components/upload-dialog/file-uploading-list-row.component.ts deleted file mode 100644 index be1a1f3b70..0000000000 --- a/src/app/components/upload-dialog/file-uploading-list-row.component.ts +++ /dev/null @@ -1,50 +0,0 @@ -/*! - * @license - * Copyright 2019 Alfresco Software, Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Component, ViewEncapsulation } from '@angular/core'; -import { FileUploadingListRowComponent } from '@alfresco/adf-content-services'; -@Component({ - selector: 'app-file-uploading-list-row', - templateUrl: './file-uploading-list-row.component.html', - styleUrls: ['./file-uploading-list-row.component.scss'], - encapsulation: ViewEncapsulation.None -}) -export class AppFileUploadingListRowComponent extends FileUploadingListRowComponent { - isUploadVersion() { - return ( - !!this.file.data && - this.file.options && - this.file.options.newVersion && - this.file.data.entry.properties && - this.file.data.entry.properties['cm:versionLabel'] - ); - } - - // todo: move to ADF 3.x.x - get versionNumber() { - return this.file.data.entry.properties['cm:versionLabel']; - } - - // todo: move to ADF 3.x.x - get mimeType(): string { - if (this.file && this.file.file && this.file.file.type) { - return this.file.file.type; - } - - return 'default'; - } -} diff --git a/src/app/components/upload-dialog/file-uploading-list.component.html b/src/app/components/upload-dialog/file-uploading-list.component.html deleted file mode 100644 index 475b084b12..0000000000 --- a/src/app/components/upload-dialog/file-uploading-list.component.html +++ /dev/null @@ -1,4 +0,0 @@ -
- - -
diff --git a/src/app/components/upload-dialog/file-uploading-list.component.ts b/src/app/components/upload-dialog/file-uploading-list.component.ts deleted file mode 100644 index 4ede362538..0000000000 --- a/src/app/components/upload-dialog/file-uploading-list.component.ts +++ /dev/null @@ -1,224 +0,0 @@ -/*! - * @license - * Copyright 2019 Alfresco Software, Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { - FileModel, - FileUploadStatus, - NodesApiService, - AlfrescoApiService, - TranslationService, - UploadService -} from '@alfresco/adf-core'; -import { - Component, - ContentChild, - Input, - Output, - TemplateRef, - EventEmitter -} from '@angular/core'; -import { Observable, forkJoin, of, from } from 'rxjs'; -import { map, catchError } from 'rxjs/operators'; - -@Component({ - selector: 'app-file-uploading-list', - templateUrl: './file-uploading-list.component.html' -}) -export class AppFileUploadingListComponent { - FileUploadStatus = FileUploadStatus; - - @ContentChild(TemplateRef) - template: any; - - @Input() - files: FileModel[] = []; - - /** Emitted when a file in the list has an error. */ - @Output() - error: EventEmitter = new EventEmitter(); - - constructor( - private alfrescoApiService: AlfrescoApiService, - private uploadService: UploadService, - private nodesApi: NodesApiService, - private translateService: TranslationService - ) {} - - /** - * Cancel file upload - * - * @param file File model to cancel upload for. - * - * @memberOf FileUploadingListComponent - */ - cancelFile(file: FileModel): void { - this.uploadService.cancelUpload(file); - } - - // todo: move to ADF 3.x.x - removeFile(file: FileModel): void { - if (file.options && file.options.newVersion) { - this.deleteNodeVersion(file).subscribe(() => { - if (file.status === FileUploadStatus.Error) { - this.notifyError(file); - } - this.uploadService.cancelUpload(file); - }); - } else { - this.deleteNode(file).subscribe(() => { - if (file.status === FileUploadStatus.Error) { - this.notifyError(file); - } - - this.cancelNodeVersionInstances(file); - this.uploadService.cancelUpload(file); - }); - } - } - - /** - * Call the appropriate method for each file, depending on state - */ - cancelAllFiles(): void { - this.getUploadingFiles().forEach(file => - this.uploadService.cancelUpload(file) - ); - - const deletedFiles = this.files - .filter(file => file.status === FileUploadStatus.Complete) - .map(file => this.deleteNode(file)); - - forkJoin(...deletedFiles).subscribe((files: FileModel[]) => { - const errors = files.filter( - file => file.status === FileUploadStatus.Error - ); - - if (errors.length) { - this.notifyError(...errors); - } - - this.uploadService.cancelUpload(...files); - }); - } - - /** - * Checks if all the files are uploaded false if there is at least one file in Progress | Starting | Pending - */ - isUploadCompleted(): boolean { - return ( - !this.isUploadCancelled() && - Boolean(this.files.length) && - !this.files.some( - ({ status }) => - status === FileUploadStatus.Starting || - status === FileUploadStatus.Progress || - status === FileUploadStatus.Pending - ) - ); - } - - /** - * Check if all the files are Cancelled | Aborted | Error. false if there is at least one file in uploading states - */ - isUploadCancelled(): boolean { - return ( - !!this.files.length && - this.files.every( - ({ status }) => - status === FileUploadStatus.Aborted || - status === FileUploadStatus.Cancelled || - status === FileUploadStatus.Deleted - ) - ); - } - - // todo: move to ADF 3.x.x - private deleteNodeVersion(file: FileModel): Observable { - return from( - this.alfrescoApiService.versionsApi.deleteVersion( - file.data.entry.id, - file.data.entry.properties['cm:versionLabel'] - ) - ).pipe( - map(() => { - file.status = FileUploadStatus.Deleted; - return file; - }), - catchError(() => { - file.status = FileUploadStatus.Error; - return of(file); - }) - ); - } - - // todo: move to ADF 3.x.x - private cancelNodeVersionInstances(file) { - this.files - .filter( - item => - item.data.entry.id === file.data.entry.id && item.options.newVersion - ) - .map(item => { - item.status = FileUploadStatus.Deleted; - }); - } - - private deleteNode(file: FileModel): Observable { - const { id } = file.data.entry; - - return this.nodesApi.deleteNode(id, { permanent: true }).pipe( - map(() => { - file.status = FileUploadStatus.Deleted; - return file; - }), - catchError(() => { - file.status = FileUploadStatus.Error; - return of(file); - }) - ); - } - - private notifyError(...files: FileModel[]) { - let messageError: string = null; - - if (files.length === 1) { - messageError = this.translateService.instant( - 'FILE_UPLOAD.MESSAGES.REMOVE_FILE_ERROR', - { fileName: files[0].name } - ); - } else { - messageError = this.translateService.instant( - 'FILE_UPLOAD.MESSAGES.REMOVE_FILES_ERROR', - { total: files.length } - ); - } - - this.error.emit(messageError); - } - - private getUploadingFiles() { - return this.files.filter(item => { - if ( - item.status === FileUploadStatus.Pending || - item.status === FileUploadStatus.Progress || - item.status === FileUploadStatus.Starting - ) { - return item; - } - }); - } -} diff --git a/src/app/components/upload-dialog/upload.module.ts b/src/app/components/upload-dialog/upload.module.ts deleted file mode 100644 index c17e26bc0e..0000000000 --- a/src/app/components/upload-dialog/upload.module.ts +++ /dev/null @@ -1,47 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2019 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { CoreModule } from '@alfresco/adf-core'; -import { AppFileUploadingDialogComponent } from './file-uploading-dialog.component'; -import { AppFileUploadingListRowComponent } from './file-uploading-list-row.component'; -import { AppFileUploadingListComponent } from './file-uploading-list.component'; -import { UploadModule } from '@alfresco/adf-content-services'; - -@NgModule({ - imports: [CommonModule, CoreModule.forChild(), UploadModule], - declarations: [ - AppFileUploadingDialogComponent, - AppFileUploadingListRowComponent, - AppFileUploadingListComponent - ], - exports: [ - AppFileUploadingDialogComponent, - AppFileUploadingListRowComponent, - AppFileUploadingListComponent - ] -}) -export class AppUploadingDialogModule {} diff --git a/src/app/directives/document-list.directive.ts b/src/app/directives/document-list.directive.ts index 4468561ce4..736fd27801 100644 --- a/src/app/directives/document-list.directive.ts +++ b/src/app/directives/document-list.directive.ts @@ -55,6 +55,7 @@ export class DocumentListDirective implements OnInit, OnDestroy { ) {} ngOnInit() { + this.documentList.stickyHeader = true; this.documentList.includeFields = ['isFavorite', 'aspectNames']; this.isLibrary = this.documentList.currentFolderId === '-mysites-' || From f74a1f5606f9b5b6c8cba151df1d711b3ffec79f Mon Sep 17 00:00:00 2001 From: Suzana Dirla Date: Fri, 3 May 2019 17:56:28 +0300 Subject: [PATCH 191/259] [ACA-1623] remove mincount set to 0 (#1094) - use the default value of 1 --- src/app.config.json | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/app.config.json b/src/app.config.json index d745b130b4..3585a5b474 100644 --- a/src/app.config.json +++ b/src/app.config.json @@ -234,22 +234,18 @@ "fields": [ { "field": "content.mimetype", - "mincount": 0, "label": "SEARCH.FACET_FIELDS.FILE_TYPE" }, { "field": "creator", - "mincount": 0, "label": "SEARCH.FACET_FIELDS.CREATOR" }, { "field": "modifier", - "mincount": 0, "label": "SEARCH.FACET_FIELDS.MODIFIER" }, { "field": "SITE", - "mincount": 0, "label": "SEARCH.FACET_FIELDS.LOCATION" } ] @@ -257,7 +253,6 @@ "facetQueries": { "label": "SEARCH.CATEGORIES.MODIFIED_DATE", "expanded": true, - "mincount": 0, "queries": [ { "label": "SEARCH.FACET_QUERIES.TODAY", "query": "cm:modified:[TODAY to TODAY]" }, { From ad1c8c58e615b287823a90ea3018f242249b0629 Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Fri, 3 May 2019 18:00:02 +0300 Subject: [PATCH 192/259] enable tests (#1093) --- e2e/suites/pagination/pag-file-libraries.test.ts | 4 ++-- e2e/suites/viewer/viewer-actions.test.ts | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/e2e/suites/pagination/pag-file-libraries.test.ts b/e2e/suites/pagination/pag-file-libraries.test.ts index 2a267e9ab3..91edddffcb 100755 --- a/e2e/suites/pagination/pag-file-libraries.test.ts +++ b/e2e/suites/pagination/pag-file-libraries.test.ts @@ -56,7 +56,7 @@ describe('Pagination on multiple pages', () => { done(); }) - xdescribe('on My Libraries', () => { + describe('on My Libraries', () => { beforeEach(async (done) => { await page.goToMyLibrariesAndWait(); done(); @@ -157,7 +157,7 @@ describe('Pagination on multiple pages', () => { }); }); - xdescribe('on Favorite Libraries', () => { + describe('on Favorite Libraries', () => { beforeEach(async (done) => { await page.goToFavoriteLibrariesAndWait(); done(); diff --git a/e2e/suites/viewer/viewer-actions.test.ts b/e2e/suites/viewer/viewer-actions.test.ts index 36054d0e8d..6228f0ff47 100755 --- a/e2e/suites/viewer/viewer-actions.test.ts +++ b/e2e/suites/viewer/viewer-actions.test.ts @@ -246,7 +246,7 @@ describe('Viewer actions', () => { expect(await viewer.isViewerOpened()).toBe(true, 'Viewer is not open'); }); - xit('Cancel Editing action - [C297585]', async () => { + it('Cancel Editing action - [C297585]', async () => { await dataTable.doubleClickOnRowByName(fileForCancelEditing); await viewer.waitForViewerToOpen(); await toolbar.clickMoreActionsCancelEditing(); @@ -501,7 +501,7 @@ describe('Viewer actions', () => { expect(await viewer.isViewerOpened()).toBe(true, 'Viewer is not open'); }); - xit('Cancel Editing action - [C297590]', async () => { + it('Cancel Editing action - [C297590]', async () => { await dataTable.doubleClickOnRowByName(fileForCancelEditing); await viewer.waitForViewerToOpen(); await toolbar.clickMoreActionsCancelEditing(); @@ -734,7 +734,7 @@ describe('Viewer actions', () => { expect(await viewer.isViewerOpened()).toBe(true, 'Viewer is not open'); }); - xit('Cancel Editing action - [C297595]', async () => { + it('Cancel Editing action - [C297595]', async () => { await dataTable.doubleClickOnRowByName(fileForCancelEditing); await viewer.waitForViewerToOpen(); await toolbar.clickMoreActionsCancelEditing(); @@ -966,7 +966,7 @@ describe('Viewer actions', () => { expect(await viewer.isViewerOpened()).toBe(true, 'Viewer is not open'); }); - xit('Cancel Editing action - [C297602]', async () => { + it('Cancel Editing action - [C297602]', async () => { await dataTable.doubleClickOnRowByName(fileForCancelEditing); await viewer.waitForViewerToOpen(); await toolbar.clickMoreActionsCancelEditing(); @@ -1200,7 +1200,7 @@ describe('Viewer actions', () => { expect(await viewer.isViewerOpened()).toBe(true, 'Viewer is not open'); }); - xit('Cancel Editing action - [C297605]', async () => { + it('Cancel Editing action - [C297605]', async () => { await dataTable.doubleClickOnRowByName(fileForCancelEditing); await viewer.waitForViewerToOpen(); await toolbar.clickMoreActionsCancelEditing(); From dbc2c6c8e4bc532952e197c58182a0e9493b1525 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Fri, 3 May 2019 16:04:44 +0100 Subject: [PATCH 193/259] [ACA-2147] minor theme fixes (#1096) --- .../content-node-share.dialog.scss | 14 -------------- src/app/ui/custom-theme.scss | 5 ++--- src/app/ui/overrides/adf-toolbar.theme.scss | 5 ----- 3 files changed, 2 insertions(+), 22 deletions(-) delete mode 100644 src/app/ui/overrides/adf-toolbar.theme.scss diff --git a/src/app/components/shared/content-node-share/content-node-share.dialog.scss b/src/app/components/shared/content-node-share/content-node-share.dialog.scss index 2d71489f14..cfd380f8cf 100644 --- a/src/app/components/shared/content-node-share/content-node-share.dialog.scss +++ b/src/app/components/shared/content-node-share/content-node-share.dialog.scss @@ -1,17 +1,3 @@ -@mixin aca-share-dialog-theme($theme) { - $accent: map-get($theme, accent); - - // fixes [ACA-2069] - .mat-slide-toggle.mat-primary.mat-checked:not(.mat-disabled) { - .mat-slide-toggle-thumb { - background-color: mat-color($accent); - } - .mat-slide-toggle-bar { - background-color: mat-color($accent, 0.54); - } - } -} - @mixin adf-share-link-typography { letter-spacing: -0.4px; line-height: 2; diff --git a/src/app/ui/custom-theme.scss b/src/app/ui/custom-theme.scss index e970dd835b..b486030c1e 100644 --- a/src/app/ui/custom-theme.scss +++ b/src/app/ui/custom-theme.scss @@ -13,7 +13,6 @@ @import '../components/layout/layout.theme.scss'; @import '../components/shared/content-node-share/content-node-share.dialog.scss'; -@import './overrides/adf-toolbar.theme'; @import 'overrides/adf-layout-container.theme'; @import './overrides/adf-document-list.theme'; @@ -62,7 +61,8 @@ $foreground: map-get($custom-theme, foreground); $warn: map-get($custom-theme, warn); @mixin custom-theme($theme) { - @include custom-adf-toolbar-theme($theme); + @include mat-button-theme($theme); + @include adf-document-list-theme($theme); @include layout-theme($theme); @@ -76,7 +76,6 @@ $warn: map-get($custom-theme, warn); @include aca-current-user-theme($theme); @include aca-context-menu-theme($theme); @include app-create-menu-theme($theme); - @include aca-share-dialog-theme($theme); } //Custom variables - ACA specific styling: diff --git a/src/app/ui/overrides/adf-toolbar.theme.scss b/src/app/ui/overrides/adf-toolbar.theme.scss deleted file mode 100644 index 85e16b2142..0000000000 --- a/src/app/ui/overrides/adf-toolbar.theme.scss +++ /dev/null @@ -1,5 +0,0 @@ -@mixin custom-adf-toolbar-theme($theme) { - .adf-toolbar { - @include angular-material-theme($theme); - } -} From 21f85015e0b96aa90b791163945cb96d74210016 Mon Sep 17 00:00:00 2001 From: Suzana Dirla Date: Mon, 6 May 2019 08:54:40 +0300 Subject: [PATCH 194/259] [ACA-1623] enable Reset all filters button (#1097) --- src/app.config.json | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app.config.json b/src/app.config.json index 3585a5b474..f836f69e8f 100644 --- a/src/app.config.json +++ b/src/app.config.json @@ -213,6 +213,7 @@ ] }, "aca:triggeredOnChange": false, + "resetButton": true, "filterQueries": [ { "query": "+TYPE:'cm:folder' OR +TYPE:'cm:content'" }, { From 6cb1ad410159efe29f5cc45c821edbd019284f86 Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Tue, 7 May 2019 09:33:09 +0300 Subject: [PATCH 195/259] [ACA-2374] Sidenav - RTL support (#1098) * add rtl HostBinding * sidenav direction input * remove unused style * rtl style changes * test --- .../app-layout/app-layout.component.html | 1 + .../components/sidenav/sidenav.component.scss | 10 ++++++++++ .../sidenav/sidenav.component.spec.ts | 18 ++++++++++++++++++ .../sidenav/sidenav.component.theme.scss | 4 ---- .../components/sidenav/sidenav.component.ts | 8 +++++++- 5 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/app/components/layout/app-layout/app-layout.component.html b/src/app/components/layout/app-layout/app-layout.component.html index b114dc453a..e9d3761e2c 100644 --- a/src/app/components/layout/app-layout/app-layout.component.html +++ b/src/app/components/layout/app-layout/app-layout.component.html @@ -23,6 +23,7 @@ Date: Wed, 8 May 2019 18:14:57 +0300 Subject: [PATCH 197/259] Upgrade to ADF 3.2.0 (#1100) * Upgrade to ADF 3.2.0 version * fixes login button color * Revert "fixes login button color" This reverts commit 29c529d * include only button color styling for toolbar --- package-lock.json | 24 ++++++++++----------- package.json | 8 +++---- src/app/ui/overrides/adf-toolbar.theme.scss | 2 +- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/package-lock.json b/package-lock.json index 269c48f168..5a1fb58797 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,33 +5,33 @@ "requires": true, "dependencies": { "@alfresco/adf-content-services": { - "version": "3.2.0-2f126fe7fd4bcb111f5aad788e01465d10c1d7d3", - "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-3.2.0-2f126fe7fd4bcb111f5aad788e01465d10c1d7d3.tgz", - "integrity": "sha512-9/iMz5vKwWXHSjfF+RONVlztwmsW6H6rBI1/o5n5l2cShnSYFxLvViMj11F0rNzXLQWhDSC6sjNaJhl0Yuj/wA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-3.2.0.tgz", + "integrity": "sha512-G8+vSL3GTGm2rAtvNgFpCctcX7WwRBoAkvkvwnIWETrl5zYb4ftzvCpSkrj8FKxueE8Ys59oTMOv1o22ev2+AA==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/adf-core": { - "version": "3.2.0-2f126fe7fd4bcb111f5aad788e01465d10c1d7d3", - "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-3.2.0-2f126fe7fd4bcb111f5aad788e01465d10c1d7d3.tgz", - "integrity": "sha512-7RSGgP25uT900qvIHJabzwMcA4rJTUDnrmNIzyg3hogZRYUN8kMt5fV3nf8vs2rKUkfHDpO12+EVlAwJ0dXsXQ==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-3.2.0.tgz", + "integrity": "sha512-mgDNroAiKjDSOVS3nfc0vYrgGtWt2dUNLfLReU89jvMAiXLVCghA/Gufhjx0t64TOneWofD9hNGV0KuIXx0wFQ==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/adf-extensions": { - "version": "3.2.0-2f126fe7fd4bcb111f5aad788e01465d10c1d7d3", - "resolved": "https://registry.npmjs.org/@alfresco/adf-extensions/-/adf-extensions-3.2.0-2f126fe7fd4bcb111f5aad788e01465d10c1d7d3.tgz", - "integrity": "sha512-uGKUotJLyqvizh8yEn28Iuj8hw4xD+UBvYbhUUvqAD/v1vG3LEwrYW0aXvFsBaj+1Sh10PvKp16kg1Z9WNpoJA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@alfresco/adf-extensions/-/adf-extensions-3.2.0.tgz", + "integrity": "sha512-nw7rzgG7WznekyzNQF+unsWITuBfQva2wvTiqRPtimpA1hZWIcxKUWhKf5nkw8nCb8qlgkVIimylZjNZFlsr7A==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/js-api": { - "version": "3.2.0-fa5916ff413131513c3e382d7f27dd9b4cfa0e7e", - "resolved": "https://registry.npmjs.org/@alfresco/js-api/-/js-api-3.2.0-fa5916ff413131513c3e382d7f27dd9b4cfa0e7e.tgz", - "integrity": "sha512-3fhNh0+jqDzO6JavRhhYhGr2RZTLwSFIDF+uY2mcGCLWEiI0t81kyv4cYhO1hOHayfwXd6cn6hB7GZIChKrCZw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@alfresco/js-api/-/js-api-3.2.0.tgz", + "integrity": "sha512-HgB/8M4mSi1mVx7ZDbgrNLP5xZiPUamkNzQI198DkWwQRxXh9V0khEavm82Rr9M5nrLw4VdPUARFLmxsNQwmng==", "requires": { "event-emitter": "0.3.4", "superagent": "3.8.2" diff --git a/package.json b/package.json index 55fa794063..7ac6bcbb5f 100644 --- a/package.json +++ b/package.json @@ -37,10 +37,10 @@ }, "private": true, "dependencies": { - "@alfresco/adf-content-services": "3.2.0-2f126fe7fd4bcb111f5aad788e01465d10c1d7d3", - "@alfresco/adf-core": "3.2.0-2f126fe7fd4bcb111f5aad788e01465d10c1d7d3", - "@alfresco/adf-extensions": "3.2.0-2f126fe7fd4bcb111f5aad788e01465d10c1d7d3", - "@alfresco/js-api": "3.2.0-fa5916ff413131513c3e382d7f27dd9b4cfa0e7e", + "@alfresco/adf-content-services": "3.2.0", + "@alfresco/adf-core": "3.2.0", + "@alfresco/adf-extensions": "3.2.0", + "@alfresco/js-api": "3.2.0", "@angular/animations": "7.2.14", "@angular/cdk": "^7.3.7", "@angular/common": "7.2.14", diff --git a/src/app/ui/overrides/adf-toolbar.theme.scss b/src/app/ui/overrides/adf-toolbar.theme.scss index 85e16b2142..b975fc27eb 100644 --- a/src/app/ui/overrides/adf-toolbar.theme.scss +++ b/src/app/ui/overrides/adf-toolbar.theme.scss @@ -1,5 +1,5 @@ @mixin custom-adf-toolbar-theme($theme) { .adf-toolbar { - @include angular-material-theme($theme); + @include mat-button-theme($theme); } } From 996975fdb515d909f780f8ae9dc85bdfced62b34 Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Wed, 8 May 2019 18:22:03 +0300 Subject: [PATCH 198/259] [ACA-2375] Contextmenu - RTL support (#1099) * direction element wrapper * use CONTEXT_MENU_DIRECTION injection * direction injection token * refactor positionStrategy * set CONTEXT_MENU_DIRECTION value * test --- .../context-menu/context-menu.component.html | 90 +++++++++--------- .../context-menu/context-menu.component.ts | 9 +- .../context-menu/context-menu.service.spec.ts | 61 ++++++++++-- .../context-menu/context-menu.service.ts | 93 +++++++++++-------- .../context-menu/direction.token.ts | 34 +++++++ 5 files changed, 197 insertions(+), 90 deletions(-) create mode 100644 src/app/components/context-menu/direction.token.ts diff --git a/src/app/components/context-menu/context-menu.component.html b/src/app/components/context-menu/context-menu.component.html index 7283cb02c7..d9ee883bf6 100644 --- a/src/app/components/context-menu/context-menu.component.html +++ b/src/app/components/context-menu/context-menu.component.html @@ -1,50 +1,54 @@ - +
+ - - - - - + + + + - - - + + + - - + + - - - - - - + + + + + + - - + + + - - + +
diff --git a/src/app/components/context-menu/context-menu.component.ts b/src/app/components/context-menu/context-menu.component.ts index 4fae5f5383..f720468718 100644 --- a/src/app/components/context-menu/context-menu.component.ts +++ b/src/app/components/context-menu/context-menu.component.ts @@ -30,10 +30,10 @@ import { OnDestroy, HostListener, ViewChild, - AfterViewInit + AfterViewInit, + Inject } from '@angular/core'; import { MatMenuTrigger } from '@angular/material/menu'; - import { AppExtensionService } from '../../extensions/extension.service'; import { AppStore, getAppSelection } from '@alfresco/aca-shared/store'; import { Store } from '@ngrx/store'; @@ -41,6 +41,8 @@ import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; import { ContentActionRef } from '@alfresco/adf-extensions'; import { ContextMenuOverlayRef } from './context-menu-overlay'; +import { CONTEXT_MENU_DIRECTION } from './direction.token'; +import { Directionality } from '@angular/cdk/bidi'; @Component({ selector: 'aca-context-menu', @@ -70,7 +72,8 @@ export class ContextMenuComponent implements OnInit, OnDestroy, AfterViewInit { constructor( private contextMenuOverlayRef: ContextMenuOverlayRef, private extensions: AppExtensionService, - private store: Store + private store: Store, + @Inject(CONTEXT_MENU_DIRECTION) public direction: Directionality ) {} onClickOutsideEvent() { diff --git a/src/app/components/context-menu/context-menu.service.spec.ts b/src/app/components/context-menu/context-menu.service.spec.ts index 5ac488db65..a21d19e396 100644 --- a/src/app/components/context-menu/context-menu.service.spec.ts +++ b/src/app/components/context-menu/context-menu.service.spec.ts @@ -31,36 +31,85 @@ import { of } from 'rxjs'; import { CoreModule } from '@alfresco/adf-core'; import { ContextMenuService } from './context-menu.service'; import { ContextMenuModule } from './context-menu.module'; +import { UserPreferencesService } from '@alfresco/adf-core'; describe('ContextMenuService', () => { let contextMenuService; + let overlay; + let injector; + let userPreferencesService; const overlayConfig = { hasBackdrop: false, backdropClass: '', - panelClass: 'test-panel' + panelClass: 'test-panel', + source: { + x: 1, + y: 1 + } }; beforeEach(() => { TestBed.configureTestingModule({ imports: [CoreModule.forRoot(), ContextMenuModule], - providers: [Overlay, { provide: Store, useValue: { select: () => of() } }] + providers: [ + Overlay, + { provide: Store, useValue: { select: () => of() } }, + UserPreferencesService + ] }); - const injector = TestBed.get(Injector); - const overlay = TestBed.get(Overlay); - - contextMenuService = new ContextMenuService(injector, overlay); + injector = TestBed.get(Injector); + overlay = TestBed.get(Overlay); + userPreferencesService = TestBed.get(UserPreferencesService); }); it('should create a custom overlay', () => { + contextMenuService = new ContextMenuService( + injector, + overlay, + userPreferencesService + ); + contextMenuService.open(overlayConfig); expect(document.querySelector('.test-panel')).not.toBe(null); }); it('should render component', () => { + contextMenuService = new ContextMenuService( + injector, + overlay, + userPreferencesService + ); + contextMenuService.open(overlayConfig); expect(document.querySelector('aca-context-menu')).not.toBe(null); }); + + it('should have default LTR direction value', () => { + contextMenuService = new ContextMenuService( + injector, + overlay, + userPreferencesService + ); + + contextMenuService.open(overlayConfig); + + expect(document.body.querySelector('div[dir="ltr"]')).not.toBe(null); + }); + + it('should change direction on textOrientation event', () => { + spyOn(userPreferencesService, 'select').and.returnValue(of('rtl')); + + contextMenuService = new ContextMenuService( + injector, + overlay, + userPreferencesService + ); + + contextMenuService.open(overlayConfig); + + expect(document.body.querySelector('div[dir="rtl"]')).not.toBe(null); + }); }); diff --git a/src/app/components/context-menu/context-menu.service.ts b/src/app/components/context-menu/context-menu.service.ts index bd9a71feaa..4787e43e90 100644 --- a/src/app/components/context-menu/context-menu.service.ts +++ b/src/app/components/context-menu/context-menu.service.ts @@ -1,15 +1,55 @@ -import { Injectable, Injector, ComponentRef, ElementRef } from '@angular/core'; +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2019 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { Injectable, Injector, ComponentRef } from '@angular/core'; import { Overlay, OverlayConfig, OverlayRef } from '@angular/cdk/overlay'; import { ComponentPortal, PortalInjector } from '@angular/cdk/portal'; import { ContextMenuOverlayRef } from './context-menu-overlay'; import { ContextMenuComponent } from './context-menu.component'; import { ContextmenuOverlayConfig } from './interfaces'; +import { UserPreferencesService } from '@alfresco/adf-core'; +import { Directionality } from '@angular/cdk/bidi'; +import { CONTEXT_MENU_DIRECTION } from './direction.token'; @Injectable({ providedIn: 'root' }) export class ContextMenuService { - constructor(private injector: Injector, private overlay: Overlay) {} + private direction: Directionality; + + constructor( + private injector: Injector, + private overlay: Overlay, + private userPreferenceService: UserPreferencesService + ) { + this.userPreferenceService + .select('textOrientation') + .subscribe(textOrientation => { + this.direction = textOrientation; + }); + } open(config: ContextmenuOverlayConfig) { const overlay = this.createOverlay(config); @@ -49,56 +89,33 @@ export class ContextMenuService { const injectionTokens = new WeakMap(); injectionTokens.set(ContextMenuOverlayRef, contextmenuOverlayRef); + injectionTokens.set(CONTEXT_MENU_DIRECTION, this.direction); return new PortalInjector(this.injector, injectionTokens); } private getOverlayConfig(config: ContextmenuOverlayConfig): OverlayConfig { - const fakeElement: any = { - getBoundingClientRect: (): ClientRect => ({ - bottom: config.source.clientY, - height: 0, - left: config.source.clientX, - right: config.source.clientX, - top: config.source.clientY, - width: 0 - }) - }; + const { x, y } = config.source; const positionStrategy = this.overlay .position() - .connectedTo( - new ElementRef(fakeElement), - { originX: 'start', originY: 'bottom' }, - { overlayX: 'start', overlayY: 'top' } - ) - .withFallbackPosition( - { originX: 'start', originY: 'top' }, - { overlayX: 'start', overlayY: 'bottom' } - ) - .withFallbackPosition( - { originX: 'end', originY: 'top' }, - { overlayX: 'start', overlayY: 'top' } - ) - .withFallbackPosition( - { originX: 'start', originY: 'top' }, - { overlayX: 'end', overlayY: 'top' } - ) - .withFallbackPosition( - { originX: 'end', originY: 'center' }, - { overlayX: 'start', overlayY: 'center' } - ) - .withFallbackPosition( - { originX: 'start', originY: 'center' }, - { overlayX: 'end', overlayY: 'center' } - ); + .flexibleConnectedTo({ x, y }) + .withPositions([ + { + originX: 'end', + originY: 'bottom', + overlayX: 'end', + overlayY: 'top' + } + ]); const overlayConfig = new OverlayConfig({ hasBackdrop: config.hasBackdrop, backdropClass: config.backdropClass, panelClass: config.panelClass, scrollStrategy: this.overlay.scrollStrategies.close(), - positionStrategy + positionStrategy, + direction: this.direction }); return overlayConfig; diff --git a/src/app/components/context-menu/direction.token.ts b/src/app/components/context-menu/direction.token.ts new file mode 100644 index 0000000000..07eca2e5ce --- /dev/null +++ b/src/app/components/context-menu/direction.token.ts @@ -0,0 +1,34 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2019 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { InjectionToken } from '@angular/core'; + +export const CONTEXT_MENU_DIRECTION = new InjectionToken( + 'CONTEXT_MENU_DIRECTION', + { + providedIn: 'root', + factory: () => 'ltr' + } +); From d5f8699976dcc75e4d5e67fb42628f4bccd8b813 Mon Sep 17 00:00:00 2001 From: Adina Parpalita Date: Thu, 9 May 2019 14:57:32 +0300 Subject: [PATCH 199/259] [ACA-1258] automate tests for viewing file/image properties (#1101) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * split InfoDrawer test component and add tests for viewing properties * add “date item” to spell ignore and remove commented code * try to increase timeout --- cspell.json | 3 +- .../info-drawer/info-drawer-comments-tab.ts | 140 +++++++ .../info-drawer-metadata-content.ts | 125 +++++++ .../info-drawer-metadata-library.ts | 254 +++++++++++++ e2e/components/info-drawer/info-drawer.ts | 349 +----------------- e2e/configs.ts | 3 +- e2e/resources/test-files/file-jpg.jpg | Bin 0 -> 22812 bytes .../context-menu-multiple-selection.test.ts | 6 +- e2e/suites/info-drawer/comments.test.ts | 204 +++++----- .../file-folder-properties.test.ts | 249 +++++++++++++ e2e/suites/info-drawer/general.test.ts | 12 +- .../info-drawer/library-properties.test.ts | 101 ++--- .../repo-client/apis/nodes/nodes-api.ts | 27 +- protractor.conf.js | 9 +- 14 files changed, 990 insertions(+), 492 deletions(-) create mode 100755 e2e/components/info-drawer/info-drawer-comments-tab.ts create mode 100755 e2e/components/info-drawer/info-drawer-metadata-content.ts create mode 100755 e2e/components/info-drawer/info-drawer-metadata-library.ts create mode 100644 e2e/resources/test-files/file-jpg.jpg create mode 100755 e2e/suites/info-drawer/file-folder-properties.test.ts diff --git a/cspell.json b/cspell.json index 615efac647..44d75942ef 100644 --- a/cspell.json +++ b/cspell.json @@ -62,7 +62,8 @@ "keycodes", "denysvuika", "submenu", - "submenus" + "submenus", + "dateitem" ], "dictionaries": ["html", "en-gb", "en_US"] } diff --git a/e2e/components/info-drawer/info-drawer-comments-tab.ts b/e2e/components/info-drawer/info-drawer-comments-tab.ts new file mode 100755 index 0000000000..70dbb3688f --- /dev/null +++ b/e2e/components/info-drawer/info-drawer-comments-tab.ts @@ -0,0 +1,140 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2019 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { ElementFinder, ElementArrayFinder, by, browser, ExpectedConditions as EC, until } from 'protractor'; +import { Component } from '../component'; +import { BROWSER_WAIT_TIMEOUT } from '../../configs'; + +export class CommentsTab extends Component { + private static selectors = { + root: 'adf-comments', + + commentsContainer: '.adf-comments-container', + commentsHeader: '.adf-comments-header', + commentsTextArea: '.adf-comments-input-container textarea', + addCommentButton: 'button.adf-comments-input-add', + commentsList: '.adf-comment-list', + commentsListItem: '.adf-comment-list-item', + commentById: `adf-comment-`, + commentUserName: 'comment-user', + commentUserAvatar: 'comment-user-icon', + commentMessage: 'comment-message', + commentTime: 'comment-time' + }; + + commentsContainer: ElementFinder = this.component.element(by.css(CommentsTab.selectors.commentsContainer)); + commentsHeader: ElementFinder = this.component.element(by.css(CommentsTab.selectors.commentsHeader)); + commentTextarea: ElementFinder = this.component.element(by.css(CommentsTab.selectors.commentsTextArea)); + addCommentButton: ElementFinder = this.component.element(by.css(CommentsTab.selectors.addCommentButton)); + commentsList: ElementArrayFinder = this.component.all(by.css(CommentsTab.selectors.commentsListItem)); + + commentListItem = by.css(CommentsTab.selectors.commentsListItem); + + commentUserAvatar = by.id(CommentsTab.selectors.commentUserAvatar); + commentUser = by.id(CommentsTab.selectors.commentUserName) + commentText = by.id(CommentsTab.selectors.commentMessage); + commentTime = by.id(CommentsTab.selectors.commentTime); + + + constructor(ancestor?: ElementFinder) { + super(CommentsTab.selectors.root, ancestor); + } + + async waitForCommentsContainer() { + await browser.wait(EC.visibilityOf(this.commentsContainer), BROWSER_WAIT_TIMEOUT); + } + + async getCommentsTabHeaderText() { + return await this.commentsHeader.getText(); + } + + async isCommentTextAreaDisplayed() { + return await browser.isElementPresent(this.commentTextarea); + } + + async isAddCommentButtonEnabled() { + const present = await browser.isElementPresent(this.addCommentButton); + if (present) { + return await this.addCommentButton.isEnabled(); + } + return false; + } + + async getCommentListItem() { + return await browser.wait(until.elementLocated(this.commentListItem), BROWSER_WAIT_TIMEOUT / 2); + } + + async getCommentById(commentId?: string) { + if (commentId) { + return await browser.wait(until.elementLocated(by.id(`${CommentsTab.selectors.commentById}${commentId}`)), BROWSER_WAIT_TIMEOUT / 2); + } + return await this.getCommentListItem(); + } + + async isCommentDisplayed(commentId?: string) { + return await browser.isElementPresent(await this.getCommentById(commentId)); + } + + async isCommentUserAvatarDisplayed(commentId?: string) { + const commentElement = await this.getCommentById(commentId); + return await browser.isElementPresent(commentElement.findElement(this.commentUserAvatar)); + } + + async getCommentText(commentId?: string) { + const commentElement = await this.getCommentById(commentId); + const message = await commentElement.findElement(this.commentText); + return await message.getText(); + } + + async getCommentUserName(commentId?: string) { + const commentElement = await this.getCommentById(commentId); + const user = await commentElement.findElement(this.commentUser); + return await user.getText(); + } + + async getCommentTime(commentId?: string) { + const commentElement = await this.getCommentById(commentId); + const time = await commentElement.findElement(this.commentTime); + return await time.getText(); + } + + async getNthCommentId(index: number) { + return await this.commentsList.get(index - 1).getAttribute('id'); + } + + async typeComment(text: string) { + return await this.commentTextarea.sendKeys(text); + } + + async clickAddButton() { + return await this.addCommentButton.click(); + } + + async getCommentTextFromTextArea() { + return await this.commentTextarea.getAttribute('value'); + } + +} + diff --git a/e2e/components/info-drawer/info-drawer-metadata-content.ts b/e2e/components/info-drawer/info-drawer-metadata-content.ts new file mode 100755 index 0000000000..6fcb52dbb7 --- /dev/null +++ b/e2e/components/info-drawer/info-drawer-metadata-content.ts @@ -0,0 +1,125 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2019 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { ElementFinder, ElementArrayFinder, by, browser, ExpectedConditions as EC } from 'protractor'; +import { Component } from '../component'; +import { BROWSER_WAIT_TIMEOUT } from '../../configs'; + +export class ContentMetadata extends Component { + private static selectors = { + root: 'adf-content-metadata-card', + + expandedPanel: '.mat-expansion-panel.mat-expanded', + propertyList: '.adf-property-list', + property: '.adf-property', + propertyLabel: '.adf-property-label', + propertyValue: '.adf-property-value', + editProperties: `button[title='Edit']`, + editProperty: `.mat-icon[title='Edit']`, + editDateItem: `.adf-dateitem-editable`, + moreLessInformation: `[data-automation-id='meta-data-card-toggle-expand']` + }; + + expandedPanel: ElementFinder = this.component.element(by.css(ContentMetadata.selectors.expandedPanel)); + propertyList: ElementFinder = this.component.element(by.css(ContentMetadata.selectors.propertyList)); + propertyListElements: ElementArrayFinder = this.component.all(by.css(ContentMetadata.selectors.property)); + propertyValue: ElementFinder = this.component.element(by.css(ContentMetadata.selectors.propertyValue)); + editPropertiesButton: ElementFinder = this.component.element(by.css(ContentMetadata.selectors.editProperties)); + lessInfoButton: ElementFinder = this.component.element(by.cssContainingText(ContentMetadata.selectors.moreLessInformation, 'Less information')); + moreInfoButton: ElementFinder = this.component.element(by.cssContainingText(ContentMetadata.selectors.moreLessInformation, 'More information')); + + imagePropertiesPanel: ElementFinder = this.component.element(by.css(`[data-automation-id='adf-metadata-group-APP.CONTENT_METADATA.EXIF_GROUP_TITLE']`)); + expandedImagePropertiesPanel: ElementFinder = this.component.element(by.css(`[data-automation-id='adf-metadata-group-APP.CONTENT_METADATA.EXIF_GROUP_TITLE'].mat-expanded`)); + + constructor(ancestor?: ElementFinder) { + super(ContentMetadata.selectors.root, ancestor); + } + + async isPropertiesListExpanded() { + return await browser.isElementPresent(this.expandedPanel); + } + + async waitForImagePropertiesPanelToExpand() { + return await browser.wait(EC.visibilityOf(this.expandedImagePropertiesPanel), BROWSER_WAIT_TIMEOUT); + } + + async getVisiblePropertiesLabels() { + return await this.component.all(by.css(ContentMetadata.selectors.propertyLabel)) + .filter(async (elem) => await elem.isDisplayed()) + .map(async (elem) => await elem.getText()); + } + + async getVisiblePropertiesValues() { + return await this.component.all(by.css(ContentMetadata.selectors.propertyValue)) + .filter(async (elem) => await elem.isDisplayed()) + .map(async (elem) => { + if (await elem.isElementPresent(by.css('.mat-checkbox'))) { + if (await elem.isElementPresent(by.css('.mat-checkbox-checked'))) { + return true; + } + return false + } + return await elem.getText(); + }); + } + + async isEditPropertiesButtonEnabled() { + return (await browser.isElementPresent(this.editPropertiesButton)) && (await this.editPropertiesButton.isEnabled()); + } + + async isLessInfoButtonEnabled() { + return (await browser.isElementPresent(this.lessInfoButton)) && (await this.lessInfoButton.isEnabled()); + } + + async isMoreInfoButtonEnabled() { + return (await browser.isElementPresent(this.moreInfoButton)) && (await this.moreInfoButton.isEnabled()); + } + + async isLessInfoButtonDisplayed() { + return await browser.isElementPresent(this.lessInfoButton); + } + + async isMoreInfoButtonDisplayed() { + return await browser.isElementPresent(this.moreInfoButton); + } + + async clickLessInformationButton() { + return await this.lessInfoButton.click(); + } + + async clickMoreInformationButton() { + return await this.moreInfoButton.click(); + } + + async isImagePropertiesPanelDisplayed() { + return (await browser.isElementPresent(this.imagePropertiesPanel)) && (await this.imagePropertiesPanel.isDisplayed()); + } + + async clickImagePropertiesPanel() { + return await this.imagePropertiesPanel.click(); + } + +} + diff --git a/e2e/components/info-drawer/info-drawer-metadata-library.ts b/e2e/components/info-drawer/info-drawer-metadata-library.ts new file mode 100755 index 0000000000..f5f2e76571 --- /dev/null +++ b/e2e/components/info-drawer/info-drawer-metadata-library.ts @@ -0,0 +1,254 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2019 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { ElementFinder, by, browser, ExpectedConditions as EC } from 'protractor'; +import { Component } from '../component'; +import { BROWSER_WAIT_TIMEOUT } from '../../configs'; + +export class LibraryMetadata extends Component { + private static selectors = { + root: 'app-library-metadata-form', + + metadataTabContent: '.mat-card-content', + metadataTabAction: '.mat-card-actions .mat-button', + field: '.mat-form-field', + fieldLabelWrapper: '.mat-form-field-label-wrapper', + fieldInput: '.mat-input-element', + dropDown: '.mat-select', + + visibilityOption: '.mat-option .mat-option-text', + + hint: '.mat-hint', + error: '.mat-error' + }; + + metadataTabContent: ElementFinder = this.component.element(by.css(LibraryMetadata.selectors.metadataTabContent)); + metadataTabAction: ElementFinder = this.component.element(by.css(LibraryMetadata.selectors.metadataTabAction)); + fieldLabelWrapper: ElementFinder = this.component.element(by.css(LibraryMetadata.selectors.fieldLabelWrapper)); + fieldInput: ElementFinder = this.component.element(by.css(LibraryMetadata.selectors.fieldInput)); + + visibilityDropDown: ElementFinder = this.component.element(by.css(LibraryMetadata.selectors.dropDown)); + visibilityPublic: ElementFinder = browser.element(by.cssContainingText(LibraryMetadata.selectors.visibilityOption, 'Public')); + visibilityPrivate: ElementFinder = browser.element(by.cssContainingText(LibraryMetadata.selectors.visibilityOption, 'Private')); + visibilityModerated: ElementFinder = browser.element(by.cssContainingText(LibraryMetadata.selectors.visibilityOption, 'Moderated')); + + hint: ElementFinder = this.component.element(by.css(LibraryMetadata.selectors.hint)); + error: ElementFinder = this.component.element(by.css(LibraryMetadata.selectors.error)); + + + constructor(ancestor?: ElementFinder) { + super(LibraryMetadata.selectors.root, ancestor); + } + + getLabelWrapper(label: string) { + return this.component.element(by.cssContainingText(LibraryMetadata.selectors.fieldLabelWrapper, label)); + } + + getFieldByName(fieldName: string) { + const wrapper = this.getLabelWrapper(fieldName); + return wrapper.element(by.xpath('..')).element(by.css(LibraryMetadata.selectors.fieldInput)); + } + + async isFieldDisplayed(fieldName: string) { + return await browser.isElementPresent(this.getFieldByName(fieldName)); + } + + async isInputEnabled(fieldName: string) { + return this.getFieldByName(fieldName).isEnabled(); + } + + async getValueOfField(fieldName: string) { + return await this.getFieldByName(fieldName).getText(); + } + + async enterTextInInput(fieldName: string, text: string) { + const input = this.getFieldByName(fieldName); + await input.clear(); + return await input.sendKeys(text); + } + + + getButton(button: string) { + return this.component.element(by.cssContainingText(LibraryMetadata.selectors.metadataTabAction, button)); + } + + async isButtonDisplayed(button: string) { + return browser.isElementPresent(this.getButton(button)); + } + + async isButtonEnabled(button: string) { + return await this.getButton(button).isEnabled(); + } + + async clickButton(button: string) { + return await this.getButton(button).click(); + } + + async waitForVisibilityDropDownToOpen() { + await browser.wait(EC.presenceOf(this.visibilityDropDown), BROWSER_WAIT_TIMEOUT); + } + + async waitForVisibilityDropDownToClose() { + await browser.wait(EC.stalenessOf(browser.$('.mat-option .mat-option-text')), BROWSER_WAIT_TIMEOUT); + } + + async isMessageDisplayed() { + return await browser.isElementPresent(this.hint); + } + + async getMessage() { + return await this.hint.getText(); + } + + async isErrorDisplayed() { + return await browser.isElementPresent(this.error); + } + + async getError() { + return await this.error.getText(); + } + + + async isNameDisplayed() { + return await this.isFieldDisplayed('Name'); + } + + async isNameEnabled() { + return await this.isInputEnabled('Name'); + } + + async getName() { + return await this.getValueOfField('Name'); + } + + async enterName(name: string) { + return await this.enterTextInInput('Name', name); + } + + + async isDescriptionDisplayed() { + return await this.isFieldDisplayed('Description'); + } + + async isDescriptionEnabled() { + return await this.isInputEnabled('Description'); + } + + async getDescription() { + return await this.getValueOfField('Description'); + } + + async enterDescription(desc: string) { + return await this.enterTextInInput('Description', desc); + } + + + async isVisibilityEnabled() { + const wrapper = this.getLabelWrapper('Visibility'); + const field = wrapper.element(by.xpath('..')).element(by.css(LibraryMetadata.selectors.dropDown)); + return await field.isEnabled(); + } + + async isVisibilityDisplayed() { + return await this.isFieldDisplayed('Visibility'); + } + + async getVisibility() { + return await this.getValueOfField('Visibility'); + } + + async setVisibility(visibility: string) { + const val = visibility.toLowerCase(); + + await this.visibilityDropDown.click(); + await this.waitForVisibilityDropDownToOpen(); + + if (val === 'public') { + await this.visibilityPublic.click(); + } else if (val === 'private') { + await this.visibilityPrivate.click(); + } else if (val === 'moderated') { + await this.visibilityModerated.click(); + } else { + console.log('----- invalid visibility', val); + } + + await this.waitForVisibilityDropDownToClose(); + } + + + async isLibraryIdDisplayed() { + return await this.isFieldDisplayed('Library ID'); + } + + async isLibraryIdEnabled() { + return await this.isInputEnabled('Library ID'); + } + + async getLibraryId() { + return await this.getValueOfField('Library ID'); + } + + + async isEditLibraryPropertiesEnabled() { + return await this.isButtonEnabled('Edit'); + } + + async isEditLibraryPropertiesDisplayed() { + return await this.isButtonDisplayed('Edit'); + } + + async clickEditLibraryProperties() { + return await this.clickButton('Edit'); + } + + + async isUpdateEnabled() { + return await this.isButtonEnabled('Update'); + } + + async isUpdateDisplayed() { + return await this.isButtonDisplayed('Update'); + } + + async clickUpdate() { + return await this.clickButton('Update'); + } + + + async isCancelEnabled() { + return await this.isButtonEnabled('Cancel'); + } + + async isCancelDisplayed() { + return await this.isButtonDisplayed('Cancel'); + } + + async clickCancel() { + return await this.clickButton('Cancel'); + } + +} + diff --git a/e2e/components/info-drawer/info-drawer.ts b/e2e/components/info-drawer/info-drawer.ts index b366ff4359..46d8371a45 100755 --- a/e2e/components/info-drawer/info-drawer.ts +++ b/e2e/components/info-drawer/info-drawer.ts @@ -23,13 +23,16 @@ * along with Alfresco. If not, see . */ -import { ElementFinder, ElementArrayFinder, by, browser, ExpectedConditions as EC, until } from 'protractor'; +import { ElementFinder, ElementArrayFinder, by, browser, ExpectedConditions as EC, $ } from 'protractor'; import { Component } from '../component'; import { BROWSER_WAIT_TIMEOUT } from '../../configs'; +import { CommentsTab } from './info-drawer-comments-tab'; +import { LibraryMetadata } from './info-drawer-metadata-library'; +import { ContentMetadata } from './info-drawer-metadata-content'; export class InfoDrawer extends Component { private static selectors = { - root: 'aca-info-drawer', + root: 'adf-info-drawer', header: '.adf-info-drawer-layout-header', content: '.adf-info-drawer-layout-content', @@ -42,34 +45,13 @@ export class InfoDrawer extends Component { next: '.mat-tab-header-pagination-after .mat-tab-header-pagination-chevron', previous: '.mat-tab-header-pagination-before .mat-tab-header-pagination-chevron', - headerTitle: '.adf-info-drawer-layout-header-title', - - // comments tab - commentsContainer: '.adf-comments-container', - commentsHeader: '.adf-comments-header', - commentsTextArea: '.adf-comments-input-container textarea', - addCommentButton: 'button.adf-comments-input-add', - commentsList: '.adf-comment-list', - commentsListItem: '.adf-comment-list-item', - commentById: `adf-comment-`, - commentUserName: 'comment-user', - commentUserAvatar: 'comment-user-icon', - commentMessage: 'comment-message', - commentTime: 'comment-time', - - // metadata card - metadataTabContent: '.app-metadata-tab .mat-card-content', - metadataTabAction: '.app-metadata-tab .mat-card-actions .mat-button', - field: '.mat-form-field', - fieldLabelWrapper: '.mat-form-field-label-wrapper', - fieldInput: '.mat-input-element', - dropDown: '.mat-select', - visibilityOption: '.mat-option .mat-option-text', - - hint: '.mat-hint', - error: '.mat-error' + headerTitle: '.adf-info-drawer-layout-header-title' }; + commentsTab = new CommentsTab($(InfoDrawer.selectors.root)); + aboutTab = new LibraryMetadata($(InfoDrawer.selectors.root)); + propertiesTab = new ContentMetadata($(InfoDrawer.selectors.root)); + header: ElementFinder = this.component.element(by.css(InfoDrawer.selectors.header)); headerTitle: ElementFinder = this.component.element(by.css(InfoDrawer.selectors.headerTitle)); tabLabel: ElementFinder = this.component.element(by.css(InfoDrawer.selectors.tabLabel)); @@ -78,40 +60,14 @@ export class InfoDrawer extends Component { tabActiveContent: ElementFinder = this.component.element(by.css(InfoDrawer.selectors.activeTabContent)); - commentsContainer: ElementFinder = this.component.element(by.css(InfoDrawer.selectors.commentsContainer)); - commentsHeader: ElementFinder = this.component.element(by.css(InfoDrawer.selectors.commentsHeader)); - commentTextarea: ElementFinder = this.component.element(by.css(InfoDrawer.selectors.commentsTextArea)); - addCommentButton: ElementFinder = this.component.element(by.css(InfoDrawer.selectors.addCommentButton)); - commentsList: ElementArrayFinder = this.component.all(by.css(InfoDrawer.selectors.commentsListItem)); - - commentListItem = by.css(InfoDrawer.selectors.commentsListItem); - - commentUserAvatar = by.id(InfoDrawer.selectors.commentUserAvatar); - commentUser = by.id(InfoDrawer.selectors.commentUserName) - commentText = by.id(InfoDrawer.selectors.commentMessage); - commentTime = by.id(InfoDrawer.selectors.commentTime); - nextButton: ElementFinder = this.component.element(by.css(InfoDrawer.selectors.next)); previousButton: ElementFinder = this.component.element(by.css(InfoDrawer.selectors.previous)); - metadataTabContent: ElementFinder = this.component.element(by.css(InfoDrawer.selectors.metadataTabContent)); - metadataTabAction: ElementFinder = this.component.element(by.css(InfoDrawer.selectors.metadataTabAction)); - fieldLabelWrapper: ElementFinder = this.component.element(by.css(InfoDrawer.selectors.fieldLabelWrapper)); - fieldInput: ElementFinder = this.component.element(by.css(InfoDrawer.selectors.fieldInput)); - - visibilityDropDown: ElementFinder = this.component.element(by.css(InfoDrawer.selectors.dropDown)); - visibilityPublic: ElementFinder = browser.element(by.cssContainingText(InfoDrawer.selectors.visibilityOption, 'Public')); - visibilityPrivate: ElementFinder = browser.element(by.cssContainingText(InfoDrawer.selectors.visibilityOption, 'Private')); - visibilityModerated: ElementFinder = browser.element(by.cssContainingText(InfoDrawer.selectors.visibilityOption, 'Moderated')); - - hint: ElementFinder = this.component.element(by.css(InfoDrawer.selectors.hint)); - error: ElementFinder = this.component.element(by.css(InfoDrawer.selectors.error)); constructor(ancestor?: ElementFinder) { super(InfoDrawer.selectors.root, ancestor); } - async waitForInfoDrawerToOpen() { return await browser.wait(EC.presenceOf(this.header), BROWSER_WAIT_TIMEOUT); } @@ -124,10 +80,6 @@ export class InfoDrawer extends Component { return !(await browser.isElementPresent(by.css(InfoDrawer.selectors.tabs))); } - async waitForCommentsTabContainer() { - await browser.wait(EC.visibilityOf(this.commentsContainer), BROWSER_WAIT_TIMEOUT); - } - getTabByTitle(title: string) { return this.component.element(by.cssContainingText(InfoDrawer.selectors.tabLabel, title)); } @@ -166,60 +118,6 @@ export class InfoDrawer extends Component { return await this.headerTitle.getText(); } - getLabelWrapper(label: string) { - return this.component.element(by.cssContainingText(InfoDrawer.selectors.fieldLabelWrapper, label)); - } - - getFieldByName(fieldName: string) { - const wrapper = this.getLabelWrapper(fieldName); - return wrapper.element(by.xpath('..')).element(by.css(InfoDrawer.selectors.fieldInput)); - } - - async isFieldDisplayed(fieldName: string) { - return await browser.isElementPresent(this.getFieldByName(fieldName)); - } - - async isInputEnabled(fieldName: string) { - return this.getFieldByName(fieldName).isEnabled(); - } - - async getValueOfField(fieldName: string) { - return await this.getFieldByName(fieldName).getText(); - } - - async enterTextInInput(fieldName: string, text: string) { - const input = this.getFieldByName(fieldName); - await input.clear(); - return await input.sendKeys(text); - } - - - getButton(button: string) { - return this.component.element(by.cssContainingText(InfoDrawer.selectors.metadataTabAction, button)); - } - - async isButtonDisplayed(button: string) { - return browser.isElementPresent(this.getButton(button)); - } - - async isButtonEnabled(button: string) { - return await this.getButton(button).isEnabled(); - } - - async clickButton(button: string) { - return await this.getButton(button).click(); - } - - async waitForVisibilityDropDownToOpen() { - await browser.wait(EC.presenceOf(this.visibilityDropDown), BROWSER_WAIT_TIMEOUT); - } - - async waitForVisibilityDropDownToClose() { - await browser.wait(EC.stalenessOf(browser.$('.mat-option .mat-option-text')), BROWSER_WAIT_TIMEOUT); - } - - // --------------- - async isAboutTabDisplayed() { return await this.isTabDisplayed('About'); } @@ -228,236 +126,27 @@ export class InfoDrawer extends Component { return await this.isTabDisplayed('Properties'); } + async isPropertiesTabActive() { + return (await this.getActiveTabTitle()) === 'PROPERTIES'; + } + async isCommentsTabDisplayed() { return await this.isTabDisplayed('Comments'); } - async clickCommentsTab() { try { await this.getTabByTitle('Comments').click(); - await this.waitForCommentsTabContainer(); - await browser.wait(EC.visibilityOf(this.addCommentButton), BROWSER_WAIT_TIMEOUT); + await this.commentsTab.waitForCommentsContainer(); + await Promise.all([ + browser.wait(EC.visibilityOf(this.commentsTab.component), BROWSER_WAIT_TIMEOUT), + browser.wait(EC.invisibilityOf(this.propertiesTab.component), BROWSER_WAIT_TIMEOUT) + ]); } catch (error) { console.error('--- catch error on clickCommentsTab ---'); throw error; } } - async clickAboutTab() { - try { - return await this.getTabByTitle('About').click(); - } catch (error) { - console.error('--- catch error on clickAboutTab ---'); - } - } - - - async isMessageDisplayed() { - return await browser.isElementPresent(this.hint); - } - - async getMessage() { - return await this.hint.getText(); - } - - async isErrorDisplayed() { - return await browser.isElementPresent(this.error); - } - - async getError() { - return await this.error.getText(); - } - - - async isNameDisplayed() { - return await this.isFieldDisplayed('Name'); - } - - async isNameEnabled() { - return await this.isInputEnabled('Name'); - } - - async getName() { - return await this.getValueOfField('Name'); - } - - async enterName(name: string) { - return await this.enterTextInInput('Name', name); - } - - - async isDescriptionDisplayed() { - return await this.isFieldDisplayed('Description'); - } - - async isDescriptionEnabled() { - return await this.isInputEnabled('Description'); - } - - async getDescription() { - return await this.getValueOfField('Description'); - } - - async enterDescription(desc: string) { - return await this.enterTextInInput('Description', desc); - } - - - async isVisibilityEnabled() { - const wrapper = this.getLabelWrapper('Visibility'); - const field = wrapper.element(by.xpath('..')).element(by.css(InfoDrawer.selectors.dropDown)); - return await field.isEnabled(); - } - - async isVisibilityDisplayed() { - return await this.isFieldDisplayed('Visibility'); - } - - async getVisibility() { - return await this.getValueOfField('Visibility'); - } - - async setVisibility(visibility: string) { - const val = visibility.toLowerCase(); - - await this.visibilityDropDown.click(); - await this.waitForVisibilityDropDownToOpen(); - - if (val === 'public') { - await this.visibilityPublic.click(); - } else if (val === 'private') { - await this.visibilityPrivate.click(); - } else if (val === 'moderated') { - await this.visibilityModerated.click(); - } else { - console.log('----- invalid visibility', val); - } - - await this.waitForVisibilityDropDownToClose(); - } - - - async isLibraryIdDisplayed() { - return await this.isFieldDisplayed('Library ID'); - } - - async isLibraryIdEnabled() { - return await this.isInputEnabled('Library ID'); - } - - async getLibraryId() { - return await this.getValueOfField('Library ID'); - } - - - async isEditEnabled() { - return await this.isButtonEnabled('Edit'); - } - - async isEditDisplayed() { - return await this.isButtonDisplayed('Edit'); - } - - async clickEdit() { - return await this.clickButton('Edit'); - } - - - async isUpdateEnabled() { - return await this.isButtonEnabled('Update'); - } - - async isUpdateDisplayed() { - return await this.isButtonDisplayed('Update'); - } - - async clickUpdate() { - return await this.clickButton('Update'); - } - - - async isCancelEnabled() { - return await this.isButtonEnabled('Cancel'); - } - - async isCancelDisplayed() { - return await this.isButtonDisplayed('Cancel'); - } - - async clickCancel() { - return await this.clickButton('Cancel'); - } - - - async getCommentsTabHeaderText() { - return await this.commentsHeader.getText(); - } - - async isCommentTextAreaDisplayed() { - return await browser.isElementPresent(this.commentTextarea); - } - - async isAddCommentButtonEnabled() { - const present = await browser.isElementPresent(this.addCommentButton); - if (present) { - return await this.addCommentButton.isEnabled(); - } - return false; - } - - async getCommentListItem() { - return await browser.wait(until.elementLocated(this.commentListItem), BROWSER_WAIT_TIMEOUT / 2); - } - - async getCommentById(commentId?: string) { - if (commentId) { - return await browser.wait(until.elementLocated(by.id(`${InfoDrawer.selectors.commentById}${commentId}`)), BROWSER_WAIT_TIMEOUT / 2); - } - return await this.getCommentListItem(); - } - - async isCommentDisplayed(commentId?: string) { - return await browser.isElementPresent(await this.getCommentById(commentId)); - } - - async isCommentUserAvatarDisplayed(commentId?: string) { - const commentElement = await this.getCommentById(commentId); - return await browser.isElementPresent(commentElement.findElement(this.commentUserAvatar)); - } - - async getCommentText(commentId?: string) { - const commentElement = await this.getCommentById(commentId); - const message = await commentElement.findElement(this.commentText); - return await message.getText(); - } - - async getCommentUserName(commentId?: string) { - const commentElement = await this.getCommentById(commentId); - const user = await commentElement.findElement(this.commentUser); - return await user.getText(); - } - - async getCommentTime(commentId?: string) { - const commentElement = await this.getCommentById(commentId); - const time = await commentElement.findElement(this.commentTime); - return await time.getText(); - } - - async getNthCommentId(index: number) { - return await this.commentsList.get(index - 1).getAttribute('id'); - } - - async typeComment(text: string) { - return await this.commentTextarea.sendKeys(text); - } - - async clickAddButton() { - return await this.addCommentButton.click(); - } - - async getCommentTextFromTextArea() { - return await this.commentTextarea.getAttribute('value'); - } } diff --git a/e2e/configs.ts b/e2e/configs.ts index 542be231cf..fe21ffde5f 100755 --- a/e2e/configs.ts +++ b/e2e/configs.ts @@ -117,7 +117,8 @@ export const FILES = { protectedFile: { name: 'protected.pdf', password: '0000' - } + }, + jpgFile: 'file-jpg.jpg' }; export const EXTENSIBILITY_CONFIGS = { diff --git a/e2e/resources/test-files/file-jpg.jpg b/e2e/resources/test-files/file-jpg.jpg new file mode 100644 index 0000000000000000000000000000000000000000..eb6bf4a4570fa8112b945e44f6af249a47450b41 GIT binary patch literal 22812 zcmeHvcU%)`*Y+eK0YXtUC?G0T6BMNc1OyGzLkppZQCEr}iAzUCbTx=IB2pq^L^eV~ z6&s+it}D7CSWpN>MRXMv3-iV6TB#1t{@AJLizuyyo<4k5IGjpH&lX zSmWRyf-^vf*fxS><0cGm3vpD%IdBD>HTGL=IIkFIgKbk_yLt;3QBnN%H&`R7k@2Z3 z5|$ys{+3>jHg=xqKJ?kp`^eYW?(pznx;u+$gVj^5?*- z^NGXfnB}W}y>Gs{VjC`&PaZyJx>)%P)>c+xoZ=i9wHU9I z5WZYYP;L{hN$_8^vI-{)-$YTBF=NulOm&+ z$D|oW#Vq3{xR^XYamvJqyVS*GzMa37f0A2F9M?M|B_=o{AS60td9>qFleu$@oYS4s zOF7Zb%pu3EKf#wyzxi7CrwT01&A&a|?bX=7svXIQ4LPDqPPw@gSiRbIh8 zCN(;Ro0P^)OfW*P7#WqgBF)7F?ks<#_@v>>{_WV6Cnm)urX{AvCH}+d!-p|}p+8D; za!ZMcOp9@c#l-}jCQB=8ODo3^rLxOU@=sjKja~g8PQtE~m=cnh_@j%-H&$d~G<;_# z^djXD4QGN>XDY;sZVu1S9Hak!{wsn1O5nc|_^$;1D}nz?;Qv1fd_{OM34k6} z0e(ZiJVnx3O4ws$JHrZbnCIiKf`WbonQMsSAcP6#UWSk&;1Rqbel9|?wzs3(+8g5M zAZjT7u(GytG{nyu`NdgzlKfgI3`LO9F|!ta+_I#QaB&^aZ5(~~!!ONS!6OmS0WDkU_XQZaCm|Wk)*1oPS$`E8X(KT5eRq{0+EP5ChjLVj;QDm z#~53?lEwx_s+uHIY%=rqtC`L_a$1+&`NGULDrJK@dE9tCeFO6;Q>ioyx}E(j2S+D2 zcMnf5Zy#oGNNCvn@CBUcr7^L~;<&ujv=u8?rLWG&+PG=+maW?a`31sVg}aOPh)T;O z((;PRs_LV4^$o|4H#Yrp=J&HL=UUs&UyyZm_w-)9cD?V;z}qmGr(vIL#itVcoJBwV!=Ep35uAycnFHM+f=-VZEan#v{;xk@ZbIfY z?Mok`Nx*?J5pbGE8S3qndY0;!4*57- z#Vquhl?z^`d~8^gGQT@Id{(Cq42~7|tqfSHAQa6`R5Gp<96VysKP;>`q%>159a5%3 zkOsuB4}o)qQ4&c4EySEEky6lc36at)xaW+xcD*tRVgLgg^`-N2X}*wUHBy#;yPd^= z(W4TeijfY5Ae93BU$3=5*yuF=r$x)0CV^Xm6wN91z?4vgFnc~QUF*Nd6dFW=DIGEB z5woC_Gq%Qr@r_0W`7+c!%$@jS6r)m(4lmI9sw(3I%>$SEFJ0f6fF)uqX3K_k2L~_|knDhD-SO$(N!Jl0R&2Wa{7VfTvm1>BGn-M9!>Ij>t2SI?ieU)QI*Ph&q=P8=;RA~fdAQx4|(#)N% z1&ehnwGu{uo`yGCgkz{F4_DcVd1ICsxeg`Y%_nl;#Ua6ihXS6+me(YhYtixAGgR zx~NWl^_^!h&y6|}qypDY*X(JuycJ8H>oi|~!H0ppvSatUau2nw*3Eg?+2lFI&??RG zFdW>AzvS#-cZhN#$!p!TDNY?be3L9l=ijQiA1?gsxm~+pD25#wTYUA24m zoHqmHPqo1}Jk5)zrAbec69R5!2_nKCf%X`oJ{6NnVZH$2FhNEzn6KhNr2uhj*u{Qz zMoO8fiOC~Q&tl-fr(*%A4A%eIeZ%dg66qiq<)HkwG!JtMrfiWOlzOD5_ZN+cH4`Sk zI}%R#D7ac@d9QKuA63y0c{QZVvke|RznZppQ@q=R%Goewz;Cbn*is`DFwhOIlre0XXUc7Ky z^8-CQ?}ABJb_K>NbDhn=rq=| z@Ik&lBR9TIt~^MNgbNC#p@84Q#nH)N?`WJg03*dwrF0<<4SRnFK!y#!tX8!aF$YwD z0hD^>_0Tn{g)}jnjml9-Ce3uIk=A8(!=_7)oc`E*^1|*jJv7Vk8vEo-@5Z9`_f_?Sj&pnW zhHQg*3?4mf{9q*zEy1OZeDd$MXHZ)d<5T_&U1J!+l|HrwdC5TNL7w2~(O9bmj$UbX zmi7<=h)UdIi3VrX^1yis*&VPkY=-Ezm6Sr(LMY znGKa&21!Sw|GZPfGQ@eu9)4TiXr4sNJ9RObAX=KunD;s;(LKtdoz)aPY3Y)4nPpR1 ztQqQW@s&Ln%WZrbKZd%6Y(5JXVupn-3^Yg;!eW;Qg~O;F3xdLW`40KG>sbV@2jy=< zvO>vlC~g?GJrZ9NLm99K98@WPTt2$d0zwj?cXa^A=unzps00(4nP@zqN+lFFE^f#t zp!BY;Z87=!=AL5wC-R|+vj*(;YhkxZcAKg;gsYl} z%(Fcm28$maozeS{+f7DVPHi$~bmlBKZAjon#FGv`bbE+Gz7XT#m?ky^>qE6`Bx=ET zf^o4&s@ivkA_weB<%IQQ6rTX@j+BE}b_f2eouWnuT826(RP4j5g3vMpLS$%+>s+;}^7&%V!8Tnm4& zF6R9D+8?}Mq;MBgvP-)0j;l$Ay~4S4z3SuJ?%y-}l#s zgVturp_V$Aj8@vMi0*Tg`0ChP%nI-zJ5(eQtxidixh{`|bz@cvj?S7z5_;Ci_*Mt+ z+WHIz*Ph;4(vxw=^JA>luk4s{@wuD&Z~BM#uZpUcR~7NP zCq0F%^zv;{o7+hHSbBdP5$_JlVvN-hUFjCTuKm|vV@1D8@(LKnElA3OE4_PN^;S*F zUcXP*8SX2GF_!OexY74z^=t&H_rJIQ#qcT*&$XQivnvimMEEBfN%N_mX~R;@eLBP=}2!i^XBf# z8nQ;^luYtM7b+r3($kYZVjz0rH}o?%lfAc0%VOxS(*9w|8AU8X8Jd|*Na z&-RLp??`JbS@OQ!Gh^@&PiNza=7+!Ac?%?X2>o)~z%r+Q5XP`@z@k(XCZ;qsY~7-# zfc_}e09peuLX5&teYt?YPp}o{Ibwds2{EW8hU^p&ti;-5!LdN6v_Ln}foZ-0`g>nU zNEgm!9peQMLrdmuq(0-`8vYBq2^^E$ZWWdXnjyzfU}A={hz>#(&6-I>D2?E$##4mff{Dq) z%m-Zl@0lgJCSoZNr5=854!7$BH&H5JVj;uQSYYvVudq1&nHF1je+6!^$z_wK)-3*& z4L2?N_+^BKus@m4uZQ{EHObvHm2&2mFw=KM71ByUws(nG$Rk%{PhQhrXEI_g{HZfE zz~Aw*+Rfg*B{ZA7#pi>2>%|2r{EQx}l4yQL=-I63rL4?C?NOYB(|tuxLb3w2%lDWN zjRrR_U9zW|xttogSzoOA+5JGF-EA#iehAci)%UqX%f^8%i4G35$ zm3uUFIN;ib{XXi7>Vjx_xU?Ni#**jH_O|#m4eefvt?86$N5yJ`9Ti3^ZMT% z4F9RCq^X=Al zBt5hU@d#?=Ol-b;5(z3%@oT(GZ}W7epI;i=&)FV3L0ijrdbM?9)(~ghE6)m2C9e4A zjD3_$k+=TAAb+dY&wWw8*@Q4$Ta6LF&Zx!bl=?3vo}M)P-Asn&yu~SZYg5NtjJYGs zxXKDY#2K6sFjO(8+sK{1S)j$bCImuE>Dc}U8bgu9b7&}^Aw`KwWwQQtJqj?K7`UY~ z3NMDTYN%3uYq_Y!cD6viY52Wd*&S9C@FEc|%cUFRw;^v1as%zU%2ytodxCA;@}b3X zH+{bsX}1aAfTCS5*;HmnIkH=if;eAO)m2G$E}M~LaVeR&$RPIx6|bYo8>RoTcP&p4 zF6i8I;cR$VhNku!S+sjNA#;c$P&ty_yZlgc*wdn?EzAj1<6Iy4ho=7-a{9DGMQFa~ z})S;WPk6gQd8Uab~~$6yy{qLmmam)XLhhf5_=S$ zZV*rvyp@vdkh4RjgAKi~grMdt%i z-l(>6tEtl2lsgPfjll9kLapnxV+;;boO_ZtD{B6|=U%%T*SzmOUL)$;N6#OOi(T78XtYQT{WdkeMOW%Q{Sgz z^eA2TyaRixY=eq+JN}?$=eGI0SUsTYboKnODzh172W{Q|y!7z=joQUeaAIx8)SNZR z%(!Vs=LbGJGP#yiIWolJ6v9M#2!%k0_k6bj5+y@Y@V$bL0?3CFBj-?Zl!2B&&>SRU z#A%YRu2AW50SjV2k&Q+ZRINMCEv|DlKa+Js^iZf>dYJw!!QqKke9fd?CQG}|Ineor zU5BYU`t$m`1!7J1OBVgwk7N+4h5dTw@>stRK@kPXKGCJSXUvBbo5`G>sf4KwF(3Bc zTlv&yhrTT9fzHrE`xljdISsol2HkR+Y6=g!#oJNK7h2C*rClnq+2vrWOO5d4CTT4o zXjY2HB#Uy>s%1B}JWTSK`W(Cg((u&3nN)MdI>+TqMQ{@#ql-}3xabGw+`cc!Q1?WK z+KHZ4$Jgw9nf(P}UM^RTR^c+0O7=MZYp@x~!OQ(pcZln+jbo<-@_>_CzIwruWjtZ9nUG1L z*7#0+cG`u{iHPET z7<1<0RlCBUYEtJDo;?05dz#M4pSb*6zXo*)W`j6^QB%Zf)Cnp$T15tkaxY9^NfnIn zunG^S)g!3lFP-hB0$MhZn1H8c><*Mr&IZZrp^EN70{22giE^q^e}lor(2#mLARv&T zP?)R1q}7*hwp|#IqKa{oS)q zTKrVzSdk_s5%K$EMKWULD-=!CI$j+37&56_K z-ETH{faBnka!V+P`Gem2zWS2Q>g}Si(Bvy_L6SLP?ms=wBMRo>ZuhJxh?`wyT-;>T zp>pXIO`|`AbuKcnXs|+M5)r8~TO}qt@o&b=_=EYt(>^<6esJ0b-&H%i=Tm=9T9f=C znBfFvJu9*s@S_?6uyY0ft~7WoJfUf=a>qZd6>)47Kul0vS~irlq`>+>(U76xik7d? zG7u4}XdqzJ@L|IK4Tjb8(fJAj;#QNBR4z!;H_DJjrUnLNme^cxwW~F-Nxn)iJn|uF zQw?RK)f8>+C-OX=(TAvdd>k(DdMs3 za$5#&(Qg0d_32*_r=erW{Vl}XJ zT~BQNaeJP6SlSoKYXl<@J1X;Uq3(#9`8U~vGEso_`Y+v>Yr(V_ReCb&rf8^FLX{dk zIQXbi;E_B~TAKuPC2R$G4{HG}4(ufKMr1KrIzK*qTDC04wA6JIez$3ZbvUK%z@9|T zR1@pG;NVZ<3X`XE!Y^8)8$@#k`UTE9x2=nU=Yn9_Kv%vEhRlC z)ppccxmbj^MQslAzw{tc>Tsha$Ei!USTOocb#T9m<5O?B)czsl zjX=wP7Ymj9Xbg$89npjTz-MEcjPan>{L-x9rUZF=0(ccgw*oZHbf5tP{EHD8rU7er z(SpE7 zis2?;CJ*_95Pqs86o(F(Z;BmdZ=d<|x$Re|{jrAerf(%SvxCTOwKEyKo1gOh8wQ>( zxNfrJYzKaDli8#Uc0~7)?86}A9S!%a&anNS9XKCdz!i?#wPV_+qsg**QDTEh^9B2t zmwBx0pX>dOte%+JZe`g0`t*@DJMGReV=8?|b2+Jxi<;!b z?n}W`jEV#70Yba>R z72UIfj-NW_?3%AXAPLbM%+;YJ&01Myo!P>a?aLhH*KKL!Ld7+|WUMvpHm}BlX7ODsk)gGDOg+rqra{n~GNpKg5GmOxSs zUa-eh#5&tS5R}B}SKzs+49$ux{~-@6Gg6_b{x0NNMOgaP$nPkpMl%r)CWW~f2#)#Mw7H@>X(!KHGnKL zqP(CvvB!y3U(lQ{C0W>{`uM4iYc~gnZ4fg@1n`i;qT;$y_kwtUBS#E#xG5PjRvhle z5l=1@+%5)I3Sa+w@esSXq2cY1@<_t2fTuov{0TlloDfB<=0C-QkSi)Z>DToJPFwYfAG;RCM>U+pFKj_xZ(fu$&Ez$H?I`AGU8?jcsJsC5oKOk6j@Uh&pA-7foe65L+W=CZCCOt@pg8w+{%vMfrp{Yu@ zS~Ht|$BBJ-f{jJ((fTaD)79BYXM8SJOzSK385G9nKIOsk$Z`b~M)4s*mI_=q3n zBVx@2Nm-$p4KVeknPl3l@qV^;O{q9=U>o2R@GMh#OJv;ZR@%LZCc|4x`7|qV*Qg&h9+GI=5I*rJ{>5= zLvs?z5&##D+HTmnA#UQPcIuG-G^P`4N?@O0ywnnpb43LsZ~{hCl}YmeyM)Qdu!6h+ z7lq2;T@#NadLIfK#uogfAoY#ei+P^oQ~!j3cFXv|3M8L^!!lNrcKLeyy8 z{EhMg>E|8^kewBj`}evsg1lpP+Un9yoQcocjjk5%46tXYm$;Ow|nTrBkn5W#wASF zde7s(t?69it3F}P%BtAh>xBtVbi7}koM!eSDMQd%5L6i8jju}yNOkve+2+OML{t$M zYz4W{pyjr-NF7i!Hs@IMP+QN#f<{+nKDs2Raj zVW9(~?odPn^c~u12(5uAbhh+-^E#*j@q#1P=~X7w36??Z!Oa4H)A$v71B>_jJY6t9 zfAwqq!=BInkcOGb?&SqXUhqvrbDc7)(!$*oq|Z&Tj@p8_C;Mb;cArQM+aHo*<0vL? zqwIJZymdmEL3iJ5GGmWJ3lcjaGRL8^Z(P9g$Sz*bBGM2;|7-+1l@mxl+A}{ZqD?%* z%}2B-NT8aGleWyFyku-47w*@!Qu+y$cw;Nn$OD;5FQY4?tq|?oLhED3k_xt5Q1bAB z_4A?GFirw(mzcp0w_}4|%40Fqcu+Z@o)~p+ioIXg!)=j*Z7trsDPmHml1etF-~w7^ zP;u720<^Ic#hD*4@HoEx;0~`(Hpz*Lh`3GqS2Lir3A}oACmnN!fFze91Vkizn{z?-LkN! zJdurUu`+4Vs|b$6dH89~vv6f-V@W^y=myks)Cn_G>ChN19}T*D0w9C=8Re9sdV`gh$7T6I{}t+q zMix_{@9itp`_@U12k6S{^S)!*IEGH}k>-l1Y!*VKq)8#SK~tvT>2T5R3+SFPD^e+0wBwlSs0KsFvIJ1E-$KFb7EGGHd5es)A#+PBrY zuc91jTNsQ7$BUekOr$-S_;}7I7XAUHe4YbEX6+q^oOcP3H=e?497wWHrYFtI8OAhQ zzf5l+SAeWyCfs(Ev{2b+VZ`?ec2&eXoUfg7e20n3+iIEcdL~1+QZlt+N*wOYzP>$R zcq>R7(t)~@clbkC7*AjE$p2lL!vNnL39hQ-Krsp?Qn}W`gC7&W z0n!plLtWbNf)c!-)Cd$SQJfZuhLM17w6hq^MgGHLfM~&835#C(2VbGr`iqGP^?g{} z23#wZkcu-{1lmp7zDM0iQyD$lu;ZsVT&lOaVNU%eS#d5AA$g|mrpwk_ES3ZbkQl1O zg*(3%aVk_+1kuQdG8FjThFz%vLktbJAj=M1%wvFG@>EVa`-+Ap2#b{Z%_AH?B;fLV z4Rr)`vflvqGKLh>X|z`i-0a`H#DLy54wbjEDM+gPf^CRa5AaQ4puw#aAr@BZqXa4C zkOhg^Pb+raXm|AFA{{3mp5v|5n`beJ#?N-BY#WeHx0vH|W5`?GbmvK2>cZYI>jSQm zd!j0rqb=!GlW!*HQVEvltb@Wzq@#pkbzbylE(hOzWlbt{xRQyL__4kD!ncq-*am3K>pqjK zlbI#j;~Bs$&$XxOn>Dt$Pe`Qqrku;oq2gXS9eo*;8fYq76g;}mwtg@>IN4ik%}@TO zJGDN9uphJOrE$$|dM(SAHNc>flU*(*2s3lei1iG+s*pkcltq)cfyQsZsVH@qH316Mgpl{5VA9sTpp4`^qu(oxum-SQXqYe6L~A*AMk#( z->+juQPDK(;t{ z3bd%sEW+;0fSdk?vW*W!3}dq{!PCK?GfQYKt8(|8i_;%H6kI*-OwQYNKh1G?>L=dU z99yUJZtcByV$ZXpq*of_%r;$~Hr845W7tNKWQYDXFY{zkd-w~dK|ZA`Ip7?P#*Y#t zPT9>B6Q>l=_pkXFBtl#RTZ{&a+vYu>BO8+gcGkMzt31c;WY)a@$i{acdGevENL6sc z?AU8JVFE9EX_}ZA_o_iB%=Og^-b+GESd2;se(!nxm2FL}8C%*_`Dzups+4nt1}lSB zQ_5+khrF8{XYQ2CMm-qDB>=w!?kfw5qF8{!h^93BkHbTBG691PKfFM z(A)o=z`uD{&Od?ZB!VoiRu3s8hu7UihkJoQyH$3*!B!cumg?=vG7) z{&K>0PMi9xKSNpNxhteo_>|;;b}te8cd6CH?5>rsnbl8{oPyh~w-_0YJ;|&p;Vn#i zJ+31Bu!eQBSo8XLZfmU-S#-a{+rIcEYup>L%F?psdFLN7qD8yu&D#^Sxz|(=WvnOd z?U3P|50gA*TBJDj^Youw=7J=FY~Fm>r!XI)@f;~^u0wh zw5&#Vd2tp&UOtM$tzfeVSEbIuAzgJ?_=Efd!ZnI1hdV!k1jvMRT?-Gj6M5cFlspG9 z$zK7$GCc^A7#JLhlu$MO22G*?cIJ=lAOFJA3|>Y?7&1jqlx&@5$R1;glM- z?y^3|%Vl<`SE#B+E2Vi?!oBQB4@SFbwsjeh9`iDotND~XtCSOy%6%6xvsvs_E?dpMVLc$(9awso>IRN?620jn`gm6nDSxKfz|-& zDk^qy5-jv$Z!ZFu1+Wg{GRAtK?=WIzBgkv8cc6l>u=@|V>wkhFev$2SiZVI~$pJ0K z?Nb7PU_kf{~E2rkF;>CXk&+LCp zC3xP&*({&qD^;&2S52=ANHwl(c7d09m@-Gd=-OF*C`5Aegb;|bo};@XUI+4a(s5Jb zE_0hy1?fVIFt!&eMJb9)v}rro6RB|FYrwDH`&Y3mX^QvfK zr8jf5NWe1!;e%D?mDUTA^I@W?vPl61l@5sPEDV^TO{ehoD$3l!KC%{C=m*97_U!>I zhQn^)`-SY6a&`gr$lub)&>M*GY}p1|pBD=Ms)@m3bynJq#z%usM%t5 zF_bd^ae#KwA&@|#qu^2@b0MM<5Gh~fL0SBnh5kK8%Pt6xrd^&LVjTLpE-b+@x7#=luYMB2diol(&r5Vpzka%JLFUL0Bc^#q~d6`%0mS*yYVbc;O zgQ`E&Tf2I}PQk^Q7Hcn`+QD;Mk?`_qv;dLZp2Vx84uvh9R&e-Uh-#idVltgfeFxM{ z0LP7aG7irKy=$h@u`&;ej2lj)*Nu)2E2(0$Tm)`p&vqNGJdPEz~oqK_{i0oKZ zXz!et-75@xaqjmWt=(M*_dEf1}(k**ee44hG8?G5`QrqhCY1{qQO-ne)jD+me(ew9Lwh!3k-4e&$NVX{!1zP?@ z#b3C!dTVsTu7mudx#S1!hx69`U~!iHL-UFGnq>`0+@$zx8Nusi_Dy=3oR*E0JynmP$X zw**w2oaez(_n1Y>iNipV&8r>nR4(#L^gQ$YLU}?%>o=z8eB8VqGPC?I%{D*Bfxp-)0f2 zHrIM_>Dy0REGV63g+ge=ITxhtco^dAbYsu{Jrs{R8 zcREz=_!hPefX%PiYn zjVHWjoPU8-zSrj2=ib#Fch}E-$4w4rxjb9J!JVU|cNYOdK+PLN33bNag6b_o3V?Gf@-2as0 zLDGy7os^f3Fk#a5m;M57fJ^tA9@W9i%`hT{bM3zl+ZhvLT$+ZE0<}!D?ZLcO0Sr0xxb{GyNUVvS;Oqc zo2|_3;x3(Ww(WWq2Jy(m$8nDN`v;`kg!cZLv4Y>aP4?*?7$5ZP$E>Fz_nWpR@$T0Y z=-|cV!S>+deA=dv6sOR4j@fr>LyewX;Yn2H_$7RL$?P@zxqsH2H%C4{ZalTtfU(r& zDa_?i-Ji`>mod$U7?eG$|lc1V;2`x6ww zV2V(4iKCEd7|aB`uW*xSWP(y;CIc9Av=ISjuU=_USo_WYi0k#i^w8JhzjBzc?ezmy zZ@9lT~kjy5gzd28S-k7@6HLQ19y0ED1LHFCL5BAqxc%!Y=={Oa(vtU6E zGLSzSf4sroQ0?+hJmXYD-ukTtex&kQ`Lv4`(rcNUJE~JG4o9U=6%aET!>VP;0@Ia5 z&XEh7o-$6;>7;v-vA^u0O>ljCAoudg$Lkxcao&%DBMUFnT4y^A)O_A=e>;hHCYPnt zTclx3v|3$lnXt)MQ*bQ6(_$_UsW{TT)KCz4zQ)DVf&{N`yTz5FMWeUlcz|O)0DeG{ zKo{~+P7U?5Y?OD9^F~-jLf!)bjuu|`LCH9XqS#9vXb%wDZ3sk^qQHT%H$u#DWARZ= z-U5S@1!Y4V>Z^ghg?X+gQ;}PD`AMTVM<{=VWNxtw+g(8y>96xG{3Yp<)%b=*#bd|a z=?^n;@aul{gTGmn-3PDQX}F`$j`ZFCyxj6oL7Pr#{!hF-BzK|Zv$#1osmR6Sw-Q`v z>4wmP9zhik6gZUEb&al|^!XJ4hArO{P!3e(Q+RO~naz&f0K`hh%Ru*AE3*VUi+lF2 z3QavF%iZ#UTD9*wovK&0wo>rKE}2 zmEp;LNJi8Kf2(o1vZb;?{upV%F8!*pQY%B0c)++p4E;*r6?Y(gn2^%}M}d`*(CIBc-NF0-s0MM$YfO-UWHHL&&j_GI5xCW1&K$KT0}S?MG2pL*Kxq^j67i@@_JMK) z{H+>(Jp4JFRt{-OpI_9zZk9hxO}{J__{mryIY@tqp*h4Hze=y7(zyDb)rlRgQe;_i z)oIEyJNo15Yr1;pZ2jD0_XfCtK&f;^N<^y-th@oFR#WsJl$ZVl!{AMb<;)Ju93_L;-v#l<=VGils+)klmCPtqH9=1B zIu;rm&~`teoGM4(*8ryBD`jlJR1`P0(VkFP z6_0IYCZaV%WCn@0GCMZ2qwCaWK2b%`U{IxJx7aCk>n}3=-pGZz+{6nrdL4Dyfxq!; zR?wUG?32W|d(1j4EjLDcDkd;Vj*{nrPf?bC_Tf^#DZMLz-X-Jf(cVB|S2dQ;)xv}I z!DFF+fWnWR=|Ry_^PdvO8<%;*bs)RbJI-t+*TcTJ9tZVbEpWtOrc{X(^{|6+WWi { }); }); - describe('Recent Files', () => { + describe('on Recent Files', () => { beforeEach(async (done) => { await Utils.pressEscape(); await page.clickRecentFilesAndWait(); @@ -408,7 +408,7 @@ describe('Context menu actions - multiple selection : ', () => { }); }); - describe('Favorites', () => { + describe('on Favorites', () => { beforeEach(async (done) => { await Utils.pressEscape(); await page.clickFavoritesAndWait(); @@ -490,7 +490,7 @@ describe('Context menu actions - multiple selection : ', () => { }); }); - describe('Trash', () => { + describe('on Trash', () => { beforeEach(async (done) => { await Utils.pressEscape(); await page.clickTrashAndWait(); diff --git a/e2e/suites/info-drawer/comments.test.ts b/e2e/suites/info-drawer/comments.test.ts index 1bd8c446f3..b7a76fe6dd 100755 --- a/e2e/suites/info-drawer/comments.test.ts +++ b/e2e/suites/info-drawer/comments.test.ts @@ -35,6 +35,8 @@ describe('Comments', () => { const parent = `parent-${Utils.random()}`; let parentId; const file1 = `file1-${Utils.random()}.txt`; + const folder1 = `folder1-${Utils.random()}`; + const folder2 = `folder2-${Utils.random()}`; let folder2Id; const fileWith1Comment = `file1Comment-${Utils.random()}.txt`; let fileWith1CommentId; const fileWith2Comments = `file2Comments-${Utils.random()}.txt`; let fileWith2CommentsId; @@ -53,6 +55,7 @@ describe('Comments', () => { }; const infoDrawer = new InfoDrawer(); + const { commentsTab } = infoDrawer; const loginPage = new LoginPage(); const page = new BrowsingPage(); @@ -80,6 +83,10 @@ describe('Comments', () => { await apis.user.shared.shareFilesByIds([file2SharedId, fileWith1CommentId, fileWith2CommentsId]); await apis.user.favorites.addFavoritesByIds('file', [file2FavoritesId, fileWith1CommentId, fileWith2CommentsId]); + await apis.user.nodes.createFolder(folder1, parentId); + folder2Id = (await apis.user.nodes.createFolder(folder2, parentId)).entry.id; + await apis.user.favorites.addFavoriteById('folder', folder2Id); + await loginPage.loginWith(username); done(); }); @@ -96,11 +103,6 @@ describe('Comments', () => { done(); }); - afterEach(async (done) => { - await dataTable.clearSelection(); - done(); - }); - it('Comments tab default fields - [C299173]', async () => { await dataTable.selectItem(file1); await page.toolbar.clickViewDetails(); @@ -108,9 +110,9 @@ describe('Comments', () => { await infoDrawer.clickCommentsTab(); expect(await infoDrawer.getActiveTabTitle()).toBe('COMMENTS'); - expect(await infoDrawer.getCommentsTabHeaderText()).toBe('Comments (0)'); - expect(await infoDrawer.isCommentTextAreaDisplayed()).toBe(true, 'Comment field not present'); - expect(await infoDrawer.isAddCommentButtonEnabled()).toBe(false, 'Add comment button not disabled'); + expect(await commentsTab.getCommentsTabHeaderText()).toBe('Comments (0)'); + expect(await commentsTab.isCommentTextAreaDisplayed()).toBe(true, 'Comment field not present'); + expect(await commentsTab.isAddCommentButtonEnabled()).toBe(false, 'Add comment button not disabled'); }); it('Comment info display - [C280582]', async () => { @@ -119,15 +121,15 @@ describe('Comments', () => { await infoDrawer.waitForInfoDrawerToOpen(); await infoDrawer.clickCommentsTab(); - expect(await infoDrawer.getCommentsTabHeaderText()).toBe('Comments (1)'); - expect(await infoDrawer.isCommentTextAreaDisplayed()).toBe(true, 'Comment field not present'); - expect(await infoDrawer.isAddCommentButtonEnabled()).toBe(false, 'Add comment button not disabled'); + expect(await commentsTab.getCommentsTabHeaderText()).toBe('Comments (1)'); + expect(await commentsTab.isCommentTextAreaDisplayed()).toBe(true, 'Comment field not present'); + expect(await commentsTab.isAddCommentButtonEnabled()).toBe(false, 'Add comment button not disabled'); - expect(await infoDrawer.isCommentDisplayed(commentFile1Entry.id)).toBe(true, `Comment with id: ${commentFile1Entry.id} not displayed`); - expect(await infoDrawer.getCommentText(commentFile1Entry.id)).toBe(commentFile1Entry.content, 'Incorrect comment text'); - expect(await infoDrawer.getCommentUserName(commentFile1Entry.id)).toBe(`${username} ${username}`, 'Incorrect comment user'); - expect(await infoDrawer.getCommentTime(commentFile1Entry.id)).toBe(moment(commentFile1Entry.createdAt).fromNow(), 'Incorrect comment created time'); - expect(await infoDrawer.isCommentUserAvatarDisplayed(commentFile1Entry.id)).toBe(true, 'User avatar not displayed'); + expect(await commentsTab.isCommentDisplayed(commentFile1Entry.id)).toBe(true, `Comment with id: ${commentFile1Entry.id} not displayed`); + expect(await commentsTab.getCommentText(commentFile1Entry.id)).toBe(commentFile1Entry.content, 'Incorrect comment text'); + expect(await commentsTab.getCommentUserName(commentFile1Entry.id)).toBe(`${username} ${username}`, 'Incorrect comment user'); + expect(await commentsTab.getCommentTime(commentFile1Entry.id)).toBe(moment(commentFile1Entry.createdAt).fromNow(), 'Incorrect comment created time'); + expect(await commentsTab.isCommentUserAvatarDisplayed(commentFile1Entry.id)).toBe(true, 'User avatar not displayed'); }); it('Comments are displayed ordered by created date in descending order - [C280583]', async () => { @@ -136,8 +138,8 @@ describe('Comments', () => { await infoDrawer.waitForInfoDrawerToOpen(); await infoDrawer.clickCommentsTab(); - expect(await infoDrawer.getNthCommentId(1)).toContain(comment2File2Entry.id); - expect(await infoDrawer.getNthCommentId(2)).toContain(comment1File2Entry.id); + expect(await commentsTab.getNthCommentId(1)).toContain(comment2File2Entry.id); + expect(await commentsTab.getNthCommentId(2)).toContain(comment1File2Entry.id); }); it('Total number of comments is displayed - [C280585]', async () => { @@ -146,7 +148,7 @@ describe('Comments', () => { await infoDrawer.waitForInfoDrawerToOpen(); await infoDrawer.clickCommentsTab(); - expect(await infoDrawer.getCommentsTabHeaderText()).toBe('Comments (2)'); + expect(await commentsTab.getCommentsTabHeaderText()).toBe('Comments (2)'); }); it('Add button is enabled when typing in the comment field - [C280589]', async () => { @@ -155,25 +157,40 @@ describe('Comments', () => { await infoDrawer.waitForInfoDrawerToOpen(); await infoDrawer.clickCommentsTab(); - expect(await infoDrawer.isAddCommentButtonEnabled()).toBe(false, 'Add comment button not disabled'); + expect(await commentsTab.isAddCommentButtonEnabled()).toBe(false, 'Add comment button not disabled'); - await infoDrawer.typeComment('my comment'); - expect(await infoDrawer.isAddCommentButtonEnabled()).toBe(true, 'Add comment button not enabled'); + await commentsTab.typeComment('my comment'); + expect(await commentsTab.isAddCommentButtonEnabled()).toBe(true, 'Add comment button not enabled'); }); - it('Add a comment - [C280590]', async () => { + it('Add a comment on a file - [C280590]', async () => { const myComment = 'my comment'; await dataTable.selectItem(file2Personal); await page.toolbar.clickViewDetails(); await infoDrawer.waitForInfoDrawerToOpen(); await infoDrawer.clickCommentsTab(); - await infoDrawer.typeComment(myComment); - await infoDrawer.clickAddButton(); + await commentsTab.typeComment(myComment); + await commentsTab.clickAddButton(); - expect(await infoDrawer.getCommentsTabHeaderText()).toBe('Comments (1)'); - expect(await infoDrawer.isCommentDisplayed()).toBe(true, `Comment not displayed`); - expect(await infoDrawer.getCommentText()).toBe(myComment, 'Incorrect comment text'); + expect(await commentsTab.getCommentsTabHeaderText()).toBe('Comments (1)'); + expect(await commentsTab.isCommentDisplayed()).toBe(true, `Comment not displayed`); + expect(await commentsTab.getCommentText()).toBe(myComment, 'Incorrect comment text'); + }); + + it('Add a comment on a folder - [C299208]', async () => { + const myComment = 'my comment'; + + await dataTable.selectItem(folder1); + await page.toolbar.clickViewDetails(); + await infoDrawer.waitForInfoDrawerToOpen(); + await infoDrawer.clickCommentsTab(); + await commentsTab.typeComment(myComment); + await commentsTab.clickAddButton(); + + expect(await commentsTab.getCommentsTabHeaderText()).toBe('Comments (1)'); + expect(await commentsTab.isCommentDisplayed()).toBe(true, `Comment not displayed`); + expect(await commentsTab.getCommentText()).toBe(myComment, 'Incorrect comment text'); }); it('Escape key clears the text when focus is on the textarea - [C280591]', async () => { @@ -181,19 +198,19 @@ describe('Comments', () => { await page.toolbar.clickViewDetails(); await infoDrawer.waitForInfoDrawerToOpen(); await infoDrawer.clickCommentsTab(); - await infoDrawer.typeComment('myComment'); + await commentsTab.typeComment('myComment'); - expect(await infoDrawer.getCommentTextFromTextArea()).toBe('myComment'); + expect(await commentsTab.getCommentTextFromTextArea()).toBe('myComment'); await Utils.pressEscape(); - expect(await infoDrawer.getCommentTextFromTextArea()).toBe(''); + expect(await commentsTab.getCommentTextFromTextArea()).toBe(''); }); }); describe('from Favorites', () => { beforeAll(async (done) => { - await apis.user.favorites.waitForApi({ expect: 3 }); + await apis.user.favorites.waitForApi({ expect: 4 }); done(); }); @@ -203,7 +220,7 @@ describe('Comments', () => { }); afterEach(async (done) => { - await dataTable.clearSelection(); + await page.clickPersonalFiles(); done(); }); @@ -213,16 +230,16 @@ describe('Comments', () => { await infoDrawer.waitForInfoDrawerToOpen(); await infoDrawer.clickCommentsTab(); - expect(await infoDrawer.getCommentsTabHeaderText()).toBe('Comments (1)'); - expect(await infoDrawer.isCommentTextAreaDisplayed()).toBe(true, 'Comment field not present'); - expect(await infoDrawer.isAddCommentButtonEnabled()).toBe(false, 'Add comment button not disabled'); + expect(await commentsTab.getCommentsTabHeaderText()).toBe('Comments (1)'); + expect(await commentsTab.isCommentTextAreaDisplayed()).toBe(true, 'Comment field not present'); + expect(await commentsTab.isAddCommentButtonEnabled()).toBe(false, 'Add comment button not disabled'); - expect(await infoDrawer.isCommentDisplayed(commentFile1Entry.id)).toBe(true, `Comment with id: ${commentFile1Entry.id} not displayed`); - expect(await infoDrawer.getCommentText(commentFile1Entry.id)).toBe(commentFile1Entry.content, 'Incorrect comment text'); - expect(await infoDrawer.getCommentUserName(commentFile1Entry.id)).toBe(`${username} ${username}`, 'Incorrect comment user'); + expect(await commentsTab.isCommentDisplayed(commentFile1Entry.id)).toBe(true, `Comment with id: ${commentFile1Entry.id} not displayed`); + expect(await commentsTab.getCommentText(commentFile1Entry.id)).toBe(commentFile1Entry.content, 'Incorrect comment text'); + expect(await commentsTab.getCommentUserName(commentFile1Entry.id)).toBe(`${username} ${username}`, 'Incorrect comment user'); // ACA-2348 expect broken because of parallel test suites - // expect(await infoDrawer.getCommentTime(commentFile1Entry.id)).toBe(moment(commentFile1Entry.createdAt).fromNow(), 'Incorrect comment created time'); - expect(await infoDrawer.isCommentUserAvatarDisplayed(commentFile1Entry.id)).toBe(true, 'User avatar not displayed'); + // expect(await commentsTab.getCommentTime(commentFile1Entry.id)).toBe(moment(commentFile1Entry.createdAt).fromNow(), 'Incorrect comment created time'); + expect(await commentsTab.isCommentUserAvatarDisplayed(commentFile1Entry.id)).toBe(true, 'User avatar not displayed'); }); it('Comments are displayed ordered by created date in descending order - [C299197]', async () => { @@ -231,8 +248,8 @@ describe('Comments', () => { await infoDrawer.waitForInfoDrawerToOpen(); await infoDrawer.clickCommentsTab(); - expect(await infoDrawer.getNthCommentId(1)).toContain(comment2File2Entry.id); - expect(await infoDrawer.getNthCommentId(2)).toContain(comment1File2Entry.id); + expect(await commentsTab.getNthCommentId(1)).toContain(comment2File2Entry.id); + expect(await commentsTab.getNthCommentId(2)).toContain(comment1File2Entry.id); }); it('Total number of comments is displayed - [C299198]', async () => { @@ -241,22 +258,37 @@ describe('Comments', () => { await infoDrawer.waitForInfoDrawerToOpen(); await infoDrawer.clickCommentsTab(); - expect(await infoDrawer.getCommentsTabHeaderText()).toBe('Comments (2)'); + expect(await commentsTab.getCommentsTabHeaderText()).toBe('Comments (2)'); }); - it('Add a comment - [C299199]', async () => { + it('Add a comment on a file - [C299199]', async () => { const myComment = 'my comment'; await dataTable.selectItem(file2Favorites); await page.toolbar.clickViewDetails(); await infoDrawer.waitForInfoDrawerToOpen(); await infoDrawer.clickCommentsTab(); - await infoDrawer.typeComment(myComment); - await infoDrawer.clickAddButton(); + await commentsTab.typeComment(myComment); + await commentsTab.clickAddButton(); + + expect(await commentsTab.getCommentsTabHeaderText()).toBe('Comments (1)'); + expect(await commentsTab.isCommentDisplayed()).toBe(true, `Comment not displayed`); + expect(await commentsTab.getCommentText()).toBe(myComment, 'Incorrect comment text'); + }); + + it('Add a comment on a folder - [C299209]', async () => { + const myComment = 'my comment'; + + await dataTable.selectItem(folder2); + await page.toolbar.clickViewDetails(); + await infoDrawer.waitForInfoDrawerToOpen(); + await infoDrawer.clickCommentsTab(); + await commentsTab.typeComment(myComment); + await commentsTab.clickAddButton(); - expect(await infoDrawer.getCommentsTabHeaderText()).toBe('Comments (1)'); - expect(await infoDrawer.isCommentDisplayed()).toBe(true, `Comment not displayed`); - expect(await infoDrawer.getCommentText()).toBe(myComment, 'Incorrect comment text'); + expect(await commentsTab.getCommentsTabHeaderText()).toBe('Comments (1)'); + expect(await commentsTab.isCommentDisplayed()).toBe(true, `Comment not displayed`); + expect(await commentsTab.getCommentText()).toBe(myComment, 'Incorrect comment text'); }); }); @@ -272,7 +304,7 @@ describe('Comments', () => { }); afterEach(async (done) => { - await dataTable.clearSelection(); + await page.clickPersonalFiles(); done(); }); @@ -282,15 +314,15 @@ describe('Comments', () => { await infoDrawer.waitForInfoDrawerToOpen(); await infoDrawer.clickCommentsTab(); - expect(await infoDrawer.getCommentsTabHeaderText()).toBe('Comments (1)'); - expect(await infoDrawer.isCommentTextAreaDisplayed()).toBe(true, 'Comment field not present'); - expect(await infoDrawer.isAddCommentButtonEnabled()).toBe(false, 'Add comment button not disabled'); + expect(await commentsTab.getCommentsTabHeaderText()).toBe('Comments (1)'); + expect(await commentsTab.isCommentTextAreaDisplayed()).toBe(true, 'Comment field not present'); + expect(await commentsTab.isAddCommentButtonEnabled()).toBe(false, 'Add comment button not disabled'); - expect(await infoDrawer.isCommentDisplayed(commentFile1Entry.id)).toBe(true, `Comment with id: ${commentFile1Entry.id} not displayed`); - expect(await infoDrawer.getCommentText(commentFile1Entry.id)).toBe(commentFile1Entry.content, 'Incorrect comment text'); - expect(await infoDrawer.getCommentUserName(commentFile1Entry.id)).toBe(`${username} ${username}`, 'Incorrect comment user'); - expect(await infoDrawer.getCommentTime(commentFile1Entry.id)).toBe(moment(commentFile1Entry.createdAt).fromNow(), 'Incorrect comment created time'); - expect(await infoDrawer.isCommentUserAvatarDisplayed(commentFile1Entry.id)).toBe(true, 'User avatar not displayed'); + expect(await commentsTab.isCommentDisplayed(commentFile1Entry.id)).toBe(true, `Comment with id: ${commentFile1Entry.id} not displayed`); + expect(await commentsTab.getCommentText(commentFile1Entry.id)).toBe(commentFile1Entry.content, 'Incorrect comment text'); + expect(await commentsTab.getCommentUserName(commentFile1Entry.id)).toBe(`${username} ${username}`, 'Incorrect comment user'); + expect(await commentsTab.getCommentTime(commentFile1Entry.id)).toBe(moment(commentFile1Entry.createdAt).fromNow(), 'Incorrect comment created time'); + expect(await commentsTab.isCommentUserAvatarDisplayed(commentFile1Entry.id)).toBe(true, 'User avatar not displayed'); }); it('Comments are displayed ordered by created date in descending order - [C299189]', async () => { @@ -299,8 +331,8 @@ describe('Comments', () => { await infoDrawer.waitForInfoDrawerToOpen(); await infoDrawer.clickCommentsTab(); - expect(await infoDrawer.getNthCommentId(1)).toContain(comment2File2Entry.id); - expect(await infoDrawer.getNthCommentId(2)).toContain(comment1File2Entry.id); + expect(await commentsTab.getNthCommentId(1)).toContain(comment2File2Entry.id); + expect(await commentsTab.getNthCommentId(2)).toContain(comment1File2Entry.id); }); it('Total number of comments is displayed - [C299190]', async () => { @@ -309,22 +341,22 @@ describe('Comments', () => { await infoDrawer.waitForInfoDrawerToOpen(); await infoDrawer.clickCommentsTab(); - expect(await infoDrawer.getCommentsTabHeaderText()).toBe('Comments (2)'); + expect(await commentsTab.getCommentsTabHeaderText()).toBe('Comments (2)'); }); - it('Add a comment - [C299191]', async () => { + it('Add a comment on a file - [C299191]', async () => { const myComment = 'my comment'; await dataTable.selectItem(file2Shared); await page.toolbar.clickViewDetails(); await infoDrawer.waitForInfoDrawerToOpen(); await infoDrawer.clickCommentsTab(); - await infoDrawer.typeComment(myComment); - await infoDrawer.clickAddButton(); + await commentsTab.typeComment(myComment); + await commentsTab.clickAddButton(); - expect(await infoDrawer.getCommentsTabHeaderText()).toBe('Comments (1)'); - expect(await infoDrawer.isCommentDisplayed()).toBe(true, `Comment not displayed`); - expect(await infoDrawer.getCommentText()).toBe(myComment, 'Incorrect comment text'); + expect(await commentsTab.getCommentsTabHeaderText()).toBe('Comments (1)'); + expect(await commentsTab.isCommentDisplayed()).toBe(true, `Comment not displayed`); + expect(await commentsTab.getCommentText()).toBe(myComment, 'Incorrect comment text'); }); }); @@ -340,7 +372,7 @@ describe('Comments', () => { }); afterEach(async (done) => { - await dataTable.clearSelection(); + await page.clickPersonalFiles(); done(); }); @@ -350,15 +382,15 @@ describe('Comments', () => { await infoDrawer.waitForInfoDrawerToOpen(); await infoDrawer.clickCommentsTab(); - expect(await infoDrawer.getCommentsTabHeaderText()).toBe('Comments (1)'); - expect(await infoDrawer.isCommentTextAreaDisplayed()).toBe(true, 'Comment field not present'); - expect(await infoDrawer.isAddCommentButtonEnabled()).toBe(false, 'Add comment button not disabled'); + expect(await commentsTab.getCommentsTabHeaderText()).toBe('Comments (1)'); + expect(await commentsTab.isCommentTextAreaDisplayed()).toBe(true, 'Comment field not present'); + expect(await commentsTab.isAddCommentButtonEnabled()).toBe(false, 'Add comment button not disabled'); - expect(await infoDrawer.isCommentDisplayed(commentFile1Entry.id)).toBe(true, `Comment with id: ${commentFile1Entry.id} not displayed`); - expect(await infoDrawer.getCommentText(commentFile1Entry.id)).toBe(commentFile1Entry.content, 'Incorrect comment text'); - expect(await infoDrawer.getCommentUserName(commentFile1Entry.id)).toBe(`${username} ${username}`, 'Incorrect comment user'); - expect(await infoDrawer.getCommentTime(commentFile1Entry.id)).toBe(moment(commentFile1Entry.createdAt).fromNow(), 'Incorrect comment created time'); - expect(await infoDrawer.isCommentUserAvatarDisplayed(commentFile1Entry.id)).toBe(true, 'User avatar not displayed'); + expect(await commentsTab.isCommentDisplayed(commentFile1Entry.id)).toBe(true, `Comment with id: ${commentFile1Entry.id} not displayed`); + expect(await commentsTab.getCommentText(commentFile1Entry.id)).toBe(commentFile1Entry.content, 'Incorrect comment text'); + expect(await commentsTab.getCommentUserName(commentFile1Entry.id)).toBe(`${username} ${username}`, 'Incorrect comment user'); + expect(await commentsTab.getCommentTime(commentFile1Entry.id)).toBe(moment(commentFile1Entry.createdAt).fromNow(), 'Incorrect comment created time'); + expect(await commentsTab.isCommentUserAvatarDisplayed(commentFile1Entry.id)).toBe(true, 'User avatar not displayed'); }); it('Comments are displayed ordered by created date in descending order - [C299193]', async () => { @@ -367,8 +399,8 @@ describe('Comments', () => { await infoDrawer.waitForInfoDrawerToOpen(); await infoDrawer.clickCommentsTab(); - expect(await infoDrawer.getNthCommentId(1)).toContain(comment2File2Entry.id); - expect(await infoDrawer.getNthCommentId(2)).toContain(comment1File2Entry.id); + expect(await commentsTab.getNthCommentId(1)).toContain(comment2File2Entry.id); + expect(await commentsTab.getNthCommentId(2)).toContain(comment1File2Entry.id); }); it('Total number of comments is displayed - [C299194]', async () => { @@ -377,22 +409,22 @@ describe('Comments', () => { await infoDrawer.waitForInfoDrawerToOpen(); await infoDrawer.clickCommentsTab(); - expect(await infoDrawer.getCommentsTabHeaderText()).toBe('Comments (2)'); + expect(await commentsTab.getCommentsTabHeaderText()).toBe('Comments (2)'); }); - it('Add a comment - [C299195]', async () => { + it('Add a comment on a file - [C299195]', async () => { const myComment = 'my comment'; await dataTable.selectItem(file2Recent); await page.toolbar.clickViewDetails(); await infoDrawer.waitForInfoDrawerToOpen(); await infoDrawer.clickCommentsTab(); - await infoDrawer.typeComment(myComment); - await infoDrawer.clickAddButton(); + await commentsTab.typeComment(myComment); + await commentsTab.clickAddButton(); - expect(await infoDrawer.getCommentsTabHeaderText()).toBe('Comments (1)'); - expect(await infoDrawer.isCommentDisplayed()).toBe(true, `Comment not displayed`); - expect(await infoDrawer.getCommentText()).toBe(myComment, 'Incorrect comment text'); + expect(await commentsTab.getCommentsTabHeaderText()).toBe('Comments (1)'); + expect(await commentsTab.isCommentDisplayed()).toBe(true, `Comment not displayed`); + expect(await commentsTab.getCommentText()).toBe(myComment, 'Incorrect comment text'); }); }); diff --git a/e2e/suites/info-drawer/file-folder-properties.test.ts b/e2e/suites/info-drawer/file-folder-properties.test.ts new file mode 100755 index 0000000000..16ac67113c --- /dev/null +++ b/e2e/suites/info-drawer/file-folder-properties.test.ts @@ -0,0 +1,249 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2019 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { LoginPage, BrowsingPage } from '../../pages/pages'; +import { RepoClient } from '../../utilities/repo-client/repo-client'; +import { InfoDrawer } from './../../components/info-drawer/info-drawer'; +import { Utils } from '../../utilities/utils'; +import { FILES } from '../../configs'; +import * as moment from 'moment'; + +describe('File / Folder properties', () => { + const username = `user1-${Utils.random()}`; + + const parent = `parent-${Utils.random()}`; let parentId; + + const file1 = { + name: `file1-${Utils.random()}.txt`, + title: 'file title', + description: 'file description', + author: 'file author' + }; + let file1Id; + + const image1 = { + name: FILES.jpgFile, + title: 'image title', + description: 'image description', + author: 'image author' + } + let image1Id; + + const folder1 = { + name: `folder1-${Utils.random()}`, + title: 'folder title', + description: 'folder description', + author: 'folder author' + }; + let folder1Id; + + const apis = { + admin: new RepoClient(), + user: new RepoClient(username, username) + }; + + const infoDrawer = new InfoDrawer(); + const { propertiesTab } = infoDrawer; + + const loginPage = new LoginPage(); + const page = new BrowsingPage(); + const { dataTable } = page; + + beforeAll(async (done) => { + await apis.admin.people.createUser({ username }); + parentId = (await apis.user.nodes.createFolder(parent)).entry.id; + file1Id = (await apis.user.nodes.createFile(file1.name, parentId, file1.title, file1.description, file1.author)).entry.id; + folder1Id = (await apis.user.nodes.createFolder(folder1.name, parentId, folder1.title, folder1.description, folder1.author)).entry.id; + image1Id = (await apis.user.upload.uploadFile(image1.name, parentId)).entry.id; + + await loginPage.loginWith(username); + done(); + }); + + afterAll(async (done) => { + await apis.user.nodes.deleteNodeById(parentId); + done(); + }); + + beforeEach(async (done) => { + await page.clickPersonalFilesAndWait(); + await dataTable.doubleClickOnRowByName(parent); + done(); + }); + + describe('View properties', () => { + it('Default tabs - [C299162]', async () => { + await dataTable.selectItem(file1.name); + await page.toolbar.clickViewDetails(); + await infoDrawer.waitForInfoDrawerToOpen(); + + expect(await infoDrawer.getHeaderTitle()).toEqual('Details'); + expect(await infoDrawer.isPropertiesTabDisplayed()).toBe(true, 'Properties tab is not displayed'); + expect(await infoDrawer.isCommentsTabDisplayed()).toBe(true, 'Comments tab is not displayed'); + expect(await infoDrawer.getTabsCount()).toBe(2, 'Incorrect number of tabs'); + }); + + it('File properties - [C269003]', async () => { + const apiProps = await apis.user.nodes.getNodeById(file1Id); + + const expectedPropLabels = [ + 'Name', + 'Title', + 'Creator', + 'Created Date', + 'Size', + 'Modifier', + 'Modified Date', + 'Mimetype', + 'Author', + 'Description' + ]; + const expectedPropValues = [ + file1.name, + file1.title, + apiProps.entry.createdByUser.displayName, + moment(apiProps.entry.createdAt).format('MMM DD YYYY'), + `${apiProps.entry.content.sizeInBytes} Bytes`, + apiProps.entry.modifiedByUser.displayName, + moment(apiProps.entry.modifiedAt).format('MMM DD YYYY'), + apiProps.entry.content.mimeTypeName, + file1.author, + file1.description + ]; + + await dataTable.selectItem(file1.name); + await page.toolbar.clickViewDetails(); + await infoDrawer.waitForInfoDrawerToOpen(); + + expect(await propertiesTab.getVisiblePropertiesLabels()).toEqual(expectedPropLabels, 'Incorrect properties displayed'); + expect(await propertiesTab.getVisiblePropertiesValues()).toEqual(expectedPropValues, 'Incorrect properties values'); + expect(await propertiesTab.isEditPropertiesButtonEnabled()).toBe(true, 'Edit button not enabled'); + expect(await propertiesTab.isLessInfoButtonEnabled()).toBe(true, 'Less information button not enabled'); + }); + + it('Folder properties - [C307106]', async () => { + const apiProps = await apis.user.nodes.getNodeById(folder1Id); + + const expectedPropLabels = [ + 'Name', + 'Title', + 'Creator', + 'Created Date', + 'Modifier', + 'Modified Date', + 'Author', + 'Description' + ]; + const expectedPropValues = [ + folder1.name, + folder1.title, + apiProps.entry.createdByUser.displayName, + moment(apiProps.entry.createdAt).format('MMM DD YYYY'), + apiProps.entry.modifiedByUser.displayName, + moment(apiProps.entry.modifiedAt).format('MMM DD YYYY'), + folder1.author, + folder1.description + ]; + + await dataTable.selectItem(folder1.name); + await page.toolbar.clickViewDetails(); + await infoDrawer.waitForInfoDrawerToOpen(); + + expect(await propertiesTab.getVisiblePropertiesLabels()).toEqual(expectedPropLabels, 'Incorrect properties displayed'); + expect(await propertiesTab.getVisiblePropertiesValues()).toEqual(expectedPropValues, 'Incorrect properties values'); + expect(await propertiesTab.isEditPropertiesButtonEnabled()).toBe(true, 'Edit button not enabled'); + expect(await propertiesTab.isLessInfoButtonEnabled()).toBe(true, 'Less information button not enabled'); + }); + + it('Less / More information buttons - [C269004]', async () => { + await dataTable.selectItem(file1.name); + await page.toolbar.clickViewDetails(); + await infoDrawer.waitForInfoDrawerToOpen(); + + expect(await propertiesTab.isLessInfoButtonEnabled()).toBe(true, 'Less information button not enabled'); + expect(await propertiesTab.isPropertiesListExpanded()).toBe(true, 'Properties list not expanded'); + + await propertiesTab.clickLessInformationButton(); + + expect(await propertiesTab.isLessInfoButtonDisplayed()).toBe(false, 'Less information button displayed'); + expect(await propertiesTab.isMoreInfoButtonEnabled()).toBe(true, 'More information button not enabled'); + expect(await propertiesTab.isPropertiesListExpanded()).toBe(false, 'Properties list expanded'); + + await propertiesTab.clickMoreInformationButton(); + + expect(await propertiesTab.isMoreInfoButtonDisplayed()).toBe(false, 'More information button displayed'); + expect(await propertiesTab.isLessInfoButtonEnabled()).toBe(true, 'Less information button not enabled'); + expect(await propertiesTab.isPropertiesListExpanded()).toBe(true, 'Properties list not expanded'); + }); + + it('Image properties - [C269007]', async () => { + const apiProps = await apis.user.nodes.getNodeById(image1Id); + + const expectedPropLabels = [ + 'Image Width', + 'Image Height', + 'Date and Time', + 'Exposure Time', + 'F Number', + 'Flash Activated', + 'Focal Length', + 'ISO Speed', + 'Orientation', + 'Camera Manufacturer', + 'Camera Model', + 'Camera Software' + ]; + const expectedPropValues = [ + apiProps.entry.properties['exif:pixelXDimension'].toString(), + apiProps.entry.properties['exif:pixelYDimension'].toString(), + moment(apiProps.entry.properties['exif:dateTimeOriginal']).format('MMM DD YYYY H:mm'), + apiProps.entry.properties['exif:exposureTime'].toString(), + apiProps.entry.properties['exif:fNumber'].toString(), + apiProps.entry.properties['exif:flash'], + apiProps.entry.properties['exif:focalLength'].toString(), + apiProps.entry.properties['exif:isoSpeedRatings'], + (apiProps.entry.properties['exif:orientation']).toString(), + apiProps.entry.properties['exif:manufacturer'], + apiProps.entry.properties['exif:model'], + apiProps.entry.properties['exif:software'] + ]; + + await dataTable.selectItem(image1.name); + await page.toolbar.clickViewDetails(); + await infoDrawer.waitForInfoDrawerToOpen(); + + await propertiesTab.clickLessInformationButton(); + await propertiesTab.clickImagePropertiesPanel(); + await propertiesTab.waitForImagePropertiesPanelToExpand(); + + expect(await propertiesTab.isImagePropertiesPanelDisplayed()).toBe(true, 'Image properties panel not displayed'); + expect(await propertiesTab.getVisiblePropertiesLabels()).toEqual(expectedPropLabels, 'Incorrect properties displayed'); + expect(await propertiesTab.getVisiblePropertiesValues()).toEqual(expectedPropValues, 'Incorrect properties values'); + expect(await propertiesTab.isEditPropertiesButtonEnabled()).toBe(true, 'Edit button not enabled'); + expect(await propertiesTab.isMoreInfoButtonEnabled()).toBe(true, 'More information button not enabled'); + }); + }); + +}); diff --git a/e2e/suites/info-drawer/general.test.ts b/e2e/suites/info-drawer/general.test.ts index 4add293f9b..4465e5f55c 100755 --- a/e2e/suites/info-drawer/general.test.ts +++ b/e2e/suites/info-drawer/general.test.ts @@ -76,15 +76,15 @@ describe('General', () => { done(); }); - it('Info drawer for a file - default tabs - [C299162]', async () => { + it('Info drawer closes on page refresh - [C268999]', async () => { await dataTable.selectItem(file1); await page.toolbar.clickViewDetails(); - await infoDrawer.waitForInfoDrawerToOpen(); + expect(await infoDrawer.isOpen()).toBe(true, 'Info drawer not open'); - expect(await infoDrawer.getHeaderTitle()).toEqual('Details'); - expect(await infoDrawer.isPropertiesTabDisplayed()).toBe(true, 'Properties tab is not displayed'); - expect(await infoDrawer.isCommentsTabDisplayed()).toBe(true, 'Comments tab is not displayed'); - expect(await infoDrawer.getTabsCount()).toBe(2, 'Incorrect number of tabs'); + await page.refresh(); + await dataTable.waitForBody(); + + expect(await infoDrawer.isOpen()).toBe(false, 'Info drawer open'); }); }); diff --git a/e2e/suites/info-drawer/library-properties.test.ts b/e2e/suites/info-drawer/library-properties.test.ts index 032db8baaa..29518cc14d 100755 --- a/e2e/suites/info-drawer/library-properties.test.ts +++ b/e2e/suites/info-drawer/library-properties.test.ts @@ -62,6 +62,7 @@ describe('Library properties', () => { }; const infoDrawer = new InfoDrawer(); + const { aboutTab } = infoDrawer; const loginPage = new LoginPage(); const page = new BrowsingPage(); @@ -108,17 +109,17 @@ describe('Library properties', () => { expect(await infoDrawer.getHeaderTitle()).toEqual('Details'); expect(await infoDrawer.isAboutTabDisplayed()).toBe(true, 'About tab is not displayed'); - expect(await infoDrawer.isNameDisplayed()).toBe(true, 'Name field not displayed'); - expect(await infoDrawer.isLibraryIdDisplayed()).toBe(true, 'Library ID field not displayed'); - expect(await infoDrawer.isVisibilityDisplayed()).toBe(true, 'Visibility field not displayed'); - expect(await infoDrawer.isDescriptionDisplayed()).toBe(true, 'Description field not displayed'); + expect(await aboutTab.isNameDisplayed()).toBe(true, 'Name field not displayed'); + expect(await aboutTab.isLibraryIdDisplayed()).toBe(true, 'Library ID field not displayed'); + expect(await aboutTab.isVisibilityDisplayed()).toBe(true, 'Visibility field not displayed'); + expect(await aboutTab.isDescriptionDisplayed()).toBe(true, 'Description field not displayed'); - expect(await infoDrawer.getName()).toEqual(site.name); - expect(await infoDrawer.getLibraryId()).toEqual(site.id); - expect((await infoDrawer.getVisibility()).toLowerCase()).toEqual((site.visibility).toLowerCase()); - expect(await infoDrawer.getDescription()).toEqual(site.description); + expect(await aboutTab.getName()).toEqual(site.name); + expect(await aboutTab.getLibraryId()).toEqual(site.id); + expect((await aboutTab.getVisibility()).toLowerCase()).toEqual((site.visibility).toLowerCase()); + expect(await aboutTab.getDescription()).toEqual(site.description); - expect(await infoDrawer.isEditDisplayed()).toBe(true, 'Edit action is not displayed'); + expect(await aboutTab.isEditLibraryPropertiesDisplayed()).toBe(true, 'Edit action is not displayed'); }); it('Editable properties - [C289338]', async () => { @@ -126,18 +127,18 @@ describe('Library properties', () => { await page.toolbar.clickViewDetails(); await infoDrawer.waitForInfoDrawerToOpen(); - expect(await infoDrawer.isEditEnabled()).toBe(true, 'Edit action is not enabled'); - await infoDrawer.clickEdit(); + expect(await aboutTab.isEditLibraryPropertiesEnabled()).toBe(true, 'Edit action is not enabled'); + await aboutTab.clickEditLibraryProperties(); - expect(await infoDrawer.isNameEnabled()).toBe(true, 'Name field not enabled'); - expect(await infoDrawer.isLibraryIdEnabled()).toBe(false, 'Library ID field not disabled'); - expect(await infoDrawer.isVisibilityEnabled()).toBe(true, 'Visibility field not enabled'); - expect(await infoDrawer.isDescriptionEnabled()).toBe(true, 'Description field not enabled'); + expect(await aboutTab.isNameEnabled()).toBe(true, 'Name field not enabled'); + expect(await aboutTab.isLibraryIdEnabled()).toBe(false, 'Library ID field not disabled'); + expect(await aboutTab.isVisibilityEnabled()).toBe(true, 'Visibility field not enabled'); + expect(await aboutTab.isDescriptionEnabled()).toBe(true, 'Description field not enabled'); - expect(await infoDrawer.isCancelDisplayed()).toBe(true, 'Cancel button not displayed'); - expect(await infoDrawer.isUpdateDisplayed()).toBe(true, 'Update button not displayed'); - expect(await infoDrawer.isCancelEnabled()).toBe(true, 'Cancel button not enabled'); - expect(await infoDrawer.isUpdateEnabled()).toBe(false, 'Update button not disabled'); + expect(await aboutTab.isCancelDisplayed()).toBe(true, 'Cancel button not displayed'); + expect(await aboutTab.isUpdateDisplayed()).toBe(true, 'Update button not displayed'); + expect(await aboutTab.isCancelEnabled()).toBe(true, 'Cancel button not enabled'); + expect(await aboutTab.isUpdateEnabled()).toBe(false, 'Update button not disabled'); }); it('Edit site details - [C289339]', async () => { @@ -145,15 +146,15 @@ describe('Library properties', () => { await page.toolbar.clickViewDetails(); await infoDrawer.waitForInfoDrawerToOpen(); - expect(await infoDrawer.isEditEnabled()).toBe(true, 'Edit action is not enabled'); - await infoDrawer.clickEdit(); + expect(await aboutTab.isEditLibraryPropertiesEnabled()).toBe(true, 'Edit action is not enabled'); + await aboutTab.clickEditLibraryProperties(); - await infoDrawer.enterName(siteUpdated.name); - await infoDrawer.enterDescription(siteUpdated.description); - await infoDrawer.setVisibility(siteUpdated.visibility); - expect(await infoDrawer.isUpdateEnabled()).toBe(true, 'Update button not enabled'); + await aboutTab.enterName(siteUpdated.name); + await aboutTab.enterDescription(siteUpdated.description); + await aboutTab.setVisibility(siteUpdated.visibility); + expect(await aboutTab.isUpdateEnabled()).toBe(true, 'Update button not enabled'); - await infoDrawer.clickUpdate(); + await aboutTab.clickUpdate(); expect(await page.getSnackBarMessage()).toEqual('Library properties updated'); expect(await dataTable.isItemPresent(siteUpdated.name)).toBe(true, 'New site name not displayed in the list'); @@ -172,14 +173,14 @@ describe('Library properties', () => { await page.toolbar.clickViewDetails(); await infoDrawer.waitForInfoDrawerToOpen(); - expect(await infoDrawer.isEditEnabled()).toBe(true, 'Edit action is not enabled'); - await infoDrawer.clickEdit(); + expect(await aboutTab.isEditLibraryPropertiesEnabled()).toBe(true, 'Edit action is not enabled'); + await aboutTab.clickEditLibraryProperties(); - await infoDrawer.enterName(newName); - await infoDrawer.enterDescription(newDesc); - await infoDrawer.setVisibility(SITE_VISIBILITY.MODERATED); + await aboutTab.enterName(newName); + await aboutTab.enterDescription(newDesc); + await aboutTab.setVisibility(SITE_VISIBILITY.MODERATED); - await infoDrawer.clickCancel(); + await aboutTab.clickCancel(); expect(await dataTable.isItemPresent(newName)).toBe(false, 'New site name is displayed in the list'); expect(await dataTable.isItemPresent(site.name)).toBe(true, 'Original site name not displayed in the list'); @@ -192,37 +193,37 @@ describe('Library properties', () => { await dataTable.selectItem(siteDup); await page.toolbar.clickViewDetails(); await infoDrawer.waitForInfoDrawerToOpen(); - await infoDrawer.clickEdit(); + await aboutTab.clickEditLibraryProperties(); - await infoDrawer.enterName(site.name); - expect(await infoDrawer.isMessageDisplayed()).toBe(true, 'Message not displayed'); - expect(await infoDrawer.getMessage()).toEqual('Library name already in use'); + await aboutTab.enterName(site.name); + expect(await aboutTab.isMessageDisplayed()).toBe(true, 'Message not displayed'); + expect(await aboutTab.getMessage()).toEqual('Library name already in use'); }); it('Site name too long - [C289342]', async () => { await dataTable.selectItem(site.name); await page.toolbar.clickViewDetails(); await infoDrawer.waitForInfoDrawerToOpen(); - await infoDrawer.clickEdit(); + await aboutTab.clickEditLibraryProperties(); - await infoDrawer.enterName(Utils.string257); + await aboutTab.enterName(Utils.string257); await Utils.pressTab(); - expect(await infoDrawer.isErrorDisplayed()).toBe(true, 'Message not displayed'); - expect(await infoDrawer.getError()).toEqual('Use 256 characters or less for title'); - expect(await infoDrawer.isUpdateEnabled()).toBe(false, 'Update button not disabled'); + expect(await aboutTab.isErrorDisplayed()).toBe(true, 'Message not displayed'); + expect(await aboutTab.getError()).toEqual('Use 256 characters or less for title'); + expect(await aboutTab.isUpdateEnabled()).toBe(false, 'Update button not disabled'); }); it('Site description too long - [C289343]', async () => { await dataTable.selectItem(site.name); await page.toolbar.clickViewDetails(); await infoDrawer.waitForInfoDrawerToOpen(); - await infoDrawer.clickEdit(); + await aboutTab.clickEditLibraryProperties(); - await infoDrawer.enterDescription(Utils.string513); + await aboutTab.enterDescription(Utils.string513); await Utils.pressTab(); - expect(await infoDrawer.isErrorDisplayed()).toBe(true, 'Message not displayed'); - expect(await infoDrawer.getError()).toEqual('Use 512 characters or less for description'); - expect(await infoDrawer.isUpdateEnabled()).toBe(false, 'Update button not disabled'); + expect(await aboutTab.isErrorDisplayed()).toBe(true, 'Message not displayed'); + expect(await aboutTab.getError()).toEqual('Use 512 characters or less for description'); + expect(await aboutTab.isUpdateEnabled()).toBe(false, 'Update button not disabled'); }); describe('Non manager', () => { @@ -238,7 +239,7 @@ describe('Library properties', () => { await dataTable.selectItem(site.name); await page.toolbar.clickViewDetails(); await infoDrawer.waitForInfoDrawerToOpen(); - expect(await infoDrawer.isEditDisplayed()).toBe(false, 'Edit action is displayed'); + expect(await aboutTab.isEditLibraryPropertiesDisplayed()).toBe(false, 'Edit action is displayed'); }); it('Error notification - [C289344]', async () => { @@ -248,12 +249,12 @@ describe('Library properties', () => { await dataTable.selectItem(site.name); await page.toolbar.clickViewDetails(); await infoDrawer.waitForInfoDrawerToOpen(); - await infoDrawer.clickEdit(); + await aboutTab.clickEditLibraryProperties(); await apis.user.sites.updateSiteMember(site.id, user3, SITE_ROLES.SITE_CONSUMER.ROLE); - await infoDrawer.enterDescription('new description'); - await infoDrawer.clickUpdate(); + await aboutTab.enterDescription('new description'); + await aboutTab.clickUpdate(); expect(await page.getSnackBarMessage()).toEqual('There was an error updating library properties'); }); diff --git a/e2e/utilities/repo-client/apis/nodes/nodes-api.ts b/e2e/utilities/repo-client/apis/nodes/nodes-api.ts index db6b346eb1..b08006e1ef 100755 --- a/e2e/utilities/repo-client/apis/nodes/nodes-api.ts +++ b/e2e/utilities/repo-client/apis/nodes/nodes-api.ts @@ -141,13 +141,14 @@ export class NodesApi extends RepoApi { return await this.createNode('cm:content', name, parentId, title, description, imageProps); } - async createNode(nodeType: string, name: string, parentId: string = '-my-', title: string = '', description: string = '', imageProps: any = null, majorVersion: boolean = true) { + async createNode(nodeType: string, name: string, parentId: string = '-my-', title: string = '', description: string = '', imageProps: any = null, author: string = '', majorVersion: boolean = true) { const nodeBody = { name, nodeType, properties: { 'cm:title': title, - 'cm:description': description + 'cm:description': description, + 'cm:author': author } }; if (imageProps) { @@ -155,22 +156,32 @@ export class NodesApi extends RepoApi { } await this.apiAuth(); - return await this.nodesApi.createNode(parentId, nodeBody, { majorVersion }); + + try { + return await this.nodesApi.createNode(parentId, nodeBody, { majorVersion }); + } catch (error) { + console.log('===========> API create node catch ==========='); + } + } - async createFile(name: string, parentId: string = '-my-', title: string = '', description: string = '', majorVersion: boolean = true) { - return await this.createNode('cm:content', name, parentId, title, description, majorVersion); + async createFile(name: string, parentId: string = '-my-', title: string = '', description: string = '', author: string = '', majorVersion: boolean = true) { + return await this.createNode('cm:content', name, parentId, title, description, null, author, majorVersion); } async createImage(name: string, parentId: string = '-my-', title: string = '', description: string = '') { return await this.createImageNode('cm:content', name, parentId, title, description); } - async createFolder(name: string, parentId: string = '-my-', title: string = '', description: string = '') { - return await this.createNode('cm:folder', name, parentId, title, description); + async createFolder(name: string, parentId: string = '-my-', title: string = '', description: string = '', author: string = '') { + try { + return await this.createNode('cm:folder', name, parentId, title, description, null, author); + } catch (error) { + console.log('======> API create folder catch =========='); + } } - async createChildren(data: NodeBodyCreate[]): Promise { + async createChildren(data: NodeBodyCreate[]) { await this.apiAuth(); return await this.nodesApi.createNode('-my-', data); } diff --git a/protractor.conf.js b/protractor.conf.js index ad1a191232..16dcf6a479 100755 --- a/protractor.conf.js +++ b/protractor.conf.js @@ -80,7 +80,7 @@ exports.config = { '--incognito', '--headless', '--remote-debugging-port=9222', - '--disable-gpu', + `--window-size=${width},${height}`, '--no-sandbox' ] } @@ -94,7 +94,7 @@ exports.config = { framework: 'jasmine', jasmineNodeOpts: { showColors: true, - defaultTimeoutInterval: 60000, + defaultTimeoutInterval: 100000, print: function() {} }, @@ -118,11 +118,6 @@ exports.config = { project: 'e2e/tsconfig.e2e.json' }); - browser - .manage() - .window() - .setSize(width, height); - jasmine.getEnv().addReporter( new SpecReporter({ spec: { From d8e3b9ada044b137bef6325a022c8aab4b8e85da Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Fri, 10 May 2019 15:08:00 +0100 Subject: [PATCH 200/259] [ACA-2364] support 'canPreview' rule for the Viewer (#1102) * support `canPreview` rule for the Viewer * update plint settings * update prettier settings for plint * test fixes * update config --- .github/plint.yml | 10 +++++++ docs/extending/application-features.md | 30 +++++++++++++++++++ extension.schema.json | 10 +++++++ src/app/extensions/extension.service.ts | 38 ++++++++++++++++++++++++- src/app/extensions/viewer.rules.ts | 31 ++++++++++++++++++++ src/app/store/effects/viewer.effects.ts | 14 +++++++-- 6 files changed, 129 insertions(+), 4 deletions(-) create mode 100644 src/app/extensions/viewer.rules.ts diff --git a/.github/plint.yml b/.github/plint.yml index 9972c50036..27172f7004 100644 --- a/.github/plint.yml +++ b/.github/plint.yml @@ -2,11 +2,21 @@ modules: - pr.prettier - pr.spellcheck +prettier: + exclude: + - '*.json' + spellcheck: + dictionaries: + - html + - en-gb + - en_US words: - plint - ngrx - qshare - snackbar + - exif + - docx exclude: - src/assets/app.extensions.json diff --git a/docs/extending/application-features.md b/docs/extending/application-features.md index 6b318815db..2bca3efa0e 100644 --- a/docs/extending/application-features.md +++ b/docs/extending/application-features.md @@ -363,6 +363,7 @@ Viewer component in ACA supports the following extension points: - Toolbar actions - `More` toolbar actions - `Open With` actions +- Rules ```json { @@ -547,6 +548,35 @@ and invoke it from the custom `Open With` menu entry called `Snackbar`. As with other content actions, custom plugins can disable, update or extend `Open With` actions. +### Rules + +You can provide global rules for the Viewer by utilizing the `features.viewer.rules` object: + +```ts +export interface ViewerRules { + /** + * Checks if user can preview the node. + */ + canPreview?: string; +} +``` + +For example: + +```json +{ + "features": { + "viewer": { + "rules": { + "canPreview": "customRule" + } + } + } +} +``` + +The rule should return `true` if node preview is allowed, otherwise `false`. + ## Content metadata presets The content metadata presets are needed by the [Content Metadata Component](https://www.alfresco.com/abn/adf/docs/content-services/content-metadata-card.component/) to render the properties of metadata aspects for a given node. diff --git a/extension.schema.json b/extension.schema.json index 678b8cc190..c8357a764e 100644 --- a/extension.schema.json +++ b/extension.schema.json @@ -684,6 +684,16 @@ "description": "Viewer component extensions", "type": "object", "properties": { + "rules": { + "description": "Viewer rules", + "type": "object", + "properties": { + "canPreview": { + "description": "Controls whether preview is enabled for particular node", + "type": "string" + } + } + }, "openWith": { "description": "The [Open With] menu extensions", "type": "array", diff --git a/src/app/extensions/extension.service.ts b/src/app/extensions/extension.service.ts index d8cba20843..060f39c526 100644 --- a/src/app/extensions/extension.service.ts +++ b/src/app/extensions/extension.service.ts @@ -53,7 +53,8 @@ import { } from '@alfresco/adf-extensions'; import { AppConfigService, AuthenticationService } from '@alfresco/adf-core'; import { BehaviorSubject, Observable } from 'rxjs'; -import { RepositoryInfo } from '@alfresco/js-api'; +import { RepositoryInfo, NodeEntry } from '@alfresco/js-api'; +import { ViewerRules } from './viewer.rules'; @Injectable({ providedIn: 'root' @@ -76,6 +77,7 @@ export class AppExtensionService implements RuleContext { navbar: Array = []; sidebar: Array = []; contentMetadata: any; + viewerRules: ViewerRules = {}; documentListPresets: { files: Array; @@ -184,6 +186,10 @@ export class AppExtensionService implements RuleContext { searchLibraries: this.getDocumentListPreset(config, 'search-libraries') }; + if (config.features && config.features.viewer) { + this.viewerRules = (config.features.viewer['rules'] || {}); + } + this.registerIcons(config); const references = (config.$references || []) @@ -504,7 +510,37 @@ export class AppExtensionService implements RuleContext { } } + // todo: move to ADF/RuleService + isRuleDefined(ruleId: string): boolean { + return ruleId && this.getEvaluator(ruleId) ? true : false; + } + + // todo: move to ADF/RuleService + evaluateRule(ruleId: string, ...args: any[]): boolean { + const evaluator = this.getEvaluator(ruleId); + + if (evaluator) { + return evaluator(this, ...args); + } + + return false; + } + getEvaluator(key: string): RuleEvaluator { return this.extensions.getEvaluator(key); } + + canPreviewNode(node: NodeEntry) { + const rules = this.viewerRules; + + if (this.isRuleDefined(rules.canPreview)) { + const canPreview = this.evaluateRule(rules.canPreview, node); + + if (!canPreview) { + return false; + } + } + + return true; + } } diff --git a/src/app/extensions/viewer.rules.ts b/src/app/extensions/viewer.rules.ts new file mode 100644 index 0000000000..500ce65857 --- /dev/null +++ b/src/app/extensions/viewer.rules.ts @@ -0,0 +1,31 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2019 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +export interface ViewerRules { + /** + * Checks if user can preview the node. + */ + canPreview?: string; +} diff --git a/src/app/store/effects/viewer.effects.ts b/src/app/store/effects/viewer.effects.ts index 31ccc90cc0..2c5f79a306 100644 --- a/src/app/store/effects/viewer.effects.ts +++ b/src/app/store/effects/viewer.effects.ts @@ -37,6 +37,7 @@ import { } from '@alfresco/aca-shared/store'; import { Router } from '@angular/router'; import { Store, createSelector } from '@ngrx/store'; +import { AppExtensionService } from '../../extensions/extension.service'; export const fileToPreview = createSelector( getAppSelection, @@ -54,7 +55,8 @@ export class ViewerEffects { constructor( private store: Store, private actions$: Actions, - private router: Router + private router: Router, + private extensions: AppExtensionService ) {} @Effect({ dispatch: false }) @@ -94,7 +96,10 @@ export class ViewerEffects { if (action.payload && action.payload.entry) { const { id, nodeId, isFile } = action.payload.entry; - if (isFile || nodeId) { + if ( + this.extensions.canPreviewNode(action.payload) && + (isFile || nodeId) + ) { this.displayPreview(nodeId || id, action.parentId); } } else { @@ -105,7 +110,10 @@ export class ViewerEffects { if (result.selection && result.selection.file) { const { id, nodeId, isFile } = result.selection.file.entry; - if (isFile || nodeId) { + if ( + this.extensions.canPreviewNode(action.payload) && + (isFile || nodeId) + ) { const parentId = result.folder ? result.folder.id : null; this.displayPreview(nodeId || id, parentId); } From 39f528af674aa015acee0c903a3e43c9fe34a188 Mon Sep 17 00:00:00 2001 From: Martin Muller Date: Tue, 14 May 2019 16:58:58 +0100 Subject: [PATCH 201/259] Feature/ACA-1676 e2e share file (#1106) * ACA-1676 add share tests with user logouts * ACA-1676 add share tests with user logouts * ACA-1676 split the logout test into own describe and reformat the tests a bit. * ACA-1676 split the logout test into own describe and reformat the tests a bit. * ACA-1676 split the logout test into own describe and reformat the tests a bit. * ACA-1676 split the logout test into own describe and reformat the tests a bit. * ACA-1676 change some protractor config as suggested from Adina * ACA-1676 change some protractor config as suggested from Adina --- .travis.yml | 3 +- e2e/suites/actions/share-file.test.ts | 2056 ++++++++++++------------- protractor.conf.js | 7 +- 3 files changed, 1033 insertions(+), 1033 deletions(-) diff --git a/.travis.yml b/.travis.yml index d14ee485c8..37a2e2d0ad 100644 --- a/.travis.yml +++ b/.travis.yml @@ -50,7 +50,8 @@ jobs: script: SUITE="--suite search" npm run e2e:docker - name: Test Suite actionsAvailable script: SUITE="--suite actionsAvailable" npm run e2e:docker - - name: Test Suite actions + - stage: e2e + name: Test Suite actions script: SUITE="--suite actions" npm run e2e:docker - name: Test Suite viewer script: SUITE="--suite viewer" npm run e2e:docker diff --git a/e2e/suites/actions/share-file.test.ts b/e2e/suites/actions/share-file.test.ts index ab1db28eb7..46c7652755 100755 --- a/e2e/suites/actions/share-file.test.ts +++ b/e2e/suites/actions/share-file.test.ts @@ -33,30 +33,31 @@ import { Utils } from '../../utilities/utils'; describe('Share a file', () => { const username = `user-${Utils.random()}`; - const parent = `parent-${Utils.random()}`; let parentId; - const expiryDate: any = '2020-12-25T18:30:00.000+0000'; + const file1 = `file1-${Utils.random()}.txt`; let file1Id; + const file2 = `file2-${Utils.random()}.txt`; let file2Id; + let file3 = `file3-${Utils.random()}.txt`; let file3Id; + const file4 = `file4-${Utils.random()}.txt`; let file4Id; + let file5 = `file5-${Utils.random()}.txt`; let file5Id; + let file6 = `file6-${Utils.random()}.txt`; let file6Id; + let file7 = `file7-${Utils.random()}.txt`; let file7Id; + const file8 = `file8-${Utils.random()}.txt`; let file8Id; + let file9 = `file9-${Utils.random()}.txt`; let file9Id; + + const viewer = new Viewer(); + const page = new BrowsingPage(); + const { dataTable, toolbar } = page; + const shareLinkPreUrl = "/#/preview/s/"; const apis = { admin: new RepoClient(), user: new RepoClient(username, username) }; - const loginPage = new LoginPage(); - const page = new BrowsingPage(); - const { dataTable, toolbar } = page; - const shareDialog = new ShareDialog(); - const viewer = new Viewer(); - const contextMenu = dataTable.menu; - const { searchInput } = page.header; - beforeAll(async (done) => { await apis.admin.people.createUser({ username }); - parentId = (await apis.user.nodes.createFolder(parent)).entry.id; - - await loginPage.loginWith(username); done(); }); @@ -65,1044 +66,1037 @@ describe('Share a file', () => { done(); }); - describe('from Personal Files', () => { - - const file1 = `file1-${Utils.random()}.txt`; let file1Id; - const file2 = `file2-${Utils.random()}.txt`; let file2Id; - const file3 = `file3-${Utils.random()}.txt`; let file3Id; - const file4 = `file4-${Utils.random()}.txt`; let file4Id; - const file5 = `file5-${Utils.random()}.txt`; let file5Id; - const file6 = `file6-${Utils.random()}.txt`; let file6Id; - const file7 = `file7-${Utils.random()}.txt`; let file7Id; - const file8 = `file8-${Utils.random()}.txt`; let file8Id; - const file9 = `file9-${Utils.random()}.txt`; let file9Id; - - beforeAll(async (done) => { - file1Id = (await apis.user.nodes.createFile(file1, parentId)).entry.id; - file2Id = (await apis.user.nodes.createFile(file2, parentId)).entry.id; - file3Id = (await apis.user.nodes.createFile(file3, parentId)).entry.id; - file4Id = (await apis.user.nodes.createFile(file4, parentId)).entry.id; - file5Id = (await apis.user.nodes.createFile(file5, parentId)).entry.id; - file6Id = (await apis.user.nodes.createFile(file6, parentId)).entry.id; - file7Id = (await apis.user.nodes.createFile(file7, parentId)).entry.id; - file8Id = (await apis.user.nodes.createFile(file8, parentId)).entry.id; - file9Id = (await apis.user.nodes.createFile(file9, parentId)).entry.id; - await apis.user.shared.shareFileById(file6Id, expiryDate); - await apis.user.shared.shareFileById(file7Id, expiryDate); - await apis.user.shared.waitForApi({ expect: 2 }); - done(); - }); - - beforeEach(async (done) => { - await page.clickPersonalFilesAndWait(); - await dataTable.doubleClickOnRowByName(parent); - await dataTable.waitForHeader(); - done(); - }); - - afterEach(async (done) => { - await Utils.pressEscape(); - done(); - }); - - afterAll(async (done) => { - await apis.user.nodes.deleteNodeById(file1Id); - await apis.user.nodes.deleteNodeById(file2Id); - await apis.user.nodes.deleteNodeById(file3Id); - await apis.user.nodes.deleteNodeById(file4Id); - await apis.user.nodes.deleteNodeById(file5Id); - await apis.user.nodes.deleteNodeById(file6Id); - await apis.user.nodes.deleteNodeById(file7Id); - await apis.user.nodes.deleteNodeById(file8Id); - await apis.user.nodes.deleteNodeById(file9Id); - await apis.user.shared.waitForApi({ expect: 0 }); - done(); - }); - - it('Share dialog default values - [C286327]', async () => { - await dataTable.selectItem(file1); - await toolbar.clickShare(); - await shareDialog.waitForDialogToOpen(); - - expect(await shareDialog.getTitle()).toEqual(`Share ${file1}`); - expect(await shareDialog.getInfoText()).toEqual('Click the link below to copy it to the clipboard.'); - expect(await shareDialog.getLabels().get(0).getText()).toEqual('Link to share'); - expect(await shareDialog.getLinkUrl()).toContain('/preview/s/'); - expect(await shareDialog.isUrlReadOnly()).toBe('true', 'url is not readonly'); - expect(await shareDialog.isShareToggleChecked()).toBe(true, 'Share toggle not checked'); - expect(await shareDialog.getLabels().get(1).getText()).toEqual('Expires on'); - expect(await shareDialog.isExpireToggleEnabled()).toBe(false, 'Expire toggle is checked'); - expect(await shareDialog.isCloseEnabled()).toBe(true, 'Close button is not enabled'); - }); - - it('Close dialog - [C286328]', async () => { - await dataTable.selectItem(file2); - await toolbar.clickShare(); - await shareDialog.waitForDialogToOpen(); - - expect(await shareDialog.isCloseEnabled()).toBe(true, 'Close button is not enabled'); - await shareDialog.clickClose(); - expect(await shareDialog.isDialogOpen()).toBe(false, 'Share dialog is open'); - }); - - it('Share a file - [C286329]', async () => { - await dataTable.selectItem(file3); - await toolbar.clickShare(); - await shareDialog.waitForDialogToOpen(); - - const url = await shareDialog.getLinkUrl(); - await Utils.pressEscape(); - const sharedId = await apis.user.nodes.getSharedId(file3Id); - expect(await apis.user.nodes.isFileShared(file3Id)).toBe(true, `${file3} is not shared`); - expect(url).toContain(sharedId); - }); - - it('Copy shared file URL - [C286330]', async () => { - await dataTable.selectItem(file4); - await toolbar.clickShare(); - await shareDialog.waitForDialogToOpen(); - const url = await shareDialog.getLinkUrl(); - expect(url).toContain('/preview/s/'); - - await shareDialog.copyUrl(); - expect(await page.getSnackBarMessage()).toBe('Link copied to the clipboard'); - - await browser.get(url); - expect(await viewer.isViewerOpened()).toBe(true, 'viewer is not open'); - expect(await viewer.getFileTitle()).toEqual(file4); - - await page.load(); - }); - - it('Share a file with expiration date - [C286332]', async () => { - await dataTable.selectItem(file5); - await toolbar.clickShare(); - await shareDialog.waitForDialogToOpen(); - - await shareDialog.clickExpirationToggle(); - expect(await shareDialog.isExpireToggleEnabled()).toBe(true, 'Expire toggle not checked'); - expect(await shareDialog.dateTimePicker.isCalendarOpen()).toBe(true, 'Calendar not opened'); - const date = await shareDialog.dateTimePicker.setDefaultDay(); - await shareDialog.dateTimePicker.waitForDateTimePickerToClose(); - - const setDate = (`${date}`).replace(',', ''); - const inputDate = await shareDialog.getExpireDate(); - - expect(new Date(inputDate)).toEqual(new Date(setDate)); - - const expireDateProperty = await apis.user.nodes.getSharedExpiryDate(file5Id); - - expect(Utils.formatDate(expireDateProperty)).toEqual(Utils.formatDate(inputDate)); - }); - - it('Expire date is displayed correctly - [C286337]', async () => { - await dataTable.selectItem(file6); - await toolbar.clickSharedLinkSettings(); - await shareDialog.waitForDialogToOpen(); - - const expireProperty = await apis.user.nodes.getSharedExpiryDate(file6Id); - expect(expireProperty).toEqual(expiryDate); - expect(await shareDialog.isExpireToggleEnabled()).toBe(true, 'Expiration is not checked'); - expect(Utils.formatDate(await shareDialog.getExpireDate())).toEqual(Utils.formatDate(expiryDate)); - }); - - it('Disable the share link expiration - [C286333]', async () => { - await dataTable.selectItem(file7); - await toolbar.clickSharedLinkSettings(); - await shareDialog.waitForDialogToOpen(); - - expect(await shareDialog.isExpireToggleEnabled()).toBe(true, 'Expiration is not checked'); - expect(await shareDialog.getExpireDate()).not.toBe('', 'Expire date input is empty'); - - await shareDialog.clickExpirationToggle(); - expect(await shareDialog.isExpireToggleEnabled()).toBe(false, 'Expiration is checked'); - expect(await shareDialog.getExpireDate()).toBe('', 'Expire date input is not empty'); - - await shareDialog.clickClose(); - expect(await apis.user.nodes.getSharedExpiryDate(file7Id)).toBe(undefined, `${file7} link still has expiration`); - }); - - it('Shared file URL is not changed when Share dialog is closed and opened again - [C286335]', async () => { - await dataTable.selectItem(file8); - await toolbar.clickShare(); - await shareDialog.waitForDialogToOpen(); - const url1 = await shareDialog.getLinkUrl(); - await shareDialog.clickClose(); - await shareDialog.waitForDialogToClose(); - - await page.dataTable.clearSelection(); - await dataTable.selectItem(file8); - await toolbar.clickSharedLinkSettings(); - await shareDialog.waitForDialogToOpen(); - const url2 = await shareDialog.getLinkUrl(); - - expect(url1).toEqual(url2); - }); - - it('Share a file from the context menu - [C286345]', async () => { - await dataTable.rightClickOnItem(file9); - await contextMenu.waitForMenuToOpen(); - await contextMenu.clickShare(); - await shareDialog.waitForDialogToOpen(); - - const url = await shareDialog.getLinkUrl(); - await Utils.pressEscape(); - const sharedId = await apis.user.nodes.getSharedId(file9Id); - expect(await apis.user.nodes.isFileShared(file9Id)).toBe(true, `${file9} is not shared`); - expect(url).toContain(sharedId); - }); - }); - - describe('from File Libraries', () => { - - const file1 = `file1-${Utils.random()}.txt`; - const file2 = `file2-${Utils.random()}.txt`; - const file3 = `file3-${Utils.random()}.txt`; let file3Id; - const file4 = `file4-${Utils.random()}.txt`; - const file5 = `file5-${Utils.random()}.txt`; let file5Id; - const file6 = `file6-${Utils.random()}.txt`; let file6Id; - const file7 = `file7-${Utils.random()}.txt`; let file7Id; - const file8 = `file8-${Utils.random()}.txt`; - const file9 = `file9-${Utils.random()}.txt`; let file9Id; - - const siteName = `site-${Utils.random()}`; - const parentInSite = `parent-site-${Utils.random()}`; let parentInSiteId; - - beforeAll(async (done) => { - await apis.user.sites.createSite(siteName, SITE_VISIBILITY.PUBLIC); - const docLibId = await apis.user.sites.getDocLibId(siteName); - parentInSiteId = (await apis.user.nodes.createFolder(parentInSite, docLibId)).entry.id; - - await apis.user.nodes.createFile(file1, parentInSiteId); - await apis.user.nodes.createFile(file2, parentInSiteId); - file3Id = (await apis.user.nodes.createFile(file3, parentInSiteId)).entry.id; - await apis.user.nodes.createFile(file4, parentInSiteId); - file5Id = (await apis.user.nodes.createFile(file5, parentInSiteId)).entry.id; - file6Id = (await apis.user.nodes.createFile(file6, parentInSiteId)).entry.id; - file7Id = (await apis.user.nodes.createFile(file7, parentInSiteId)).entry.id; - await apis.user.nodes.createFile(file8, parentInSiteId); - file9Id = (await apis.user.nodes.createFile(file9, parentInSiteId)).entry.id; - await apis.user.shared.shareFileById(file6Id, expiryDate); - await apis.user.shared.shareFileById(file7Id, expiryDate); - await apis.user.shared.waitForApi({ expect: 2 }); - done(); - }); - - beforeEach(async (done) => { - await page.goToMyLibrariesAndWait(); - await dataTable.doubleClickOnRowByName(siteName); - await dataTable.waitForHeader(); - await dataTable.doubleClickOnRowByName(parentInSite); - await dataTable.waitForHeader(); - done(); - }); - - afterEach(async (done) => { - await Utils.pressEscape(); - await page.clickPersonalFilesAndWait(); - done(); - }); - - afterAll(async (done) => { - await apis.admin.sites.deleteSite(siteName); - await apis.user.shared.waitForApi({ expect: 0 }); - done(); - }); - - it('Share dialog default values - [C286639]', async () => { - await dataTable.selectItem(file1); - await toolbar.clickShare(); - await shareDialog.waitForDialogToOpen(); - - expect(await shareDialog.getTitle()).toEqual(`Share ${file1}`); - expect(await shareDialog.getInfoText()).toEqual('Click the link below to copy it to the clipboard.'); - expect(await shareDialog.getLabels().get(0).getText()).toEqual('Link to share'); - expect(await shareDialog.getLinkUrl()).toContain('/preview/s/'); - expect(await shareDialog.isUrlReadOnly()).toBe('true', 'url is not readonly'); - expect(await shareDialog.isShareToggleChecked()).toBe(true, 'Share toggle not checked'); - expect(await shareDialog.getLabels().get(1).getText()).toEqual('Expires on'); - expect(await shareDialog.isExpireToggleEnabled()).toBe(false, 'Expire toggle is checked'); - expect(await shareDialog.isCloseEnabled()).toBe(true, 'Close button is not enabled'); - }); - - it('Close dialog - [C286640]', async () => { - await dataTable.selectItem(file2); - await toolbar.clickShare(); - await shareDialog.waitForDialogToOpen(); - - expect(await shareDialog.isCloseEnabled()).toBe(true, 'Close button is not enabled'); - await shareDialog.clickClose(); - expect(await shareDialog.isDialogOpen()).toBe(false, 'Share dialog is open'); - }); - - it('Share a file - [C286641]', async () => { - await dataTable.selectItem(file3); - await toolbar.clickShare(); - await shareDialog.waitForDialogToOpen(); - - const url = await shareDialog.getLinkUrl(); - await Utils.pressEscape(); - const sharedId = await apis.user.nodes.getSharedId(file3Id); - expect(await apis.user.nodes.isFileShared(file3Id)).toBe(true, `${file3} is not shared`); - expect(url).toContain(sharedId); - }); - - it('Copy shared file URL - [C286642]', async () => { - await dataTable.selectItem(file4); - await toolbar.clickShare(); - await shareDialog.waitForDialogToOpen(); - const url = await shareDialog.getLinkUrl(); - expect(url).toContain('/preview/s/'); - - await shareDialog.copyUrl(); - expect(await page.getSnackBarMessage()).toBe('Link copied to the clipboard'); - - await browser.get(url); - expect(await viewer.isViewerOpened()).toBe(true, 'viewer is not open'); - expect(await viewer.getFileTitle()).toEqual(file4); - - await page.load(); - }); - - it('Share a file with expiration date - [C286643]', async () => { - await dataTable.selectItem(file5); - await toolbar.clickShare(); - await shareDialog.waitForDialogToOpen(); - - await shareDialog.clickExpirationToggle(); - expect(await shareDialog.isExpireToggleEnabled()).toBe(true, 'Expire toggle not checked'); - expect(await shareDialog.dateTimePicker.isCalendarOpen()).toBe(true, 'Calendar not opened'); - const date = await shareDialog.dateTimePicker.setDefaultDay(); - await shareDialog.dateTimePicker.waitForDateTimePickerToClose(); - - const setDate = (`${date}`).replace(',', ''); - const inputDate = await shareDialog.getExpireDate(); - - expect(new Date(inputDate)).toEqual(new Date(setDate)); - - const expireDateProperty = await apis.user.nodes.getSharedExpiryDate(file5Id); - - expect(Utils.formatDate(expireDateProperty)).toEqual(Utils.formatDate(inputDate)); - }); - - it('Expire date is displayed correctly - [C286644]', async () => { - await dataTable.selectItem(file6); - await toolbar.clickSharedLinkSettings(); - await shareDialog.waitForDialogToOpen(); - - const expireProperty = await apis.user.nodes.getSharedExpiryDate(file6Id); - expect(expireProperty).toEqual(expiryDate); - expect(await shareDialog.isExpireToggleEnabled()).toBe(true, 'Expiration is not checked'); - expect(Utils.formatDate(await shareDialog.getExpireDate())).toEqual(Utils.formatDate(expiryDate)); - }); - - it('Disable the share link expiration - [C286645]', async () => { - await dataTable.selectItem(file7); - await toolbar.clickSharedLinkSettings(); - await shareDialog.waitForDialogToOpen(); - - expect(await shareDialog.isExpireToggleEnabled()).toBe(true, 'Expiration is not checked'); - expect(await shareDialog.getExpireDate()).not.toBe('', 'Expire date input is empty'); - - await shareDialog.clickExpirationToggle(); - expect(await shareDialog.isExpireToggleEnabled()).toBe(false, 'Expiration is checked'); - expect(await shareDialog.getExpireDate()).toBe('', 'Expire date input is not empty'); - - await shareDialog.clickClose(); - expect(await apis.user.nodes.getSharedExpiryDate(file7Id)).toBe(undefined, `${file7} link still has expiration`); - }); - - it('Shared file URL is not changed when Share dialog is closed and opened again - [C286646]', async () => { - await dataTable.selectItem(file8); - await toolbar.clickShare(); - await shareDialog.waitForDialogToOpen(); - const url1 = await shareDialog.getLinkUrl(); - await shareDialog.clickClose(); - await shareDialog.waitForDialogToClose(); - - await page.dataTable.clearSelection(); - await dataTable.selectItem(file8); - await toolbar.clickSharedLinkSettings(); - await shareDialog.waitForDialogToOpen(); - const url2 = await shareDialog.getLinkUrl(); - - expect(url1).toEqual(url2); - }); - - it('Share a file from the context menu - [C286647]', async () => { - await dataTable.rightClickOnItem(file9); - await contextMenu.waitForMenuToOpen(); - await contextMenu.clickShare(); - await shareDialog.waitForDialogToOpen(); - - const url = await shareDialog.getLinkUrl(); - await Utils.pressEscape(); - const sharedId = await apis.user.nodes.getSharedId(file9Id); - expect(await apis.user.nodes.isFileShared(file9Id)).toBe(true, `${file9} is not shared`); - expect(url).toContain(sharedId); - }); - }); - - describe('from Recent Files', () => { - - const file1 = `file1-${Utils.random()}.txt`; let file1Id; - const file2 = `file2-${Utils.random()}.txt`; let file2Id; - const file3 = `file3-${Utils.random()}.txt`; let file3Id; - const file4 = `file4-${Utils.random()}.txt`; let file4Id; - const file5 = `file5-${Utils.random()}.txt`; let file5Id; - const file6 = `file6-${Utils.random()}.txt`; let file6Id; - const file7 = `file7-${Utils.random()}.txt`; let file7Id; - const file8 = `file8-${Utils.random()}.txt`; let file8Id; - const file9 = `file9-${Utils.random()}.txt`; let file9Id; - - beforeAll(async (done) => { - file1Id = (await apis.user.nodes.createFile(file1, parentId)).entry.id; - file2Id = (await apis.user.nodes.createFile(file2, parentId)).entry.id; - file3Id = (await apis.user.nodes.createFile(file3, parentId)).entry.id; - file4Id = (await apis.user.nodes.createFile(file4, parentId)).entry.id; - file5Id = (await apis.user.nodes.createFile(file5, parentId)).entry.id; - file6Id = (await apis.user.nodes.createFile(file6, parentId)).entry.id; - file7Id = (await apis.user.nodes.createFile(file7, parentId)).entry.id; - file8Id = (await apis.user.nodes.createFile(file8, parentId)).entry.id; - file9Id = (await apis.user.nodes.createFile(file9, parentId)).entry.id; - await apis.user.shared.shareFileById(file6Id, expiryDate); - await apis.user.shared.shareFileById(file7Id, expiryDate); - await apis.user.shared.waitForApi({ expect: 2 }); - done(); - }); - - beforeEach(async (done) => { - await page.clickRecentFilesAndWait(); - done(); - }); - - afterEach(async (done) => { - await Utils.pressEscape(); - await page.clickPersonalFilesAndWait(); - done(); - }); - - afterAll(async (done) => { - await apis.user.nodes.deleteNodeById(file1Id); - await apis.user.nodes.deleteNodeById(file2Id); - await apis.user.nodes.deleteNodeById(file3Id); - await apis.user.nodes.deleteNodeById(file4Id); - await apis.user.nodes.deleteNodeById(file5Id); - await apis.user.nodes.deleteNodeById(file6Id); - await apis.user.nodes.deleteNodeById(file7Id); - await apis.user.nodes.deleteNodeById(file8Id); - await apis.user.nodes.deleteNodeById(file9Id); - await apis.user.shared.waitForApi({ expect: 0 }); - done(); - }); - - it('Share dialog default values - [C286657]', async () => { - await dataTable.selectItem(file1); - await toolbar.clickShare(); - await shareDialog.waitForDialogToOpen(); - - expect(await shareDialog.getTitle()).toEqual(`Share ${file1}`); - expect(await shareDialog.getInfoText()).toEqual('Click the link below to copy it to the clipboard.'); - expect(await shareDialog.getLabels().get(0).getText()).toEqual('Link to share'); - expect(await shareDialog.getLinkUrl()).toContain('/preview/s/'); - expect(await shareDialog.isUrlReadOnly()).toBe('true', 'url is not readonly'); - expect(await shareDialog.isShareToggleChecked()).toBe(true, 'Share toggle not checked'); - expect(await shareDialog.getLabels().get(1).getText()).toEqual('Expires on'); - expect(await shareDialog.isExpireToggleEnabled()).toBe(false, 'Expire toggle is checked'); - expect(await shareDialog.isCloseEnabled()).toBe(true, 'Close button is not enabled'); - }); - - it('Close dialog - [C286658]', async () => { - await dataTable.selectItem(file2); - await toolbar.clickShare(); - await shareDialog.waitForDialogToOpen(); - - expect(await shareDialog.isCloseEnabled()).toBe(true, 'Close button is not enabled'); - await shareDialog.clickClose(); - expect(await shareDialog.isDialogOpen()).toBe(false, 'Share dialog is open'); - }); - - it('Share a file - [C286659]', async () => { - await dataTable.selectItem(file3); - await toolbar.clickShare(); - await shareDialog.waitForDialogToOpen(); - - const url = await shareDialog.getLinkUrl(); - await Utils.pressEscape(); - const sharedId = await apis.user.nodes.getSharedId(file3Id); - expect(await apis.user.nodes.isFileShared(file3Id)).toBe(true, `${file3} is not shared`); - expect(url).toContain(sharedId); - }); - - it('Copy shared file URL - [C286660]', async () => { - await dataTable.selectItem(file4); - await toolbar.clickShare(); - await shareDialog.waitForDialogToOpen(); - const url = await shareDialog.getLinkUrl(); - expect(url).toContain('/preview/s/'); - - await shareDialog.copyUrl(); - expect(await page.getSnackBarMessage()).toBe('Link copied to the clipboard'); - - await browser.get(url); - expect(await viewer.isViewerOpened()).toBe(true, 'viewer is not open'); - expect(await viewer.getFileTitle()).toEqual(file4); - - await page.load(); - }); - - it('Share a file with expiration date - [C286661]', async () => { - await dataTable.selectItem(file5); - await toolbar.clickShare(); - await shareDialog.waitForDialogToOpen(); - - await shareDialog.clickExpirationToggle(); - expect(await shareDialog.isExpireToggleEnabled()).toBe(true, 'Expire toggle not checked'); - expect(await shareDialog.dateTimePicker.isCalendarOpen()).toBe(true, 'Calendar not opened'); - const date = await shareDialog.dateTimePicker.setDefaultDay(); - await shareDialog.dateTimePicker.waitForDateTimePickerToClose(); - - const setDate = (`${date}`).replace(',', ''); - const inputDate = await shareDialog.getExpireDate(); - - expect(new Date(inputDate)).toEqual(new Date(setDate)); - - const expireDateProperty = await apis.user.nodes.getSharedExpiryDate(file5Id); - - expect(Utils.formatDate(expireDateProperty)).toEqual(Utils.formatDate(inputDate)); - }); - - it('Expire date is displayed correctly - [C286662]', async () => { - await dataTable.selectItem(file6); - await toolbar.clickSharedLinkSettings(); - await shareDialog.waitForDialogToOpen(); - - const expireProperty = await apis.user.nodes.getSharedExpiryDate(file6Id); - expect(expireProperty).toEqual(expiryDate); - expect(await shareDialog.isExpireToggleEnabled()).toBe(true, 'Expiration is not checked'); - expect(Utils.formatDate(await shareDialog.getExpireDate())).toEqual(Utils.formatDate(expiryDate)); - }); - - it('Disable the share link expiration - [C286663]', async () => { - await dataTable.selectItem(file7); - await toolbar.clickSharedLinkSettings(); - await shareDialog.waitForDialogToOpen(); - - expect(await shareDialog.isExpireToggleEnabled()).toBe(true, 'Expiration is not checked'); - expect(await shareDialog.getExpireDate()).not.toBe('', 'Expire date input is empty'); - - await shareDialog.clickExpirationToggle(); - expect(await shareDialog.isExpireToggleEnabled()).toBe(false, 'Expiration is checked'); - expect(await shareDialog.getExpireDate()).toBe('', 'Expire date input is not empty'); - - await shareDialog.clickClose(); - expect(await apis.user.nodes.getSharedExpiryDate(file7Id)).toBe(undefined, `${file7} link still has expiration`); - }); - - it('Shared file URL is not changed when Share dialog is closed and opened again - [C286664]', async () => { - await dataTable.selectItem(file8); - await toolbar.clickShare(); - await shareDialog.waitForDialogToOpen(); - const url1 = await shareDialog.getLinkUrl(); - await shareDialog.clickClose(); - await shareDialog.waitForDialogToClose(); - - await page.dataTable.clearSelection(); - await dataTable.selectItem(file8); - await toolbar.clickSharedLinkSettings(); - await shareDialog.waitForDialogToOpen(); - const url2 = await shareDialog.getLinkUrl(); - - expect(url1).toEqual(url2); - }); - - it('Share a file from the context menu - [C286665]', async () => { - await dataTable.rightClickOnItem(file9); - await contextMenu.waitForMenuToOpen(); - await contextMenu.clickShare(); - await shareDialog.waitForDialogToOpen(); - - const url = await shareDialog.getLinkUrl(); - await Utils.pressEscape(); - const sharedId = await apis.user.nodes.getSharedId(file9Id); - expect(await apis.user.nodes.isFileShared(file9Id)).toBe(true, `${file9} is not shared`); - expect(url).toContain(sharedId); - }); - }); - - describe('from Shared Files', () => { - - const file1 = `file1-${Utils.random()}.txt`; let file1Id; - const file2 = `file2-${Utils.random()}.txt`; let file2Id; - const file3 = `file3-${Utils.random()}.txt`; let file3Id; - const file4 = `file4-${Utils.random()}.txt`; let file4Id; - const file5 = `file5-${Utils.random()}.txt`; let file5Id; - const file6 = `file6-${Utils.random()}.txt`; let file6Id; - const file7 = `file7-${Utils.random()}.txt`; let file7Id; + describe('when logged out', () => { + let file6SharedLink; beforeAll(async (done) => { - file1Id = (await apis.user.nodes.createFile(file1, parentId)).entry.id; - file2Id = (await apis.user.nodes.createFile(file2, parentId)).entry.id; - file3Id = (await apis.user.nodes.createFile(file3, parentId)).entry.id; - file4Id = (await apis.user.nodes.createFile(file4, parentId)).entry.id; - file5Id = (await apis.user.nodes.createFile(file5, parentId)).entry.id; file6Id = (await apis.user.nodes.createFile(file6, parentId)).entry.id; - file7Id = (await apis.user.nodes.createFile(file7, parentId)).entry.id; - - await apis.user.shared.shareFileById(file1Id); - await apis.user.shared.shareFileById(file2Id); - await apis.user.shared.shareFileById(file3Id); - await apis.user.shared.shareFileById(file4Id, expiryDate); - await apis.user.shared.shareFileById(file5Id, expiryDate); - await apis.user.shared.shareFileById(file6Id); - await apis.user.shared.shareFileById(file7Id); - await apis.user.shared.waitForApi({ expect: 7 }); - done(); - }); - - beforeEach(async (done) => { - await page.clickSharedFilesAndWait(); - done(); - }); - - afterEach(async (done) => { - await Utils.pressEscape(); - await page.clickPersonalFilesAndWait(); + const sharedId = (await apis.user.shared.shareFileById(file6Id)).entry.id; + file6SharedLink = `${shareLinkPreUrl}${sharedId}`; + await apis.user.shared.waitForApi({ expect: 1 }); done(); }); afterAll(async (done) => { - await apis.user.nodes.deleteNodeById(file1Id); - await apis.user.nodes.deleteNodeById(file2Id); - await apis.user.nodes.deleteNodeById(file3Id); - await apis.user.nodes.deleteNodeById(file4Id); - await apis.user.nodes.deleteNodeById(file5Id); await apis.user.nodes.deleteNodeById(file6Id); - await apis.user.nodes.deleteNodeById(file7Id); await apis.user.shared.waitForApi({ expect: 0 }); done(); }); - it('Share dialog default values - [C286648]', async () => { - await dataTable.selectItem(file1); - await toolbar.clickSharedLinkSettings(); - await shareDialog.waitForDialogToOpen(); - - expect(await shareDialog.getTitle()).toEqual(`Share ${file1}`); - expect(await shareDialog.getInfoText()).toEqual('Click the link below to copy it to the clipboard.'); - expect(await shareDialog.getLabels().get(0).getText()).toEqual('Link to share'); - expect(await shareDialog.getLinkUrl()).toContain('/preview/s/'); - expect(await shareDialog.isUrlReadOnly()).toBe('true', 'url is not readonly'); - expect(await shareDialog.isShareToggleChecked()).toBe(true, 'Share toggle not checked'); - expect(await shareDialog.getLabels().get(1).getText()).toEqual('Expires on'); - expect(await shareDialog.isExpireToggleEnabled()).toBe(false, 'Expire toggle is checked'); - expect(await shareDialog.isCloseEnabled()).toBe(true, 'Close button is not enabled'); - }); - - it('Close dialog - [C286649]', async () => { - await dataTable.selectItem(file2); - await toolbar.clickSharedLinkSettings(); - await shareDialog.waitForDialogToOpen(); - - expect(await shareDialog.isCloseEnabled()).toBe(true, 'Close button is not enabled'); - await shareDialog.clickClose(); - expect(await shareDialog.isDialogOpen()).toBe(false, 'Share dialog is open'); - }); - - it('Copy shared file URL - [C286651]', async () => { - await dataTable.selectItem(file3); - await toolbar.clickSharedLinkSettings(); - await shareDialog.waitForDialogToOpen(); - const url = await shareDialog.getLinkUrl(); - expect(url).toContain('/preview/s/'); - - await shareDialog.copyUrl(); - expect(await page.getSnackBarMessage()).toBe('Link copied to the clipboard'); - - await browser.get(url); + it('A non-logged user can download the shared file from the viewer - [C286326]', async () => { + await browser.get(file6SharedLink); expect(await viewer.isViewerOpened()).toBe(true, 'viewer is not open'); - expect(await viewer.getFileTitle()).toEqual(file3); - - await page.load(); - }); - - it('Expire date is displayed correctly - [C286653]', async () => { - await dataTable.selectItem(file4); - await toolbar.clickSharedLinkSettings(); - await shareDialog.waitForDialogToOpen(); + expect(await viewer.getFileTitle()).toEqual(file6); - const expireProperty = await apis.user.nodes.getSharedExpiryDate(file4Id); - expect(expireProperty).toEqual(expiryDate); - expect(await shareDialog.isExpireToggleEnabled()).toBe(true, 'Expiration is not checked'); - expect(Utils.formatDate(await shareDialog.getExpireDate())).toEqual(Utils.formatDate(expiryDate)); + await toolbar.clickDownload(); + expect(await Utils.fileExistsOnOS(file6)).toBe(true, 'File not found in download location'); }); + }) - it('Disable the share link expiration - [C286654]', async () => { - await dataTable.selectItem(file5); - await toolbar.clickSharedLinkSettings(); - await shareDialog.waitForDialogToOpen(); - - expect(await shareDialog.isExpireToggleEnabled()).toBe(true, 'Expiration is not checked'); - expect(await shareDialog.getExpireDate()).not.toBe('', 'Expire date input is empty'); - - await shareDialog.clickExpirationToggle(); - expect(await shareDialog.isExpireToggleEnabled()).toBe(false, 'Expiration is checked'); - expect(await shareDialog.getExpireDate()).toBe('', 'Expire date input is not empty'); - - await shareDialog.clickClose(); - expect(await apis.user.nodes.getSharedExpiryDate(file5Id)).toBe(undefined, `${file5} link still has expiration`); - }); - - it('Shared file URL is not changed when Share dialog is closed and opened again - [C286655]', async () => { - await dataTable.selectItem(file6); - await toolbar.clickSharedLinkSettings(); - await shareDialog.waitForDialogToOpen(); - const url1 = await shareDialog.getLinkUrl(); - await shareDialog.clickClose(); - await shareDialog.waitForDialogToClose(); - - await page.dataTable.clearSelection(); - await dataTable.selectItem(file6); - await toolbar.clickSharedLinkSettings(); - await shareDialog.waitForDialogToOpen(); - const url2 = await shareDialog.getLinkUrl(); - - expect(url1).toEqual(url2); - }); - - it('Open Share dialog from context menu - [C286656]', async () => { - await dataTable.rightClickOnItem(file7); - await contextMenu.waitForMenuToOpen(); - await contextMenu.clickSharedLinkSettings(); - await shareDialog.waitForDialogToOpen(); - - expect(await shareDialog.getTitle()).toEqual(`Share ${file7}`); - expect(await shareDialog.getInfoText()).toEqual('Click the link below to copy it to the clipboard.'); - expect(await shareDialog.getLabels().get(0).getText()).toEqual('Link to share'); - expect(await shareDialog.getLinkUrl()).toContain('/preview/s/'); - expect(await shareDialog.isUrlReadOnly()).toBe('true', 'url is not readonly'); - expect(await shareDialog.isShareToggleChecked()).toBe(true, 'Share toggle not checked'); - expect(await shareDialog.getLabels().get(1).getText()).toEqual('Expires on'); - expect(await shareDialog.isExpireToggleEnabled()).toBe(false, 'Expire toggle is checked'); - expect(await shareDialog.isCloseEnabled()).toBe(true, 'Close button is not enabled'); - }); - }); + describe('when logged in', () => { + const expiryDate: any = '2020-12-25T18:30:00.000+0000'; - describe('from Favorites', () => { - - const file1 = `file1-${Utils.random()}.txt`; let file1Id; - const file2 = `file2-${Utils.random()}.txt`; let file2Id; - const file3 = `file3-${Utils.random()}.txt`; let file3Id; - const file4 = `file4-${Utils.random()}.txt`; let file4Id; - const file5 = `file5-${Utils.random()}.txt`; let file5Id; - const file6 = `file6-${Utils.random()}.txt`; let file6Id; - const file7 = `file7-${Utils.random()}.txt`; let file7Id; - const file8 = `file8-${Utils.random()}.txt`; let file8Id; - const file9 = `file9-${Utils.random()}.txt`; let file9Id; + const loginPage = new LoginPage(); + const shareDialog = new ShareDialog(); + const contextMenu = dataTable.menu; + const { searchInput } = page.header; beforeAll(async (done) => { - file1Id = (await apis.user.nodes.createFile(file1, parentId)).entry.id; - file2Id = (await apis.user.nodes.createFile(file2, parentId)).entry.id; - file3Id = (await apis.user.nodes.createFile(file3, parentId)).entry.id; - file4Id = (await apis.user.nodes.createFile(file4, parentId)).entry.id; - file5Id = (await apis.user.nodes.createFile(file5, parentId)).entry.id; - file6Id = (await apis.user.nodes.createFile(file6, parentId)).entry.id; - file7Id = (await apis.user.nodes.createFile(file7, parentId)).entry.id; - file8Id = (await apis.user.nodes.createFile(file8, parentId)).entry.id; - file9Id = (await apis.user.nodes.createFile(file9, parentId)).entry.id; - - await apis.user.favorites.addFavoriteById('file', file1Id); - await apis.user.favorites.addFavoriteById('file', file2Id); - await apis.user.favorites.addFavoriteById('file', file3Id); - await apis.user.favorites.addFavoriteById('file', file4Id); - await apis.user.favorites.addFavoriteById('file', file5Id); - await apis.user.favorites.addFavoriteById('file', file6Id); - await apis.user.favorites.addFavoriteById('file', file7Id); - await apis.user.favorites.addFavoriteById('file', file8Id); - await apis.user.favorites.addFavoriteById('file', file9Id); - - await apis.user.shared.shareFileById(file6Id, expiryDate); - await apis.user.shared.shareFileById(file7Id, expiryDate); - await apis.user.favorites.waitForApi({ expect: 9 }); - await apis.user.shared.waitForApi({ expect: 2 }); - done(); - }); - - beforeEach(async (done) => { - await page.clickFavoritesAndWait(); + await loginPage.loginWith(username); done(); }); - afterEach(async (done) => { - await Utils.pressEscape(); - await page.clickPersonalFilesAndWait(); - done(); - }); - - afterAll(async (done) => { - await apis.user.nodes.deleteNodeById(file1Id); - await apis.user.nodes.deleteNodeById(file2Id); - await apis.user.nodes.deleteNodeById(file3Id); - await apis.user.nodes.deleteNodeById(file4Id); - await apis.user.nodes.deleteNodeById(file5Id); - await apis.user.nodes.deleteNodeById(file6Id); - await apis.user.nodes.deleteNodeById(file7Id); - await apis.user.nodes.deleteNodeById(file8Id); - await apis.user.nodes.deleteNodeById(file9Id); - await apis.user.shared.waitForApi({ expect: 0 }); - done(); - }); - - it('Share dialog default values - [C286666]', async () => { - await dataTable.selectItem(file1); - await toolbar.clickShare(); - await shareDialog.waitForDialogToOpen(); - - expect(await shareDialog.getTitle()).toEqual(`Share ${file1}`); - expect(await shareDialog.getInfoText()).toEqual('Click the link below to copy it to the clipboard.'); - expect(await shareDialog.getLabels().get(0).getText()).toEqual('Link to share'); - expect(await shareDialog.getLinkUrl()).toContain('/preview/s/'); - expect(await shareDialog.isUrlReadOnly()).toBe('true', 'url is not readonly'); - expect(await shareDialog.isShareToggleChecked()).toBe(true, 'Share toggle not checked'); - expect(await shareDialog.getLabels().get(1).getText()).toEqual('Expires on'); - expect(await shareDialog.isExpireToggleEnabled()).toBe(false, 'Expire toggle is checked'); - expect(await shareDialog.isCloseEnabled()).toBe(true, 'Close button is not enabled'); - }); - - it('Close dialog - [C286667]', async () => { - await dataTable.selectItem(file2); - await toolbar.clickShare(); - await shareDialog.waitForDialogToOpen(); - - expect(await shareDialog.isCloseEnabled()).toBe(true, 'Close button is not enabled'); - await shareDialog.clickClose(); - expect(await shareDialog.isDialogOpen()).toBe(false, 'Share dialog is open'); - }); - - it('Share a file - [C286668]', async () => { - await dataTable.selectItem(file3); - await toolbar.clickShare(); - await shareDialog.waitForDialogToOpen(); - - const url = await shareDialog.getLinkUrl(); - await Utils.pressEscape(); - const sharedId = await apis.user.nodes.getSharedId(file3Id); - expect(await apis.user.nodes.isFileShared(file3Id)).toBe(true, `${file3} is not shared`); - expect(url).toContain(sharedId); - }); - - it('Copy shared file URL - [C286669]', async () => { - await dataTable.selectItem(file4); - await toolbar.clickShare(); - await shareDialog.waitForDialogToOpen(); - const url = await shareDialog.getLinkUrl(); - expect(url).toContain('/preview/s/'); - - await shareDialog.copyUrl(); - expect(await page.getSnackBarMessage()).toBe('Link copied to the clipboard'); - - await browser.get(url); - expect(await viewer.isViewerOpened()).toBe(true, 'viewer is not open'); - expect(await viewer.getFileTitle()).toEqual(file4); - - await page.load(); - }); - - it('Share a file with expiration date - [C286670]', async () => { - await dataTable.selectItem(file5); - await toolbar.clickShare(); - await shareDialog.waitForDialogToOpen(); - - await shareDialog.clickExpirationToggle(); - expect(await shareDialog.isExpireToggleEnabled()).toBe(true, 'Expire toggle not checked'); - expect(await shareDialog.dateTimePicker.isCalendarOpen()).toBe(true, 'Calendar not opened'); - const date = await shareDialog.dateTimePicker.setDefaultDay(); - await shareDialog.dateTimePicker.waitForDateTimePickerToClose(); - - const setDate = (`${date}`).replace(',', ''); - const inputDate = await shareDialog.getExpireDate(); - - expect(new Date(inputDate)).toEqual(new Date(setDate)); - - const expireDateProperty = await apis.user.nodes.getSharedExpiryDate(file5Id); - - expect(Utils.formatDate(expireDateProperty)).toEqual(Utils.formatDate(inputDate)); - }); - - it('Expire date is displayed correctly - [C286671]', async () => { - await dataTable.selectItem(file6); - await toolbar.clickShare(); - await shareDialog.waitForDialogToOpen(); - - const expireProperty = await apis.user.nodes.getSharedExpiryDate(file6Id); - expect(expireProperty).toEqual(expiryDate); - expect(await shareDialog.isExpireToggleEnabled()).toBe(true, 'Expiration is not checked'); - expect(Utils.formatDate(await shareDialog.getExpireDate())).toEqual(Utils.formatDate(expiryDate)); - }); - - it('Disable the share link expiration - [C286672]', async () => { - await dataTable.selectItem(file7); - await toolbar.clickShare(); - await shareDialog.waitForDialogToOpen(); - - expect(await shareDialog.isExpireToggleEnabled()).toBe(true, 'Expiration is not checked'); - expect(await shareDialog.getExpireDate()).not.toBe('', 'Expire date input is empty'); - - await shareDialog.clickExpirationToggle(); - expect(await shareDialog.isExpireToggleEnabled()).toBe(false, 'Expiration is checked'); - expect(await shareDialog.getExpireDate()).toBe('', 'Expire date input is not empty'); - - await shareDialog.clickClose(); - expect(await apis.user.nodes.getSharedExpiryDate(file7Id)).toBe(undefined, `${file7} link still has expiration`); - }); - - it('Shared file URL is not changed when Share dialog is closed and opened again - [C286673]', async () => { - await dataTable.selectItem(file8); - await toolbar.clickShare(); - await shareDialog.waitForDialogToOpen(); - const url1 = await shareDialog.getLinkUrl(); - await shareDialog.clickClose(); - await shareDialog.waitForDialogToClose(); - - await page.dataTable.clearSelection(); - await dataTable.selectItem(file8); - await toolbar.clickShare(); - await shareDialog.waitForDialogToOpen(); - const url2 = await shareDialog.getLinkUrl(); - - expect(url1).toEqual(url2); - }); - - it('Share a file from the context menu - [C286674]', async () => { - await dataTable.rightClickOnItem(file9); - await contextMenu.waitForMenuToOpen(); - await contextMenu.clickShare(); - await shareDialog.waitForDialogToOpen(); - - const url = await shareDialog.getLinkUrl(); - await Utils.pressEscape(); - const sharedId = await apis.user.nodes.getSharedId(file9Id); - expect(await apis.user.nodes.isFileShared(file9Id)).toBe(true, `${file9} is not shared`); - expect(url).toContain(sharedId); - }); - }); - - describe('from Search Results', () => { - const file3 = `search-file3-${Utils.random()}.txt`; let file3Id; - const file5 = `search-file5-${Utils.random()}.txt`; let file5Id; - const file6 = `search-file6-${Utils.random()}.txt`; let file6Id; - const file7 = `search-file7-${Utils.random()}.txt`; let file7Id; - const file9 = `search-file9-${Utils.random()}.txt`; let file9Id; - - beforeAll(async (done) => { - file3Id = (await apis.user.nodes.createFile(file3, parentId)).entry.id; - file5Id = (await apis.user.nodes.createFile(file5, parentId)).entry.id; - file6Id = (await apis.user.nodes.createFile(file6, parentId)).entry.id; - file7Id = (await apis.user.nodes.createFile(file7, parentId)).entry.id; - file9Id = (await apis.user.nodes.createFile(file9, parentId)).entry.id; - await apis.user.shared.shareFileById(file6Id, expiryDate); - await apis.user.shared.shareFileById(file7Id, expiryDate); - await apis.user.shared.waitForApi({ expect: 2 }); - await apis.user.search.waitForNodes('search-f', { expect: 5 }); - done(); - }); - - beforeEach(async done => { - await searchInput.clickSearchButton(); - await searchInput.checkFilesAndFolders(); - await searchInput.searchFor('search-f'); - await dataTable.waitForBody(); - done(); - }); - - afterEach(async (done) => { - await Utils.pressEscape(); - await page.clickPersonalFilesAndWait(); - done(); - }); - - afterAll(async (done) => { - await apis.user.nodes.deleteNodeById(file3Id); - await apis.user.nodes.deleteNodeById(file5Id); - await apis.user.nodes.deleteNodeById(file6Id); - await apis.user.nodes.deleteNodeById(file7Id); - await apis.user.nodes.deleteNodeById(file9Id); - await apis.user.shared.waitForApi({ expect: 0 }); - done(); - }); - - it('Share a file - [C306975]', async () => { - await dataTable.selectItem(file3); - await toolbar.clickShare(); - await shareDialog.waitForDialogToOpen(); - - const url = await shareDialog.getLinkUrl(); - await Utils.pressEscape(); - const sharedId = await apis.user.nodes.getSharedId(file3Id); - expect(await apis.user.nodes.isFileShared(file3Id)).toBe(true, `${file3} is not shared`); - expect(url).toContain(sharedId); - }); - - it('Share a file with expiration date - [C306977]', async () => { - await dataTable.selectItem(file5); - await toolbar.clickShare(); - await shareDialog.waitForDialogToOpen(); - - await shareDialog.clickExpirationToggle(); - expect(await shareDialog.isExpireToggleEnabled()).toBe(true, 'Expire toggle not checked'); - expect(await shareDialog.dateTimePicker.isCalendarOpen()).toBe(true, 'Calendar not opened'); - const date = await shareDialog.dateTimePicker.setDefaultDay(); - await shareDialog.dateTimePicker.waitForDateTimePickerToClose(); - - const setDate = (`${date}`).replace(',', ''); - const inputDate = await shareDialog.getExpireDate(); - - expect(new Date(inputDate)).toEqual(new Date(setDate)); - - const expireDateProperty = await apis.user.nodes.getSharedExpiryDate(file5Id); - - expect(Utils.formatDate(expireDateProperty)).toEqual(Utils.formatDate(inputDate)); - }); - - it('Expire date is displayed correctly - [C306978]', async () => { - await dataTable.selectItem(file6); - await toolbar.clickSharedLinkSettings(); - await shareDialog.waitForDialogToOpen(); - - const expireProperty = await apis.user.nodes.getSharedExpiryDate(file6Id); - expect(expireProperty).toEqual(expiryDate); - expect(await shareDialog.isExpireToggleEnabled()).toBe(true, 'Expiration is not checked'); - expect(Utils.formatDate(await shareDialog.getExpireDate())).toEqual(Utils.formatDate(expiryDate)); - }); - - it('Disable the share link expiration - [C306979]', async () => { - await dataTable.selectItem(file7); - await toolbar.clickSharedLinkSettings(); - await shareDialog.waitForDialogToOpen(); - - expect(await shareDialog.isExpireToggleEnabled()).toBe(true, 'Expiration is not checked'); - expect(await shareDialog.getExpireDate()).not.toBe('', 'Expire date input is empty'); - - await shareDialog.clickExpirationToggle(); - expect(await shareDialog.isExpireToggleEnabled()).toBe(false, 'Expiration is checked'); - expect(await shareDialog.getExpireDate()).toBe('', 'Expire date input is not empty'); - - await shareDialog.clickClose(); - expect(await apis.user.nodes.getSharedExpiryDate(file7Id)).toBe(undefined, `${file7} link still has expiration`); - }); - - it('Share a file from the context menu - [C306981]', async () => { - await dataTable.rightClickOnItem(file9); - await contextMenu.waitForMenuToOpen(); - await contextMenu.clickShare(); - await shareDialog.waitForDialogToOpen(); - - const url = await shareDialog.getLinkUrl(); - await Utils.pressEscape(); - const sharedId = await apis.user.nodes.getSharedId(file9Id); - expect(await apis.user.nodes.isFileShared(file9Id)).toBe(true, `${file9} is not shared`); - expect(url).toContain(sharedId); - }); - }); - + describe('from Personal Files', () => { + + beforeAll(async (done) => { + file1Id = (await apis.user.nodes.createFile(file1, parentId)).entry.id; + file2Id = (await apis.user.nodes.createFile(file2, parentId)).entry.id; + file3Id = (await apis.user.nodes.createFile(file3, parentId)).entry.id; + file4Id = (await apis.user.nodes.createFile(file4, parentId)).entry.id; + file5Id = (await apis.user.nodes.createFile(file5, parentId)).entry.id; + file6Id = (await apis.user.nodes.createFile(file6, parentId)).entry.id; + file7Id = (await apis.user.nodes.createFile(file7, parentId)).entry.id; + file8Id = (await apis.user.nodes.createFile(file8, parentId)).entry.id; + file9Id = (await apis.user.nodes.createFile(file9, parentId)).entry.id; + await apis.user.shared.shareFileById(file6Id, expiryDate); + await apis.user.shared.shareFileById(file7Id, expiryDate); + await apis.user.shared.waitForApi({ expect: 2 }); + done(); + }); + + beforeEach(async (done) => { + await page.clickPersonalFilesAndWait(); + await dataTable.doubleClickOnRowByName(parent); + await dataTable.waitForHeader(); + done(); + }); + + afterEach(async (done) => { + await Utils.pressEscape(); + done(); + }); + + afterAll(async (done) => { + await apis.user.nodes.deleteNodeById(file1Id); + await apis.user.nodes.deleteNodeById(file2Id); + await apis.user.nodes.deleteNodeById(file3Id); + await apis.user.nodes.deleteNodeById(file4Id); + await apis.user.nodes.deleteNodeById(file5Id); + await apis.user.nodes.deleteNodeById(file6Id); + await apis.user.nodes.deleteNodeById(file7Id); + await apis.user.nodes.deleteNodeById(file8Id); + await apis.user.nodes.deleteNodeById(file9Id); + await apis.user.shared.waitForApi({ expect: 0 }); + done(); + }); + + it('Share dialog default values - [C286327]', async () => { + await dataTable.selectItem(file1); + await toolbar.clickShare(); + await shareDialog.waitForDialogToOpen(); + + expect(await shareDialog.getTitle()).toEqual(`Share ${file1}`); + expect(await shareDialog.getInfoText()).toEqual('Click the link below to copy it to the clipboard.'); + expect(await shareDialog.getLabels().get(0).getText()).toEqual('Link to share'); + expect(await shareDialog.getLinkUrl()).toContain(shareLinkPreUrl); + expect(await shareDialog.isUrlReadOnly()).toBe('true', 'url is not readonly'); + expect(await shareDialog.isShareToggleChecked()).toBe(true, 'Share toggle not checked'); + expect(await shareDialog.getLabels().get(1).getText()).toEqual('Expires on'); + expect(await shareDialog.isExpireToggleEnabled()).toBe(false, 'Expire toggle is checked'); + expect(await shareDialog.isCloseEnabled()).toBe(true, 'Close button is not enabled'); + }); + + it('Close dialog - [C286328]', async () => { + await dataTable.selectItem(file2); + await toolbar.clickShare(); + await shareDialog.waitForDialogToOpen(); + + expect(await shareDialog.isCloseEnabled()).toBe(true, 'Close button is not enabled'); + await shareDialog.clickClose(); + expect(await shareDialog.isDialogOpen()).toBe(false, 'Share dialog is open'); + }); + + it('Share a file - [C286329]', async () => { + await dataTable.selectItem(file3); + await toolbar.clickShare(); + await shareDialog.waitForDialogToOpen(); + + const url = await shareDialog.getLinkUrl(); + await Utils.pressEscape(); + const sharedId = await apis.user.nodes.getSharedId(file3Id); + expect(await apis.user.nodes.isFileShared(file3Id)).toBe(true, `${file3} is not shared`); + expect(url).toContain(sharedId); + }); + + it('Copy shared file URL - [C286330]', async () => { + await dataTable.selectItem(file4); + await toolbar.clickShare(); + await shareDialog.waitForDialogToOpen(); + const url = await shareDialog.getLinkUrl(); + expect(url).toContain(shareLinkPreUrl); + + await shareDialog.copyUrl(); + expect(await page.getSnackBarMessage()).toBe('Link copied to the clipboard'); + + await browser.get(url); + expect(await viewer.isViewerOpened()).toBe(true, 'viewer is not open'); + expect(await viewer.getFileTitle()).toEqual(file4); + + await page.load(); + }); + + it('Share a file with expiration date - [C286332]', async () => { + await dataTable.selectItem(file5); + await toolbar.clickShare(); + await shareDialog.waitForDialogToOpen(); + + await shareDialog.clickExpirationToggle(); + expect(await shareDialog.isExpireToggleEnabled()).toBe(true, 'Expire toggle not checked'); + expect(await shareDialog.dateTimePicker.isCalendarOpen()).toBe(true, 'Calendar not opened'); + const date = await shareDialog.dateTimePicker.setDefaultDay(); + await shareDialog.dateTimePicker.waitForDateTimePickerToClose(); + + const setDate = (`${date}`).replace(',', ''); + const inputDate = await shareDialog.getExpireDate(); + + expect(new Date(inputDate)).toEqual(new Date(setDate)); + + const expireDateProperty = await apis.user.nodes.getSharedExpiryDate(file5Id); + + expect(Utils.formatDate(expireDateProperty)).toEqual(Utils.formatDate(inputDate)); + }); + + it('Expire date is displayed correctly - [C286337]', async () => { + await dataTable.selectItem(file6); + await toolbar.clickSharedLinkSettings(); + await shareDialog.waitForDialogToOpen(); + + const expireProperty = await apis.user.nodes.getSharedExpiryDate(file6Id); + expect(expireProperty).toEqual(expiryDate); + expect(await shareDialog.isExpireToggleEnabled()).toBe(true, 'Expiration is not checked'); + expect(Utils.formatDate(await shareDialog.getExpireDate())).toEqual(Utils.formatDate(expiryDate)); + }); + + it('Disable the share link expiration - [C286333]', async () => { + await dataTable.selectItem(file7); + await toolbar.clickSharedLinkSettings(); + await shareDialog.waitForDialogToOpen(); + + expect(await shareDialog.isExpireToggleEnabled()).toBe(true, 'Expiration is not checked'); + expect(await shareDialog.getExpireDate()).not.toBe('', 'Expire date input is empty'); + + await shareDialog.clickExpirationToggle(); + expect(await shareDialog.isExpireToggleEnabled()).toBe(false, 'Expiration is checked'); + expect(await shareDialog.getExpireDate()).toBe('', 'Expire date input is not empty'); + + await shareDialog.clickClose(); + expect(await apis.user.nodes.getSharedExpiryDate(file7Id)).toBe(undefined, `${file7} link still has expiration`); + }); + + it('Shared file URL is not changed when Share dialog is closed and opened again - [C286335]', async () => { + await dataTable.selectItem(file8); + await toolbar.clickShare(); + await shareDialog.waitForDialogToOpen(); + const url1 = await shareDialog.getLinkUrl(); + await shareDialog.clickClose(); + await shareDialog.waitForDialogToClose(); + + await page.dataTable.clearSelection(); + await dataTable.selectItem(file8); + await toolbar.clickSharedLinkSettings(); + await shareDialog.waitForDialogToOpen(); + const url2 = await shareDialog.getLinkUrl(); + + expect(url1).toEqual(url2); + }); + + it('Share a file from the context menu - [C286345]', async () => { + await dataTable.rightClickOnItem(file9); + await contextMenu.waitForMenuToOpen(); + await contextMenu.clickShare(); + await shareDialog.waitForDialogToOpen(); + + const url = await shareDialog.getLinkUrl(); + await Utils.pressEscape(); + const sharedId = await apis.user.nodes.getSharedId(file9Id); + expect(await apis.user.nodes.isFileShared(file9Id)).toBe(true, `${file9} is not shared`); + expect(url).toContain(sharedId); + }); + }); + + describe('from File Libraries', () => { + + const siteName = `site-${Utils.random()}`; + const parentInSite = `parent-site-${Utils.random()}`; let parentInSiteId; + + beforeAll(async (done) => { + await apis.user.sites.createSite(siteName, SITE_VISIBILITY.PUBLIC); + const docLibId = await apis.user.sites.getDocLibId(siteName); + parentInSiteId = (await apis.user.nodes.createFolder(parentInSite, docLibId)).entry.id; + + await apis.user.nodes.createFile(file1, parentInSiteId); + await apis.user.nodes.createFile(file2, parentInSiteId); + file3Id = (await apis.user.nodes.createFile(file3, parentInSiteId)).entry.id; + await apis.user.nodes.createFile(file4, parentInSiteId); + file5Id = (await apis.user.nodes.createFile(file5, parentInSiteId)).entry.id; + file6Id = (await apis.user.nodes.createFile(file6, parentInSiteId)).entry.id; + file7Id = (await apis.user.nodes.createFile(file7, parentInSiteId)).entry.id; + await apis.user.nodes.createFile(file8, parentInSiteId); + file9Id = (await apis.user.nodes.createFile(file9, parentInSiteId)).entry.id; + await apis.user.shared.shareFileById(file6Id, expiryDate); + await apis.user.shared.shareFileById(file7Id, expiryDate); + await apis.user.shared.waitForApi({ expect: 2 }); + done(); + }); + + beforeEach(async (done) => { + await page.goToMyLibrariesAndWait(); + await dataTable.doubleClickOnRowByName(siteName); + await dataTable.waitForHeader(); + await dataTable.doubleClickOnRowByName(parentInSite); + await dataTable.waitForHeader(); + done(); + }); + + afterEach(async (done) => { + await Utils.pressEscape(); + await page.clickPersonalFilesAndWait(); + done(); + }); + + afterAll(async (done) => { + await apis.admin.sites.deleteSite(siteName); + await apis.user.shared.waitForApi({ expect: 0 }); + done(); + }); + + it('Share dialog default values - [C286639]', async () => { + await dataTable.selectItem(file1); + await toolbar.clickShare(); + await shareDialog.waitForDialogToOpen(); + + expect(await shareDialog.getTitle()).toEqual(`Share ${file1}`); + expect(await shareDialog.getInfoText()).toEqual('Click the link below to copy it to the clipboard.'); + expect(await shareDialog.getLabels().get(0).getText()).toEqual('Link to share'); + expect(await shareDialog.getLinkUrl()).toContain(shareLinkPreUrl); + expect(await shareDialog.isUrlReadOnly()).toBe('true', 'url is not readonly'); + expect(await shareDialog.isShareToggleChecked()).toBe(true, 'Share toggle not checked'); + expect(await shareDialog.getLabels().get(1).getText()).toEqual('Expires on'); + expect(await shareDialog.isExpireToggleEnabled()).toBe(false, 'Expire toggle is checked'); + expect(await shareDialog.isCloseEnabled()).toBe(true, 'Close button is not enabled'); + }); + + it('Close dialog - [C286640]', async () => { + await dataTable.selectItem(file2); + await toolbar.clickShare(); + await shareDialog.waitForDialogToOpen(); + + expect(await shareDialog.isCloseEnabled()).toBe(true, 'Close button is not enabled'); + await shareDialog.clickClose(); + expect(await shareDialog.isDialogOpen()).toBe(false, 'Share dialog is open'); + }); + + it('Share a file - [C286641]', async () => { + await dataTable.selectItem(file3); + await toolbar.clickShare(); + await shareDialog.waitForDialogToOpen(); + + const url = await shareDialog.getLinkUrl(); + await Utils.pressEscape(); + const sharedId = await apis.user.nodes.getSharedId(file3Id); + expect(await apis.user.nodes.isFileShared(file3Id)).toBe(true, `${file3} is not shared`); + expect(url).toContain(sharedId); + }); + + it('Copy shared file URL - [C286642]', async () => { + await dataTable.selectItem(file4); + await toolbar.clickShare(); + await shareDialog.waitForDialogToOpen(); + const url = await shareDialog.getLinkUrl(); + expect(url).toContain(shareLinkPreUrl); + + await shareDialog.copyUrl(); + expect(await page.getSnackBarMessage()).toBe('Link copied to the clipboard'); + + await browser.get(url); + expect(await viewer.isViewerOpened()).toBe(true, 'viewer is not open'); + expect(await viewer.getFileTitle()).toEqual(file4); + + await page.load(); + }); + + it('Share a file with expiration date - [C286643]', async () => { + await dataTable.selectItem(file5); + await toolbar.clickShare(); + await shareDialog.waitForDialogToOpen(); + + await shareDialog.clickExpirationToggle(); + expect(await shareDialog.isExpireToggleEnabled()).toBe(true, 'Expire toggle not checked'); + expect(await shareDialog.dateTimePicker.isCalendarOpen()).toBe(true, 'Calendar not opened'); + const date = await shareDialog.dateTimePicker.setDefaultDay(); + await shareDialog.dateTimePicker.waitForDateTimePickerToClose(); + + const setDate = (`${date}`).replace(',', ''); + const inputDate = await shareDialog.getExpireDate(); + + expect(new Date(inputDate)).toEqual(new Date(setDate)); + + const expireDateProperty = await apis.user.nodes.getSharedExpiryDate(file5Id); + + expect(Utils.formatDate(expireDateProperty)).toEqual(Utils.formatDate(inputDate)); + }); + + it('Expire date is displayed correctly - [C286644]', async () => { + await dataTable.selectItem(file6); + await toolbar.clickSharedLinkSettings(); + await shareDialog.waitForDialogToOpen(); + + const expireProperty = await apis.user.nodes.getSharedExpiryDate(file6Id); + expect(expireProperty).toEqual(expiryDate); + expect(await shareDialog.isExpireToggleEnabled()).toBe(true, 'Expiration is not checked'); + expect(Utils.formatDate(await shareDialog.getExpireDate())).toEqual(Utils.formatDate(expiryDate)); + }); + + it('Disable the share link expiration - [C286645]', async () => { + await dataTable.selectItem(file7); + await toolbar.clickSharedLinkSettings(); + await shareDialog.waitForDialogToOpen(); + + expect(await shareDialog.isExpireToggleEnabled()).toBe(true, 'Expiration is not checked'); + expect(await shareDialog.getExpireDate()).not.toBe('', 'Expire date input is empty'); + + await shareDialog.clickExpirationToggle(); + expect(await shareDialog.isExpireToggleEnabled()).toBe(false, 'Expiration is checked'); + expect(await shareDialog.getExpireDate()).toBe('', 'Expire date input is not empty'); + + await shareDialog.clickClose(); + expect(await apis.user.nodes.getSharedExpiryDate(file7Id)).toBe(undefined, `${file7} link still has expiration`); + }); + + it('Shared file URL is not changed when Share dialog is closed and opened again - [C286646]', async () => { + await dataTable.selectItem(file8); + await toolbar.clickShare(); + await shareDialog.waitForDialogToOpen(); + const url1 = await shareDialog.getLinkUrl(); + await shareDialog.clickClose(); + await shareDialog.waitForDialogToClose(); + + await page.dataTable.clearSelection(); + await dataTable.selectItem(file8); + await toolbar.clickSharedLinkSettings(); + await shareDialog.waitForDialogToOpen(); + const url2 = await shareDialog.getLinkUrl(); + + expect(url1).toEqual(url2); + }); + + it('Share a file from the context menu - [C286647]', async () => { + await dataTable.rightClickOnItem(file9); + await contextMenu.waitForMenuToOpen(); + await contextMenu.clickShare(); + await shareDialog.waitForDialogToOpen(); + + const url = await shareDialog.getLinkUrl(); + await Utils.pressEscape(); + const sharedId = await apis.user.nodes.getSharedId(file9Id); + expect(await apis.user.nodes.isFileShared(file9Id)).toBe(true, `${file9} is not shared`); + expect(url).toContain(sharedId); + }); + }); + + describe('from Recent Files', () => { + + beforeAll(async (done) => { + file1Id = (await apis.user.nodes.createFile(file1, parentId)).entry.id; + file2Id = (await apis.user.nodes.createFile(file2, parentId)).entry.id; + file3Id = (await apis.user.nodes.createFile(file3, parentId)).entry.id; + file4Id = (await apis.user.nodes.createFile(file4, parentId)).entry.id; + file5Id = (await apis.user.nodes.createFile(file5, parentId)).entry.id; + file6Id = (await apis.user.nodes.createFile(file6, parentId)).entry.id; + file7Id = (await apis.user.nodes.createFile(file7, parentId)).entry.id; + file8Id = (await apis.user.nodes.createFile(file8, parentId)).entry.id; + file9Id = (await apis.user.nodes.createFile(file9, parentId)).entry.id; + await apis.user.shared.shareFileById(file6Id, expiryDate); + await apis.user.shared.shareFileById(file7Id, expiryDate); + await apis.user.shared.waitForApi({ expect: 2 }); + done(); + }); + + beforeEach(async (done) => { + await page.clickRecentFilesAndWait(); + done(); + }); + + afterEach(async (done) => { + await Utils.pressEscape(); + await page.clickPersonalFilesAndWait(); + done(); + }); + + afterAll(async (done) => { + await apis.user.nodes.deleteNodeById(file1Id); + await apis.user.nodes.deleteNodeById(file2Id); + await apis.user.nodes.deleteNodeById(file3Id); + await apis.user.nodes.deleteNodeById(file4Id); + await apis.user.nodes.deleteNodeById(file5Id); + await apis.user.nodes.deleteNodeById(file6Id); + await apis.user.nodes.deleteNodeById(file7Id); + await apis.user.nodes.deleteNodeById(file8Id); + await apis.user.nodes.deleteNodeById(file9Id); + await apis.user.shared.waitForApi({ expect: 0 }); + done(); + }); + + it('Share dialog default values - [C286657]', async () => { + await dataTable.selectItem(file1); + await toolbar.clickShare(); + await shareDialog.waitForDialogToOpen(); + + expect(await shareDialog.getTitle()).toEqual(`Share ${file1}`); + expect(await shareDialog.getInfoText()).toEqual('Click the link below to copy it to the clipboard.'); + expect(await shareDialog.getLabels().get(0).getText()).toEqual('Link to share'); + expect(await shareDialog.getLinkUrl()).toContain(shareLinkPreUrl); + expect(await shareDialog.isUrlReadOnly()).toBe('true', 'url is not readonly'); + expect(await shareDialog.isShareToggleChecked()).toBe(true, 'Share toggle not checked'); + expect(await shareDialog.getLabels().get(1).getText()).toEqual('Expires on'); + expect(await shareDialog.isExpireToggleEnabled()).toBe(false, 'Expire toggle is checked'); + expect(await shareDialog.isCloseEnabled()).toBe(true, 'Close button is not enabled'); + }); + + it('Close dialog - [C286658]', async () => { + await dataTable.selectItem(file2); + await toolbar.clickShare(); + await shareDialog.waitForDialogToOpen(); + + expect(await shareDialog.isCloseEnabled()).toBe(true, 'Close button is not enabled'); + await shareDialog.clickClose(); + expect(await shareDialog.isDialogOpen()).toBe(false, 'Share dialog is open'); + }); + + it('Share a file - [C286659]', async () => { + await dataTable.selectItem(file3); + await toolbar.clickShare(); + await shareDialog.waitForDialogToOpen(); + + const url = await shareDialog.getLinkUrl(); + await Utils.pressEscape(); + const sharedId = await apis.user.nodes.getSharedId(file3Id); + expect(await apis.user.nodes.isFileShared(file3Id)).toBe(true, `${file3} is not shared`); + expect(url).toContain(sharedId); + }); + + it('Copy shared file URL - [C286660]', async () => { + await dataTable.selectItem(file4); + await toolbar.clickShare(); + await shareDialog.waitForDialogToOpen(); + const url = await shareDialog.getLinkUrl(); + expect(url).toContain(shareLinkPreUrl); + + await shareDialog.copyUrl(); + expect(await page.getSnackBarMessage()).toBe('Link copied to the clipboard'); + + await browser.get(url); + expect(await viewer.isViewerOpened()).toBe(true, 'viewer is not open'); + expect(await viewer.getFileTitle()).toEqual(file4); + + await page.load(); + }); + + it('Share a file with expiration date - [C286661]', async () => { + await dataTable.selectItem(file5); + await toolbar.clickShare(); + await shareDialog.waitForDialogToOpen(); + + await shareDialog.clickExpirationToggle(); + expect(await shareDialog.isExpireToggleEnabled()).toBe(true, 'Expire toggle not checked'); + expect(await shareDialog.dateTimePicker.isCalendarOpen()).toBe(true, 'Calendar not opened'); + const date = await shareDialog.dateTimePicker.setDefaultDay(); + await shareDialog.dateTimePicker.waitForDateTimePickerToClose(); + + const setDate = (`${date}`).replace(',', ''); + const inputDate = await shareDialog.getExpireDate(); + + expect(new Date(inputDate)).toEqual(new Date(setDate)); + + const expireDateProperty = await apis.user.nodes.getSharedExpiryDate(file5Id); + + expect(Utils.formatDate(expireDateProperty)).toEqual(Utils.formatDate(inputDate)); + }); + + it('Expire date is displayed correctly - [C286662]', async () => { + await dataTable.selectItem(file6); + await toolbar.clickSharedLinkSettings(); + await shareDialog.waitForDialogToOpen(); + + const expireProperty = await apis.user.nodes.getSharedExpiryDate(file6Id); + expect(expireProperty).toEqual(expiryDate); + expect(await shareDialog.isExpireToggleEnabled()).toBe(true, 'Expiration is not checked'); + expect(Utils.formatDate(await shareDialog.getExpireDate())).toEqual(Utils.formatDate(expiryDate)); + }); + + it('Disable the share link expiration - [C286663]', async () => { + await dataTable.selectItem(file7); + await toolbar.clickSharedLinkSettings(); + await shareDialog.waitForDialogToOpen(); + + expect(await shareDialog.isExpireToggleEnabled()).toBe(true, 'Expiration is not checked'); + expect(await shareDialog.getExpireDate()).not.toBe('', 'Expire date input is empty'); + + await shareDialog.clickExpirationToggle(); + expect(await shareDialog.isExpireToggleEnabled()).toBe(false, 'Expiration is checked'); + expect(await shareDialog.getExpireDate()).toBe('', 'Expire date input is not empty'); + + await shareDialog.clickClose(); + expect(await apis.user.nodes.getSharedExpiryDate(file7Id)).toBe(undefined, `${file7} link still has expiration`); + }); + + it('Shared file URL is not changed when Share dialog is closed and opened again - [C286664]', async () => { + await dataTable.selectItem(file8); + await toolbar.clickShare(); + await shareDialog.waitForDialogToOpen(); + const url1 = await shareDialog.getLinkUrl(); + await shareDialog.clickClose(); + await shareDialog.waitForDialogToClose(); + + await page.dataTable.clearSelection(); + await dataTable.selectItem(file8); + await toolbar.clickSharedLinkSettings(); + await shareDialog.waitForDialogToOpen(); + const url2 = await shareDialog.getLinkUrl(); + + expect(url1).toEqual(url2); + }); + + it('Share a file from the context menu - [C286665]', async () => { + await dataTable.rightClickOnItem(file9); + await contextMenu.waitForMenuToOpen(); + await contextMenu.clickShare(); + await shareDialog.waitForDialogToOpen(); + + const url = await shareDialog.getLinkUrl(); + await Utils.pressEscape(); + const sharedId = await apis.user.nodes.getSharedId(file9Id); + expect(await apis.user.nodes.isFileShared(file9Id)).toBe(true, `${file9} is not shared`); + expect(url).toContain(sharedId); + }); + }); + + describe('from Shared Files', () => { + + beforeAll(async (done) => { + file1Id = (await apis.user.nodes.createFile(file1, parentId)).entry.id; + file2Id = (await apis.user.nodes.createFile(file2, parentId)).entry.id; + file3Id = (await apis.user.nodes.createFile(file3, parentId)).entry.id; + file4Id = (await apis.user.nodes.createFile(file4, parentId)).entry.id; + file5Id = (await apis.user.nodes.createFile(file5, parentId)).entry.id; + file6Id = (await apis.user.nodes.createFile(file6, parentId)).entry.id; + file7Id = (await apis.user.nodes.createFile(file7, parentId)).entry.id; + + await apis.user.shared.shareFileById(file1Id); + await apis.user.shared.shareFileById(file2Id); + await apis.user.shared.shareFileById(file3Id); + await apis.user.shared.shareFileById(file4Id, expiryDate); + await apis.user.shared.shareFileById(file5Id, expiryDate); + await apis.user.shared.shareFileById(file6Id); + await apis.user.shared.shareFileById(file7Id); + await apis.user.shared.waitForApi({ expect: 7 }); + done(); + }); + + beforeEach(async (done) => { + await page.clickSharedFilesAndWait(); + done(); + }); + + afterEach(async (done) => { + await Utils.pressEscape(); + await page.clickPersonalFilesAndWait(); + done(); + }); + + afterAll(async (done) => { + await apis.user.nodes.deleteNodeById(file1Id); + await apis.user.nodes.deleteNodeById(file2Id); + await apis.user.nodes.deleteNodeById(file3Id); + await apis.user.nodes.deleteNodeById(file4Id); + await apis.user.nodes.deleteNodeById(file5Id); + await apis.user.nodes.deleteNodeById(file6Id); + await apis.user.nodes.deleteNodeById(file7Id); + await apis.user.shared.waitForApi({ expect: 0 }); + done(); + }); + + it('Share dialog default values - [C286648]', async () => { + await dataTable.selectItem(file1); + await toolbar.clickSharedLinkSettings(); + await shareDialog.waitForDialogToOpen(); + + expect(await shareDialog.getTitle()).toEqual(`Share ${file1}`); + expect(await shareDialog.getInfoText()).toEqual('Click the link below to copy it to the clipboard.'); + expect(await shareDialog.getLabels().get(0).getText()).toEqual('Link to share'); + expect(await shareDialog.getLinkUrl()).toContain(shareLinkPreUrl); + expect(await shareDialog.isUrlReadOnly()).toBe('true', 'url is not readonly'); + expect(await shareDialog.isShareToggleChecked()).toBe(true, 'Share toggle not checked'); + expect(await shareDialog.getLabels().get(1).getText()).toEqual('Expires on'); + expect(await shareDialog.isExpireToggleEnabled()).toBe(false, 'Expire toggle is checked'); + expect(await shareDialog.isCloseEnabled()).toBe(true, 'Close button is not enabled'); + }); + + it('Close dialog - [C286649]', async () => { + await dataTable.selectItem(file2); + await toolbar.clickSharedLinkSettings(); + await shareDialog.waitForDialogToOpen(); + + expect(await shareDialog.isCloseEnabled()).toBe(true, 'Close button is not enabled'); + await shareDialog.clickClose(); + expect(await shareDialog.isDialogOpen()).toBe(false, 'Share dialog is open'); + }); + + it('Copy shared file URL - [C286651]', async () => { + await dataTable.selectItem(file3); + await toolbar.clickSharedLinkSettings(); + await shareDialog.waitForDialogToOpen(); + const url = await shareDialog.getLinkUrl(); + expect(url).toContain(shareLinkPreUrl); + + await shareDialog.copyUrl(); + expect(await page.getSnackBarMessage()).toBe('Link copied to the clipboard'); + + await browser.get(url); + expect(await viewer.isViewerOpened()).toBe(true, 'viewer is not open'); + expect(await viewer.getFileTitle()).toEqual(file3); + + await page.load(); + }); + + it('Expire date is displayed correctly - [C286653]', async () => { + await dataTable.selectItem(file4); + await toolbar.clickSharedLinkSettings(); + await shareDialog.waitForDialogToOpen(); + + const expireProperty = await apis.user.nodes.getSharedExpiryDate(file4Id); + expect(expireProperty).toEqual(expiryDate); + expect(await shareDialog.isExpireToggleEnabled()).toBe(true, 'Expiration is not checked'); + expect(Utils.formatDate(await shareDialog.getExpireDate())).toEqual(Utils.formatDate(expiryDate)); + }); + + it('Disable the share link expiration - [C286654]', async () => { + await dataTable.selectItem(file5); + await toolbar.clickSharedLinkSettings(); + await shareDialog.waitForDialogToOpen(); + + expect(await shareDialog.isExpireToggleEnabled()).toBe(true, 'Expiration is not checked'); + expect(await shareDialog.getExpireDate()).not.toBe('', 'Expire date input is empty'); + + await shareDialog.clickExpirationToggle(); + expect(await shareDialog.isExpireToggleEnabled()).toBe(false, 'Expiration is checked'); + expect(await shareDialog.getExpireDate()).toBe('', 'Expire date input is not empty'); + + await shareDialog.clickClose(); + expect(await apis.user.nodes.getSharedExpiryDate(file5Id)).toBe(undefined, `${file5} link still has expiration`); + }); + + it('Shared file URL is not changed when Share dialog is closed and opened again - [C286655]', async () => { + await dataTable.selectItem(file6); + await toolbar.clickSharedLinkSettings(); + await shareDialog.waitForDialogToOpen(); + const url1 = await shareDialog.getLinkUrl(); + await shareDialog.clickClose(); + await shareDialog.waitForDialogToClose(); + + await page.dataTable.clearSelection(); + await dataTable.selectItem(file6); + await toolbar.clickSharedLinkSettings(); + await shareDialog.waitForDialogToOpen(); + const url2 = await shareDialog.getLinkUrl(); + + expect(url1).toEqual(url2); + }); + + it('Open Share dialog from context menu - [C286656]', async () => { + await dataTable.rightClickOnItem(file7); + await contextMenu.waitForMenuToOpen(); + await contextMenu.clickSharedLinkSettings(); + await shareDialog.waitForDialogToOpen(); + + expect(await shareDialog.getTitle()).toEqual(`Share ${file7}`); + expect(await shareDialog.getInfoText()).toEqual('Click the link below to copy it to the clipboard.'); + expect(await shareDialog.getLabels().get(0).getText()).toEqual('Link to share'); + expect(await shareDialog.getLinkUrl()).toContain(shareLinkPreUrl); + expect(await shareDialog.isUrlReadOnly()).toBe('true', 'url is not readonly'); + expect(await shareDialog.isShareToggleChecked()).toBe(true, 'Share toggle not checked'); + expect(await shareDialog.getLabels().get(1).getText()).toEqual('Expires on'); + expect(await shareDialog.isExpireToggleEnabled()).toBe(false, 'Expire toggle is checked'); + expect(await shareDialog.isCloseEnabled()).toBe(true, 'Close button is not enabled'); + }); + }); + + describe('from Favorites', () => { + + beforeAll(async (done) => { + file1Id = (await apis.user.nodes.createFile(file1, parentId)).entry.id; + file2Id = (await apis.user.nodes.createFile(file2, parentId)).entry.id; + file3Id = (await apis.user.nodes.createFile(file3, parentId)).entry.id; + file4Id = (await apis.user.nodes.createFile(file4, parentId)).entry.id; + file5Id = (await apis.user.nodes.createFile(file5, parentId)).entry.id; + file6Id = (await apis.user.nodes.createFile(file6, parentId)).entry.id; + file7Id = (await apis.user.nodes.createFile(file7, parentId)).entry.id; + file8Id = (await apis.user.nodes.createFile(file8, parentId)).entry.id; + file9Id = (await apis.user.nodes.createFile(file9, parentId)).entry.id; + + await apis.user.favorites.addFavoriteById('file', file1Id); + await apis.user.favorites.addFavoriteById('file', file2Id); + await apis.user.favorites.addFavoriteById('file', file3Id); + await apis.user.favorites.addFavoriteById('file', file4Id); + await apis.user.favorites.addFavoriteById('file', file5Id); + await apis.user.favorites.addFavoriteById('file', file6Id); + await apis.user.favorites.addFavoriteById('file', file7Id); + await apis.user.favorites.addFavoriteById('file', file8Id); + await apis.user.favorites.addFavoriteById('file', file9Id); + + await apis.user.shared.shareFileById(file6Id, expiryDate); + await apis.user.shared.shareFileById(file7Id, expiryDate); + await apis.user.favorites.waitForApi({ expect: 9 }); + await apis.user.shared.waitForApi({ expect: 2 }); + done(); + }); + + beforeEach(async (done) => { + await page.clickFavoritesAndWait(); + done(); + }); + + afterEach(async (done) => { + await Utils.pressEscape(); + await page.clickPersonalFilesAndWait(); + done(); + }); + + afterAll(async (done) => { + await apis.user.nodes.deleteNodeById(file1Id); + await apis.user.nodes.deleteNodeById(file2Id); + await apis.user.nodes.deleteNodeById(file3Id); + await apis.user.nodes.deleteNodeById(file4Id); + await apis.user.nodes.deleteNodeById(file5Id); + await apis.user.nodes.deleteNodeById(file6Id); + await apis.user.nodes.deleteNodeById(file7Id); + await apis.user.nodes.deleteNodeById(file8Id); + await apis.user.nodes.deleteNodeById(file9Id); + await apis.user.shared.waitForApi({ expect: 0 }); + done(); + }); + + it('Share dialog default values - [C286666]', async () => { + await dataTable.selectItem(file1); + await toolbar.clickShare(); + await shareDialog.waitForDialogToOpen(); + + expect(await shareDialog.getTitle()).toEqual(`Share ${file1}`); + expect(await shareDialog.getInfoText()).toEqual('Click the link below to copy it to the clipboard.'); + expect(await shareDialog.getLabels().get(0).getText()).toEqual('Link to share'); + expect(await shareDialog.getLinkUrl()).toContain(shareLinkPreUrl); + expect(await shareDialog.isUrlReadOnly()).toBe('true', 'url is not readonly'); + expect(await shareDialog.isShareToggleChecked()).toBe(true, 'Share toggle not checked'); + expect(await shareDialog.getLabels().get(1).getText()).toEqual('Expires on'); + expect(await shareDialog.isExpireToggleEnabled()).toBe(false, 'Expire toggle is checked'); + expect(await shareDialog.isCloseEnabled()).toBe(true, 'Close button is not enabled'); + }); + + it('Close dialog - [C286667]', async () => { + await dataTable.selectItem(file2); + await toolbar.clickShare(); + await shareDialog.waitForDialogToOpen(); + + expect(await shareDialog.isCloseEnabled()).toBe(true, 'Close button is not enabled'); + await shareDialog.clickClose(); + expect(await shareDialog.isDialogOpen()).toBe(false, 'Share dialog is open'); + }); + + it('Share a file - [C286668]', async () => { + await dataTable.selectItem(file3); + await toolbar.clickShare(); + await shareDialog.waitForDialogToOpen(); + + const url = await shareDialog.getLinkUrl(); + await Utils.pressEscape(); + const sharedId = await apis.user.nodes.getSharedId(file3Id); + expect(await apis.user.nodes.isFileShared(file3Id)).toBe(true, `${file3} is not shared`); + expect(url).toContain(sharedId); + }); + + it('Copy shared file URL - [C286669]', async () => { + await dataTable.selectItem(file4); + await toolbar.clickShare(); + await shareDialog.waitForDialogToOpen(); + const url = await shareDialog.getLinkUrl(); + expect(url).toContain(shareLinkPreUrl); + + await shareDialog.copyUrl(); + expect(await page.getSnackBarMessage()).toBe('Link copied to the clipboard'); + + await browser.get(url); + expect(await viewer.isViewerOpened()).toBe(true, 'viewer is not open'); + expect(await viewer.getFileTitle()).toEqual(file4); + + await page.load(); + }); + + it('Share a file with expiration date - [C286670]', async () => { + await dataTable.selectItem(file5); + await toolbar.clickShare(); + await shareDialog.waitForDialogToOpen(); + + await shareDialog.clickExpirationToggle(); + expect(await shareDialog.isExpireToggleEnabled()).toBe(true, 'Expire toggle not checked'); + expect(await shareDialog.dateTimePicker.isCalendarOpen()).toBe(true, 'Calendar not opened'); + const date = await shareDialog.dateTimePicker.setDefaultDay(); + await shareDialog.dateTimePicker.waitForDateTimePickerToClose(); + + const setDate = (`${date}`).replace(',', ''); + const inputDate = await shareDialog.getExpireDate(); + + expect(new Date(inputDate)).toEqual(new Date(setDate)); + + const expireDateProperty = await apis.user.nodes.getSharedExpiryDate(file5Id); + + expect(Utils.formatDate(expireDateProperty)).toEqual(Utils.formatDate(inputDate)); + }); + + it('Expire date is displayed correctly - [C286671]', async () => { + await dataTable.selectItem(file6); + await toolbar.clickShare(); + await shareDialog.waitForDialogToOpen(); + + const expireProperty = await apis.user.nodes.getSharedExpiryDate(file6Id); + expect(expireProperty).toEqual(expiryDate); + expect(await shareDialog.isExpireToggleEnabled()).toBe(true, 'Expiration is not checked'); + expect(Utils.formatDate(await shareDialog.getExpireDate())).toEqual(Utils.formatDate(expiryDate)); + }); + + it('Disable the share link expiration - [C286672]', async () => { + await dataTable.selectItem(file7); + await toolbar.clickShare(); + await shareDialog.waitForDialogToOpen(); + + expect(await shareDialog.isExpireToggleEnabled()).toBe(true, 'Expiration is not checked'); + expect(await shareDialog.getExpireDate()).not.toBe('', 'Expire date input is empty'); + + await shareDialog.clickExpirationToggle(); + expect(await shareDialog.isExpireToggleEnabled()).toBe(false, 'Expiration is checked'); + expect(await shareDialog.getExpireDate()).toBe('', 'Expire date input is not empty'); + + await shareDialog.clickClose(); + expect(await apis.user.nodes.getSharedExpiryDate(file7Id)).toBe(undefined, `${file7} link still has expiration`); + }); + + it('Shared file URL is not changed when Share dialog is closed and opened again - [C286673]', async () => { + await dataTable.selectItem(file8); + await toolbar.clickShare(); + await shareDialog.waitForDialogToOpen(); + const url1 = await shareDialog.getLinkUrl(); + await shareDialog.clickClose(); + await shareDialog.waitForDialogToClose(); + + await page.dataTable.clearSelection(); + await dataTable.selectItem(file8); + await toolbar.clickShare(); + await shareDialog.waitForDialogToOpen(); + const url2 = await shareDialog.getLinkUrl(); + + expect(url1).toEqual(url2); + }); + + it('Share a file from the context menu - [C286674]', async () => { + await dataTable.rightClickOnItem(file9); + await contextMenu.waitForMenuToOpen(); + await contextMenu.clickShare(); + await shareDialog.waitForDialogToOpen(); + + const url = await shareDialog.getLinkUrl(); + await Utils.pressEscape(); + const sharedId = await apis.user.nodes.getSharedId(file9Id); + expect(await apis.user.nodes.isFileShared(file9Id)).toBe(true, `${file9} is not shared`); + expect(url).toContain(sharedId); + }); + }); + + describe('from Search Results', () => { + + file3 = `search-file3-${Utils.random()}.txt`; + file5 = `search-file5-${Utils.random()}.txt`; + file6 = `search-file6-${Utils.random()}.txt`; + file7 = `search-file7-${Utils.random()}.txt`; + file9 = `search-file9-${Utils.random()}.txt`; + + beforeAll(async (done) => { + file3Id = (await apis.user.nodes.createFile(file3, parentId)).entry.id; + file5Id = (await apis.user.nodes.createFile(file5, parentId)).entry.id; + file6Id = (await apis.user.nodes.createFile(file6, parentId)).entry.id; + file7Id = (await apis.user.nodes.createFile(file7, parentId)).entry.id; + file9Id = (await apis.user.nodes.createFile(file9, parentId)).entry.id; + await apis.user.shared.shareFileById(file6Id, expiryDate); + await apis.user.shared.shareFileById(file7Id, expiryDate); + await apis.user.shared.waitForApi({ expect: 2 }); + await apis.user.search.waitForNodes('search-f', { expect: 5 }); + done(); + }); + + beforeEach(async done => { + await searchInput.clickSearchButton(); + await searchInput.checkFilesAndFolders(); + await searchInput.searchFor('search-f'); + await dataTable.waitForBody(); + done(); + }); + + afterEach(async (done) => { + await Utils.pressEscape(); + await page.clickPersonalFilesAndWait(); + done(); + }); + + afterAll(async (done) => { + await apis.user.nodes.deleteNodeById(file3Id); + await apis.user.nodes.deleteNodeById(file5Id); + await apis.user.nodes.deleteNodeById(file6Id); + await apis.user.nodes.deleteNodeById(file7Id); + await apis.user.nodes.deleteNodeById(file9Id); + await apis.user.shared.waitForApi({ expect: 0 }); + done(); + }); + + it('Share a file - [C306975]', async () => { + await dataTable.selectItem(file3); + await toolbar.clickShare(); + await shareDialog.waitForDialogToOpen(); + + const url = await shareDialog.getLinkUrl(); + await Utils.pressEscape(); + const sharedId = await apis.user.nodes.getSharedId(file3Id); + expect(await apis.user.nodes.isFileShared(file3Id)).toBe(true, `${file3} is not shared`); + expect(url).toContain(sharedId); + }); + + it('Share a file with expiration date - [C306977]', async () => { + await dataTable.selectItem(file5); + await toolbar.clickShare(); + await shareDialog.waitForDialogToOpen(); + + await shareDialog.clickExpirationToggle(); + expect(await shareDialog.isExpireToggleEnabled()).toBe(true, 'Expire toggle not checked'); + expect(await shareDialog.dateTimePicker.isCalendarOpen()).toBe(true, 'Calendar not opened'); + const date = await shareDialog.dateTimePicker.setDefaultDay(); + await shareDialog.dateTimePicker.waitForDateTimePickerToClose(); + + const setDate = (`${date}`).replace(',', ''); + const inputDate = await shareDialog.getExpireDate(); + + expect(new Date(inputDate)).toEqual(new Date(setDate)); + + const expireDateProperty = await apis.user.nodes.getSharedExpiryDate(file5Id); + + expect(Utils.formatDate(expireDateProperty)).toEqual(Utils.formatDate(inputDate)); + }); + + it('Expire date is displayed correctly - [C306978]', async () => { + await dataTable.selectItem(file6); + await toolbar.clickSharedLinkSettings(); + await shareDialog.waitForDialogToOpen(); + + const expireProperty = await apis.user.nodes.getSharedExpiryDate(file6Id); + expect(expireProperty).toEqual(expiryDate); + expect(await shareDialog.isExpireToggleEnabled()).toBe(true, 'Expiration is not checked'); + expect(Utils.formatDate(await shareDialog.getExpireDate())).toEqual(Utils.formatDate(expiryDate)); + }); + + it('Disable the share link expiration - [C306979]', async () => { + await dataTable.selectItem(file7); + await toolbar.clickSharedLinkSettings(); + await shareDialog.waitForDialogToOpen(); + + expect(await shareDialog.isExpireToggleEnabled()).toBe(true, 'Expiration is not checked'); + expect(await shareDialog.getExpireDate()).not.toBe('', 'Expire date input is empty'); + + await shareDialog.clickExpirationToggle(); + expect(await shareDialog.isExpireToggleEnabled()).toBe(false, 'Expiration is checked'); + expect(await shareDialog.getExpireDate()).toBe('', 'Expire date input is not empty'); + + await shareDialog.clickClose(); + expect(await apis.user.nodes.getSharedExpiryDate(file7Id)).toBe(undefined, `${file7} link still has expiration`); + }); + + it('Share a file from the context menu - [C306981]', async () => { + await dataTable.rightClickOnItem(file9); + await contextMenu.waitForMenuToOpen(); + await contextMenu.clickShare(); + await shareDialog.waitForDialogToOpen(); + + const url = await shareDialog.getLinkUrl(); + await Utils.pressEscape(); + const sharedId = await apis.user.nodes.getSharedId(file9Id); + expect(await apis.user.nodes.isFileShared(file9Id)).toBe(true, `${file9} is not shared`); + expect(url).toContain(sharedId); + }); + }); + }) }); diff --git a/protractor.conf.js b/protractor.conf.js index 16dcf6a479..478a90cbd6 100755 --- a/protractor.conf.js +++ b/protractor.conf.js @@ -80,7 +80,7 @@ exports.config = { '--incognito', '--headless', '--remote-debugging-port=9222', - `--window-size=${width},${height}`, + '--disable-gpu', '--no-sandbox' ] } @@ -118,6 +118,11 @@ exports.config = { project: 'e2e/tsconfig.e2e.json' }); + browser + .manage() + .window() + .setSize(width, height); + jasmine.getEnv().addReporter( new SpecReporter({ spec: { From 1c18f6c555c533531babca00fb43cdd5b0a17831 Mon Sep 17 00:00:00 2001 From: Adina Parpalita Date: Wed, 15 May 2019 11:47:52 +0300 Subject: [PATCH 202/259] [ACA-2387] rebalance suites (#1107) * rebalance suites * try to fix flaky test * fix more related tests * fix retry * reorganise some more suites * move file to another suite --- .travis.yml | 35 +++++++------------ e2e/suites/actions/upload-new-version.test.ts | 3 -- .../single-click.test.ts | 0 e2e/suites/viewer/viewer-actions.test.ts | 10 +++--- .../repo-client/apis/nodes/nodes-api.ts | 23 ++++++++++++ protractor.conf.js | 25 ++++++++++++- 6 files changed, 64 insertions(+), 32 deletions(-) rename e2e/suites/{actions => navigation}/single-click.test.ts (100%) diff --git a/.travis.yml b/.travis.yml index 37a2e2d0ad..37f91dddbd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,26 +36,15 @@ jobs: - name: 'Prepare dist cache' script: npm run build.e2e - stage: e2e - name: Test Suite authentication - script: SUITE="--suite authentication" npm run e2e:docker - - name: Test Suite listViews - script: SUITE="--suite listViews" npm run e2e:docker - - name: Test Suite application - script: SUITE="--suite application" npm run e2e:docker - - name: Test Suite navigation - script: SUITE="--suite navigation" npm run e2e:docker - - name: Test Suite pagination - script: SUITE="--suite pagination" npm run e2e:docker - - name: Test Suite search - script: SUITE="--suite search" npm run e2e:docker - - name: Test Suite actionsAvailable - script: SUITE="--suite actionsAvailable" npm run e2e:docker - - stage: e2e - name: Test Suite actions - script: SUITE="--suite actions" npm run e2e:docker - - name: Test Suite viewer - script: SUITE="--suite viewer" npm run e2e:docker - - name: Test Suite infoDrawer - script: SUITE="--suite infoDrawer" npm run e2e:docker - - name: Test Suite extensions - script: SUITE="--suite extensions" npm run e2e:docker + name: Test Suite appNavigation + script: SUITE="--suite authentication,listViews,navigation,application,pagination" npm run e2e:docker + - name: Test Suite search&actionsAvailable + script: SUITE="--suite search,actionsAvailable" npm run e2e:docker + - name: Test Suite addRemoveContent + script: SUITE="--suite addRemoveContent" npm run e2e:docker + - name: Test Suite manageContent + script: SUITE="--suite manageContent" npm run e2e:docker + - name: Test Suite sharingContent&markFavorite + script: SUITE="--suite sharingContent" npm run e2e:docker + - name: Test Suite viewContent&metadata&extensions + script: SUITE="--suite viewer,infoDrawer,extensions" npm run e2e:docker diff --git a/e2e/suites/actions/upload-new-version.test.ts b/e2e/suites/actions/upload-new-version.test.ts index 8ebcf8f8d0..0363a68e06 100755 --- a/e2e/suites/actions/upload-new-version.test.ts +++ b/e2e/suites/actions/upload-new-version.test.ts @@ -264,7 +264,6 @@ describe('Upload new version', () => { }); afterEach(async (done) => { - // await Utils.pressEscape(); await page.refresh(); done(); }); @@ -411,7 +410,6 @@ describe('Upload new version', () => { }); afterEach(async (done) => { - // await Utils.pressEscape(); await page.refresh(); done(); }); @@ -559,7 +557,6 @@ describe('Upload new version', () => { }); afterEach(async (done) => { - // await Utils.pressEscape(); await page.refresh(); done(); }); diff --git a/e2e/suites/actions/single-click.test.ts b/e2e/suites/navigation/single-click.test.ts similarity index 100% rename from e2e/suites/actions/single-click.test.ts rename to e2e/suites/navigation/single-click.test.ts diff --git a/e2e/suites/viewer/viewer-actions.test.ts b/e2e/suites/viewer/viewer-actions.test.ts index 6228f0ff47..18bc83d1ae 100755 --- a/e2e/suites/viewer/viewer-actions.test.ts +++ b/e2e/suites/viewer/viewer-actions.test.ts @@ -251,7 +251,7 @@ describe('Viewer actions', () => { await viewer.waitForViewerToOpen(); await toolbar.clickMoreActionsCancelEditing(); - expect(await apis.user.nodes.isFileLockedWrite(fileForCancelEditingId)).toBe(false, `${fileForCancelEditing} is still locked`); + expect(await apis.user.nodes.isFileLockedWriteWithRetry(fileForCancelEditingId, false)).toBe(false, `${fileForCancelEditing} is still locked`); expect(await viewer.isViewerOpened()).toBe(true, 'Viewer is not open'); }); @@ -506,7 +506,7 @@ describe('Viewer actions', () => { await viewer.waitForViewerToOpen(); await toolbar.clickMoreActionsCancelEditing(); - expect(await apis.user.nodes.isFileLockedWrite(fileForCancelEditingId)).toBe(false, `${fileForCancelEditing} is still locked`); + expect(await apis.user.nodes.isFileLockedWriteWithRetry(fileForCancelEditingId, false)).toBe(false, `${fileForCancelEditing} is still locked`); expect(await viewer.isViewerOpened()).toBe(true, 'Viewer is not open'); }); @@ -739,7 +739,7 @@ describe('Viewer actions', () => { await viewer.waitForViewerToOpen(); await toolbar.clickMoreActionsCancelEditing(); - expect(await apis.user.nodes.isFileLockedWrite(fileForCancelEditingId)).toBe(false, `${fileForCancelEditing} is still locked`); + expect(await apis.user.nodes.isFileLockedWriteWithRetry(fileForCancelEditingId, false)).toBe(false, `${fileForCancelEditing} is still locked`); expect(await viewer.isViewerOpened()).toBe(true, 'Viewer is not open'); }); @@ -971,7 +971,7 @@ describe('Viewer actions', () => { await viewer.waitForViewerToOpen(); await toolbar.clickMoreActionsCancelEditing(); - expect(await apis.user.nodes.isFileLockedWrite(fileForCancelEditingId)).toBe(false, `${fileForCancelEditing} is still locked`); + expect(await apis.user.nodes.isFileLockedWriteWithRetry(fileForCancelEditingId, false)).toBe(false, `${fileForCancelEditing} is still locked`); expect(await viewer.isViewerOpened()).toBe(true, 'Viewer is not open'); }); @@ -1205,7 +1205,7 @@ describe('Viewer actions', () => { await viewer.waitForViewerToOpen(); await toolbar.clickMoreActionsCancelEditing(); - expect(await apis.user.nodes.isFileLockedWrite(fileForCancelEditingId)).toBe(false, `${fileForCancelEditing} is still locked`); + expect(await apis.user.nodes.isFileLockedWriteWithRetry(fileForCancelEditingId, false)).toBe(false, `${fileForCancelEditing} is still locked`); expect(await viewer.isViewerOpened()).toBe(true, 'Viewer is not open'); }); diff --git a/e2e/utilities/repo-client/apis/nodes/nodes-api.ts b/e2e/utilities/repo-client/apis/nodes/nodes-api.ts index b08006e1ef..e575686bb9 100755 --- a/e2e/utilities/repo-client/apis/nodes/nodes-api.ts +++ b/e2e/utilities/repo-client/apis/nodes/nodes-api.ts @@ -27,6 +27,7 @@ import { RepoApi } from '../repo-api'; import { NodeBodyCreate } from './node-body-create'; import { NodeContentTree, flattenNodeContentTree } from './node-content-tree'; import { NodesApi as AdfNodeApi, NodeBodyLock} from '@alfresco/js-api'; +import { Utils } from '../../../../utilities/utils'; export class NodesApi extends RepoApi { nodesApi = new AdfNodeApi(this.alfrescoJsApi); @@ -264,6 +265,28 @@ export class NodesApi extends RepoApi { return (await this.getLockType(nodeId)) === 'WRITE_LOCK'; } + async isFileLockedWriteWithRetry(nodeId: string, expect: boolean) { + const data = { + expect: expect, + retry: 5 + }; + let isLocked; + try { + const locked = async () => { + isLocked = (await this.getLockType(nodeId)) === 'WRITE_LOCK'; + if ( isLocked !== data.expect ) { + return Promise.reject(isLocked); + } else { + return Promise.resolve(isLocked); + } + } + return await Utils.retryCall(locked, data.retry); + } catch (error) { + console.log('-----> catch isLockedWriteWithRetry: ', error); + } + return isLocked; + } + async isFileLockedByName(fileName: string, parentId: string) { const id = await this.getNodeIdFromParent(fileName, parentId); return await this.isFileLockedWrite(id); diff --git a/protractor.conf.js b/protractor.conf.js index 478a90cbd6..d22f17094f 100755 --- a/protractor.conf.js +++ b/protractor.conf.js @@ -58,7 +58,30 @@ exports.config = { pagination: './e2e/suites/pagination/*.test.ts', search: './e2e/suites/search/*.test.ts', actionsAvailable: './e2e/suites/actions-available/*.test.ts', - actions: './e2e/suites/actions/*.test.ts', + addRemoveContent: [ + './e2e/suites/actions/new-menu.test.ts', + './e2e/suites/actions/create-folder.test.ts', + './e2e/suites/actions/create-library.test.ts', + './e2e/suites/actions/upload-file.test.ts', + './e2e/suites/actions/upload-new-version.test.ts', + './e2e/suites/actions/delete-undo-delete.test.ts', + './e2e/suites/actions/permanently-delete.test.ts', + './e2e/suites/actions/restore.test.ts', + './e2e/suites/actions/download.test.ts' + ], + manageContent: [ + './e2e/suites/actions/copy.test.ts', + './e2e/suites/actions/move.test.ts', + './e2e/suites/actions/library-actions.test.ts', + './e2e/suites/actions/edit-folder.test.ts', + './e2e/suites/actions/edit-offline.test.ts' + ], + sharingContent: [ + './e2e/suites/actions/mark-favorite.test.ts', + './e2e/suites/actions/share-file.test.ts', + './e2e/suites/actions/unshare-file-search-results.test.ts', + './e2e/suites/actions/unshare-file.test.ts' + ], viewer: './e2e/suites/viewer/*.test.ts', infoDrawer: './e2e/suites/info-drawer/*.test.ts', extensions: './e2e/suites/extensions/*.test.ts' From 07c7f49af1f080a9633c8f660cdc8e50d6ee81db Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Wed, 15 May 2019 15:38:51 +0300 Subject: [PATCH 203/259] [ACA] 3.3.0 alpha update (#1108) * update to 3.3.0 alpha * add arabic language * layout orientation support * take direction from parent * set direction based on language locale on initialization * test --- package-lock.json | 65 ++++++----------- package.json | 8 +-- src/app.config.json | 5 ++ .../app-layout/app-layout.component.html | 2 +- .../app-layout/app-layout.component.spec.ts | 70 ++++++++++++++----- .../layout/app-layout/app-layout.component.ts | 26 ++++++- .../components/sidenav/sidenav.component.scss | 12 ++-- .../sidenav/sidenav.component.spec.ts | 18 ----- .../components/sidenav/sidenav.component.ts | 8 +-- 9 files changed, 118 insertions(+), 96 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5a1fb58797..57d7ea1ec1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,33 +5,33 @@ "requires": true, "dependencies": { "@alfresco/adf-content-services": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-3.2.0.tgz", - "integrity": "sha512-G8+vSL3GTGm2rAtvNgFpCctcX7WwRBoAkvkvwnIWETrl5zYb4ftzvCpSkrj8FKxueE8Ys59oTMOv1o22ev2+AA==", + "version": "3.3.0-4a363c731be09d8213e25cd149bee302ebcbeb82", + "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-3.3.0-4a363c731be09d8213e25cd149bee302ebcbeb82.tgz", + "integrity": "sha512-G4zvUwzVDm5YAK4/eo/U8tMA7osIU5axBhc1JGxRyWR3jcd1E6tVeHDQP+i4X9cQWdYF6fvSOYNS4qqapk8JAg==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/adf-core": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-3.2.0.tgz", - "integrity": "sha512-mgDNroAiKjDSOVS3nfc0vYrgGtWt2dUNLfLReU89jvMAiXLVCghA/Gufhjx0t64TOneWofD9hNGV0KuIXx0wFQ==", + "version": "3.3.0-4a363c731be09d8213e25cd149bee302ebcbeb82", + "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-3.3.0-4a363c731be09d8213e25cd149bee302ebcbeb82.tgz", + "integrity": "sha512-7SEJLDr23/JgZDZaw4aD6FDgvnOIfQ5SIh/qJUdhxyD1eC852qpm/OlNRg4zqJ+6so8pvvOqEEqrDgFJvr1OWg==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/adf-extensions": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@alfresco/adf-extensions/-/adf-extensions-3.2.0.tgz", - "integrity": "sha512-nw7rzgG7WznekyzNQF+unsWITuBfQva2wvTiqRPtimpA1hZWIcxKUWhKf5nkw8nCb8qlgkVIimylZjNZFlsr7A==", + "version": "3.3.0-4a363c731be09d8213e25cd149bee302ebcbeb82", + "resolved": "https://registry.npmjs.org/@alfresco/adf-extensions/-/adf-extensions-3.3.0-4a363c731be09d8213e25cd149bee302ebcbeb82.tgz", + "integrity": "sha512-l8VIc3Zg0Nr1mJUGbeC+9oPUdBAtqg5f4NUNedb8vSMumYAyK/p8DvZdEERHPXxRCfrxxGuYvDwxu1IlcZkCZg==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/js-api": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@alfresco/js-api/-/js-api-3.2.0.tgz", - "integrity": "sha512-HgB/8M4mSi1mVx7ZDbgrNLP5xZiPUamkNzQI198DkWwQRxXh9V0khEavm82Rr9M5nrLw4VdPUARFLmxsNQwmng==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@alfresco/js-api/-/js-api-3.2.1.tgz", + "integrity": "sha512-qaXftaHqFonWRKRmYxhB2/bEpUh5fvUj6cN+xuKUXIGgt9XxF76NpWkXnEEQLZ0BWg5upd19Q3N1x4E7DiNGUg==", "requires": { "event-emitter": "0.3.4", "superagent": "3.8.2" @@ -4961,8 +4961,7 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "aproba": { "version": "1.2.0", @@ -4983,14 +4982,12 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -5005,20 +5002,17 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -5135,8 +5129,7 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -5148,7 +5141,6 @@ "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -5163,7 +5155,6 @@ "version": "3.0.4", "bundled": true, "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -5171,14 +5162,12 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -5197,7 +5186,6 @@ "version": "0.5.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -5278,8 +5266,7 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -5291,7 +5278,6 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -5377,8 +5363,7 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "safer-buffer": { "version": "2.1.2", @@ -5414,7 +5399,6 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -5434,7 +5418,6 @@ "version": "3.0.1", "bundled": true, "dev": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -5478,14 +5461,12 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true } } }, diff --git a/package.json b/package.json index 7ac6bcbb5f..1c29c2dba4 100644 --- a/package.json +++ b/package.json @@ -37,10 +37,10 @@ }, "private": true, "dependencies": { - "@alfresco/adf-content-services": "3.2.0", - "@alfresco/adf-core": "3.2.0", - "@alfresco/adf-extensions": "3.2.0", - "@alfresco/js-api": "3.2.0", + "@alfresco/adf-content-services": "3.3.0-4a363c731be09d8213e25cd149bee302ebcbeb82", + "@alfresco/adf-core": "3.3.0-4a363c731be09d8213e25cd149bee302ebcbeb82", + "@alfresco/adf-extensions": "3.3.0-4a363c731be09d8213e25cd149bee302ebcbeb82", + "@alfresco/js-api": "3.2.1", "@angular/animations": "7.2.14", "@angular/cdk": "^7.3.7", "@angular/common": "7.2.14", diff --git a/src/app.config.json b/src/app.config.json index f836f69e8f..7963b60583 100644 --- a/src/app.config.json +++ b/src/app.config.json @@ -104,6 +104,11 @@ { "key": "sv", "label": "Svenska" + }, + { + "key": "ar", + "label": "Arabic", + "direction": "rtl" } ], "content-metadata": { diff --git a/src/app/components/layout/app-layout/app-layout.component.html b/src/app/components/layout/app-layout/app-layout.component.html index e9d3761e2c..953955e942 100644 --- a/src/app/components/layout/app-layout/app-layout.component.html +++ b/src/app/components/layout/app-layout/app-layout.component.html @@ -7,6 +7,7 @@ [hideSidenav]="hideSidenav" [expandedSidenav]="expandedSidenav" (expanded)="onExpanded($event)" + [direction]="direction" > @@ -23,7 +24,6 @@ Date: Thu, 16 May 2019 08:01:32 +0100 Subject: [PATCH 205/259] Fix/ACA-2111 blue toggle (#1109) * Revert "[ACA-2069] fix blue slider issue (#854)" This reverts commit 84b0cd4e7ecb18ee4363b56ecc755f3f5700021e. * ACA-2111 remove default color for toggle as it defaults to orange * ACA-2111 remove default color for toggle as it defaults to orange --- .../content-node-share.dialog.html | 2 -- .../content-node-share.dialog.scss | 14 -------------- src/app/ui/custom-theme.scss | 2 -- 3 files changed, 18 deletions(-) diff --git a/src/app/components/shared/content-node-share/content-node-share.dialog.html b/src/app/components/shared/content-node-share/content-node-share.dialog.html index 791bc85a5d..ffa3138e34 100644 --- a/src/app/components/shared/content-node-share/content-node-share.dialog.html +++ b/src/app/components/shared/content-node-share/content-node-share.dialog.html @@ -10,7 +10,6 @@

{{ 'SHARE.TITLE' | translate }}

{{ 'SHARE.EXPIRES' | translate }}

Date: Fri, 17 May 2019 12:34:21 +0300 Subject: [PATCH 206/259] [ACA-1619] automatically show content metadata (#1104) * [ACA-1619] overwrite the app.config metadata settings only of the 'content-metadata-presets' is non-empty * [ACA-1619] app config to show automatically all metadata aspects - not extendable version * [ACA-1619] app extension to show automatically all metadata aspects - extendable version - the app.config setting is overwritten by the one with ids from app.extensions - could remove completely the content metadata setting from app.json * [ACA-1619] allow 'disabled' property on content metadata configuration * [ACA-1619] test content-metadata plugin extension - allow 'disabled' property on content metadata configuration * [ACA-1619] remove test reference to metadata plugin * [ACA-1619] backwards compatibility for metadata plugin extensions - add back initial structure (& ids) of content-metadata "custom" preset - revert change to sample metadata extension plugin * [ACA-1619] forgotten change * [ACA-1619] tests --- extension.schema.json | 12 +++++ src/app.config.json | 51 +++++++++--------- .../metadata-tab.component.spec.ts | 52 ++++++++++++++++--- .../metadata-tab/metadata-tab.component.ts | 7 +-- src/app/extensions/extension.service.ts | 4 ++ src/assets/app.extensions.json | 29 ++++++----- 6 files changed, 104 insertions(+), 51 deletions(-) diff --git a/extension.schema.json b/extension.schema.json index c8357a764e..d9fe567aa6 100644 --- a/extension.schema.json +++ b/extension.schema.json @@ -371,6 +371,14 @@ "id": { "type": "string", "description": "Unique identifier" + }, + "includeAll": { + "type": "boolean", + "description": "Enable to automatically show all properties" + }, + "disabled": { + "description": "Toggles disabled state", + "type": "boolean" } }, "patternProperties": { @@ -748,6 +756,10 @@ "id": { "type": "string", "description": "Unique identifier" + }, + "disabled": { + "type": "boolean", + "description": "Toggle disabled state" } }, "patternProperties": { diff --git a/src/app.config.json b/src/app.config.json index 97cc2c1faf..f78b110a2a 100644 --- a/src/app.config.json +++ b/src/app.config.json @@ -114,25 +114,25 @@ "content-metadata": { "presets": { "custom": [ + { + "includeAll": true, + "exclude": [ + "rn:renditioned", + "cm:versionable", + "cm:auditable", + "cm:thumbnailModification", + "cm:content", + "qshare:shared", + + "exif:exif" + ] + }, { "title": "APP.CONTENT_METADATA.EXIF_GROUP_TITLE", "items": [ { "aspect": "exif:exif", - "properties": [ - "exif:pixelXDimension", - "exif:pixelYDimension", - "exif:dateTimeOriginal", - "exif:exposureTime", - "exif:fNumber", - "exif:flash", - "exif:focalLength", - "exif:isoSpeedRatings", - "exif:orientation", - "exif:manufacturer", - "exif:model", - "exif:software" - ] + "properties": "*" } ] } @@ -141,13 +141,7 @@ }, "search": { "filterWithContains": true, - "aca:fields": [ - "cm:name", - "cm:title", - "cm:description", - "TEXT", - "TAG" - ], + "aca:fields": ["cm:name", "cm:title", "cm:description", "TEXT", "TAG"], "include": ["path", "allowableOperations", "properties"], "sorting": { "options": [ @@ -260,7 +254,10 @@ "label": "SEARCH.CATEGORIES.MODIFIED_DATE", "expanded": true, "queries": [ - { "label": "SEARCH.FACET_QUERIES.TODAY", "query": "cm:modified:[TODAY to TODAY]" }, + { + "label": "SEARCH.FACET_QUERIES.TODAY", + "query": "cm:modified:[TODAY to TODAY]" + }, { "label": "SEARCH.FACET_QUERIES.THIS_WEEK", "query": "cm:modified:[NOW/DAY-7DAYS TO NOW/DAY+1DAY]" @@ -288,7 +285,10 @@ "selector": "check-list", "settings": { "options": [ - { "name": "SEARCH.CATEGORIES.SIZE_OPTIONS.SMALL", "value": "content.size:[0 TO 1048576>" }, + { + "name": "SEARCH.CATEGORIES.SIZE_OPTIONS.SMALL", + "value": "content.size:[0 TO 1048576>" + }, { "name": "SEARCH.CATEGORIES.SIZE_OPTIONS.MEDIUM", "value": "content.size:[1048576 TO 52428800]" @@ -297,7 +297,10 @@ "name": "SEARCH.CATEGORIES.SIZE_OPTIONS.LARGE", "value": "content.size:<52428800 TO 524288000]" }, - { "name": "SEARCH.CATEGORIES.SIZE_OPTIONS.HUGE", "value": "content.size:<524288000 TO MAX]" } + { + "name": "SEARCH.CATEGORIES.SIZE_OPTIONS.HUGE", + "value": "content.size:<524288000 TO MAX]" + } ] } } diff --git a/src/app/components/info-drawer/metadata-tab/metadata-tab.component.spec.ts b/src/app/components/info-drawer/metadata-tab/metadata-tab.component.spec.ts index e77ebc585f..66fb62873e 100644 --- a/src/app/components/info-drawer/metadata-tab/metadata-tab.component.spec.ts +++ b/src/app/components/info-drawer/metadata-tab/metadata-tab.component.spec.ts @@ -27,7 +27,7 @@ import { MetadataTabComponent } from './metadata-tab.component'; import { Node } from '@alfresco/js-api'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { AppTestingModule } from '../../../testing/app-testing.module'; -import { setupTestBed } from '@alfresco/adf-core'; +import { AppConfigService, setupTestBed } from '@alfresco/adf-core'; import { ContentMetadataModule } from '@alfresco/adf-content-services'; import { Store } from '@ngrx/store'; import { @@ -35,28 +35,60 @@ import { AppState } from '@alfresco/aca-shared/store'; import { By } from '@angular/platform-browser'; +import { AppExtensionService } from '../../../extensions/extension.service'; describe('MetadataTabComponent', () => { let fixture: ComponentFixture; let component: MetadataTabComponent; let store: Store; + let appConfig: AppConfigService; + let extensions: AppExtensionService; setupTestBed({ imports: [AppTestingModule, ContentMetadataModule], declarations: [MetadataTabComponent] }); - beforeEach(() => { - fixture = TestBed.createComponent(MetadataTabComponent); - store = TestBed.get(Store); - component = fixture.componentInstance; - }); - afterEach(() => { fixture.destroy(); }); + describe('content-metadata configuration', () => { + beforeEach(() => { + appConfig = TestBed.get(AppConfigService); + extensions = TestBed.get(AppExtensionService); + }); + + it('should remain unchanged when metadata extension is missing', () => { + appConfig.config['content-metadata'] = 'initial config'; + extensions.contentMetadata = null; + + fixture = TestBed.createComponent(MetadataTabComponent); + + expect(appConfig.config['content-metadata']).toEqual('initial config'); + }); + + it('should be overwritten by the one from extension', () => { + appConfig.config['content-metadata'] = 'initial config'; + extensions.contentMetadata = [{ 'new config': true }]; + + fixture = TestBed.createComponent(MetadataTabComponent); + + expect(appConfig.config['content-metadata']).not.toEqual( + 'initial config' + ); + expect(appConfig.config['content-metadata']).toEqual( + extensions.contentMetadata + ); + }); + }); + describe('canUpdateNode()', () => { + beforeEach(() => { + fixture = TestBed.createComponent(MetadataTabComponent); + component = fixture.componentInstance; + }); + it('should return true if node is not locked and has update permission', () => { const node = { isLocked: false, @@ -102,6 +134,12 @@ describe('MetadataTabComponent', () => { }); describe('displayAspect', () => { + beforeEach(() => { + fixture = TestBed.createComponent(MetadataTabComponent); + store = TestBed.get(Store); + component = fixture.componentInstance; + }); + it('show pass empty when store is in initial state', () => { const initialState = fixture.debugElement.query( By.css('adf-content-metadata-card') diff --git a/src/app/components/info-drawer/metadata-tab/metadata-tab.component.ts b/src/app/components/info-drawer/metadata-tab/metadata-tab.component.ts index f394d25a42..37457e2385 100644 --- a/src/app/components/info-drawer/metadata-tab/metadata-tab.component.ts +++ b/src/app/components/info-drawer/metadata-tab/metadata-tab.component.ts @@ -59,15 +59,10 @@ export class MetadataTabComponent { private appConfig: AppConfigService, private store: Store ) { - try { + if (this.extensions.contentMetadata) { this.appConfig.config[ 'content-metadata' ] = this.extensions.contentMetadata; - } catch (error) { - console.error( - error, - '- could not change content-metadata from app.config' - ); } this.displayAspect$ = this.store.select(infoDrawerMetadataAspect); } diff --git a/src/app/extensions/extension.service.ts b/src/app/extensions/extension.service.ts index 060f39c526..6ff144fe7a 100644 --- a/src/app/extensions/extension.service.ts +++ b/src/app/extensions/extension.service.ts @@ -307,6 +307,10 @@ export class AppExtensionService implements RuleContext { config, 'features.content-metadata-presets' ); + if (!elements.length) { + return null; + } + let presets = {}; presets = this.filterDisabled(mergeObjects(presets, ...elements)); diff --git a/src/assets/app.extensions.json b/src/assets/app.extensions.json index b6b0f71093..719f095c1d 100644 --- a/src/assets/app.extensions.json +++ b/src/assets/app.extensions.json @@ -1029,6 +1029,20 @@ { "id": "app.content.metadata.custom", "custom": [ + { + "id": "app.content.metadata.customSetting", + "includeAll": true, + "exclude": [ + "rn:renditioned", + "cm:versionable", + "cm:auditable", + "cm:thumbnailModification", + "cm:content", + "qshare:shared", + + "exif:exif" + ] + }, { "id": "app.content.metadata.customGroup", "title": "APP.CONTENT_METADATA.EXIF_GROUP_TITLE", @@ -1036,20 +1050,7 @@ { "id": "app.content.metadata.exifAspect", "aspect": "exif:exif", - "properties": [ - "exif:pixelXDimension", - "exif:pixelYDimension", - "exif:dateTimeOriginal", - "exif:exposureTime", - "exif:fNumber", - "exif:flash", - "exif:focalLength", - "exif:isoSpeedRatings", - "exif:orientation", - "exif:manufacturer", - "exif:model", - "exif:software" - ] + "properties": "*" } ] } From 9892580e29a4e7d53c8f80bc1cd0fe669cb892a5 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Fri, 17 May 2019 11:52:58 +0100 Subject: [PATCH 207/259] use css variables for About screen (#1111) --- src/app/components/about/about.component.scss | 25 ++++++++++++++++ .../about/about.component.theme.scss | 29 ------------------- src/app/components/about/about.component.ts | 1 + src/app/ui/custom-theme.scss | 2 -- 4 files changed, 26 insertions(+), 31 deletions(-) create mode 100644 src/app/components/about/about.component.scss delete mode 100644 src/app/components/about/about.component.theme.scss diff --git a/src/app/components/about/about.component.scss b/src/app/components/about/about.component.scss new file mode 100644 index 0000000000..bcaae901e0 --- /dev/null +++ b/src/app/components/about/about.component.scss @@ -0,0 +1,25 @@ +.app-about { + .main-content { + padding: 10px; + + article { + color: var(--theme-text-color); + padding: 25px 0 25px 0; + + & > header { + line-height: 24px; + font-size: 14px; + font-weight: 800; + letter-spacing: -0.2px; + } + } + + article:first-of-type { + padding-bottom: 0; + } + + article:last-of-type { + margin-bottom: 50px; + } + } +} diff --git a/src/app/components/about/about.component.theme.scss b/src/app/components/about/about.component.theme.scss deleted file mode 100644 index beb373af3f..0000000000 --- a/src/app/components/about/about.component.theme.scss +++ /dev/null @@ -1,29 +0,0 @@ -@mixin aca-about-component-theme($theme) { - $foreground: map-get($theme, foreground); - - .app-about { - .main-content { - padding: 10px; - - article { - color: mat-color($foreground, text, 0.54); - padding: 25px 0 25px 0; - - & > header { - line-height: 24px; - font-size: 14px; - font-weight: 800; - letter-spacing: -0.2px; - } - } - - article:first-of-type { - padding-bottom: 0; - } - - article:last-of-type { - margin-bottom: 50px; - } - } - } -} diff --git a/src/app/components/about/about.component.ts b/src/app/components/about/about.component.ts index eb28b814ec..dbdec3c0cc 100644 --- a/src/app/components/about/about.component.ts +++ b/src/app/components/about/about.component.ts @@ -34,6 +34,7 @@ import { version, dependencies } from '../../../../package.json'; @Component({ selector: 'app-about', templateUrl: './about.component.html', + styleUrls: ['about.component.scss'], encapsulation: ViewEncapsulation.None, host: { class: 'app-about' } }) diff --git a/src/app/ui/custom-theme.scss b/src/app/ui/custom-theme.scss index 789f4cada2..30bf508170 100644 --- a/src/app/ui/custom-theme.scss +++ b/src/app/ui/custom-theme.scss @@ -2,7 +2,6 @@ @import '~@alfresco/adf-content-services/theming'; @import '../components/sidenav/sidenav.component.theme'; -@import '../components/about/about.component.theme'; @import '../components/search/search-input/search-input.component.theme'; @import '../components/settings/settings.component.theme'; @import '../components/current-user/current-user.component.theme'; @@ -71,7 +70,6 @@ $warn: map-get($custom-theme, warn); @include aca-settings-theme($theme); @include snackbar-theme($theme); @include sidenav-component-theme($theme); - @include aca-about-component-theme($theme); @include aca-current-user-theme($theme); @include aca-context-menu-theme($theme); @include app-create-menu-theme($theme); From 1928aa0b1b68f51a37984663a7f02e8803ae7d00 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Fri, 17 May 2019 15:14:23 +0100 Subject: [PATCH 208/259] npm security audit fixes (#1112) * update angular libs * audit fix * fix code style * remove rimraf dependency --- package-lock.json | 1858 ++++++++--------- package.json | 37 +- src/app.config.json | 2 +- src/app/components/about/about.component.html | 2 +- .../current-user/current-user.component.html | 2 +- .../favorite-libraries.component.html | 2 +- .../favorites/favorites.component.html | 2 +- src/app/components/files/files.component.html | 2 +- .../libraries/libraries.component.html | 2 +- .../components/preview/preview.component.html | 2 +- .../recent-files/recent-files.component.html | 2 +- .../search-libraries-results.component.html | 2 +- .../search-results.component.html | 2 +- .../shared-files/shared-files.component.html | 2 +- .../toggle-shared.component.html | 2 +- .../toggle-join-library-button.component.ts | 2 +- .../toggle-join-library-menu.component.ts | 2 +- .../components/viewer/viewer.component.html | 2 +- 18 files changed, 909 insertions(+), 1018 deletions(-) diff --git a/package-lock.json b/package-lock.json index 57d7ea1ec1..8ac16f9ed0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -59,16 +59,16 @@ } }, "@angular-devkit/build-angular": { - "version": "0.13.8", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-0.13.8.tgz", - "integrity": "sha512-uRb8CKC0hUdcE+Fv2Ov9LJNelyjsiMuddBpo8pdTKCIHVVC6hvip9S/Z18Tvb207kKI3k7Dn+Ji1J63mCqmQzA==", + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-0.13.9.tgz", + "integrity": "sha512-onh07LhdxotDFjja0KKsDWNCwgpM/ymuRr5h0e+vT4AgklP2Uioz1CpzVOgxPIKkdVdGR9QgDinVsWAmY90J8g==", "dev": true, "requires": { - "@angular-devkit/architect": "0.13.8", - "@angular-devkit/build-optimizer": "0.13.8", - "@angular-devkit/build-webpack": "0.13.8", - "@angular-devkit/core": "7.3.8", - "@ngtools/webpack": "7.3.8", + "@angular-devkit/architect": "0.13.9", + "@angular-devkit/build-optimizer": "0.13.9", + "@angular-devkit/build-webpack": "0.13.9", + "@angular-devkit/core": "7.3.9", + "@ngtools/webpack": "7.3.9", "ajv": "6.9.1", "autoprefixer": "9.4.6", "circular-dependency-plugin": "5.0.2", @@ -84,7 +84,7 @@ "loader-utils": "1.2.3", "mini-css-extract-plugin": "0.5.0", "minimatch": "3.0.4", - "node-sass": "4.11.0", + "node-sass": "4.12.0", "open": "6.0.0", "parse5": "4.0.0", "postcss": "7.0.14", @@ -112,19 +112,19 @@ }, "dependencies": { "@angular-devkit/architect": { - "version": "0.13.8", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.13.8.tgz", - "integrity": "sha512-gxUs5rhnP576T8ZclKqxlspiChrqRtqaJo54wqNVFvYKEjRZKyMa+1AK6p0oD9zcIToEkcjknj3BbtQa27lLHg==", + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.13.9.tgz", + "integrity": "sha512-EAFtCs9dsGhpMRC45PoYsrkiExpWz9Ax15qXfzwdDRacz5DmdOVt+QpkLW1beUOwiyj/bhFyj23eaONK2RTn/w==", "dev": true, "requires": { - "@angular-devkit/core": "7.3.8", + "@angular-devkit/core": "7.3.9", "rxjs": "6.3.3" } }, "@angular-devkit/core": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.3.8.tgz", - "integrity": "sha512-3X9uzaZXFpm5o2TSzhD6wEOtVU32CgeytKjD1Scxj+uMMVo48SWLlKiFh312T+smI9ko7tOT8VqxglwYkWosgg==", + "version": "7.3.9", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.3.9.tgz", + "integrity": "sha512-SaxD+nKFW3iCBKsxNR7+66J30EexW/y7tm8m5AvUH+GwSAgIj0ZYmRUzFEPggcaLVA4WnE/YWqIXZMJW5dT7gw==", "dev": true, "requires": { "ajv": "6.9.1", @@ -146,6 +146,60 @@ "uri-js": "^4.2.2" } }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "optional": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "optional": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", + "dev": true, + "optional": true + }, + "node-sass": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.12.0.tgz", + "integrity": "sha512-A1Iv4oN+Iel6EPv77/HddXErL2a+gZ4uBeZUy+a8O35CFYTXhgA8MgLCWBtwpGZdCvTvQ9d+bQxX/QC36GDPpQ==", + "dev": true, + "optional": true, + "requires": { + "async-foreach": "^0.1.3", + "chalk": "^1.1.1", + "cross-spawn": "^3.0.0", + "gaze": "^1.0.0", + "get-stdin": "^4.0.1", + "glob": "^7.0.3", + "in-publish": "^2.0.0", + "lodash": "^4.17.11", + "meow": "^3.7.0", + "mkdirp": "^0.5.1", + "nan": "^2.13.2", + "node-gyp": "^3.8.0", + "npmlog": "^4.0.0", + "request": "^2.88.0", + "sass-graph": "^2.2.4", + "stdout-stream": "^1.4.0", + "true-case-path": "^1.0.2" + } + }, "parse5": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", @@ -160,6 +214,13 @@ "requires": { "tslib": "^1.9.0" } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "optional": true } } }, @@ -187,9 +248,9 @@ } }, "@angular-devkit/build-optimizer": { - "version": "0.13.8", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.13.8.tgz", - "integrity": "sha512-RvYxtsdYuvpFb1iivVixylSVN/Q8LsQ449uYuqEe3OsDjQBvUVG2fMLPOQjmKWhi0NC9WSsNiUluxLDNdvd0Vw==", + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.13.9.tgz", + "integrity": "sha512-GQtCntthQHSBv5l1ZY5p00JOECb/WcE1qUBo5kFjp84z0fszDkhOy52M1kcWCX4PFzJaY4DKk58hbUE/2UN0jw==", "dev": true, "requires": { "loader-utils": "1.2.3", @@ -207,30 +268,30 @@ } }, "@angular-devkit/build-webpack": { - "version": "0.13.8", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.13.8.tgz", - "integrity": "sha512-WMyn1vUHyx+VfJKgYuEHrICwQzPMDTaUNB1zlvzZt9gX/9H+XnetrebeWBZCITPXHBw/377oA6wmiHWJ0yaZRw==", + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.13.9.tgz", + "integrity": "sha512-6ypu6pzNmQxzATF4rTWEhGSl5hyGQ8a/3aCZF/ux+XGc3d4hi2HW+NWlDm1UEna6ZjNtgEPlgfP4q8BKrjRmfA==", "dev": true, "requires": { - "@angular-devkit/architect": "0.13.8", - "@angular-devkit/core": "7.3.8", + "@angular-devkit/architect": "0.13.9", + "@angular-devkit/core": "7.3.9", "rxjs": "6.3.3" }, "dependencies": { "@angular-devkit/architect": { - "version": "0.13.8", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.13.8.tgz", - "integrity": "sha512-gxUs5rhnP576T8ZclKqxlspiChrqRtqaJo54wqNVFvYKEjRZKyMa+1AK6p0oD9zcIToEkcjknj3BbtQa27lLHg==", + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.13.9.tgz", + "integrity": "sha512-EAFtCs9dsGhpMRC45PoYsrkiExpWz9Ax15qXfzwdDRacz5DmdOVt+QpkLW1beUOwiyj/bhFyj23eaONK2RTn/w==", "dev": true, "requires": { - "@angular-devkit/core": "7.3.8", + "@angular-devkit/core": "7.3.9", "rxjs": "6.3.3" } }, "@angular-devkit/core": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.3.8.tgz", - "integrity": "sha512-3X9uzaZXFpm5o2TSzhD6wEOtVU32CgeytKjD1Scxj+uMMVo48SWLlKiFh312T+smI9ko7tOT8VqxglwYkWosgg==", + "version": "7.3.9", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.3.9.tgz", + "integrity": "sha512-SaxD+nKFW3iCBKsxNR7+66J30EexW/y7tm8m5AvUH+GwSAgIj0ZYmRUzFEPggcaLVA4WnE/YWqIXZMJW5dT7gw==", "dev": true, "requires": { "ajv": "6.9.1", @@ -300,19 +361,19 @@ } }, "@angular-devkit/schematics": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-7.3.8.tgz", - "integrity": "sha512-mvaKoORZIaW/h0VNZ3IQWP0qThRCZRX6869FNlzV0jlW0mhn07XbiIGHCGGSCDRxS7qJ0VbuIVnKXntF+iDeWw==", + "version": "7.3.9", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-7.3.9.tgz", + "integrity": "sha512-xzROGCYp7aQbeJ3V6YC0MND7wKEAdWqmm/GaCufEk0dDS8ZGe0sQhcM2oBRa2nQqGQNeThFIH51kx+FayrJP0w==", "dev": true, "requires": { - "@angular-devkit/core": "7.3.8", + "@angular-devkit/core": "7.3.9", "rxjs": "6.3.3" }, "dependencies": { "@angular-devkit/core": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.3.8.tgz", - "integrity": "sha512-3X9uzaZXFpm5o2TSzhD6wEOtVU32CgeytKjD1Scxj+uMMVo48SWLlKiFh312T+smI9ko7tOT8VqxglwYkWosgg==", + "version": "7.3.9", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.3.9.tgz", + "integrity": "sha512-SaxD+nKFW3iCBKsxNR7+66J30EexW/y7tm8m5AvUH+GwSAgIj0ZYmRUzFEPggcaLVA4WnE/YWqIXZMJW5dT7gw==", "dev": true, "requires": { "ajv": "6.9.1", @@ -346,9 +407,9 @@ } }, "@angular/animations": { - "version": "7.2.14", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-7.2.14.tgz", - "integrity": "sha512-K+wdq7TslmvDhrbwy65x7owE8wezI0fDdO+8SO9RU4m/w6R6vo4QS3uSdc5I2pxwm4QSXSc5eKhoWJkq0muTbQ==", + "version": "7.2.15", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-7.2.15.tgz", + "integrity": "sha512-8oBt3HLgd2+kyJHUgsd7OzKCCss67t2sch15XNoIWlOLfxclqU+EfFE6t/vCzpT8/+lpZS6LU9ZrTnb+UBj5jg==", "requires": { "tslib": "^1.9.0" } @@ -363,16 +424,16 @@ } }, "@angular/cli": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-7.3.8.tgz", - "integrity": "sha512-5ldU1idvWstmRaavGZen9WRjfjIViERGt8NYuLLI7dgVLYOPF5TyFoTnpT5nxkiCopp4tPIcpbzPV394Bxmdtg==", + "version": "7.3.9", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-7.3.9.tgz", + "integrity": "sha512-7oJj7CKDlFUbQav1x1CV4xKKcbt0pnxY4unKcm7Q1tVXhu8bU2bc3cDA0aJnbofcYb6TJcd/C2qHgCt78q7edA==", "dev": true, "requires": { - "@angular-devkit/architect": "0.13.8", - "@angular-devkit/core": "7.3.8", - "@angular-devkit/schematics": "7.3.8", - "@schematics/angular": "7.3.8", - "@schematics/update": "0.13.8", + "@angular-devkit/architect": "0.13.9", + "@angular-devkit/core": "7.3.9", + "@angular-devkit/schematics": "7.3.9", + "@schematics/angular": "7.3.9", + "@schematics/update": "0.13.9", "@yarnpkg/lockfile": "1.1.0", "ini": "1.3.5", "inquirer": "6.2.1", @@ -384,19 +445,19 @@ }, "dependencies": { "@angular-devkit/architect": { - "version": "0.13.8", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.13.8.tgz", - "integrity": "sha512-gxUs5rhnP576T8ZclKqxlspiChrqRtqaJo54wqNVFvYKEjRZKyMa+1AK6p0oD9zcIToEkcjknj3BbtQa27lLHg==", + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.13.9.tgz", + "integrity": "sha512-EAFtCs9dsGhpMRC45PoYsrkiExpWz9Ax15qXfzwdDRacz5DmdOVt+QpkLW1beUOwiyj/bhFyj23eaONK2RTn/w==", "dev": true, "requires": { - "@angular-devkit/core": "7.3.8", + "@angular-devkit/core": "7.3.9", "rxjs": "6.3.3" } }, "@angular-devkit/core": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.3.8.tgz", - "integrity": "sha512-3X9uzaZXFpm5o2TSzhD6wEOtVU32CgeytKjD1Scxj+uMMVo48SWLlKiFh312T+smI9ko7tOT8VqxglwYkWosgg==", + "version": "7.3.9", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.3.9.tgz", + "integrity": "sha512-SaxD+nKFW3iCBKsxNR7+66J30EexW/y7tm8m5AvUH+GwSAgIj0ZYmRUzFEPggcaLVA4WnE/YWqIXZMJW5dT7gw==", "dev": true, "requires": { "ajv": "6.9.1", @@ -430,25 +491,25 @@ } }, "@angular/common": { - "version": "7.2.14", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-7.2.14.tgz", - "integrity": "sha512-c2QBhVpbQhg1FDhOQkyVdFvU11mfvYHW5ZaXzxdCpq2rZXCureYiCSnlv++EsIAKqi22+2a6GACHF9Gh8kBmSg==", + "version": "7.2.15", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-7.2.15.tgz", + "integrity": "sha512-2b5JY2HWVHCf3D1GZjmde7jdAXSTXkYtmjLtA9tQkjOOTr80eHpNSujQqnzb97dk9VT9OjfjqTQd7K3pxZz8jw==", "requires": { "tslib": "^1.9.0" } }, "@angular/compiler": { - "version": "7.2.14", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-7.2.14.tgz", - "integrity": "sha512-Idhs+5HIzx+1+hrXIDaRpSqobMB7UvSvPlvCvtb3EDYjmltTNG68TtwMzGM8W2jdayliYuFOjFrnw1wCTkK3Ag==", + "version": "7.2.15", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-7.2.15.tgz", + "integrity": "sha512-5yb4NcLk8GuXkYf7Dcor4XkGueYp4dgihzDmMjYDUrV0NPhubKlr+SwGtLOtzgRBWJ1I2bO0S3zwa0q0OgIPOw==", "requires": { "tslib": "^1.9.0" } }, "@angular/compiler-cli": { - "version": "7.2.14", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-7.2.14.tgz", - "integrity": "sha512-w5qn1nIPjiCP3WdbqicofpKpiRlh6NMYjWhe6mJysSBnVd34aSuGisYW/gVPQrmD46E1gmfpWTnWPeABVnjj6w==", + "version": "7.2.15", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-7.2.15.tgz", + "integrity": "sha512-+AsfyKawmj/sa+m4Pz8VSRFbCfx/3IOjAuuEjhopbyr154YpPDSu8NTbcwzq3yfbVcPwK4/4exmbQzpsndaCTg==", "dev": true, "requires": { "canonical-path": "1.0.0", @@ -477,9 +538,9 @@ "dev": true }, "chokidar": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.5.tgz", - "integrity": "sha512-i0TprVWp+Kj4WRPtInjexJ8Q+BqTE909VpH8xVhXrJkoc5QC8VO9TryGOqTr+2hljzc1sC62t22h5tZePodM/A==", + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.6.tgz", + "integrity": "sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g==", "dev": true, "requires": { "anymatch": "^2.0.0", @@ -684,9 +745,9 @@ } }, "@angular/core": { - "version": "7.2.14", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-7.2.14.tgz", - "integrity": "sha512-XeZZJCyBKSKo0E/7Ef0SfJejmn+E7uBXa5cR1QapafS0Hnrq/hZu/NI039IDU/51NoycMDH2vTV19SmKu9Mkow==", + "version": "7.2.15", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-7.2.15.tgz", + "integrity": "sha512-XsuYm0jEU/mOqwDOk2utThv8J9kESkAerfuCHClE9rB2TtHUOGCfekF7lJWqjjypu6/J9ygoPFo7hdAE058ZGg==", "requires": { "tslib": "^1.9.0" } @@ -700,25 +761,25 @@ } }, "@angular/forms": { - "version": "7.2.14", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-7.2.14.tgz", - "integrity": "sha512-jL5YbTk7VZmz4l0++iFVUNa1vGM+nnALjHKi1Ub8VWioRDRboYUsHyxzlgWW9gZRbHpnLEXFiUz1td+v7TouJw==", + "version": "7.2.15", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-7.2.15.tgz", + "integrity": "sha512-p0kcIQLtBBC1qeTA6M3nOuXf/k91E80FKquVM9zEsO2kDjI0oZJVfFYL2UMov5samlJOPN+t6lRHEIUa7ApPsw==", "requires": { "tslib": "^1.9.0" } }, "@angular/http": { - "version": "7.2.14", - "resolved": "https://registry.npmjs.org/@angular/http/-/http-7.2.14.tgz", - "integrity": "sha512-rSdH2JojApDU83qVm7RabIlNo3Ni3yr2gwsmQWs4XZ7SC8jLNnDkzdUbQ6T0vfuVX3v/FtAuMJl0yaVcG3EUJg==", + "version": "7.2.15", + "resolved": "https://registry.npmjs.org/@angular/http/-/http-7.2.15.tgz", + "integrity": "sha512-TR7PEdmLWNIre3Zn8lvyb4lSrvPUJhKLystLnp4hBMcWsJqq5iK8S3bnlR4viZ9HMlf7bW7+Hm4SI6aB3tdUtw==", "requires": { "tslib": "^1.9.0" } }, "@angular/language-service": { - "version": "7.2.14", - "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-7.2.14.tgz", - "integrity": "sha512-YTU4ePAKikbIxNae9Qta8qaDArPgek7nhLEW9QfvrUAnpF7BkVboEI+7yLX5+NTfGf9cQ9cUfQ0TEreV+tMs7A==", + "version": "7.2.15", + "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-7.2.15.tgz", + "integrity": "sha512-Ig5Jr7mnDelaZvSbUd9YhI5am3q1ku9xelAuwvtyDKvQJeKQj3BtTagcOgWrnQBfrJ/FsA/M5Zo48ncSsV0tqQ==", "dev": true }, "@angular/material": { @@ -738,25 +799,25 @@ } }, "@angular/platform-browser": { - "version": "7.2.14", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-7.2.14.tgz", - "integrity": "sha512-yAq2+3W4J4B48HEmZYQucdEb9AHwRnv72q9CC/SxU7g59vaLhl1nv7cAWGJ4XFaJTbB7aB4Y4rLffuR+Gxkn7A==", + "version": "7.2.15", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-7.2.15.tgz", + "integrity": "sha512-aYgmPsbC9Tvp9vmKWD8voeAp4crwCay7/D6lM3ClEe2EeK934LuEXq3/uczMrFVbnIX7BBIo8fh03Tl7wbiGPw==", "requires": { "tslib": "^1.9.0" } }, "@angular/platform-browser-dynamic": { - "version": "7.2.14", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-7.2.14.tgz", - "integrity": "sha512-lmTCBiDRbOPtniIqBjm1n5jl1TdyQM0qWQdBcoCsKpMNS/6/RacRcQsJZApAMdWm6gIVuLgmRQzaCLkSoekfYA==", + "version": "7.2.15", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-7.2.15.tgz", + "integrity": "sha512-UL2PqhzXMD769NQ6Lh6pxlBDKvN9Qol3XLRFil80lwJ1GRW16ITeYbCamcafIH2GOyd88IhmYcbMfUQ/6q4MMQ==", "requires": { "tslib": "^1.9.0" } }, "@angular/router": { - "version": "7.2.14", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-7.2.14.tgz", - "integrity": "sha512-uqg0SKy79voEOIOvzVbCzFDD9XOAfZWkYt01ca2qLFXMx+6jWeVQIDuXc8Dmz5udIXNK5Ae//9R+nt5UZUZrSA==", + "version": "7.2.15", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-7.2.15.tgz", + "integrity": "sha512-qAubRJRQanguUqJQ76J9GSZ4JFtoyhJKRmX5P23ANZJXpB6YLzF2fJmOGi+E6cV8F0tKBMEq1pjxFTisx0MXwQ==", "requires": { "tslib": "^1.9.0" } @@ -771,14 +832,14 @@ } }, "@babel/generator": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.3.2.tgz", - "integrity": "sha512-f3QCuPppXxtZOEm5GWPra/uYUjmNQlu9pbAD8D/9jze4pTY83rTtB1igTBSwvkeNlC5gR24zFFkz+2WHLFQhqQ==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.4.4.tgz", + "integrity": "sha512-53UOLK6TVNqKxf7RUh8NE851EHRxOOeVXKbK2bivdb+iziMyk03Sr4eaE9OELCbyZAAafAKPDwF2TPUES5QbxQ==", "dev": true, "requires": { - "@babel/types": "^7.3.2", + "@babel/types": "^7.4.4", "jsesc": "^2.5.1", - "lodash": "^4.17.10", + "lodash": "^4.17.11", "source-map": "^0.5.0", "trim-right": "^1.0.1" }, @@ -818,12 +879,12 @@ } }, "@babel/helper-split-export-declaration": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz", - "integrity": "sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz", + "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==", "dev": true, "requires": { - "@babel/types": "^7.0.0" + "@babel/types": "^7.4.4" } }, "@babel/highlight": { @@ -846,24 +907,24 @@ } }, "@babel/parser": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.3.2.tgz", - "integrity": "sha512-QzNUC2RO1gadg+fs21fi0Uu0OuGNzRKEmgCxoLNzbCdoprLwjfmZwzUrpUNfJPaVRwBpDY47A17yYEGWyRelnQ==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.4.tgz", + "integrity": "sha512-5pCS4mOsL+ANsFZGdvNLybx4wtqAZJ0MJjMHxvzI3bvIsz6sQvzW8XX92EYIkiPtIvcfG3Aj+Ir5VNyjnZhP7w==", "dev": true }, "@babel/runtime": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.0.0.tgz", - "integrity": "sha512-7hGhzlcmg01CvH1EHdSPVXYX1aJ8KCEyz6I9xYIi/asDtzBPMyMhVibhM/K6g/5qnKBwjZtp10bNZIEFTRW1MA==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.4.4.tgz", + "integrity": "sha512-w0+uT71b6Yi7i5SE0co4NioIpSYS6lLiXvCzWzGSKvpK5vdQtCbICHMj+gbAKAOtxiV6HsVh/MBdaF9EQ6faSg==", "dev": true, "requires": { - "regenerator-runtime": "^0.12.0" + "regenerator-runtime": "^0.13.2" }, "dependencies": { "regenerator-runtime": { - "version": "0.12.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz", - "integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==", + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz", + "integrity": "sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA==", "dev": true } } @@ -887,31 +948,31 @@ } }, "@babel/template": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.2.2.tgz", - "integrity": "sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz", + "integrity": "sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.2.2", - "@babel/types": "^7.2.2" + "@babel/parser": "^7.4.4", + "@babel/types": "^7.4.4" } }, "@babel/traverse": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.2.3.tgz", - "integrity": "sha512-Z31oUD/fJvEWVR0lNZtfgvVt512ForCTNKYcJBGbPb1QZfve4WGH8Wsy7+Mev33/45fhP/hwQtvgusNdcCMgSw==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.4.tgz", + "integrity": "sha512-Gw6qqkw/e6AGzlyj9KnkabJX7VcubqPtkUQVAwkc0wUMldr3A/hezNB3Rc5eIvId95iSGkGIOe5hh1kMKf951A==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@babel/generator": "^7.2.2", + "@babel/generator": "^7.4.4", "@babel/helper-function-name": "^7.1.0", - "@babel/helper-split-export-declaration": "^7.0.0", - "@babel/parser": "^7.2.3", - "@babel/types": "^7.2.2", + "@babel/helper-split-export-declaration": "^7.4.4", + "@babel/parser": "^7.4.4", + "@babel/types": "^7.4.4", "debug": "^4.1.0", "globals": "^11.1.0", - "lodash": "^4.17.10" + "lodash": "^4.17.11" }, "dependencies": { "debug": { @@ -924,21 +985,21 @@ } }, "globals": { - "version": "11.11.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.11.0.tgz", - "integrity": "sha512-WHq43gS+6ufNOEqlrDBxVEbb8ntfXrfAUU2ZOpCxrBdGKW3gyv8mCxAfIBD0DroPKGrJ2eSsXsLtY9MPntsyTw==", + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true } } }, "@babel/types": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.3.2.tgz", - "integrity": "sha512-3Y6H8xlUlpbGR+XvawiH0UXehqydTmNmEpozWcXymqwcrwYAl5KMvKtQ+TF6f6E08V6Jur7v/ykdDSF+WDEIXQ==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz", + "integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==", "dev": true, "requires": { "esutils": "^2.0.2", - "lodash": "^4.17.10", + "lodash": "^4.17.11", "to-fast-properties": "^2.0.0" }, "dependencies": { @@ -993,12 +1054,12 @@ "dev": true }, "@ngtools/webpack": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-7.3.8.tgz", - "integrity": "sha512-gfjSKz+F/2T4tZHpnQ1XqelKP/CIfI87XdoHsOI53ceTUrAkVKsOb3ULmEfkcdsdQZ/HhmCiLivcutHcW8xkhQ==", + "version": "7.3.9", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-7.3.9.tgz", + "integrity": "sha512-+ROpqfCXLdQwfP+UNDLk4p959ZrocpStkdd2Iy9CeOJ8yDkityqpstTwQC3oHzzu/95BiyZ0hrHbM6AsPPIvJg==", "dev": true, "requires": { - "@angular-devkit/core": "7.3.8", + "@angular-devkit/core": "7.3.9", "enhanced-resolve": "4.1.0", "rxjs": "6.3.3", "tree-kill": "1.2.1", @@ -1006,9 +1067,9 @@ }, "dependencies": { "@angular-devkit/core": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.3.8.tgz", - "integrity": "sha512-3X9uzaZXFpm5o2TSzhD6wEOtVU32CgeytKjD1Scxj+uMMVo48SWLlKiFh312T+smI9ko7tOT8VqxglwYkWosgg==", + "version": "7.3.9", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.3.9.tgz", + "integrity": "sha512-SaxD+nKFW3iCBKsxNR7+66J30EexW/y7tm8m5AvUH+GwSAgIj0ZYmRUzFEPggcaLVA4WnE/YWqIXZMJW5dT7gw==", "dev": true, "requires": { "ajv": "6.9.1", @@ -1068,20 +1129,20 @@ } }, "@schematics/angular": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-7.3.8.tgz", - "integrity": "sha512-7o90bnIxXNpJhWPDY/zCedcG6KMIihz7a4UQe6UdlhEX21MNZLYFiDiR5Vmsx39wjm2EfPh3JTuBIHGmMCXkQQ==", + "version": "7.3.9", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-7.3.9.tgz", + "integrity": "sha512-B3lytFtFeYNLfWdlrIzvy3ulFRccD2/zkoL0734J+DAGfUz7vbysJ50RwYL46sQUcKdZdvb48ktfu1S8yooP6Q==", "dev": true, "requires": { - "@angular-devkit/core": "7.3.8", - "@angular-devkit/schematics": "7.3.8", + "@angular-devkit/core": "7.3.9", + "@angular-devkit/schematics": "7.3.9", "typescript": "3.2.4" }, "dependencies": { "@angular-devkit/core": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.3.8.tgz", - "integrity": "sha512-3X9uzaZXFpm5o2TSzhD6wEOtVU32CgeytKjD1Scxj+uMMVo48SWLlKiFh312T+smI9ko7tOT8VqxglwYkWosgg==", + "version": "7.3.9", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.3.9.tgz", + "integrity": "sha512-SaxD+nKFW3iCBKsxNR7+66J30EexW/y7tm8m5AvUH+GwSAgIj0ZYmRUzFEPggcaLVA4WnE/YWqIXZMJW5dT7gw==", "dev": true, "requires": { "ajv": "6.9.1", @@ -1115,13 +1176,13 @@ } }, "@schematics/update": { - "version": "0.13.8", - "resolved": "https://registry.npmjs.org/@schematics/update/-/update-0.13.8.tgz", - "integrity": "sha512-2jP9w7Nnn24jOdrJtWjoS9LsNPmO9/Eu/+gDxBAVERCqR71mtNW+DopgWDtxleE9jri/pZWrHwShGFCSS7w23g==", + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/@schematics/update/-/update-0.13.9.tgz", + "integrity": "sha512-4MQcaKFxhMzZyE//+DknDh3h3duy3avg2oxSHxdwXlCZ8Q92+4lpegjJcSRiqlEwO4qeJ5XnrjrvzfIiaIZOmA==", "dev": true, "requires": { - "@angular-devkit/core": "7.3.8", - "@angular-devkit/schematics": "7.3.8", + "@angular-devkit/core": "7.3.9", + "@angular-devkit/schematics": "7.3.9", "@yarnpkg/lockfile": "1.1.0", "ini": "1.3.5", "pacote": "9.4.0", @@ -1131,9 +1192,9 @@ }, "dependencies": { "@angular-devkit/core": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.3.8.tgz", - "integrity": "sha512-3X9uzaZXFpm5o2TSzhD6wEOtVU32CgeytKjD1Scxj+uMMVo48SWLlKiFh312T+smI9ko7tOT8VqxglwYkWosgg==", + "version": "7.3.9", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.3.9.tgz", + "integrity": "sha512-SaxD+nKFW3iCBKsxNR7+66J30EexW/y7tm8m5AvUH+GwSAgIj0ZYmRUzFEPggcaLVA4WnE/YWqIXZMJW5dT7gw==", "dev": true, "requires": { "ajv": "6.9.1", @@ -1199,6 +1260,15 @@ "integrity": "sha1-vShOV8hPEyXacCur/IKlMoGQwMU=", "dev": true }, + "@types/resolve": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", + "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/selenium-webdriver": { "version": "3.0.14", "resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-3.0.14.tgz", @@ -1743,11 +1813,12 @@ } }, "assert": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", - "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", "dev": true, "requires": { + "object-assign": "^4.1.1", "util": "0.10.3" }, "dependencies": { @@ -1915,25 +1986,6 @@ "babel-runtime": "^6.22.0" } }, - "babel-polyfill": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.23.0.tgz", - "integrity": "sha1-g2TKYt+Or7gwSZ9pkXdGbDsDSZ0=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "core-js": "^2.4.0", - "regenerator-runtime": "^0.10.0" - }, - "dependencies": { - "regenerator-runtime": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", - "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=", - "dev": true - } - } - }, "babel-runtime": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", @@ -3082,10 +3134,13 @@ "dev": true }, "content-disposition": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", - "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=", - "dev": true + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "dev": true, + "requires": { + "safe-buffer": "5.1.2" + } }, "content-type": { "version": "1.0.4", @@ -3283,54 +3338,66 @@ "dev": true }, "cspell": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/cspell/-/cspell-3.2.1.tgz", - "integrity": "sha512-VjEcxU+WUfJn1/ShgYVsH4fdT8MaOBmLATKZ2DpsY+zdh5i07NmC8fVlsF56F4rE5Ybz2e9KHMi+HcNN08ruEg==", + "version": "3.2.17", + "resolved": "https://registry.npmjs.org/cspell/-/cspell-3.2.17.tgz", + "integrity": "sha512-ubl9KnYgigK06Qo9tUx0xGSlyNpV1M68HDPnA7UNtL4yloOE6/K1GVw6J9prhV2KZZgBxqa5GATD8T6nS0mxMQ==", "dev": true, "requires": { "chalk": "^2.4.2", - "commander": "^2.19.0", + "commander": "^2.20.0", "comment-json": "^1.1.3", "configstore": "^4.0.0", - "cspell-dict-companies": "^1.0.3", - "cspell-dict-cpp": "^1.1.11", - "cspell-dict-django": "^1.0.7", - "cspell-dict-elixir": "^1.0.4", - "cspell-dict-en-gb": "^1.1.7", - "cspell-dict-en_us": "^1.2.10", - "cspell-dict-fullstack": "^1.0.6", - "cspell-dict-golang": "^1.1.8", - "cspell-dict-java": "^1.0.5", - "cspell-dict-latex": "^1.0.6", - "cspell-dict-lorem-ipsum": "^1.0.4", - "cspell-dict-php": "^1.0.7", - "cspell-dict-python": "^1.0.8", + "cspell-dict-companies": "^1.0.6", + "cspell-dict-cpp": "^1.1.14", + "cspell-dict-django": "^1.0.8", + "cspell-dict-elixir": "^1.0.5", + "cspell-dict-en-gb": "^1.1.8", + "cspell-dict-en_us": "^1.2.12", + "cspell-dict-fullstack": "^1.0.10", + "cspell-dict-golang": "^1.1.9", + "cspell-dict-java": "^1.0.7", + "cspell-dict-latex": "^1.0.8", + "cspell-dict-lorem-ipsum": "^1.0.6", + "cspell-dict-php": "^1.0.8", + "cspell-dict-python": "^1.0.9", "cspell-dict-rust": "^1.0.6", - "cspell-dict-scala": "^1.0.5", - "cspell-lib": "^3.0.5", - "cspell-trie": "^3.0.7", + "cspell-dict-scala": "^1.0.6", + "cspell-lib": "^3.0.8", + "cspell-trie": "^3.0.10", "fs-extra": "^7.0.1", "gensequence": "^2.1.2", - "glob": "^7.1.3", + "get-stdin": "^7.0.0", + "glob": "^7.1.4", "minimatch": "^3.0.4", - "rxjs": "6.3.3", + "rxjs": "^6.5.2", "vscode-uri": "^1.0.6", "xregexp": "^4.2.4" }, "dependencies": { "commander": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", - "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", + "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", "dev": true }, - "rxjs": { - "version": "6.3.3", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", - "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", + "get-stdin": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-7.0.0.tgz", + "integrity": "sha512-zRKcywvrXlXsA0v0i9Io4KDRaAw7+a1ZpjRwl9Wox8PFlVCCHra7E9c4kqXCoCM9nR5tBkaTTZRBoCm60bFqTQ==", + "dev": true + }, + "glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", "dev": true, "requires": { - "tslib": "^1.9.0" + "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" } }, "xregexp": { @@ -3345,144 +3412,144 @@ } }, "cspell-dict-companies": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/cspell-dict-companies/-/cspell-dict-companies-1.0.3.tgz", - "integrity": "sha512-L4CKmMuI2kSno99tKYHI807y02niwxaFZOsRtmTjb0+zJ8dzyscXvQFmTwynUn3XZf4G+TbYcCOZaSpsx0RlWA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/cspell-dict-companies/-/cspell-dict-companies-1.0.7.tgz", + "integrity": "sha512-J78DyrVDKhS7Jqk8TuSStqus4LVRBLN3SYasysTq1IE+VRV0IJYP2lAURBGjBbnqBuh7a41fNHQu3/Y+GoXbuQ==", "dev": true, "requires": { "configstore": "^4.0.0" } }, "cspell-dict-cpp": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/cspell-dict-cpp/-/cspell-dict-cpp-1.1.11.tgz", - "integrity": "sha512-FWiOe6nntT1k4r/CkSo8qG6Ib4phu3WXGPqg6txOw+e9wlojzXN7rND2Z8AHt4TUA36h3lHpk/y7gTBgJgR+lw==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/cspell-dict-cpp/-/cspell-dict-cpp-1.1.15.tgz", + "integrity": "sha512-MEjsCg8ubqRX7mNn8ABUVUvwndATZ3P4kOGQks0rBsXsR9cIPo8E1wyFV3VpMY4SUdUhpAAU1X5yzjvBQTcTDg==", "dev": true, "requires": { "configstore": "^4.0.0" } }, "cspell-dict-django": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/cspell-dict-django/-/cspell-dict-django-1.0.7.tgz", - "integrity": "sha512-Gi7fYuGLEJSH307ywkOIziQYS3hdIBwMesjvEW71ovqjg0CyQKADcU4ZUd5fcMlndxRLpVhG4NXo3tGdsDf3wA==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/cspell-dict-django/-/cspell-dict-django-1.0.9.tgz", + "integrity": "sha512-l5Di7WFfoXzzmXdRsEYpHj9o+OwEmAwVHzS4KQ18NJ6r4lsR4sb4GERFqXM7vaQoKkN0tN/skTqGqYoMl1wARA==", "dev": true, "requires": { "configstore": "^4.0.0" } }, "cspell-dict-elixir": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cspell-dict-elixir/-/cspell-dict-elixir-1.0.4.tgz", - "integrity": "sha512-K4W3kmb7ZLbtaoV0Xwd1XGS6DzNah3tygbp7yT4jaq2f6WvG8Uh80tSNog6YIF+DAVk6709RKbIurbHZsx08dg==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cspell-dict-elixir/-/cspell-dict-elixir-1.0.6.tgz", + "integrity": "sha512-fXYQwb8lSiJk/26vhZcrzaYbja0ka6IravSU7S+ivt/4guXYlrzoFvnKtwGVhgEJ0VTVh0Dqtmz2N8xDemyalw==", "dev": true, "requires": { "configstore": "^4.0.0" } }, "cspell-dict-en-gb": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/cspell-dict-en-gb/-/cspell-dict-en-gb-1.1.7.tgz", - "integrity": "sha512-inEzvckvzzscmRE3zCF3dAtAdSD0xHeIba/KAFuu6/yVNWp0zwqMiW1UQ6lW6kXyueETjHLuZMSAJbC4R1DrOA==", + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/cspell-dict-en-gb/-/cspell-dict-en-gb-1.1.9.tgz", + "integrity": "sha512-DwCKORzqcU/Ob4U/O/5Gdl6Uw3R0qu8Px9FR3kUskXNYDmzZzDL7niLVZ8E6pnGGB58oOPPGQZqGJy5c8ucATQ==", "dev": true, "requires": { "configstore": "^4.0.0" } }, "cspell-dict-en_us": { - "version": "1.2.10", - "resolved": "https://registry.npmjs.org/cspell-dict-en_us/-/cspell-dict-en_us-1.2.10.tgz", - "integrity": "sha512-3unRvF++r1v2kh9C6R6jzIL0J67i8XIQ/RwNWjQ8fRBdchAzpiV9l0hnpXn4V98Icyy3r1aUpVzBIwGogBQiqw==", + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/cspell-dict-en_us/-/cspell-dict-en_us-1.2.13.tgz", + "integrity": "sha512-Aw8GVw1EHnITloqkpKEIjZOvDKF1ElB7BTqkT6bfTEMG8ddTui9hsNuGGGRZFH2ZL92MH1hNsFcSaY4WLVztOA==", "dev": true, "requires": { "configstore": "^4.0.0" } }, "cspell-dict-fullstack": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cspell-dict-fullstack/-/cspell-dict-fullstack-1.0.6.tgz", - "integrity": "sha512-40rQ/6E5erZC4ZS7uQ8Q93M0VrFuqFhcGCup/ZrO2lRHsRPj5+iVeX80VY1jl/gPmG2H/pnJ5+oC5CJkgEBGVw==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/cspell-dict-fullstack/-/cspell-dict-fullstack-1.0.11.tgz", + "integrity": "sha512-c1F97bdrt7jvQBfoz8XNq9SBMyyNRl53SlCGWCJr2OJw0PMDYoysOYrgAKSQ86wLOlEgqcaTuYPxghuHiSK8Pg==", "dev": true, "requires": { "configstore": "^4.0.0" } }, "cspell-dict-golang": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/cspell-dict-golang/-/cspell-dict-golang-1.1.8.tgz", - "integrity": "sha512-Ux7Qm9P9sWiVHgbsuKQGJWj+iJkcQkLrlKmqsmNxXc9JeGpS6exmhJLNkhTjQwryB+ry5zcsvvobpCGUC+NBPw==", + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/cspell-dict-golang/-/cspell-dict-golang-1.1.10.tgz", + "integrity": "sha512-R+ovnhScVm3FcIjsQcLFTFnf9CuZM4hjAfl/+s1fDHY2fnSjW2fsplGvTHbH8OXICfDVap0+vjyvxweC7vTWGw==", "dev": true, "requires": { "configstore": "^4.0.0" } }, "cspell-dict-java": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/cspell-dict-java/-/cspell-dict-java-1.0.5.tgz", - "integrity": "sha512-kwp3i+JW2LwzYFk0w9cPCGKe80z7V89GOubFTGpudm9E6y46eO+3YAAjVK5PhMIuuDYF69CicaiP6eW8FsbyhA==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/cspell-dict-java/-/cspell-dict-java-1.0.8.tgz", + "integrity": "sha512-xb1UR9pllrblxTvIa4wlxiLpTzP/ctsBMAinEATJ1nGboHStZAY7wCNOFDaBCNgdA8yHcQ4QBoKfXmN2jsb61w==", "dev": true, "requires": { "configstore": "^4.0.0" } }, "cspell-dict-latex": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cspell-dict-latex/-/cspell-dict-latex-1.0.6.tgz", - "integrity": "sha512-BQJbH1RwOPuIHfKsWKSBxIj2QZydVWPSRruwrMQ15gzcheYBz623QhedvrNMgm29AVoH7Lu7i0GIopOyb4ebPw==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/cspell-dict-latex/-/cspell-dict-latex-1.0.9.tgz", + "integrity": "sha512-2fexq4EYQ5X7Ly8w9EMYarVk9nShIQbivSEhtAuNM5fEe40+r1knuGGPblO/BHS96jR0QC6Q92ztw1uh+u4w/g==", "dev": true, "requires": { "configstore": "^4.0.0" } }, "cspell-dict-lorem-ipsum": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cspell-dict-lorem-ipsum/-/cspell-dict-lorem-ipsum-1.0.4.tgz", - "integrity": "sha512-JcYUh671h4eLQ3ZX11fnf9pwcGNdFmuSBSE0T37UMFRWkhTPYzoAqXuoWQ1JPE4r4uq9KIEBzGl/VPOIpw1g7w==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/cspell-dict-lorem-ipsum/-/cspell-dict-lorem-ipsum-1.0.7.tgz", + "integrity": "sha512-qL3oenberecxOpbjq8wfg6XdxKW0iAqlvdqLbCBTSX6wA6MBEKDTFbOWYLUF34op/GVVHhtbUbQnhqulIGG0JQ==", "dev": true, "requires": { "configstore": "^4.0.0" } }, "cspell-dict-php": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/cspell-dict-php/-/cspell-dict-php-1.0.7.tgz", - "integrity": "sha512-D17wWNAAnlzqSzN9xo7tqPlxyXebKKNXaBFpsehyTZy9GBBk4jzCk6tYW6QKPmAm/Z6rATRdaeoRg2u866+87A==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/cspell-dict-php/-/cspell-dict-php-1.0.9.tgz", + "integrity": "sha512-oteYXYDg0uVokEJlmsRx8J/iIc4OW+/+f4mNWsKrcr0ufjm+4JRYzlaRi3Lq2TglFmsnv7pP9NqL3ku3cvX5Sg==", "dev": true, "requires": { "configstore": "^4.0.0" } }, "cspell-dict-python": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/cspell-dict-python/-/cspell-dict-python-1.0.8.tgz", - "integrity": "sha512-j89SutsSPefWxjk8UjYVNEEIaFS07ubh2qXCGQyjMe8nKer2244QBrbUtCCDGeePEIOqvSNP1IS26k32a6SEuw==", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/cspell-dict-python/-/cspell-dict-python-1.0.10.tgz", + "integrity": "sha512-y1bR0EFtxOVV4MJC0D83g2tHpxfZROqOmGwlNPqIcZwARTvF9/FJkV72trnagBWwXBu81ztnHKm1tJqIbTf26A==", "dev": true, "requires": { "configstore": "^4.0.0" } }, "cspell-dict-rust": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cspell-dict-rust/-/cspell-dict-rust-1.0.6.tgz", - "integrity": "sha512-dOBSzOwV+HkfLqMq7JKNaxjUa3W0szWa2gKslZMvolwdaV5t2yWion0EfO63JvFZqky/oN2on52CQ3wSgHlT3w==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/cspell-dict-rust/-/cspell-dict-rust-1.0.7.tgz", + "integrity": "sha512-1H8SgMUfFg0wQAZX8KI+wuZF3PypO/1aCfJhdSE0c+JL6AxAHkSl0e1Xx7iyQv+5MBcah7BdNCzLa3SGfg63AQ==", "dev": true, "requires": { "configstore": "^4.0.0" } }, "cspell-dict-scala": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/cspell-dict-scala/-/cspell-dict-scala-1.0.5.tgz", - "integrity": "sha512-7rAmPo36imNIb6X9wu02SCaF5hW8d6/ECPDixFD/X+yyHNGnZDOKlx1eVd4jDEHbL+m0v6CdHBxM2te8nnfgdA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/cspell-dict-scala/-/cspell-dict-scala-1.0.7.tgz", + "integrity": "sha512-bJRjLusww7Dr97OQMXWXVfI6Vcm69v0NwqsQGXl4w+pAUh7yA7tutYZJlXBTwQTMhrdI823Sva6axm3F969f6Q==", "dev": true, "requires": { "configstore": "^4.0.0" } }, "cspell-lib": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/cspell-lib/-/cspell-lib-3.0.5.tgz", - "integrity": "sha512-z2f5t4un43qWFYYtEKjdDj1aG2TIdOUUYQpytkDrzWcJxyOkSzxOPItOe9zypQeJrIQ8YeVnrazzKpzeap/Ulw==", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/cspell-lib/-/cspell-lib-3.0.8.tgz", + "integrity": "sha512-JRuvKQEli2SYYhH0/P4YgOEhZM9hKzKO8Fw1PPkX+nSiYWrdt7xkNd6vBG0t1aGngm7Tw4fBs1V3nl3D9BlvIA==", "dev": true, "requires": { "iconv-lite": "^0.4.24", @@ -3501,24 +3568,25 @@ } }, "cspell-trie": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/cspell-trie/-/cspell-trie-3.0.7.tgz", - "integrity": "sha512-ASunLF5cb9qr8aLw23mcD6150Ipcn3c2pGcbIgN6Qoenk12An3JYZIi9+SLDvsf/LgPFa+EccUiFw1ox+WpvKg==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/cspell-trie/-/cspell-trie-3.0.10.tgz", + "integrity": "sha512-70maLAmZTvbUo5qKr2UD3zA9FZ31p2a4bAyJsMdTvVHMj+t5CyuGGgOQ5579FF4MpOWpnSxT5/uzpZtWlkEk1A==", "dev": true, "requires": { - "commander": "^2.18.0", - "cspell-lib": "^3.0.4", - "fs-extra": "^7.0.0", - "gensequence": "^2.1.1", - "hunspell-reader": "^2.0.3", - "rxjs": "^6.3.3", + "commander": "^2.20.0", + "cspell-lib": "^3.0.8", + "fs-extra": "^7.0.1", + "gensequence": "^2.1.2", + "hunspell-reader": "^2.1.2", + "js-xxhash": "^1.0.1", + "rxjs": "^6.5.2", "rxjs-stream": "^3.0.1" }, "dependencies": { "commander": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", - "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", + "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", "dev": true } } @@ -4226,9 +4294,9 @@ "dev": true }, "estree-walker": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.5.2.tgz", - "integrity": "sha512-XpCnW/AE10ws/kDAs37cngSkvgIR8aN3G0MS85m7dUpuK2EREo9VJ00uvw6Dg/hXEpfsE1I1TvJOJr+Z+TL+ig==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.0.tgz", + "integrity": "sha512-peq1RfVAVzr3PU/jL31RaOjUKLoZJpObQWJJ+LgfcxDUifyLZ1RjPQZTl0pzj2uJ45b7A7XpyppXvxdEqzo4rw==", "dev": true }, "esutils": { @@ -4369,101 +4437,90 @@ } } }, - "expand-range": { - "version": "1.8.2", - "resolved": "http://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { - "fill-range": "^2.1.0" - }, - "dependencies": { - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "dev": true, - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, "express": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz", - "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.0.tgz", + "integrity": "sha512-1Z7/t3Z5ZnBG252gKUPyItc4xdeaA0X934ca2ewckAsVsw9EG71i++ZHZPYnus8g/s5Bty8IMpSVEuRkmwwPRQ==", "dev": true, "requires": { - "accepts": "~1.3.5", + "accepts": "~1.3.7", "array-flatten": "1.1.1", - "body-parser": "1.18.3", - "content-disposition": "0.5.2", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", "content-type": "~1.0.4", - "cookie": "0.3.1", + "cookie": "0.4.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "~1.1.2", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "1.1.1", + "finalhandler": "~1.1.2", "fresh": "0.5.2", "merge-descriptors": "1.0.1", "methods": "~1.1.2", "on-finished": "~2.3.0", - "parseurl": "~1.3.2", + "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.4", - "qs": "6.5.2", - "range-parser": "~1.2.0", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", "safe-buffer": "5.1.2", - "send": "0.16.2", - "serve-static": "1.13.2", - "setprototypeof": "1.1.0", - "statuses": "~1.4.0", - "type-is": "~1.6.16", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" }, "dependencies": { + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "dev": true, + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, "array-flatten": { "version": "1.1.1", "resolved": "http://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", "dev": true }, + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "dev": true, + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + } + }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true + }, + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", + "dev": true + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -4473,17 +4530,100 @@ "ms": "2.0.0" } }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "mime-db": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==", + "dev": true + }, + "mime-types": { + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", + "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "dev": true, + "requires": { + "mime-db": "1.40.0" + } + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "dev": true + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true + }, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "dev": true, + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", "dev": true + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } } } }, @@ -4669,12 +4809,6 @@ } } }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, "fileset": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz", @@ -4709,17 +4843,17 @@ } }, "finalhandler": { - "version": "1.1.1", - "resolved": "http://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", - "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", "dev": true, "requires": { "debug": "2.6.9", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "on-finished": "~2.3.0", - "parseurl": "~1.3.2", - "statuses": "~1.4.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", "unpipe": "~1.0.0" }, "dependencies": { @@ -4737,6 +4871,18 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true } } }, @@ -4915,9 +5061,9 @@ } }, "fs-minipass": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.5.tgz", - "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.6.tgz", + "integrity": "sha512-crhvyXcMejjv3Z5d2Fa9sf5xLYVCF5O1c71QxbVnbLsmYMBEvDAftewesN/HhY03YRoA7zOMxjNGrF5svGaaeQ==", "dev": true, "requires": { "minipass": "^2.2.1" @@ -4961,7 +5107,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -4982,12 +5129,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": 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" @@ -5002,17 +5151,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -5129,7 +5281,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -5141,6 +5294,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -5155,6 +5309,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -5162,12 +5317,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -5186,6 +5343,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -5266,7 +5424,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -5278,6 +5437,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -5363,7 +5523,8 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -5399,6 +5560,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -5418,6 +5580,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -5461,19 +5624,21 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, "fstream": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", - "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", "dev": true, "requires": { "graceful-fs": "^4.1.2", @@ -5583,42 +5748,6 @@ "path-is-absolute": "^1.0.0" } }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - }, - "dependencies": { - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - } - } - }, "glob-parent": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", @@ -5716,6 +5845,26 @@ "integrity": "sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ==", "dev": true }, + "handlebars": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.2.tgz", + "integrity": "sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw==", + "dev": true, + "requires": { + "neo-async": "^2.6.0", + "optimist": "^0.6.1", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -6000,9 +6149,9 @@ }, "dependencies": { "commander": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", - "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", + "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", "dev": true } } @@ -6434,21 +6583,6 @@ "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", "dev": true }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, "is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", @@ -6578,18 +6712,6 @@ "isobject": "^3.0.1" } }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, "is-promise": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", @@ -6686,55 +6808,76 @@ "dev": true }, "istanbul-api": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-2.1.1.tgz", - "integrity": "sha512-kVmYrehiwyeBAk/wE71tW6emzLiHGjYIiDrc8sfyty4F8M02/lrgXSm+R1kXysmF20zArvmZXjlE/mg24TVPJw==", + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-2.1.7.tgz", + "integrity": "sha512-LYTOa2UrYFyJ/aSczZi/6lBykVMjCCvUmT64gOe+jPZFy4w6FYfPGqFT2IiQ2BxVHHDOvCD7qrIXb0EOh4uGWw==", "dev": true, "requires": { - "async": "^2.6.1", - "compare-versions": "^3.2.1", + "async": "^2.6.2", + "compare-versions": "^3.4.0", "fileset": "^2.0.3", - "istanbul-lib-coverage": "^2.0.3", - "istanbul-lib-hook": "^2.0.3", - "istanbul-lib-instrument": "^3.1.0", - "istanbul-lib-report": "^2.0.4", - "istanbul-lib-source-maps": "^3.0.2", - "istanbul-reports": "^2.1.1", - "js-yaml": "^3.12.0", - "make-dir": "^1.3.0", + "istanbul-lib-coverage": "^2.0.5", + "istanbul-lib-hook": "^2.0.7", + "istanbul-lib-instrument": "^3.3.0", + "istanbul-lib-report": "^2.0.8", + "istanbul-lib-source-maps": "^3.0.6", + "istanbul-reports": "^2.2.5", + "js-yaml": "^3.13.1", + "make-dir": "^2.1.0", "minimatch": "^3.0.4", "once": "^1.4.0" }, "dependencies": { - "async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz", - "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==", - "dev": true, - "requires": { - "lodash": "^4.17.11" - } - }, "istanbul-lib-coverage": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", - "integrity": "sha512-dKWuzRGCs4G+67VfW9pBFFz2Jpi4vSp/k7zBcJ888ofV5Mi1g5CUML5GvMvV6u9Cjybftu+E8Cgp+k0dI1E5lw==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", + "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", "dev": true }, "istanbul-lib-instrument": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.1.0.tgz", - "integrity": "sha512-ooVllVGT38HIk8MxDj/OIHXSYvH+1tq/Vb38s8ixt9GoJadXska4WkGY+0wkmtYCZNYtaARniH/DixUGGLZ0uA==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", + "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", "dev": true, "requires": { - "@babel/generator": "^7.0.0", - "@babel/parser": "^7.0.0", - "@babel/template": "^7.0.0", - "@babel/traverse": "^7.0.0", - "@babel/types": "^7.0.0", - "istanbul-lib-coverage": "^2.0.3", - "semver": "^5.5.0" + "@babel/generator": "^7.4.0", + "@babel/parser": "^7.4.3", + "@babel/template": "^7.4.0", + "@babel/traverse": "^7.4.3", + "@babel/types": "^7.4.0", + "istanbul-lib-coverage": "^2.0.5", + "semver": "^6.0.0" } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "semver": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.0.0.tgz", + "integrity": "sha512-0UewU+9rFapKFnlbirLi3byoOuhrSsli/z/ihNnvM24vgF+8sNBiI1LZPBSH9wJKUwaUbw+s3hToDLCXkrghrQ==", + "dev": true } } }, @@ -6792,9 +6935,9 @@ "dev": true }, "istanbul-lib-hook": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-2.0.3.tgz", - "integrity": "sha512-CLmEqwEhuCYtGcpNVJjLV1DQyVnIqavMLFHV/DP+np/g3qvdxu3gsPqYoJMXm15sN84xOlckFB3VNvRbf5yEgA==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-2.0.7.tgz", + "integrity": "sha512-vrRztU9VRRFDyC+aklfLoeXyNdTfga2EI3udDGn4cZ6fpSXpHLV9X6CHvfoMCPtggg8zvDDmC4b9xfu0z6/llA==", "dev": true, "requires": { "append-transform": "^1.0.0" @@ -6816,34 +6959,50 @@ } }, "istanbul-lib-report": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.4.tgz", - "integrity": "sha512-sOiLZLAWpA0+3b5w5/dq0cjm2rrNdAfHWaGhmn7XEFW6X++IV9Ohn+pnELAl9K3rfpaeBfbmH9JU5sejacdLeA==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", + "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", "dev": true, "requires": { - "istanbul-lib-coverage": "^2.0.3", - "make-dir": "^1.3.0", - "supports-color": "^6.0.0" + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "supports-color": "^6.1.0" }, "dependencies": { "istanbul-lib-coverage": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", - "integrity": "sha512-dKWuzRGCs4G+67VfW9pBFFz2Jpi4vSp/k7zBcJ888ofV5Mi1g5CUML5GvMvV6u9Cjybftu+E8Cgp+k0dI1E5lw==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", + "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", + "dev": true + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true } } }, "istanbul-lib-source-maps": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.2.tgz", - "integrity": "sha512-JX4v0CiKTGp9fZPmoxpu9YEkPbEqCqBbO3403VabKjH+NRXo72HafD5UgnjTEqHL2SAjaZK1XDuDOkn6I5QVfQ==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", + "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", "dev": true, "requires": { "debug": "^4.1.1", - "istanbul-lib-coverage": "^2.0.3", - "make-dir": "^1.3.0", - "rimraf": "^2.6.2", + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "rimraf": "^2.6.3", "source-map": "^0.6.1" }, "dependencies": { @@ -6857,47 +7016,34 @@ } }, "istanbul-lib-coverage": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", - "integrity": "sha512-dKWuzRGCs4G+67VfW9pBFFz2Jpi4vSp/k7zBcJ888ofV5Mi1g5CUML5GvMvV6u9Cjybftu+E8Cgp+k0dI1E5lw==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", + "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", "dev": true }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "istanbul-reports": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.1.1.tgz", - "integrity": "sha512-FzNahnidyEPBCI0HcufJoSEoKykesRlFcSzQqjH9x0+LC8tnnE/p/90PBLu8iZTxr8yYZNyTtiAujUqyN+CIxw==", - "dev": true, - "requires": { - "handlebars": "^4.1.0" - }, - "dependencies": { - "async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz", - "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==", + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", "dev": true, "requires": { - "lodash": "^4.17.11" + "pify": "^4.0.1", + "semver": "^5.6.0" } }, - "handlebars": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.0.tgz", - "integrity": "sha512-l2jRuU1NAWK6AW5qqcTATWQJvNPEwkM7NEKSiv/gqOsoSQbVoWyqVEY5GS+XPQ88zLNmqASRpzfdm8d79hJS+w==", + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", "dev": true, "requires": { - "async": "^2.5.0", - "optimist": "^0.6.1", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4" + "glob": "^7.1.3" } }, "source-map": { @@ -6908,6 +7054,15 @@ } } }, + "istanbul-reports": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.6.tgz", + "integrity": "sha512-SKi4rnMyLBKe0Jy2uUdx28h8oG7ph2PPuQPvIAh31d+Ci+lSiEu4C+h3oBPuJ9+mPKhOyW0M8gY4U5NM1WLeXA==", + "dev": true, + "requires": { + "handlebars": "^4.1.2" + } + }, "jasmine": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-2.8.0.tgz", @@ -6973,10 +7128,16 @@ "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", "dev": true }, + "js-xxhash": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/js-xxhash/-/js-xxhash-1.0.1.tgz", + "integrity": "sha512-ociwKjHkCPjqNMmZtD7uUoL+AVhcSZX3WPmirRwXg+PzKD0v5x9K2yLpvkSglbThvbGN/TVA+3XFjPVolQwDpQ==", + "dev": true + }, "js-yaml": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.1.tgz", - "integrity": "sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA==", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", "dev": true, "requires": { "argparse": "^1.0.7", @@ -7348,14 +7509,14 @@ } }, "lint-staged": { - "version": "8.1.5", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-8.1.5.tgz", - "integrity": "sha512-e5ZavfnSLcBJE1BTzRTqw6ly8OkqVyO3GL2M6teSmTBYQ/2BuueD5GIt2RPsP31u/vjKdexUyDCxSyK75q4BDA==", + "version": "8.1.7", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-8.1.7.tgz", + "integrity": "sha512-egT0goFhIFoOGk6rasPngTFh2qDqxZddM0PwI58oi66RxCDcn5uDwxmiasWIF0qGnchHSYVJ8HPRD5LrFo7TKA==", "dev": true, "requires": { "chalk": "^2.3.1", "commander": "^2.14.1", - "cosmiconfig": "^5.0.2", + "cosmiconfig": "^5.2.0", "debug": "^3.1.0", "dedent": "^0.7.0", "del": "^3.0.0", @@ -7377,19 +7538,18 @@ "staged-git-files": "1.1.2", "string-argv": "^0.0.2", "stringify-object": "^3.2.2", - "yup": "^0.26.10" + "yup": "^0.27.0" }, "dependencies": { "cosmiconfig": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.1.0.tgz", - "integrity": "sha512-kCNPvthka8gvLtzAxQXvWo4FxqRB+ftRZyPZNuab5ngvM9Y7yw7hbEysglptLgpkGX9nAOKTBVkHUAe8xtYR6Q==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", "dev": true, "requires": { "import-fresh": "^2.0.0", "is-directory": "^0.3.1", - "js-yaml": "^3.9.0", - "lodash.get": "^4.4.2", + "js-yaml": "^3.13.1", "parse-json": "^4.0.0" } }, @@ -7406,6 +7566,12 @@ "which": "^1.2.9" } }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, "execa": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", @@ -7430,6 +7596,16 @@ "pump": "^3.0.0" } }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", @@ -7470,9 +7646,9 @@ }, "dependencies": { "p-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.0.0.tgz", - "integrity": "sha512-GO107XdrSUmtHxVoi60qc9tUl/KkNKm+X2CF4P9amalpGxv5YqVPJNfSb0wcA+syCopkZvYYIzW8OVTQW59x/w==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", "dev": true } } @@ -7616,12 +7792,6 @@ "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", "dev": true }, - "lodash.assign": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", - "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=", - "dev": true - }, "lodash.clonedeep": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", @@ -7631,19 +7801,7 @@ "lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", - "dev": true - }, - "lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", - "dev": true - }, - "lodash.mergewith": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz", - "integrity": "sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ==", + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", "dev": true }, "lodash.tail": { @@ -7929,12 +8087,6 @@ "escape-string-regexp": "^1.0.4" } }, - "math-random": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", - "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", - "dev": true - }, "md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", @@ -8282,7 +8434,8 @@ "version": "2.12.1", "resolved": "https://registry.npmjs.org/nan/-/nan-2.12.1.tgz", "integrity": "sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw==", - "dev": true + "dev": true, + "optional": true }, "nanomatch": { "version": "1.2.13", @@ -8310,9 +8463,9 @@ "dev": true }, "neo-async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.0.tgz", - "integrity": "sha512-MFh0d/Wa7vkKO3Y3LlacqAEeHK0mckVqzDieUKTT+KGxi+zIpeVsFxymkIiRpbpDziHc290Xr9A1O4Om7otoRA==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", + "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", "dev": true }, "next-tick": { @@ -8321,9 +8474,9 @@ "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" }, "ng-packagr": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/ng-packagr/-/ng-packagr-4.7.0.tgz", - "integrity": "sha512-FNCe4WpHwBk107pCX0KOnsv+cUaM2bCGAD/oYUl0FIwQXkI+iYjDik9KlqJ/bWDUsiCUxiAH2v5AsTaEF7G4bw==", + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/ng-packagr/-/ng-packagr-4.7.1.tgz", + "integrity": "sha512-MIPKxyrnV22fS3wSfst2XjwWOonFKujVVEnIehYJhiu8GOg37bCdbbr9plsE1jRDmDAUz6M1MvdKibUrJyRp6Q==", "dev": true, "requires": { "@ngtools/json-schema": "^1.1.0", @@ -8340,7 +8493,7 @@ "less-plugin-npm-import": "^2.1.0", "node-sass": "^4.9.3", "node-sass-tilde-importer": "^1.0.0", - "opencollective": "^1.0.3", + "opencollective-postinstall": "^2.0.1", "postcss": "^7.0.0", "postcss-url": "^8.0.0", "read-pkg-up": "^4.0.0", @@ -8388,9 +8541,9 @@ } }, "p-limit": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz", - "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", + "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", "dev": true, "requires": { "p-try": "^2.0.0" @@ -8406,9 +8559,9 @@ } }, "p-try": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", - "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, "parse-json": { @@ -8461,16 +8614,6 @@ "resolved": "https://registry.npmjs.org/node-ensure/-/node-ensure-0.0.0.tgz", "integrity": "sha1-7K52QVDemYYexcgQ/V0Jaxg5Mqc=" }, - "node-fetch": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.6.3.tgz", - "integrity": "sha1-3CNO3WSJmC1Y6PDbT2lQKavNjAQ=", - "dev": true, - "requires": { - "encoding": "^0.1.11", - "is-stream": "^1.0.1" - } - }, "node-fetch-npm": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/node-fetch-npm/-/node-fetch-npm-2.0.2.tgz", @@ -8565,9 +8708,9 @@ } }, "node-sass": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.11.0.tgz", - "integrity": "sha512-bHUdHTphgQJZaF1LASx0kAviPH7sGlcyNhWade4eVIpFp6tsn7SV8xNMTbsQFpEV9VXpnwTTnNYlfsZXgGgmkA==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.12.0.tgz", + "integrity": "sha512-A1Iv4oN+Iel6EPv77/HddXErL2a+gZ4uBeZUy+a8O35CFYTXhgA8MgLCWBtwpGZdCvTvQ9d+bQxX/QC36GDPpQ==", "dev": true, "requires": { "async-foreach": "^0.1.3", @@ -8577,12 +8720,10 @@ "get-stdin": "^4.0.1", "glob": "^7.0.3", "in-publish": "^2.0.0", - "lodash.assign": "^4.2.0", - "lodash.clonedeep": "^4.3.2", - "lodash.mergewith": "^4.6.0", + "lodash": "^4.17.11", "meow": "^3.7.0", "mkdirp": "^0.5.1", - "nan": "^2.10.0", + "nan": "^2.13.2", "node-gyp": "^3.8.0", "npmlog": "^4.0.0", "request": "^2.88.0", @@ -8610,6 +8751,12 @@ "supports-color": "^2.0.0" } }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", + "dev": true + }, "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", @@ -8839,27 +8986,6 @@ "isobject": "^3.0.0" } }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - }, - "dependencies": { - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - } - } - }, "object.pick": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", @@ -8917,133 +9043,11 @@ "is-wsl": "^1.1.0" } }, - "opencollective": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/opencollective/-/opencollective-1.0.3.tgz", - "integrity": "sha1-ruY3K8KBRFg2kMPKja7PwSDdDvE=", - "dev": true, - "requires": { - "babel-polyfill": "6.23.0", - "chalk": "1.1.3", - "inquirer": "3.0.6", - "minimist": "1.2.0", - "node-fetch": "1.6.3", - "opn": "4.0.2" - }, - "dependencies": { - "ansi-escapes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", - "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", - "dev": true - }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "chardet": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", - "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", - "dev": true - }, - "external-editor": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", - "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", - "dev": true, - "requires": { - "chardet": "^0.4.0", - "iconv-lite": "^0.4.17", - "tmp": "^0.0.33" - } - }, - "inquirer": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.0.6.tgz", - "integrity": "sha1-4EqqnQW3o8ubD0B9BDdfBEcZA0c=", - "dev": true, - "requires": { - "ansi-escapes": "^1.1.0", - "chalk": "^1.0.0", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^2.0.1", - "figures": "^2.0.0", - "lodash": "^4.3.0", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rx": "^4.1.0", - "string-width": "^2.0.0", - "strip-ansi": "^3.0.0", - "through": "^2.3.6" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "opn": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/opn/-/opn-4.0.2.tgz", - "integrity": "sha1-erwi5kTf9jsKltWrfyeQwPAavJU=", - "dev": true, - "requires": { - "object-assign": "^4.0.1", - "pinkie-promise": "^2.0.0" - } - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } + "opencollective-postinstall": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz", + "integrity": "sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw==", + "dev": true }, "opn": { "version": "5.5.0", @@ -9356,35 +9360,6 @@ "safe-buffer": "^5.1.1" } }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - }, - "dependencies": { - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - } - } - }, "parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", @@ -9674,9 +9649,9 @@ }, "dependencies": { "mime": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.0.tgz", - "integrity": "sha512-ikBcWwyqXQSHKtciCcctu9YfPbFYZ4+gbHEmE0Q8jzcTYQg5dHCr3g2wwAZjPoJfQVXZq6KXAjpXOTf5/cjT7w==", + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.3.tgz", + "integrity": "sha512-QgrPRJfE+riq5TPZMcHZOtm8c6K/yYrMbKIoRfapfiGLxS8OTeIfRhUGW5LU7MlRa52KOAGCfUNruqLrIBvWZw==", "dev": true } } @@ -9726,16 +9701,10 @@ "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", "dev": true }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, "prettier": { - "version": "1.16.4", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.16.4.tgz", - "integrity": "sha512-ZzWuos7TI5CKUeQAtFd6Zhm2s6EpAD/ZLApIhsF9pRvRtM1RFo61dM/4MSRUA0SuLugA/zgrZD8m0BaY46Og7g==", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.17.1.tgz", + "integrity": "sha512-TzGRNvuUSmPgwivDqkZ9tM/qTGW9hqDKWOE9YHiyQdixlKbv7kvEqsmDPrcHJTKwthU774TQwZXVtaQ/mMsvjg==", "dev": true }, "process": { @@ -10058,25 +10027,6 @@ "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", "dev": true }, - "randomatic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", - "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", - "dev": true, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - } - } - }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -10289,15 +10239,6 @@ "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", "dev": true }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, "regex-not": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", @@ -10320,9 +10261,9 @@ } }, "registry-auth-token": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz", - "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz", + "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==", "dev": true, "requires": { "rc": "^1.1.6", @@ -10533,21 +10474,21 @@ } }, "rollup-plugin-commonjs": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-commonjs/-/rollup-plugin-commonjs-9.2.0.tgz", - "integrity": "sha512-0RM5U4Vd6iHjL6rLvr3lKBwnPsaVml+qxOGaaNUWN1lSq6S33KhITOfHmvxV3z2vy9Mk4t0g4rNlVaJJsNQPWA==", + "version": "9.3.4", + "resolved": "https://registry.npmjs.org/rollup-plugin-commonjs/-/rollup-plugin-commonjs-9.3.4.tgz", + "integrity": "sha512-DTZOvRoiVIHHLFBCL4pFxOaJt8pagxsVldEXBOn6wl3/V21wVaj17HFfyzTsQUuou3sZL3lEJZVWKPFblJfI6w==", "dev": true, "requires": { - "estree-walker": "^0.5.2", - "magic-string": "^0.25.1", - "resolve": "^1.8.1", - "rollup-pluginutils": "^2.3.3" + "estree-walker": "^0.6.0", + "magic-string": "^0.25.2", + "resolve": "^1.10.0", + "rollup-pluginutils": "^2.6.0" }, "dependencies": { "resolve": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", - "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.0.tgz", + "integrity": "sha512-WL2pBDjqT6pGUNSUzMw00o4T7If+z4H2x3Gz893WoUQ5KW8Vr9txp00ykiP16VBaZF5+j/OcXJHZ9+PCvdiDKw==", "dev": true, "requires": { "path-parse": "^1.0.6" @@ -10565,26 +10506,27 @@ } }, "rollup-plugin-node-resolve": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-4.0.0.tgz", - "integrity": "sha512-7Ni+/M5RPSUBfUaP9alwYQiIKnKeXCOHiqBpKUl9kwp3jX5ZJtgXAait1cne6pGEVUUztPD6skIKH9Kq9sNtfw==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-4.2.4.tgz", + "integrity": "sha512-t/64I6l7fZ9BxqD3XlX4ZeO6+5RLKyfpwE2CiPNUKa+GocPlQhf/C208ou8y3AwtNsc6bjSk/8/6y/YAyxCIvw==", "dev": true, "requires": { - "builtin-modules": "^3.0.0", + "@types/resolve": "0.0.8", + "builtin-modules": "^3.1.0", "is-module": "^1.0.0", - "resolve": "^1.8.1" + "resolve": "^1.10.0" }, "dependencies": { "builtin-modules": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.0.0.tgz", - "integrity": "sha512-hMIeU4K2ilbXV6Uv93ZZ0Avg/M91RaKXucQ+4me2Do1txxBDyDZWCBa5bJSLqoNTRpXTLwEzIk1KmloenDDjhg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.1.0.tgz", + "integrity": "sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw==", "dev": true }, "resolve": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", - "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.0.tgz", + "integrity": "sha512-WL2pBDjqT6pGUNSUzMw00o4T7If+z4H2x3Gz893WoUQ5KW8Vr9txp00ykiP16VBaZF5+j/OcXJHZ9+PCvdiDKw==", "dev": true, "requires": { "path-parse": "^1.0.6" @@ -10603,104 +10545,13 @@ } }, "rollup-pluginutils": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.3.3.tgz", - "integrity": "sha512-2XZwja7b6P5q4RZ5FhyX1+f46xi1Z3qBKigLRZ6VTZjwbN0K1IFGMlwm06Uu0Emcre2Z63l77nq/pzn+KxIEoA==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.7.0.tgz", + "integrity": "sha512-FoP6L1YnMYTAR06Dpq5LE3jJtMwPE6H4VEOqFU23yoziZnqNRSiWcVy6YgEY5PdQB4G7278+8c4TvB0JKS1csA==", "dev": true, "requires": { - "estree-walker": "^0.5.2", - "micromatch": "^2.3.11" - }, - "dependencies": { - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - } - } + "estree-walker": "^0.6.0", + "micromatch": "^3.1.10" } }, "run-async": { @@ -10728,17 +10579,17 @@ "dev": true }, "rxjs": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.1.tgz", - "integrity": "sha512-y0j31WJc83wPu31vS1VlAFW5JGrnGC+j+TtGAa1fRQphy48+fDYiDmX8tjGloToEsMkxnouOg/1IzXGKkJnZMg==", + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz", + "integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==", "requires": { "tslib": "^1.9.0" } }, "rxjs-stream": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/rxjs-stream/-/rxjs-stream-3.0.1.tgz", - "integrity": "sha512-KZ+B7MWw2mygAsLJJ+mjYkCXHtSeYRXWhUVQBQRX4NgBmEiAEGAmVz7epY+8Gj0REL22W0T8ZbysFbzI/76ikA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rxjs-stream/-/rxjs-stream-3.0.2.tgz", + "integrity": "sha512-DASSTemCVcghTvUGKd6g2QYQ1Y/tCKwxZ2Xj41+PH0GHRLQLknwLIIHtPfbK1Cb7aorf0jZXAe123oSMHXLn7Q==", "dev": true }, "rxjs-tslint-rules": { @@ -10959,9 +10810,9 @@ } }, "send": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", - "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", "dev": true, "requires": { "debug": "2.6.9", @@ -10971,12 +10822,12 @@ "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "~1.6.2", - "mime": "1.4.1", - "ms": "2.0.0", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", "on-finished": "~2.3.0", - "range-parser": "~1.2.0", - "statuses": "~1.4.0" + "range-parser": "~1.2.1", + "statuses": "~1.5.0" }, "dependencies": { "debug": { @@ -10986,18 +10837,45 @@ "dev": true, "requires": { "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } } }, - "mime": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", - "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "dev": true }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "dev": true + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", "dev": true } } @@ -11041,15 +10919,23 @@ } }, "serve-static": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", - "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", "dev": true, "requires": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", - "parseurl": "~1.3.2", - "send": "0.16.2" + "parseurl": "~1.3.3", + "send": "0.17.1" + }, + "dependencies": { + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true + } } }, "set-blocking": { @@ -11155,9 +11041,9 @@ "dev": true }, "simple-git": { - "version": "1.110.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-1.110.0.tgz", - "integrity": "sha512-UYY0rQkknk0P5eb+KW+03F4TevZ9ou0H+LoGaj7iiVgpnZH4wdj/HTViy/1tNNkmIPcmtxuBqXWiYt2YwlRKOQ==", + "version": "1.113.0", + "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-1.113.0.tgz", + "integrity": "sha512-i9WVsrK2u0G/cASI9nh7voxOk9mhanWY9eGtWBDSYql6m49Yk5/Fan6uZsDr/xmzv8n+eQ8ahKCoEr8cvU3h+g==", "dev": true, "requires": { "debug": "^4.0.1" @@ -11986,9 +11872,9 @@ "dev": true }, "synchronous-promise": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/synchronous-promise/-/synchronous-promise-2.0.6.tgz", - "integrity": "sha512-TyOuWLwkmtPL49LHCX1caIwHjRzcVd62+GF6h8W/jHOeZUFHpnd2XJDVuUlaTaLPH1nuu2M69mfHr5XbQJnf/g==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/synchronous-promise/-/synchronous-promise-2.0.7.tgz", + "integrity": "sha512-16GbgwTmFMYFyQMLvtQjvNWh30dsFe1cAW5Fg1wm5+dg84L9Pe36mftsIRU95/W2YsISxsz/xq4VB23sqpgb/A==", "dev": true }, "tapable": { @@ -11998,13 +11884,13 @@ "dev": true }, "tar": { - "version": "2.2.1", - "resolved": "http://registry.npmjs.org/tar/-/tar-2.2.1.tgz", - "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", + "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", "dev": true, "requires": { "block-stream": "*", - "fstream": "^1.0.2", + "fstream": "^1.0.12", "inherits": "2" } }, @@ -12364,6 +12250,12 @@ "repeat-string": "^1.6.1" } }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "dev": true + }, "topo": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/topo/-/topo-3.0.3.tgz", @@ -13031,9 +12923,9 @@ }, "dependencies": { "mime": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.2.tgz", - "integrity": "sha512-zJBfZDkwRu+j3Pdd2aHsR5GfH2jIWhmL1ZzBoc+X+3JEti2hbArWcyJ+1laC1D2/U/W1a/+Cegj0/OnEU2ybjg==", + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.3.tgz", + "integrity": "sha512-QgrPRJfE+riq5TPZMcHZOtm8c6K/yYrMbKIoRfapfiGLxS8OTeIfRhUGW5LU7MlRa52KOAGCfUNruqLrIBvWZw==", "dev": true } } @@ -13197,9 +13089,9 @@ } }, "mime": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.2.tgz", - "integrity": "sha512-zJBfZDkwRu+j3Pdd2aHsR5GfH2jIWhmL1ZzBoc+X+3JEti2hbArWcyJ+1laC1D2/U/W1a/+Cegj0/OnEU2ybjg==", + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.3.tgz", + "integrity": "sha512-QgrPRJfE+riq5TPZMcHZOtm8c6K/yYrMbKIoRfapfiGLxS8OTeIfRhUGW5LU7MlRa52KOAGCfUNruqLrIBvWZw==", "dev": true }, "os-locale": { @@ -13472,9 +13364,9 @@ } }, "worker-farm": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.6.0.tgz", - "integrity": "sha512-6w+3tHbM87WnSWnENBUvA2pxJPLhQUg5LKwUQHq3r+XPhIM+Gh2R5ycbwPCyuGbNg+lPgdcnQUhuC02kJCvffQ==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", + "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", "dev": true, "requires": { "errno": "~0.1.7" @@ -13667,16 +13559,16 @@ "dev": true }, "yup": { - "version": "0.26.10", - "resolved": "https://registry.npmjs.org/yup/-/yup-0.26.10.tgz", - "integrity": "sha512-keuNEbNSnsOTOuGCt3UJW69jDE3O4P+UHAakO7vSeFMnjaitcmlbij/a3oNb9g1Y1KvSKH/7O1R2PQ4m4TRylw==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/yup/-/yup-0.27.0.tgz", + "integrity": "sha512-v1yFnE4+u9za42gG/b/081E7uNW9mUj3qtkmelLbW5YPROZzSH/KUUyJu9Wt8vxFJcT9otL/eZopS0YK1L5yPQ==", "dev": true, "requires": { - "@babel/runtime": "7.0.0", + "@babel/runtime": "^7.0.0", "fn-name": "~2.0.1", - "lodash": "^4.17.10", + "lodash": "^4.17.11", "property-expr": "^1.5.0", - "synchronous-promise": "^2.0.5", + "synchronous-promise": "^2.0.6", "toposort": "^2.0.2" } }, diff --git a/package.json b/package.json index 1c29c2dba4..e3827bcbff 100644 --- a/package.json +++ b/package.json @@ -41,19 +41,19 @@ "@alfresco/adf-core": "3.3.0-4a363c731be09d8213e25cd149bee302ebcbeb82", "@alfresco/adf-extensions": "3.3.0-4a363c731be09d8213e25cd149bee302ebcbeb82", "@alfresco/js-api": "3.2.1", - "@angular/animations": "7.2.14", + "@angular/animations": "7.2.15", "@angular/cdk": "^7.3.7", - "@angular/common": "7.2.14", - "@angular/compiler": "7.2.14", - "@angular/core": "7.2.14", + "@angular/common": "7.2.15", + "@angular/compiler": "7.2.15", + "@angular/core": "7.2.15", "@angular/flex-layout": "^7.0.0-beta.24", - "@angular/forms": "7.2.14", - "@angular/http": "7.2.14", + "@angular/forms": "7.2.15", + "@angular/http": "7.2.15", "@angular/material": "^7.3.7", "@angular/material-moment-adapter": "^7.3.7", - "@angular/platform-browser": "7.2.14", - "@angular/platform-browser-dynamic": "7.2.14", - "@angular/router": "7.2.14", + "@angular/platform-browser": "7.2.15", + "@angular/platform-browser-dynamic": "7.2.15", + "@angular/router": "7.2.15", "@mat-datetimepicker/core": "^3.0.0-beta.0", "@mat-datetimepicker/moment": "^3.0.0-beta.0", "@ngrx/effects": "^7.4.0", @@ -67,15 +67,15 @@ "moment": "^2.24.0", "moment-es6": "1.0.0", "pdfjs-dist": "^2.0.489", - "rxjs": "^6.5.1", + "rxjs": "^6.5.2", "zone.js": "0.8.29" }, "devDependencies": { - "@angular-devkit/build-angular": "~0.13.8", + "@angular-devkit/build-angular": "~0.13.9", "@angular-devkit/build-ng-packagr": "~0.13.0", - "@angular/cli": "^7.3.8", - "@angular/compiler-cli": "7.2.14", - "@angular/language-service": "7.2.14", + "@angular/cli": "^7.3.9", + "@angular/compiler-cli": "7.2.15", + "@angular/language-service": "7.2.15", "@types/jasmine": "^2.5.53", "@types/jasminewd2": "^2.0.2", "@types/node": "9.3.0", @@ -83,7 +83,7 @@ "chrome-remote-interface": "^0.26.1", "codelyzer": "^4.5.0", "cpr": "^3.0.1", - "cspell": "^3.1.3", + "cspell": "^3.2.17", "jasmine-core": "~2.8.0", "jasmine-reporters": "^2.2.1", "jasmine-spec-reporter": "~4.2.1", @@ -94,14 +94,13 @@ "karma-coverage-istanbul-reporter": "^2.0.4", "karma-jasmine": "~1.1.0", "karma-jasmine-html-reporter": "^0.2.2", - "lint-staged": "^8.1.5", - "ng-packagr": "^4.7.0", + "lint-staged": "^8.1.7", + "ng-packagr": "^4.7.1", "node-stream-zip": "1.8.0", "pre-commit": "^1.2.2", - "prettier": "^1.16.0", + "prettier": "^1.17.1", "protractor": "^5.4.0", "protractor-screenshoter-plugin": "0.10.3", - "rimraf": "2.6.2", "rxjs-tslint-rules": "^4.19.0", "selenium-webdriver": "4.0.0-alpha.1", "ts-node": "^8.0.3", diff --git a/src/app.config.json b/src/app.config.json index f78b110a2a..07cbb0062d 100644 --- a/src/app.config.json +++ b/src/app.config.json @@ -21,7 +21,7 @@ "copyright": "APP.COPYRIGHT" }, "headerColor": "#2196F3", - "languagePicker": false, + "languagePicker": true, "pagination": { "size": 25, "supportedPageSizes": [25, 50, 100] diff --git a/src/app/components/about/about.component.html b/src/app/components/about/about.component.html index 643e33c9c3..01d1961248 100644 --- a/src/app/components/about/about.component.html +++ b/src/app/components/about/about.component.html @@ -6,7 +6,7 @@

{{ 'APP.ABOUT.VERSION' | translate }} {{ releaseVersion }}

- +
{{ 'APP.ABOUT.PLUGINS.TITLE' | translate }}
diff --git a/src/app/components/current-user/current-user.component.html b/src/app/components/current-user/current-user.component.html index 8a32ab9b5f..9623b3e9e3 100644 --- a/src/app/components/current-user/current-user.component.html +++ b/src/app/components/current-user/current-user.component.html @@ -7,7 +7,7 @@
- - - - - - - - - + . */ -import { Component, Input, ViewEncapsulation } from '@angular/core'; +import { + Component, + Input, + ViewEncapsulation, + OnInit, + OnDestroy +} from '@angular/core'; import { MinimalNodeEntryEntity } from '@alfresco/js-api'; import { NodePermissionService } from '@alfresco/aca-shared'; import { AppStore, infoDrawerMetadataAspect } from '@alfresco/aca-shared/store'; import { AppExtensionService } from '../../../extensions/extension.service'; -import { AppConfigService } from '@alfresco/adf-core'; +import { AppConfigService, NotificationService } from '@alfresco/adf-core'; import { isLocked } from '../../../utils/node.utils'; -import { Observable } from 'rxjs'; +import { Observable, Subject } from 'rxjs'; import { Store } from '@ngrx/store'; +import { ContentMetadataService } from '@alfresco/adf-content-services'; +import { takeUntil } from 'rxjs/operators'; @Component({ selector: 'app-metadata-tab', @@ -47,7 +55,9 @@ import { Store } from '@ngrx/store'; encapsulation: ViewEncapsulation.None, host: { class: 'app-metadata-tab' } }) -export class MetadataTabComponent { +export class MetadataTabComponent implements OnInit, OnDestroy { + protected onDestroy$ = new Subject(); + @Input() node: MinimalNodeEntryEntity; @@ -57,7 +67,9 @@ export class MetadataTabComponent { private permission: NodePermissionService, protected extensions: AppExtensionService, private appConfig: AppConfigService, - private store: Store + private store: Store, + private notificationService: NotificationService, + private contentMetadataService: ContentMetadataService ) { if (this.extensions.contentMetadata) { this.appConfig.config[ @@ -74,4 +86,17 @@ export class MetadataTabComponent { return false; } + + ngOnInit() { + this.contentMetadataService.error + .pipe(takeUntil(this.onDestroy$)) + .subscribe((err: { message: string }) => { + this.notificationService.showError(err.message); + }); + } + + ngOnDestroy() { + this.onDestroy$.next(true); + this.onDestroy$.complete(); + } } From d28114f2eee0ca3e948688e4e8770f273bb95b9a Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Fri, 24 May 2019 18:12:54 +0300 Subject: [PATCH 211/259] [ACA-2390] Evaluators - user is admin (#1116) * user isAdmin rule * register rule * test * update docs * remove fdescribe --- docs/extending/rules.md | 1 + projects/aca-shared/rules/src/public_api.ts | 1 + .../aca-shared/rules/src/user.rules.spec.ts | 50 +++++++++++++++++++ projects/aca-shared/rules/src/user.rules.ts | 34 +++++++++++++ src/app/extensions/core.extensions.module.ts | 3 +- 5 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 projects/aca-shared/rules/src/user.rules.spec.ts create mode 100644 projects/aca-shared/rules/src/user.rules.ts diff --git a/docs/extending/rules.md b/docs/extending/rules.md index 2cbf2f3506..7096c6c3d2 100644 --- a/docs/extending/rules.md +++ b/docs/extending/rules.md @@ -165,6 +165,7 @@ The button will be visible only when the linked rule evaluates to `true`. | 1.8.0 | canManageFileVersions | Checks if user can manage file versions for the selected node. | | 1.8.0 | canManagePermissions | Checks if user can manage permissions for the selected node. | | 1.8.0 | canToggleEditOffline | Checks if user can toggle **Edit Offline** mode for selected node. | +| 1.8.0 | user.isAdmin | Checks if user is admin. | ## Navigation Evaluators diff --git a/projects/aca-shared/rules/src/public_api.ts b/projects/aca-shared/rules/src/public_api.ts index 542beb99a7..b83e404759 100644 --- a/projects/aca-shared/rules/src/public_api.ts +++ b/projects/aca-shared/rules/src/public_api.ts @@ -26,3 +26,4 @@ export * from './app.rules'; export * from './navigation.rules'; export * from './repository.rules'; +export * from './user.rules'; diff --git a/projects/aca-shared/rules/src/user.rules.spec.ts b/projects/aca-shared/rules/src/user.rules.spec.ts new file mode 100644 index 0000000000..47c91d2f29 --- /dev/null +++ b/projects/aca-shared/rules/src/user.rules.spec.ts @@ -0,0 +1,50 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2019 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import * as user from './user.rules'; + +describe('evaluators', () => { + describe('isAdmin', () => { + it('should return [true] if user is admin', () => { + const context: any = { + profile: { + isAdmin: true + } + }; + + expect(user.isAdmin(context)).toBe(true); + }); + + it('should return [false] if user is not an admin', () => { + const context: any = { + profile: { + isAdmin: false + } + }; + + expect(user.isAdmin(context)).toBe(false); + }); + }); +}); diff --git a/projects/aca-shared/rules/src/user.rules.ts b/projects/aca-shared/rules/src/user.rules.ts new file mode 100644 index 0000000000..62cb67c77b --- /dev/null +++ b/projects/aca-shared/rules/src/user.rules.ts @@ -0,0 +1,34 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2019 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { RuleContext } from '@alfresco/adf-extensions'; + +/** + * Checks if user is admin. + * JSON ref: `user.isAdmin` + */ +export function isAdmin(context: RuleContext): boolean { + return context.profile.isAdmin; +} diff --git a/src/app/extensions/core.extensions.module.ts b/src/app/extensions/core.extensions.module.ts index f7332d8ec8..7bd1006410 100644 --- a/src/app/extensions/core.extensions.module.ts +++ b/src/app/extensions/core.extensions.module.ts @@ -163,7 +163,8 @@ export class CoreExtensionsModule { 'app.navigation.isFavoritesPreview': rules.isFavoritesPreview, 'app.navigation.isSharedFileViewer': rules.isSharedFileViewer, - 'repository.isQuickShareEnabled': rules.hasQuickShareEnabled + 'repository.isQuickShareEnabled': rules.hasQuickShareEnabled, + 'user.isAdmin': rules.isAdmin }); } } From 14adbad1a955c4ac389bf7323e03d056c2d43546 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Tue, 28 May 2019 12:06:30 +0100 Subject: [PATCH 212/259] bump aca-shared version --- projects/aca-shared/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/aca-shared/package.json b/projects/aca-shared/package.json index ce18997cee..5735ef082b 100644 --- a/projects/aca-shared/package.json +++ b/projects/aca-shared/package.json @@ -1,6 +1,6 @@ { "name": "@alfresco/aca-shared", - "version": "1.8.1", + "version": "1.8.2", "peerDependencies": { "@angular/common": "^7.2.0", "@angular/core": "^7.2.0", From 9fef05b69f9a502a46463be3c3bbae5865512326 Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Fri, 31 May 2019 13:30:11 +0300 Subject: [PATCH 213/259] 3.3.0 alpha update (#1118) * alpha * locale --- package-lock.json | 59 +++++++------------ package.json | 6 +- src/app.config.json | 1 + .../app-layout/app-layout.component.html | 1 - .../app-layout/app-layout.component.spec.ts | 39 ------------ .../layout/app-layout/app-layout.component.ts | 24 +------- 6 files changed, 25 insertions(+), 105 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8ac16f9ed0..ad1b180cb8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,25 +5,25 @@ "requires": true, "dependencies": { "@alfresco/adf-content-services": { - "version": "3.3.0-4a363c731be09d8213e25cd149bee302ebcbeb82", - "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-3.3.0-4a363c731be09d8213e25cd149bee302ebcbeb82.tgz", - "integrity": "sha512-G4zvUwzVDm5YAK4/eo/U8tMA7osIU5axBhc1JGxRyWR3jcd1E6tVeHDQP+i4X9cQWdYF6fvSOYNS4qqapk8JAg==", + "version": "3.3.0-9aafb804830cba52f2a92e0a14549f6b41fcaa92", + "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-3.3.0-9aafb804830cba52f2a92e0a14549f6b41fcaa92.tgz", + "integrity": "sha512-tc7uNSbzWimRqRb6dbUMZ+tIWsD4yRs/FHNYUzR5JBs+PNX6zcLytl3cj68C4qbo95hAb1svYJt8vJ1h1Tv8IA==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/adf-core": { - "version": "3.3.0-4a363c731be09d8213e25cd149bee302ebcbeb82", - "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-3.3.0-4a363c731be09d8213e25cd149bee302ebcbeb82.tgz", - "integrity": "sha512-7SEJLDr23/JgZDZaw4aD6FDgvnOIfQ5SIh/qJUdhxyD1eC852qpm/OlNRg4zqJ+6so8pvvOqEEqrDgFJvr1OWg==", + "version": "3.3.0-9aafb804830cba52f2a92e0a14549f6b41fcaa92", + "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-3.3.0-9aafb804830cba52f2a92e0a14549f6b41fcaa92.tgz", + "integrity": "sha512-uVCzyoRwX0Oha8qifVpjxExNuY1mBEAkgpgDh/rRZshtsJQ3r2iSkx6o9JV9ZACRP1i5ct0KHJkcOxB0o+f36A==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/adf-extensions": { - "version": "3.3.0-4a363c731be09d8213e25cd149bee302ebcbeb82", - "resolved": "https://registry.npmjs.org/@alfresco/adf-extensions/-/adf-extensions-3.3.0-4a363c731be09d8213e25cd149bee302ebcbeb82.tgz", - "integrity": "sha512-l8VIc3Zg0Nr1mJUGbeC+9oPUdBAtqg5f4NUNedb8vSMumYAyK/p8DvZdEERHPXxRCfrxxGuYvDwxu1IlcZkCZg==", + "version": "3.3.0-9aafb804830cba52f2a92e0a14549f6b41fcaa92", + "resolved": "https://registry.npmjs.org/@alfresco/adf-extensions/-/adf-extensions-3.3.0-9aafb804830cba52f2a92e0a14549f6b41fcaa92.tgz", + "integrity": "sha512-8dAUsEfENFQsDRlFveuvw6XsfxTCX8aYPlvE1Mo24HjFvc6wRU98+m1hso4aJWZo194W4otjtj7IEvRWnTovwA==", "requires": { "tslib": "^1.9.0" } @@ -5107,8 +5107,7 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "aproba": { "version": "1.2.0", @@ -5129,14 +5128,12 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -5151,20 +5148,17 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -5281,8 +5275,7 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -5294,7 +5287,6 @@ "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -5309,7 +5301,6 @@ "version": "3.0.4", "bundled": true, "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -5317,14 +5308,12 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -5343,7 +5332,6 @@ "version": "0.5.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -5424,8 +5412,7 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -5437,7 +5424,6 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -5523,8 +5509,7 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "safer-buffer": { "version": "2.1.2", @@ -5560,7 +5545,6 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -5580,7 +5564,6 @@ "version": "3.0.1", "bundled": true, "dev": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -5624,14 +5607,12 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true } } }, diff --git a/package.json b/package.json index e3827bcbff..acb9225cfb 100644 --- a/package.json +++ b/package.json @@ -37,9 +37,9 @@ }, "private": true, "dependencies": { - "@alfresco/adf-content-services": "3.3.0-4a363c731be09d8213e25cd149bee302ebcbeb82", - "@alfresco/adf-core": "3.3.0-4a363c731be09d8213e25cd149bee302ebcbeb82", - "@alfresco/adf-extensions": "3.3.0-4a363c731be09d8213e25cd149bee302ebcbeb82", + "@alfresco/adf-content-services": "3.3.0-9aafb804830cba52f2a92e0a14549f6b41fcaa92", + "@alfresco/adf-core": "3.3.0-9aafb804830cba52f2a92e0a14549f6b41fcaa92", + "@alfresco/adf-extensions": "3.3.0-9aafb804830cba52f2a92e0a14549f6b41fcaa92", "@alfresco/js-api": "3.2.1", "@angular/animations": "7.2.15", "@angular/cdk": "^7.3.7", diff --git a/src/app.config.json b/src/app.config.json index 59c704c40b..b83f7b721d 100644 --- a/src/app.config.json +++ b/src/app.config.json @@ -15,6 +15,7 @@ "redirectUri": "/", "redirectUriLogout": "/logout" }, + "locale": "en", "application": { "name": "Alfresco Content Application", "logo": "assets/images/alfresco-logo-flower.svg", diff --git a/src/app/components/layout/app-layout/app-layout.component.html b/src/app/components/layout/app-layout/app-layout.component.html index 953955e942..b114dc453a 100644 --- a/src/app/components/layout/app-layout/app-layout.component.html +++ b/src/app/components/layout/app-layout/app-layout.component.html @@ -7,7 +7,6 @@ [hideSidenav]="hideSidenav" [expandedSidenav]="expandedSidenav" (expanded)="onExpanded($event)" - [direction]="direction" > diff --git a/src/app/components/layout/app-layout/app-layout.component.spec.ts b/src/app/components/layout/app-layout/app-layout.component.spec.ts index d4bb05759b..95398bf0a6 100644 --- a/src/app/components/layout/app-layout/app-layout.component.spec.ts +++ b/src/app/components/layout/app-layout/app-layout.component.spec.ts @@ -195,43 +195,4 @@ describe('AppLayoutComponent', () => { expect(component.layout.container.toggleMenu).toHaveBeenCalled(); }); - - it('should set direction `ltr` if no direction declared', () => { - appConfig.config.languages = [ - { - key: 'en' - } - ]; - - spyOn(userPreference, 'get').and.callFake(key => { - if (key === 'locale') { - return 'en'; - } - }); - - const spy = spyOn(userPreference, 'set'); - fixture.detectChanges(); - - expect(spy.calls.mostRecent().args).toEqual(['textOrientation', 'ltr']); - }); - - it('should set direction `rtl` based on locale language direction', () => { - appConfig.config.languages = [ - { - key: 'en', - direction: 'rtl' - } - ]; - - spyOn(userPreference, 'get').and.callFake(key => { - if (key === 'locale') { - return 'en'; - } - }); - - const spy = spyOn(userPreference, 'set'); - fixture.detectChanges(); - - expect(spy.calls.mostRecent().args).toEqual(['textOrientation', 'rtl']); - }); }); diff --git a/src/app/components/layout/app-layout/app-layout.component.ts b/src/app/components/layout/app-layout/app-layout.component.ts index 7e1127a423..103defa4a4 100644 --- a/src/app/components/layout/app-layout/app-layout.component.ts +++ b/src/app/components/layout/app-layout/app-layout.component.ts @@ -26,9 +26,7 @@ import { AppConfigService, SidenavLayoutComponent, - UserPreferencesService, - LanguageItem, - AppConfigValues + UserPreferencesService } from '@alfresco/adf-core'; import { Component, @@ -151,18 +149,6 @@ export class AppLayoutComponent implements OnInit, OnDestroy { takeUntil(this.onDestroy$) ) .subscribe(() => this.store.dispatch(new SetSelectedNodesAction([]))); - - this.userPreferenceService - .select('textOrientation') - .subscribe((textOrientation: Directionality) => { - this.direction = textOrientation; - }); - - this.userPreferenceService.set( - 'textOrientation', - this.getCurrentLanguage(this.userPreferenceService.get('locale')) - .direction || 'ltr' - ); } ngOnDestroy() { @@ -221,12 +207,4 @@ export class AppLayoutComponent implements OnInit, OnDestroy { return expand; } - - private getCurrentLanguage(key: string): LanguageItem { - return ( - this.appConfigService - .get>(AppConfigValues.APP_CONFIG_LANGUAGES_KEY) - .find(language => language.key === key) || {} - ); - } } From baef12dd0ff9fdc36a6084fb7ca9bd7d118ca631 Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Wed, 5 Jun 2019 14:08:40 +0300 Subject: [PATCH 214/259] mirror mat-icon when rtl (#1119) --- src/app/ui/application.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/app/ui/application.scss b/src/app/ui/application.scss index 2014b63a0f..d6d67a516c 100644 --- a/src/app/ui/application.scss +++ b/src/app/ui/application.scss @@ -16,6 +16,10 @@ body { } } +[dir='rtl'] .mat-icon { + transform: scale(-1, 1); +} + // todo: move this to corresponding component theme files app-root, app-about, From 9e95b6414f99fc967d7462ecccb25461ce24dd36 Mon Sep 17 00:00:00 2001 From: Suzana Dirla Date: Fri, 7 Jun 2019 06:13:57 +0300 Subject: [PATCH 215/259] [ACA-2415] author & titled aspects should be excluded (#1120) --- src/app.config.json | 2 ++ src/assets/app.extensions.json | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/app.config.json b/src/app.config.json index b83f7b721d..8178a91377 100644 --- a/src/app.config.json +++ b/src/app.config.json @@ -123,6 +123,8 @@ "cm:auditable", "cm:thumbnailModification", "cm:content", + "cm:author", + "cm:titled", "qshare:shared", "exif:exif" diff --git a/src/assets/app.extensions.json b/src/assets/app.extensions.json index 431d1127a1..124bb585c6 100644 --- a/src/assets/app.extensions.json +++ b/src/assets/app.extensions.json @@ -1038,6 +1038,8 @@ "cm:auditable", "cm:thumbnailModification", "cm:content", + "cm:author", + "cm:titled", "qshare:shared", "exif:exif" From b0ee874a3aa078abb24721c8d911be18f013159b Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Fri, 7 Jun 2019 10:13:36 +0100 Subject: [PATCH 216/259] switch to husky for pre-commit hook (#1121) --- package-lock.json | 373 +++++++++++++++++++++++++++++++++++----------- package.json | 13 +- 2 files changed, 295 insertions(+), 91 deletions(-) diff --git a/package-lock.json b/package-lock.json index ad1b180cb8..fea1783058 100644 --- a/package-lock.json +++ b/package-lock.json @@ -913,9 +913,9 @@ "dev": true }, "@babel/runtime": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.4.4.tgz", - "integrity": "sha512-w0+uT71b6Yi7i5SE0co4NioIpSYS6lLiXvCzWzGSKvpK5vdQtCbICHMj+gbAKAOtxiV6HsVh/MBdaF9EQ6faSg==", + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.4.5.tgz", + "integrity": "sha512-TuI4qpWZP6lGOGIuGWtp9sPluqYICmbk8T/1vpSysqJxRPkudh/ofFWyqdcMsDf2s7KvDL4/YHgKyvcS3g9CJQ==", "dev": true, "requires": { "regenerator-runtime": "^0.13.2" @@ -1254,6 +1254,12 @@ "integrity": "sha512-wNBfvNjzsJl4tswIZKXCFQY0lss9nKUyJnG6T94X/eqjRgI2jHZ4evdjhQYBSan/vGtF6XVXPApOmNH2rf0KKw==", "dev": true }, + "@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "dev": true + }, "@types/q": { "version": "0.0.32", "resolved": "http://registry.npmjs.org/@types/q/-/q-0.0.32.tgz", @@ -5107,7 +5113,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -5128,12 +5135,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": 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" @@ -5148,17 +5157,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -5275,7 +5287,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -5287,6 +5300,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -5301,6 +5315,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -5308,12 +5323,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -5332,6 +5349,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -5412,7 +5430,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -5424,6 +5443,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -5509,7 +5529,8 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -5545,6 +5566,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -5564,6 +5586,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -5607,12 +5630,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, @@ -6137,6 +6162,236 @@ } } }, + "husky": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/husky/-/husky-2.4.0.tgz", + "integrity": "sha512-3k1wuZU20gFkphNWMjh2ISCFaqfbaLY7R9FST2Mj9HeRhUK9ydj9qQR8qfXlog3EctVGsyeilcZkIT7uBZDDVA==", + "dev": true, + "requires": { + "cosmiconfig": "^5.2.0", + "execa": "^1.0.0", + "find-up": "^3.0.0", + "get-stdin": "^7.0.0", + "is-ci": "^2.0.0", + "pkg-dir": "^4.1.0", + "please-upgrade-node": "^3.1.1", + "read-pkg": "^5.1.1", + "run-node": "^1.0.0", + "slash": "^3.0.0" + }, + "dependencies": { + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "requires": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "get-stdin": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-7.0.0.tgz", + "integrity": "sha512-zRKcywvrXlXsA0v0i9Io4KDRaAw7+a1ZpjRwl9Wox8PFlVCCHra7E9c4kqXCoCM9nR5tBkaTTZRBoCm60bFqTQ==", + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "p-limit": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", + "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.0.0.tgz", + "integrity": "sha512-zoH7ZWPkRdgwYCDVoQTzqjG8JSPANhtvLhh4KVUHyKnaUJJrNeFmWIkTcNuJmR3GLMEmGYEf2S2bjgx26JTF+Q==", + "dev": true, + "requires": { + "locate-path": "^5.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + } + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "read-pkg": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.1.1.tgz", + "integrity": "sha512-dFcTLQi6BZ+aFUaICg7er+/usEoqFdQxiEBsEMNGoipenihtxxtdrQuBXvyANCEI8VuUIVYFgeHGx9sLLvim4w==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^4.0.0", + "type-fest": "^0.4.1" + } + }, + "resolve": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.1.tgz", + "integrity": "sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + } + } + }, "iconv-lite": { "version": "0.4.23", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", @@ -7490,9 +7745,9 @@ } }, "lint-staged": { - "version": "8.1.7", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-8.1.7.tgz", - "integrity": "sha512-egT0goFhIFoOGk6rasPngTFh2qDqxZddM0PwI58oi66RxCDcn5uDwxmiasWIF0qGnchHSYVJ8HPRD5LrFo7TKA==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-8.2.0.tgz", + "integrity": "sha512-DxguyxGOIfb67wZ6EOrqzjAbw6ZH9XK3YS74HO+erJf6+SAQeJJPN//GBOG5xhdt2THeuXjVPaHcCYOWGZwRbA==", "dev": true, "requires": { "chalk": "^2.3.1", @@ -7502,7 +7757,6 @@ "dedent": "^0.7.0", "del": "^3.0.0", "execa": "^1.0.0", - "find-parent-dir": "^0.3.0", "g-status": "^2.0.2", "is-glob": "^4.0.0", "is-windows": "^1.0.2", @@ -7547,12 +7801,6 @@ "which": "^1.2.9" } }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, "execa": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", @@ -7577,16 +7825,6 @@ "pump": "^3.0.0" } }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", @@ -9093,12 +9331,6 @@ "lcid": "^1.0.0" } }, - "os-shim": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/os-shim/-/os-shim-0.1.3.tgz", - "integrity": "sha1-a2LDeRz3kJ6jXtRuF2WLtBfLORc=", - "dev": true - }, "os-tmpdir": { "version": "1.0.2", "resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", @@ -9643,39 +9875,6 @@ "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", "dev": true }, - "pre-commit": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/pre-commit/-/pre-commit-1.2.2.tgz", - "integrity": "sha1-287g7p3nI15X95xW186UZBpp7sY=", - "dev": true, - "requires": { - "cross-spawn": "^5.0.1", - "spawn-sync": "^1.0.15", - "which": "1.2.x" - }, - "dependencies": { - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "which": { - "version": "1.2.14", - "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", - "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, "prepend-http": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", @@ -10544,6 +10743,12 @@ "is-promise": "^2.1.0" } }, + "run-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/run-node/-/run-node-1.0.0.tgz", + "integrity": "sha512-kc120TBlQ3mih1LSzdAJXo4xn/GWS2ec0l3S+syHDXP9uRr0JAT8Qd3mdMuyjqCzeZktgP3try92cEgf9Nks8A==", + "dev": true + }, "run-queue": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", @@ -11417,16 +11622,6 @@ "integrity": "sha512-CYAPYdBu34781kLHkaW3m6b/uUSyMOC2R61gcYMWooeuaGtjof86ZA/8T+qVPPt7np1085CR9hmMGrySwEc8Xg==", "dev": true }, - "spawn-sync": { - "version": "1.0.15", - "resolved": "https://registry.npmjs.org/spawn-sync/-/spawn-sync-1.0.15.tgz", - "integrity": "sha1-sAeZVX63+wyDdsKdROih6mfldHY=", - "dev": true, - "requires": { - "concat-stream": "^1.4.7", - "os-shim": "^0.1.2" - } - }, "spdx-correct": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", @@ -11853,9 +12048,9 @@ "dev": true }, "synchronous-promise": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/synchronous-promise/-/synchronous-promise-2.0.7.tgz", - "integrity": "sha512-16GbgwTmFMYFyQMLvtQjvNWh30dsFe1cAW5Fg1wm5+dg84L9Pe36mftsIRU95/W2YsISxsz/xq4VB23sqpgb/A==", + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/synchronous-promise/-/synchronous-promise-2.0.9.tgz", + "integrity": "sha512-LO95GIW16x69LuND1nuuwM4pjgFGupg7pZ/4lU86AmchPKrhk0o2tpMU2unXRrqo81iAFe1YJ0nAGEVwsrZAgg==", "dev": true }, "tapable": { @@ -12410,6 +12605,12 @@ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", "dev": true }, + "type-fest": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.4.1.tgz", + "integrity": "sha512-IwzA/LSfD2vC1/YDYMv/zHP4rDF1usCwllsDpbolT3D4fUepIO7f9K70jjmUewU/LmGUKJcwcVtDCpnKk4BPMw==", + "dev": true + }, "type-is": { "version": "1.6.16", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", diff --git a/package.json b/package.json index acb9225cfb..84a3abedf5 100644 --- a/package.json +++ b/package.json @@ -32,8 +32,7 @@ "e2e.tomcat": "npm run wd:update && protractor --baseUrl=http://localhost:4000/content-app/ $SUITE", "docker.tomcat.start": "cd docker/tomcat && docker-compose up -d --build && npm run wait:app", "docker.tomcat.stop": "cd docker/tomcat && docker-compose stop", - "docker.tomcat.e2e": "npm run docker.tomcat.start && npm run e2e.tomcat", - "lint:staged": "lint-staged" + "docker.tomcat.e2e": "npm run docker.tomcat.start && npm run e2e.tomcat" }, "private": true, "dependencies": { @@ -84,6 +83,7 @@ "codelyzer": "^4.5.0", "cpr": "^3.0.1", "cspell": "^3.2.17", + "husky": "^2.4.0", "jasmine-core": "~2.8.0", "jasmine-reporters": "^2.2.1", "jasmine-spec-reporter": "~4.2.1", @@ -94,10 +94,9 @@ "karma-coverage-istanbul-reporter": "^2.0.4", "karma-jasmine": "~1.1.0", "karma-jasmine-html-reporter": "^0.2.2", - "lint-staged": "^8.1.7", + "lint-staged": "^8.2.0", "ng-packagr": "^4.7.1", "node-stream-zip": "1.8.0", - "pre-commit": "^1.2.2", "prettier": "^1.17.1", "protractor": "^5.4.0", "protractor-screenshoter-plugin": "0.10.3", @@ -116,5 +115,9 @@ "git add" ] }, - "pre-commit": "lint:staged" + "husky": { + "hooks": { + "pre-commit": "lint-staged" + } + } } From 24217dc05007ba4d5d9f11b480e38ab6179a7db7 Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Sat, 8 Jun 2019 17:01:24 +0300 Subject: [PATCH 217/259] upgrade ADF 3.3.0 alpha (#1123) * update to alpha * remove locale --- package-lock.json | 59 +++++++------------ package.json | 6 +- src/app.config.json | 1 - src/app/ui/custom-theme.scss | 1 - .../overrides/adf-layout-container.theme.scss | 10 ---- 5 files changed, 23 insertions(+), 54 deletions(-) delete mode 100644 src/app/ui/overrides/adf-layout-container.theme.scss diff --git a/package-lock.json b/package-lock.json index fea1783058..a92e48b4d7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,25 +5,25 @@ "requires": true, "dependencies": { "@alfresco/adf-content-services": { - "version": "3.3.0-9aafb804830cba52f2a92e0a14549f6b41fcaa92", - "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-3.3.0-9aafb804830cba52f2a92e0a14549f6b41fcaa92.tgz", - "integrity": "sha512-tc7uNSbzWimRqRb6dbUMZ+tIWsD4yRs/FHNYUzR5JBs+PNX6zcLytl3cj68C4qbo95hAb1svYJt8vJ1h1Tv8IA==", + "version": "3.3.0-8a2a71d60be3f2b3dd0173f6a51d8075241e7203", + "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-3.3.0-8a2a71d60be3f2b3dd0173f6a51d8075241e7203.tgz", + "integrity": "sha512-QPbvSfCG/rOLVcwzAw2IWDrGe8fgzK209zgQwgOiGzmHhtY2Ru3GF2in+rlG+VK/qZvErv9x6nT0BVEmlc2SoQ==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/adf-core": { - "version": "3.3.0-9aafb804830cba52f2a92e0a14549f6b41fcaa92", - "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-3.3.0-9aafb804830cba52f2a92e0a14549f6b41fcaa92.tgz", - "integrity": "sha512-uVCzyoRwX0Oha8qifVpjxExNuY1mBEAkgpgDh/rRZshtsJQ3r2iSkx6o9JV9ZACRP1i5ct0KHJkcOxB0o+f36A==", + "version": "3.3.0-8a2a71d60be3f2b3dd0173f6a51d8075241e7203", + "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-3.3.0-8a2a71d60be3f2b3dd0173f6a51d8075241e7203.tgz", + "integrity": "sha512-BMqpwOyBAXKL9atGa4oNM+8KsQ/twiFiSJFTvi0tKbd+EhxaKINMv9/smnIE1D54hGzBHca/dBua4kT1FWbQwg==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/adf-extensions": { - "version": "3.3.0-9aafb804830cba52f2a92e0a14549f6b41fcaa92", - "resolved": "https://registry.npmjs.org/@alfresco/adf-extensions/-/adf-extensions-3.3.0-9aafb804830cba52f2a92e0a14549f6b41fcaa92.tgz", - "integrity": "sha512-8dAUsEfENFQsDRlFveuvw6XsfxTCX8aYPlvE1Mo24HjFvc6wRU98+m1hso4aJWZo194W4otjtj7IEvRWnTovwA==", + "version": "3.3.0-8a2a71d60be3f2b3dd0173f6a51d8075241e7203", + "resolved": "https://registry.npmjs.org/@alfresco/adf-extensions/-/adf-extensions-3.3.0-8a2a71d60be3f2b3dd0173f6a51d8075241e7203.tgz", + "integrity": "sha512-iEABQcxgUxlh7/qhbUprgL+zxLue/NSPIAs5rxuBAsGbPusIPh15cvJmo1YUnm0cbjxLs5CMUGurenfeh7afEQ==", "requires": { "tslib": "^1.9.0" } @@ -5113,8 +5113,7 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "aproba": { "version": "1.2.0", @@ -5135,14 +5134,12 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -5157,20 +5154,17 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -5287,8 +5281,7 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -5300,7 +5293,6 @@ "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -5315,7 +5307,6 @@ "version": "3.0.4", "bundled": true, "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -5323,14 +5314,12 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -5349,7 +5338,6 @@ "version": "0.5.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -5430,8 +5418,7 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -5443,7 +5430,6 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -5529,8 +5515,7 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "safer-buffer": { "version": "2.1.2", @@ -5566,7 +5551,6 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -5586,7 +5570,6 @@ "version": "3.0.1", "bundled": true, "dev": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -5630,14 +5613,12 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true } } }, diff --git a/package.json b/package.json index 84a3abedf5..b71d9a13c2 100644 --- a/package.json +++ b/package.json @@ -36,9 +36,9 @@ }, "private": true, "dependencies": { - "@alfresco/adf-content-services": "3.3.0-9aafb804830cba52f2a92e0a14549f6b41fcaa92", - "@alfresco/adf-core": "3.3.0-9aafb804830cba52f2a92e0a14549f6b41fcaa92", - "@alfresco/adf-extensions": "3.3.0-9aafb804830cba52f2a92e0a14549f6b41fcaa92", + "@alfresco/adf-content-services": "3.3.0-8a2a71d60be3f2b3dd0173f6a51d8075241e7203", + "@alfresco/adf-core": "3.3.0-8a2a71d60be3f2b3dd0173f6a51d8075241e7203", + "@alfresco/adf-extensions": "3.3.0-8a2a71d60be3f2b3dd0173f6a51d8075241e7203", "@alfresco/js-api": "3.2.1", "@angular/animations": "7.2.15", "@angular/cdk": "^7.3.7", diff --git a/src/app.config.json b/src/app.config.json index 8178a91377..3edf0a43ac 100644 --- a/src/app.config.json +++ b/src/app.config.json @@ -15,7 +15,6 @@ "redirectUri": "/", "redirectUriLogout": "/logout" }, - "locale": "en", "application": { "name": "Alfresco Content Application", "logo": "assets/images/alfresco-logo-flower.svg", diff --git a/src/app/ui/custom-theme.scss b/src/app/ui/custom-theme.scss index 4dba63a3d2..73c51d4372 100644 --- a/src/app/ui/custom-theme.scss +++ b/src/app/ui/custom-theme.scss @@ -11,7 +11,6 @@ @import '../components/create-menu/create-menu.component.scss'; @import '../components/layout/layout.theme.scss'; -@import 'overrides/adf-layout-container.theme'; @import './overrides/adf-document-list.theme'; @import 'snackbar'; diff --git a/src/app/ui/overrides/adf-layout-container.theme.scss b/src/app/ui/overrides/adf-layout-container.theme.scss deleted file mode 100644 index d40af3d35d..0000000000 --- a/src/app/ui/overrides/adf-layout-container.theme.scss +++ /dev/null @@ -1,10 +0,0 @@ -@mixin adf-layout-container-theme($theme) { - $adf-layout-container-height: 100% !default; - - adf-layout-container { - .mat-drawer-content > div, - .mat-drawer-content > div > div { - height: $adf-layout-container-height; - } - } -} From 3e2c33567dbe145f9962ce5e965da75ac78b7359 Mon Sep 17 00:00:00 2001 From: Suzana Dirla Date: Thu, 13 Jun 2019 10:09:40 +0300 Subject: [PATCH 218/259] [ACA-2420] exclude aspects and order effectivity properties (#1124) * [ACA-2420] exclude aspects and order effectivity properties * [ACA-2420] ids not needed inside app.config - this is the 'applied' setting for content-metadata when there isn't one inside the app.extensions.json that overwrites it --- src/app.config.json | 19 ++++++++++++++++++- src/assets/app.extensions.json | 21 ++++++++++++++++++++- src/assets/i18n/en.json | 3 ++- 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/app.config.json b/src/app.config.json index 3edf0a43ac..9b7937934b 100644 --- a/src/app.config.json +++ b/src/app.config.json @@ -124,9 +124,14 @@ "cm:content", "cm:author", "cm:titled", + "cm:generalclassifiable", + "cm:taggable", + "dp:restrictable", + "fm:commentsRollup", "qshare:shared", - "exif:exif" + "exif:exif", + "cm:effectivity" ] }, { @@ -150,6 +155,18 @@ ] } ] + }, + { + "title": "APP.CONTENT_METADATA.EFFECTIVITY_GROUP_TITLE", + "items": [ + { + "aspect": "cm:effectivity", + "properties": [ + "cm:from", + "cm:to" + ] + } + ] } ] } diff --git a/src/assets/app.extensions.json b/src/assets/app.extensions.json index 124bb585c6..c7f05b0e70 100644 --- a/src/assets/app.extensions.json +++ b/src/assets/app.extensions.json @@ -1040,9 +1040,14 @@ "cm:content", "cm:author", "cm:titled", + "cm:generalclassifiable", + "cm:taggable", + "dp:restrictable", + "fm:commentsRollup", "qshare:shared", - "exif:exif" + "exif:exif", + "cm:effectivity" ] }, { @@ -1068,6 +1073,20 @@ ] } ] + }, + { + "id": "app.content.metadata.effectivityGroup", + "title": "APP.CONTENT_METADATA.EFFECTIVITY_GROUP_TITLE", + "items": [ + { + "id": "app.content.metadata.effectivityAspect", + "aspect": "cm:effectivity", + "properties": [ + "cm:from", + "cm:to" + ] + } + ] } ] } diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index c689651324..2506ca3118 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -335,7 +335,8 @@ } }, "CONTENT_METADATA": { - "EXIF_GROUP_TITLE": "Image EXIF" + "EXIF_GROUP_TITLE": "Image EXIF", + "EFFECTIVITY_GROUP_TITLE": "Effectivity" }, "INFO_DRAWER": { "TITLE": "Details", From ca5795fac0c8c577296a57fa0d44383edda46a20 Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Fri, 14 Jun 2019 10:26:31 +0300 Subject: [PATCH 219/259] rtl fixes (#1128) --- .../page-layout/page-layout.component.scss | 13 ++++++++++++- src/app/components/sidenav/sidenav.component.scss | 12 +++++------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/projects/aca-shared/src/lib/components/page-layout/page-layout.component.scss b/projects/aca-shared/src/lib/components/page-layout/page-layout.component.scss index 79670dfcce..e48ec8dd0b 100644 --- a/projects/aca-shared/src/lib/components/page-layout/page-layout.component.scss +++ b/projects/aca-shared/src/lib/components/page-layout/page-layout.component.scss @@ -23,7 +23,6 @@ .main-content { @include flex-column; - border-right: 1px solid var(--theme-border-color, rgba(0, 0, 0, 0.07)); } .scrollable { @@ -42,3 +41,15 @@ width: 350px; } } + +[dir='rtl'] .aca-page-layout { + .main-content { + border-left: 1px solid var(--theme-border-color, rgba(0, 0, 0, 0.07)); + } +} + +[dir='ltr'] .aca-page-layout { + .main-content { + border-right: 1px solid var(--theme-border-color, rgba(0, 0, 0, 0.07)); + } +} diff --git a/src/app/components/sidenav/sidenav.component.scss b/src/app/components/sidenav/sidenav.component.scss index 383d127fa7..2d03e8d2af 100644 --- a/src/app/components/sidenav/sidenav.component.scss +++ b/src/app/components/sidenav/sidenav.component.scss @@ -55,7 +55,7 @@ } .action-button .action-button__label { - margin-left: 8px !important; + margin: 0 8px !important; } .app-item, @@ -103,10 +103,8 @@ } } -[dir='rtl'] .action-button .action-button__label { - margin-right: 8px !important; -} - -[dir='rtl'] .mat-expansion-panel-header { - padding: 0 0 0 8px !important; +[dir='rtl'] .sidenav { + .mat-expansion-panel-header { + padding: 0 0 0 8px !important; + } } From 36043d1473a65b6ef9601757a032a44e6c6cff68 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Fri, 14 Jun 2019 12:59:09 +0100 Subject: [PATCH 220/259] [ACA-2182] ADF 3.3.0 alpha (#1126) * upgrade to latest adf 3.0.0 alpha * use ADF share dialog * [ACA-2069] make sure toggles have the right color * raise error popups for shared links * update test * use date only for sharing * [ACA-2069] small improvement - make sure toggles have the right color * remove old share dialog * move toggle-shared component to common module --- package-lock.json | 59 ++- package.json | 6 +- src/app.config.json | 1 + src/app/app.component.spec.ts | 1 + src/app/app.component.ts | 12 +- src/app/app.module.ts | 2 - src/app/components/common/common.module.ts | 12 +- .../toggle-shared.component.html | 0 .../toggle-shared.component.spec.ts | 0 .../toggle-shared/toggle-shared.component.ts | 0 .../content-node-share.dialog.html | 92 ----- .../content-node-share.dialog.scss | 64 ---- .../content-node-share.dialog.spec.ts | 350 ------------------ .../content-node-share.dialog.ts | 255 ------------- .../content-node-share.module.ts | 41 -- src/app/components/shared/shared.module.ts | 44 --- .../toggle-shared/toggle-shared.module.ts | 48 --- src/app/extensions/core.extensions.module.ts | 2 +- .../services/content-management.service.ts | 5 +- src/app/ui/theme.scss | 12 + 20 files changed, 78 insertions(+), 928 deletions(-) rename src/app/components/{shared => common}/toggle-shared/toggle-shared.component.html (100%) rename src/app/components/{shared => common}/toggle-shared/toggle-shared.component.spec.ts (100%) rename src/app/components/{shared => common}/toggle-shared/toggle-shared.component.ts (100%) delete mode 100644 src/app/components/shared/content-node-share/content-node-share.dialog.html delete mode 100644 src/app/components/shared/content-node-share/content-node-share.dialog.scss delete mode 100644 src/app/components/shared/content-node-share/content-node-share.dialog.spec.ts delete mode 100644 src/app/components/shared/content-node-share/content-node-share.dialog.ts delete mode 100644 src/app/components/shared/content-node-share/content-node-share.module.ts delete mode 100644 src/app/components/shared/shared.module.ts delete mode 100644 src/app/components/shared/toggle-shared/toggle-shared.module.ts diff --git a/package-lock.json b/package-lock.json index a92e48b4d7..d9f90e2226 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,25 +5,25 @@ "requires": true, "dependencies": { "@alfresco/adf-content-services": { - "version": "3.3.0-8a2a71d60be3f2b3dd0173f6a51d8075241e7203", - "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-3.3.0-8a2a71d60be3f2b3dd0173f6a51d8075241e7203.tgz", - "integrity": "sha512-QPbvSfCG/rOLVcwzAw2IWDrGe8fgzK209zgQwgOiGzmHhtY2Ru3GF2in+rlG+VK/qZvErv9x6nT0BVEmlc2SoQ==", + "version": "3.3.0-626bb01bf7d26e693a4947982d20695c45794503", + "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-3.3.0-626bb01bf7d26e693a4947982d20695c45794503.tgz", + "integrity": "sha512-2Y2VPvSxXxlhBJoKLQo9NGy0r9paAnAweXIi9EiuZctLNFDAzG2UVDb93gGhtcAi+ulH5xyoRu/9mDIpE4e5ew==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/adf-core": { - "version": "3.3.0-8a2a71d60be3f2b3dd0173f6a51d8075241e7203", - "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-3.3.0-8a2a71d60be3f2b3dd0173f6a51d8075241e7203.tgz", - "integrity": "sha512-BMqpwOyBAXKL9atGa4oNM+8KsQ/twiFiSJFTvi0tKbd+EhxaKINMv9/smnIE1D54hGzBHca/dBua4kT1FWbQwg==", + "version": "3.3.0-626bb01bf7d26e693a4947982d20695c45794503", + "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-3.3.0-626bb01bf7d26e693a4947982d20695c45794503.tgz", + "integrity": "sha512-mEL+/0udJ1R4vnb8UK6QsdLRd/PPMo1q1esTYUAu0in0TR6PesqBiTMAtmj5sVV40IIeW7u7kD/TpZNBRDlxrg==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/adf-extensions": { - "version": "3.3.0-8a2a71d60be3f2b3dd0173f6a51d8075241e7203", - "resolved": "https://registry.npmjs.org/@alfresco/adf-extensions/-/adf-extensions-3.3.0-8a2a71d60be3f2b3dd0173f6a51d8075241e7203.tgz", - "integrity": "sha512-iEABQcxgUxlh7/qhbUprgL+zxLue/NSPIAs5rxuBAsGbPusIPh15cvJmo1YUnm0cbjxLs5CMUGurenfeh7afEQ==", + "version": "3.3.0-626bb01bf7d26e693a4947982d20695c45794503", + "resolved": "https://registry.npmjs.org/@alfresco/adf-extensions/-/adf-extensions-3.3.0-626bb01bf7d26e693a4947982d20695c45794503.tgz", + "integrity": "sha512-qh2xdGTeNBvh7QzScvaYxHxvoTld5bCwDRIUKNj+Dt+C3aaAs5mdN85hTVQ82+vNptD8NO9nCBaS/CR5ISwt9Q==", "requires": { "tslib": "^1.9.0" } @@ -5113,7 +5113,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -5134,12 +5135,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": 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" @@ -5154,17 +5157,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -5281,7 +5287,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -5293,6 +5300,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -5307,6 +5315,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -5314,12 +5323,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -5338,6 +5349,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -5418,7 +5430,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -5430,6 +5443,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -5515,7 +5529,8 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -5551,6 +5566,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -5570,6 +5586,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -5613,12 +5630,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, diff --git a/package.json b/package.json index b71d9a13c2..309acd06e1 100644 --- a/package.json +++ b/package.json @@ -36,9 +36,9 @@ }, "private": true, "dependencies": { - "@alfresco/adf-content-services": "3.3.0-8a2a71d60be3f2b3dd0173f6a51d8075241e7203", - "@alfresco/adf-core": "3.3.0-8a2a71d60be3f2b3dd0173f6a51d8075241e7203", - "@alfresco/adf-extensions": "3.3.0-8a2a71d60be3f2b3dd0173f6a51d8075241e7203", + "@alfresco/adf-content-services": "3.3.0-626bb01bf7d26e693a4947982d20695c45794503", + "@alfresco/adf-core": "3.3.0-626bb01bf7d26e693a4947982d20695c45794503", + "@alfresco/adf-extensions": "3.3.0-626bb01bf7d26e693a4947982d20695c45794503", "@alfresco/js-api": "3.2.1", "@angular/animations": "7.2.15", "@angular/cdk": "^7.3.7", diff --git a/src/app.config.json b/src/app.config.json index 9b7937934b..e82941ab9e 100644 --- a/src/app.config.json +++ b/src/app.config.json @@ -20,6 +20,7 @@ "logo": "assets/images/alfresco-logo-flower.svg", "copyright": "APP.COPYRIGHT" }, + "sharedLinkDateTimePickerType": "date", "headerColor": "#2196F3", "languagePicker": true, "pagination": { diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts index b5c55f0bc6..11c2e77d73 100644 --- a/src/app/app.component.spec.ts +++ b/src/app/app.component.spec.ts @@ -54,6 +54,7 @@ describe('AppComponent', () => { null, null, null, + null, null ); }); diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 0295f27022..4f7ead6ddf 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -29,7 +29,8 @@ import { AuthenticationService, FileUploadErrorEvent, PageTitleService, - UploadService + UploadService, + SharedLinksApiService } from '@alfresco/adf-core'; import { Component, OnInit, OnDestroy } from '@angular/core'; import { ActivatedRoute, NavigationEnd, Router } from '@angular/router'; @@ -70,7 +71,8 @@ export class AppComponent implements OnInit, OnDestroy { private uploadService: UploadService, private extensions: AppExtensionService, private contentApi: ContentApiService, - private appService: AppService + private appService: AppService, + private sharedLinksApiService: SharedLinksApiService ) {} ngOnInit() { @@ -120,6 +122,12 @@ export class AppComponent implements OnInit, OnDestroy { this.onFileUploadedError(error) ); + this.sharedLinksApiService.error + .pipe(takeUntil(this.onDestroy$)) + .subscribe((err: { message: string }) => { + this.store.dispatch(new SnackbarErrorAction(err.message)); + }); + this.appService.ready$ .pipe(takeUntil(this.onDestroy$)) .subscribe(isReady => { diff --git a/src/app/app.module.ts b/src/app/app.module.ts index d74c500035..9ef973b2b6 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -61,7 +61,6 @@ import { DirectivesModule } from './directives/directives.module'; import { ContextMenuModule } from './components/context-menu/context-menu.module'; import { ExtensionsModule } from '@alfresco/adf-extensions'; import { AppToolbarModule } from './components/toolbar/toolbar.module'; -import { AppSharedModule } from './components/shared/shared.module'; import { AppCreateMenuModule } from './components/create-menu/create-menu.module'; import { AppSidenavModule } from './components/sidenav/sidenav.module'; import { AppPermissionsModule } from './components/permissions/permissions.module'; @@ -102,7 +101,6 @@ import { environment } from '../environments/environment'; ContextMenuModule, AppInfoDrawerModule, AppToolbarModule, - AppSharedModule, AppSidenavModule, AppCreateMenuModule, DocumentListCustomComponentsModule, diff --git a/src/app/components/common/common.module.ts b/src/app/components/common/common.module.ts index fbda679d47..17ac4f12f6 100644 --- a/src/app/components/common/common.module.ts +++ b/src/app/components/common/common.module.ts @@ -29,6 +29,7 @@ import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; import { GenericErrorModule } from '@alfresco/aca-shared'; import { LocationLinkComponent } from './location-link/location-link.component'; +import { ToggleSharedComponent } from './toggle-shared/toggle-shared.component'; @NgModule({ imports: [ @@ -37,8 +38,13 @@ import { LocationLinkComponent } from './location-link/location-link.component'; ExtensionsModule, GenericErrorModule ], - declarations: [LocationLinkComponent], - exports: [ExtensionsModule, LocationLinkComponent, GenericErrorModule], - entryComponents: [LocationLinkComponent] + declarations: [LocationLinkComponent, ToggleSharedComponent], + exports: [ + ExtensionsModule, + LocationLinkComponent, + GenericErrorModule, + ToggleSharedComponent + ], + entryComponents: [LocationLinkComponent, ToggleSharedComponent] }) export class AppCommonModule {} diff --git a/src/app/components/shared/toggle-shared/toggle-shared.component.html b/src/app/components/common/toggle-shared/toggle-shared.component.html similarity index 100% rename from src/app/components/shared/toggle-shared/toggle-shared.component.html rename to src/app/components/common/toggle-shared/toggle-shared.component.html diff --git a/src/app/components/shared/toggle-shared/toggle-shared.component.spec.ts b/src/app/components/common/toggle-shared/toggle-shared.component.spec.ts similarity index 100% rename from src/app/components/shared/toggle-shared/toggle-shared.component.spec.ts rename to src/app/components/common/toggle-shared/toggle-shared.component.spec.ts diff --git a/src/app/components/shared/toggle-shared/toggle-shared.component.ts b/src/app/components/common/toggle-shared/toggle-shared.component.ts similarity index 100% rename from src/app/components/shared/toggle-shared/toggle-shared.component.ts rename to src/app/components/common/toggle-shared/toggle-shared.component.ts diff --git a/src/app/components/shared/content-node-share/content-node-share.dialog.html b/src/app/components/shared/content-node-share/content-node-share.dialog.html deleted file mode 100644 index ffa3138e34..0000000000 --- a/src/app/components/shared/content-node-share/content-node-share.dialog.html +++ /dev/null @@ -1,92 +0,0 @@ - diff --git a/src/app/components/shared/content-node-share/content-node-share.dialog.scss b/src/app/components/shared/content-node-share/content-node-share.dialog.scss deleted file mode 100644 index cfd380f8cf..0000000000 --- a/src/app/components/shared/content-node-share/content-node-share.dialog.scss +++ /dev/null @@ -1,64 +0,0 @@ -@mixin adf-share-link-typography { - letter-spacing: -0.4px; - line-height: 2; - font-weight: normal; - font-style: normal; - font-stretch: normal; - font-size: 16px; - opacity: 0.87; -} - -.adf-share-link-dialog { - .adf-share-link { - &__dialog-content { - display: flex; - flex-direction: column; - } - - &__label { - @include adf-share-link-typography; - flex: 1 1 auto; - } - - &__title { - @include adf-share-link-typography; - } - - &__info { - @include adf-share-link-typography; - opacity: 0.54; - font-size: 13px; - } - - &--row { - display: flex; - flex-direction: row; - flex-wrap: wrap; - align-items: center; - } - - &__input { - opacity: 0.54; - } - } - - .adf-input-action { - cursor: pointer; - } - - .mat-form-field-infix { - border-top: unset; - } - - .mat-dialog-actions { - justify-content: flex-end; - - & > button { - text-transform: uppercase; - } - } - - .mat-form-field-flex { - align-items: center; - } -} diff --git a/src/app/components/shared/content-node-share/content-node-share.dialog.spec.ts b/src/app/components/shared/content-node-share/content-node-share.dialog.spec.ts deleted file mode 100644 index 3f3a3af580..0000000000 --- a/src/app/components/shared/content-node-share/content-node-share.dialog.spec.ts +++ /dev/null @@ -1,350 +0,0 @@ -/*! - * @license - * Copyright 2019 Alfresco Software, Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { TestBed, fakeAsync, async, tick } from '@angular/core/testing'; -import { - MatDialogRef, - MAT_DIALOG_DATA, - MatDialog -} from '@angular/material/dialog'; -import { of } from 'rxjs'; -import { - setupTestBed, - CoreModule, - SharedLinksApiService, - NodesApiService, - NotificationService -} from '@alfresco/adf-core'; -import { ContentNodeShareModule } from './content-node-share.module'; -import { ShareDialogComponent } from './content-node-share.dialog'; -import * as moment from 'moment'; -import { Store } from '@ngrx/store'; - -describe('ShareDialogComponent', () => { - let node; - let matDialog: MatDialog; - const notificationServiceMock = { - openSnackMessage: jasmine.createSpy('openSnackMessage') - }; - let sharedLinksApiService: SharedLinksApiService; - let nodesApiService: NodesApiService; - let fixture; - let component; - const storeMock = { - dispatch: jasmine.createSpy('dispatch') - }; - - setupTestBed({ - imports: [ - NoopAnimationsModule, - CoreModule.forRoot(), - ContentNodeShareModule - ], - providers: [ - NodesApiService, - SharedLinksApiService, - { provide: Store, useValue: storeMock }, - { provide: NotificationService, useValue: notificationServiceMock }, - { provide: MatDialogRef, useValue: {} }, - { provide: MAT_DIALOG_DATA, useValue: {} } - ] - }); - - beforeEach(() => { - fixture = TestBed.createComponent(ShareDialogComponent); - matDialog = TestBed.get(MatDialog); - sharedLinksApiService = TestBed.get(SharedLinksApiService); - nodesApiService = TestBed.get(NodesApiService); - component = fixture.componentInstance; - }); - - beforeEach(() => { - node = { - entry: { - id: 'nodeId', - allowableOperations: ['update'], - isFile: true, - properties: {} - } - }; - }); - - afterEach(() => { - fixture.destroy(); - }); - - it(`should toggle share action when property 'sharedId' does not exists`, fakeAsync(() => { - spyOn(sharedLinksApiService, 'createSharedLinks').and.returnValue( - of({ - entry: { id: 'sharedId', sharedId: 'sharedId' } - }) - ); - - component.data = { - node, - permission: true, - baseShareUrl: 'some-url/' - }; - - fixture.detectChanges(); - tick(500); - - expect(sharedLinksApiService.createSharedLinks).toHaveBeenCalled(); - expect( - fixture.nativeElement.querySelector('input[formcontrolname="sharedUrl"]') - .value - ).toBe('some-url/sharedId'); - expect( - fixture.nativeElement.querySelector( - '.mat-slide-toggle[data-automation-id="adf-share-toggle"' - ).classList - ).toContain('mat-checked'); - })); - - it(`should not toggle share action when file has 'sharedId' property`, fakeAsync(() => { - spyOn(sharedLinksApiService, 'createSharedLinks'); - node.entry.properties['qshare:sharedId'] = 'sharedId'; - - component.data = { - node, - permission: true, - baseShareUrl: 'some-url/' - }; - - fixture.detectChanges(); - tick(500); - - expect(sharedLinksApiService.createSharedLinks).not.toHaveBeenCalled(); - expect( - fixture.nativeElement.querySelector('input[formcontrolname="sharedUrl"]') - .value - ).toBe('some-url/sharedId'); - expect( - fixture.nativeElement.querySelector( - '.mat-slide-toggle[data-automation-id="adf-share-toggle"' - ).classList - ).toContain('mat-checked'); - })); - - xit(`should copy shared link and notify on button event`, async(() => { - node.entry.properties['qshare:sharedId'] = 'sharedId'; - spyOn(document, 'execCommand').and.callThrough(); - - component.data = { - node, - permission: true, - baseShareUrl: 'some-url/' - }; - - fixture.detectChanges(); - - fixture.whenStable().then(() => { - fixture.detectChanges(); - - fixture.nativeElement - .querySelector('.adf-input-action') - .dispatchEvent(new MouseEvent('click')); - - fixture.detectChanges(); - - expect(document.execCommand).toHaveBeenCalledWith('copy'); - expect(notificationServiceMock.openSnackMessage).toHaveBeenCalledWith( - 'SHARE.CLIPBOARD-MESSAGE' - ); - }); - })); - - it('should open a confirmation dialog when unshare button is triggered', () => { - spyOn(matDialog, 'open').and.returnValue({ beforeClose: () => of(false) }); - spyOn(sharedLinksApiService, 'deleteSharedLink'); - node.entry.properties['qshare:sharedId'] = 'sharedId'; - - component.data = { - node, - permission: true, - baseShareUrl: 'some-url/' - }; - - fixture.detectChanges(); - - fixture.nativeElement - .querySelector( - '.mat-slide-toggle[data-automation-id="adf-share-toggle"] label' - ) - .dispatchEvent(new MouseEvent('click')); - - fixture.detectChanges(); - - expect(matDialog.open).toHaveBeenCalled(); - }); - - it('should unshare file when confirmation dialog returns true', fakeAsync(() => { - spyOn(matDialog, 'open').and.returnValue({ beforeClose: () => of(true) }); - spyOn(sharedLinksApiService, 'deleteSharedLink').and.returnValue(of(null)); - node.entry.properties['qshare:sharedId'] = 'sharedId'; - - component.data = { - node, - permission: true, - baseShareUrl: 'some-url/' - }; - - fixture.detectChanges(); - - fixture.nativeElement - .querySelector( - '.mat-slide-toggle[data-automation-id="adf-share-toggle"] label' - ) - .dispatchEvent(new MouseEvent('click')); - - fixture.detectChanges(); - - expect(sharedLinksApiService.deleteSharedLink).toHaveBeenCalled(); - })); - - it('should not unshare file when confirmation dialog returns false', fakeAsync(() => { - spyOn(matDialog, 'open').and.returnValue({ beforeClose: () => of(false) }); - spyOn(sharedLinksApiService, 'deleteSharedLink'); - node.entry.properties['qshare:sharedId'] = 'sharedId'; - - component.data = { - node, - permission: true, - baseShareUrl: 'some-url/' - }; - - fixture.detectChanges(); - - fixture.nativeElement - .querySelector( - '.mat-slide-toggle[data-automation-id="adf-share-toggle"] label' - ) - .dispatchEvent(new MouseEvent('click')); - - fixture.detectChanges(); - - expect(sharedLinksApiService.deleteSharedLink).not.toHaveBeenCalled(); - })); - - it('should reset expiration date when toggle is unchecked', () => { - spyOn(nodesApiService, 'updateNode').and.returnValue(of({})); - node.entry.properties['qshare:sharedId'] = 'sharedId'; - node.entry.properties['qshare:sharedId'] = '2017-04-15T18:31:37+00:00'; - - component.data = { - node, - permission: true, - baseShareUrl: 'some-url/' - }; - - fixture.detectChanges(); - - component.form.controls['time'].setValue(moment()); - - fixture.detectChanges(); - - fixture.nativeElement - .querySelector( - '.mat-slide-toggle[data-automation-id="adf-expire-toggle"] label' - ) - .dispatchEvent(new MouseEvent('click')); - - fixture.detectChanges(); - - expect(nodesApiService.updateNode).toHaveBeenCalledWith('nodeId', { - properties: { 'qshare:expiryDate': null } - }); - - expect( - fixture.nativeElement.querySelector('input[formcontrolname="time"]').value - ).toBe(''); - }); - - it('should not allow expiration date action when node has no update permission', () => { - node.entry.properties['qshare:sharedId'] = 'sharedId'; - - component.data = { - node, - permission: false, - baseShareUrl: 'some-url/' - }; - - fixture.detectChanges(); - - expect( - fixture.nativeElement.querySelector('input[formcontrolname="time"]') - .disabled - ).toBe(true); - expect( - fixture.nativeElement.querySelector( - '.mat-slide-toggle[data-automation-id="adf-expire-toggle"]' - ).classList - ).toContain('mat-disabled'); - }); - - it('should show permission error notification on un-share action', () => { - node.entry.properties['qshare:sharedId'] = 'sharedId'; - spyOn(matDialog, 'open').and.returnValue({ beforeClose: () => of(true) }); - spyOn(sharedLinksApiService, 'deleteSharedLink').and.returnValue( - of(new Error('{"error": { "statusCode": 403 } }')) - ); - component.data = { - node, - permission: false, - baseShareUrl: 'some-url/' - }; - - fixture.detectChanges(); - - fixture.nativeElement - .querySelector( - '.mat-slide-toggle[data-automation-id="adf-share-toggle"] label' - ) - .dispatchEvent(new MouseEvent('click')); - - expect(storeMock.dispatch).toHaveBeenCalled(); - }); - - it('should update node expiration date with selected date and time', () => { - const date = moment(); - node.entry.properties['qshare:sharedId'] = 'sharedId'; - spyOn(nodesApiService, 'updateNode').and.returnValue(of({})); - fixture.componentInstance.form.controls['time'].setValue(null); - - component.data = { - node, - permission: true, - baseShareUrl: 'some-url/' - }; - - fixture.detectChanges(); - - fixture.nativeElement - .querySelector( - 'mat-slide-toggle[data-automation-id="adf-expire-toggle"] label' - ) - .dispatchEvent(new MouseEvent('click')); - - fixture.componentInstance.form.controls['time'].setValue(date); - fixture.detectChanges(); - - expect(nodesApiService.updateNode).toHaveBeenCalledWith('nodeId', { - properties: { 'qshare:expiryDate': date } - }); - }); -}); diff --git a/src/app/components/shared/content-node-share/content-node-share.dialog.ts b/src/app/components/shared/content-node-share/content-node-share.dialog.ts deleted file mode 100644 index 43455dfa25..0000000000 --- a/src/app/components/shared/content-node-share/content-node-share.dialog.ts +++ /dev/null @@ -1,255 +0,0 @@ -/*! - * @license - * Copyright 2019 Alfresco Software, Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { - Component, - Inject, - OnInit, - ViewEncapsulation, - ViewChild, - OnDestroy -} from '@angular/core'; -import { - MAT_DIALOG_DATA, - MatDialogRef, - MatDialog -} from '@angular/material/dialog'; -import { FormGroup, FormControl } from '@angular/forms'; -import { Subscription, Observable, throwError } from 'rxjs'; -import { AppStore, SnackbarErrorAction } from '@alfresco/aca-shared/store'; -import { Store } from '@ngrx/store'; -import { - skip, - mergeMap, - catchError, - distinctUntilChanged -} from 'rxjs/operators'; -import { SharedLinksApiService, NodesApiService } from '@alfresco/adf-core'; -import { SharedLinkEntry, MinimalNodeEntryEntity } from '@alfresco/js-api'; -import { ConfirmDialogComponent } from '@alfresco/adf-content-services'; -import * as moment from 'moment'; - -@Component({ - selector: 'aca-share-dialog', - templateUrl: './content-node-share.dialog.html', - styleUrls: ['./content-node-share.dialog.scss'], - host: { class: 'adf-share-dialog' }, - encapsulation: ViewEncapsulation.None -}) -export class ShareDialogComponent implements OnInit, OnDestroy { - private subscriptions: Subscription[] = []; - - minDate = moment().add(1, 'd'); - sharedId: string; - fileName: string; - baseShareUrl: string; - isFileShared = false; - isDisabled = false; - form: FormGroup = new FormGroup({ - sharedUrl: new FormControl(''), - time: new FormControl({ value: '', disabled: false }) - }); - - @ViewChild('matDatetimepickerToggle') - matDatetimepickerToggle; - - @ViewChild('slideToggleExpirationDate') - slideToggleExpirationDate; - - @ViewChild('dateTimePickerInput') - dateTimePickerInput; - - constructor( - private sharedLinksApiService: SharedLinksApiService, - private dialogRef: MatDialogRef, - private dialog: MatDialog, - private nodesApiService: NodesApiService, - private store: Store, - @Inject(MAT_DIALOG_DATA) public data: any - ) {} - - ngOnInit() { - if (!this.canUpdate) { - this.form.controls['time'].disable(); - } - - this.subscriptions.push( - this.form.controls.time.valueChanges - .pipe( - skip(1), - distinctUntilChanged(), - mergeMap( - updates => this.updateNode(updates), - formUpdates => formUpdates - ), - catchError(error => { - return throwError(error); - }) - ) - .subscribe(updates => { - this.updateEntryExpiryDate(updates); - }) - ); - - if (this.data.node && this.data.node.entry) { - this.fileName = this.data.node.entry.name; - this.baseShareUrl = this.data.baseShareUrl; - const properties = this.data.node.entry.properties; - - if (!properties || !properties['qshare:sharedId']) { - this.createSharedLinks(this.data.node.entry.id); - } else { - this.sharedId = properties['qshare:sharedId']; - this.isFileShared = true; - - this.updateForm(); - } - } - } - - ngOnDestroy() { - this.subscriptions.forEach(subscription => subscription.unsubscribe); - } - - onSlideShareChange() { - this.openConfirmationDialog(); - } - - get canUpdate() { - return this.data.permission; - } - - onToggleExpirationDate(slideToggle) { - if (slideToggle.checked) { - this.matDatetimepickerToggle.datetimepicker.open(); - } else { - this.matDatetimepickerToggle.datetimepicker.close(); - this.form.controls.time.setValue(null); - } - } - - onDatetimepickerClosed() { - this.dateTimePickerInput.nativeElement.blur(); - - if (!this.form.controls.time.value) { - this.slideToggleExpirationDate.checked = false; - } - } - - private openConfirmationDialog() { - this.isFileShared = false; - - this.dialog - .open(ConfirmDialogComponent, { - data: { - title: 'SHARE.CONFIRMATION.DIALOG-TITLE', - message: 'SHARE.CONFIRMATION.MESSAGE', - yesLabel: 'SHARE.CONFIRMATION.REMOVE', - noLabel: 'SHARE.CONFIRMATION.CANCEL' - }, - minWidth: '250px', - closeOnNavigation: true - }) - .beforeClose() - .subscribe(deleteSharedLink => { - if (deleteSharedLink) { - this.deleteSharedLink(this.sharedId); - } else { - this.isFileShared = true; - } - }); - } - - private createSharedLinks(nodeId: string) { - this.isDisabled = true; - - this.sharedLinksApiService.createSharedLinks(nodeId).subscribe( - (sharedLink: SharedLinkEntry) => { - if (sharedLink.entry) { - this.sharedId = sharedLink.entry.id; - if (this.data.node.entry.properties) { - this.data.node.entry.properties['qshare:sharedId'] = this.sharedId; - } else { - this.data.node.entry.properties = { - 'qshare:sharedId': this.sharedId - }; - } - this.isDisabled = false; - this.isFileShared = true; - - this.updateForm(); - } - }, - () => { - this.isDisabled = false; - this.isFileShared = false; - } - ); - } - - private deleteSharedLink(sharedId: string) { - this.isDisabled = true; - - this.sharedLinksApiService - .deleteSharedLink(sharedId) - .subscribe((response: any) => { - if (response instanceof Error) { - this.isDisabled = false; - this.isFileShared = true; - this.showError(response); - } else { - this.data.node.entry.properties['qshare:sharedId'] = null; - this.data.node.entry.properties['qshare:expiryDate'] = null; - this.dialogRef.close(this.data.node); - } - }); - } - - private updateForm() { - const { entry } = this.data.node; - const expiryDate = entry.properties['qshare:expiryDate']; - - this.form.setValue({ - sharedUrl: `${this.baseShareUrl}${this.sharedId}`, - time: expiryDate ? expiryDate : null - }); - } - - private updateNode(date: moment.Moment): Observable { - return this.nodesApiService.updateNode(this.data.node.entry.id, { - properties: { - 'qshare:expiryDate': date ? date.endOf('day') : null - } - }); - } - - private updateEntryExpiryDate(date: moment.Moment) { - const { properties } = this.data.node.entry; - - properties['qshare:expiryDate'] = date ? date.toDate() : null; - } - - private showError(response: { message: any }) { - let message; - const statusCode = JSON.parse(response.message).error.statusCode; - if (statusCode === 403) { - message = 'SHARED_LINK.UNSHARE_PERMISSION_ERROR'; - } - - this.store.dispatch(new SnackbarErrorAction(message)); - } -} diff --git a/src/app/components/shared/content-node-share/content-node-share.module.ts b/src/app/components/shared/content-node-share/content-node-share.module.ts deleted file mode 100644 index eef58ca1a7..0000000000 --- a/src/app/components/shared/content-node-share/content-node-share.module.ts +++ /dev/null @@ -1,41 +0,0 @@ -/*! - * @license - * Copyright 2019 Alfresco Software, Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { NgModule, ModuleWithProviders } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { CoreModule } from '@alfresco/adf-core'; -import { ShareDialogComponent } from './content-node-share.dialog'; - -@NgModule({ - imports: [CoreModule.forChild(), CommonModule], - declarations: [ShareDialogComponent], - exports: [ShareDialogComponent], - entryComponents: [ShareDialogComponent] -}) -export class ContentNodeShareModule { - static forRoot(): ModuleWithProviders { - return { - ngModule: ContentNodeShareModule - }; - } - - static forChild(): ModuleWithProviders { - return { - ngModule: ContentNodeShareModule - }; - } -} diff --git a/src/app/components/shared/shared.module.ts b/src/app/components/shared/shared.module.ts deleted file mode 100644 index 06139e7acd..0000000000 --- a/src/app/components/shared/shared.module.ts +++ /dev/null @@ -1,44 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2019 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { CoreModule } from '@alfresco/adf-core'; -import { ExtensionsModule } from '@alfresco/adf-extensions'; -import { ToggleSharedModule } from './toggle-shared/toggle-shared.module'; -import { ContentNodeShareModule } from './content-node-share/content-node-share.module'; -import { ShareDialogComponent } from './content-node-share/content-node-share.dialog'; - -@NgModule({ - imports: [ - CommonModule, - CoreModule.forChild(), - ExtensionsModule, - ContentNodeShareModule, - ToggleSharedModule - ], - entryComponents: [ShareDialogComponent] -}) -export class AppSharedModule {} diff --git a/src/app/components/shared/toggle-shared/toggle-shared.module.ts b/src/app/components/shared/toggle-shared/toggle-shared.module.ts deleted file mode 100644 index a9a0e7b76f..0000000000 --- a/src/app/components/shared/toggle-shared/toggle-shared.module.ts +++ /dev/null @@ -1,48 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2019 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { CoreModule } from '@alfresco/adf-core'; -import { ContentNodeShareModule } from '@alfresco/adf-content-services'; -import { ExtensionsModule } from '@alfresco/adf-extensions'; -import { ToggleSharedComponent } from './toggle-shared.component'; - -export function components() { - return [ToggleSharedComponent]; -} - -@NgModule({ - imports: [ - CommonModule, - CoreModule.forChild(), - ExtensionsModule, - ContentNodeShareModule - ], - declarations: components(), - exports: components(), - entryComponents: components() -}) -export class ToggleSharedModule {} diff --git a/src/app/extensions/core.extensions.module.ts b/src/app/extensions/core.extensions.module.ts index 7bd1006410..b7a318d5c9 100644 --- a/src/app/extensions/core.extensions.module.ts +++ b/src/app/extensions/core.extensions.module.ts @@ -32,7 +32,6 @@ import { AppExtensionService } from './extension.service'; import { ToggleInfoDrawerComponent } from '../components/toolbar/toggle-info-drawer/toggle-info-drawer.component'; import { ToggleFavoriteComponent } from '../components/toolbar/toggle-favorite/toggle-favorite.component'; import { ToggleFavoriteLibraryComponent } from '../components/toolbar/toggle-favorite-library/toggle-favorite-library.component'; -import { ToggleSharedComponent } from '../components/shared/toggle-shared/toggle-shared.component'; import { MetadataTabComponent } from '../components/info-drawer/metadata-tab/metadata-tab.component'; import { LibraryMetadataTabComponent } from '../components/info-drawer/library-metadata-tab/library-metadata-tab.component'; import { CommentsTabComponent } from '../components/info-drawer/comments-tab/comments-tab.component'; @@ -50,6 +49,7 @@ import { TrashcanNameColumnComponent, LibraryRoleColumnComponent } from '@alfresco/adf-content-services'; +import { ToggleSharedComponent } from '../components/common/toggle-shared/toggle-shared.component'; export function setupExtensions(service: AppExtensionService): Function { return () => service.load(); diff --git a/src/app/services/content-management.service.ts b/src/app/services/content-management.service.ts index 91ec3c779b..5b57b4065f 100644 --- a/src/app/services/content-management.service.ts +++ b/src/app/services/content-management.service.ts @@ -45,7 +45,8 @@ import { import { ConfirmDialogComponent, FolderDialogComponent, - LibraryDialogComponent + LibraryDialogComponent, + ShareDialogComponent } from '@alfresco/adf-content-services'; import { TranslationService } from '@alfresco/adf-core'; import { @@ -65,7 +66,6 @@ import { Store } from '@ngrx/store'; import { forkJoin, Observable, of, Subject, zip } from 'rxjs'; import { catchError, flatMap, map, mergeMap, take, tap } from 'rxjs/operators'; import { NodePermissionsDialogComponent } from '../components/permissions/permission-dialog/node-permissions.dialog'; -import { ShareDialogComponent } from '../components/shared/content-node-share/content-node-share.dialog'; import { NodeVersionUploadDialogComponent } from '../dialogs/node-version-upload/node-version-upload.dialog'; import { NodeVersionsDialogComponent } from '../dialogs/node-versions/node-versions.dialog'; import { NodeActionsService } from './node-actions.service'; @@ -208,7 +208,6 @@ export class ContentManagementService { width: '600px', panelClass: 'adf-share-link-dialog', data: { - permission: this.permission.check(node, ['update']), node, baseShareUrl } diff --git a/src/app/ui/theme.scss b/src/app/ui/theme.scss index be8881e7f4..c2b968d9d5 100644 --- a/src/app/ui/theme.scss +++ b/src/app/ui/theme.scss @@ -17,4 +17,16 @@ $theme: mat-light-theme($primary, $accent, $warn); @include adf-content-services-theme($theme); @include adf-core-theme($theme); +// fixes [ACA-2069] +$primary: map-get($theme, primary); +.mat-slide-toggle.mat-primary.mat-checked:not(.mat-disabled) { + .mat-slide-toggle-thumb, + .mat-slide-toggle-ripple .mat-ripple-element { + background-color: mat-color($primary); + } + .mat-slide-toggle-bar { + background-color: mat-color($primary, 0.54); + } +} + @include custom-theme($custom-theme); From e6b959df7b7aabaf75f333b93a940b08c51489ae Mon Sep 17 00:00:00 2001 From: Suzana Dirla Date: Fri, 14 Jun 2019 18:13:20 +0300 Subject: [PATCH 221/259] [ACA-2472] Temporarily disable "Emailed" and "Likes" properties (#1130) * [ACA-2472] Temporarily disable "Emailed" and "Likes" aspects * [ACA-2472] keep the app.config metadata config in sync with app.extensions - testing purpose in case we remove the metadata config from app.extensions --- src/app.config.json | 5 ++++- src/assets/app.extensions.json | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/app.config.json b/src/app.config.json index e82941ab9e..374757a36a 100644 --- a/src/app.config.json +++ b/src/app.config.json @@ -132,7 +132,10 @@ "qshare:shared", "exif:exif", - "cm:effectivity" + "cm:effectivity", + + "cm:emailed", + "cm:likesRatingSchemeRollups" ] }, { diff --git a/src/assets/app.extensions.json b/src/assets/app.extensions.json index c7f05b0e70..99a11336f9 100644 --- a/src/assets/app.extensions.json +++ b/src/assets/app.extensions.json @@ -1047,7 +1047,10 @@ "qshare:shared", "exif:exif", - "cm:effectivity" + "cm:effectivity", + + "cm:emailed", + "cm:likesRatingSchemeRollups" ] }, { From 5491545ac9eddb8dd795aa65bc328ea14167a378 Mon Sep 17 00:00:00 2001 From: dhrn <14145706+dhrn@users.noreply.github.com> Date: Sat, 15 Jun 2019 08:47:59 +0530 Subject: [PATCH 222/259] [ACA-2471] - close preview action (#1129) --- docs/extending/application-actions.md | 1 + .../store/src/actions/viewer.actions.ts | 8 ++++++- proxy.conf.js | 22 +++++++++---------- .../preview/preview.component.spec.ts | 11 ++++++++++ .../components/preview/preview.component.ts | 19 +++++++++++++--- 5 files changed, 46 insertions(+), 15 deletions(-) diff --git a/docs/extending/application-actions.md b/docs/extending/application-actions.md index 122f28ec1a..f1bbb5da99 100644 --- a/docs/extending/application-actions.md +++ b/docs/extending/application-actions.md @@ -122,3 +122,4 @@ Below is the list of public actions types you can use in the plugin definitions | 1.7.0 | SHOW_SEARCH_FILTER | n/a | Show Filter component in Search Results. | | 1.7.0 | HIDE_SEARCH_FILTER | n/a | Hide Filter component in Search Results | | 1.8.0 | VIEW_NODE | string | Lightweight preview of a node by id. Can be invoked from extensions. | +| 1.8.0 | CLOSE_PREVIEW | n/a | Closes the viewer ( preview of the item ) | diff --git a/projects/aca-shared/store/src/actions/viewer.actions.ts b/projects/aca-shared/store/src/actions/viewer.actions.ts index 1e878b13a4..0dae7f87ea 100644 --- a/projects/aca-shared/store/src/actions/viewer.actions.ts +++ b/projects/aca-shared/store/src/actions/viewer.actions.ts @@ -29,7 +29,8 @@ import { MinimalNodeEntity } from '@alfresco/js-api'; export enum ViewerActionTypes { ViewFile = 'VIEW_FILE', ViewNode = 'VIEW_NODE', - FullScreen = 'FULLSCREEN_VIEWER' + FullScreen = 'FULLSCREEN_VIEWER', + ClosePreview = 'CLOSE_PREVIEW' } export class ViewFileAction implements Action { @@ -49,3 +50,8 @@ export class FullscreenViewerAction implements Action { constructor(public payload: MinimalNodeEntity) {} } + +export class ClosePreviewAction implements Action { + readonly type = ViewerActionTypes.ClosePreview; + constructor(public payload?: MinimalNodeEntity) {} +} diff --git a/proxy.conf.js b/proxy.conf.js index 5bea784f0b..26a361bd35 100644 --- a/proxy.conf.js +++ b/proxy.conf.js @@ -1,14 +1,14 @@ module.exports = { - "/alfresco": { - "target": "http://0.0.0.0:8080", - "secure": false, - "changeOrigin": true, - // workaround for REPO-2260 - onProxyRes: function (proxyRes, req, res) { - const header = proxyRes.headers['www-authenticate']; - if (header && header.startsWith('Basic')) { - proxyRes.headers['www-authenticate'] = 'x' + header; - } - } + '/alfresco': { + target: 'http://0.0.0.0:8080', + secure: false, + changeOrigin: true, + // workaround for REPO-2260 + onProxyRes: function(proxyRes, req, res) { + const header = proxyRes.headers['www-authenticate']; + if (header && header.startsWith('Basic')) { + proxyRes.headers['www-authenticate'] = 'x' + header; + } } + } }; diff --git a/src/app/components/preview/preview.component.spec.ts b/src/app/components/preview/preview.component.spec.ts index fcac4d2f47..544eda545c 100644 --- a/src/app/components/preview/preview.component.spec.ts +++ b/src/app/components/preview/preview.component.spec.ts @@ -39,6 +39,7 @@ import { UploadService, AlfrescoApiService } from '@alfresco/adf-core'; +import { ClosePreviewAction } from '@alfresco/aca-shared/store'; import { PreviewComponent } from './preview.component'; import { of, throwError } from 'rxjs'; import { EffectsModule } from '@ngrx/effects'; @@ -46,6 +47,7 @@ import { NodeEffects } from '../../store/effects/node.effects'; import { AppTestingModule } from '../../testing/app-testing.module'; import { ContentApiService } from '@alfresco/aca-shared'; import { ContentManagementService } from '../../services/content-management.service'; +import { Store } from '@ngrx/store'; describe('PreviewComponent', () => { let fixture: ComponentFixture; @@ -57,6 +59,7 @@ describe('PreviewComponent', () => { let uploadService: UploadService; let alfrescoApiService: AlfrescoApiService; let contentManagementService: ContentManagementService; + let store: Store; beforeEach(() => { TestBed.configureTestingModule({ @@ -76,6 +79,7 @@ describe('PreviewComponent', () => { uploadService = TestBed.get(UploadService); alfrescoApiService = TestBed.get(AlfrescoApiService); contentManagementService = TestBed.get(ContentManagementService); + store = TestBed.get(Store); }); it('should extract the property path root', () => { @@ -732,4 +736,11 @@ describe('PreviewComponent', () => { expect(alfrescoApiService.nodeUpdated.next).toHaveBeenCalled(); })); + + it('should return to parent folder when event emitted from extension', async(() => { + spyOn(component, 'navigateToFileLocation'); + fixture.detectChanges(); + store.dispatch(new ClosePreviewAction()); + expect(component.navigateToFileLocation).toHaveBeenCalled(); + })); }); diff --git a/src/app/components/preview/preview.component.ts b/src/app/components/preview/preview.component.ts index 97fdf7f935..3a451aa3fd 100644 --- a/src/app/components/preview/preview.component.ts +++ b/src/app/components/preview/preview.component.ts @@ -38,7 +38,7 @@ import { UrlSegment, PRIMARY_OUTLET } from '@angular/router'; -import { debounceTime, takeUntil } from 'rxjs/operators'; +import { debounceTime, map, takeUntil } from 'rxjs/operators'; import { UserPreferencesService, ObjectUtils, @@ -46,7 +46,11 @@ import { AlfrescoApiService } from '@alfresco/adf-core'; import { Store } from '@ngrx/store'; -import { AppStore } from '@alfresco/aca-shared/store'; +import { + AppStore, + ClosePreviewAction, + ViewerActionTypes +} from '@alfresco/aca-shared/store'; import { SetSelectedNodesAction } from '@alfresco/aca-shared/store'; import { PageComponent } from '../page.component'; import { ContentApiService } from '@alfresco/aca-shared'; @@ -55,6 +59,7 @@ import { ContentManagementService } from '../../services/content-management.serv import { ContentActionRef, ViewerExtensionRef } from '@alfresco/adf-extensions'; import { SearchRequest } from '@alfresco/js-api'; import { from } from 'rxjs'; +import { Actions, ofType } from '@ngrx/effects'; @Component({ selector: 'app-preview', @@ -115,6 +120,7 @@ export class PreviewComponent extends PageComponent private router: Router, private apiService: AlfrescoApiService, private uploadService: UploadService, + private actions$: Actions, store: Store, extensions: AppExtensionService, content: ContentManagementService @@ -167,7 +173,14 @@ export class PreviewComponent extends PageComponent this.uploadService.fileUploadComplete .pipe(debounceTime(300)) - .subscribe(file => this.apiService.nodeUpdated.next(file.data.entry)) + .subscribe(file => this.apiService.nodeUpdated.next(file.data.entry)), + + this.actions$ + .pipe( + ofType(ViewerActionTypes.ClosePreview), + map(() => this.navigateToFileLocation(true)) + ) + .subscribe(() => {}) ]); this.openWith = this.extensions.openWithActions; From aeffbe91b1da773fe042ac41a93980e14b7162fd Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Mon, 17 Jun 2019 11:34:05 +0300 Subject: [PATCH 223/259] manually import locales (#1131) --- src/app.config.json | 5 +++++ src/app/app.module.ts | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/src/app.config.json b/src/app.config.json index 374757a36a..82009a368f 100644 --- a/src/app.config.json +++ b/src/app.config.json @@ -33,6 +33,11 @@ "nocase": true } }, + "dateValues": { + "defaultDateFormat": "mediumDate", + "defaultDateTimeFormat": "MMM d, y, h:mm", + "defaultLocale": "en-US" + }, "adf-version-manager": { "allowComments": true, "allowDownload": true diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 9ef973b2b6..bdb487aff8 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -75,6 +75,41 @@ import { AppHeaderModule } from './components/header/header.module'; import { AppNodeVersionModule } from './components/node-version/node-version.module'; import { environment } from '../environments/environment'; +import { registerLocaleData } from '@angular/common'; +import localeFr from '@angular/common/locales/fr'; +import localeDe from '@angular/common/locales/de'; +import localeIt from '@angular/common/locales/it'; +import localeEs from '@angular/common/locales/es'; +import localeJa from '@angular/common/locales/ja'; +import localeNl from '@angular/common/locales/nl'; +import localePt from '@angular/common/locales/pt'; +import localeNb from '@angular/common/locales/nb'; +import localeRu from '@angular/common/locales/ru'; +import localeCh from '@angular/common/locales/zh'; +import localeAr from '@angular/common/locales/ar'; +import localeCs from '@angular/common/locales/cs'; +import localePl from '@angular/common/locales/pl'; +import localeFi from '@angular/common/locales/fi'; +import localeDa from '@angular/common/locales/da'; +import localeSv from '@angular/common/locales/sv'; + +registerLocaleData(localeFr); +registerLocaleData(localeDe); +registerLocaleData(localeIt); +registerLocaleData(localeEs); +registerLocaleData(localeJa); +registerLocaleData(localeNl); +registerLocaleData(localePt); +registerLocaleData(localeNb); +registerLocaleData(localeRu); +registerLocaleData(localeCh); +registerLocaleData(localeAr); +registerLocaleData(localeCs); +registerLocaleData(localePl); +registerLocaleData(localeFi); +registerLocaleData(localeDa); +registerLocaleData(localeSv); + @NgModule({ imports: [ BrowserModule, From 8f145862eed5d3682927e83f0ac02da63849c6c3 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Mon, 17 Jun 2019 09:39:23 +0100 Subject: [PATCH 224/259] bump aca-shared version --- projects/aca-shared/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/aca-shared/package.json b/projects/aca-shared/package.json index 5735ef082b..40c18dcdf8 100644 --- a/projects/aca-shared/package.json +++ b/projects/aca-shared/package.json @@ -1,6 +1,6 @@ { "name": "@alfresco/aca-shared", - "version": "1.8.2", + "version": "1.8.3", "peerDependencies": { "@angular/common": "^7.2.0", "@angular/core": "^7.2.0", From 3bc54478c0a2c324694150a4227bc5319b8b67a2 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Tue, 18 Jun 2019 15:21:03 +0100 Subject: [PATCH 225/259] latest ADF alpha (#1132) * latest ADF alpha * get latest adf * update tests * use date format via config * update time format * Revert "update time format" This reverts commit 3a4864ef01e8e1f6bc89d7425ffa7b6051dc19a6. --- .vscode/extensions.json | 2 +- e2e/configs.ts | 4 ++ .../file-folder-properties.test.ts | 12 +++--- package-lock.json | 41 +++++++++++-------- package.json | 6 +-- 5 files changed, 38 insertions(+), 27 deletions(-) diff --git a/.vscode/extensions.json b/.vscode/extensions.json index a398c3a8a4..376a66e9ef 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,6 +1,6 @@ { "recommendations": [ - "eg2.tslint", + "ms-vscode.vscode-typescript-tslint-plugin", "angular.ng-template", "streetsidesoftware.code-spell-checker", "peterjausovec.vscode-docker", diff --git a/e2e/configs.ts b/e2e/configs.ts index fe21ffde5f..9b3997d77e 100755 --- a/e2e/configs.ts +++ b/e2e/configs.ts @@ -42,6 +42,10 @@ export const ADMIN_FULL_NAME = 'Administrator'; export const E2E_ROOT_PATH = __dirname; +// Dates +export const DATE_FORMAT = 'MMM DD, YYYY'; +export const DATE_TIME_FORMAT = 'MMM D, YYYY, h:mm'; + // Application Routes export const APP_ROUTES = { FAVORITES: '/favorites', diff --git a/e2e/suites/info-drawer/file-folder-properties.test.ts b/e2e/suites/info-drawer/file-folder-properties.test.ts index 16ac67113c..d26ad95b1c 100755 --- a/e2e/suites/info-drawer/file-folder-properties.test.ts +++ b/e2e/suites/info-drawer/file-folder-properties.test.ts @@ -27,7 +27,7 @@ import { LoginPage, BrowsingPage } from '../../pages/pages'; import { RepoClient } from '../../utilities/repo-client/repo-client'; import { InfoDrawer } from './../../components/info-drawer/info-drawer'; import { Utils } from '../../utilities/utils'; -import { FILES } from '../../configs'; +import { FILES, DATE_TIME_FORMAT, DATE_FORMAT } from '../../configs'; import * as moment from 'moment'; describe('File / Folder properties', () => { @@ -124,10 +124,10 @@ describe('File / Folder properties', () => { file1.name, file1.title, apiProps.entry.createdByUser.displayName, - moment(apiProps.entry.createdAt).format('MMM DD YYYY'), + moment(apiProps.entry.createdAt).format(DATE_FORMAT), `${apiProps.entry.content.sizeInBytes} Bytes`, apiProps.entry.modifiedByUser.displayName, - moment(apiProps.entry.modifiedAt).format('MMM DD YYYY'), + moment(apiProps.entry.modifiedAt).format(DATE_FORMAT), apiProps.entry.content.mimeTypeName, file1.author, file1.description @@ -160,9 +160,9 @@ describe('File / Folder properties', () => { folder1.name, folder1.title, apiProps.entry.createdByUser.displayName, - moment(apiProps.entry.createdAt).format('MMM DD YYYY'), + moment(apiProps.entry.createdAt).format(DATE_FORMAT), apiProps.entry.modifiedByUser.displayName, - moment(apiProps.entry.modifiedAt).format('MMM DD YYYY'), + moment(apiProps.entry.modifiedAt).format(DATE_FORMAT), folder1.author, folder1.description ]; @@ -218,7 +218,7 @@ describe('File / Folder properties', () => { const expectedPropValues = [ apiProps.entry.properties['exif:pixelXDimension'].toString(), apiProps.entry.properties['exif:pixelYDimension'].toString(), - moment(apiProps.entry.properties['exif:dateTimeOriginal']).format('MMM DD YYYY H:mm'), + moment(apiProps.entry.properties['exif:dateTimeOriginal']).format(DATE_TIME_FORMAT), apiProps.entry.properties['exif:exposureTime'].toString(), apiProps.entry.properties['exif:fNumber'].toString(), apiProps.entry.properties['exif:flash'], diff --git a/package-lock.json b/package-lock.json index d9f90e2226..4a684131fe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,25 +5,25 @@ "requires": true, "dependencies": { "@alfresco/adf-content-services": { - "version": "3.3.0-626bb01bf7d26e693a4947982d20695c45794503", - "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-3.3.0-626bb01bf7d26e693a4947982d20695c45794503.tgz", - "integrity": "sha512-2Y2VPvSxXxlhBJoKLQo9NGy0r9paAnAweXIi9EiuZctLNFDAzG2UVDb93gGhtcAi+ulH5xyoRu/9mDIpE4e5ew==", + "version": "3.3.0-d6c33732989b9d38e3f6e128fe195ac742e78825", + "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-3.3.0-d6c33732989b9d38e3f6e128fe195ac742e78825.tgz", + "integrity": "sha512-WVfTlxtoMupoQpSM+5RHY475RYDXwblYJt8nvS/vGB6P76n/UThyH2semfJgU/KEu7xf2kzFynpIEZABLu/Fxg==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/adf-core": { - "version": "3.3.0-626bb01bf7d26e693a4947982d20695c45794503", - "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-3.3.0-626bb01bf7d26e693a4947982d20695c45794503.tgz", - "integrity": "sha512-mEL+/0udJ1R4vnb8UK6QsdLRd/PPMo1q1esTYUAu0in0TR6PesqBiTMAtmj5sVV40IIeW7u7kD/TpZNBRDlxrg==", + "version": "3.3.0-d6c33732989b9d38e3f6e128fe195ac742e78825", + "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-3.3.0-d6c33732989b9d38e3f6e128fe195ac742e78825.tgz", + "integrity": "sha512-3LLEBPMSkPyjqz8xYmibPQCs3eshjC3uLahjkRjqBH+wxGA70N3BaIvzqFTV4vBlWcQ71AKbze891zh8Uzp0UA==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/adf-extensions": { - "version": "3.3.0-626bb01bf7d26e693a4947982d20695c45794503", - "resolved": "https://registry.npmjs.org/@alfresco/adf-extensions/-/adf-extensions-3.3.0-626bb01bf7d26e693a4947982d20695c45794503.tgz", - "integrity": "sha512-qh2xdGTeNBvh7QzScvaYxHxvoTld5bCwDRIUKNj+Dt+C3aaAs5mdN85hTVQ82+vNptD8NO9nCBaS/CR5ISwt9Q==", + "version": "3.3.0-d6c33732989b9d38e3f6e128fe195ac742e78825", + "resolved": "https://registry.npmjs.org/@alfresco/adf-extensions/-/adf-extensions-3.3.0-d6c33732989b9d38e3f6e128fe195ac742e78825.tgz", + "integrity": "sha512-LWtgNi6hnVWgMUIEeE7qWVEdcGbe76faLuwUykA/4M5tv09NIGMwsq8shbogkC6cTiDFJzF4dADrS9WgEIdBYQ==", "requires": { "tslib": "^1.9.0" } @@ -4204,11 +4204,12 @@ }, "dependencies": { "d": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", - "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", "requires": { - "es5-ext": "^0.10.9" + "es5-ext": "^0.10.50", + "type": "^1.0.1" } } } @@ -4238,11 +4239,12 @@ }, "dependencies": { "d": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", - "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", "requires": { - "es5-ext": "^0.10.9" + "es5-ext": "^0.10.50", + "type": "^1.0.1" } } } @@ -12605,6 +12607,11 @@ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", "dev": true }, + "type": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/type/-/type-1.0.1.tgz", + "integrity": "sha512-MAM5dBMJCJNKs9E7JXo4CXRAansRfG0nlJxW7Wf6GZzSOvH31zClSaHdIMWLehe/EGMBkqeC55rrkaOr5Oo7Nw==" + }, "type-fest": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.4.1.tgz", diff --git a/package.json b/package.json index 309acd06e1..3a3f44bc00 100644 --- a/package.json +++ b/package.json @@ -36,9 +36,9 @@ }, "private": true, "dependencies": { - "@alfresco/adf-content-services": "3.3.0-626bb01bf7d26e693a4947982d20695c45794503", - "@alfresco/adf-core": "3.3.0-626bb01bf7d26e693a4947982d20695c45794503", - "@alfresco/adf-extensions": "3.3.0-626bb01bf7d26e693a4947982d20695c45794503", + "@alfresco/adf-content-services": "3.3.0-d6c33732989b9d38e3f6e128fe195ac742e78825", + "@alfresco/adf-core": "3.3.0-d6c33732989b9d38e3f6e128fe195ac742e78825", + "@alfresco/adf-extensions": "3.3.0-d6c33732989b9d38e3f6e128fe195ac742e78825", "@alfresco/js-api": "3.2.1", "@angular/animations": "7.2.15", "@angular/cdk": "^7.3.7", From 2cf42376c333f461d77e5aed94394ef6cd41391e Mon Sep 17 00:00:00 2001 From: Suzana Dirla Date: Wed, 19 Jun 2019 20:57:06 +0300 Subject: [PATCH 226/259] [ACA-2640] Exclude problematic aspects (#1133) --- src/app.config.json | 4 +++- src/assets/app.extensions.json | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/app.config.json b/src/app.config.json index 82009a368f..aa884960df 100644 --- a/src/app.config.json +++ b/src/app.config.json @@ -140,7 +140,9 @@ "cm:effectivity", "cm:emailed", - "cm:likesRatingSchemeRollups" + "cm:likesRatingSchemeRollups", + "cm:lockable", + "cm:ownable" ] }, { diff --git a/src/assets/app.extensions.json b/src/assets/app.extensions.json index 99a11336f9..b7e12a3b87 100644 --- a/src/assets/app.extensions.json +++ b/src/assets/app.extensions.json @@ -1050,7 +1050,9 @@ "cm:effectivity", "cm:emailed", - "cm:likesRatingSchemeRollups" + "cm:likesRatingSchemeRollups", + "cm:lockable", + "cm:ownable" ] }, { From cab4196872200551445c97d7f7afaea070c0c5fe Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Wed, 19 Jun 2019 21:02:36 +0100 Subject: [PATCH 227/259] upgrade to the ADF release 3.3.0 (#1134) * upgrade to the ADF release 3.3.0 * update e2e config --- e2e/configs.ts | 2 +- package-lock.json | 24 ++++++++++++------------ package.json | 8 ++++---- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/e2e/configs.ts b/e2e/configs.ts index 9b3997d77e..cfc0835c6a 100755 --- a/e2e/configs.ts +++ b/e2e/configs.ts @@ -44,7 +44,7 @@ export const E2E_ROOT_PATH = __dirname; // Dates export const DATE_FORMAT = 'MMM DD, YYYY'; -export const DATE_TIME_FORMAT = 'MMM D, YYYY, h:mm'; +export const DATE_TIME_FORMAT = 'MMM D, YYYY, H:mm'; // Application Routes export const APP_ROUTES = { diff --git a/package-lock.json b/package-lock.json index 4a684131fe..ee559b0e51 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,33 +5,33 @@ "requires": true, "dependencies": { "@alfresco/adf-content-services": { - "version": "3.3.0-d6c33732989b9d38e3f6e128fe195ac742e78825", - "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-3.3.0-d6c33732989b9d38e3f6e128fe195ac742e78825.tgz", - "integrity": "sha512-WVfTlxtoMupoQpSM+5RHY475RYDXwblYJt8nvS/vGB6P76n/UThyH2semfJgU/KEu7xf2kzFynpIEZABLu/Fxg==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-3.3.0.tgz", + "integrity": "sha512-VzEqJC+e2CYtFSwSJDXI8PR7xFCozsV113CpLEW9GT1rcNOyZrwQUe1MZqD3iNJzZdtsw+VI1kfsOwX9v0LNeA==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/adf-core": { - "version": "3.3.0-d6c33732989b9d38e3f6e128fe195ac742e78825", - "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-3.3.0-d6c33732989b9d38e3f6e128fe195ac742e78825.tgz", - "integrity": "sha512-3LLEBPMSkPyjqz8xYmibPQCs3eshjC3uLahjkRjqBH+wxGA70N3BaIvzqFTV4vBlWcQ71AKbze891zh8Uzp0UA==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-3.3.0.tgz", + "integrity": "sha512-OKjG0FduZWj/Ux4O/hKtvz4opWCLrrRP0bsQfRPMfNymIUlHHhS12ciPVSlKaVlozrJ4poyjq8maGa8gqSDMcA==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/adf-extensions": { - "version": "3.3.0-d6c33732989b9d38e3f6e128fe195ac742e78825", - "resolved": "https://registry.npmjs.org/@alfresco/adf-extensions/-/adf-extensions-3.3.0-d6c33732989b9d38e3f6e128fe195ac742e78825.tgz", - "integrity": "sha512-LWtgNi6hnVWgMUIEeE7qWVEdcGbe76faLuwUykA/4M5tv09NIGMwsq8shbogkC6cTiDFJzF4dADrS9WgEIdBYQ==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@alfresco/adf-extensions/-/adf-extensions-3.3.0.tgz", + "integrity": "sha512-Fvet22KpZ8zLGKccgsjlf9uEE2+47h0QMDMSX1S4tMbLlLs34PpHQiYNPOEKZgeV/kWx0+nhM7QhQUfH8NpRUA==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/js-api": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/@alfresco/js-api/-/js-api-3.2.1.tgz", - "integrity": "sha512-qaXftaHqFonWRKRmYxhB2/bEpUh5fvUj6cN+xuKUXIGgt9XxF76NpWkXnEEQLZ0BWg5upd19Q3N1x4E7DiNGUg==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@alfresco/js-api/-/js-api-3.3.0.tgz", + "integrity": "sha512-A15Q5j4jVNFUI0hdw0zIGonU05Wbjvq8ZJBijrkC3fq904oYuq49giKpPkbXjowk9xBfZZejGvaDMT5jYTXlxg==", "requires": { "event-emitter": "0.3.4", "superagent": "3.8.2" diff --git a/package.json b/package.json index 3a3f44bc00..c9b631e236 100644 --- a/package.json +++ b/package.json @@ -36,10 +36,10 @@ }, "private": true, "dependencies": { - "@alfresco/adf-content-services": "3.3.0-d6c33732989b9d38e3f6e128fe195ac742e78825", - "@alfresco/adf-core": "3.3.0-d6c33732989b9d38e3f6e128fe195ac742e78825", - "@alfresco/adf-extensions": "3.3.0-d6c33732989b9d38e3f6e128fe195ac742e78825", - "@alfresco/js-api": "3.2.1", + "@alfresco/adf-content-services": "3.3.0", + "@alfresco/adf-core": "3.3.0", + "@alfresco/adf-extensions": "3.3.0", + "@alfresco/js-api": "3.3.0", "@angular/animations": "7.2.15", "@angular/cdk": "^7.3.7", "@angular/common": "7.2.15", From 42c78e6fa6ef2e74f4875da5f1192cb85b5c7654 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Thu, 20 Jun 2019 09:24:25 +0100 Subject: [PATCH 228/259] update recommended extensions --- .vscode/extensions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 376a66e9ef..3a7af4412e 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -3,7 +3,7 @@ "ms-vscode.vscode-typescript-tslint-plugin", "angular.ng-template", "streetsidesoftware.code-spell-checker", - "peterjausovec.vscode-docker", + "ms-azuretools.vscode-docker", "editorconfig.editorconfig", "davidanson.vscode-markdownlint", "esbenp.prettier-vscode", From 900d002a08b218dbd49dec905ee8608ce9a0c171 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Thu, 20 Jun 2019 10:28:41 +0100 Subject: [PATCH 229/259] cleanup update-version script --- scripts/update-version.sh | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/scripts/update-version.sh b/scripts/update-version.sh index 22d0762c30..a0946bfadf 100755 --- a/scripts/update-version.sh +++ b/scripts/update-version.sh @@ -1,7 +1,6 @@ #!/usr/bin/env bash DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -eval GNU=false eval libs=( "@alfresco/adf-core" "@alfresco/adf-content-services" @@ -15,11 +14,6 @@ show_help() { echo "Usage: update-version.sh -v latest" echo "" echo "-v or -version the new version of the libraries, can also be alpha|beta|latest" - echo "-gnu for gnu" -} - -set_gnu_mode() { - GNU=true } set_version() { @@ -39,17 +33,10 @@ while [[ $1 == -* ]]; do case "$1" in -h|--help|-\?) show_help; exit 0;; -v|version) set_version $2; shift 2;; - -gnu) set_gnu_mode; shift;; -*) shift;; esac done -if $GNU; then - sedi='-i' -else - sedi=('-i' '') -fi - if [[ "${VERSION}" == "" ]] then echo "Error: version number is required" From 6e894fc196d1a31fbc9d15c01c9ee91b26a21714 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Thu, 20 Jun 2019 15:28:05 +0100 Subject: [PATCH 230/259] [ACA-2470] encode urls for docker entrypoint --- docker/entrypoint.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index ce49ba3a72..061618081c 100644 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -60,7 +60,9 @@ if [ -n "${APP_CONFIG_OAUTH2_REDIRECT_LOGOUT}" ];then fi if [[ $ACSURL ]]; then - sed -i s%{protocol}//{hostname}{:port}%"$ACSURL"%g /tmp/app.config.json && \ + replace="\/" + encoded=${ACSURL//\//$replace} + sed -i s%{protocol}//{hostname}{:port}%"$encoded"%g /tmp/app.config.json && \ cat /tmp/app.config.json > ./app.config.json fi @@ -70,7 +72,9 @@ if [[ $BASEPATH ]]; then fi if [ -n "${APP_BASE_SHARE_URL}" ];then - sed -e "s/\"baseShareUrl\": \".*\"/\"baseShareUrl\": \"${APP_BASE_SHARE_URL}\"/g" \ + replace="\/" + encoded=${APP_BASE_SHARE_URL//\//$replace} + sed -e "s/\"baseShareUrl\": \".*\"/\"baseShareUrl\": \"${encoded}\"/g" \ -i /tmp/app.config.json && \ cat /tmp/app.config.json > ./app.config.json fi From 9975261ed91290d9d6cec85156b6bd8e2802c5d6 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Thu, 20 Jun 2019 15:34:28 +0100 Subject: [PATCH 231/259] [ACA-2470] base path encoding for entry point --- docker/entrypoint.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index 061618081c..1d75d9c187 100644 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -67,7 +67,9 @@ if [[ $ACSURL ]]; then fi if [[ $BASEPATH ]]; then - sed -i s%href=\"/\"%href=\""$BASEPATH"\"%g /tmp/index.html && \ + replace="\/" + encoded=${BASEPATH//\//$replace} + sed -i s%href=\"/\"%href=\""$encoded"\"%g /tmp/index.html && \ cat /tmp/index.html > ./index.html fi From 9bd56897479b01ad850f1e0d6d8d69ee2cb8f8c8 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Thu, 20 Jun 2019 16:14:19 +0100 Subject: [PATCH 232/259] [ACA-2411] include application license to output --- angular.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/angular.json b/angular.json index 6cf5af0d3c..2528404c91 100644 --- a/angular.json +++ b/angular.json @@ -22,6 +22,11 @@ ] }, "assets": [ + { + "glob": "LICENSE", + "input": ".", + "output": "/" + }, "src/assets", "src/favicon-96x96.png", "src/app.config.json", From 92eed32c615f0377812cb06b7a7cade1fb192a5f Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Thu, 20 Jun 2019 17:02:27 +0100 Subject: [PATCH 233/259] [ACA-2509] configurable version number --- src/app.config.json | 1 + src/app/components/about/about.component.html | 5 ++++- src/app/components/about/about.component.ts | 3 +-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/app.config.json b/src/app.config.json index aa884960df..2c101f7ed9 100644 --- a/src/app.config.json +++ b/src/app.config.json @@ -17,6 +17,7 @@ }, "application": { "name": "Alfresco Content Application", + "version": "1.8.0", "logo": "assets/images/alfresco-logo-flower.svg", "copyright": "APP.COPYRIGHT" }, diff --git a/src/app/components/about/about.component.html b/src/app/components/about/about.component.html index 01d1961248..54019bc02c 100644 --- a/src/app/components/about/about.component.html +++ b/src/app/components/about/about.component.html @@ -3,7 +3,10 @@
{{ 'application.name' | adfAppConfig }}
-

{{ 'APP.ABOUT.VERSION' | translate }} {{ releaseVersion }}

+

+ {{ 'APP.ABOUT.VERSION' | translate }} + {{ 'application.version' | adfAppConfig }} +

diff --git a/src/app/components/about/about.component.ts b/src/app/components/about/about.component.ts index dbdec3c0cc..9cf1890a5d 100644 --- a/src/app/components/about/about.component.ts +++ b/src/app/components/about/about.component.ts @@ -30,7 +30,7 @@ import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; import { AppExtensionService } from '../../extensions/extension.service'; import { ContentApiService } from '@alfresco/aca-shared'; -import { version, dependencies } from '../../../../package.json'; +import { dependencies } from '../../../../package.json'; @Component({ selector: 'app-about', templateUrl: './about.component.html', @@ -40,7 +40,6 @@ import { version, dependencies } from '../../../../package.json'; }) export class AboutComponent implements OnInit { repository: RepositoryInfo; - releaseVersion = version; extensions$: Observable; dependencyEntries: Array<{ name: string; version: string }>; statusEntries: Array<{ property: string; value: string }>; From 9b74063032e0b4a88fcce5be713b9c4246db6bd8 Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Fri, 21 Jun 2019 17:34:16 +0300 Subject: [PATCH 234/259] update edited folder node (#1136) --- .../content-management.service.spec.ts | 59 +++++++++++++++++-- .../services/content-management.service.ts | 5 +- 2 files changed, 58 insertions(+), 6 deletions(-) diff --git a/src/app/services/content-management.service.spec.ts b/src/app/services/content-management.service.spec.ts index 2c33097f35..4572aba2b9 100644 --- a/src/app/services/content-management.service.spec.ts +++ b/src/app/services/content-management.service.spec.ts @@ -24,7 +24,7 @@ */ import { TestBed, fakeAsync, tick, flush } from '@angular/core/testing'; -import { of, throwError } from 'rxjs'; +import { of, throwError, Subject } from 'rxjs'; import { Actions, ofType, EffectsModule } from '@ngrx/effects'; import { AppStore, @@ -49,7 +49,7 @@ import { ContentApiService } from '@alfresco/aca-shared'; import { Store } from '@ngrx/store'; import { ContentManagementService } from './content-management.service'; import { NodeActionsService } from './node-actions.service'; -import { TranslationService } from '@alfresco/adf-core'; +import { TranslationService, AlfrescoApiService } from '@alfresco/adf-core'; import { MatDialog } from '@angular/material/dialog'; import { MatSnackBar } from '@angular/material/snack-bar'; import { @@ -66,6 +66,7 @@ describe('ContentManagementService', () => { let snackBar: MatSnackBar; let nodeActions: NodeActionsService; let translationService: TranslationService; + let alfrescoApiService: AlfrescoApiService; beforeEach(() => { TestBed.configureTestingModule({ @@ -79,6 +80,7 @@ describe('ContentManagementService', () => { snackBar = TestBed.get(MatSnackBar); nodeActions = TestBed.get(NodeActionsService); translationService = TestBed.get(TranslationService); + alfrescoApiService = TestBed.get(AlfrescoApiService); dialog = TestBed.get(MatDialog); }); @@ -675,8 +677,6 @@ describe('ContentManagementService', () => { spyOn(snackBar, 'open').and.returnValue({ onAction: () => of({}) }); - - // spyOn(snackBar, 'open').and.callThrough(); }); it('should move node back to initial parent, after succeeded move', () => { @@ -1588,4 +1588,55 @@ describe('ContentManagementService', () => { expect(dialogRef).toBe(mockDialogInstance); }); }); + + describe('editFolder', () => { + it('should open dialog with FolderDialogComponent instance', () => { + const mockDialogInstance = { + componentInstance: { error: of() }, + afterClosed: () => of() + }; + const node = { entry: { id: '1', name: 'name1', isFolder: true } }; + spyOn(dialog, 'open').and.returnValue(mockDialogInstance); + + contentManagementService.editFolder(node); + + expect(dialog.open['calls'].argsFor(0)[0].name).toBe( + 'FolderDialogComponent' + ); + }); + + it('should raise error when edit operation fails', fakeAsync(() => { + const mockDialogInstance = { + componentInstance: { error: new Subject() }, + afterClosed: () => of() + }; + const node = { entry: { id: '1', name: 'name1', isFolder: true } }; + spyOn(dialog, 'open').and.returnValue(mockDialogInstance); + spyOn(store, 'dispatch').and.callThrough(); + + contentManagementService.editFolder(node); + + mockDialogInstance.componentInstance.error.next('edit folder error'); + + expect(store.dispatch['calls'].argsFor(0)[0]).toEqual( + new SnackbarErrorAction('edit folder error') + ); + })); + + it('should call nodeUpdated event with edited node data', fakeAsync(() => { + const node = { entry: { id: '1', name: 'name1' } }; + const newNode = { entry: { id: '1', name: 'name-edited' } }; + const mockDialogInstance = { + componentInstance: { error: new Subject() }, + afterClosed: () => of(newNode) + }; + + spyOn(alfrescoApiService.nodeUpdated, 'next'); + spyOn(dialog, 'open').and.returnValue(mockDialogInstance); + + contentManagementService.editFolder(node); + + expect(alfrescoApiService.nodeUpdated.next).toHaveBeenCalledWith(newNode); + })); + }); }); diff --git a/src/app/services/content-management.service.ts b/src/app/services/content-management.service.ts index 5b57b4065f..b2bbb4313a 100644 --- a/src/app/services/content-management.service.ts +++ b/src/app/services/content-management.service.ts @@ -48,7 +48,7 @@ import { LibraryDialogComponent, ShareDialogComponent } from '@alfresco/adf-content-services'; -import { TranslationService } from '@alfresco/adf-core'; +import { TranslationService, AlfrescoApiService } from '@alfresco/adf-core'; import { DeletedNodesPaging, MinimalNodeEntity, @@ -94,6 +94,7 @@ export class ContentManagementService { favoriteLibraryToggle = new Subject(); constructor( + private alfrescoApiService: AlfrescoApiService, private store: Store, private contentApi: ContentApiService, private permission: NodePermissionService, @@ -263,7 +264,7 @@ export class ContentManagementService { dialog.afterClosed().subscribe(node => { if (node) { - this.store.dispatch(new ReloadDocumentListAction()); + this.alfrescoApiService.nodeUpdated.next(node); } }); } From 9e0e50d57df50c6f501804bc92092a428294d11a Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Wed, 26 Jun 2019 10:33:13 +0300 Subject: [PATCH 235/259] [ACA-2643] Upload new version - refactoring (#1138) * refactor upload version effect * subscriber noop fn * move logic to subscribe * tests --- src/app/store/effects/upload.effects.spec.ts | 247 ++++++++++++------- src/app/store/effects/upload.effects.ts | 63 ++--- 2 files changed, 191 insertions(+), 119 deletions(-) diff --git a/src/app/store/effects/upload.effects.spec.ts b/src/app/store/effects/upload.effects.spec.ts index 8a4992f9e4..5b5a3912be 100644 --- a/src/app/store/effects/upload.effects.spec.ts +++ b/src/app/store/effects/upload.effects.spec.ts @@ -34,13 +34,34 @@ import { FileUploadCompleteEvent, FileModel } from '@alfresco/adf-core'; -import { UnlockWriteAction } from '@alfresco/aca-shared/store'; +import { + UnlockWriteAction, + SnackbarErrorAction +} from '@alfresco/aca-shared/store'; +import { ContentManagementService } from '../../services/content-management.service'; +import { of, throwError } from 'rxjs'; + +function createFileList(fileName, type = 'text/plain') { + const data = new Blob([''], { type }); + const arrayOfBlob = new Array(); + arrayOfBlob.push(data); + const file = new File(arrayOfBlob, fileName); + const files = [file]; + + const reducer = (dataTransfer, currentFile) => { + dataTransfer.items.add(currentFile); + return dataTransfer; + }; + return files.reduce(reducer, new DataTransfer()).files; +} describe('UploadEffects', () => { let store: Store; let uploadService: UploadService; let effects: UploadEffects; let zone: NgZone; + let contentManagementService: ContentManagementService; + let uploadVersionInput: HTMLInputElement; beforeEach(() => { TestBed.configureTestingModule({ @@ -52,121 +73,165 @@ describe('UploadEffects', () => { return fn(); }); + contentManagementService = TestBed.get(ContentManagementService); store = TestBed.get(Store); uploadService = TestBed.get(UploadService); effects = TestBed.get(UploadEffects); }); - it('should work', () => { - expect(store).toBeDefined(); - expect(uploadService).toBeDefined(); - expect(effects).toBeDefined(); + beforeEach(() => { + uploadVersionInput = document.querySelector('#app-upload-file-version'); }); - it('should not upload and unlock file if param not provided', () => { - effects.uploadAndUnlock(null); - expect(zone.run).not.toHaveBeenCalled(); + afterEach(() => { + uploadVersionInput.remove(); }); - it('should upload the file before unlocking', () => { - const file: any = {}; + describe('uploadAndUnlock()', () => { + it('should not upload and unlock file if param not provided', () => { + effects.uploadAndUnlock(null); + expect(zone.run).not.toHaveBeenCalled(); + }); - spyOn(uploadService, 'addToQueue').and.stub(); - spyOn(uploadService, 'uploadFilesInTheQueue').and.stub(); + it('should upload the file before unlocking', () => { + const file: any = {}; - effects.uploadAndUnlock(file); + spyOn(uploadService, 'addToQueue').and.stub(); + spyOn(uploadService, 'uploadFilesInTheQueue').and.stub(); - expect(uploadService.addToQueue).toHaveBeenCalled(); - expect(uploadService.uploadFilesInTheQueue).toHaveBeenCalled(); - }); + effects.uploadAndUnlock(file); + + expect(uploadService.addToQueue).toHaveBeenCalled(); + expect(uploadService.uploadFilesInTheQueue).toHaveBeenCalled(); + }); - it('should dispatch the unlock write action for a locked file', () => { - const file: FileModel = new FileModel( - { name: 'file1.png', size: 10 }, - null, - 'file1' - ); - - file.data = { - entry: { - id: 'file1', - properties: { - 'cm:lockType': 'WRITE_LOCK' + it('should dispatch the unlock write action for a locked file', () => { + const file: FileModel = new FileModel( + { name: 'file1.png', size: 10 }, + null, + 'file1' + ); + + file.data = { + entry: { + id: 'file1', + properties: { + 'cm:lockType': 'WRITE_LOCK' + } } - } - }; + }; - spyOn(uploadService, 'addToQueue').and.stub(); - spyOn(uploadService, 'uploadFilesInTheQueue').and.stub(); - spyOn(store, 'dispatch').and.stub(); + spyOn(uploadService, 'addToQueue').and.stub(); + spyOn(uploadService, 'uploadFilesInTheQueue').and.stub(); + spyOn(store, 'dispatch').and.stub(); - effects.uploadAndUnlock(file); - uploadService.fileUploadComplete.next( - new FileUploadCompleteEvent(file, 100, file.data) - ); + effects.uploadAndUnlock(file); + uploadService.fileUploadComplete.next( + new FileUploadCompleteEvent(file, 100, file.data) + ); - expect(store.dispatch).toHaveBeenCalledWith( - new UnlockWriteAction(file.data) - ); - }); + expect(store.dispatch).toHaveBeenCalledWith( + new UnlockWriteAction(file.data) + ); + }); - it('should dispatch only one unlock action for a locked file', () => { - const file: FileModel = new FileModel( - { name: 'file1.png', size: 10 }, - null, - 'file1' - ); - - file.data = { - entry: { - id: 'file1', - properties: { - 'cm:lockType': 'WRITE_LOCK' + it('should dispatch only one unlock action for a locked file', () => { + const file: FileModel = new FileModel( + { name: 'file1.png', size: 10 }, + null, + 'file1' + ); + + file.data = { + entry: { + id: 'file1', + properties: { + 'cm:lockType': 'WRITE_LOCK' + } } - } - }; + }; + + spyOn(uploadService, 'addToQueue').and.stub(); + spyOn(uploadService, 'uploadFilesInTheQueue').and.stub(); + spyOn(store, 'dispatch').and.stub(); + + effects.uploadAndUnlock(file); - spyOn(uploadService, 'addToQueue').and.stub(); - spyOn(uploadService, 'uploadFilesInTheQueue').and.stub(); - spyOn(store, 'dispatch').and.stub(); + const completeEvent = new FileUploadCompleteEvent(file, 100, file.data); + uploadService.fileUploadComplete.next(completeEvent); + uploadService.fileUploadComplete.next(completeEvent); + uploadService.fileUploadComplete.next(completeEvent); - effects.uploadAndUnlock(file); + expect(store.dispatch).toHaveBeenCalledWith( + new UnlockWriteAction(file.data) + ); - const completeEvent = new FileUploadCompleteEvent(file, 100, file.data); - uploadService.fileUploadComplete.next(completeEvent); - uploadService.fileUploadComplete.next(completeEvent); - uploadService.fileUploadComplete.next(completeEvent); + expect(store.dispatch).toHaveBeenCalledTimes(1); + }); + + it('should dispatch no actions if file is not locked', () => { + const file: FileModel = new FileModel( + { name: 'file1.png', size: 10 }, + null, + 'file1' + ); + + file.data = { + entry: { + id: 'file1', + properties: {} + } + }; - expect(store.dispatch).toHaveBeenCalledWith( - new UnlockWriteAction(file.data) - ); + spyOn(uploadService, 'addToQueue').and.stub(); + spyOn(uploadService, 'uploadFilesInTheQueue').and.stub(); + spyOn(store, 'dispatch').and.stub(); - expect(store.dispatch).toHaveBeenCalledTimes(1); + effects.uploadAndUnlock(file); + uploadService.fileUploadComplete.next( + new FileUploadCompleteEvent(file, 100, file.data) + ); + + expect(store.dispatch).not.toHaveBeenCalled(); + }); }); - it('should dispatch no actions if file is not locked', () => { - const file: FileModel = new FileModel( - { name: 'file1.png', size: 10 }, - null, - 'file1' - ); - - file.data = { - entry: { - id: 'file1', - properties: {} - } - }; - - spyOn(uploadService, 'addToQueue').and.stub(); - spyOn(uploadService, 'uploadFilesInTheQueue').and.stub(); - spyOn(store, 'dispatch').and.stub(); - - effects.uploadAndUnlock(file); - uploadService.fileUploadComplete.next( - new FileUploadCompleteEvent(file, 100, file.data) - ); - - expect(store.dispatch).not.toHaveBeenCalled(); + describe('upload file version', () => { + beforeEach(() => { + const dialog = { afterClosed: () => of({}) }; + spyOn(contentManagementService, 'versionUploadDialog').and.returnValue( + dialog + ); + spyOn(effects, 'uploadAndUnlock').and.stub(); + }); + + it('should upload file', () => { + spyOn(contentManagementService, 'getNodeInfo').and.returnValue( + of({ + entry: { + id: 'file1', + properties: {} + } + }) + ); + + uploadVersionInput.files = createFileList('bogus.txt'); + uploadVersionInput.dispatchEvent(new CustomEvent('change')); + expect(effects.uploadAndUnlock).toHaveBeenCalled(); + }); + + it('should raise error when getNodeInfo fails', () => { + spyOn(store, 'dispatch').and.stub(); + spyOn(contentManagementService, 'getNodeInfo').and.returnValue( + throwError('error') + ); + + uploadVersionInput.files = createFileList('bogus.txt'); + uploadVersionInput.dispatchEvent(new CustomEvent('change')); + expect(store.dispatch).toHaveBeenCalledWith( + new SnackbarErrorAction('VERSION.ERROR.GENERIC') + ); + expect(effects.uploadAndUnlock).not.toHaveBeenCalled(); + }); }); }); diff --git a/src/app/store/effects/upload.effects.ts b/src/app/store/effects/upload.effects.ts index e53e8a471a..ce9bf61df3 100644 --- a/src/app/store/effects/upload.effects.ts +++ b/src/app/store/effects/upload.effects.ts @@ -37,17 +37,8 @@ import { FileModel, FileUtils, UploadService } from '@alfresco/adf-core'; import { Injectable, NgZone, RendererFactory2 } from '@angular/core'; import { Actions, Effect, ofType } from '@ngrx/effects'; import { Store } from '@ngrx/store'; -import { forkJoin, fromEvent, of } from 'rxjs'; -import { - catchError, - distinctUntilChanged, - filter, - flatMap, - map, - switchMap, - take, - tap -} from 'rxjs/operators'; +import { forkJoin, of } from 'rxjs'; +import { tap, filter, catchError, flatMap, map, take } from 'rxjs/operators'; import { ContentManagementService } from '../../services/content-management.service'; @Injectable() @@ -78,7 +69,9 @@ export class UploadEffects { this.fileVersionInput.id = 'app-upload-file-version'; this.fileVersionInput.type = 'file'; this.fileVersionInput.style.display = 'none'; - this.fileVersionInput.addEventListener('change', event => event); + this.fileVersionInput.addEventListener('change', () => + this.uploadVersion() + ); renderer.appendChild(document.body, this.fileVersionInput); this.folderInput = renderer.createElement('input') as HTMLInputElement; @@ -110,19 +103,38 @@ export class UploadEffects { @Effect({ dispatch: false }) uploadVersion$ = this.actions$.pipe( ofType(UploadActionTypes.UploadFileVersion), - switchMap(() => { + map(() => { this.fileVersionInput.click(); - return fromEvent(this.fileVersionInput, 'change').pipe( - distinctUntilChanged(), - flatMap(() => this.contentService.versionUploadDialog().afterClosed()), + }) + ); + + private uploadVersion() { + this.contentService + .versionUploadDialog() + .afterClosed() + .pipe( tap(form => { if (!form) { this.fileVersionInput.value = ''; } }), filter(form => !!form), - flatMap(form => forkJoin(of(form), this.contentService.getNodeInfo())), - map(([form, node]) => { + flatMap(form => + forkJoin( + of(form), + this.contentService.getNodeInfo().pipe( + catchError(_ => { + this.store.dispatch( + new SnackbarErrorAction('VERSION.ERROR.GENERIC') + ); + return of(null); + }) + ) + ) + ) + ) + .subscribe(([form, node]) => { + if (form && node) { const file = this.fileVersionInput.files[0]; const fileModel = new FileModel( file, @@ -139,17 +151,12 @@ export class UploadEffects { }, node.id ); - - this.fileVersionInput.value = ''; this.uploadAndUnlock(fileModel); - }), - catchError(_ => { - this.fileVersionInput.value = ''; - return of(new SnackbarErrorAction('VERSION.ERROR.GENERIC')); - }) - ); - }) - ); + } + + this.fileVersionInput.value = ''; + }); + } private upload(event: any): void { this.store From 17ce7f1cbca12b48b756bab7e6102613af613dd8 Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Wed, 26 Jun 2019 12:02:40 +0300 Subject: [PATCH 236/259] [ACA-2473] action menus - reorder and capitalisation (#1135) * reorder actions and typography * capitalize labels * added titlecase pipe name * remove titlecase pipe * actions titlecase strings * update e2e * fix text selector * e2e exclude deleteaction checks --- cspell.json | 1 + e2e/components/menu/menu.ts | 22 +-- e2e/components/sidenav/sidenav.ts | 2 +- e2e/components/toolbar/toolbar.ts | 18 +-- .../context-menu-multiple-selection.test.ts | 6 +- .../context-menu-single-selection.test.ts | 4 +- .../toolbar-multiple-selection.test.ts | 6 +- .../toolbar-single-selection.test.ts | 4 +- e2e/suites/actions/library-actions.test.ts | 4 +- e2e/suites/actions/mark-favorite.test.ts | 4 +- e2e/suites/actions/new-menu.test.ts | 4 +- src/assets/app.extensions.json | 142 +++++++++--------- src/assets/i18n/en.json | 26 ++-- 13 files changed, 122 insertions(+), 121 deletions(-) diff --git a/cspell.json b/cspell.json index 44d75942ef..1ca728ea28 100644 --- a/cspell.json +++ b/cspell.json @@ -42,6 +42,7 @@ "docx", "SOLR", "simpletask", + "titlecase", "unshare", "qshare", diff --git a/e2e/components/menu/menu.ts b/e2e/components/menu/menu.ts index e955fffa34..71880de0a5 100755 --- a/e2e/components/menu/menu.ts +++ b/e2e/components/menu/menu.ts @@ -40,8 +40,8 @@ export class Menu extends Component { editFolder: `.mat-menu-item[id$='editFolder']`, favoriteAction: `.mat-menu-item[id$='favorite.add']`, removeFavoriteAction: `.mat-menu-item[id$='favorite.remove']`, - editOffline: `.mat-menu-item[title='Edit offline']`, - cancelEditing: `.mat-menu-item[title='Cancel editing']` + editOffline: `.mat-menu-item[title='Edit Offline']`, + cancelEditing: `.mat-menu-item[title='Cancel Editing']` }; items: ElementArrayFinder = this.component.all(by.css(Menu.selectors.item)); @@ -50,9 +50,9 @@ export class Menu extends Component { submenus: ElementArrayFinder = browser.element.all(by.css(Menu.selectors.submenu)); cancelEditingAction: ElementFinder = this.component.element(by.css(Menu.selectors.cancelEditing)); - cancelJoinAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Cancel join')); + cancelJoinAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Cancel Join')); copyAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Copy')); - createFolderAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Create folder')); + createFolderAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Create Folder')); createLibraryAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Create Library')); deleteAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Delete')); downloadAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Download')); @@ -61,21 +61,21 @@ export class Menu extends Component { favoriteAction: ElementFinder = this.component.element(by.css(Menu.selectors.favoriteAction)); removeFavoriteAction: ElementFinder = this.component.element(by.css(Menu.selectors.removeFavoriteAction)); toggleFavoriteAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Favorite')); - toggleRemoveFavoriteAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Remove favorite')); + toggleRemoveFavoriteAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Remove Favorite')); joinAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Join')); leaveAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Leave')); managePermissionsAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Permissions')); manageVersionsAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Manage Versions')); - uploadNewVersionAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Upload new version')); + uploadNewVersionAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Upload New Version')); moveAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Move')); - permanentDeleteAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Permanently delete')); + permanentDeleteAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Permanently Delete')); restoreAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Restore')); shareAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Share')); - shareEditAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Shared link settings')); - uploadFileAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Upload file')); - uploadFolderAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Upload folder')); + shareEditAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Shared Link Settings')); + uploadFileAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Upload File')); + uploadFolderAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'Upload Folder')); viewAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'View')); - viewDetailsAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'View details')); + viewDetailsAction: ElementFinder = this.component.element(by.cssContainingText(Menu.selectors.item, 'View Details')); constructor(ancestor?: ElementFinder) { super(Menu.selectors.root, ancestor); diff --git a/e2e/components/sidenav/sidenav.ts b/e2e/components/sidenav/sidenav.ts index 7601ccd031..b6c4fecd31 100755 --- a/e2e/components/sidenav/sidenav.ts +++ b/e2e/components/sidenav/sidenav.ts @@ -98,7 +98,7 @@ export class Sidenav extends Component { async openCreateFolderDialog() { await this.openNewMenu(); - await this.menu.clickMenuItem('Create folder'); + await this.menu.clickMenuItem('Create Folder'); } async openCreateLibraryDialog() { diff --git a/e2e/components/toolbar/toolbar.ts b/e2e/components/toolbar/toolbar.ts index baf0108ff4..e350ac34ce 100755 --- a/e2e/components/toolbar/toolbar.ts +++ b/e2e/components/toolbar/toolbar.ts @@ -34,17 +34,17 @@ export class Toolbar extends Component { button: 'button', share: `.mat-icon-button[title='Share']`, - shareEdit: `.mat-icon-button[title='Shared link settings']`, + shareEdit: `.mat-icon-button[title='Shared Link Settings']`, view: `.mat-icon-button[title='View']`, searchFilterToggle: `.mat-icon-button[title='Toggle search filter']`, download: `.mat-icon-button[title='Download']`, editFolder: 'app.toolbar.editFolder', - viewDetails: `.mat-icon-button[title='View details']`, + viewDetails: `.mat-icon-button[title='View Details']`, print: `.mat-icon-button[title='Print']`, fullScreen: `.mat-icon-button[title='Activate full-screen mode']`, joinLibrary: `.mat-icon-button[title='Join']`, leaveLibrary: `.mat-icon-button[title='Leave library']`, - permanentlyDelete: `.mat-icon-button[title='Permanently delete']`, + permanentlyDelete: `.mat-icon-button[title='Permanently Delete']`, restore: `.mat-icon-button[title='Restore']` }; @@ -95,8 +95,8 @@ export class Toolbar extends Component { } async openMoreMenu() { - await this.isButtonPresent('More actions'); - const moreMenu = this.getButtonByTitleAttribute('More actions'); + await this.isButtonPresent('More Actions'); + const moreMenu = this.getButtonByTitleAttribute('More Actions'); await moreMenu.click(); await this.menu.waitForMenuToOpen(); } @@ -209,7 +209,7 @@ export class Toolbar extends Component { async clickMoreActionsRemoveFavorite() { await this.openMoreMenu(); - return await this.menu.clickMenuItem('Remove favorite'); + return await this.menu.clickMenuItem('Remove Favorite'); } async clickMoreActionsDelete() { @@ -234,17 +234,17 @@ export class Toolbar extends Component { async clickMoreActionsEditOffline() { await this.openMoreMenu(); - return await this.menu.clickMenuItem('Edit offline'); + return await this.menu.clickMenuItem('Edit Offline'); } async clickMoreActionsCancelEditing() { await this.openMoreMenu(); - return await this.menu.clickMenuItem('Cancel editing'); + return await this.menu.clickMenuItem('Cancel Editing'); } async clickMoreActionsUploadNewVersion() { await this.openMoreMenu(); - return await this.menu.clickMenuItem('Upload new version'); + return await this.menu.clickMenuItem('Upload New Version'); } async clickFullScreen() { diff --git a/e2e/suites/actions-available/context-menu-multiple-selection.test.ts b/e2e/suites/actions-available/context-menu-multiple-selection.test.ts index 5ae20fbce3..7b974bc8b7 100755 --- a/e2e/suites/actions-available/context-menu-multiple-selection.test.ts +++ b/e2e/suites/actions-available/context-menu-multiple-selection.test.ts @@ -513,7 +513,7 @@ describe('Context menu actions - multiple selection : ', () => { expect(await contextMenu.isDownloadPresent()).toBe(false, 'Download is displayed'); expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); expect(await contextMenu.isCopyPresent()).toBe(false, `Copy is displayed`); - expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); + // expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); expect(await contextMenu.isFavoritePresent()).toBe(false, `Favorite is displayed`); expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); @@ -532,7 +532,7 @@ describe('Context menu actions - multiple selection : ', () => { expect(await contextMenu.isDownloadPresent()).toBe(false, 'Download is displayed'); expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); expect(await contextMenu.isCopyPresent()).toBe(false, `Copy is displayed`); - expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); + // expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); expect(await contextMenu.isFavoritePresent()).toBe(false, `Favorite is displayed`); expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); @@ -551,7 +551,7 @@ describe('Context menu actions - multiple selection : ', () => { expect(await contextMenu.isDownloadPresent()).toBe(false, 'Download is displayed'); expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); expect(await contextMenu.isCopyPresent()).toBe(false, `Copy is displayed`); - expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); + // expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); expect(await contextMenu.isFavoritePresent()).toBe(false, `Favorite is displayed`); expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); diff --git a/e2e/suites/actions-available/context-menu-single-selection.test.ts b/e2e/suites/actions-available/context-menu-single-selection.test.ts index ea9798ac72..84a2091b77 100755 --- a/e2e/suites/actions-available/context-menu-single-selection.test.ts +++ b/e2e/suites/actions-available/context-menu-single-selection.test.ts @@ -587,7 +587,7 @@ describe('Context menu actions - single selection : ', () => { expect(await contextMenu.isFavoritePresent()).toBe(false, `Favorite is displayed for ${fileInTrash}`); expect(await contextMenu.isCopyPresent()).toBe(false, `Copy is displayed for ${fileInTrash}`); expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed for ${fileInTrash}`); - expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed for ${fileInTrash}`); + // expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed for ${fileInTrash}`); expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed for ${fileInTrash}`); expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions is displayed for ${fileInTrash}`); expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed for ${fileInTrash}`); @@ -607,7 +607,7 @@ describe('Context menu actions - single selection : ', () => { expect(await contextMenu.isFavoritePresent()).toBe(false, `Favorite is displayed for ${folderInTrash}`); expect(await contextMenu.isCopyPresent()).toBe(false, `Copy is displayed for ${folderInTrash}`); expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed for ${folderInTrash}`); - expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed for ${folderInTrash}`); + // expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed for ${folderInTrash}`); expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed for ${folderInTrash}`); expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions is displayed for ${folderInTrash}`); expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed for ${folderInTrash}`); diff --git a/e2e/suites/actions-available/toolbar-multiple-selection.test.ts b/e2e/suites/actions-available/toolbar-multiple-selection.test.ts index 47ad8ada66..d151f7f9f7 100755 --- a/e2e/suites/actions-available/toolbar-multiple-selection.test.ts +++ b/e2e/suites/actions-available/toolbar-multiple-selection.test.ts @@ -573,21 +573,21 @@ describe('Toolbar actions - multiple selection : ', () => { it('correct actions appear when multiple files are selected - [C280472]', async () => { await dataTable.selectMultipleItems([fileForDelete1, fileForDelete2]); - expect(await toolbar.isButtonPresent('Permanently delete')).toBe(true, 'Permanently delete is displayed'); + expect(await toolbar.isButtonPresent('Permanently Delete')).toBe(true, 'Permanently delete is displayed'); expect(await toolbar.isButtonPresent('Restore')).toBe(true, 'Restore is not displayed'); }); it('correct actions appear when multiple folders are selected - [C280473]', async () => { await dataTable.selectMultipleItems([folderForDelete1, folderForDelete2]); - expect(await toolbar.isButtonPresent('Permanently delete')).toBe(true, 'Permanently delete is displayed'); + expect(await toolbar.isButtonPresent('Permanently Delete')).toBe(true, 'Permanently delete is displayed'); expect(await toolbar.isButtonPresent('Restore')).toBe(true, 'Restore is not displayed'); }); it('correct actions appear when both files and folders are selected - [C280474]', async () => { await dataTable.selectMultipleItems([fileForDelete1, fileForDelete2, folderForDelete1, folderForDelete2]); - expect(await toolbar.isButtonPresent('Permanently delete')).toBe(true, 'Permanently delete is displayed'); + expect(await toolbar.isButtonPresent('Permanently Delete')).toBe(true, 'Permanently delete is displayed'); expect(await toolbar.isButtonPresent('Restore')).toBe(true, 'Restore is not displayed'); }); }); diff --git a/e2e/suites/actions-available/toolbar-single-selection.test.ts b/e2e/suites/actions-available/toolbar-single-selection.test.ts index 4d8b17af44..6d65d96092 100755 --- a/e2e/suites/actions-available/toolbar-single-selection.test.ts +++ b/e2e/suites/actions-available/toolbar-single-selection.test.ts @@ -352,7 +352,7 @@ describe('Toolbar actions - single selection : ', () => { expect(await toolbar.isEmpty()).toBe(false, 'toolbar not displayed'); expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${adminModerated}`); - expect(await toolbar.isButtonPresent('Cancel join request')).toBe(true, `Cancel join is not displayed for ${adminModerated}`); + expect(await toolbar.isButtonPresent('Cancel Join Request')).toBe(true, `Cancel join is not displayed for ${adminModerated}`); await toolbar.openMoreMenu(); @@ -406,7 +406,7 @@ describe('Toolbar actions - single selection : ', () => { expect(await toolbar.isEmpty()).toBe(false, 'toolbar not displayed'); expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${adminModerated}`); - expect(await toolbar.isButtonPresent('Cancel join request')).toBe(true, `Cancel join is not displayed for ${adminModerated}`); + expect(await toolbar.isButtonPresent('Cancel Join Request')).toBe(true, `Cancel join is not displayed for ${adminModerated}`); await toolbar.openMoreMenu(); diff --git a/e2e/suites/actions/library-actions.test.ts b/e2e/suites/actions/library-actions.test.ts index 5abc635c7d..c7d0e01b84 100755 --- a/e2e/suites/actions/library-actions.test.ts +++ b/e2e/suites/actions/library-actions.test.ts @@ -286,7 +286,7 @@ describe('Library actions', () => { it('from Favorite Libraries - [C290108]', async () => { await page.goToFavoriteLibrariesAndWait(); await dataTable.selectItem(siteModerated2Admin); - await toolbar.clickButton('Cancel join request'); + await toolbar.clickButton('Cancel Join Request'); expect(await page.getSnackBarMessage()).toEqual(`Canceled the request to join the library`); @@ -301,7 +301,7 @@ describe('Library actions', () => { await dataTable.waitForBody(); await dataTable.selectItem(siteSearchModerated2Admin); - await toolbar.clickButton('Cancel join request'); + await toolbar.clickButton('Cancel Join Request'); expect(await page.getSnackBarMessage()).toEqual(`Canceled the request to join the library`); diff --git a/e2e/suites/actions/mark-favorite.test.ts b/e2e/suites/actions/mark-favorite.test.ts index 01c4370f93..b078486deb 100644 --- a/e2e/suites/actions/mark-favorite.test.ts +++ b/e2e/suites/actions/mark-favorite.test.ts @@ -153,7 +153,7 @@ describe('Mark items as favorites', () => { await dataTable.selectItem(fileFavUI); await toolbar.openMoreMenu(); - expect(await toolbar.menu.getItemIconText('Remove favorite')).toEqual('star'); + expect(await toolbar.menu.getItemIconText('Remove Favorite')).toEqual('star'); }); it('favorite a file - [C217189]', async () => { @@ -345,7 +345,7 @@ describe('Mark items as favorites', () => { await dataTable.selectItem(fileFav2); await toolbar.openMoreMenu(); - expect(await toolbar.menu.getItemIconText('Remove favorite')).toEqual('star'); + expect(await toolbar.menu.getItemIconText('Remove Favorite')).toEqual('star'); }); }); diff --git a/e2e/suites/actions/new-menu.test.ts b/e2e/suites/actions/new-menu.test.ts index 79e1b2395d..e5b1349ccc 100755 --- a/e2e/suites/actions/new-menu.test.ts +++ b/e2e/suites/actions/new-menu.test.ts @@ -149,7 +149,7 @@ describe('New menu', () => { await page.clickPersonalFiles(); await sidenav.openNewMenu(); - const tooltip = await sidenav.menu.getItemTooltip('Create folder'); + const tooltip = await sidenav.menu.getItemTooltip('Create Folder'); expect(tooltip).toContain('Create new folder'); }); @@ -158,7 +158,7 @@ describe('New menu', () => { await dataTable.doubleClickOnRowByName(siteAdmin); await sidenav.openNewMenu(); - const tooltip = await sidenav.menu.getItemTooltip('Create folder'); + const tooltip = await sidenav.menu.getItemTooltip('Create Folder'); expect(tooltip).toContain(`Folders cannot be created whilst viewing the current items`); }); diff --git a/src/assets/app.extensions.json b/src/assets/app.extensions.json index b7e12a3b87..55676b2385 100644 --- a/src/assets/app.extensions.json +++ b/src/assets/app.extensions.json @@ -339,16 +339,11 @@ "visible": "app.selection.file.canUploadVersion" } }, - { - "id": "app.create.separator.1", - "type": "separator", - "order": 300 - }, { "id": "app.toolbar.favorite", "comment": "workaround for Recent Files and Search API issue", "type": "custom", - "order": 400, + "order": 300, "component": "app.toolbar.toggleFavorite", "rules": { "visible": "canToggleFavorite" @@ -357,7 +352,7 @@ { "id": "app.libraries.toolbar.toggleFavorite", "type": "custom", - "order": 401, + "order": 301, "component": "app.toolbar.toggleFavoriteLibrary", "rules": { "visible": "app.selection.library" @@ -365,7 +360,7 @@ }, { "id": "app.toolbar.favorite.add", - "order": 402, + "order": 302, "title": "APP.ACTIONS.FAVORITE", "icon": "star_border", "actions": { @@ -377,7 +372,7 @@ }, { "id": "app.toolbar.favorite.remove", - "order": 403, + "order": 303, "title": "APP.ACTIONS.REMOVE_FAVORITE", "icon": "star", "actions": { @@ -387,6 +382,11 @@ "visible": "app.toolbar.favorite.canRemove" } }, + { + "id": "app.create.separator.1", + "type": "separator", + "order": 400 + }, { "id": "app.toolbar.editFolder", "order": 450, @@ -405,27 +405,27 @@ "order": 500 }, { - "id": "app.toolbar.copy", + "id": "app.toolbar.move", "order": 600, - "title": "APP.ACTIONS.COPY", - "icon": "content_copy", + "title": "APP.ACTIONS.MOVE", + "icon": "adf:move_file", "actions": { - "click": "COPY_NODES" + "click": "MOVE_NODES" }, "rules": { - "visible": "canCopyNode" + "visible": "app.selection.canDelete" } }, { - "id": "app.toolbar.move", + "id": "app.toolbar.copy", "order": 700, - "title": "APP.ACTIONS.MOVE", - "icon": "adf:move_file", + "title": "APP.ACTIONS.COPY", + "icon": "content_copy", "actions": { - "click": "MOVE_NODES" + "click": "COPY_NODES" }, "rules": { - "visible": "app.selection.canDelete" + "visible": "canCopyNode" } }, { @@ -486,68 +486,80 @@ ], "contextMenu": [ { - "id": "app.context.toggleLock", - "order": 100, + "id": "app.context.menu.share", "type": "custom", - "component": "app.toolbar.toggleEditOffline", + "order": 100, + "component": "app.shared-link.toggleSharedLink", "rules": { - "visible": "canToggleEditOffline" + "visible": "canToggleSharedLink" } }, { - "id": "app.context.menu.uploadNodeVersion", - "title": "APP.ACTIONS.UPLOAD_VERSION", + "id": "app.context.menu.download", "order": 200, - "icon": "playlist_add", + "title": "APP.ACTIONS.DOWNLOAD", + "icon": "get_app", "actions": { - "click": "UPLOAD_FILE_VERSION" + "click": "DOWNLOAD_NODES" }, "rules": { - "visible": "app.selection.file.canUploadVersion" + "visible": "app.selection.canDownload" + } + }, + { + "id": "app.context.menu.preview", + "order": 300, + "title": "APP.ACTIONS.VIEW", + "icon": "visibility", + "actions": { + "click": "VIEW_FILE" + }, + "rules": { + "visible": "canViewFile" } }, { "id": "app.create.separator.1", "type": "separator", - "order": 300 + "order": 400 }, { - "id": "app.context.menu.share", + "id": "app.context.toggleLock", + "order": 500, "type": "custom", - "order": 400, - "component": "app.shared-link.toggleSharedLink", + "component": "app.toolbar.toggleEditOffline", "rules": { - "visible": "canToggleSharedLink" + "visible": "canToggleEditOffline" } }, { - "id": "app.context.menu.download", - "order": 500, - "title": "APP.ACTIONS.DOWNLOAD", - "icon": "get_app", + "id": "app.context.menu.editFolder", + "order": 600, + "title": "APP.ACTIONS.EDIT", + "icon": "create", "actions": { - "click": "DOWNLOAD_NODES" + "click": "EDIT_FOLDER" }, "rules": { - "visible": "app.selection.canDownload" + "visible": "canEditFolder" } }, { - "id": "app.context.menu.preview", - "order": 600, - "title": "APP.ACTIONS.VIEW", - "icon": "visibility", + "id": "app.context.menu.uploadNodeVersion", + "title": "APP.ACTIONS.UPLOAD_VERSION", + "order": 700, + "icon": "playlist_add", "actions": { - "click": "VIEW_FILE" + "click": "UPLOAD_FILE_VERSION" }, "rules": { - "visible": "canViewFile" + "visible": "app.selection.file.canUploadVersion" } }, { "id": "app.context.menu.favorite.add", "title": "APP.ACTIONS.FAVORITE", - "order": 700, + "order": 800, "icon": "star_border", "actions": { "click": "ADD_FAVORITE" @@ -559,7 +571,7 @@ { "id": "app.context.menu.favorite.remove", "title": "APP.ACTIONS.REMOVE_FAVORITE", - "order": 701, + "order": 801, "icon": "star", "actions": { "click": "REMOVE_FAVORITE" @@ -572,7 +584,7 @@ "id": "app.context.menu.favorite", "comment": "workaround for Recent Files and Search API issue", "type": "custom", - "order": 702, + "order": 802, "component": "app.toolbar.toggleFavorite", "rules": { "visible": "canToggleFavorite" @@ -581,51 +593,39 @@ { "id": "app.context.menu.libraries.toggleFavorite", "type": "custom", - "order": 703, + "order": 803, "component": "app.toolbar.toggleFavoriteLibrary", "rules": { "visible": "app.selection.library" } }, - { - "id": "app.context.menu.editFolder", - "order": 800, - "title": "APP.ACTIONS.EDIT", - "icon": "create", - "actions": { - "click": "EDIT_FOLDER" - }, - "rules": { - "visible": "canEditFolder" - } - }, { "id": "app.create.separator.2", "type": "separator", "order": 900 }, { - "id": "app.context.menu.copy", - "title": "APP.ACTIONS.COPY", + "id": "app.context.menu.move", + "title": "APP.ACTIONS.MOVE", "order": 1000, - "icon": "content_copy", + "icon": "adf:move_file", "actions": { - "click": "COPY_NODES" + "click": "MOVE_NODES" }, "rules": { - "visible": "canCopyNode" + "visible": "app.selection.canDelete" } }, { - "id": "app.context.menu.move", - "title": "APP.ACTIONS.MOVE", + "id": "app.context.menu.copy", + "title": "APP.ACTIONS.COPY", "order": 1100, - "icon": "adf:move_file", + "icon": "content_copy", "actions": { - "click": "MOVE_NODES" + "click": "COPY_NODES" }, "rules": { - "visible": "app.selection.canDelete" + "visible": "canCopyNode" } }, { diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 2506ca3118..3eb732f2d1 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -54,9 +54,9 @@ "LABEL": "New", "TOOLTIP": "Add new files and folders, or create a new File Library", "MENU_ITEMS": { - "CREATE_FOLDER": "Create folder", - "UPLOAD_FILE": "Upload file", - "UPLOAD_FOLDER": "Upload folder", + "CREATE_FOLDER": "Create Folder", + "UPLOAD_FILE": "Upload File", + "UPLOAD_FOLDER": "Upload Folder", "CREATE_LIBRARY": "Create Library" }, "TOOLTIPS": { @@ -190,28 +190,28 @@ "COPY": "Copy", "MOVE": "Move", "DELETE": "Delete", - "DELETE_PERMANENT": "Permanently delete", - "MORE": "More actions", + "DELETE_PERMANENT": "Permanently Delete", + "MORE": "More Actions", "UNDO": "Undo", "PERMISSIONS": "Permissions", "RESTORE": "Restore", "FAVORITE": "Favorite", - "ADD_FAVORITE": "Add favorite", - "REMOVE_FAVORITE": "Remove favorite", + "ADD_FAVORITE": "Add Favorite", + "REMOVE_FAVORITE": "Remove Favorite", "UNSHARE": "Unshare", - "DETAILS": "View details", + "DETAILS": "View Details", "VERSIONS": "Manage Versions", - "UPLOAD_VERSION": "Upload new version", + "UPLOAD_VERSION": "Upload New Version", "TOGGLE-SIDENAV": "Toggle side navigation bar", "SHARE": "Share", - "SHARE_EDIT": "Shared link settings", + "SHARE_EDIT": "Shared Link Settings", "PRINT": "Print", "FULLSCREEN": "Activate full-screen mode", "JOIN": "Join", - "CANCEL_JOIN": "Cancel join request", + "CANCEL_JOIN": "Cancel Join Request", "LEAVE": "Leave library", - "EDIT_OFFLINE": "Edit offline", - "EDIT_OFFLINE_CANCEL": "Cancel editing" + "EDIT_OFFLINE": "Edit Offline", + "EDIT_OFFLINE_CANCEL": "Cancel Editing" }, "DIALOGS": { "CONFIRM_PURGE": { From 9176cf993c16523a6d3a24e45907bf2b842461eb Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Wed, 26 Jun 2019 11:01:08 +0100 Subject: [PATCH 237/259] setup code owners and default reviewers (#1140) * setup code owners and default reviewers * protractor config rule --- .github/CODEOWNERS | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000000..dc0e090d57 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,38 @@ +# This is a comment. +# Each line is a file pattern followed by one or more owners. + +# These owners will be the default owners for everything in +# the repo. Unless a later match takes precedence, +# these users will be requested for +# review when someone opens a pull request. +* @DenysVuika @pionnegru + +# Order is important; the last matching pattern takes the most +# precedence. When someone opens a pull request that only +# modifies JS files, only @js-owner and not the global +# owner(s) will be requested for a review. +e2e/* @adinapitul @pionnegru @DenysVuika +protractor.conf.js @adinapitul + +# You can also use email addresses if you prefer. They'll be +# used to look up users just like we do for commit author +# emails. +#*.go docs@example.com + +# In this example, @doctocat owns any files in the build/logs +# directory at the root of the repository and any of its +# subdirectories. +#/build/logs/ @doctocat + +# The `docs/*` pattern will match files like +# `docs/getting-started.md` but not further nested files like +# `docs/build-app/troubleshooting.md`. +#docs/* docs@example.com + +# In this example, @octocat owns any file in an apps directory +# anywhere in your repository. +#apps/ @octocat + +# In this example, @doctocat owns any file in the `/docs` +# directory in the root of your repository. +#/docs/ @doctocat From 16b7eee62145bdb86a5deecdb1fe3f5c067b142c Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Thu, 27 Jun 2019 11:18:00 +0300 Subject: [PATCH 238/259] [ACA-2645] Shared - don't render shared settings action for multiple selection (#1141) * check if is single selection * tests --- .../aca-shared/rules/src/app.rules.spec.ts | 77 +++++++++++++++++++ projects/aca-shared/rules/src/app.rules.ts | 2 +- 2 files changed, 78 insertions(+), 1 deletion(-) diff --git a/projects/aca-shared/rules/src/app.rules.spec.ts b/projects/aca-shared/rules/src/app.rules.spec.ts index 1f37fd3426..3306e147e4 100644 --- a/projects/aca-shared/rules/src/app.rules.spec.ts +++ b/projects/aca-shared/rules/src/app.rules.spec.ts @@ -362,4 +362,81 @@ describe('app.evaluators', () => { expect(app.canUploadVersion(context)).toBe(true); }); }); + + describe('isShared', () => { + it('should return true if route is shared files and single selection', () => { + const context: any = { + selection: { + file: {} + }, + navigation: { + url: '/shared' + } + }; + + expect(app.isShared(context)).toBe(true); + }); + + it('should return false if route is shared files and multiple selection', () => { + const context: any = { + selection: { + file: null + }, + navigation: { + url: '/shared' + } + }; + + expect(app.isShared(context)).toBe(false); + }); + + it('should return false if route is trashcan route', () => { + const context: any = { + selection: { + file: {} + }, + navigation: { + url: '/trashcan' + } + }; + + expect(app.isShared(context)).toBe(false); + }); + + it('should return false if selection is not shared', () => { + const context: any = { + selection: { + file: { + entry: { + properties: {} + } + } + }, + navigation: { + url: '/other' + } + }; + + expect(app.isShared(context)).toBe(false); + }); + + it('should return true if selection is shared', () => { + const context: any = { + selection: { + file: { + entry: { + properties: { + 'qshare:sharedId': 'some-id' + } + } + } + }, + navigation: { + url: '/other' + } + }; + + expect(app.isShared(context)).toBe(true); + }); + }); }); diff --git a/projects/aca-shared/rules/src/app.rules.ts b/projects/aca-shared/rules/src/app.rules.ts index 129c4d5851..426d49eabd 100644 --- a/projects/aca-shared/rules/src/app.rules.ts +++ b/projects/aca-shared/rules/src/app.rules.ts @@ -114,7 +114,7 @@ export function canEditFolder(context: RuleContext): boolean { * JSON ref: `app.selection.file.isShared` */ export function isShared(context: RuleContext): boolean { - if (navigation.isSharedFiles(context) && !context.selection.isEmpty) { + if (navigation.isSharedFiles(context) && context.selection.file) { return true; } From e12fe9375987997225f6ac2668bf4f8b8deccaf5 Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Thu, 27 Jun 2019 15:13:59 +0300 Subject: [PATCH 239/259] relocate edit folder (#1142) --- src/assets/app.extensions.json | 37 +++++++++++++++------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/src/assets/app.extensions.json b/src/assets/app.extensions.json index 55676b2385..70793f690b 100644 --- a/src/assets/app.extensions.json +++ b/src/assets/app.extensions.json @@ -339,11 +339,23 @@ "visible": "app.selection.file.canUploadVersion" } }, + { + "id": "app.toolbar.editFolder", + "order": 300, + "title": "APP.ACTIONS.EDIT", + "icon": "create", + "actions": { + "click": "EDIT_FOLDER" + }, + "rules": { + "visible": "canEditFolder" + } + }, { "id": "app.toolbar.favorite", "comment": "workaround for Recent Files and Search API issue", "type": "custom", - "order": 300, + "order": 400, "component": "app.toolbar.toggleFavorite", "rules": { "visible": "canToggleFavorite" @@ -352,7 +364,7 @@ { "id": "app.libraries.toolbar.toggleFavorite", "type": "custom", - "order": 301, + "order": 401, "component": "app.toolbar.toggleFavoriteLibrary", "rules": { "visible": "app.selection.library" @@ -360,7 +372,7 @@ }, { "id": "app.toolbar.favorite.add", - "order": 302, + "order": 402, "title": "APP.ACTIONS.FAVORITE", "icon": "star_border", "actions": { @@ -372,7 +384,7 @@ }, { "id": "app.toolbar.favorite.remove", - "order": 303, + "order": 403, "title": "APP.ACTIONS.REMOVE_FAVORITE", "icon": "star", "actions": { @@ -385,23 +397,6 @@ { "id": "app.create.separator.1", "type": "separator", - "order": 400 - }, - { - "id": "app.toolbar.editFolder", - "order": 450, - "title": "APP.ACTIONS.EDIT", - "icon": "create", - "actions": { - "click": "EDIT_FOLDER" - }, - "rules": { - "visible": "canEditFolder" - } - }, - { - "id": "app.create.separator.2", - "type": "separator", "order": 500 }, { From 39de66088cb29318ece0ccac1d38fbba3667b6ae Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Fri, 28 Jun 2019 12:06:48 +0300 Subject: [PATCH 240/259] reordering (#1143) --- src/assets/app.extensions.json | 47 +++++++++++++++------------------- 1 file changed, 21 insertions(+), 26 deletions(-) diff --git a/src/assets/app.extensions.json b/src/assets/app.extensions.json index 70793f690b..fb754c4fb4 100644 --- a/src/assets/app.extensions.json +++ b/src/assets/app.extensions.json @@ -831,14 +831,9 @@ "visible": "app.selection.file.canUploadVersion" } }, - { - "id": "app.viewer.more.separator.1", - "type": "separator", - "order": 300 - }, { "id": "app.viewer.favorite.add", - "order": 400, + "order": 300, "title": "APP.ACTIONS.FAVORITE", "icon": "star_border", "actions": { @@ -850,7 +845,7 @@ }, { "id": "app.viewer.favorite.remove", - "order": 401, + "order": 301, "title": "APP.ACTIONS.REMOVE_FAVORITE", "icon": "star", "actions": { @@ -864,44 +859,44 @@ "id": "app.viewer.favorite", "comment": "workaround for Recent Files and Search API issue", "type": "custom", - "order": 402, + "order": 302, "component": "app.toolbar.toggleFavorite", "rules": { "visible": "canToggleFavorite" } }, { - "id": "app.viewer.more.separator.2", + "id": "app.viewer.more.separator.1", "type": "separator", - "order": 500 + "order": 400 }, { - "id": "app.viewer.copy", - "order": 600, - "title": "APP.ACTIONS.COPY", - "icon": "content_copy", + "id": "app.viewer.move", + "order": 500, + "title": "APP.ACTIONS.MOVE", + "icon": "adf:move_file", "actions": { - "click": "COPY_NODES" + "click": "MOVE_NODES" }, "rules": { - "visible": "canCopyNode" + "visible": "app.selection.canDelete" } }, { - "id": "app.viewer.move", - "order": 700, - "title": "APP.ACTIONS.MOVE", - "icon": "adf:move_file", + "id": "app.viewer.copy", + "order": 600, + "title": "APP.ACTIONS.COPY", + "icon": "content_copy", "actions": { - "click": "MOVE_NODES" + "click": "COPY_NODES" }, "rules": { - "visible": "app.selection.canDelete" + "visible": "canCopyNode" } }, { "id": "app.viewer.delete", - "order": 800, + "order": 700, "title": "APP.ACTIONS.DELETE", "icon": "delete", "actions": { @@ -914,12 +909,12 @@ { "id": "app.viewer.more.separator.3", "type": "separator", - "order": 900 + "order": 800 }, { "id": "app.viewer.versions", - "order": 1000, + "order": 900, "title": "APP.ACTIONS.VERSIONS", "icon": "history", "actions": { @@ -931,7 +926,7 @@ }, { "id": "app.viewer.permissions", - "order": 1100, + "order": 1000, "title": "APP.ACTIONS.PERMISSIONS", "icon": "settings_input_component", "actions": { From ef8f779947210a4e8665dd7841daba22992df61b Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Tue, 2 Jul 2019 10:03:56 +0100 Subject: [PATCH 241/259] update cspell config --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c9b631e236..8f9a6a31e7 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "start:docker": "docker-compose up -d --build && npm run wait:app", "stop:docker": "docker-compose stop", "e2e:docker": "npm run start:docker && npm run e2e && npm run stop:docker", - "spellcheck": "cspell 'src/**/*.ts' 'e2e/**/*.ts' 'projects/**/*.ts'", + "spellcheck": "cspell '{src,e2e,projects}/**/*.ts'", "inspect.bundle": "ng build app --prod --stats-json && npx webpack-bundle-analyzer dist/app/stats.json", "format:check": "prettier --check \"src/{app,environments}/**/*.{ts,js,css,scss,html}\"", "format:fix": "prettier --write \"src/{app,environments}/**/*.{ts,js,css,scss,html}\"", From c83a3f53cc92cb18aec65e4d89a09c5dc83a25c4 Mon Sep 17 00:00:00 2001 From: Suzana Dirla Date: Tue, 2 Jul 2019 13:24:35 +0300 Subject: [PATCH 242/259] [ACA-2288] Music / video stops playing when opening the Info drawer in the viewer (#1146) * [ACA-2288] avoid triggering ngOnChanges on showRightSide toggle * [ACA-2288] code review change * check mediumDate corresponding format --- e2e/configs.ts | 2 +- src/app/components/preview/preview.component.html | 7 +++++-- src/app/components/preview/preview.component.scss | 4 ++++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/e2e/configs.ts b/e2e/configs.ts index cfc0835c6a..d1504f59aa 100755 --- a/e2e/configs.ts +++ b/e2e/configs.ts @@ -43,7 +43,7 @@ export const ADMIN_FULL_NAME = 'Administrator'; export const E2E_ROOT_PATH = __dirname; // Dates -export const DATE_FORMAT = 'MMM DD, YYYY'; +export const DATE_FORMAT = 'MMM D, YYYY'; export const DATE_TIME_FORMAT = 'MMM D, YYYY, H:mm'; // Application Routes diff --git a/src/app/components/preview/preview.component.html b/src/app/components/preview/preview.component.html index 4618a47cac..8430ee1711 100644 --- a/src/app/components/preview/preview.component.html +++ b/src/app/components/preview/preview.component.html @@ -1,10 +1,13 @@ button:last-child { display: none; } + +.adf-viewer.right_side--hide .adf-viewer__sidebar__right { + width: 0; +} From 1bcb29473d4de08952edcc06596ef8d34beb43cd Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Tue, 2 Jul 2019 15:45:58 +0300 Subject: [PATCH 243/259] relative order for context menu (#1145) --- projects/adf-office-services-ext/assets/aos.plugin.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/adf-office-services-ext/assets/aos.plugin.json b/projects/adf-office-services-ext/assets/aos.plugin.json index 3a903057cc..ee56e6ed23 100644 --- a/projects/adf-office-services-ext/assets/aos.plugin.json +++ b/projects/adf-office-services-ext/assets/aos.plugin.json @@ -39,7 +39,7 @@ "contextMenu": [ { "id": "aos.context.openWith.office", - "order": 90, + "order": 450, "icon": "edit", "title": "AOS.ACTION_TITLE", "actions": { From b0121f06f8f7bf7c558cd556934ec001dd46f5e6 Mon Sep 17 00:00:00 2001 From: Adina Parpalita Date: Wed, 3 Jul 2019 07:03:02 +0300 Subject: [PATCH 244/259] [ACA-2380] refactor actions-available tests (#1144) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * compare arrays of actions instead of checking the available actions one by one add more tests for more file types reorganise and separate test files use correct capitalisation of “Leave Library”, according to ACA-2473 add some try catch blocks * fix test and rebalance suites * remove hidden old info button - that exists in DOM, even though hidden, after fix of [ACA-2288] issue * change actions order after ACA-2649 --- .travis.yml | 8 +- e2e/components/data-table/data-table.ts | 23 +- e2e/components/menu/menu.ts | 7 + e2e/components/toolbar/toolbar.ts | 8 +- .../context-menu-multiple-selection.test.ts | 656 ------ .../context-menu-single-selection.test.ts | 697 ------ .../files-folders/favorites.test.ts | 182 ++ .../files-folders/personal.test.ts | 244 ++ .../files-folders/recent.test.ts | 212 ++ .../files-folders/search.test.ts | 291 +++ .../files-folders/shared.test.ts | 162 ++ .../files-folders/test-data-files-folders.ts | 472 ++++ .../files-folders/trash.test.ts | 106 + .../files-folders/viewer.test.ts | 421 ++++ e2e/suites/actions-available/generic.test.ts | 224 ++ .../libraries/library.test.ts | 328 +++ .../libraries/test-data-libraries.ts | 156 ++ ...cial-permissions-available-actions.test.ts | 2009 ----------------- .../other-permissions.test.ts | 841 +++++++ .../permissions-favorites.test.ts | 198 ++ .../permissions-my-libraries.test.ts | 266 +++ .../permissions-search.test.ts | 310 +++ .../permissions-shared.test.ts | 179 ++ .../permissions-viewer.test.ts | 401 ++++ .../test-data-permissions.ts | 335 +++ e2e/suites/actions-available/test-util.ts | 102 + .../toolbar-multiple-selection.test.ts | 703 ------ .../toolbar-single-selection.test.ts | 760 ------- e2e/suites/actions/library-actions.test.ts | 2 +- e2e/suites/viewer/viewer-actions.test.ts | 294 +-- .../apis/favorites/favorites-api.ts | 4 +- .../repo-client/apis/nodes/nodes-api.ts | 4 + .../repo-client/apis/sites/sites-api.ts | 6 +- .../repo-client/apis/upload/upload-api.ts | 11 +- protractor.conf.js | 4 +- src/assets/i18n/en.json | 2 +- 36 files changed, 5505 insertions(+), 5123 deletions(-) delete mode 100755 e2e/suites/actions-available/context-menu-multiple-selection.test.ts delete mode 100755 e2e/suites/actions-available/context-menu-single-selection.test.ts create mode 100755 e2e/suites/actions-available/files-folders/favorites.test.ts create mode 100755 e2e/suites/actions-available/files-folders/personal.test.ts create mode 100755 e2e/suites/actions-available/files-folders/recent.test.ts create mode 100755 e2e/suites/actions-available/files-folders/search.test.ts create mode 100755 e2e/suites/actions-available/files-folders/shared.test.ts create mode 100644 e2e/suites/actions-available/files-folders/test-data-files-folders.ts create mode 100755 e2e/suites/actions-available/files-folders/trash.test.ts create mode 100755 e2e/suites/actions-available/files-folders/viewer.test.ts create mode 100755 e2e/suites/actions-available/generic.test.ts create mode 100755 e2e/suites/actions-available/libraries/library.test.ts create mode 100644 e2e/suites/actions-available/libraries/test-data-libraries.ts delete mode 100755 e2e/suites/actions-available/special-permissions-available-actions.test.ts create mode 100755 e2e/suites/actions-available/special-permissions/other-permissions.test.ts create mode 100755 e2e/suites/actions-available/special-permissions/permissions-favorites.test.ts create mode 100755 e2e/suites/actions-available/special-permissions/permissions-my-libraries.test.ts create mode 100755 e2e/suites/actions-available/special-permissions/permissions-search.test.ts create mode 100755 e2e/suites/actions-available/special-permissions/permissions-shared.test.ts create mode 100755 e2e/suites/actions-available/special-permissions/permissions-viewer.test.ts create mode 100644 e2e/suites/actions-available/special-permissions/test-data-permissions.ts create mode 100644 e2e/suites/actions-available/test-util.ts delete mode 100755 e2e/suites/actions-available/toolbar-multiple-selection.test.ts delete mode 100755 e2e/suites/actions-available/toolbar-single-selection.test.ts diff --git a/.travis.yml b/.travis.yml index 89ff290a3c..a768059ad3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,10 +33,10 @@ jobs: - npm run test:ci - bash <(curl -s https://codecov.io/bash) -X gcov - stage: e2e - name: Test Suite appNavigation - script: npm run build.e2e && SUITE="--suite authentication,listViews,navigation,application,pagination" npm run e2e:docker - - name: Test Suite search&actionsAvailable - script: npm run build.e2e && SUITE="--suite search,actionsAvailable" npm run e2e:docker + name: Test Suite appNavigation&search + script: npm run build.e2e && SUITE="--suite authentication,listViews,navigation,application,pagination,search" npm run e2e:docker + - name: Test Suite actionsAvailable + script: npm run build.e2e && SUITE="--suite actionsAvailable" npm run e2e:docker - name: Test Suite addRemoveContent script: npm run build.e2e && SUITE="--suite addRemoveContent" npm run e2e:docker - name: Test Suite manageContent diff --git a/e2e/components/data-table/data-table.ts b/e2e/components/data-table/data-table.ts index 6f5d73a2d1..7917cf83bc 100755 --- a/e2e/components/data-table/data-table.ts +++ b/e2e/components/data-table/data-table.ts @@ -235,20 +235,29 @@ export class DataTable extends Component { const item = this.getRowFirstCell(name, location); await Utils.waitUntilElementClickable(item); await browser.actions().mouseMove(item).perform(); - await browser.actions().click().click().perform(); + await browser.actions().doubleClick().perform(); } catch (error) { console.log('--- catch: doubleClickOnRowByName', error); } } async selectItem(name: string, location: string = '') { - try{ - const item = this.getRowFirstCell(name, location); - await item.click(); - - } catch (e) { - console.log('--- select item catch : ', e); + const isSelected = await this.hasCheckMarkIcon(name, location); + if (!isSelected) { + try { + const item = this.getRowFirstCell(name, location); + await item.click(); + + } catch (e) { + console.log('--- select item catch : ', e); + } } + + } + + async clickItem(name: string, location: string = '') { + const item = this.getRowFirstCell(name, location); + await item.click(); } async clickNameLink(itemName: string) { diff --git a/e2e/components/menu/menu.ts b/e2e/components/menu/menu.ts index 71880de0a5..6dabbd736b 100755 --- a/e2e/components/menu/menu.ts +++ b/e2e/components/menu/menu.ts @@ -127,6 +127,13 @@ export class Menu extends Component { return await this.items.count(); } + async getMenuItems(): Promise { + return this.items.map(async (elem) => { + const text = await elem.element(by.css('span')).getText(); + return text; + }); + } + async clickNthItem(nth: number) { try { const elem = this.getNthItem(nth); diff --git a/e2e/components/toolbar/toolbar.ts b/e2e/components/toolbar/toolbar.ts index e350ac34ce..1e52b0c767 100755 --- a/e2e/components/toolbar/toolbar.ts +++ b/e2e/components/toolbar/toolbar.ts @@ -43,7 +43,7 @@ export class Toolbar extends Component { print: `.mat-icon-button[title='Print']`, fullScreen: `.mat-icon-button[title='Activate full-screen mode']`, joinLibrary: `.mat-icon-button[title='Join']`, - leaveLibrary: `.mat-icon-button[title='Leave library']`, + leaveLibrary: `.mat-icon-button[title='Leave Library']`, permanentlyDelete: `.mat-icon-button[title='Permanently Delete']`, restore: `.mat-icon-button[title='Restore']` }; @@ -77,6 +77,12 @@ export class Toolbar extends Component { return await this.buttons.count(); } + async getButtons(): Promise { + return this.buttons.map(async elem => { + return await elem.getAttribute('title'); + }); + } + async isButtonPresent(title: string) { const elem = this.component.element(by.css(`${Toolbar.selectors.button}[title="${title}"]`)); return await elem.isPresent(); diff --git a/e2e/suites/actions-available/context-menu-multiple-selection.test.ts b/e2e/suites/actions-available/context-menu-multiple-selection.test.ts deleted file mode 100755 index 7b974bc8b7..0000000000 --- a/e2e/suites/actions-available/context-menu-multiple-selection.test.ts +++ /dev/null @@ -1,656 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2019 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { LoginPage, BrowsingPage, SearchResultsPage } from '../../pages/pages'; -import { SITE_VISIBILITY } from '../../configs'; -import { RepoClient } from '../../utilities/repo-client/repo-client'; -import { Utils } from '../../utilities/utils'; - -describe('Context menu actions - multiple selection : ', () => { - const username = `user-${Utils.random()}`; - - const parent = `parent=${Utils.random()}`; let parentId; - - const file1 = `my-file1-${Utils.random()}.txt`; let file1Id; - const file2 = `my-file2-${Utils.random()}.txt`; let file2Id; - const fileLocked1 = `my-fileLocked1-${Utils.random()}.txt`; let fileLocked1Id; - const fileLocked2 = `my-fileLocked2-${Utils.random()}.txt`; let fileLocked2Id; - - const folder1 = `my-folder1-${Utils.random()}`; let folder1Id; - const folder2 = `my-folder2-${Utils.random()}`; let folder2Id; - - const fileInTrash1 = `deletedFile1-${Utils.random()}.txt`; let fileInTrash1Id; - const fileInTrash2 = `deletedFile2-${Utils.random()}.txt`; let fileInTrash2Id; - const folderInTrash1 = `deletedFolder1-${Utils.random()}`; let folderInTrash1Id; - const folderInTrash2 = `deletedFolder2-${Utils.random()}`; let folderInTrash2Id; - - const siteName = `site-${Utils.random()}`; - const file1Site = `my-inSite-file1-${Utils.random()}.txt`; - const file2Site = `my-inSite-file2-${Utils.random()}.txt`; - const fileLocked1Site = `my-inSite-fileLocked1-${Utils.random()}.txt`; let fileLocked1SiteId; - const fileLocked2Site = `my-inSite-fileLocked2-${Utils.random()}.txt`; let fileLocked2SiteId; - const folder1Site = `my-inSite-folder1-${Utils.random()}`; - const folder2Site = `my-inSite-folder2-${Utils.random()}`; - - const apis = { - admin: new RepoClient(), - user: new RepoClient(username, username) - }; - - const loginPage = new LoginPage(); - const page = new BrowsingPage(); - const { dataTable } = page; - const contextMenu = dataTable.menu; - const searchResultsPage = new SearchResultsPage(); - const { searchInput } = searchResultsPage.header; - - beforeAll(async (done) => { - await apis.admin.people.createUser({ username }); - parentId = (await apis.user.nodes.createFolder(parent)).entry.id; - - file1Id = (await apis.user.nodes.createFile(file1, parentId)).entry.id; - file2Id = (await apis.user.nodes.createFile(file2, parentId)).entry.id; - folder1Id = (await apis.user.nodes.createFolder(folder1, parentId)).entry.id; - folder2Id = (await apis.user.nodes.createFolder(folder2, parentId)).entry.id; - - fileLocked1Id = (await apis.user.nodes.createFile(fileLocked1, parentId)).entry.id; - fileLocked2Id = (await apis.user.nodes.createFile(fileLocked2, parentId)).entry.id; - await apis.user.nodes.lockFile(fileLocked1Id); - await apis.user.nodes.lockFile(fileLocked2Id); - - await apis.user.sites.createSite(siteName, SITE_VISIBILITY.PUBLIC); - const docLibId = await apis.user.sites.getDocLibId(siteName); - await apis.user.nodes.createFile(file1Site, docLibId); - await apis.user.nodes.createFile(file2Site, docLibId); - await apis.user.nodes.createFolder(folder1Site, docLibId); - await apis.user.nodes.createFolder(folder2Site, docLibId); - fileLocked1SiteId = (await apis.user.nodes.createFile(fileLocked1Site, docLibId)).entry.id; - fileLocked2SiteId = (await apis.user.nodes.createFile(fileLocked2Site, docLibId)).entry.id; - await apis.user.nodes.lockFile(fileLocked1SiteId); - await apis.user.nodes.lockFile(fileLocked2SiteId); - - await apis.user.shared.shareFilesByIds([ file1Id, file2Id, fileLocked1Id, fileLocked2Id ]); - await apis.user.shared.waitForApi({ expect: 4 }); - - await apis.user.favorites.addFavoritesByIds('file', [ file1Id, file2Id, fileLocked1Id, fileLocked2Id ]); - await apis.user.favorites.addFavoritesByIds('folder', [ folder1Id, folder2Id ]); - await apis.user.favorites.waitForApi({ expect: 6 + 1 }); - - fileInTrash1Id = (await apis.user.nodes.createFile(fileInTrash1)).entry.id; - fileInTrash2Id = (await apis.user.nodes.createFile(fileInTrash2)).entry.id; - folderInTrash1Id = (await apis.user.nodes.createFolder(folderInTrash1)).entry.id; - folderInTrash2Id = (await apis.user.nodes.createFolder(folderInTrash2)).entry.id; - await apis.user.nodes.deleteNodesById([ fileInTrash1Id, fileInTrash2Id, folderInTrash1Id, folderInTrash2Id ], false); - - await loginPage.loginWith(username); - done(); - }); - - afterAll(async (done) => { - await apis.user.nodes.deleteNodeById(parentId); - await apis.user.sites.deleteSite(siteName); - await apis.user.trashcan.emptyTrash(); - done(); - }); - - describe('Generic tests', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await page.clickPersonalFilesAndWait(); - await dataTable.doubleClickOnRowByName(parent); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('Context menu appears on right click on a multiple selection of items - [C286268]', async () => { - await dataTable.selectMultipleItems([ file1, file2 ]); - await dataTable.rightClickOnMultipleSelection(); - - expect(await dataTable.hasContextMenu()).toBe(true, 'Context menu is not displayed'); - }); - - it('Context menu appears when right clicking on a single item while having multiple items selected - [C286269]', async () => { - await dataTable.selectMultipleItems([ file2, folder1 ]); - await dataTable.rightClickOnItem(file1); - - expect(await dataTable.hasContextMenu()).toBe(true, `Context menu is not displayed for ${file1}`); - expect(await dataTable.countSelectedRows()).toEqual(1, 'incorrect number of selected rows'); - expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${file1}`); - expect(await dataTable.hasCheckMarkIcon(file1)).toBe(true, `${file1} is not selected`); - expect(await dataTable.hasCheckMarkIcon(file2)).toBe(false, `${file2} is selected`); - expect(await dataTable.hasCheckMarkIcon(folder1)).toBe(false, `${folder1} is selected`); - }); - }); - - describe('on Personal Files', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await page.clickPersonalFilesAndWait(); - await dataTable.doubleClickOnRowByName(parent); - await dataTable.waitForBody(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('correct actions appear when multiple files are selected - [C280661]', async () => { - await dataTable.selectMultipleItems([file1, file2]); - await dataTable.rightClickOnMultipleSelection(); - - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed`); - expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed`); - expect(await contextMenu.isRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - }); - - it('correct actions appear when multiple locked files are selected - [C297627]', async () => { - await dataTable.selectMultipleItems([fileLocked1, fileLocked2]); - await dataTable.rightClickOnMultipleSelection(); - - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed`); - expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed`); - expect(await contextMenu.isRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - }); - - it('correct actions appear when multiple folders are selected - [C280632]', async () => { - await dataTable.selectMultipleItems([folder1, folder2]); - await dataTable.rightClickOnMultipleSelection(); - - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed`); - expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed`); - expect(await contextMenu.isRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - }); - - it('correct actions appear when both files and folders are selected - [C280631]', async () => { - await dataTable.selectMultipleItems([file1, file2, folder1, folder2]); - await dataTable.rightClickOnMultipleSelection(); - - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed`); - expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed`); - expect(await contextMenu.isRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - }); - }); - - describe('on File Libraries', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await page.goToMyLibrariesAndWait(); - await dataTable.doubleClickOnRowByName(siteName); - await dataTable.waitForHeader(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('correct actions appear when multiple files are selected - [C280641]', async () => { - await dataTable.selectMultipleItems([ file1Site, file2Site ]); - await dataTable.rightClickOnMultipleSelection(); - - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed`); - expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed`); - expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - }); - - it('correct actions appear when multiple locked files are selected - [C297628]', async () => { - await dataTable.selectMultipleItems([ fileLocked1Site, fileLocked2Site ]); - await dataTable.rightClickOnMultipleSelection(); - - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed`); - expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed`); - expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - }); - - it('correct actions appear when multiple folders are selected - [C280574]', async () => { - await dataTable.selectMultipleItems([ folder1Site, folder2Site ]); - await dataTable.rightClickOnMultipleSelection(); - - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed`); - expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed`); - expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - }); - - it('correct actions appear when both files and folders are selected - [C280642]', async () => { - await dataTable.selectMultipleItems([ file1Site, file2Site, folder1Site, folder2Site ]); - await dataTable.rightClickOnMultipleSelection(); - - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed`); - expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed`); - expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - }); - }); - - describe('on Shared Files', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await page.clickSharedFilesAndWait(); - await dataTable.clearSelection(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('correct actions appear when multiple files are selected - [C280648]', async () => { - await dataTable.selectMultipleItems([ file1, file2 ]); - await dataTable.rightClickOnMultipleSelection(); - - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed`); - expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed`); - expect(await contextMenu.isToggleRemoveFavoritePresent()).toBe(true, `Toggle favorite is not displayed`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is not displayed`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - }); - - it('correct actions appear when multiple locked files are selected - [C297629]', async () => { - await dataTable.selectMultipleItems([ fileLocked1, fileLocked2 ]); - await dataTable.rightClickOnMultipleSelection(); - - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed`); - expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed`); - expect(await contextMenu.isToggleRemoveFavoritePresent()).toBe(true, `Toggle favorite is not displayed`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is not displayed`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - }); - }); - - describe('on Recent Files', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await page.clickRecentFilesAndWait(); - await dataTable.clearSelection(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('correct actions appear when multiple files are selected - [C280652]', async () => { - await dataTable.selectMultipleItems([ file1, file2 ]); - await dataTable.rightClickOnMultipleSelection(); - - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed`); - expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed`); - expect(await contextMenu.isToggleRemoveFavoritePresent()).toBe(true, `Toggle favorite is not displayed`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - }); - - it('correct actions appear when multiple locked files are selected - [C297630]', async () => { - await dataTable.selectMultipleItems([ fileLocked1, fileLocked2 ]); - await dataTable.rightClickOnMultipleSelection(); - - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed`); - expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed`); - expect(await contextMenu.isToggleRemoveFavoritePresent()).toBe(true, `Toggle favorite is not displayed`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - }); - }); - - describe('on Favorites', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await page.clickFavoritesAndWait(); - await dataTable.clearSelection(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('correct actions appear when multiple files are selected - [C280656]', async () => { - await dataTable.selectMultipleItems([ file1, file2 ]); - await dataTable.rightClickOnMultipleSelection(); - - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed`); - expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed`); - expect(await contextMenu.isToggleRemoveFavoritePresent()).toBe(true, `Toggle favorite is not displayed`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - }); - - it('correct actions appear when multiple locked files are selected - [C297631]', async () => { - await dataTable.selectMultipleItems([ fileLocked1, fileLocked2 ]); - await dataTable.rightClickOnMultipleSelection(); - - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed`); - expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed`); - expect(await contextMenu.isToggleRemoveFavoritePresent()).toBe(true, `Toggle favorite is not displayed`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - }); - - it('correct actions appear when multiple folders are selected - [C280664]', async () => { - await dataTable.selectMultipleItems([ folder1, folder2 ]); - await dataTable.rightClickOnMultipleSelection(); - - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed`); - expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed`); - expect(await contextMenu.isToggleRemoveFavoritePresent()).toBe(true, `Toggle favorite is not displayed`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - }); - - it('correct actions appear when both files and folders are selected - [C280657]', async () => { - await dataTable.selectMultipleItems([ file1, file2, folder1, folder2 ]); - await dataTable.rightClickOnMultipleSelection(); - - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed`); - expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed`); - expect(await contextMenu.isToggleRemoveFavoritePresent()).toBe(true, `Toggle favorite is not displayed`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - }); - }); - - describe('on Trash', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await page.clickTrashAndWait(); - await dataTable.clearSelection(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('correct actions appear when multiple files are selected - [C286273]', async () => { - await dataTable.selectMultipleItems([ fileInTrash1, fileInTrash2 ]); - await dataTable.rightClickOnMultipleSelection(); - - expect(await contextMenu.isPermanentDeletePresent()).toBe(true, 'Permanently delete is not displayed'); - expect(await contextMenu.isRestorePresent()).toBe(true, 'Restore is not displayed'); - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(false, 'Download is displayed'); - expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); - expect(await contextMenu.isCopyPresent()).toBe(false, `Copy is displayed`); - // expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await contextMenu.isFavoritePresent()).toBe(false, `Favorite is displayed`); - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - }); - - it('correct actions appear when multiple folders are selected - [C286274]', async () => { - await dataTable.selectMultipleItems([ folderInTrash1, folderInTrash2 ]); - await dataTable.rightClickOnMultipleSelection(); - - expect(await contextMenu.isPermanentDeletePresent()).toBe(true, 'Permanently delete is not displayed'); - expect(await contextMenu.isRestorePresent()).toBe(true, 'Restore is not displayed'); - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(false, 'Download is displayed'); - expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); - expect(await contextMenu.isCopyPresent()).toBe(false, `Copy is displayed`); - // expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await contextMenu.isFavoritePresent()).toBe(false, `Favorite is displayed`); - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - }); - - it('correct actions appear when both files and folders are selected - [C286275]', async () => { - await dataTable.selectMultipleItems([ fileInTrash1, fileInTrash2, folderInTrash1, folderInTrash2 ]); - await dataTable.rightClickOnMultipleSelection(); - - expect(await contextMenu.isPermanentDeletePresent()).toBe(true, 'Permanently delete is not displayed'); - expect(await contextMenu.isRestorePresent()).toBe(true, 'Restore is not displayed'); - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(false, 'Download is displayed'); - expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); - expect(await contextMenu.isCopyPresent()).toBe(false, `Copy is displayed`); - // expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await contextMenu.isFavoritePresent()).toBe(false, `Favorite is displayed`); - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - }); - }); - - describe('on Search Results', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await page.clickPersonalFilesAndWait(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('correct actions appear when multiple files are selected - [C291831]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkOnlyFiles(); - await searchInput.searchFor('my-inSite-file'); - await dataTable.selectMultipleItems([ file1Site, file2Site ]); - await dataTable.rightClickOnMultipleSelection(); - - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await contextMenu.isToggleFavoritePresent()).toBe(true, `Toggle favorite is not displayed`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - }); - - it('correct actions appear when multiple locked files are selected - [C297632]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkOnlyFiles(); - await searchInput.searchFor('my-inSite-file'); - await dataTable.selectMultipleItems([ fileLocked1Site, fileLocked2Site ]); - await dataTable.rightClickOnMultipleSelection(); - - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await contextMenu.isToggleFavoritePresent()).toBe(true, `Toggle favorite is not displayed`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - }); - - it('correct actions appear when multiple folders are selected - [C291832]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkOnlyFolders(); - await searchInput.searchFor('my-inSite-folder'); - await dataTable.selectMultipleItems([ folder1Site, folder2Site ]); - await dataTable.rightClickOnMultipleSelection(); - - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await contextMenu.isToggleFavoritePresent()).toBe(true, `Toggle favorite is not displayed`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - }); - - it('correct actions appear when both files and folders are selected - [C291833]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkFilesAndFolders(); - await searchInput.searchFor('my-inSite-f'); - await dataTable.selectMultipleItems([ file1Site, file2Site, folder1Site, folder2Site ]); - await dataTable.rightClickOnMultipleSelection(); - - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await contextMenu.isToggleFavoritePresent()).toBe(true, `Toggle favorite is not displayed`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - }); - }); -}); diff --git a/e2e/suites/actions-available/context-menu-single-selection.test.ts b/e2e/suites/actions-available/context-menu-single-selection.test.ts deleted file mode 100755 index 84a2091b77..0000000000 --- a/e2e/suites/actions-available/context-menu-single-selection.test.ts +++ /dev/null @@ -1,697 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2019 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { LoginPage, BrowsingPage, SearchResultsPage } from '../../pages/pages'; -import { SITE_VISIBILITY } from '../../configs'; -import { RepoClient } from '../../utilities/repo-client/repo-client'; -import { Utils } from '../../utilities/utils'; - -describe('Context menu actions - single selection : ', () => { - const username = `user-${Utils.random()}`; - - const fileUser = `fileUser-${Utils.random()}.txt`; let fileUserId; - const folderUser = `folderUser-${Utils.random()}`; let folderUserId; - const fileInTrash = `fileForDelete-${Utils.random()}.txt`; let fileInTrashId; - const folderInTrash = `folderForDelete-${Utils.random()}`; let folderInTrashId; - const fileLocked = `fileLocked-${Utils.random()}.txt`; let fileLockedId; - - const siteName = `userSite-${Utils.random()}`; - const fileSiteUser = `fileUser-${Utils.random()}.txt`; - const fileLockedInSite = `file-locked-site-${Utils.random()}.txt`; let fileLockedInSiteId; - const folderSiteUser = `folderUser-${Utils.random()}`; - - const adminPublic = `admin-public-${Utils.random()}`; - const adminModerated = `admin-moderated-${Utils.random()}`; - - const apis = { - admin: new RepoClient(), - user: new RepoClient(username, username) - }; - - const loginPage = new LoginPage(); - const page = new BrowsingPage(); - const { dataTable } = page; - const contextMenu = dataTable.menu; - const searchResultsPage = new SearchResultsPage(); - const { searchInput } = searchResultsPage.header; - - beforeAll(async (done) => { - await apis.admin.people.createUser({ username }); - - fileUserId = (await apis.user.nodes.createFile(fileUser)).entry.id; - folderUserId = (await apis.user.nodes.createFolder(folderUser)).entry.id; - - fileLockedId = (await apis.user.nodes.createFile(fileLocked)).entry.id; - await apis.user.nodes.lockFile(fileLockedId); - - await apis.user.sites.createSite(siteName, SITE_VISIBILITY.PUBLIC); - const docLibId = await apis.user.sites.getDocLibId(siteName); - await apis.user.nodes.createFile(fileSiteUser, docLibId); - fileLockedInSiteId = (await apis.user.nodes.createFile(fileLockedInSite, docLibId)).entry.id; - await apis.user.nodes.createFolder(folderSiteUser, docLibId); - await apis.user.nodes.lockFile(fileLockedInSiteId); - - fileInTrashId = (await apis.user.nodes.createFiles([fileInTrash])).entry.id; - folderInTrashId = (await apis.user.nodes.createFolders([ folderInTrash ])).entry.id; - await apis.user.nodes.deleteNodeById(fileInTrashId, false); - await apis.user.nodes.deleteNodeById(folderInTrashId, false); - - await apis.user.shared.shareFileById(fileUserId); - await apis.user.shared.shareFileById(fileLockedId); - await apis.user.shared.waitForApi({ expect: 2 }); - - await apis.user.favorites.addFavoriteById('file', fileUserId); - await apis.user.favorites.addFavoriteById('file', fileLockedId); - await apis.user.favorites.addFavoriteById('folder', folderUserId); - await apis.user.favorites.waitForApi({ expect: 4 }); - - await apis.admin.sites.createSite(adminPublic); - await apis.admin.sites.createSite(adminModerated, SITE_VISIBILITY.MODERATED); - await apis.user.favorites.addFavoriteById('site', adminPublic); - await apis.user.favorites.addFavoriteById('site', adminModerated); - await apis.user.sites.requestToJoin(adminModerated); - - await apis.user.queries.waitForSites(siteName, { expect: 1 }); - await apis.user.queries.waitForSites(adminPublic, { expect: 1 }); - await apis.user.queries.waitForSites(adminModerated, { expect: 1 }); - - await loginPage.loginWith(username); - done(); - }); - - afterAll(async (done) => { - await apis.user.nodes.deleteNodeById(fileUserId); - await apis.user.nodes.deleteNodeById(folderUserId); - await apis.user.sites.deleteSite(siteName); - await apis.admin.sites.deleteSite(adminPublic); - await apis.admin.sites.deleteSite(adminModerated); - await apis.user.trashcan.emptyTrash(); - done(); - }); - - describe('Generic tests', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await page.clickPersonalFilesAndWait(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('Row is marked with a check circle icon on direct right click - [C286252]', async () => { - await dataTable.rightClickOnItem(fileUser); - - expect(await dataTable.hasCheckMarkIcon(fileUser)).toBe(true, 'check mark missing'); - }); - - it('Context menu appears on direct right click on an item - [C286253]', async () => { - await dataTable.rightClickOnItem(fileUser); - - expect(await dataTable.hasContextMenu()).toBe(true, 'Context menu is not displayed'); - }); - - it('Context menu appears when selecting an item and then right clicking on it - [C286254]', async () => { - await dataTable.selectItem(fileUser); - await dataTable.rightClickOnItem(fileUser); - - expect(await dataTable.hasContextMenu()).toBe(true, 'Context menu is not displayed'); - }); - - it('Context menu appears correctly when right clicking on another item - [C284666]', async () => { - await dataTable.selectItem(fileUser); - await dataTable.rightClickOnItem(folderUser); - - expect(await dataTable.hasContextMenu()).toBe(true, `Context menu is not displayed for ${folderUser}`); - expect(await contextMenu.isEditFolderPresent()).toBe(true, `Edit folder is not displayed for ${folderUser}`); - expect(await dataTable.hasCheckMarkIcon(folderUser)).toBe(true, `${folderUser} is not selected`); - expect(await dataTable.hasCheckMarkIcon(fileUser)).toBe(false, `${fileUser} is not selected`); - }); - - it('Context menu closes when clicking away from it - [C280619]', async () => { - await dataTable.rightClickOnItem(fileUser); - - expect(await dataTable.hasContextMenu()).toBe(true, 'Context menu is not displayed'); - - await page.sidenav.getActiveLink().click(); - - expect(await dataTable.hasContextMenu()).toBe(false, 'Context menu is displayed'); - }); - }); - - describe('on Personal Files', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await page.clickPersonalFilesAndWait(); - await dataTable.clearSelection(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('Context menu has the correct actions for a file - [C280615]', async () => { - await dataTable.rightClickOnItem(fileUser); - - expect(await contextMenu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed for ${fileUser}`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${fileUser}`); - expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileUser}`); - expect(await contextMenu.isViewPresent()).toBe(true, `View is not displayed for ${fileUser}`); - expect(await contextMenu.isRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${fileUser}`); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileUser}`); - expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed for ${fileUser}`); - expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed for ${fileUser}`); - expect(await contextMenu.isSharePresent()).toBe(true, `Share is not displayed for ${fileUser}`); - expect(await contextMenu.isManageVersionsPresent()).toBe(true, `Manage Versions is not displayed for ${fileUser}`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed for ${fileUser}`); - expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed for ${fileUser}`); - expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileUser}`); - expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${fileUser}`); - }); - - it('Context menu has the correct actions for a locked file - [C297633]', async () => { - await dataTable.rightClickOnItem(fileLocked); - - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileLocked}`); - expect(await contextMenu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed for ${fileLocked}`); - expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLocked}`); - expect(await contextMenu.isViewPresent()).toBe(true, `View is not displayed for ${fileLocked}`); - expect(await contextMenu.isRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${fileLocked}`); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLocked}`); - expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed for ${fileLocked}`); - expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed for ${fileLocked}`); - expect(await contextMenu.isSharePresent()).toBe(true, `Share is not displayed for ${fileLocked}`); - expect(await contextMenu.isManageVersionsPresent()).toBe(true, `Manage Versions is not displayed for ${fileLocked}`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed for ${fileLocked}`); - expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed for ${fileLocked}`); - expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLocked}`); - expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${fileLocked}`); - }); - - it('Context menu has the correct actions for a folder - [C280616]', async () => { - await dataTable.rightClickOnItem(folderUser); - - expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${folderUser}`); - expect(await contextMenu.isEditFolderPresent()).toBe(true, `Edit folder is not displayed for ${folderUser}`); - expect(await contextMenu.isRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${folderUser}`); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${folderUser}`); - expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed for ${folderUser}`); - expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed for ${folderUser}`); - expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed for ${folderUser}`); - expect(await contextMenu.isViewPresent()).toBe(false, `View is displayed for ${folderUser}`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions is displayed for ${folderUser}`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed for ${folderUser}`); - expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed for ${folderUser}`); - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${folderUser}`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${folderUser}`); - }); - }); - - describe('on File Libraries', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await page.goToMyLibrariesAndWait(); - await dataTable.doubleClickOnRowByName(siteName); - await dataTable.waitForHeader(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('Context menu has the correct actions for a file - [C280594]', async () => { - await dataTable.rightClickOnItem(fileSiteUser); - - expect(await contextMenu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed for ${fileSiteUser}`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${fileSiteUser}`); - expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileSiteUser}`); - expect(await contextMenu.isViewPresent()).toBe(true, `View is not displayed for ${fileSiteUser}`); - expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${fileSiteUser}`); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileSiteUser}`); - expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed for ${fileSiteUser}`); - expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed for ${fileSiteUser}`); - expect(await contextMenu.isSharePresent()).toBe(true, `Share is not displayed for ${fileSiteUser}`); - expect(await contextMenu.isManageVersionsPresent()).toBe(true, `Manage Versions not displayed for ${fileSiteUser}`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(true, `Upload new version not displayed for ${fileSiteUser}`); - expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed for ${fileSiteUser}`); - expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileSiteUser}`); - expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${fileSiteUser}`); - }); - - it('Context menu has the correct actions for a locked file - [C297634]', async () => { - await dataTable.rightClickOnItem(fileLockedInSite); - - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is not displayed for ${fileLockedInSite}`); - expect(await contextMenu.isCancelEditingPresent()).toBe(true, `Cancel editing is displayed for ${fileLockedInSite}`); - expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLockedInSite}`); - expect(await contextMenu.isViewPresent()).toBe(true, `View is not displayed for ${fileLockedInSite}`); - expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${fileLockedInSite}`); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLockedInSite}`); - expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed for ${fileLockedInSite}`); - expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed for ${fileLockedInSite}`); - expect(await contextMenu.isSharePresent()).toBe(true, `Share is not displayed for ${fileLockedInSite}`); - expect(await contextMenu.isManageVersionsPresent()).toBe(true, `Manage Versions not displayed for ${fileLockedInSite}`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(true, `Upload new version not displayed for ${fileLockedInSite}`); - expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed for ${fileLockedInSite}`); - expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLockedInSite}`); - expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${fileLockedInSite}`); - }); - - it('Context menu has the correct actions for a folder - [C280595]', async () => { - await dataTable.rightClickOnItem(folderSiteUser); - - expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${folderSiteUser}`); - expect(await contextMenu.isEditFolderPresent()).toBe(true, `Edit folder is not displayed for ${folderSiteUser}`); - expect(await contextMenu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${folderSiteUser}`); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${folderSiteUser}`); - expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed for ${folderSiteUser}`); - expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed for ${folderSiteUser}`); - expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed for ${folderSiteUser}`); - expect(await contextMenu.isViewPresent()).toBe(false, `View is displayed for ${folderSiteUser}`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions displayed for ${folderSiteUser}`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version displayed for ${folderSiteUser}`); - expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed for ${folderSiteUser}`); - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${folderSiteUser}`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${folderSiteUser}`); - }); - }); - - describe('on a library', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await dataTable.clearSelection(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('Available actions for a library - My Libraries - [C290080]', async () => { - await page.goToMyLibrariesAndWait(); - await dataTable.rightClickOnItem(siteName); - - expect(await dataTable.hasContextMenu()).toBe(true, 'Context menu is not displayed'); - expect(await contextMenu.isLeaveLibraryPresent()).toBe(true, `Leave is not displayed for ${siteName}`); - expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed for ${siteName}`); - expect(await contextMenu.isToggleRemoveFavoritePresent()).toBe(true, `Toggle favorite is not displayed for ${siteName}`); - }); - - it('Available actions for a library - Favorite Libraries - user is a member - [C290081]', async () => { - await page.goToFavoriteLibrariesAndWait(); - await dataTable.rightClickOnItem(siteName); - - expect(await dataTable.hasContextMenu()).toBe(true, 'Context menu is not displayed'); - expect(await contextMenu.isLeaveLibraryPresent()).toBe(true, `Leave is not displayed for ${siteName}`); - expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed for ${siteName}`); - expect(await contextMenu.isToggleRemoveFavoritePresent()).toBe(true, `Toggle favorite is not displayed for ${siteName}`); - }); - - it('Available actions for a library - Favorite Libraries - user is not a member - [C290082]', async () => { - await page.goToFavoriteLibrariesAndWait(); - await dataTable.rightClickOnItem(adminPublic); - - expect(await dataTable.hasContextMenu()).toBe(true, 'Context menu is not displayed'); - expect(await contextMenu.isJoinLibraryPresent()).toBe(true, `Join is not displayed for ${adminPublic}`); - expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed for ${adminPublic}`); - expect(await contextMenu.isToggleRemoveFavoritePresent()).toBe(true, `Toggle favorite is not displayed for ${adminPublic}`); - }); - - it('Available actions for a moderated library - Favorite Libraries - user requested to join - [C290089]', async () => { - await page.goToFavoriteLibrariesAndWait(); - await dataTable.rightClickOnItem(adminModerated); - - expect(await dataTable.hasContextMenu()).toBe(true, 'Context menu is not displayed'); - expect(await contextMenu.isCancelJoinPresent()).toBe(true, `Cancel join is not displayed for ${adminModerated}`); - expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed for ${adminModerated}`); - expect(await contextMenu.isToggleRemoveFavoritePresent()).toBe(true, `Toggle favorite is not displayed for ${adminModerated}`); - }); - - it('Available actions for a library - Search Results - user is a member - [C291812]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkLibraries(); - await searchInput.searchFor(siteName); - await dataTable.rightClickOnItem(siteName); - - expect(await dataTable.hasContextMenu()).toBe(true, 'Context menu is not displayed'); - expect(await contextMenu.isLeaveLibraryPresent()).toBe(true, `Leave is not displayed for ${siteName}`); - expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed for ${siteName}`); - expect(await contextMenu.isToggleRemoveFavoritePresent()).toBe(true, `Toggle favorite is not displayed for ${siteName}`); - }); - - it('Available actions for a library - Search Results - user is not a member - [C291813]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkLibraries(); - await searchInput.searchFor(adminPublic); - await dataTable.rightClickOnItem(adminPublic); - - expect(await dataTable.hasContextMenu()).toBe(true, 'Context menu is not displayed'); - expect(await contextMenu.isJoinLibraryPresent()).toBe(true, `Join is not displayed for ${adminPublic}`); - expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed for ${adminPublic}`); - expect(await contextMenu.isToggleRemoveFavoritePresent()).toBe(true, `Toggle favorite is not displayed for ${adminPublic}`); - }); - - it('Available actions for a moderated library - Search Results - user requested to join - [C291814]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkLibraries(); - await searchInput.searchFor(adminModerated); - await dataTable.rightClickOnItem(adminModerated); - - expect(await dataTable.hasContextMenu()).toBe(true, 'Context menu is not displayed'); - expect(await contextMenu.isCancelJoinPresent()).toBe(true, `Cancel join is not displayed for ${adminModerated}`); - expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed for ${adminModerated}`); - expect(await contextMenu.isToggleRemoveFavoritePresent()).toBe(true, `Toggle favorite is not displayed for ${adminModerated}`); - }); - }); - - describe('on Shared Files', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await page.clickSharedFilesAndWait(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('Context menu has the correct actions for a file - [C280601]', async () => { - await dataTable.rightClickOnItem(fileUser); - - // TODO: change expect to true when ACA-2173 is done - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileUser}`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${fileUser}`); - expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileUser}`); - expect(await contextMenu.isViewPresent()).toBe(true, `View is not displayed for ${fileUser}`); - expect(await contextMenu.isToggleRemoveFavoritePresent()).toBe(true, `Toggle favorite is not displayed for ${fileUser}`); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileUser}`); - expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed for ${fileUser}`); - expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed for ${fileUser}`); - expect(await contextMenu.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed for ${fileUser}`); - expect(await contextMenu.isManageVersionsPresent()).toBe(true, `Manage Versions not displayed for ${fileUser}`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(true, `Upload new version not displayed for ${fileUser}`); - expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed for ${fileUser}`); - expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileUser}`); - expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${fileUser}`); - }); - - it('Context menu has the correct actions for a locked file - [C297635]', async () => { - await dataTable.rightClickOnItem(fileLocked); - - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileLocked}`); - // TODO: change expect to true when ACA-2173 is done - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${fileLocked}`); - expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLocked}`); - expect(await contextMenu.isViewPresent()).toBe(true, `View is not displayed for ${fileLocked}`); - expect(await contextMenu.isToggleRemoveFavoritePresent()).toBe(true, `Toggle favorite is not displayed for ${fileLocked}`); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLocked}`); - expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed for ${fileLocked}`); - expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed for ${fileLocked}`); - expect(await contextMenu.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed for ${fileLocked}`); - expect(await contextMenu.isManageVersionsPresent()).toBe(true, `Manage Versions not displayed for ${fileLocked}`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(true, `Upload new version not displayed for ${fileLocked}`); - expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed for ${fileLocked}`); - expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLocked}`); - expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${fileLocked}`); - }); - }); - - describe('on Recent Files', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await page.clickRecentFilesAndWait(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('Context menu has the correct actions for a file - [C280622]', async () => { - await dataTable.rightClickOnItem(fileUser); - - expect(await contextMenu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed for ${fileUser}`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${fileUser}`); - expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileUser}`); - expect(await contextMenu.isViewPresent()).toBe(true, `View is not displayed for ${fileUser}`); - expect(await contextMenu.isToggleRemoveFavoritePresent()).toBe(true, `Toggle favorite is not displayed for ${fileUser}`); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileUser}`); - expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed for ${fileUser}`); - expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed for ${fileUser}`); - expect(await contextMenu.isSharePresent()).toBe(true, `Share is not displayed for ${fileUser}`); - expect(await contextMenu.isManageVersionsPresent()).toBe(true, `Manage Versions not displayed for ${fileUser}`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(true, `Upload new version not displayed for ${fileUser}`); - expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed for ${fileUser}`); - expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileUser}`); - expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${fileUser}`); - }); - - it('Context menu has the correct actions for a locked file - [C297636]', async () => { - await dataTable.rightClickOnItem(fileLocked); - - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileLocked}`); - expect(await contextMenu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed for ${fileLocked}`); - expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLocked}`); - expect(await contextMenu.isViewPresent()).toBe(true, `View is not displayed for ${fileLocked}`); - expect(await contextMenu.isToggleRemoveFavoritePresent()).toBe(true, `Toggle favorite is not displayed for ${fileLocked}`); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLocked}`); - expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed for ${fileLocked}`); - expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed for ${fileLocked}`); - expect(await contextMenu.isSharePresent()).toBe(true, `Share is not displayed for ${fileLocked}`); - expect(await contextMenu.isManageVersionsPresent()).toBe(true, `Manage Versions not displayed for ${fileLocked}`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(true, `Upload new version not displayed for ${fileLocked}`); - expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed for ${fileLocked}`); - expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLocked}`); - expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${fileLocked}`); - }); - }); - - describe('on Favorites', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await page.clickFavoritesAndWait(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('Context menu has the correct actions for a file - [C280608]', async () => { - await dataTable.rightClickOnItem(fileUser); - - // TODO: change expect to true when ACA-2174 is done - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileUser}`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${fileUser}`); - expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileUser}`); - expect(await contextMenu.isViewPresent()).toBe(true, `View is not displayed for ${fileUser}`); - expect(await contextMenu.isToggleRemoveFavoritePresent()).toBe(true, `Toggle favorite is not displayed for ${fileUser}`); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileUser}`); - expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed for ${fileUser}`); - expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed for ${fileUser}`); - expect(await contextMenu.isSharePresent()).toBe(true, `Share is not displayed for ${fileUser}`); - expect(await contextMenu.isManageVersionsPresent()).toBe(true, `Manage Versions is not displayed for ${fileUser}`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed for ${fileUser}`); - expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileUser}`); - expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${fileUser}`); - }); - - it('Context menu has the correct actions for a locked file - [C297637]', async () => { - await dataTable.rightClickOnItem(fileLocked); - - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileLocked}`); - // TODO: change expect to true when ACA-2174 is done - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${fileLocked}`); - expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLocked}`); - expect(await contextMenu.isViewPresent()).toBe(true, `View is not displayed for ${fileLocked}`); - expect(await contextMenu.isToggleRemoveFavoritePresent()).toBe(true, `Toggle favorite is not displayed for ${fileLocked}`); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLocked}`); - expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed for ${fileLocked}`); - expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed for ${fileLocked}`); - expect(await contextMenu.isSharePresent()).toBe(true, `Share is not displayed for ${fileLocked}`); - expect(await contextMenu.isManageVersionsPresent()).toBe(true, `Manage Versions is not displayed for ${fileLocked}`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed for ${fileLocked}`); - expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLocked}`); - expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${fileLocked}`); - }); - - it('Context menu has the correct actions for a folder - [C280609]', async () => { - await dataTable.rightClickOnItem(folderUser); - - expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${folderUser}`); - expect(await contextMenu.isEditFolderPresent()).toBe(true, `Edit folder is not displayed for ${folderUser}`); - expect(await contextMenu.isToggleRemoveFavoritePresent()).toBe(true, `Toggle favorite is not displayed for ${folderUser}`); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${folderUser}`); - expect(await contextMenu.isMovePresent()).toBe(true, `Move is not displayed for ${folderUser}`); - expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is not displayed for ${folderUser}`); - expect(await contextMenu.isViewPresent()).toBe(false, `View is displayed for ${folderUser}`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions is displayed for ${folderUser}`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed for ${folderUser}`); - expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed for ${folderUser}`); - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${folderUser}`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${folderUser}`); - }); - }); - - describe('on Trash', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await page.clickTrashAndWait(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('Context menu has the correct actions for a file - [C286258]', async () => { - await dataTable.rightClickOnItem(fileInTrash); - - expect(await contextMenu.isPermanentDeletePresent()).toBe(true, `Permanently delete is not displayed for ${fileInTrash}`); - expect(await contextMenu.isRestorePresent()).toBe(true, `Restore is not displayed for ${fileInTrash}`); - expect(await contextMenu.isDownloadPresent()).toBe(false, `Download is displayed for ${fileInTrash}`); - expect(await contextMenu.isViewPresent()).toBe(false, `View is displayed for ${fileInTrash}`); - expect(await contextMenu.isFavoritePresent()).toBe(false, `Favorite is displayed for ${fileInTrash}`); - expect(await contextMenu.isCopyPresent()).toBe(false, `Copy is displayed for ${fileInTrash}`); - expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed for ${fileInTrash}`); - // expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed for ${fileInTrash}`); - expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed for ${fileInTrash}`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions is displayed for ${fileInTrash}`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed for ${fileInTrash}`); - expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileInTrash}`); - expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${fileInTrash}`); - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileInTrash}`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${fileInTrash}`); - }); - - it('Context menu has the correct actions for a folder - [C286259]', async () => { - await dataTable.rightClickOnItem(folderInTrash); - - expect(await contextMenu.isPermanentDeletePresent()).toBe(true, `Permanently delete is not displayed for ${folderInTrash}`); - expect(await contextMenu.isRestorePresent()).toBe(true, `Restore is not displayed for ${folderInTrash}`); - expect(await contextMenu.isDownloadPresent()).toBe(false, `Download is displayed for ${folderInTrash}`); - expect(await contextMenu.isViewPresent()).toBe(false, `View is displayed for ${folderInTrash}`); - expect(await contextMenu.isFavoritePresent()).toBe(false, `Favorite is displayed for ${folderInTrash}`); - expect(await contextMenu.isCopyPresent()).toBe(false, `Copy is displayed for ${folderInTrash}`); - expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed for ${folderInTrash}`); - // expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed for ${folderInTrash}`); - expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed for ${folderInTrash}`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions is displayed for ${folderInTrash}`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed for ${folderInTrash}`); - expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${folderInTrash}`); - expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${folderInTrash}`); - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${folderInTrash}`); - }); - }); - - describe('on Search Results', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await page.clickPersonalFilesAndWait(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('Context menu has the correct actions for a file - [C291827]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkOnlyFiles(); - await searchInput.searchFor(fileSiteUser); - await dataTable.rightClickOnItem(fileSiteUser); - - expect(await contextMenu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed for ${fileSiteUser}`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${fileSiteUser}`); - expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileSiteUser}`); - expect(await contextMenu.isViewPresent()).toBe(true, `View is not displayed for ${fileSiteUser}`); - expect(await contextMenu.isToggleFavoritePresent()).toBe(true, `Toggle favorite is not displayed for ${fileSiteUser}`); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileSiteUser}`); - expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed for ${fileSiteUser}`); - expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed for ${fileSiteUser}`); - expect(await contextMenu.isSharePresent()).toBe(true, `Share is not displayed for ${fileSiteUser}`); - expect(await contextMenu.isManageVersionsPresent()).toBe(true, `Manage Versions not displayed for ${fileSiteUser}`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(true, `Upload new version not displayed for ${fileSiteUser}`); - expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed for ${fileSiteUser}`); - expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileSiteUser}`); - expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${fileSiteUser}`); - }); - - it('Context menu has the correct actions for a locked file - [C297638]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkOnlyFiles(); - await searchInput.searchFor(fileLocked); - await dataTable.rightClickOnItem(fileLocked); - - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileLocked}`); - expect(await contextMenu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed for ${fileLocked}`); - expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLocked}`); - expect(await contextMenu.isViewPresent()).toBe(true, `View is not displayed for ${fileLocked}`); - expect(await contextMenu.isToggleRemoveFavoritePresent()).toBe(true, `Toggle favorite is not displayed for ${fileLocked}`); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLocked}`); - expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed for ${fileLocked}`); - expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed for ${fileLocked}`); - expect(await contextMenu.isSharePresent()).toBe(true, `Share is not displayed for ${fileLocked}`); - expect(await contextMenu.isManageVersionsPresent()).toBe(true, `Manage Versions not displayed for ${fileLocked}`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(true, `Upload new version not displayed for ${fileLocked}`); - expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed for ${fileLocked}`); - expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLocked}`); - expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${fileLocked}`); - }); - - it('Context menu has the correct actions for a folder - [C291828]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkOnlyFolders(); - await searchInput.searchFor(folderSiteUser); - await dataTable.rightClickOnItem(folderSiteUser); - - expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${folderSiteUser}`); - expect(await contextMenu.isEditFolderPresent()).toBe(true, `Edit folder is not displayed for ${folderSiteUser}`); - expect(await contextMenu.isToggleFavoritePresent()).toBe(true, `Toggle favorite is not displayed for ${folderSiteUser}`); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${folderSiteUser}`); - expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed for ${folderSiteUser}`); - expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed for ${folderSiteUser}`); - expect(await contextMenu.isManagePermissionsPresent()).toBe(true, `Permissions is not displayed for ${folderSiteUser}`); - expect(await contextMenu.isViewPresent()).toBe(false, `View is displayed for ${folderSiteUser}`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions displayed for ${folderSiteUser}`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version displayed for ${folderSiteUser}`); - expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed for ${folderSiteUser}`); - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${folderSiteUser}`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${folderSiteUser}`); - }); - }); -}); diff --git a/e2e/suites/actions-available/files-folders/favorites.test.ts b/e2e/suites/actions-available/files-folders/favorites.test.ts new file mode 100755 index 0000000000..2351ed6798 --- /dev/null +++ b/e2e/suites/actions-available/files-folders/favorites.test.ts @@ -0,0 +1,182 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2019 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { LoginPage, BrowsingPage } from '../../../pages/pages'; +import { FILES } from '../../../configs'; +import { RepoClient } from '../../../utilities/repo-client/repo-client'; +import { Utils } from '../../../utilities/utils'; +import * as data from './test-data-files-folders'; +import * as testUtil from '../test-util'; + +describe('File/folder actions : on Favorites : ', () => { + + const random = Utils.random(); + + const username = `user-${random}`; + + const parent = `parent-${random}`; let parentId; + + let fileDocxFavId, fileFavId, fileDocxSharedFavId, fileSharedFavId, fileFavLockedId, fileSharedFavLockedId; + let folderFavId, folderFav2Id; + + const apis = { + admin: new RepoClient(), + user: new RepoClient(username, username) + }; + + const loginPage = new LoginPage(); + const page = new BrowsingPage(); + + beforeAll(async (done) => { + await apis.admin.people.createUser({ username }); + + parentId = (await apis.user.nodes.createFolder(parent)).entry.id; + + fileDocxFavId = (await apis.user.upload.uploadFileWithRename(FILES.docxFile, parentId, data.fileDocxFav.name)).entry.id; + fileFavId = (await apis.user.nodes.createFile(data.fileFav.name, parentId)).entry.id; + fileDocxSharedFavId = (await apis.user.upload.uploadFileWithRename(FILES.docxFile, parentId, data.fileDocxSharedFav.name)).entry.id; + fileSharedFavId = (await apis.user.nodes.createFile(data.fileSharedFav.name, parentId)).entry.id; + fileFavLockedId = (await apis.user.nodes.createFile(data.fileFavLocked.name, parentId)).entry.id; + fileSharedFavLockedId = (await apis.user.nodes.createFile(data.fileSharedFavLocked.name, parentId)).entry.id; + + folderFavId = (await apis.user.nodes.createFolder(data.folderFav.name, parentId)).entry.id; + folderFav2Id = (await apis.user.nodes.createFolder(data.folderFav2.name, parentId)).entry.id; + await apis.user.favorites.addFavoriteById('folder', folderFavId); + await apis.user.favorites.addFavoriteById('folder', folderFav2Id); + + await apis.user.shared.shareFilesByIds([ + fileDocxSharedFavId, + fileSharedFavId, + fileSharedFavLockedId + ]); + + await apis.user.favorites.addFavoritesByIds('file', [ + fileDocxFavId, + fileFavId, + fileDocxSharedFavId, + fileSharedFavId, + fileFavLockedId, + fileSharedFavLockedId + ]); + + await apis.user.nodes.lockFile(fileFavLockedId); + await apis.user.nodes.lockFile(fileSharedFavLockedId); + + await apis.user.favorites.waitForApi({ expect: 8 }); + await apis.user.shared.waitForApi({ expect: 3 }); + + await loginPage.loginWith(username); + done(); + }); + + afterAll(async (done) => { + await apis.user.nodes.deleteNodeById(parentId); + done(); + }); + + beforeEach(async (done) => { + await Utils.pressEscape(); + await page.clickFavoritesAndWait(); + done(); + }); + + afterEach(async (done) => { + await Utils.pressEscape(); + done(); + }); + + describe('on a file', () => { + + it('File Office, favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.fileDocxFav.name, data.fileDocxFav.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileDocxFav.name, data.fileDocxFav.favoritesToolbarMore); + await testUtil.checkContextMenu(data.fileDocxFav.name, data.fileDocxFav.favoritesContextMenu); + }); + + it('File favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.fileFav.name, data.fileFav.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileFav.name, data.fileFav.favoritesToolbarMore); + await testUtil.checkContextMenu(data.fileFav.name, data.fileFav.favoritesContextMenu); + }); + + it('File Office, shared, favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.fileDocxSharedFav.name, data.fileDocxSharedFav.favoritesToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileDocxSharedFav.name, data.fileDocxSharedFav.favoritesToolbarMore); + await testUtil.checkContextMenu(data.fileDocxSharedFav.name, data.fileDocxSharedFav.favoritesContextMenu); + }); + + it('File shared, favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.fileSharedFav.name, data.fileSharedFav.favoritesToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileSharedFav.name, data.fileSharedFav.favoritesToolbarMore); + await testUtil.checkContextMenu(data.fileSharedFav.name, data.fileSharedFav.favoritesContextMenu); + }); + + it('File favorite, locked - []', async () => { + await testUtil.checkToolbarPrimary(data.fileFavLocked.name, data.fileFavLocked.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileFavLocked.name, data.fileFavLocked.favoritesToolbarMore); + await testUtil.checkContextMenu(data.fileFavLocked.name, data.fileFavLocked.favoritesContextMenu); + }); + + it('File shared, favorite, locked - []', async () => { + await testUtil.checkToolbarPrimary(data.fileSharedFavLocked.name, data.fileSharedFavLocked.favoritesToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileSharedFavLocked.name, data.fileSharedFavLocked.favoritesToolbarMore); + await testUtil.checkContextMenu(data.fileSharedFavLocked.name, data.fileSharedFavLocked.favoritesContextMenu); + }); + }); + + describe('on a folder', () => { + it('Folder favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.folderFav.name, data.folderFav.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.folderFav.name, data.folderFav.favoritesToolbarMore); + await testUtil.checkContextMenu(data.folderFav.name, data.folderFav.favoritesContextMenu); + }); + }); + + describe('on multiple selection', () => { + it('multiple files - [C280656]', async () => { + await testUtil.checkMultipleSelContextMenu([ data.fileDocxFav.name, data.fileDocxSharedFav.name ], data.multipleSelAllFav.favoritesContextMenu); + await testUtil.checkMultipleSelToolbarPrimary([ data.fileDocxFav.name, data.fileDocxSharedFav.name ], data.multipleSelAllFav.toolbarPrimary); + await testUtil.checkMultipleSelToolbarMoreActions([ data.fileDocxFav.name, data.fileDocxSharedFav.name ], data.multipleSelAllFav.favoritesToolbarMore); + }); + + it('multiple locked files - [C297631]', async () => { + await testUtil.checkMultipleSelContextMenu([ data.fileFavLocked.name, data.fileSharedFavLocked.name ], data.multipleSelAllFav.favoritesContextMenu); + await testUtil.checkMultipleSelToolbarPrimary([ data.fileFavLocked.name, data.fileSharedFavLocked.name ], data.multipleSelAllFav.toolbarPrimary); + await testUtil.checkMultipleSelToolbarMoreActions([ data.fileFavLocked.name, data.fileSharedFavLocked.name ], data.multipleSelAllFav.favoritesToolbarMore); + }); + + it('multiple folders - [C280664]', async () => { + await testUtil.checkMultipleSelContextMenu([ data.folderFav.name, data.folderFav2.name ], data.multipleSelAllFav.favoritesContextMenu); + await testUtil.checkMultipleSelToolbarPrimary([ data.folderFav.name, data.folderFav2.name ], data.multipleSelAllFav.toolbarPrimary); + await testUtil.checkMultipleSelToolbarMoreActions([ data.folderFav.name, data.folderFav2.name ], data.multipleSelAllFav.favoritesToolbarMore); + }); + + it('both files and folders - [C280657]', async () => { + await testUtil.checkMultipleSelContextMenu([ data.fileFav.name, data.folderFav.name ], data.multipleSelAllFav.favoritesContextMenu); + await testUtil.checkMultipleSelToolbarPrimary([ data.fileFav.name, data.folderFav.name ], data.multipleSelAllFav.toolbarPrimary); + await testUtil.checkMultipleSelToolbarMoreActions([ data.fileFav.name, data.folderFav.name ], data.multipleSelAllFav.favoritesToolbarMore); + }); + }); +}); diff --git a/e2e/suites/actions-available/files-folders/personal.test.ts b/e2e/suites/actions-available/files-folders/personal.test.ts new file mode 100755 index 0000000000..27eb298419 --- /dev/null +++ b/e2e/suites/actions-available/files-folders/personal.test.ts @@ -0,0 +1,244 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2019 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { LoginPage, BrowsingPage } from '../../../pages/pages'; +import { FILES } from '../../../configs'; +import { RepoClient } from '../../../utilities/repo-client/repo-client'; +import { Utils } from '../../../utilities/utils'; +import * as data from './test-data-files-folders'; +import * as testUtil from '../test-util'; + +describe('File/folder actions : on Personal Files: ', () => { + + const random = Utils.random(); + + const username = `user-${random}`; + + const parent = `parent-${random}`; let parentId; + + let fileDocxFavId, fileFavId, fileDocxSharedId, fileDocxSharedFavId, fileSharedId, fileSharedFavId, fileLockedId, fileFavLockedId, fileSharedLockedId, fileSharedFavLockedId; + let folderFavId; + + const apis = { + admin: new RepoClient(), + user: new RepoClient(username, username) + }; + + const loginPage = new LoginPage(); + const page = new BrowsingPage(); + const { dataTable } = page; + + beforeAll(async (done) => { + await apis.admin.people.createUser({ username }); + + parentId = (await apis.user.nodes.createFolder(parent)).entry.id; + + await apis.user.upload.uploadFileWithRename(FILES.docxFile, parentId, data.fileDocx.name ); + fileDocxFavId = (await apis.user.upload.uploadFileWithRename(FILES.docxFile, parentId, data.fileDocxFav.name)).entry.id; + await apis.user.nodes.createFile(data.file.name, parentId); + fileFavId = (await apis.user.nodes.createFile(data.fileFav.name, parentId)).entry.id; + fileDocxSharedId = (await apis.user.upload.uploadFileWithRename(FILES.docxFile, parentId, data.fileDocxShared.name)).entry.id; + fileDocxSharedFavId = (await apis.user.upload.uploadFileWithRename(FILES.docxFile, parentId, data.fileDocxSharedFav.name)).entry.id; + fileSharedId = (await apis.user.nodes.createFile(data.fileShared.name, parentId)).entry.id; + fileSharedFavId = (await apis.user.nodes.createFile(data.fileSharedFav.name, parentId)).entry.id; + fileLockedId = (await apis.user.nodes.createFile(data.fileLocked.name, parentId)).entry.id; + fileFavLockedId = (await apis.user.nodes.createFile(data.fileFavLocked.name, parentId)).entry.id; + fileSharedLockedId = (await apis.user.nodes.createFile(data.fileSharedLocked.name, parentId)).entry.id; + fileSharedFavLockedId = (await apis.user.nodes.createFile(data.fileSharedFavLocked.name, parentId)).entry.id; + + await apis.user.nodes.createFolder(data.folder.name, parentId); + folderFavId = (await apis.user.nodes.createFolder(data.folderFav.name, parentId)).entry.id; + await apis.user.favorites.addFavoriteById('folder', folderFavId); + + await apis.user.favorites.addFavoritesByIds('file', [ + fileDocxFavId, + fileFavId, + fileDocxSharedFavId, + fileSharedFavId, + fileFavLockedId, + fileSharedFavLockedId + ]); + + await apis.user.shared.shareFilesByIds([ + fileDocxSharedId, + fileDocxSharedFavId, + fileSharedId, + fileSharedFavId, + fileSharedLockedId, + fileSharedFavLockedId + ]); + + await apis.user.nodes.lockFile(fileLockedId); + await apis.user.nodes.lockFile(fileFavLockedId); + await apis.user.nodes.lockFile(fileSharedLockedId); + await apis.user.nodes.lockFile(fileSharedFavLockedId); + + await apis.user.favorites.waitForApi({ expect: 7 }); + await apis.user.shared.waitForApi({ expect: 6 }); + + await loginPage.loginWith(username); + done(); + }); + + afterAll(async (done) => { + await apis.user.nodes.deleteNodeById(parentId); + done(); + }); + + beforeEach(async (done) => { + await Utils.pressEscape(); + await page.clickPersonalFilesAndWait(); + await dataTable.doubleClickOnRowByName(parent); + await dataTable.waitForHeader(); + done(); + }); + + afterEach(async (done) => { + await Utils.pressEscape(); + done(); + }); + + describe('on a file', () => { + + it('File Office - []', async () => { + await testUtil.checkToolbarPrimary(data.fileDocx.name, data.fileDocx.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileDocx.name, data.fileDocx.toolbarMore); + await testUtil.checkContextMenu(data.fileDocx.name, data.fileDocx.contextMenu); + }); + + it('File Office, favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.fileDocxFav.name, data.fileDocxFav.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileDocxFav.name, data.fileDocxFav.toolbarMore); + await testUtil.checkContextMenu(data.fileDocxFav.name, data.fileDocxFav.contextMenu); + }); + + it('File simple - []', async () => { + await testUtil.checkToolbarPrimary(data.file.name, data.file.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.file.name, data.file.toolbarMore); + await testUtil.checkContextMenu(data.file.name, data.file.contextMenu); + }); + + it('File favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.fileFav.name, data.fileFav.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileFav.name, data.fileFav.toolbarMore); + await testUtil.checkContextMenu(data.fileFav.name, data.fileFav.contextMenu); + }); + + it('File Office, shared - []', async () => { + await testUtil.checkToolbarPrimary(data.fileDocxShared.name, data.fileDocxShared.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileDocxShared.name, data.fileDocxShared.toolbarMore); + await testUtil.checkContextMenu(data.fileDocxShared.name, data.fileDocxShared.contextMenu); + }); + + it('File Office, shared, favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.fileDocxSharedFav.name, data.fileDocxSharedFav.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileDocxSharedFav.name, data.fileDocxSharedFav.toolbarMore); + await testUtil.checkContextMenu(data.fileDocxSharedFav.name, data.fileDocxSharedFav.contextMenu); + }); + + it('File shared - []', async () => { + await testUtil.checkToolbarPrimary(data.fileShared.name, data.fileShared.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileShared.name, data.fileShared.toolbarMore); + await testUtil.checkContextMenu(data.fileShared.name, data.fileShared.contextMenu); + }); + + it('File shared, favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.fileSharedFav.name, data.fileSharedFav.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileSharedFav.name, data.fileSharedFav.toolbarMore); + await testUtil.checkContextMenu(data.fileSharedFav.name, data.fileSharedFav.contextMenu); + }); + + it('File locked - []', async () => { + await testUtil.checkToolbarPrimary(data.fileLocked.name, data.fileLocked.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileLocked.name, data.fileLocked.toolbarMore); + await testUtil.checkContextMenu(data.fileLocked.name, data.fileLocked.contextMenu); + }); + + it('File favorite, locked - []', async () => { + await testUtil.checkToolbarPrimary(data.fileFavLocked.name, data.fileFavLocked.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileFavLocked.name, data.fileFavLocked.toolbarMore); + await testUtil.checkContextMenu(data.fileFavLocked.name, data.fileFavLocked.contextMenu); + }); + + it('File shared, locked - []', async () => { + await testUtil.checkToolbarPrimary(data.fileSharedLocked.name, data.fileSharedLocked.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileSharedLocked.name, data.fileSharedLocked.toolbarMore); + await testUtil.checkContextMenu(data.fileSharedLocked.name, data.fileSharedLocked.contextMenu); + }); + + it('File shared, favorite, locked - []', async () => { + await testUtil.checkToolbarPrimary(data.fileSharedFavLocked.name, data.fileSharedFavLocked.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileSharedFavLocked.name, data.fileSharedFavLocked.toolbarMore); + await testUtil.checkContextMenu(data.fileSharedFavLocked.name, data.fileSharedFavLocked.contextMenu); + }); + }); + + describe('on a folder', () => { + + it('Folder not favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.folder.name, data.folder.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.folder.name, data.folder.toolbarMore); + await testUtil.checkContextMenu(data.folder.name, data.folder.contextMenu); + }); + + it('Folder favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.folderFav.name, data.folderFav.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.folderFav.name, data.folderFav.toolbarMore); + await testUtil.checkContextMenu(data.folderFav.name, data.folderFav.contextMenu); + }); + }); + + describe('on multiple selection', () => { + it('multiple files - [C217112]', async () => { + await testUtil.checkMultipleSelContextMenu([ data.fileDocx.name, data.fileDocxSharedFav.name ], data.multipleSel.contextMenu); + await testUtil.checkMultipleSelToolbarPrimary([ data.fileDocx.name, data.fileDocxSharedFav.name ], data.multipleSel.toolbarPrimary); + await testUtil.checkMultipleSelToolbarMoreActions([ data.fileDocx.name, data.fileDocxSharedFav.name ], data.multipleSel.toolbarMore); + }); + + it('multiple files - all favorite - []', async () => { + await testUtil.checkMultipleSelContextMenu([ data.fileDocxFav.name, data.fileDocxSharedFav.name ], data.multipleSelAllFav.contextMenu); + await testUtil.checkMultipleSelToolbarPrimary([ data.fileDocxFav.name, data.fileDocxSharedFav.name ], data.multipleSel.toolbarPrimary); + await testUtil.checkMultipleSelToolbarMoreActions([ data.fileDocxFav.name, data.fileDocxSharedFav.name ], data.multipleSelAllFav.toolbarMore); + }); + + it('multiple locked files - [C297619]', async () => { + await testUtil.checkMultipleSelContextMenu([ data.fileLocked.name, data.fileSharedFavLocked.name ], data.multipleSel.contextMenu); + await testUtil.checkMultipleSelToolbarPrimary([ data.fileLocked.name, data.fileSharedFavLocked.name ], data.multipleSel.toolbarPrimary); + await testUtil.checkMultipleSelToolbarMoreActions([ data.fileLocked.name, data.fileSharedFavLocked.name ], data.multipleSel.toolbarMore); + }); + + it('multiple folders - [C280459]', async () => { + await testUtil.checkMultipleSelContextMenu([ data.folderFav.name, data.folder.name ], data.multipleSel.contextMenu); + await testUtil.checkMultipleSelToolbarPrimary([ data.folderFav.name, data.folder.name ], data.multipleSel.toolbarPrimary); + await testUtil.checkMultipleSelToolbarMoreActions([ data.folderFav.name, data.folder.name ], data.multipleSel.toolbarMore); + }); + + it('both files and folders - [C280460]', async () => { + await testUtil.checkMultipleSelContextMenu([ data.file.name, data.folder.name ], data.multipleSel.contextMenu); + await testUtil.checkMultipleSelToolbarPrimary([ data.file.name, data.folder.name ], data.multipleSel.toolbarPrimary); + await testUtil.checkMultipleSelToolbarMoreActions([ data.file.name, data.folder.name ], data.multipleSel.toolbarMore); + }); + }); +}); diff --git a/e2e/suites/actions-available/files-folders/recent.test.ts b/e2e/suites/actions-available/files-folders/recent.test.ts new file mode 100755 index 0000000000..e6e13bbb56 --- /dev/null +++ b/e2e/suites/actions-available/files-folders/recent.test.ts @@ -0,0 +1,212 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2019 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { LoginPage, BrowsingPage } from '../../../pages/pages'; +import { FILES } from '../../../configs'; +import { RepoClient } from '../../../utilities/repo-client/repo-client'; +import { Utils } from '../../../utilities/utils'; +import * as data from './test-data-files-folders'; +import * as testUtil from '../test-util'; + +describe('File actions : on Recent Files: ', () => { + + const random = Utils.random(); + + const username = `user-${random}`; + + const parent = `parent-${random}`; let parentId; + + let fileDocxFavId, fileFavId, fileDocxSharedId, fileDocxSharedFavId, fileSharedId, fileSharedFavId, fileLockedId, fileFavLockedId, fileSharedLockedId, fileSharedFavLockedId; + + const apis = { + admin: new RepoClient(), + user: new RepoClient(username, username) + }; + + const loginPage = new LoginPage(); + const page = new BrowsingPage(); + const { dataTable } = page; + + beforeAll(async (done) => { + await apis.admin.people.createUser({ username }); + + parentId = (await apis.user.nodes.createFolder(parent)).entry.id; + + await apis.user.upload.uploadFileWithRename(FILES.docxFile, parentId, data.fileDocx.name); + fileDocxFavId = (await apis.user.upload.uploadFileWithRename(FILES.docxFile, parentId, data.fileDocxFav.name)).entry.id; + await apis.user.nodes.createFile(data.file.name, parentId); + fileFavId = (await apis.user.nodes.createFile(data.fileFav.name, parentId)).entry.id; + fileDocxSharedId = (await apis.user.upload.uploadFileWithRename(FILES.docxFile, parentId, data.fileDocxShared.name)).entry.id; + fileDocxSharedFavId = (await apis.user.upload.uploadFileWithRename(FILES.docxFile, parentId, data.fileDocxSharedFav.name)).entry.id; + fileSharedId = (await apis.user.nodes.createFile(data.fileShared.name, parentId)).entry.id; + fileSharedFavId = (await apis.user.nodes.createFile(data.fileSharedFav.name, parentId)).entry.id; + fileLockedId = (await apis.user.nodes.createFile(data.fileLocked.name, parentId)).entry.id; + fileFavLockedId = (await apis.user.nodes.createFile(data.fileFavLocked.name, parentId)).entry.id; + fileSharedLockedId = (await apis.user.nodes.createFile(data.fileSharedLocked.name, parentId)).entry.id; + fileSharedFavLockedId = (await apis.user.nodes.createFile(data.fileSharedFavLocked.name, parentId)).entry.id; + + await apis.user.favorites.addFavoritesByIds('file', [ + fileDocxFavId, + fileFavId, + fileDocxSharedFavId, + fileSharedFavId, + fileFavLockedId, + fileSharedFavLockedId + ]); + + await apis.user.shared.shareFilesByIds([ + fileDocxSharedId, + fileDocxSharedFavId, + fileSharedId, + fileSharedFavId, + fileSharedLockedId, + fileSharedFavLockedId + ]); + + await apis.user.nodes.lockFile(fileLockedId); + await apis.user.nodes.lockFile(fileFavLockedId); + await apis.user.nodes.lockFile(fileSharedLockedId); + await apis.user.nodes.lockFile(fileSharedFavLockedId); + + await apis.user.favorites.waitForApi({ expect: 6 }); + await apis.user.shared.waitForApi({ expect: 6 }); + await apis.user.search.waitForApi(username, { expect: 12 }); + + await loginPage.loginWith(username); + done(); + }); + + afterAll(async (done) => { + await apis.user.nodes.deleteNodeById(parentId); + done(); + }); + + beforeEach(async (done) => { + await Utils.pressEscape(); + await page.clickRecentFilesAndWait(); + await dataTable.waitForHeader(); + done(); + }); + + afterEach(async (done) => { + await Utils.pressEscape(); + done(); + }); + + describe('on single selection', () => { + it('File Office - []', async () => { + await testUtil.checkToolbarPrimary(data.fileDocx.name, data.fileDocx.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileDocx.name, data.fileDocx.toolbarMore); + await testUtil.checkContextMenu(data.fileDocx.name, data.fileDocx.contextMenu); + }); + + it('File Office, favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.fileDocxFav.name, data.fileDocxFav.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileDocxFav.name, data.fileDocxFav.toolbarMore); + await testUtil.checkContextMenu(data.fileDocxFav.name, data.fileDocxFav.contextMenu); + }); + + it('File simple - []', async () => { + await testUtil.checkToolbarPrimary(data.file.name, data.file.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.file.name, data.file.toolbarMore); + await testUtil.checkContextMenu(data.file.name, data.file.contextMenu); + }); + + it('File favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.fileFav.name, data.fileFav.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileFav.name, data.fileFav.toolbarMore); + await testUtil.checkContextMenu(data.fileFav.name, data.fileFav.contextMenu); + }); + + it('File Office, shared - []', async () => { + await testUtil.checkToolbarPrimary(data.fileDocxShared.name, data.fileDocxShared.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileDocxShared.name, data.fileDocxShared.toolbarMore); + await testUtil.checkContextMenu(data.fileDocxShared.name, data.fileDocxShared.contextMenu); + }); + + it('File Office, shared, favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.fileDocxSharedFav.name, data.fileDocxSharedFav.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileDocxSharedFav.name, data.fileDocxSharedFav.toolbarMore); + await testUtil.checkContextMenu(data.fileDocxSharedFav.name, data.fileDocxSharedFav.contextMenu); + }); + + it('File shared - []', async () => { + await testUtil.checkToolbarPrimary(data.fileShared.name, data.fileShared.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileShared.name, data.fileShared.toolbarMore); + await testUtil.checkContextMenu(data.fileShared.name, data.fileShared.contextMenu); + }); + + it('File shared, favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.fileSharedFav.name, data.fileSharedFav.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileSharedFav.name, data.fileSharedFav.toolbarMore); + await testUtil.checkContextMenu(data.fileSharedFav.name, data.fileSharedFav.contextMenu); + }); + + it('File locked - []', async () => { + await testUtil.checkToolbarPrimary(data.fileLocked.name, data.fileLocked.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileLocked.name, data.fileLocked.toolbarMore); + await testUtil.checkContextMenu(data.fileLocked.name, data.fileLocked.contextMenu); + }); + + it('File favorite, locked - []', async () => { + await testUtil.checkToolbarPrimary(data.fileFavLocked.name, data.fileFavLocked.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileFavLocked.name, data.fileFavLocked.toolbarMore); + await testUtil.checkContextMenu(data.fileFavLocked.name, data.fileFavLocked.contextMenu); + }); + + it('File shared, locked - []', async () => { + await testUtil.checkToolbarPrimary(data.fileSharedLocked.name, data.fileSharedLocked.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileSharedLocked.name, data.fileSharedLocked.toolbarMore); + await testUtil.checkContextMenu(data.fileSharedLocked.name, data.fileSharedLocked.contextMenu); + }); + + it('File shared, favorite, locked - []', async () => { + await testUtil.checkToolbarPrimary(data.fileSharedFavLocked.name, data.fileSharedFavLocked.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileSharedFavLocked.name, data.fileSharedFavLocked.toolbarMore); + await testUtil.checkContextMenu(data.fileSharedFavLocked.name, data.fileSharedFavLocked.contextMenu); + }); + }); + + describe('on multiple selection', () => { + it('multiple files - [C280468]', async () => { + await testUtil.checkMultipleSelContextMenu([ data.fileDocxFav.name, data.fileLocked.name ], data.multipleSel.contextMenu); + await testUtil.checkMultipleSelToolbarPrimary([ data.fileDocxFav.name, data.fileLocked.name ], data.multipleSel.toolbarPrimary); + await testUtil.checkMultipleSelToolbarMoreActions([ data.fileDocxFav.name, data.fileLocked.name ], data.multipleSel.toolbarMore); + }); + + it('multiple files - all favorite - []', async () => { + await testUtil.checkMultipleSelContextMenu([ data.fileDocxFav.name, data.fileFav.name ], data.multipleSelAllFav.contextMenu); + await testUtil.checkMultipleSelToolbarPrimary([ data.fileDocxFav.name, data.fileFav.name ], data.multipleSel.toolbarPrimary); + await testUtil.checkMultipleSelToolbarMoreActions([ data.fileDocxFav.name, data.fileFav.name ], data.multipleSelAllFav.toolbarMore); + }); + + it('multiple locked files - [C297624]', async () => { + await testUtil.checkMultipleSelContextMenu([ data.fileLocked.name, data.fileSharedFavLocked.name ], data.multipleSel.contextMenu); + await testUtil.checkMultipleSelToolbarPrimary([ data.fileLocked.name, data.fileSharedFavLocked.name ], data.multipleSel.toolbarPrimary); + await testUtil.checkMultipleSelToolbarMoreActions([ data.fileLocked.name, data.fileSharedFavLocked.name ], data.multipleSel.toolbarMore); + }); + }); + +}); diff --git a/e2e/suites/actions-available/files-folders/search.test.ts b/e2e/suites/actions-available/files-folders/search.test.ts new file mode 100755 index 0000000000..44ca365735 --- /dev/null +++ b/e2e/suites/actions-available/files-folders/search.test.ts @@ -0,0 +1,291 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2019 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { LoginPage, BrowsingPage } from '../../../pages/pages'; +import { FILES } from '../../../configs'; +import { RepoClient } from '../../../utilities/repo-client/repo-client'; +import { Utils } from '../../../utilities/utils'; +import * as data from './test-data-files-folders'; +import * as testUtil from '../test-util'; + +describe('File/folder actions : on Search Results : ', () => { + + const random = Utils.random(); + + const username = `user-${random}`; + + const parent = `parent-${random}`; let parentId; + + let fileDocxFavId, fileFavId, fileDocxSharedId, fileDocxSharedFavId, fileSharedId, fileSharedFavId, fileLockedId, fileFavLockedId, fileSharedLockedId, fileSharedFavLockedId; + let folderFavId; + + const apis = { + admin: new RepoClient(), + user: new RepoClient(username, username) + }; + + const loginPage = new LoginPage(); + const page = new BrowsingPage(); + const { searchInput } = page.header; + + beforeAll(async (done) => { + await apis.admin.people.createUser({ username }); + + parentId = (await apis.user.nodes.createFolder(parent)).entry.id; + + await apis.user.upload.uploadFileWithRename(FILES.docxFile, parentId, data.fileDocx.name ); + fileDocxFavId = (await apis.user.upload.uploadFileWithRename(FILES.docxFile, parentId, data.fileDocxFav.name)).entry.id; + await apis.user.nodes.createFile(data.file.name, parentId); + fileFavId = (await apis.user.nodes.createFile(data.fileFav.name, parentId)).entry.id; + fileDocxSharedId = (await apis.user.upload.uploadFileWithRename(FILES.docxFile, parentId, data.fileDocxShared.name)).entry.id; + fileDocxSharedFavId = (await apis.user.upload.uploadFileWithRename(FILES.docxFile, parentId, data.fileDocxSharedFav.name)).entry.id; + fileSharedId = (await apis.user.nodes.createFile(data.fileShared.name, parentId)).entry.id; + fileSharedFavId = (await apis.user.nodes.createFile(data.fileSharedFav.name, parentId)).entry.id; + fileLockedId = (await apis.user.nodes.createFile(data.fileLocked.name, parentId)).entry.id; + fileFavLockedId = (await apis.user.nodes.createFile(data.fileFavLocked.name, parentId)).entry.id; + fileSharedLockedId = (await apis.user.nodes.createFile(data.fileSharedLocked.name, parentId)).entry.id; + fileSharedFavLockedId = (await apis.user.nodes.createFile(data.fileSharedFavLocked.name, parentId)).entry.id; + + await apis.user.nodes.createFolder(data.folder.name, parentId); + folderFavId = (await apis.user.nodes.createFolder(data.folderFav.name, parentId)).entry.id; + await apis.user.favorites.addFavoriteById('folder', folderFavId); + + await apis.user.favorites.addFavoritesByIds('file', [ + fileDocxFavId, + fileFavId, + fileDocxSharedFavId, + fileSharedFavId, + fileFavLockedId, + fileSharedFavLockedId + ]); + + await apis.user.shared.shareFilesByIds([ + fileDocxSharedId, + fileDocxSharedFavId, + fileSharedId, + fileSharedFavId, + fileSharedLockedId, + fileSharedFavLockedId + ]); + + await apis.user.nodes.lockFile(fileLockedId); + await apis.user.nodes.lockFile(fileFavLockedId); + await apis.user.nodes.lockFile(fileSharedLockedId); + await apis.user.nodes.lockFile(fileSharedFavLockedId); + + await apis.user.favorites.waitForApi({ expect: 7 }); + await apis.user.shared.waitForApi({ expect: 6 }); + await apis.user.search.waitForApi(username, { expect: 12 }); + + await loginPage.loginWith(username); + done(); + }); + + afterAll(async (done) => { + await apis.user.nodes.deleteNodeById(parentId); + done(); + }); + + describe('on a file', () => { + + beforeEach(async (done) => { + await Utils.pressEscape(); + await page.clickPersonalFiles(); + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFiles(); + await searchInput.searchFor('file-'); + done(); + }); + + afterEach(async (done) => { + await Utils.pressEscape(); + done(); + }); + + it('File Office - []', async () => { + await testUtil.checkToolbarPrimary(data.fileDocx.name, data.fileDocx.searchToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileDocx.name, data.fileDocx.searchToolbarMore); + await testUtil.checkContextMenu(data.fileDocx.name, data.fileDocx.searchContextMenu); + }); + + it('File Office, favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.fileDocxFav.name, data.fileDocxFav.searchToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileDocxFav.name, data.fileDocxFav.searchToolbarMore); + await testUtil.checkContextMenu(data.fileDocxFav.name, data.fileDocxFav.searchContextMenu); + }); + + it('File simple - []', async () => { + await testUtil.checkToolbarPrimary(data.file.name, data.file.searchToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.file.name, data.file.searchToolbarMore); + await testUtil.checkContextMenu(data.file.name, data.file.searchContextMenu); + }); + + it('File favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.fileFav.name, data.fileFav.searchToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileFav.name, data.fileFav.searchToolbarMore); + await testUtil.checkContextMenu(data.fileFav.name, data.fileFav.searchContextMenu); + }); + + it('File Office, shared - []', async () => { + await testUtil.checkToolbarPrimary(data.fileDocxShared.name, data.fileDocxShared.searchToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileDocxShared.name, data.fileDocxShared.searchToolbarMore); + await testUtil.checkContextMenu(data.fileDocxShared.name, data.fileDocxShared.searchContextMenu); + }); + + it('File Office, shared, favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.fileDocxSharedFav.name, data.fileDocxSharedFav.searchToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileDocxSharedFav.name, data.fileDocxSharedFav.searchToolbarMore); + await testUtil.checkContextMenu(data.fileDocxSharedFav.name, data.fileDocxSharedFav.searchContextMenu); + }); + + it('File shared - []', async () => { + await testUtil.checkToolbarPrimary(data.fileShared.name, data.fileShared.searchToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileShared.name, data.fileShared.searchToolbarMore); + await testUtil.checkContextMenu(data.fileShared.name, data.fileShared.searchContextMenu); + }); + + it('File shared, favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.fileSharedFav.name, data.fileSharedFav.searchToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileSharedFav.name, data.fileSharedFav.searchToolbarMore); + await testUtil.checkContextMenu(data.fileSharedFav.name, data.fileSharedFav.searchContextMenu); + }); + + it('File locked - []', async () => { + await testUtil.checkToolbarPrimary(data.fileLocked.name, data.fileLocked.searchToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileLocked.name, data.fileLocked.searchToolbarMore); + await testUtil.checkContextMenu(data.fileLocked.name, data.fileLocked.searchContextMenu); + }); + + it('File favorite, locked - []', async () => { + await testUtil.checkToolbarPrimary(data.fileFavLocked.name, data.fileFavLocked.searchToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileFavLocked.name, data.fileFavLocked.searchToolbarMore); + await testUtil.checkContextMenu(data.fileFavLocked.name, data.fileFavLocked.searchContextMenu); + }); + + it('File shared, locked - []', async () => { + await testUtil.checkToolbarPrimary(data.fileSharedLocked.name, data.fileSharedLocked.searchToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileSharedLocked.name, data.fileSharedLocked.searchToolbarMore); + await testUtil.checkContextMenu(data.fileSharedLocked.name, data.fileSharedLocked.searchContextMenu); + }); + + it('File shared, favorite, locked - []', async () => { + await testUtil.checkToolbarPrimary(data.fileSharedFavLocked.name, data.fileSharedFavLocked.searchToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileSharedFavLocked.name, data.fileSharedFavLocked.searchToolbarMore); + await testUtil.checkContextMenu(data.fileSharedFavLocked.name, data.fileSharedFavLocked.searchContextMenu); + }); + }); + + describe('on a folder', () => { + + beforeEach(async (done) => { + await Utils.pressEscape(); + await page.clickPersonalFiles(); + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFolders(); + await searchInput.searchFor('folder-'); + done(); + }); + + afterEach(async (done) => { + await Utils.pressEscape(); + done(); + }); + + it('Folder not favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.folder.name, data.folder.searchToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.folder.name, data.folder.searchToolbarMore); + await testUtil.checkContextMenu(data.folder.name, data.folder.searchContextMenu); + }); + + it('Folder favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.folderFav.name, data.folderFav.searchToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.folderFav.name, data.folderFav.searchToolbarMore); + await testUtil.checkContextMenu(data.folderFav.name, data.folderFav.searchContextMenu); + }); + }); + + describe('on multiple selection', () => { + beforeEach(async (done) => { + await Utils.pressEscape(); + await page.clickPersonalFiles(); + done(); + }); + + afterEach(async (done) => { + await Utils.pressEscape(); + done(); + }); + + it('multiple files - [C291820]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFiles(); + await searchInput.searchFor('file-'); + + await testUtil.checkMultipleSelContextMenu([ data.file.name, data.fileDocxShared.name ], data.multipleSel.searchContextMenu); + await testUtil.checkMultipleSelToolbarPrimary([ data.file.name, data.fileDocxShared.name ], data.multipleSel.searchToolbarPrimary); + await testUtil.checkMultipleSelToolbarMoreActions([ data.file.name, data.fileDocxShared.name ], data.multipleSel.searchToolbarMore); + }); + + it('multiple files - all favorite - []', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFiles(); + await searchInput.searchFor('file-'); + + await testUtil.checkMultipleSelContextMenu([ data.fileDocxFav.name, data.fileSharedFav.name ], data.multipleSelAllFav.searchContextMenu); + await testUtil.checkMultipleSelToolbarPrimary([ data.fileDocxFav.name, data.fileSharedFav.name ], data.multipleSelAllFav.searchToolbarPrimary); + await testUtil.checkMultipleSelToolbarMoreActions([ data.fileDocxFav.name, data.fileSharedFav.name ], data.multipleSelAllFav.searchToolbarMore); + }); + + it('multiple locked files - [C297626]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFiles(); + await searchInput.searchFor('file-'); + + await testUtil.checkMultipleSelContextMenu([ data.fileLocked.name, data.fileSharedFavLocked.name ], data.multipleSel.searchContextMenu); + await testUtil.checkMultipleSelToolbarPrimary([ data.fileLocked.name, data.fileSharedFavLocked.name ], data.multipleSel.searchToolbarPrimary); + await testUtil.checkMultipleSelToolbarMoreActions([ data.fileLocked.name, data.fileSharedFavLocked.name ], data.multipleSel.searchToolbarMore); + }); + + it('multiple folders - [C291821]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFolders(); + await searchInput.searchFor('folder-'); + + await testUtil.checkMultipleSelContextMenu([ data.folder.name, data.folderFav.name ], data.multipleSel.searchContextMenu); + await testUtil.checkMultipleSelToolbarPrimary([ data.folder.name, data.folderFav.name ], data.multipleSel.searchToolbarPrimary); + await testUtil.checkMultipleSelToolbarMoreActions([ data.folder.name, data.folderFav.name ], data.multipleSel.searchToolbarMore); + }); + + it('both files and folders - [C291822]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkFilesAndFolders(); + await searchInput.searchFor(`=${data.file.name} or =${data.folderFav.name}`); + + await testUtil.checkMultipleSelContextMenu([ data.file.name, data.folderFav.name ], data.multipleSel.searchContextMenu); + await testUtil.checkMultipleSelToolbarPrimary([ data.file.name, data.folderFav.name ], data.multipleSel.searchToolbarPrimary); + await testUtil.checkMultipleSelToolbarMoreActions([ data.file.name, data.folderFav.name ], data.multipleSel.searchToolbarMore); + }); + }); +}); diff --git a/e2e/suites/actions-available/files-folders/shared.test.ts b/e2e/suites/actions-available/files-folders/shared.test.ts new file mode 100755 index 0000000000..105e365f4c --- /dev/null +++ b/e2e/suites/actions-available/files-folders/shared.test.ts @@ -0,0 +1,162 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2019 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { LoginPage, BrowsingPage } from '../../../pages/pages'; +import { FILES } from '../../../configs'; +import { RepoClient } from '../../../utilities/repo-client/repo-client'; +import { Utils } from '../../../utilities/utils'; +import * as data from './test-data-files-folders'; +import * as testUtil from '../test-util'; + +describe('File actions : on Shared Files : ', () => { + + const random = Utils.random(); + + const username = `user-${random}`; + + const parent = `parent-${random}`; let parentId; + + let fileDocxSharedId, fileDocxSharedFavId, fileSharedId, fileSharedFavId, fileSharedLockedId, fileSharedFavLockedId; + + const apis = { + admin: new RepoClient(), + user: new RepoClient(username, username) + }; + + const loginPage = new LoginPage(); + const page = new BrowsingPage(); + + beforeAll(async (done) => { + await apis.admin.people.createUser({ username }); + + parentId = (await apis.user.nodes.createFolder(parent)).entry.id; + + fileDocxSharedId = (await apis.user.upload.uploadFileWithRename(FILES.docxFile, parentId, data.fileDocxShared.name)).entry.id; + fileDocxSharedFavId = (await apis.user.upload.uploadFileWithRename(FILES.docxFile, parentId, data.fileDocxSharedFav.name)).entry.id; + fileSharedId = (await apis.user.nodes.createFile(data.fileShared.name, parentId)).entry.id; + fileSharedFavId = (await apis.user.nodes.createFile(data.fileSharedFav.name, parentId)).entry.id; + fileSharedLockedId = (await apis.user.nodes.createFile(data.fileSharedLocked.name, parentId)).entry.id; + fileSharedFavLockedId = (await apis.user.nodes.createFile(data.fileSharedFavLocked.name, parentId)).entry.id; + + await apis.user.favorites.addFavoritesByIds('file', [ + fileDocxSharedFavId, + fileSharedFavId, + fileSharedFavLockedId + ]); + + await apis.user.shared.shareFilesByIds([ + fileDocxSharedId, + fileDocxSharedFavId, + fileSharedId, + fileSharedFavId, + fileSharedLockedId, + fileSharedFavLockedId + ]); + + await apis.user.nodes.lockFile(fileSharedLockedId); + await apis.user.nodes.lockFile(fileSharedFavLockedId); + + await apis.user.favorites.waitForApi({ expect: 3 }); + await apis.user.shared.waitForApi({ expect: 6 }); + + await loginPage.loginWith(username); + done(); + }); + + afterAll(async (done) => { + await apis.user.nodes.deleteNodeById(parentId); + done(); + }); + + beforeEach(async (done) => { + await Utils.pressEscape(); + await page.clickSharedFilesAndWait(); + done(); + }); + + afterEach(async (done) => { + await Utils.pressEscape(); + done(); + }); + + describe('single selection', () => { + it('File Office, shared - []', async () => { + await testUtil.checkToolbarPrimary(data.fileDocxShared.name, data.fileDocxShared.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileDocxShared.name, data.fileDocxShared.sharedToolbarMore); + await testUtil.checkContextMenu(data.fileDocxShared.name, data.fileDocxShared.sharedContextMenu); + }); + + it('File Office, shared, favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.fileDocxSharedFav.name, data.fileDocxSharedFav.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileDocxSharedFav.name, data.fileDocxSharedFav.sharedToolbarMore); + await testUtil.checkContextMenu(data.fileDocxSharedFav.name, data.fileDocxSharedFav.sharedContextMenu); + }); + + it('File shared - []', async () => { + await testUtil.checkToolbarPrimary(data.fileShared.name, data.fileShared.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileShared.name, data.fileShared.sharedToolbarMore); + await testUtil.checkContextMenu(data.fileShared.name, data.fileShared.sharedContextMenu); + }); + + it('File shared, favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.fileSharedFav.name, data.fileSharedFav.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileSharedFav.name, data.fileSharedFav.sharedToolbarMore); + await testUtil.checkContextMenu(data.fileSharedFav.name, data.fileSharedFav.sharedContextMenu); + }); + + it('File shared, locked - []', async () => { + await testUtil.checkToolbarPrimary(data.fileSharedLocked.name, data.fileSharedLocked.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileSharedLocked.name, data.fileSharedLocked.sharedToolbarMore); + await testUtil.checkContextMenu(data.fileSharedLocked.name, data.fileSharedLocked.sharedContextMenu); + }); + + it('File shared, favorite, locked - []', async () => { + await testUtil.checkToolbarPrimary(data.fileSharedFavLocked.name, data.fileSharedFavLocked.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileSharedFavLocked.name, data.fileSharedFavLocked.sharedToolbarMore); + await testUtil.checkContextMenu(data.fileSharedFavLocked.name, data.fileSharedFavLocked.sharedContextMenu); + }); + }); + + describe('multiple selection', () => { + it('multiple files - [C280467]', async () => { + await testUtil.checkMultipleSelContextMenu([ data.fileShared.name, data.fileSharedFav.name ], data.multipleSel.contextMenu); + await testUtil.checkMultipleSelToolbarPrimary([ data.fileShared.name, data.fileSharedFav.name ], data.multipleSel.toolbarPrimary); + await testUtil.checkMultipleSelToolbarMoreActions([ data.fileShared.name, data.fileSharedFav.name ], data.multipleSel.toolbarMore); + }); + + it('multiple files - all favorite - []', async () => { + await testUtil.checkMultipleSelContextMenu([ data.fileSharedFav.name, data.fileSharedFavLocked.name ], data.multipleSelAllFav.contextMenu); + await testUtil.checkMultipleSelToolbarPrimary([ data.fileSharedFav.name, data.fileSharedFavLocked.name ], data.multipleSelAllFav.toolbarPrimary); + await testUtil.checkMultipleSelToolbarMoreActions([ data.fileSharedFav.name, data.fileSharedFavLocked.name ], data.multipleSelAllFav.toolbarMore); + }); + + it('multiple locked files - [C297623]', async () => { + await testUtil.checkMultipleSelContextMenu([ data.fileSharedLocked.name, data.fileSharedFavLocked.name ], data.multipleSel.contextMenu); + await testUtil.checkMultipleSelToolbarPrimary([ data.fileSharedLocked.name, data.fileSharedFavLocked.name ], data.multipleSel.toolbarPrimary); + await testUtil.checkMultipleSelToolbarMoreActions([ data.fileSharedLocked.name, data.fileSharedFavLocked.name ], data.multipleSel.toolbarMore); + }); + }); + +}); diff --git a/e2e/suites/actions-available/files-folders/test-data-files-folders.ts b/e2e/suites/actions-available/files-folders/test-data-files-folders.ts new file mode 100644 index 0000000000..ea17c4986b --- /dev/null +++ b/e2e/suites/actions-available/files-folders/test-data-files-folders.ts @@ -0,0 +1,472 @@ +import { Utils } from '../../../utilities/utils'; + +export const trashActions = ['Permanently Delete', 'Restore']; + +// ----- files ----- + +const fileContextMenu = ['Share', 'Download', 'View', 'Edit Offline', 'Upload New Version', 'Favorite', 'Move', 'Copy', 'Delete', 'Manage Versions', 'Permissions']; +const fileSharedFavLockedContextMenu = ['Shared Link Settings', 'Download', 'View', 'Cancel Editing', 'Upload New Version', 'Remove Favorite', 'Move', 'Copy', 'Delete', 'Manage Versions', 'Permissions']; +const fileToolbarPrimary = ['Share', 'Download', 'View', 'View Details', 'More Actions']; +const fileToolbarMore = ['Edit Offline', 'Upload New Version', 'Favorite', 'Move', 'Copy', 'Delete', 'Manage Versions', 'Permissions']; +const fileDocxToolbarMore = ['Edit in Microsoft Office™', 'Edit Offline', 'Upload New Version', 'Favorite', 'Move', 'Copy', 'Delete', 'Manage Versions', 'Permissions']; +const fileDocxContextMenu = ['Share', 'Download', 'View', 'Edit in Microsoft Office™', 'Edit Offline', 'Upload New Version', 'Favorite', 'Move', 'Copy', 'Delete', 'Manage Versions', 'Permissions']; +const fileSharedToolbarPrimary = ['Shared Link Settings', 'Download', 'View', 'View Details', 'More Actions']; +const fileFavLockedToolbarMore = ['Cancel Editing', 'Upload New Version', 'Remove Favorite', 'Move', 'Copy', 'Delete', 'Manage Versions', 'Permissions']; +const fileDocxFavContextMenu = ['Share', 'Download', 'View', 'Edit in Microsoft Office™', 'Edit Offline', 'Upload New Version', 'Remove Favorite', 'Move', 'Copy', 'Delete', 'Manage Versions', 'Permissions']; +const fileDocxFavToolbarMore = ['Edit in Microsoft Office™', 'Edit Offline', 'Upload New Version', 'Remove Favorite', 'Move', 'Copy', 'Delete', 'Manage Versions', 'Permissions']; +const fileDocxSharedFavContextMenu = ['Shared Link Settings', 'Download', 'View', 'Edit in Microsoft Office™', 'Edit Offline', 'Upload New Version', 'Remove Favorite', 'Move', 'Copy', 'Delete', 'Manage Versions', 'Permissions']; +const fileDocxSharedContextMenu = ['Shared Link Settings', 'Download', 'View', 'Edit in Microsoft Office™', 'Edit Offline', 'Upload New Version', 'Favorite', 'Move', 'Copy', 'Delete', 'Manage Versions', 'Permissions']; +const fileFavContextMenu = ['Share', 'Download', 'View', 'Edit Offline', 'Upload New Version', 'Remove Favorite', 'Move', 'Copy', 'Delete', 'Manage Versions', 'Permissions']; +const fileFavToolbarMore = ['Edit Offline', 'Upload New Version', 'Remove Favorite', 'Move', 'Copy', 'Delete', 'Manage Versions', 'Permissions']; +const fileSharedFavContextMenu = ['Shared Link Settings', 'Download', 'View', 'Edit Offline', 'Upload New Version', 'Remove Favorite', 'Move', 'Copy', 'Delete', 'Manage Versions', 'Permissions']; +const fileSharedContextMenu = ['Shared Link Settings', 'Download', 'View', 'Edit Offline', 'Upload New Version', 'Favorite', 'Move', 'Copy', 'Delete', 'Manage Versions', 'Permissions']; +const fileFavLockedContextMenu = ['Share', 'Download', 'View', 'Cancel Editing', 'Upload New Version', 'Remove Favorite', 'Move', 'Copy', 'Delete', 'Manage Versions', 'Permissions']; +const fileLockedContextMenu = ['Share', 'Download', 'View', 'Cancel Editing', 'Upload New Version', 'Favorite', 'Move', 'Copy', 'Delete', 'Manage Versions', 'Permissions']; +const fileLockedToolbarMore = ['Cancel Editing', 'Upload New Version', 'Favorite', 'Move', 'Copy', 'Delete', 'Manage Versions', 'Permissions']; +const fileSharedLockedContextMenu = ['Shared Link Settings', 'Download', 'View', 'Cancel Editing', 'Upload New Version', 'Favorite', 'Move', 'Copy', 'Delete', 'Manage Versions', 'Permissions']; + +// ---- VIEWER ---- + +const viewerSharedToolbarPrimary = ['Activate full-screen mode', 'Shared Link Settings', 'Download', 'Print', 'View Details', 'More Actions']; +const viewerToolbarPrimary = ['Activate full-screen mode', 'Share', 'Download', 'Print', 'View Details', 'More Actions']; +const viewerToolbarMore = ['Edit Offline', 'Upload New Version', 'Favorite', 'Move', 'Copy', 'Delete', 'Manage Versions', 'Permissions']; +const viewerFavToolbarMore = ['Edit Offline', 'Upload New Version', 'Remove Favorite', 'Move', 'Copy', 'Delete', 'Manage Versions', 'Permissions']; +const viewerDocxToolbarMore = ['Edit in Microsoft Office™', 'Edit Offline', 'Upload New Version', 'Favorite', 'Move', 'Copy', 'Delete', 'Manage Versions', 'Permissions']; +const viewerFavLockedToolbarMore = ['Cancel Editing', 'Upload New Version', 'Remove Favorite', 'Move', 'Copy', 'Delete', 'Manage Versions', 'Permissions']; +const viewerDocxFavToolbarMore = ['Edit in Microsoft Office™', 'Edit Offline', 'Upload New Version', 'Remove Favorite', 'Move', 'Copy', 'Delete', 'Manage Versions', 'Permissions']; +const viewerLockedToolbarMore = ['Cancel Editing', 'Upload New Version', 'Favorite', 'Move', 'Copy', 'Delete', 'Manage Versions', 'Permissions']; + + +// ---- FAVORITES workarounds ---- + +// TODO: add Edit Offline when ACA-2174 is fixed +// TODO: change 'Share' into 'Shared Link Settings' when ACA-2175 is done +// TODO: investigate why 'Edit in Microsoft Office™' and 'Permissions' are not displayed and raise issue + +// TODO: change 'Share' into 'Shared Link Settings' when ACA-2175 is done +const favoritesSharedToolbarPrimary = ['Share', 'Download', 'View', 'View Details', 'More Actions']; +// TODO: add Edit Offline when ACA-2174 is fixed +// TODO: investigate why 'Edit in Microsoft Office™' and 'Permissions' are not displayed and raise issue +const favoritesContextMenu = ['Share', 'Download', 'View', 'Upload New Version', 'Remove Favorite', 'Move', 'Copy', 'Delete', 'Manage Versions']; +// TODO: add Edit Offline when ACA-2174 is fixed +// TODO: investigate why 'Edit in Microsoft Office™' and 'Permissions' are not displayed and raise issue +const favoritesToolbarMore = ['Upload New Version', 'Remove Favorite', 'Move', 'Copy', 'Delete', 'Manage Versions']; +// TODO: add Edit Offline when ACA-2174 is fixed +// TODO: investigate why 'Edit in Microsoft Office™' and 'Permissions' are not displayed and raise issue +// TODO: change 'Share' into 'Shared Link Settings' when ACA-2175 is done +const favoritesSharedContextMenu = ['Share', 'Download', 'View', 'Upload New Version', 'Remove Favorite', 'Move', 'Copy', 'Delete', 'Manage Versions']; + +// ---- SEARCH workarounds ---- + +const searchDocxContextMenu = ['Share', 'Download', 'View', 'Edit in Microsoft Office™', 'Edit Offline', 'Upload New Version', 'Favorite', 'Copy', 'Manage Versions', 'Permissions']; +const searchToolbarPrimary = ['Toggle search filter', 'Share', 'Download', 'View', 'View Details', 'More Actions']; +const searchSharedToolbarPrimary = ['Toggle search filter', 'Shared Link Settings', 'Download', 'View', 'View Details', 'More Actions']; +const searchFavLockedToolbarMore = ['Cancel Editing', 'Upload New Version', 'Remove Favorite', 'Copy', 'Manage Versions', 'Permissions']; +const searchSharedFavLockedContextMenu = ['Shared Link Settings', 'Download', 'View', 'Cancel Editing', 'Upload New Version', 'Remove Favorite', 'Copy', 'Manage Versions', 'Permissions']; +const searchDocxToolbarMore = ['Edit in Microsoft Office™', 'Edit Offline', 'Upload New Version', 'Favorite', 'Copy', 'Manage Versions', 'Permissions']; +const searchFavContextMenu = ['Share', 'Download', 'View', 'Edit Offline', 'Upload New Version', 'Remove Favorite', 'Copy', 'Manage Versions', 'Permissions']; +const searchSharedLockedContextMenu = ['Shared Link Settings', 'Download', 'View', 'Cancel Editing', 'Upload New Version', 'Favorite', 'Copy', 'Manage Versions', 'Permissions']; +const searchDocxFavContextMenu = ['Share', 'Download', 'View', 'Edit in Microsoft Office™', 'Edit Offline', 'Upload New Version', 'Remove Favorite', 'Copy', 'Manage Versions', 'Permissions']; +const searchDocxFavToolbarMore = ['Edit in Microsoft Office™', 'Edit Offline', 'Upload New Version', 'Remove Favorite', 'Copy', 'Manage Versions', 'Permissions']; +const searchSharedContextMenu = ['Shared Link Settings', 'Download', 'View', 'Edit Offline', 'Upload New Version', 'Favorite', 'Copy', 'Manage Versions', 'Permissions']; +const searchToolbarMore = ['Edit Offline', 'Upload New Version', 'Favorite', 'Copy', 'Manage Versions', 'Permissions']; +const searchDocxSharedFavContextMenu = ['Shared Link Settings', 'Download', 'View', 'Edit in Microsoft Office™', 'Edit Offline', 'Upload New Version', 'Remove Favorite', 'Copy', 'Manage Versions', 'Permissions']; +const searchDocxSharedContextMenu = ['Shared Link Settings', 'Download', 'View', 'Edit in Microsoft Office™', 'Edit Offline', 'Upload New Version', 'Favorite', 'Copy', 'Manage Versions', 'Permissions']; +const searchFavToolbarMore = ['Edit Offline', 'Upload New Version', 'Remove Favorite', 'Copy', 'Manage Versions', 'Permissions']; +const searchContextMenu = ['Share', 'Download', 'View', 'Edit Offline', 'Upload New Version', 'Favorite', 'Copy', 'Manage Versions', 'Permissions']; +const searchFavLockedContextMenu = ['Share', 'Download', 'View', 'Cancel Editing', 'Upload New Version', 'Remove Favorite', 'Copy', 'Manage Versions', 'Permissions']; +const searchLockedToolbarMore = ['Cancel Editing', 'Upload New Version', 'Favorite', 'Copy', 'Manage Versions', 'Permissions']; +const searchLockedContextMenu = ['Share', 'Download', 'View', 'Cancel Editing', 'Upload New Version', 'Favorite', 'Copy', 'Manage Versions', 'Permissions']; +const searchSharedFavContextMenu = ['Shared Link Settings', 'Download', 'View', 'Edit Offline', 'Upload New Version', 'Remove Favorite', 'Copy', 'Manage Versions', 'Permissions']; + +const searchViewerToolbarMore = ['Edit Offline', 'Upload New Version', 'Favorite', 'Copy', 'Manage Versions', 'Permissions']; +const searchViewerFavToolbarMore = ['Edit Offline', 'Upload New Version', 'Remove Favorite', 'Copy', 'Manage Versions', 'Permissions']; +const searchViewerDocxToolbarMore = ['Edit in Microsoft Office™', 'Edit Offline', 'Upload New Version', 'Favorite', 'Copy', 'Manage Versions', 'Permissions']; +const searchViewerFavLockedToolbarMore = ['Cancel Editing', 'Upload New Version', 'Remove Favorite', 'Copy', 'Manage Versions', 'Permissions']; +const searchViewerDocxFavToolbarMore = ['Edit in Microsoft Office™', 'Edit Offline', 'Upload New Version', 'Remove Favorite', 'Copy', 'Manage Versions', 'Permissions']; +const searchViewerLockedToolbarMore = ['Cancel Editing', 'Upload New Version', 'Favorite', 'Copy', 'Manage Versions', 'Permissions']; + +// ---- SHARED workarounds ---- + +// TODO: add Edit Offline to expectedContextMenu when ACA-2173 is fixed +const sharedFilesDocxContextMenu = ['Shared Link Settings', 'Download', 'View', 'Edit in Microsoft Office™', 'Upload New Version', 'Favorite', 'Move', 'Copy', 'Delete', 'Manage Versions', 'Permissions']; +// TODO: add Edit Offline to expectedToolbarMore when ACA-2173 is fixed +const sharedFilesDocxToolbarMore = ['Edit in Microsoft Office™', 'Upload New Version', 'Favorite', 'Move', 'Copy', 'Delete', 'Manage Versions', 'Permissions']; +// TODO: add Edit Offline to expectedContextMenu when ACA-2173 is fixed +const sharedFilesDocxSharedFavContextMenu = ['Shared Link Settings', 'Download', 'View', 'Edit in Microsoft Office™', 'Upload New Version', 'Remove Favorite', 'Move', 'Copy', 'Delete', 'Manage Versions', 'Permissions']; +// TODO: add Edit Offline to expectedToolbarMore when ACA-2173 is fixed +const sharedFilesDocxSharedFavToolbarMore = ['Edit in Microsoft Office™', 'Upload New Version', 'Remove Favorite', 'Move', 'Copy', 'Delete', 'Manage Versions', 'Permissions']; +// TODO: add Cancel Editing to expectedContextMenu when ACA-2173 is fixed +const sharedFilesSharedContextMenu = ['Shared Link Settings', 'Download', 'View', 'Upload New Version', 'Favorite', 'Move', 'Copy', 'Delete', 'Manage Versions', 'Permissions']; +// TODO: add Cancel Editing to expectedToolbarMore when ACA-2173 is fixed +const sharedFilesSharedToolbarMore = ['Upload New Version', 'Favorite', 'Move', 'Copy', 'Delete', 'Manage Versions', 'Permissions']; +// TODO: add Edit Offline to expectedToolbarMore when ACA-2173 is fixed +const sharedFilesFavSharedContextMenu = ['Shared Link Settings', 'Download', 'View', 'Upload New Version', 'Remove Favorite', 'Move', 'Copy', 'Delete', 'Manage Versions', 'Permissions']; +// TODO: add Cancel Editing to expectedToolbarMore when ACA-2173 is fixed +const sharedFilesSharedFavToolbarMore = ['Upload New Version', 'Remove Favorite', 'Move', 'Copy', 'Delete', 'Manage Versions', 'Permissions']; + + + + +export const fileDocx = { + name: `file-docx-${Utils.random()}.docx`, + description: 'file not shared, not fav, office, not locked', + + contextMenu: fileDocxContextMenu, + toolbarPrimary: fileToolbarPrimary, + toolbarMore: fileDocxToolbarMore, + viewerToolbarPrimary, + viewerToolbarMore: viewerDocxToolbarMore, + + searchContextMenu: searchDocxContextMenu, + searchToolbarPrimary, + searchToolbarMore: searchDocxToolbarMore, + searchViewerToolbarMore: searchViewerDocxToolbarMore +}; + +export const fileDocxFav = { + name: `file-docx-fav-${Utils.random()}.docx`, + description: 'file not shared, fav, office, not locked', + + contextMenu: fileDocxFavContextMenu, + toolbarPrimary: fileToolbarPrimary, + toolbarMore: fileDocxFavToolbarMore, + viewerToolbarPrimary, + viewerToolbarMore: viewerDocxFavToolbarMore, + + favoritesToolbarMore, + favoritesContextMenu, + + searchContextMenu: searchDocxFavContextMenu, + searchToolbarPrimary, + searchToolbarMore: searchDocxFavToolbarMore, + searchViewerToolbarMore: searchViewerDocxFavToolbarMore, +}; + +export const file = { + name: `file-${Utils.random()}.txt`, + description: 'file not shared, not fav, not office, not locked', + + contextMenu: fileContextMenu, + toolbarPrimary: fileToolbarPrimary, + toolbarMore: fileToolbarMore, + viewerToolbarPrimary, + viewerToolbarMore, + + searchViewerToolbarMore, + searchContextMenu, + searchToolbarPrimary, + searchToolbarMore +}; + +export const fileFav = { + name: `file-fav-${Utils.random()}.txt`, + description: 'file not shared, fav, not office, not locked', + + contextMenu: fileFavContextMenu, + toolbarPrimary: fileToolbarPrimary, + toolbarMore: fileFavToolbarMore, + viewerToolbarPrimary, + viewerToolbarMore: viewerFavToolbarMore, + + favoritesContextMenu, + favoritesToolbarMore, + + searchContextMenu: searchFavContextMenu, + searchToolbarPrimary, + searchToolbarMore: searchFavToolbarMore, + searchViewerToolbarMore: searchViewerFavToolbarMore +}; + +export const fileDocxShared = { + name: `file-docx-shared-${Utils.random()}.docx`, + description: 'file shared, not fav, office, not locked', + + contextMenu: fileDocxSharedContextMenu, + toolbarPrimary: fileSharedToolbarPrimary, + toolbarMore: fileDocxToolbarMore, + viewerToolbarPrimary: viewerSharedToolbarPrimary, + viewerToolbarMore: viewerDocxToolbarMore, + + searchContextMenu: searchDocxSharedContextMenu, + searchToolbarPrimary: searchSharedToolbarPrimary, + searchToolbarMore: searchDocxToolbarMore, + searchViewerToolbarMore: searchViewerDocxToolbarMore, + + sharedContextMenu: sharedFilesDocxContextMenu, + sharedToolbarMore: sharedFilesDocxToolbarMore +}; + +export const fileDocxSharedFav = { + name: `file-docx-shared-fav-${Utils.random()}.docx`, + description: 'file shared, fav, office, not locked', + + contextMenu: fileDocxSharedFavContextMenu, + toolbarPrimary: fileSharedToolbarPrimary, + toolbarMore: fileDocxFavToolbarMore, + viewerToolbarPrimary: viewerSharedToolbarPrimary, + viewerToolbarMore: viewerDocxFavToolbarMore, + + favoritesContextMenu: favoritesSharedContextMenu, + favoritesToolbarPrimary: favoritesSharedToolbarPrimary, + favoritesToolbarMore, + + searchContextMenu: searchDocxSharedFavContextMenu, + searchToolbarPrimary: searchSharedToolbarPrimary, + searchToolbarMore: searchDocxFavToolbarMore, + searchViewerToolbarMore: searchViewerDocxFavToolbarMore, + + sharedContextMenu: sharedFilesDocxSharedFavContextMenu, + sharedToolbarMore: sharedFilesDocxSharedFavToolbarMore +}; + +export const fileShared = { + name: `file-shared-${Utils.random()}.txt`, + description: 'file shared, not fav, not office, not locked', + + contextMenu: fileSharedContextMenu, + toolbarPrimary: fileSharedToolbarPrimary, + toolbarMore: fileToolbarMore, + viewerToolbarPrimary: viewerSharedToolbarPrimary, + viewerToolbarMore, + + searchContextMenu: searchSharedContextMenu, + searchToolbarPrimary: searchSharedToolbarPrimary, + searchToolbarMore, + searchViewerToolbarMore, + + sharedContextMenu: sharedFilesSharedContextMenu, + sharedToolbarMore: sharedFilesSharedToolbarMore +}; + +export const fileSharedFav = { + name: `file-shared-fav-${Utils.random()}.txt`, + description: 'file shared, fav, not office, not locked', + + contextMenu: fileSharedFavContextMenu, + toolbarPrimary: fileSharedToolbarPrimary, + toolbarMore: fileFavToolbarMore, + viewerToolbarPrimary: viewerSharedToolbarPrimary, + viewerToolbarMore: viewerFavToolbarMore, + + favoritesContextMenu: favoritesSharedContextMenu, + favoritesToolbarPrimary: favoritesSharedToolbarPrimary, + favoritesToolbarMore, + + searchContextMenu: searchSharedFavContextMenu, + searchToolbarPrimary: searchSharedToolbarPrimary, + searchToolbarMore: searchFavToolbarMore, + searchViewerToolbarMore: searchViewerFavToolbarMore, + + sharedContextMenu: sharedFilesFavSharedContextMenu, + sharedToolbarMore: sharedFilesSharedFavToolbarMore +}; + +export const fileLocked = { + name: `file-locked-${Utils.random()}.txt`, + description: 'file not shared, not fav, not office, locked', + + contextMenu: fileLockedContextMenu, + toolbarPrimary: fileToolbarPrimary, + toolbarMore: fileLockedToolbarMore, + viewerToolbarPrimary, + viewerToolbarMore: viewerLockedToolbarMore, + + searchContextMenu: searchLockedContextMenu, + searchToolbarPrimary, + searchToolbarMore: searchLockedToolbarMore, + searchViewerToolbarMore: searchViewerLockedToolbarMore +}; + +export const fileFavLocked = { + name: `file-fav-locked-${Utils.random()}.txt`, + description: 'file not shared, fav, not office, locked', + + contextMenu: fileFavLockedContextMenu, + toolbarPrimary: fileToolbarPrimary, + toolbarMore: fileFavLockedToolbarMore, + viewerToolbarPrimary, + viewerToolbarMore: viewerFavLockedToolbarMore, + + favoritesContextMenu, + favoritesToolbarMore, + + searchContextMenu: searchFavLockedContextMenu, + searchToolbarPrimary, + searchToolbarMore: searchFavLockedToolbarMore, + searchViewerToolbarMore: searchViewerFavLockedToolbarMore +}; + +export const fileSharedLocked = { + name: `file-shared-locked-${Utils.random()}.txt`, + description: 'file shared, not fav, not office, locked', + + contextMenu: fileSharedLockedContextMenu, + toolbarPrimary: fileSharedToolbarPrimary, + toolbarMore: fileLockedToolbarMore, + viewerToolbarPrimary: viewerSharedToolbarPrimary, + viewerToolbarMore: viewerLockedToolbarMore, + + searchContextMenu: searchSharedLockedContextMenu, + searchToolbarPrimary: searchSharedToolbarPrimary, + searchToolbarMore: searchLockedToolbarMore, + searchViewerToolbarMore: searchViewerLockedToolbarMore, + + sharedContextMenu: sharedFilesSharedContextMenu, + sharedToolbarMore: sharedFilesSharedToolbarMore +}; + +export const fileSharedFavLocked = { + name: `file-shared-fav-locked-${Utils.random()}.txt`, + description: 'file shared, fav, not office, locked', + + contextMenu: fileSharedFavLockedContextMenu, + toolbarPrimary: fileSharedToolbarPrimary, + toolbarMore: fileFavLockedToolbarMore, + viewerToolbarPrimary: viewerSharedToolbarPrimary, + viewerToolbarMore: viewerFavLockedToolbarMore, + + favoritesContextMenu: favoritesSharedContextMenu, + favoritesToolbarPrimary: favoritesSharedToolbarPrimary, + favoritesToolbarMore, + + searchContextMenu: searchSharedFavLockedContextMenu, + searchToolbarPrimary: searchSharedToolbarPrimary, + searchToolbarMore: searchFavLockedToolbarMore, + searchViewerToolbarMore: searchViewerFavLockedToolbarMore, + + sharedContextMenu: sharedFilesFavSharedContextMenu, + sharedToolbarMore: sharedFilesSharedFavToolbarMore +}; + +export const fileInTrash = { + name: `deleted-file-${Utils.random()}.txt`, + trashActions +}; + +export const file2InTrash = { + name: `deleted-file2-${Utils.random()}.txt`, + trashActions +}; + +export const folderInTrash = { + name: `deleted-folder-${Utils.random()}`, + trashActions +}; + +export const folder2InTrash = { + name: `deleted-folder2-${Utils.random()}`, + trashActions +}; + +// ---- folders --- + +const folderContextMenu = ['Download', 'Edit', 'Favorite', 'Move', 'Copy', 'Delete', 'Permissions']; +const folderFavContextMenu = ['Download', 'Edit', 'Remove Favorite', 'Move', 'Copy', 'Delete', 'Permissions']; +const folderToolbarPrimary = ['Download', 'View Details', 'More Actions']; +const folderToolbarMore = ['Edit', 'Favorite', 'Move', 'Copy', 'Delete', 'Permissions']; +const folderFavToolbarMore = ['Edit', 'Remove Favorite', 'Move', 'Copy', 'Delete', 'Permissions']; + +const favoritesFolderFavContextMenu = ['Download', 'Edit', 'Remove Favorite', 'Move', 'Copy', 'Delete']; +const favoritesFolderFavToolbarMore = ['Edit', 'Remove Favorite', 'Move', 'Copy', 'Delete']; + +const searchFolderContextMenu = ['Download', 'Edit', 'Favorite', 'Copy', 'Permissions']; +const searchFolderToolbarPrimary = ['Toggle search filter', 'Download', 'View Details', 'More Actions']; +const searchFolderToolbarMore = ['Edit', 'Favorite', 'Copy', 'Permissions']; +const searchFolderFavContextMenu = ['Download', 'Edit', 'Remove Favorite', 'Copy', 'Permissions']; +const searchFolderFavToolbarMore = ['Edit', 'Remove Favorite', 'Copy', 'Permissions']; + +export const folder = { + name: `folder-${Utils.random()}`, + description: 'folder not favorite', + + contextMenu: folderContextMenu, + toolbarPrimary: folderToolbarPrimary, + toolbarMore: folderToolbarMore, + + searchContextMenu: searchFolderContextMenu, + searchToolbarPrimary: searchFolderToolbarPrimary, + searchToolbarMore: searchFolderToolbarMore +}; + +export const folderFav = { + name: `folder-fav-${Utils.random()}`, + description: 'folder favorite', + + contextMenu: folderFavContextMenu, + toolbarPrimary: folderToolbarPrimary, + toolbarMore: folderFavToolbarMore, + + favoritesContextMenu: favoritesFolderFavContextMenu, + favoritesToolbarMore: favoritesFolderFavToolbarMore, + + searchContextMenu: searchFolderFavContextMenu, + searchToolbarPrimary: searchFolderToolbarPrimary, + searchToolbarMore: searchFolderFavToolbarMore +}; + +export const folderFav2 = { + name: `folder-fav-2-${Utils.random()}`, + description: 'folder favorite', + + contextMenu: folderFavContextMenu, + toolbarPrimary: folderToolbarPrimary, + toolbarMore: folderFavToolbarMore, + + favoritesContextMenu: favoritesFolderFavContextMenu, + favoritesToolbarMore: favoritesFolderFavToolbarMore, + + searchContextMenu: searchFolderFavContextMenu, + searchToolbarPrimary: searchFolderToolbarPrimary, + searchToolbarMore: searchFolderFavToolbarMore +}; + +// ---- multiple selection --- + + +// TODO: raise issue to remove 'Permissions' +const multipleSelContextMenu = ['Download', 'Favorite', 'Move', 'Copy', 'Delete', 'Permissions']; +// TODO: raise issue to remove 'Permissions' +const multipleSelAllFavContextMenu = ['Download', 'Remove Favorite', 'Move', 'Copy', 'Delete', 'Permissions']; +const multipleSelToolbarPrimary = ['Download', 'View Details', 'More Actions']; +// TODO: raise issue to remove 'Permissions' +const multipleSelToolbarMore = ['Favorite', 'Move', 'Copy', 'Delete', 'Permissions']; +// TODO: raise issue to remove 'Permissions' +const multipleSelAllFavToolbarMore = ['Remove Favorite', 'Move', 'Copy', 'Delete', 'Permissions']; + +const favoritesMultipleSelAllFavContextMenu = ['Download', 'Remove Favorite', 'Move', 'Copy', 'Delete']; +const favoritesMultipleSelAllFavToolbarMore = ['Remove Favorite', 'Move', 'Copy', 'Delete']; + +// TODO: raise issue to remove 'Permissions' +const searchMultipleSelContextMenu = ['Download', 'Favorite', 'Copy', 'Permissions']; +// TODO: raise issue to remove 'Permissions' +const searchMultipleSelAllFavContextMenu = ['Download', 'Remove Favorite', 'Copy', 'Permissions']; +const searchMultipleSelToolbarPrimary = ['Toggle search filter', 'Download', 'View Details', 'More Actions']; +// TODO: raise issue to remove 'Permissions' +const searchMultipleSelToolbarMore = ['Favorite', 'Copy', 'Permissions']; +// TODO: raise issue to remove 'Permissions' +const searchMultipleSelAllFavToolbarMore = ['Remove Favorite', 'Copy', 'Permissions']; + + +export const multipleSel = { + contextMenu: multipleSelContextMenu, + toolbarPrimary: multipleSelToolbarPrimary, + toolbarMore: multipleSelToolbarMore, + + searchContextMenu: searchMultipleSelContextMenu, + searchToolbarMore: searchMultipleSelToolbarMore, + searchToolbarPrimary: searchMultipleSelToolbarPrimary +} + +export const multipleSelAllFav = { + contextMenu: multipleSelAllFavContextMenu, + toolbarPrimary: multipleSelToolbarPrimary, + toolbarMore: multipleSelAllFavToolbarMore, + + favoritesContextMenu: favoritesMultipleSelAllFavContextMenu, + favoritesToolbarMore: favoritesMultipleSelAllFavToolbarMore, + + searchToolbarPrimary: searchMultipleSelToolbarPrimary, + searchContextMenu: searchMultipleSelAllFavContextMenu, + searchToolbarMore: searchMultipleSelAllFavToolbarMore +} diff --git a/e2e/suites/actions-available/files-folders/trash.test.ts b/e2e/suites/actions-available/files-folders/trash.test.ts new file mode 100755 index 0000000000..af1e1e19dc --- /dev/null +++ b/e2e/suites/actions-available/files-folders/trash.test.ts @@ -0,0 +1,106 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2019 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { LoginPage, BrowsingPage } from '../../../pages/pages'; +import { RepoClient } from '../../../utilities/repo-client/repo-client'; +import { Utils } from '../../../utilities/utils'; +import * as data from './test-data-files-folders'; +import * as testUtil from '../test-util'; + +describe('File/folder actions : on Trash : ', () => { + + const username = `user-${Utils.random()}`; + + let fileInTrashId, file2InTrashId, folderInTrashId, folder2InTrashId; + + const apis = { + admin: new RepoClient(), + user: new RepoClient(username, username) + }; + + const loginPage = new LoginPage(); + const page = new BrowsingPage(); + + beforeAll(async (done) => { + await apis.admin.people.createUser({ username }); + + fileInTrashId = (await apis.user.nodes.createFile(data.fileInTrash.name)).entry.id; + file2InTrashId = (await apis.user.nodes.createFile(data.file2InTrash.name)).entry.id; + folderInTrashId = (await apis.user.nodes.createFolder(data.folderInTrash.name)).entry.id; + folder2InTrashId = (await apis.user.nodes.createFolder(data.folder2InTrash.name)).entry.id; + + await apis.user.nodes.deleteNodeById(fileInTrashId, false); + await apis.user.nodes.deleteNodeById(file2InTrashId, false); + await apis.user.nodes.deleteNodeById(folderInTrashId, false); + await apis.user.nodes.deleteNodeById(folder2InTrashId, false); + + await apis.user.trashcan.waitForApi({ expect: 4 }); + + await loginPage.loginWith(username); + done(); + }); + + afterAll(async (done) => { + await apis.user.trashcan.emptyTrash(); + done(); + }); + + beforeEach(async (done) => { + await Utils.pressEscape(); + await page.clickTrashAndWait(); + done(); + }); + + afterEach(async (done) => { + await Utils.pressEscape(); + done(); + }); + + it('on a file - [C286258]', async () => { + await testUtil.checkToolbarPrimary(data.fileInTrash.name, data.fileInTrash.trashActions); + await testUtil.checkContextMenu(data.fileInTrash.name, data.fileInTrash.trashActions); + }); + + it('on a folder - [C286259]', async () => { + await testUtil.checkToolbarPrimary(data.folderInTrash.name, data.folderInTrash.trashActions); + await testUtil.checkContextMenu(data.folderInTrash.name, data.folderInTrash.trashActions); + }); + + it('multiple files - [C280472]', async () => { + await testUtil.checkMultipleSelContextMenu([ data.fileInTrash.name, data.file2InTrash.name ], data.trashActions); + await testUtil.checkMultipleSelToolbarPrimary([ data.fileInTrash.name, data.file2InTrash.name ], data.trashActions); + }); + + it('multiple folders - [C280473]', async () => { + await testUtil.checkMultipleSelContextMenu([ data.folderInTrash.name, data.folder2InTrash.name ], data.trashActions); + await testUtil.checkMultipleSelToolbarPrimary([ data.folderInTrash.name, data.folder2InTrash.name ], data.trashActions); + }); + + it('both files and folders - [C280474]', async () => { + await testUtil.checkMultipleSelContextMenu([ data.fileInTrash.name, data.folderInTrash.name ], data.trashActions); + await testUtil.checkMultipleSelToolbarPrimary([ data.fileInTrash.name, data.folderInTrash.name ], data.trashActions); + }); + +}); diff --git a/e2e/suites/actions-available/files-folders/viewer.test.ts b/e2e/suites/actions-available/files-folders/viewer.test.ts new file mode 100755 index 0000000000..fbb575534a --- /dev/null +++ b/e2e/suites/actions-available/files-folders/viewer.test.ts @@ -0,0 +1,421 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2019 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { LoginPage, BrowsingPage } from '../../../pages/pages'; +import { FILES } from '../../../configs'; +import { RepoClient } from '../../../utilities/repo-client/repo-client'; +import { Utils } from '../../../utilities/utils'; +import * as data from './test-data-files-folders'; +import * as testUtil from '../test-util'; + +describe('File/folder actions : in the viewer : ', () => { + + const random = Utils.random(); + + const username = `user-${random}`; + + const parent = `parent-${random}`; let parentId; + + let fileDocxFavId, fileFavId, fileDocxSharedId, fileDocxSharedFavId, fileSharedId, fileSharedFavId, fileLockedId, fileFavLockedId, fileSharedLockedId, fileSharedFavLockedId; + + const apis = { + admin: new RepoClient(), + user: new RepoClient(username, username) + }; + + const loginPage = new LoginPage(); + const page = new BrowsingPage(); + const { dataTable } = page; + const { searchInput } = page.header; + + beforeAll(async (done) => { + await apis.admin.people.createUser({ username }); + + parentId = (await apis.user.nodes.createFolder(parent)).entry.id; + + await apis.user.upload.uploadFileWithRename(FILES.docxFile, parentId, data.fileDocx.name ); + fileDocxFavId = (await apis.user.upload.uploadFileWithRename(FILES.docxFile, parentId, data.fileDocxFav.name)).entry.id; + await apis.user.nodes.createFile(data.file.name, parentId); + fileFavId = (await apis.user.nodes.createFile(data.fileFav.name, parentId)).entry.id; + fileDocxSharedId = (await apis.user.upload.uploadFileWithRename(FILES.docxFile, parentId, data.fileDocxShared.name)).entry.id; + fileDocxSharedFavId = (await apis.user.upload.uploadFileWithRename(FILES.docxFile, parentId, data.fileDocxSharedFav.name)).entry.id; + fileSharedId = (await apis.user.nodes.createFile(data.fileShared.name, parentId)).entry.id; + fileSharedFavId = (await apis.user.nodes.createFile(data.fileSharedFav.name, parentId)).entry.id; + fileLockedId = (await apis.user.nodes.createFile(data.fileLocked.name, parentId)).entry.id; + fileFavLockedId = (await apis.user.nodes.createFile(data.fileFavLocked.name, parentId)).entry.id; + fileSharedLockedId = (await apis.user.nodes.createFile(data.fileSharedLocked.name, parentId)).entry.id; + fileSharedFavLockedId = (await apis.user.nodes.createFile(data.fileSharedFavLocked.name, parentId)).entry.id; + + await apis.user.favorites.addFavoritesByIds('file', [ + fileDocxFavId, + fileFavId, + fileDocxSharedFavId, + fileSharedFavId, + fileFavLockedId, + fileSharedFavLockedId + ]); + + await apis.user.shared.shareFilesByIds([ + fileDocxSharedId, + fileDocxSharedFavId, + fileSharedId, + fileSharedFavId, + fileSharedLockedId, + fileSharedFavLockedId + ]); + + await apis.user.nodes.lockFile(fileLockedId); + await apis.user.nodes.lockFile(fileFavLockedId); + await apis.user.nodes.lockFile(fileSharedLockedId); + await apis.user.nodes.lockFile(fileSharedFavLockedId); + + await apis.user.favorites.waitForApi({ expect: 6 }); + await apis.user.shared.waitForApi({ expect: 6 }); + + await loginPage.loginWith(username); + done(); + }); + + afterAll(async (done) => { + await apis.user.nodes.deleteNodeById(parentId); + done(); + }); + + describe('file opened from Personal Files', () => { + + beforeEach(async (done) => { + await Utils.pressEscape(); + await page.clickPersonalFilesAndWait(); + await dataTable.doubleClickOnRowByName(parent); + await dataTable.waitForHeader(); + done(); + }); + + afterEach(async (done) => { + await Utils.pressEscape(); + done(); + }); + + it('File Office - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileDocx.name, data.fileDocx.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileDocx.name, data.fileDocx.viewerToolbarMore); + }); + + it('File Office, favorite - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileDocxFav.name, data.fileDocxFav.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileDocxFav.name, data.fileDocxFav.viewerToolbarMore); + }); + + it('File simple - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.file.name, data.file.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.file.name, data.file.viewerToolbarMore); + }); + + it('File favorite - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileFav.name, data.fileFav.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileFav.name, data.fileFav.viewerToolbarMore); + }); + + it('File Office, shared - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileDocxShared.name, data.fileDocxShared.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileDocxShared.name, data.fileDocxShared.viewerToolbarMore); + }); + + it('File Office, shared, favorite - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileDocxSharedFav.name, data.fileDocxSharedFav.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileDocxSharedFav.name, data.fileDocxSharedFav.viewerToolbarMore); + }); + + it('File shared - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileShared.name, data.fileShared.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileShared.name, data.fileShared.viewerToolbarMore); + }); + + it('File shared, favorite - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileSharedFav.name, data.fileSharedFav.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileSharedFav.name, data.fileSharedFav.viewerToolbarMore); + }); + + it('File locked - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileLocked.name, data.fileLocked.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileLocked.name, data.fileLocked.viewerToolbarMore); + }); + + it('File favorite, locked - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileFavLocked.name, data.fileFavLocked.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileFavLocked.name, data.fileFavLocked.viewerToolbarMore); + }); + + it('File shared, locked - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileSharedLocked.name, data.fileSharedLocked.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileSharedLocked.name, data.fileSharedLocked.viewerToolbarMore); + }); + + it('File shared, favorite, locked - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileSharedFavLocked.name, data.fileSharedFavLocked.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileSharedFavLocked.name, data.fileSharedFavLocked.viewerToolbarMore); + }); + }); + + describe('file opened from Recent Files', () => { + + beforeEach(async (done) => { + await Utils.pressEscape(); + await page.clickRecentFilesAndWait(); + done(); + }); + + afterEach(async (done) => { + await Utils.pressEscape(); + done(); + }); + + it('File Office - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileDocx.name, data.fileDocx.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileDocx.name, data.fileDocx.viewerToolbarMore); + }); + + it('File Office, favorite - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileDocxFav.name, data.fileDocxFav.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileDocxFav.name, data.fileDocxFav.viewerToolbarMore); + }); + + it('File simple - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.file.name, data.file.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.file.name, data.file.viewerToolbarMore); + }); + + it('File favorite - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileFav.name, data.fileFav.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileFav.name, data.fileFav.viewerToolbarMore); + }); + + it('File Office, shared - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileDocxShared.name, data.fileDocxShared.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileDocxShared.name, data.fileDocxShared.viewerToolbarMore); + }); + + it('File Office, shared, favorite - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileDocxSharedFav.name, data.fileDocxSharedFav.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileDocxSharedFav.name, data.fileDocxSharedFav.viewerToolbarMore); + }); + + it('File shared - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileShared.name, data.fileShared.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileShared.name, data.fileShared.viewerToolbarMore); + }); + + it('File shared, favorite - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileSharedFav.name, data.fileSharedFav.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileSharedFav.name, data.fileSharedFav.viewerToolbarMore); + }); + + it('File locked - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileLocked.name, data.fileLocked.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileLocked.name, data.fileLocked.viewerToolbarMore); + }); + + it('File favorite, locked - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileFavLocked.name, data.fileFavLocked.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileFavLocked.name, data.fileFavLocked.viewerToolbarMore); + }); + + it('File shared, locked - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileSharedLocked.name, data.fileSharedLocked.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileSharedLocked.name, data.fileSharedLocked.viewerToolbarMore); + }); + + it('File shared, favorite, locked - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileSharedFavLocked.name, data.fileSharedFavLocked.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileSharedFavLocked.name, data.fileSharedFavLocked.viewerToolbarMore); + }); + }); + + describe('file opened from Favorites', () => { + + beforeEach(async (done) => { + await Utils.pressEscape(); + await page.clickFavoritesAndWait(); + done(); + }); + + afterEach(async (done) => { + await Utils.pressEscape(); + done(); + }); + + it('File Office, favorite - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileDocxFav.name, data.fileDocxFav.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileDocxFav.name, data.fileDocxFav.viewerToolbarMore); + }); + + it('File favorite - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileFav.name, data.fileFav.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileFav.name, data.fileFav.viewerToolbarMore); + }); + + it('File Office, shared, favorite - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileDocxSharedFav.name, data.fileDocxSharedFav.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileDocxSharedFav.name, data.fileDocxSharedFav.viewerToolbarMore); + }); + + it('File shared, favorite - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileSharedFav.name, data.fileSharedFav.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileSharedFav.name, data.fileSharedFav.viewerToolbarMore); + }); + + it('File favorite, locked - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileFavLocked.name, data.fileFavLocked.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileFavLocked.name, data.fileFavLocked.viewerToolbarMore); + }); + + it('File shared, favorite, locked - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileSharedFavLocked.name, data.fileSharedFavLocked.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileSharedFavLocked.name, data.fileSharedFavLocked.viewerToolbarMore); + }); + }); + + describe('file opened from Shared Files', () => { + + beforeEach(async (done) => { + await Utils.pressEscape(); + await page.clickSharedFilesAndWait(); + done(); + }); + + afterEach(async (done) => { + await Utils.pressEscape(); + done(); + }); + + it('File Office, shared - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileDocxShared.name, data.fileDocxShared.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileDocxShared.name, data.fileDocxShared.viewerToolbarMore); + }); + + it('File Office, shared, favorite - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileDocxSharedFav.name, data.fileDocxSharedFav.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileDocxSharedFav.name, data.fileDocxSharedFav.viewerToolbarMore); + }); + + it('File shared - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileShared.name, data.fileShared.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileShared.name, data.fileShared.viewerToolbarMore); + }); + + it('File shared, favorite - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileSharedFav.name, data.fileSharedFav.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileSharedFav.name, data.fileSharedFav.viewerToolbarMore); + }); + + it('File shared, locked - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileSharedLocked.name, data.fileSharedLocked.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileSharedLocked.name, data.fileSharedLocked.viewerToolbarMore); + }); + + it('File shared, favorite, locked - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileSharedFavLocked.name, data.fileSharedFavLocked.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileSharedFavLocked.name, data.fileSharedFavLocked.viewerToolbarMore); + }); + }); + + describe('file opened from Search Results', () => { + + beforeAll(async (done) => { + await Utils.pressEscape(); + await page.clickPersonalFiles(); + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFiles(); + await searchInput.searchFor('file-'); + done(); + }); + + afterEach(async (done) => { + await Utils.pressEscape(); + done(); + }); + + it('File Office - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileDocx.name, data.fileDocx.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileDocx.name, data.fileDocx.searchViewerToolbarMore); + }); + + it('File Office, favorite - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileDocxFav.name, data.fileDocxFav.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileDocxFav.name, data.fileDocxFav.searchViewerToolbarMore); + }); + + it('File simple - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.file.name, data.file.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.file.name, data.file.searchViewerToolbarMore); + }); + + it('File favorite - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileFav.name, data.fileFav.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileFav.name, data.fileFav.searchViewerToolbarMore); + }); + + it('File Office, shared - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileDocxShared.name, data.fileDocxShared.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileDocxShared.name, data.fileDocxShared.searchViewerToolbarMore); + }); + + it('File Office, shared, favorite - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileDocxSharedFav.name, data.fileDocxSharedFav.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileDocxSharedFav.name, data.fileDocxSharedFav.searchViewerToolbarMore); + }); + + it('File shared - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileShared.name, data.fileShared.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileShared.name, data.fileShared.searchViewerToolbarMore); + }); + + it('File shared, favorite - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileSharedFav.name, data.fileSharedFav.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileSharedFav.name, data.fileSharedFav.searchViewerToolbarMore); + }); + + it('File locked - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileLocked.name, data.fileLocked.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileLocked.name, data.fileLocked.searchViewerToolbarMore); + }); + + it('File favorite, locked - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileFavLocked.name, data.fileFavLocked.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileFavLocked.name, data.fileFavLocked.searchViewerToolbarMore); + }); + + it('File shared, locked - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileSharedLocked.name, data.fileSharedLocked.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileSharedLocked.name, data.fileSharedLocked.searchViewerToolbarMore); + }); + + it('File shared, favorite, locked - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileSharedFavLocked.name, data.fileSharedFavLocked.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileSharedFavLocked.name, data.fileSharedFavLocked.searchViewerToolbarMore); + }); + }); + +}); diff --git a/e2e/suites/actions-available/generic.test.ts b/e2e/suites/actions-available/generic.test.ts new file mode 100755 index 0000000000..467b2d5c24 --- /dev/null +++ b/e2e/suites/actions-available/generic.test.ts @@ -0,0 +1,224 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2019 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { browser, protractor } from 'protractor'; +import { LoginPage, BrowsingPage } from '../../pages/pages'; +import { RepoClient } from '../../utilities/repo-client/repo-client'; +import { Utils } from '../../utilities/utils'; + + +describe('Generic tests : ', () => { + + const random = Utils.random(); + + const username = `user-${random}`; + + const parent = `parent-${random}`; let parentId; + + const file1 = `file1-${random}.txt`; + const file2 = `file2-${random}.txt`; + + const folder1 = `my-folder1-${Utils.random()}`; + const folder2 = `my-folder2-${Utils.random()}`; + + const apis = { + admin: new RepoClient(), + user: new RepoClient(username, username) + }; + + const loginPage = new LoginPage(); + const page = new BrowsingPage(); + const { dataTable, toolbar } = page; + const { searchInput } = page.header; + const contextMenu = dataTable.menu; + + beforeAll(async (done) => { + await apis.admin.people.createUser({ username }); + + parentId = (await apis.user.nodes.createFolder(parent)).entry.id; + await apis.user.nodes.createFile(file1, parentId); + await apis.user.nodes.createFile(file2, parentId); + + await apis.user.nodes.createFolder(folder1, parentId); + await apis.user.nodes.createFolder(folder2, parentId); + + await loginPage.loginWith(username); + done(); + }); + + afterAll(async (done) => { + await apis.user.nodes.deleteNodeById(parentId); + done(); + }); + + beforeEach(async (done) => { + await Utils.pressEscape(); + await page.clickPersonalFilesAndWait(); + await dataTable.doubleClickOnRowByName(parent); + await dataTable.waitForHeader(); + done(); + }); + + afterEach(async (done) => { + await Utils.pressEscape(); + done(); + }); + + it('selected row is marked with a check circle icon - [C213134]', async () => { + await dataTable.selectItem(file1); + expect(await dataTable.hasCheckMarkIcon(file1)).toBe(true, 'check mark missing'); + }); + + it('Row is marked with a check circle icon on direct right click - [C286252]', async () => { + await dataTable.rightClickOnItem(file2); + expect(await dataTable.hasCheckMarkIcon(file2)).toBe(true, 'check mark missing'); + }); + + it('Context menu appears on direct right click on an item - [C286253]', async () => { + await dataTable.rightClickOnItem(file1); + expect(await dataTable.hasContextMenu()).toBe(true, 'Context menu is not displayed'); + }); + + it('Context menu appears when selecting an item and then right clicking on it - [C286254]', async () => { + await dataTable.selectItem(file2); + await dataTable.rightClickOnItem(file2); + expect(await dataTable.hasContextMenu()).toBe(true, 'Context menu is not displayed'); + }); + + it('Context menu appears correctly when right clicking on another item - [C284666]', async () => { + await dataTable.selectItem(file1); + await dataTable.rightClickOnItem(file2); + expect(await dataTable.hasContextMenu()).toBe(true, `Context menu is not displayed`); + expect(await dataTable.hasCheckMarkIcon(file2)).toBe(true, `${file2} is not selected`); + expect(await dataTable.hasCheckMarkIcon(file1)).toBe(false, `${file1} is not selected`); + }); + + it('Context menu closes when clicking away from it - [C280619]', async () => { + await dataTable.rightClickOnItem(file1); + expect(await dataTable.hasContextMenu()).toBe(true, 'Context menu is not displayed'); + await page.breadcrumb.getCurrentItem().click(); + expect(await dataTable.hasContextMenu()).toBe(false, 'Context menu is displayed'); + }); + + describe('Actions are not displayed when no item is selected', () => { + it('on Personal Files - [C213120]', async () => { + await page.clickPersonalFilesAndWait(); + await dataTable.clearSelection(); + expect(await toolbar.isEmpty()).toBe(true, `actions displayed though nothing selected`); + }); + + it('on Trash - [C280452]', async () => { + await page.clickTrash(); + await dataTable.clearSelection(); + expect(await toolbar.isEmpty()).toBe(true, `actions displayed though nothing selected`); + }); + + it('on Favorites - [C280449]', async () => { + await page.clickFavorites(); + await dataTable.clearSelection(); + expect(await toolbar.isEmpty()).toBe(true, `actions displayed though nothing selected`); + }); + + it('on Recent Files - [C280447]', async () => { + await page.clickRecentFilesAndWait(); + await dataTable.clearSelection(); + expect(await toolbar.isEmpty()).toBe(true, `actions displayed though nothing selected`); + }); + + it('on Shared Files - [C280445]', async () => { + await page.clickSharedFiles(); + await dataTable.clearSelection(); + expect(await toolbar.isEmpty()).toBe(true, `actions displayed though nothing selected`); + }); + + it('on My Libraries - [C280439]', async () => { + await page.goToMyLibraries(); + await dataTable.clearSelection(); + expect(await toolbar.isEmpty()).toBe(true, `actions displayed though nothing selected`); + }); + + it('on Favorite Libraries - [C280439]', async () => { + await page.goToFavoriteLibraries(); + await dataTable.clearSelection(); + expect(await toolbar.isEmpty()).toBe(true, `actions displayed though nothing selected`); + }); + + it('on Search Results - [C291815]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkFilesAndFolders(); + await searchInput.searchFor('*'); + + expect(await toolbar.isToggleSearchFiltersPresent()).toBe(true, `Search filter toggle is not displayed`); + expect(await toolbar.numberOfAvailableActions()).toBe(1, `more than 1 action is present`); + }); + }); + + it('Context menu appears on right click on a multiple selection of items - [C286268]', async () => { + await dataTable.selectMultipleItems([ file1, file2 ]); + await dataTable.rightClickOnMultipleSelection(); + + expect(await dataTable.hasContextMenu()).toBe(true, 'Context menu is not displayed'); + }); + + it('Context menu appears when right clicking on a single item while having multiple items selected - [C286269]', async () => { + await dataTable.selectMultipleItems([ file2, folder1 ]); + await dataTable.rightClickOnItem(file1); + + expect(await dataTable.hasContextMenu()).toBe(true, `Context menu is not displayed for ${file1}`); + expect(await dataTable.countSelectedRows()).toEqual(1, 'incorrect number of selected rows'); + expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${file1}`); + expect(await dataTable.hasCheckMarkIcon(file1)).toBe(true, `${file1} is not selected`); + expect(await dataTable.hasCheckMarkIcon(file2)).toBe(false, `${file2} is selected`); + expect(await dataTable.hasCheckMarkIcon(folder1)).toBe(false, `${folder1} is selected`); + }); + + it('Unselect items with single click - [C280458]', async () => { + await dataTable.selectMultipleItems([file1, file2, folder1, folder2]); + + expect(await dataTable.countSelectedRows()).toEqual(4, 'incorrect selected rows number'); + + await dataTable.clickItem(file1); + + expect(await dataTable.countSelectedRows()).toEqual(1, 'incorrect selected rows number'); + }); + + it('Select / unselect items by CMD+click - [C217110]', async () => { + await browser.actions().sendKeys(protractor.Key.COMMAND).perform(); + await dataTable.clickItem(file1); + await dataTable.clickItem(file2); + await dataTable.clickItem(folder1); + await dataTable.clickItem(folder2); + await browser.actions().sendKeys(protractor.Key.NULL).perform(); + + expect(await dataTable.countSelectedRows()).toEqual(4, 'incorrect selected rows number'); + + await browser.actions().sendKeys(protractor.Key.COMMAND).perform(); + await dataTable.clickItem(file1); + await dataTable.clickItem(file2); + await browser.actions().sendKeys(protractor.Key.NULL).perform(); + + expect(await dataTable.countSelectedRows()).toEqual(2, 'incorrect selected rows number'); + }); +}); diff --git a/e2e/suites/actions-available/libraries/library.test.ts b/e2e/suites/actions-available/libraries/library.test.ts new file mode 100755 index 0000000000..5d2ad5fe40 --- /dev/null +++ b/e2e/suites/actions-available/libraries/library.test.ts @@ -0,0 +1,328 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2019 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { LoginPage, BrowsingPage, SearchResultsPage } from '../../../pages/pages'; +import { SITE_VISIBILITY } from '../../../configs'; +import { RepoClient } from '../../../utilities/repo-client/repo-client'; +import { Utils } from '../../../utilities/utils'; +import * as data from './test-data-libraries'; +import * as testUtil from '../test-util'; + +describe('Library actions : ', () => { + const username = `user-${Utils.random()}`; + + const apis = { + admin: new RepoClient(), + user: new RepoClient(username, username) + }; + + const loginPage = new LoginPage(); + const page = new BrowsingPage(); + const searchResultsPage = new SearchResultsPage(); + const { searchInput } = searchResultsPage.header; + + beforeAll(async (done) => { + await apis.admin.people.createUser({ username }); + + await apis.user.sites.createSite(data.publicUserMemberFav.name); + await apis.user.sites.createSite(data.privateUserMemberFav.name, SITE_VISIBILITY.PRIVATE); + await apis.user.sites.createSite(data.moderatedUserMemberFav.name, SITE_VISIBILITY.MODERATED); + + const publicUserMemberNotFavId = (await apis.user.sites.createSite(data.publicUserMemberNotFav.name)).entry.guid; + const privateUserMemberNotFavId = (await apis.user.sites.createSite(data.privateUserMemberNotFav.name, SITE_VISIBILITY.PRIVATE)).entry.guid; + const moderatedUserMemberNotFavId = (await apis.user.sites.createSite(data.moderatedUserMemberNotFav.name, SITE_VISIBILITY.MODERATED)).entry.guid; + + await apis.admin.sites.createSite(data.publicNotMemberFav.name); + await apis.admin.sites.createSite(data.moderatedNotMemberFav.name, SITE_VISIBILITY.MODERATED); + + await apis.admin.sites.createSite(data.publicNotMemberNotFav.name); + await apis.admin.sites.createSite(data.moderatedNotMemberNotFav.name, SITE_VISIBILITY.MODERATED); + + await apis.admin.sites.createSite(data.moderatedRequestedJoinFav.name, SITE_VISIBILITY.MODERATED); + await apis.admin.sites.createSite(data.moderatedRequestedJoinNotFav.name, SITE_VISIBILITY.MODERATED); + + await apis.user.sites.createSite(data.siteInTrash.name, SITE_VISIBILITY.PUBLIC); + await apis.user.sites.createSite(data.site2InTrash.name, SITE_VISIBILITY.PUBLIC); + + await apis.user.sites.waitForApi({ expect: 8 }); + await apis.admin.sites.waitForApi({ expect: 6 }); + + await apis.user.favorites.removeFavoriteById(publicUserMemberNotFavId); + await apis.user.favorites.removeFavoriteById(privateUserMemberNotFavId); + await apis.user.favorites.removeFavoriteById(moderatedUserMemberNotFavId); + + await apis.user.favorites.addFavoriteById('site', data.publicNotMemberFav.name); + await apis.user.favorites.addFavoriteById('site', data.moderatedNotMemberFav.name); + await apis.user.favorites.addFavoriteById('site', data.moderatedRequestedJoinFav.name); + + await apis.user.sites.requestToJoin(data.moderatedRequestedJoinFav.name); + await apis.user.sites.requestToJoin(data.moderatedRequestedJoinNotFav.name); + + await apis.user.queries.waitForSites('site-', { expect: 13 }); + + await apis.user.sites.deleteSite(data.siteInTrash.name, false); + await apis.user.sites.deleteSite(data.site2InTrash.name, false); + + await apis.user.trashcan.waitForApi({ expect: 2 }); + + await loginPage.loginWith(username); + done(); + }); + + afterAll(async (done) => { + await Promise.all([ + apis.user.sites.deleteSites([ + data.publicUserMemberFav.name, + data.privateUserMemberFav.name, + data.moderatedUserMemberFav.name, + data.publicUserMemberNotFav.name, + data.privateUserMemberNotFav.name, + data.moderatedUserMemberNotFav.name + ]), + apis.admin.sites.deleteSites([ + data.publicNotMemberFav.name, + data.moderatedNotMemberFav.name, + data.publicNotMemberNotFav.name, + data.moderatedNotMemberNotFav.name, + data.moderatedRequestedJoinFav.name, + data.moderatedRequestedJoinNotFav.name + ]), + apis.user.trashcan.emptyTrash() + ]); + done(); + }); + + describe('on My Libraries', () => { + + beforeEach(async (done) => { + await Utils.pressEscape(); + await page.goToMyLibrariesAndWait(); + done(); + }); + + afterEach(async (done) => { + await Utils.pressEscape(); + done(); + }); + + it('Public library, user is a member, favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.publicUserMemberFav.name, data.publicUserMemberFav.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.publicUserMemberFav.name, data.publicUserMemberFav.toolbarMore); + await testUtil.checkContextMenu(data.publicUserMemberFav.name, data.publicUserMemberFav.contextMenu); + }); + + it('Private library, user is a member, favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.privateUserMemberFav.name, data.privateUserMemberFav.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.privateUserMemberFav.name, data.privateUserMemberFav.toolbarMore); + await testUtil.checkContextMenu(data.privateUserMemberFav.name, data.privateUserMemberFav.contextMenu); + }); + + it('Moderated library, user is a member, favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.moderatedUserMemberFav.name, data.moderatedUserMemberFav.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.moderatedUserMemberFav.name, data.moderatedUserMemberFav.toolbarMore); + await testUtil.checkContextMenu(data.moderatedUserMemberFav.name, data.moderatedUserMemberFav.contextMenu); + }); + + it('Public library, user is a member, not favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.publicUserMemberNotFav.name, data.publicUserMemberNotFav.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.publicUserMemberNotFav.name, data.publicUserMemberNotFav.toolbarMore); + await testUtil.checkContextMenu(data.publicUserMemberNotFav.name, data.publicUserMemberNotFav.contextMenu); + }); + + it('Private library, user is a member, not favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.privateUserMemberNotFav.name, data.privateUserMemberNotFav.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.privateUserMemberNotFav.name, data.privateUserMemberNotFav.toolbarMore); + await testUtil.checkContextMenu(data.privateUserMemberNotFav.name, data.privateUserMemberNotFav.contextMenu); + }); + + it('Moderated library, user is a member, not favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.moderatedUserMemberNotFav.name, data.moderatedUserMemberNotFav.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.moderatedUserMemberNotFav.name, data.moderatedUserMemberNotFav.toolbarMore); + await testUtil.checkContextMenu(data.moderatedUserMemberNotFav.name, data.moderatedUserMemberNotFav.contextMenu); + }); + + }); + + describe('on Favorite Libraries', () => { + + beforeEach(async (done) => { + await Utils.pressEscape(); + await page.goToFavoriteLibrariesAndWait(); + done(); + }); + + afterEach(async (done) => { + await Utils.pressEscape(); + done(); + }); + + it('Public library, user is a member, favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.publicUserMemberFav.name, data.publicUserMemberFav.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.publicUserMemberFav.name, data.publicUserMemberFav.toolbarMore); + await testUtil.checkContextMenu(data.publicUserMemberFav.name, data.publicUserMemberFav.contextMenu); + }); + + it('Private library, user is a member, favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.privateUserMemberFav.name, data.privateUserMemberFav.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.privateUserMemberFav.name, data.privateUserMemberFav.toolbarMore); + await testUtil.checkContextMenu(data.privateUserMemberFav.name, data.privateUserMemberFav.contextMenu); + }); + + it('Moderated library, user is a member, favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.moderatedUserMemberFav.name, data.moderatedUserMemberFav.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.moderatedUserMemberFav.name, data.moderatedUserMemberFav.toolbarMore); + await testUtil.checkContextMenu(data.moderatedUserMemberFav.name, data.moderatedUserMemberFav.contextMenu); + }); + + it('Public library, user not a member, favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.publicNotMemberFav.name, data.publicNotMemberFav.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.publicNotMemberFav.name, data.publicNotMemberFav.toolbarMore); + await testUtil.checkContextMenu(data.publicNotMemberFav.name, data.publicNotMemberFav.contextMenu); + }); + + it('Moderated library, user not a member, favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.moderatedNotMemberFav.name, data.moderatedNotMemberFav.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.moderatedNotMemberFav.name, data.moderatedNotMemberFav.toolbarMore); + await testUtil.checkContextMenu(data.moderatedNotMemberFav.name, data.moderatedNotMemberFav.contextMenu); + }); + + it('Moderated library, user requested to join, favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.moderatedRequestedJoinFav.name, data.moderatedRequestedJoinFav.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.moderatedRequestedJoinFav.name, data.moderatedRequestedJoinFav.toolbarMore); + await testUtil.checkContextMenu(data.moderatedRequestedJoinFav.name, data.moderatedRequestedJoinFav.contextMenu); + }); + }); + + describe('on Search Results', () => { + + beforeEach(async (done) => { + await Utils.pressEscape(); + await page.clickPersonalFiles(); + await searchInput.clickSearchButton(); + await searchInput.checkLibraries(); + await searchInput.searchFor('site-'); + done(); + }); + + afterEach(async (done) => { + await Utils.pressEscape(); + done(); + }); + + it('Public library, user is a member, favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.publicUserMemberFav.name, data.publicUserMemberFav.searchToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.publicUserMemberFav.name, data.publicUserMemberFav.toolbarMore); + await testUtil.checkContextMenu(data.publicUserMemberFav.name, data.publicUserMemberFav.contextMenu); + }); + + it('Private library, user is a member, favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.privateUserMemberFav.name, data.privateUserMemberFav.searchToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.privateUserMemberFav.name, data.privateUserMemberFav.toolbarMore); + await testUtil.checkContextMenu(data.privateUserMemberFav.name, data.privateUserMemberFav.contextMenu); + }); + + it('Moderated library, user is a member, favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.moderatedUserMemberFav.name, data.moderatedUserMemberFav.searchToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.moderatedUserMemberFav.name, data.moderatedUserMemberFav.toolbarMore); + await testUtil.checkContextMenu(data.moderatedUserMemberFav.name, data.moderatedUserMemberFav.contextMenu); + }); + + it('Public library, user is a member, not favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.publicUserMemberNotFav.name, data.publicUserMemberNotFav.searchToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.publicUserMemberNotFav.name, data.publicUserMemberNotFav.toolbarMore); + await testUtil.checkContextMenu(data.publicUserMemberNotFav.name, data.publicUserMemberNotFav.contextMenu); + }); + + it('Private library, user is a member, not favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.privateUserMemberNotFav.name, data.privateUserMemberNotFav.searchToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.privateUserMemberNotFav.name, data.privateUserMemberNotFav.toolbarMore); + await testUtil.checkContextMenu(data.privateUserMemberNotFav.name, data.privateUserMemberNotFav.contextMenu); + }); + + it('Moderated library, user is a member, not favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.moderatedUserMemberNotFav.name, data.moderatedUserMemberNotFav.searchToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.moderatedUserMemberNotFav.name, data.moderatedUserMemberNotFav.toolbarMore); + await testUtil.checkContextMenu(data.moderatedUserMemberNotFav.name, data.moderatedUserMemberNotFav.contextMenu); + }); + + it('Public library, user not a member, favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.publicNotMemberFav.name, data.publicNotMemberFav.searchToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.publicNotMemberFav.name, data.publicNotMemberFav.toolbarMore); + await testUtil.checkContextMenu(data.publicNotMemberFav.name, data.publicNotMemberFav.contextMenu); + }); + + it('Moderated library, user not a member, favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.moderatedNotMemberFav.name, data.moderatedNotMemberFav.searchToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.moderatedNotMemberFav.name, data.moderatedNotMemberFav.toolbarMore); + await testUtil.checkContextMenu(data.moderatedNotMemberFav.name, data.moderatedNotMemberFav.contextMenu); + }); + + it('Public library, user not a member, not favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.publicNotMemberNotFav.name, data.publicNotMemberNotFav.searchToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.publicNotMemberNotFav.name, data.publicNotMemberNotFav.toolbarMore); + await testUtil.checkContextMenu(data.publicNotMemberNotFav.name, data.publicNotMemberNotFav.contextMenu); + }); + + it('Moderated library, user not a member, not favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.moderatedNotMemberNotFav.name, data.moderatedNotMemberNotFav.searchToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.moderatedNotMemberNotFav.name, data.moderatedNotMemberNotFav.toolbarMore); + await testUtil.checkContextMenu(data.moderatedNotMemberNotFav.name, data.moderatedNotMemberNotFav.contextMenu); + }); + + it('Moderated library, user requested to join, favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.moderatedRequestedJoinFav.name, data.moderatedRequestedJoinFav.searchToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.moderatedRequestedJoinFav.name, data.moderatedRequestedJoinFav.toolbarMore); + await testUtil.checkContextMenu(data.moderatedRequestedJoinFav.name, data.moderatedRequestedJoinFav.contextMenu); + }); + + it('Moderated library, user requested to join, not favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.moderatedRequestedJoinNotFav.name, data.moderatedRequestedJoinNotFav.searchToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.moderatedRequestedJoinNotFav.name, data.moderatedRequestedJoinNotFav.toolbarMore); + await testUtil.checkContextMenu(data.moderatedRequestedJoinNotFav.name, data.moderatedRequestedJoinNotFav.contextMenu); + }); + }); + + describe('on Trash', () => { + beforeEach(async (done) => { + await page.clickTrashAndWait(); + done(); + }); + + afterEach(async (done) => { + await Utils.pressEscape(); + done(); + }); + + it('single library - []', async () => { + await testUtil.checkToolbarPrimary(data.siteInTrash.name, data.siteInTrash.trashActions); + await testUtil.checkContextMenu(data.siteInTrash.name, data.siteInTrash.trashActions); + }); + + it('multiple libraries - []', async () => { + await testUtil.checkMultipleSelContextMenu([ data.siteInTrash.name, data.site2InTrash.name ], data.trashActions); + await testUtil.checkMultipleSelToolbarPrimary([ data.siteInTrash.name, data.site2InTrash.name ], data.trashActions); + }); + }); +}); diff --git a/e2e/suites/actions-available/libraries/test-data-libraries.ts b/e2e/suites/actions-available/libraries/test-data-libraries.ts new file mode 100644 index 0000000000..9e1d6e1ae4 --- /dev/null +++ b/e2e/suites/actions-available/libraries/test-data-libraries.ts @@ -0,0 +1,156 @@ +import { Utils } from '../../../utilities/utils'; + + +// ---- multiple selection --- + +export const trashActions = ['Permanently Delete', 'Restore']; + + +// ---- single selection ---- + +const memberFavContextMenu = ['Leave Library', 'Delete', 'Remove Favorite']; +const memberNotFavContextMenu = ['Leave Library', 'Delete', 'Favorite']; +const memberToolbarPrimary = ['Leave Library', 'View Details', 'More Actions']; +const favToolbarMore = ['Delete', 'Remove Favorite']; +const notFavToolbarMore = ['Delete', 'Favorite']; +const searchMemberToolbarPrimary = ['Toggle search filter', 'Leave Library', 'View Details', 'More Actions']; +const searchReqJoinToolbarPrimary = ['Toggle search filter', 'Cancel Join Request', 'View Details', 'More Actions']; +const searchNotMemberToolbarPrimary = ['Toggle search filter', 'Join', 'View Details', 'More Actions']; +const reqJoinToolbarMore = ['Cancel Join Request', 'View Details', 'More Actions']; +const notMemberFavContextMenu = ['Join', 'Delete', 'Remove Favorite']; +const notMemberNotFavContextMenu = ['Join', 'Delete', 'Favorite']; +const notMemberToolbarPrimary = ['Join', 'View Details', 'More Actions']; +const reqJoinNotFavContextMenu = ['Cancel Join Request', 'Delete', 'Favorite']; +const reqJoinFavContextMenu = ['Cancel Join Request', 'Delete', 'Remove Favorite']; + + +export const publicUserMemberFav = { + name: `site-public-member-fav-${Utils.random()}`, + description: 'public site, user member, user favorite', + contextMenu: memberFavContextMenu, + toolbarPrimary: memberToolbarPrimary, + toolbarMore: favToolbarMore, + + searchToolbarPrimary: searchMemberToolbarPrimary +}; + +export const privateUserMemberFav = { + name: `site-private-member-fav-${Utils.random()}`, + description: 'private site, user member, user favorite', + contextMenu: memberFavContextMenu, + toolbarPrimary: memberToolbarPrimary, + toolbarMore: favToolbarMore, + + searchToolbarPrimary: searchMemberToolbarPrimary +}; + +export const moderatedUserMemberFav = { + name: `site-moderated-member-fav-${Utils.random()}`, + description: 'moderated site, user member, user favorite', + contextMenu: memberFavContextMenu, + toolbarPrimary: memberToolbarPrimary, + toolbarMore: favToolbarMore, + + searchToolbarPrimary: searchMemberToolbarPrimary +}; + +export const publicUserMemberNotFav = { + name: `site-public-member-not-fav-${Utils.random()}`, + description: 'public site, user member, not favorite', + contextMenu: memberNotFavContextMenu, + toolbarPrimary: memberToolbarPrimary, + toolbarMore: notFavToolbarMore, + + searchToolbarPrimary: searchMemberToolbarPrimary +}; + +export const privateUserMemberNotFav = { + name: `site-private-member-not-fav-${Utils.random()}`, + description: 'private site, user member, not favorite', + contextMenu: memberNotFavContextMenu, + toolbarPrimary: memberToolbarPrimary, + toolbarMore: notFavToolbarMore, + + searchToolbarPrimary: searchMemberToolbarPrimary +}; + +export const moderatedUserMemberNotFav = { + name: `site-moderated-member-not-fav-${Utils.random()}`, + description: 'moderated site, user member, not favorite', + contextMenu: memberNotFavContextMenu, + toolbarPrimary: memberToolbarPrimary, + toolbarMore: notFavToolbarMore, + + searchToolbarPrimary: searchMemberToolbarPrimary +}; + +export const publicNotMemberFav = { + name: `site-public-not-member-fav-${Utils.random()}`, + description: 'public site, user not member, user favorite', + contextMenu: notMemberFavContextMenu, + toolbarPrimary: notMemberToolbarPrimary, + toolbarMore: favToolbarMore, + + searchToolbarPrimary: searchNotMemberToolbarPrimary +}; + +export const moderatedNotMemberFav = { + name: `site-moderated-not-member-fav-${Utils.random()}`, + description: 'moderated site, user not member, user favorite', + contextMenu: notMemberFavContextMenu, + toolbarPrimary: notMemberToolbarPrimary, + toolbarMore: favToolbarMore, + + searchToolbarPrimary: searchNotMemberToolbarPrimary +}; + +export const publicNotMemberNotFav = { + name: `site-public-not-member-not-fav-${Utils.random()}`, + description: 'public site, user not member, not favorite', + contextMenu: notMemberNotFavContextMenu, + toolbarPrimary: notMemberToolbarPrimary, + toolbarMore: notFavToolbarMore, + + searchToolbarPrimary: searchNotMemberToolbarPrimary +}; + +export const moderatedNotMemberNotFav = { + name: `site-moderated-not-member-not-fav-${Utils.random()}`, + description: 'moderated site, user not member, not favorite', + contextMenu: notMemberNotFavContextMenu, + toolbarPrimary: notMemberToolbarPrimary, + toolbarMore: notFavToolbarMore, + + searchToolbarPrimary: searchNotMemberToolbarPrimary +}; + +export const moderatedRequestedJoinFav = { + name: `site-moderated-req-join-fav-${Utils.random()}`, + description: 'moderated site, user requested join, user favorite', + contextMenu: reqJoinFavContextMenu, + toolbarPrimary: reqJoinToolbarMore, + toolbarMore: favToolbarMore, + + searchToolbarPrimary: searchReqJoinToolbarPrimary +}; + +export const moderatedRequestedJoinNotFav = { + name: `site-moderated-req-join-not-fav-${Utils.random()}`, + description: 'moderated site, user requested join, not favorite', + contextMenu: reqJoinNotFavContextMenu, + toolbarPrimary: reqJoinToolbarMore, + toolbarMore: notFavToolbarMore, + + searchToolbarPrimary: searchReqJoinToolbarPrimary +}; + +export const siteInTrash = { + name: `deleted-site-${Utils.random()}`, + trashActions +}; + +export const site2InTrash = { + name: `deleted-site2-${Utils.random()}`, + trashActions +}; + diff --git a/e2e/suites/actions-available/special-permissions-available-actions.test.ts b/e2e/suites/actions-available/special-permissions-available-actions.test.ts deleted file mode 100755 index 5320290d45..0000000000 --- a/e2e/suites/actions-available/special-permissions-available-actions.test.ts +++ /dev/null @@ -1,2009 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2019 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { LoginPage, BrowsingPage, SearchResultsPage } from '../../pages/pages'; -import { SITE_VISIBILITY, SITE_ROLES, FILES } from '../../configs'; -import { RepoClient } from '../../utilities/repo-client/repo-client'; -import { Utils } from '../../utilities/utils'; -import { Viewer } from '../../components/viewer/viewer'; - -describe('Special permissions available actions : ', () => { - const userConsumer = `consumer-${Utils.random()}`; - const userManager = `manager-${Utils.random()}`; - const userCollaborator = `collaborator-${Utils.random()}`; - const userDemoted = `demoted-${Utils.random()}`; - - const siteName = `site-private-${Utils.random()}`; - const file1 = `my-file1-${Utils.random()}.txt`; - let file1Id; - const file2 = `my-file2-${Utils.random()}.txt`; - let file2Id; - const file3 = `my-file3-${Utils.random()}.txt`; - let file3Id; - const fileLocked = `my-file-locked-${Utils.random()}.txt`; - let fileLockedId; - - const folder1 = `my-folder1-${Utils.random()}`; - let folder1Id; - const folder2 = `my-folder2-${Utils.random()}`; - let folder2Id; - - const docxFile = FILES.docxFile; - let docxFileId; - - const apis = { - admin: new RepoClient(), - userConsumer: new RepoClient(userConsumer, userConsumer), - userCollaborator: new RepoClient(userCollaborator, userCollaborator), - userDemoted: new RepoClient(userDemoted, userDemoted) - }; - - const loginPage = new LoginPage(); - const page = new BrowsingPage(); - const { dataTable, toolbar } = page; - const contextMenu = dataTable.menu; - const viewer = new Viewer(); - const viewerToolbar = viewer.toolbar; - const searchResultsPage = new SearchResultsPage(); - const { searchInput } = searchResultsPage.header; - - beforeAll(async (done) => { - await apis.admin.people.createUser({ username: userConsumer }); - await apis.admin.people.createUser({ username: userManager }); - await apis.admin.people.createUser({ username: userCollaborator }); - await apis.admin.people.createUser({ username: userDemoted }); - - await apis.admin.sites.createSite(siteName, SITE_VISIBILITY.PRIVATE); - const docLibId = await apis.admin.sites.getDocLibId(siteName); - - file1Id = (await apis.admin.nodes.createFile(file1, docLibId)).entry.id; - file2Id = (await apis.admin.nodes.createFile(file2, docLibId)).entry.id; - file3Id = (await apis.admin.nodes.createFile(file3, docLibId)).entry.id; - folder1Id = (await apis.admin.nodes.createFolder(folder1, docLibId)).entry.id; - folder2Id = (await apis.admin.nodes.createFolder(folder2, docLibId)).entry.id; - - docxFileId = (await apis.admin.upload.uploadFile(docxFile, docLibId)).entry.id; - - await apis.admin.sites.addSiteMember(siteName, userManager, SITE_ROLES.SITE_MANAGER.ROLE); - await apis.admin.sites.addSiteMember(siteName, userConsumer, SITE_ROLES.SITE_CONSUMER.ROLE); - await apis.admin.sites.addSiteMember(siteName, userCollaborator, SITE_ROLES.SITE_COLLABORATOR.ROLE); - await apis.admin.sites.addSiteMember(siteName, userDemoted, SITE_ROLES.SITE_MANAGER.ROLE); - - fileLockedId = (await apis.admin.nodes.createFile(fileLocked, docLibId)).entry.id; - await apis.userDemoted.nodes.lockFile(fileLockedId); - await apis.userDemoted.favorites.addFavoriteById('file', fileLockedId); - await apis.userDemoted.shared.shareFileById(fileLockedId); - await apis.admin.sites.updateSiteMember(siteName, userDemoted, SITE_ROLES.SITE_CONSUMER.ROLE); - - await apis.admin.nodes.setGranularPermission(file3Id, false, userConsumer, SITE_ROLES.SITE_MANAGER.ROLE); - - await apis.userConsumer.shared.shareFileById(file1Id); - await apis.userConsumer.shared.shareFileById(file2Id); - await apis.userConsumer.shared.shareFileById(docxFileId); - await apis.userConsumer.shared.shareFileById(file3Id); - await apis.userConsumer.shared.waitForApi({ expect: 5 }); - - await apis.userConsumer.favorites.addFavoritesByIds('file', [file1Id, file2Id, file3Id, docxFileId]); - await apis.userConsumer.favorites.addFavoritesByIds('folder', [folder1Id, folder2Id]); - await apis.userConsumer.favorites.waitForApi({ expect: 6 }); - - await apis.userCollaborator.favorites.addFavoritesByIds('file', [file1Id, docxFileId]); - await apis.userCollaborator.favorites.waitForApi({ expect: 2 }); - - await apis.admin.favorites.addFavoriteById('file', fileLockedId); - - done(); - }); - - afterAll(async (done) => { - await apis.admin.sites.deleteSite(siteName); - done(); - }); - - describe('Consumer', () => { - beforeAll(async (done) => { - await loginPage.loginWith(userConsumer); - done(); - }); - - describe('toolbar displays correct actions when selecting multiple files with different granular permissions', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await dataTable.clearSelection(); - await page.clickPersonalFiles(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('on File Libraries - [C280476]', async () => { - await page.clickFileLibrariesAndWait(); - await dataTable.doubleClickOnRowByName(siteName); - await dataTable.waitForHeader(); - await dataTable.selectMultipleItems([file1, file2]); - - expect(await toolbar.isViewPresent()).toBe(false, `View is displayed for selected files`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for selected files`); - expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for selected files`); - expect(await toolbar.isSharePresent()).toBe(false, `Share is displayed`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for selected files`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for selected files`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); - expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for selected files`); - expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for selected files`); - expect(await toolbar.menu.isRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for selected files`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed for selected files`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed for selected files`); - - await toolbar.closeMoreMenu(); - }); - - it('on Shared Files - [C280477]', async () => { - await page.clickSharedFilesAndWait(); - await dataTable.selectMultipleItems([file1, file2]); - - expect(await toolbar.isViewPresent()).toBe(false, `View is displayed for selected files`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for selected files`); - expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for selected files`); - expect(await toolbar.isSharePresent()).toBe(false, `Share is displayed`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for selected files`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for selected files`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); - expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for selected files`); - expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for selected files`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for selected files`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed for selected files`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed for selected files`); - - await toolbar.closeMoreMenu(); - }); - - it('on Favorites - [C280478]', async () => { - await page.clickFavoritesAndWait(); - await dataTable.selectMultipleItems([file1, file2]); - - expect(await toolbar.isViewPresent()).toBe(false, `View is displayed for selected files`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for selected files`); - expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for selected files`); - expect(await toolbar.isSharePresent()).toBe(false, `Share is displayed`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for selected files`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); - // TODO: change expect to false when ACA-1737 is done - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is displayed for selected files`); - // TODO: change expect to false when ACA-1737 is done - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is displayed for selected files`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for selected files`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed for selected files`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed for selected files`); - - await toolbar.closeMoreMenu(); - }); - - it('on Search Results - [C291823]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkOnlyFiles(); - await searchInput.searchFor('my-file'); - await dataTable.selectMultipleItems([file1, file2]); - - expect(await toolbar.isViewPresent()).toBe(false, `View is displayed for selected files`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for selected files`); - expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for selected files`); - expect(await toolbar.isSharePresent()).toBe(false, `Share is displayed`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for selected files`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for selected files`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); - expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for selected files`); - expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for selected files`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for selected files`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed for selected files`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed for selected files`); - - await toolbar.closeMoreMenu(); - }); - }); - - describe('toolbar actions appear correctly for a file', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await dataTable.clearSelection(); - await page.clickPersonalFiles(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('on File Libraries - [C280455]', async () => { - await page.clickFileLibrariesAndWait(); - await dataTable.doubleClickOnRowByName(siteName); - await dataTable.waitForHeader(); - await dataTable.selectItem(file1); - - expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${file1}`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${file1}`); - expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${file1}`); - expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${file1}`); - expect(await toolbar.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${file1}`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${file1}`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${file1}`); - expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${file1}`); - expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${file1}`); - expect(await toolbar.menu.isRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${file1}`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed for ${file1}`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed for ${file1}`); - - await toolbar.closeMoreMenu(); - }); - - it('on Shared Files - [C280456]', async () => { - await page.clickSharedFilesAndWait(); - await page.dataTable.selectItem(file1); - - expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${file1}`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${file1}`); - expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${file1}`); - expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${file1}`); - expect(await toolbar.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${file1}`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${file1}`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${file1}`); - expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${file1}`); - expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${file1}`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${file1}`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed for ${file1}`); - // TODO: change expect to false when ACA-2173 is done - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is displayed for ${file1}`); - - await toolbar.closeMoreMenu(); - }); - - it('on Favorites - [C213121]', async () => { - await page.clickFavoritesAndWait(); - await dataTable.selectItem(file1); - - expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${file1}`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${file1}`); - expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${file1}`); - expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${file1}`); - // TODO: replace with isSharedLinkSettingsPresent when ACA-2175 is done - expect(await toolbar.isSharePresent()).toBe(true, `Share is not displayed`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${file1}`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${file1}`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${file1}`); - // TODO: change expect to false when ACA-1737 is done - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is displayed for ${file1}`); - // TODO: change expect to false when ACA-1737 is done - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is displayed for ${file1}`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${file1}`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed for ${file1}`); - // TODO: change expect to false when ACA-1737 is done - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is displayed for ${file1}`); - - await toolbar.closeMoreMenu(); - }); - - it('on Search Results - [C291818]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkOnlyFiles(); - await searchInput.searchFor(file1); - await dataTable.selectItem(file1); - - expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${file1}`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${file1}`); - expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${file1}`); - expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${file1}`); - expect(await toolbar.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${file1}`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${file1}`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${file1}`); - expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${file1}`); - expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${file1}`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${file1}`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed for ${file1}`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed for ${file1}`); - - await toolbar.closeMoreMenu(); - }); - }); - - describe('toolbar actions appear correctly for a folder', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await dataTable.clearSelection(); - await page.clickPersonalFiles(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('on File Libraries - [C280444]', async () => { - await page.clickFileLibrariesAndWait(); - await dataTable.doubleClickOnRowByName(siteName); - await dataTable.waitForHeader(); - await dataTable.selectItem(folder1); - - expect(await toolbar.isViewPresent()).toBe(false, `View is displayed for ${folder1}`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${folder1}`); - expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${folder1}`); - expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${folder1}`); - expect(await toolbar.isSharePresent()).toBe(false, `Share is displayed`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${folder1}`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${folder1}`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${folder1}`); - expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${folder1}`); - expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${folder1}`); - expect(await toolbar.menu.isRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${folder1}`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed for ${folder1}`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed for ${folder1}`); - - await toolbar.closeMoreMenu(); - }); - - it('on Favorites - [C286266]', async () => { - await page.clickFavoritesAndWait(); - await dataTable.selectItem(folder1); - - expect(await toolbar.isViewPresent()).toBe(false, `View is not displayed for ${folder1}`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${folder1}`); - expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${folder1}`); - expect(await toolbar.isSharePresent()).toBe(false, `Share is displayed`); - - await toolbar.openMoreMenu(); - - // TODO: change expect to false when ACA-1737 is done - expect(await toolbar.menu.isEditFolderPresent()).toBe(true, `Edit folder is displayed for ${folder1}`); - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${folder1}`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${folder1}`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${folder1}`); - // TODO: change expect to false when ACA-1737 is done - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is displayed for ${folder1}`); - // TODO: change expect to false when ACA-1737 is done - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is displayed for ${folder1}`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${folder1}`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed for ${folder1}`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed for ${folder1}`); - - await toolbar.closeMoreMenu(); - }); - - it('on Search Results - [C291819]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkOnlyFolders(); - await searchInput.searchFor(folder1); - await dataTable.selectItem(folder1); - - expect(await toolbar.isViewPresent()).toBe(false, `View is displayed for ${folder1}`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${folder1}`); - expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${folder1}`); - expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${folder1}`); - expect(await toolbar.isSharePresent()).toBe(false, `Share is displayed`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${folder1}`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${folder1}`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${folder1}`); - expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${folder1}`); - expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${folder1}`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${folder1}`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed for ${folder1}`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed for ${folder1}`); - - await toolbar.closeMoreMenu(); - }); - }); - - describe('toolbar actions appear correctly for multiple selection of files', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await dataTable.clearSelection(); - await page.clickPersonalFiles(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('on File Libraries - [C280464]', async () => { - await page.clickFileLibrariesAndWait(); - await dataTable.doubleClickOnRowByName(siteName); - await dataTable.waitForHeader(); - await dataTable.selectMultipleItems([file1, file2]); - - expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); - expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); - expect(await toolbar.isSharePresent()).toBe(false, `Share is displayed`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await toolbar.menu.isRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - - await toolbar.closeMoreMenu(); - }); - - it('on Shared Files - [C286284]', async () => { - await page.clickSharedFilesAndWait(); - await dataTable.selectMultipleItems([file1, file2]); - - expect(await toolbar.isViewPresent()).toBe(false, `View is displayed for selected files`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for selected files`); - expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for selected files`); - expect(await toolbar.isSharePresent()).toBe(false, `Share is displayed`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); - expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for selected files`); - expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for selected files`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for selected files`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - - await toolbar.closeMoreMenu(); - }); - - it('on Favorites - [C286285]', async () => { - await page.clickFavoritesAndWait(); - await dataTable.selectMultipleItems([file1, file2]); - - expect(await toolbar.isViewPresent()).toBe(false, `View is displayed for selected files`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for selected files`); - expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for selected files`); - expect(await toolbar.isSharePresent()).toBe(false, `Share is displayed`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); - // TODO: change expect to false when ACA-1737 is done - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is displayed for selected files`); - // TODO: change expect to false when ACA-1737 is done - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is displayed for selected files`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for selected files`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - - await toolbar.closeMoreMenu(); - }); - - it('on Search Results - [C291824]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkOnlyFiles(); - await searchInput.searchFor('my-file'); - await dataTable.selectMultipleItems([file1, file2]); - - expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); - expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); - expect(await toolbar.isSharePresent()).toBe(false, `Share is displayed`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - - await toolbar.closeMoreMenu(); - }); - }); - - describe('toolbar actions appear correctly for multiple selection of folders', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await dataTable.clearSelection(); - await page.clickPersonalFiles(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('on File Libraries - [C280465]', async () => { - await page.clickFileLibrariesAndWait(); - await dataTable.doubleClickOnRowByName(siteName); - await dataTable.waitForHeader(); - await dataTable.selectMultipleItems([folder1, folder2]); - - expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); - expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); - expect(await toolbar.isSharePresent()).toBe(false, `Share is displayed`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await toolbar.menu.isRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - - await toolbar.closeMoreMenu(); - }); - - it('on Favorites - [C286286]', async () => { - await page.clickFavoritesAndWait(); - await dataTable.selectMultipleItems([folder1, folder2]); - - expect(await toolbar.isViewPresent()).toBe(false, `View is displayed`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); - expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed`); - expect(await toolbar.isSharePresent()).toBe(false, `Share is displayed`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - // TODO: change expect to false when ACA-1737 is done - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is displayed`); - // TODO: change expect to false when ACA-1737 is done - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is displayed`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - - await toolbar.closeMoreMenu(); - }); - - it('on Search Results - [C291825]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkOnlyFolders(); - await searchInput.searchFor('my-folder'); - await dataTable.selectMultipleItems([folder1, folder2]); - - expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); - expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); - expect(await toolbar.isSharePresent()).toBe(false, `Share is displayed`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - - await toolbar.closeMoreMenu(); - }); - }); - - describe('toolbar actions appear correctly for when both files and folders are selected', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await dataTable.clearSelection(); - await page.clickPersonalFiles(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('on File Libraries - [C280466]', async () => { - await page.clickFileLibrariesAndWait(); - await dataTable.doubleClickOnRowByName(siteName); - await dataTable.waitForHeader(); - await dataTable.selectMultipleItems([file1, folder1]); - - expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); - expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); - expect(await toolbar.isSharePresent()).toBe(false, `Share is displayed`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await toolbar.menu.isRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - - await toolbar.closeMoreMenu(); - }); - - it('on Favorites - [C286287]', async () => { - await page.clickFavoritesAndWait(); - await dataTable.selectMultipleItems([file1, folder1]); - - expect(await toolbar.isViewPresent()).toBe(false, `View is displayed`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); - expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed`); - expect(await toolbar.isSharePresent()).toBe(false, `Share is displayed`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - // TODO: change expect to false when ACA-1737 is done - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is displayed`); - // TODO: change expect to false when ACA-1737 is done - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is displayed`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - - await toolbar.closeMoreMenu(); - }); - - it('on Search Results - [C291826]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkFilesAndFolders(); - await searchInput.searchFor('my-f'); - await dataTable.selectMultipleItems([file1, folder1]); - - expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); - expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); - expect(await toolbar.isSharePresent()).toBe(false, `Share is displayed`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - - await toolbar.closeMoreMenu(); - }); - }); - - describe('context menu actions are correct for a file', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await dataTable.clearSelection(); - await page.clickPersonalFiles(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('on File Libraries - [C280599]', async () => { - await page.clickFileLibrariesAndWait(); - await dataTable.doubleClickOnRowByName(siteName); - await dataTable.waitForHeader(); - await dataTable.rightClickOnItem(file1); - - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${file1}`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${file1}`); - expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${file1}`); - expect(await contextMenu.isViewPresent()).toBe(true, `View is not displayed for ${file1}`); - expect(await contextMenu.isRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${file1}`); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${file1}`); - expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed for ${file1}`); - expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed for ${file1}`); - expect(await contextMenu.isManageVersionsPresent()).toBe(true, `Manage Versions is not displayed for ${file1}`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed for ${file1}`); - expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${file1}`); - expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${file1}`); - expect(await contextMenu.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed`); - }); - - it('on Shared Files - [C286264]', async () => { - await page.clickSharedFilesAndWait(); - await dataTable.rightClickOnItem(file1); - - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${file1}`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${file1}`); - expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${file1}`); - expect(await contextMenu.isViewPresent()).toBe(true, `View is not displayed for ${file1}`); - expect(await contextMenu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${file1}`); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${file1}`); - expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed for ${file1}`); - expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed for ${file1}`); - expect(await contextMenu.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed for ${file1}`); - expect(await contextMenu.isManageVersionsPresent()).toBe(true, `Manage Versions is not displayed for ${file1}`); - // TODO: change expect to false when ACA-2173 is done - expect(await contextMenu.isUploadNewVersionPresent()).toBe(true, `Upload new version is displayed for ${file1}`); - expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${file1}`); - expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${file1}`); - }); - - it('on Favorites - [C286262]', async () => { - await page.clickFavoritesAndWait(); - await dataTable.rightClickOnItem(file1); - - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${file1}`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${file1}`); - expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${file1}`); - expect(await contextMenu.isViewPresent()).toBe(true, `View is not displayed for ${file1}`); - expect(await contextMenu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${file1}`); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${file1}`); - // TODO: change expect to false when ACA-1737 is done - expect(await contextMenu.isMovePresent()).toBe(true, `Move is displayed for ${file1}`); - // TODO: change expect to false when ACA-1737 is done - expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is displayed for ${file1}`); - // TODO: replace with isSharedLinkSettingsPresent when ACA-2175 is done - expect(await toolbar.isSharePresent()).toBe(true, `Share is not displayed`); - expect(await contextMenu.isManageVersionsPresent()).toBe(true, `Manage Versions is not displayed for ${file1}`); - // TODO: change expect to false when ACA-1737 is done - expect(await contextMenu.isUploadNewVersionPresent()).toBe(true, `Upload new version is displayed for ${file1}`); - expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${file1}`); - expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${file1}`); - }); - - it('on Search Results - [C291829]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkOnlyFiles(); - await searchInput.searchFor(file1); - await dataTable.rightClickOnItem(file1); - - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${file1}`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${file1}`); - expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${file1}`); - expect(await contextMenu.isViewPresent()).toBe(true, `View is not displayed for ${file1}`); - expect(await contextMenu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${file1}`); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${file1}`); - expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed for ${file1}`); - expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed for ${file1}`); - expect(await contextMenu.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed`); - expect(await contextMenu.isManageVersionsPresent()).toBe(true, `Manage Versions is not displayed for ${file1}`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed for ${file1}`); - expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${file1}`); - expect(await contextMenu.isViewDetailsPresent()).toBe(false, `View details is displayed for ${file1}`); - }); - }); - - describe('context menu actions are correct for a folder', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await dataTable.clearSelection(); - await page.clickPersonalFiles(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('on File Libraries - [C280600]', async () => { - await page.clickFileLibrariesAndWait(); - await dataTable.doubleClickOnRowByName(siteName); - await dataTable.waitForHeader(); - await dataTable.rightClickOnItem(folder1); - - expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${folder1}`); - expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${folder1}`); - expect(await contextMenu.isRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${folder1}`); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${folder1}`); - expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed for ${folder1}`); - expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed for ${folder1}`); - expect(await contextMenu.isViewPresent()).toBe(false, `View is displayed for ${folder1}`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions is displayed for ${folder1}`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed for ${folder1}`); - expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed for ${folder1}`); - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${folder1}`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${folder1}`); - }); - - it('on Favorites - [C286263]', async () => { - await page.clickFavoritesAndWait(); - await dataTable.rightClickOnItem(folder1); - - expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${folder1}`); - // TODO: change expect to false when ACA-1737 is done - expect(await contextMenu.isEditFolderPresent()).toBe(true, `Edit folder is displayed for ${folder1}`); - expect(await contextMenu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${folder1}`); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${folder1}`); - // TODO: change expect to false when ACA-1737 is done - expect(await contextMenu.isMovePresent()).toBe(true, `Move is displayed for ${folder1}`); - // TODO: change expect to false when ACA-1737 is done - expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is displayed for ${folder1}`); - expect(await contextMenu.isViewPresent()).toBe(false, `View is displayed for ${folder1}`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions is displayed for ${folder1}`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed for ${folder1}`); - expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed for ${folder1}`); - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${folder1}`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${folder1}`); - }); - - it('on Search Results - [C291830]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkOnlyFolders(); - await searchInput.searchFor(folder1); - await dataTable.rightClickOnItem(folder1); - - expect(await contextMenu.isDownloadPresent()).toBe(true, `Download is not displayed for ${folder1}`); - expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${folder1}`); - expect(await contextMenu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${folder1}`); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed for ${folder1}`); - expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed for ${folder1}`); - expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed for ${folder1}`); - expect(await contextMenu.isViewPresent()).toBe(false, `View is displayed for ${folder1}`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions is displayed for ${folder1}`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed for ${folder1}`); - expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed for ${folder1}`); - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${folder1}`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${folder1}`); - }); - }); - - describe('context menu actions are correct for multiple selection of files', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await dataTable.clearSelection(); - await page.clickPersonalFiles(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('on File Libraries - [C280647]', async () => { - await page.clickFileLibrariesAndWait(); - await dataTable.doubleClickOnRowByName(siteName); - await dataTable.waitForHeader(); - await dataTable.selectMultipleItems([file1, file2]); - await dataTable.rightClickOnMultipleSelection(); - - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await contextMenu.isRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions is displayed`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed`); - }); - - it('on Shared Files - [C286283]', async () => { - await page.clickSharedFilesAndWait(); - await dataTable.selectMultipleItems([file1, file2]); - await dataTable.rightClickOnMultipleSelection(); - - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await contextMenu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions is displayed`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed`); - }); - - it('on Favorites - [C286280]', async () => { - await page.clickFavoritesAndWait(); - await dataTable.selectMultipleItems([file1, file2]); - await dataTable.rightClickOnMultipleSelection(); - - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); - // TODO: change expect to false when ACA-1737 is done - expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is displayed`); - // TODO: change expect to false when ACA-1737 is done - expect(await contextMenu.isMovePresent()).toBe(true, `Move is displayed`); - expect(await contextMenu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions is displayed`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed`); - }); - - it('on Search Results - [C291834]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkOnlyFiles(); - await searchInput.searchFor('my-file'); - await dataTable.selectMultipleItems([file1, file2]); - await dataTable.rightClickOnMultipleSelection(); - - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await contextMenu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions is displayed`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed`); - }); - }); - - describe('context menu actions are correct for multiple selection of folders', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await dataTable.clearSelection(); - await page.clickPersonalFiles(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('on File Libraries - [C280666]', async () => { - await page.clickFileLibrariesAndWait(); - await dataTable.doubleClickOnRowByName(siteName); - await dataTable.waitForHeader(); - await dataTable.selectMultipleItems([folder1, folder2]); - await dataTable.rightClickOnMultipleSelection(); - - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed`); - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await contextMenu.isRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions is displayed`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed`); - }); - - it('on Favorites - [C286281]', async () => { - await page.clickFavoritesAndWait(); - await dataTable.selectMultipleItems([folder1, folder2]); - await dataTable.rightClickOnMultipleSelection(); - - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed`); - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); - // TODO: change expect to false when ACA-1737 is done - expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is displayed`); - // TODO: change expect to false when ACA-1737 is done - expect(await contextMenu.isMovePresent()).toBe(true, `Move is displayed`); - expect(await contextMenu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions is displayed`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed`); - }); - - it('on Search Results - [C291835]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkOnlyFolders(); - await searchInput.searchFor('my-folder'); - await dataTable.selectMultipleItems([folder1, folder2]); - await dataTable.rightClickOnMultipleSelection(); - - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await contextMenu.isEditFolderPresent()).toBe(false, `Edit folder is displayed`); - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await contextMenu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions is displayed`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed`); - }); - }); - - describe('context menu actions are correct when both files and folders are selected', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await dataTable.clearSelection(); - await page.clickPersonalFiles(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('on File Libraries - [C280669]', async () => { - await page.clickFileLibrariesAndWait(); - await dataTable.doubleClickOnRowByName(siteName); - await dataTable.waitForHeader(); - await dataTable.selectMultipleItems([file1, folder1]); - await dataTable.rightClickOnMultipleSelection(); - - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await contextMenu.isRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions is displayed`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed`); - }); - - it('on Favorites - [C286282]', async () => { - await page.clickFavoritesAndWait(); - await dataTable.selectMultipleItems([file1, folder1]); - await dataTable.rightClickOnMultipleSelection(); - - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); - // TODO: change expect to false when ACA-1737 is done - expect(await contextMenu.isDeletePresent()).toBe(true, `Delete is displayed`); - // TODO: change expect to false when ACA-1737 is done - expect(await contextMenu.isMovePresent()).toBe(true, `Move is displayed`); - expect(await contextMenu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions is displayed`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed`); - }); - - it('on Search Results - [C291836]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkFilesAndFolders(); - await searchInput.searchFor('my-f'); - await dataTable.selectMultipleItems([file1, folder1]); - await dataTable.rightClickOnMultipleSelection(); - - expect(await contextMenu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await contextMenu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await contextMenu.isViewPresent()).toBe(false, 'View is displayed'); - expect(await contextMenu.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await contextMenu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await contextMenu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await contextMenu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await contextMenu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); - expect(await contextMenu.isManageVersionsPresent()).toBe(false, `Manage Versions is displayed`); - expect(await contextMenu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - expect(await contextMenu.isSharePresent()).toBe(false, `Share is displayed`); - }); - }); - - describe('toolbar actions appear correctly in the viewer', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await page.clickPersonalFiles(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('file from File Libraries - [C268128]', async () => { - await page.clickFileLibrariesAndWait(); - await dataTable.doubleClickOnRowByName(siteName); - await dataTable.waitForHeader(); - await dataTable.doubleClickOnRowByName(docxFile); - await viewer.waitForViewerToOpen(); - - expect(await viewerToolbar.isViewPresent()).toBe(false, `View is displayed`); - expect(await viewerToolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); - expect(await viewerToolbar.isPrintPresent()).toBe(true, `Print is not displayed`); - expect(await viewerToolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); - expect(await viewerToolbar.isSharedLinkSettingsPresent()).toBe(true, 'Shared link settings is not displayed'); - expect(await viewerToolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed`); - - await viewerToolbar.openMoreMenu(); - - expect(await viewerToolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await viewerToolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await viewerToolbar.menu.isRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); - expect(await viewerToolbar.menu.isSharePresent()).toBe(false, `Share is displayed in More actions`); - expect(await viewerToolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await viewerToolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await viewerToolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await viewerToolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); - expect(await viewerToolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - - await toolbar.closeMoreMenu(); - }); - - it('file from Shared Files - [C286310]', async () => { - await page.clickSharedFilesAndWait(); - await dataTable.doubleClickOnRowByName(docxFile); - await viewer.waitForViewerToOpen(); - - expect(await viewerToolbar.isViewPresent()).toBe(false, `View is displayed`); - expect(await viewerToolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); - expect(await viewerToolbar.isPrintPresent()).toBe(true, `Print is not displayed`); - expect(await viewerToolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); - expect(await viewerToolbar.isSharedLinkSettingsPresent()).toBe(true, 'Shared link settings is not displayed'); - expect(await viewerToolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed`); - - await viewerToolbar.openMoreMenu(); - - expect(await viewerToolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await viewerToolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await viewerToolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); - expect(await viewerToolbar.menu.isSharePresent()).toBe(false, `Share is displayed in More actions`); - expect(await viewerToolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await viewerToolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await viewerToolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await viewerToolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); - expect(await viewerToolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - - await toolbar.closeMoreMenu(); - }); - - it('file from Favorites - [C286311]', async () => { - await page.clickFavoritesAndWait(); - await dataTable.doubleClickOnRowByName(docxFile); - await viewer.waitForViewerToOpen(); - - expect(await viewerToolbar.isViewPresent()).toBe(false, `View is displayed`); - expect(await viewerToolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); - expect(await viewerToolbar.isPrintPresent()).toBe(true, `Print is not displayed`); - expect(await viewerToolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); - expect(await viewerToolbar.isSharedLinkSettingsPresent()).toBe(true, 'Shared link settings is not displayed'); - expect(await viewerToolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed`); - - await viewerToolbar.openMoreMenu(); - - expect(await viewerToolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await viewerToolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await viewerToolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); - expect(await viewerToolbar.menu.isSharePresent()).toBe(false, `Share is displayed in More actions`); - expect(await viewerToolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await viewerToolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await viewerToolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await viewerToolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); - expect(await viewerToolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - - await toolbar.closeMoreMenu(); - }); - - it('file from Search Results - [C306991]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkOnlyFiles(); - await searchInput.searchFor(docxFile); - await dataTable.waitForBody(); - await dataTable.doubleClickOnRowByName(docxFile); - await viewer.waitForViewerToOpen(); - - expect(await viewerToolbar.isViewPresent()).toBe(false, `View is displayed`); - expect(await viewerToolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); - expect(await viewerToolbar.isPrintPresent()).toBe(true, `Print is not displayed`); - expect(await viewerToolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); - expect(await viewerToolbar.isSharedLinkSettingsPresent()).toBe(true, 'Shared link settings is not displayed'); - expect(await viewerToolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed`); - - await viewerToolbar.openMoreMenu(); - - expect(await viewerToolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await viewerToolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await viewerToolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); - expect(await viewerToolbar.menu.isSharePresent()).toBe(false, `Share is displayed in More actions`); - expect(await viewerToolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await viewerToolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await viewerToolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await viewerToolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); - expect(await viewerToolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - - await toolbar.closeMoreMenu(); - }); - }); - }); - - describe('Collaborator', () => { - beforeAll(async (done) => { - await loginPage.loginWith(userCollaborator); - done(); - }); - - it('on File Libraries - [C297647]', async () => { - await page.clickFileLibrariesAndWait(); - await dataTable.doubleClickOnRowByName(siteName); - await dataTable.waitForHeader(); - await dataTable.selectItem(file1); - - expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${file1}`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${file1}`); - expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${file1}`); - expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${file1}`); - expect(await toolbar.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed for ${file1}`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${file1}`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${file1}`); - expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${file1}`); - expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${file1}`); - expect(await toolbar.menu.isRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${file1}`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed`); - - await toolbar.closeMoreMenu(); - }); - - it('on Shared Files - [C297651]', async () => { - await page.clickSharedFilesAndWait(); - await page.dataTable.selectItem(file1); - - expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${file1}`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${file1}`); - expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${file1}`); - expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${file1}`); - expect(await toolbar.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed`); - - await toolbar.openMoreMenu(); - - // TODO: change expect to true when ACA-2173 is done - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${file1}`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${file1}`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${file1}`); - expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${file1}`); - expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${file1}`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${file1}`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed`); - - await toolbar.closeMoreMenu(); - }); - - it('on Favorites - [C297652]', async () => { - await page.clickFavoritesAndWait(); - await dataTable.selectItem(file1); - - expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${file1}`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${file1}`); - expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${file1}`); - expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${file1}`); - // TODO: replace with isSharedLinkSettingsPresent when ACA-2175 is done - expect(await toolbar.isSharePresent()).toBe(true, `Share is not displayed`); - - await toolbar.openMoreMenu(); - - // TODO: change expect to true when ACA-2174 is done - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is not displayed for ${file1}`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${file1}`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${file1}`); - // TODO: change expect to false when ACA-1737 is done - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is displayed for ${file1}`); - // TODO: change expect to false when ACA-1737 is done - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is displayed for ${file1}`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${file1}`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed`); - - await toolbar.closeMoreMenu(); - }); - - it('on Search Results - [C297653]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkOnlyFiles(); - await searchInput.searchFor(file1); - await dataTable.selectItem(file1); - - expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${file1}`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${file1}`); - expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${file1}`); - expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${file1}`); - expect(await toolbar.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed for ${file1}`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${file1}`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${file1}`); - expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${file1}`); - expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${file1}`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${file1}`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed`); - - await toolbar.closeMoreMenu(); - }); - - describe('in the viewer', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await dataTable.clearSelection(); - await page.clickPersonalFiles(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('file opened from File Libraries - [C297654]', async () => { - await page.clickFileLibrariesAndWait(); - await dataTable.doubleClickOnRowByName(siteName); - await dataTable.waitForHeader(); - await dataTable.doubleClickOnRowByName(docxFile); - await viewer.waitForViewerToOpen(); - - expect(await viewerToolbar.isViewPresent()).toBe(false, `View is displayed`); - expect(await viewerToolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); - expect(await viewerToolbar.isPrintPresent()).toBe(true, `Print is not displayed`); - expect(await viewerToolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); - expect(await viewerToolbar.isSharedLinkSettingsPresent()).toBe(true, 'Shared link settings is not displayed'); - expect(await viewerToolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed`); - - await viewerToolbar.openMoreMenu(); - - expect(await viewerToolbar.menu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed`); - expect(await viewerToolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await viewerToolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); - expect(await viewerToolbar.menu.isSharePresent()).toBe(false, `Share is displayed in More actions`); - expect(await viewerToolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await viewerToolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await viewerToolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await viewerToolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); - expect(await viewerToolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed`); - - await viewerToolbar.closeMoreMenu(); - }); - - it('file opened from Shared Files - [C297655]', async () => { - await page.clickSharedFilesAndWait(); - await dataTable.doubleClickOnRowByName(docxFile); - await viewer.waitForViewerToOpen(); - - expect(await viewerToolbar.isViewPresent()).toBe(false, `View is displayed`); - expect(await viewerToolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); - expect(await viewerToolbar.isPrintPresent()).toBe(true, `Print is not displayed`); - expect(await viewerToolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); - expect(await viewerToolbar.isSharedLinkSettingsPresent()).toBe(true, 'Shared link settings is not displayed'); - expect(await viewerToolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed`); - - await viewerToolbar.openMoreMenu(); - - expect(await viewerToolbar.menu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed`); - expect(await viewerToolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await viewerToolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); - expect(await viewerToolbar.menu.isSharePresent()).toBe(false, `Share is displayed in More actions`); - expect(await viewerToolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await viewerToolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await viewerToolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await viewerToolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); - expect(await viewerToolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed`); - - await viewerToolbar.closeMoreMenu(); - }); - - it('file opened from Favorites - [C297656]', async () => { - await page.clickFavoritesAndWait(); - await dataTable.doubleClickOnRowByName(docxFile); - await viewer.waitForViewerToOpen(); - - expect(await viewerToolbar.isViewPresent()).toBe(false, `View is displayed`); - expect(await viewerToolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); - expect(await viewerToolbar.isPrintPresent()).toBe(true, `Print is not displayed`); - expect(await viewerToolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); - expect(await viewerToolbar.isSharedLinkSettingsPresent()).toBe(true, 'Shared link settings is not displayed'); - expect(await viewerToolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed`); - - await viewerToolbar.openMoreMenu(); - - expect(await viewerToolbar.menu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed`); - expect(await viewerToolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await viewerToolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove Favorite is not displayed`); - expect(await viewerToolbar.menu.isSharePresent()).toBe(false, `Share is displayed in More actions`); - expect(await viewerToolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await viewerToolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await viewerToolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await viewerToolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); - expect(await viewerToolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed`); - - await viewerToolbar.closeMoreMenu(); - }); - - it('file opened from Search Results - [C306992]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkOnlyFiles(); - await searchInput.searchFor(docxFile); - await dataTable.waitForBody(); - await dataTable.doubleClickOnRowByName(docxFile); - await viewer.waitForViewerToOpen(); - - expect(await viewerToolbar.isViewPresent()).toBe(false, `View is displayed`); - expect(await viewerToolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); - expect(await viewerToolbar.isPrintPresent()).toBe(true, `Print is not displayed`); - expect(await viewerToolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); - expect(await viewerToolbar.isSharedLinkSettingsPresent()).toBe(true, 'Shared link settings is not displayed'); - expect(await viewerToolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed`); - - await viewerToolbar.openMoreMenu(); - - expect(await viewerToolbar.menu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed`); - expect(await viewerToolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await viewerToolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); - expect(await viewerToolbar.menu.isSharePresent()).toBe(false, `Share is displayed in More actions`); - expect(await viewerToolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await viewerToolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await viewerToolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await viewerToolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); - expect(await viewerToolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed`); - - await viewerToolbar.closeMoreMenu(); - }); - }); - }); - - describe('File locked - lock owner : ', () => { - beforeAll(async (done) => { - await loginPage.loginWith(userDemoted); - done(); - }); - - it('on File Libraries - [C297657]', async () => { - await page.clickFileLibrariesAndWait(); - await dataTable.doubleClickOnRowByName(siteName); - await dataTable.waitForHeader(); - await dataTable.selectItem(fileLocked); - - expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileLocked}`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLocked}`); - expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${fileLocked}`); - expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLocked}`); - expect(await toolbar.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileLocked}`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${fileLocked}`); - expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${fileLocked}`); - expect(await toolbar.menu.isRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, 'Manage versions is not displayed'); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, 'Upload new version is not displayed'); - - await toolbar.closeMoreMenu(); - }); - - it('on Shared Files - [C297658]', async () => { - await page.clickSharedFilesAndWait(); - await page.dataTable.selectItem(fileLocked); - - expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileLocked}`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLocked}`); - expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${fileLocked}`); - expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLocked}`); - expect(await toolbar.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileLocked}`); - // TODO: change expect to true when ACA-2173 is done - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${fileLocked}`); - expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${fileLocked}`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, 'Manage versions is not displayed'); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, 'Upload new version is not displayed'); - - await toolbar.closeMoreMenu(); - }); - - it('on Favorites - [C297659]', async () => { - await page.clickFavoritesAndWait(); - await dataTable.selectItem(fileLocked); - - expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileLocked}`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLocked}`); - expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${fileLocked}`); - expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLocked}`); - // TODO: replace with isSharedLinkSettingsPresent when ACA-2175 is done - expect(await toolbar.isSharePresent()).toBe(true, `Share is not displayed`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileLocked}`); - // TODO: change expect to true when ACA-2174 is fixed - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLocked}`); - // TODO: change expect to false when ACA-1737 is fixed - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is displayed for ${fileLocked}`); - // TODO: change expect to false when ACA-1737 is fixed - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is displayed for ${fileLocked}`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, 'Manage versions is not displayed'); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, 'Upload new version is not displayed'); - - await toolbar.closeMoreMenu(); - }); - - it('on Search Results - [C297660]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkOnlyFiles(); - await searchInput.searchFor(fileLocked); - await dataTable.selectItem(fileLocked); - - expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileLocked}`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLocked}`); - expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${fileLocked}`); - expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLocked}`); - expect(await toolbar.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileLocked}`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${fileLocked}`); - expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${fileLocked}`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, 'Manage versions is not displayed'); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, 'Upload new version is not displayed'); - - await toolbar.closeMoreMenu(); - }); - - describe('in the viewer', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await dataTable.clearSelection(); - await page.clickPersonalFiles(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('file opened from File Libraries - [C297661]', async () => { - await page.clickFileLibrariesAndWait(); - await dataTable.doubleClickOnRowByName(siteName); - await dataTable.waitForHeader(); - await dataTable.doubleClickOnRowByName(fileLocked); - await viewer.waitForViewerToOpen(); - - expect(await viewerToolbar.isViewPresent()).toBe(false, `View is displayed`); - expect(await viewerToolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); - expect(await viewerToolbar.isPrintPresent()).toBe(true, `Print is not displayed`); - expect(await viewerToolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); - expect(await viewerToolbar.isSharedLinkSettingsPresent()).toBe(true, 'Shared link settings is not displayed'); - expect(await viewerToolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed`); - - await viewerToolbar.openMoreMenu(); - - expect(await viewerToolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await viewerToolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed`); - expect(await viewerToolbar.menu.isRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); - expect(await viewerToolbar.menu.isSharePresent()).toBe(false, `Share is displayed in More actions`); - expect(await viewerToolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await viewerToolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await viewerToolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await viewerToolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); - expect(await viewerToolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed`); - - await viewerToolbar.closeMoreMenu(); - }); - - it('file opened from Shared Files - [C297662]', async () => { - await page.clickSharedFilesAndWait(); - await dataTable.doubleClickOnRowByName(fileLocked); - await viewer.waitForViewerToOpen(); - - expect(await viewerToolbar.isViewPresent()).toBe(false, `View is displayed`); - expect(await viewerToolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); - expect(await viewerToolbar.isPrintPresent()).toBe(true, `Print is not displayed`); - expect(await viewerToolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); - expect(await viewerToolbar.isSharedLinkSettingsPresent()).toBe(true, 'Shared link settings is not displayed'); - expect(await viewerToolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed`); - - await viewerToolbar.openMoreMenu(); - - expect(await viewerToolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await viewerToolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed`); - expect(await viewerToolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); - expect(await viewerToolbar.menu.isSharePresent()).toBe(false, `Share is displayed in More actions`); - expect(await viewerToolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await viewerToolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await viewerToolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await viewerToolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); - expect(await viewerToolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed`); - - await viewerToolbar.closeMoreMenu(); - }); - - it('file opened from Favorites - [C297663]', async () => { - await page.clickFavoritesAndWait(); - await dataTable.doubleClickOnRowByName(fileLocked); - await viewer.waitForViewerToOpen(); - - expect(await viewerToolbar.isEmpty()).toBe(false, `viewer toolbar is empty`); - expect(await viewerToolbar.isViewPresent()).toBe(false, `View is displayed`); - expect(await viewerToolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); - expect(await viewerToolbar.isPrintPresent()).toBe(true, `Print is not displayed`); - expect(await viewerToolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); - expect(await viewerToolbar.isSharedLinkSettingsPresent()).toBe(true, 'Shared link settings is not displayed'); - expect(await viewerToolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed`); - - await viewerToolbar.openMoreMenu(); - - expect(await viewerToolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await viewerToolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed`); - expect(await viewerToolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); - expect(await viewerToolbar.menu.isSharePresent()).toBe(false, `Share is displayed in More actions`); - expect(await viewerToolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await viewerToolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await viewerToolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await viewerToolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); - expect(await viewerToolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed`); - - await viewerToolbar.closeMoreMenu(); - }); - - it('file opened from Search Results - [C306993]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkOnlyFiles(); - await searchInput.searchFor(fileLocked); - await dataTable.waitForBody(); - await dataTable.doubleClickOnRowByName(fileLocked); - await viewer.waitForViewerToOpen(); - - expect(await viewerToolbar.isViewPresent()).toBe(false, `View is displayed`); - expect(await viewerToolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); - expect(await viewerToolbar.isPrintPresent()).toBe(true, `Print is not displayed`); - expect(await viewerToolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); - expect(await viewerToolbar.isSharedLinkSettingsPresent()).toBe(true, 'Shared link settings is not displayed'); - expect(await viewerToolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed`); - - await viewerToolbar.openMoreMenu(); - - expect(await viewerToolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await viewerToolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed`); - expect(await viewerToolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); - expect(await viewerToolbar.menu.isSharePresent()).toBe(false, `Share is displayed in More actions`); - expect(await viewerToolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await viewerToolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); - expect(await viewerToolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); - expect(await viewerToolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); - expect(await viewerToolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed`); - - await viewerToolbar.closeMoreMenu(); - }); - }); - }); - - describe('File locked - manager : ', () => { - beforeAll(async (done) => { - await loginPage.loginWithAdmin(); - done(); - }); - - it('on File Libraries - [C297664]', async () => { - await page.clickFileLibrariesAndWait(); - await dataTable.doubleClickOnRowByName(siteName); - await dataTable.waitForHeader(); - await dataTable.selectItem(fileLocked); - - expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileLocked}`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLocked}`); - expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${fileLocked}`); - expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLocked}`); - expect(await toolbar.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileLocked}`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, 'Manage versions is not displayed'); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, 'Upload new version is displayed'); - - await toolbar.closeMoreMenu(); - }); - - it('on Shared Files - [C297665]', async () => { - await page.clickSharedFilesAndWait(); - await page.dataTable.selectItem(fileLocked); - - expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileLocked}`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLocked}`); - expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${fileLocked}`); - expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLocked}`); - expect(await toolbar.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileLocked}`); - // TODO: change expect to true when ACA-2173 is done - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, 'Manage versions is not displayed'); - // TODO: change expect to false when ACA-2173 is done - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, 'Upload new version is displayed'); - - await toolbar.closeMoreMenu(); - }); - - it('on Favorites - [C297666]', async () => { - await page.clickFavoritesAndWait(); - await dataTable.selectItem(fileLocked); - - expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileLocked}`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLocked}`); - expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${fileLocked}`); - expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLocked}`); - // TODO: replace with isSharedLinkSettingsPresent when ACA-2175 is done - expect(await toolbar.isSharePresent()).toBe(true, `Share is not displayed`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileLocked}`); - // TODO: change expect to true when ACA-2174 is fixed - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, 'Manage versions is not displayed'); - // TODO: change expect to false when ACA-1737 is done - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, 'Upload new version is displayed'); - - await toolbar.closeMoreMenu(); - }); - - it('on Search Results - [C297667]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkOnlyFiles(); - await searchInput.searchFor(fileLocked); - await dataTable.selectItem(fileLocked); - - expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileLocked}`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLocked}`); - expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${fileLocked}`); - expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLocked}`); - expect(await toolbar.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileLocked}`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${fileLocked} in Search Results`); - expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${fileLocked} in Search Results`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, 'Manage versions is not displayed'); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, 'Upload new version is displayed'); - - await toolbar.closeMoreMenu(); - }); - - describe('in the viewer', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await dataTable.clearSelection(); - await page.clickPersonalFiles(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('file opened from File Libraries - [C297671]', async () => { - await page.clickFileLibrariesAndWait(); - await dataTable.doubleClickOnRowByName(siteName); - await dataTable.waitForHeader(); - await dataTable.doubleClickOnRowByName(fileLocked); - await viewer.waitForViewerToOpen(); - - expect(await viewerToolbar.isViewPresent()).toBe(false, `View is displayed`); - expect(await viewerToolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); - expect(await viewerToolbar.isPrintPresent()).toBe(true, `Print is not displayed`); - expect(await viewerToolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); - expect(await viewerToolbar.isSharedLinkSettingsPresent()).toBe(true, 'Shared link settings is not displayed'); - expect(await viewerToolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed`); - - await viewerToolbar.openMoreMenu(); - - expect(await viewerToolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await viewerToolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed`); - expect(await viewerToolbar.menu.isRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); - expect(await viewerToolbar.menu.isSharePresent()).toBe(false, `Share is displayed in More actions`); - expect(await viewerToolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await viewerToolbar.menu.isMovePresent()).toBe(true, `Move is not displayed`); - expect(await viewerToolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed`); - expect(await viewerToolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); - expect(await viewerToolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - - await viewerToolbar.closeMoreMenu(); - }); - - it('file opened from Shared Files - [C297672]', async () => { - await page.clickSharedFilesAndWait(); - await dataTable.doubleClickOnRowByName(fileLocked); - await viewer.waitForViewerToOpen(); - - expect(await viewerToolbar.isViewPresent()).toBe(false, `View is displayed`); - expect(await viewerToolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); - expect(await viewerToolbar.isPrintPresent()).toBe(true, `Print is not displayed`); - expect(await viewerToolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); - expect(await viewerToolbar.isSharedLinkSettingsPresent()).toBe(true, 'Shared link settings is not displayed'); - expect(await viewerToolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed`); - - await viewerToolbar.openMoreMenu(); - - expect(await viewerToolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await viewerToolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed`); - expect(await viewerToolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); - expect(await viewerToolbar.menu.isSharePresent()).toBe(false, `Share is displayed in More actions`); - expect(await viewerToolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await viewerToolbar.menu.isMovePresent()).toBe(true, `Move is not displayed`); - expect(await viewerToolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed`); - expect(await viewerToolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); - expect(await viewerToolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - - await viewerToolbar.closeMoreMenu(); - }); - - it('file opened from Favorites - [C297673]', async () => { - await page.clickFavoritesAndWait(); - await dataTable.doubleClickOnRowByName(fileLocked); - await viewer.waitForViewerToOpen(); - - expect(await viewerToolbar.isEmpty()).toBe(false, `viewer toolbar is empty`); - expect(await viewerToolbar.isViewPresent()).toBe(false, `View is displayed`); - expect(await viewerToolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); - expect(await viewerToolbar.isPrintPresent()).toBe(true, `Print is not displayed`); - expect(await viewerToolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); - expect(await viewerToolbar.isSharedLinkSettingsPresent()).toBe(true, 'Shared link settings is not displayed'); - expect(await viewerToolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed`); - - await viewerToolbar.openMoreMenu(); - - expect(await viewerToolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await viewerToolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed`); - expect(await viewerToolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); - expect(await viewerToolbar.menu.isSharePresent()).toBe(false, `Share is displayed in More actions`); - expect(await viewerToolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await viewerToolbar.menu.isMovePresent()).toBe(true, `Move is not displayed`); - expect(await viewerToolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed`); - expect(await viewerToolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); - expect(await viewerToolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - - await viewerToolbar.closeMoreMenu(); - }); - - it('file opened from Search Results - [C306994]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkOnlyFiles(); - await searchInput.searchFor(fileLocked); - await dataTable.waitForBody(); - await dataTable.doubleClickOnRowByName(fileLocked); - await viewer.waitForViewerToOpen(); - - expect(await viewerToolbar.isViewPresent()).toBe(false, `View is displayed`); - expect(await viewerToolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); - expect(await viewerToolbar.isPrintPresent()).toBe(true, `Print is not displayed`); - expect(await viewerToolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); - expect(await viewerToolbar.isSharedLinkSettingsPresent()).toBe(true, 'Shared link settings is not displayed'); - expect(await viewerToolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed`); - - await viewerToolbar.openMoreMenu(); - - expect(await viewerToolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await viewerToolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed`); - expect(await viewerToolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); - expect(await viewerToolbar.menu.isSharePresent()).toBe(false, `Share is displayed in More actions`); - expect(await viewerToolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - // TODO: change expect to true when ACA-2319 is fixed - expect(await viewerToolbar.menu.isMovePresent()).toBe(false, `Move is not displayed`); - // TODO: change expect to true when ACA-2319 is fixed - expect(await viewerToolbar.menu.isDeletePresent()).toBe(false, `Delete is not displayed`); - expect(await viewerToolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); - expect(await viewerToolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - - await viewerToolbar.closeMoreMenu(); - }); - }); - }); -}); diff --git a/e2e/suites/actions-available/special-permissions/other-permissions.test.ts b/e2e/suites/actions-available/special-permissions/other-permissions.test.ts new file mode 100755 index 0000000000..7a7af0e993 --- /dev/null +++ b/e2e/suites/actions-available/special-permissions/other-permissions.test.ts @@ -0,0 +1,841 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2019 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { LoginPage, BrowsingPage, SearchResultsPage } from '../../../pages/pages'; +import { SITE_VISIBILITY, SITE_ROLES, FILES } from '../../../configs'; +import { RepoClient } from '../../../utilities/repo-client/repo-client'; +import { Utils } from '../../../utilities/utils'; +import { Viewer } from '../../../components/viewer/viewer'; + +describe('', () => { + const userConsumer = `consumer-${Utils.random()}`; + const userCollaborator = `collaborator-${Utils.random()}`; + const userDemoted = `demoted-${Utils.random()}`; + + const siteName = `site-private-${Utils.random()}`; + const file1 = `my-file1-${Utils.random()}.txt`; + let file1Id; + const file2 = `my-file2-${Utils.random()}.txt`; + let file2Id; + const file3 = `my-file3-${Utils.random()}.txt`; + let file3Id; + const fileLocked = `my-file-locked-${Utils.random()}.txt`; + let fileLockedId; + + const folder1 = `my-folder1-${Utils.random()}`; + let folder1Id; + const folder2 = `my-folder2-${Utils.random()}`; + let folder2Id; + + const docxFile = FILES.docxFile; + let docxFileId; + + const apis = { + admin: new RepoClient(), + userConsumer: new RepoClient(userConsumer, userConsumer), + userCollaborator: new RepoClient(userCollaborator, userCollaborator), + userDemoted: new RepoClient(userDemoted, userDemoted) + }; + + const loginPage = new LoginPage(); + const page = new BrowsingPage(); + const { dataTable, toolbar } = page; + const viewer = new Viewer(); + const viewerToolbar = viewer.toolbar; + const searchResultsPage = new SearchResultsPage(); + const { searchInput } = searchResultsPage.header; + + beforeAll(async (done) => { + await apis.admin.people.createUser({ username: userConsumer }); + await apis.admin.people.createUser({ username: userCollaborator }); + await apis.admin.people.createUser({ username: userDemoted }); + + await apis.admin.sites.createSite(siteName, SITE_VISIBILITY.PRIVATE); + const docLibId = await apis.admin.sites.getDocLibId(siteName); + + file1Id = (await apis.admin.nodes.createFile(file1, docLibId)).entry.id; + file2Id = (await apis.admin.nodes.createFile(file2, docLibId)).entry.id; + file3Id = (await apis.admin.nodes.createFile(file3, docLibId)).entry.id; + folder1Id = (await apis.admin.nodes.createFolder(folder1, docLibId)).entry.id; + folder2Id = (await apis.admin.nodes.createFolder(folder2, docLibId)).entry.id; + + docxFileId = (await apis.admin.upload.uploadFile(docxFile, docLibId)).entry.id; + + await apis.admin.sites.addSiteMember(siteName, userConsumer, SITE_ROLES.SITE_CONSUMER.ROLE); + await apis.admin.sites.addSiteMember(siteName, userCollaborator, SITE_ROLES.SITE_COLLABORATOR.ROLE); + await apis.admin.sites.addSiteMember(siteName, userDemoted, SITE_ROLES.SITE_MANAGER.ROLE); + + fileLockedId = (await apis.admin.nodes.createFile(fileLocked, docLibId)).entry.id; + await apis.userDemoted.nodes.lockFile(fileLockedId); + await apis.userDemoted.favorites.addFavoriteById('file', fileLockedId); + await apis.userDemoted.shared.shareFileById(fileLockedId); + await apis.admin.sites.updateSiteMember(siteName, userDemoted, SITE_ROLES.SITE_CONSUMER.ROLE); + + await apis.admin.nodes.setGranularPermission(file3Id, false, userConsumer, SITE_ROLES.SITE_MANAGER.ROLE); + + await apis.userConsumer.shared.shareFileById(file1Id); + await apis.userConsumer.shared.shareFileById(file2Id); + await apis.userConsumer.shared.shareFileById(docxFileId); + await apis.userConsumer.shared.shareFileById(file3Id); + await apis.userConsumer.shared.waitForApi({ expect: 5 }); + + await apis.userConsumer.favorites.addFavoritesByIds('file', [file1Id, file2Id, file3Id, docxFileId]); + await apis.userConsumer.favorites.addFavoritesByIds('folder', [folder1Id, folder2Id]); + await apis.userConsumer.favorites.waitForApi({ expect: 6 }); + + await apis.userCollaborator.favorites.addFavoritesByIds('file', [file1Id, docxFileId]); + await apis.userCollaborator.favorites.waitForApi({ expect: 2 }); + + await apis.admin.favorites.addFavoriteById('file', fileLockedId); + + done(); + }); + + afterAll(async (done) => { + await apis.admin.sites.deleteSite(siteName); + done(); + }); + + describe('Collaborator', () => { + beforeAll(async (done) => { + await loginPage.loginWith(userCollaborator); + done(); + }); + + it('on File Libraries - [C297647]', async () => { + await page.clickFileLibrariesAndWait(); + await dataTable.doubleClickOnRowByName(siteName); + await dataTable.waitForHeader(); + await dataTable.selectItem(file1); + + expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${file1}`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${file1}`); + expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${file1}`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${file1}`); + expect(await toolbar.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed for ${file1}`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${file1}`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${file1}`); + expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${file1}`); + expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${file1}`); + expect(await toolbar.menu.isRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${file1}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); + expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed`); + + await toolbar.closeMoreMenu(); + }); + + it('on Shared Files - [C297651]', async () => { + await page.clickSharedFilesAndWait(); + await page.dataTable.selectItem(file1); + + expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${file1}`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${file1}`); + expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${file1}`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${file1}`); + expect(await toolbar.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed`); + + await toolbar.openMoreMenu(); + + // TODO: change expect to true when ACA-2173 is done + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${file1}`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${file1}`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${file1}`); + expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${file1}`); + expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${file1}`); + expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${file1}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); + expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed`); + + await toolbar.closeMoreMenu(); + }); + + it('on Favorites - [C297652]', async () => { + await page.clickFavoritesAndWait(); + await dataTable.selectItem(file1); + + expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${file1}`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${file1}`); + expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${file1}`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${file1}`); + // TODO: replace with isSharedLinkSettingsPresent when ACA-2175 is done + expect(await toolbar.isSharePresent()).toBe(true, `Share is not displayed`); + + await toolbar.openMoreMenu(); + + // TODO: change expect to true when ACA-2174 is done + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is not displayed for ${file1}`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${file1}`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${file1}`); + // TODO: change expect to false when ACA-1737 is done + expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is displayed for ${file1}`); + // TODO: change expect to false when ACA-1737 is done + expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is displayed for ${file1}`); + expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${file1}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); + expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed`); + + await toolbar.closeMoreMenu(); + }); + + it('on Search Results - [C297653]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFiles(); + await searchInput.searchFor(file1); + await dataTable.selectItem(file1); + + expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${file1}`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${file1}`); + expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${file1}`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${file1}`); + expect(await toolbar.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed for ${file1}`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${file1}`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${file1}`); + expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${file1}`); + expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${file1}`); + expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${file1}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); + expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed`); + + await toolbar.closeMoreMenu(); + }); + + describe('in the viewer', () => { + beforeEach(async (done) => { + await Utils.pressEscape(); + await dataTable.clearSelection(); + await page.clickPersonalFiles(); + done(); + }); + + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + + it('file opened from File Libraries - [C297654]', async () => { + await page.clickFileLibrariesAndWait(); + await dataTable.doubleClickOnRowByName(siteName); + await dataTable.waitForHeader(); + await dataTable.doubleClickOnRowByName(docxFile); + await viewer.waitForViewerToOpen(); + + expect(await viewerToolbar.isViewPresent()).toBe(false, `View is displayed`); + expect(await viewerToolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); + expect(await viewerToolbar.isPrintPresent()).toBe(true, `Print is not displayed`); + expect(await viewerToolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); + expect(await viewerToolbar.isSharedLinkSettingsPresent()).toBe(true, 'Shared link settings is not displayed'); + expect(await viewerToolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed`); + + await viewerToolbar.openMoreMenu(); + + expect(await viewerToolbar.menu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed`); + expect(await viewerToolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await viewerToolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); + expect(await viewerToolbar.menu.isSharePresent()).toBe(false, `Share is displayed in More Actions`); + expect(await viewerToolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await viewerToolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); + expect(await viewerToolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); + expect(await viewerToolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); + expect(await viewerToolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed`); + + await viewerToolbar.closeMoreMenu(); + }); + + it('file opened from Shared Files - [C297655]', async () => { + await page.clickSharedFilesAndWait(); + await dataTable.doubleClickOnRowByName(docxFile); + await viewer.waitForViewerToOpen(); + + expect(await viewerToolbar.isViewPresent()).toBe(false, `View is displayed`); + expect(await viewerToolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); + expect(await viewerToolbar.isPrintPresent()).toBe(true, `Print is not displayed`); + expect(await viewerToolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); + expect(await viewerToolbar.isSharedLinkSettingsPresent()).toBe(true, 'Shared link settings is not displayed'); + expect(await viewerToolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed`); + + await viewerToolbar.openMoreMenu(); + + expect(await viewerToolbar.menu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed`); + expect(await viewerToolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await viewerToolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); + expect(await viewerToolbar.menu.isSharePresent()).toBe(false, `Share is displayed in More Actions`); + expect(await viewerToolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await viewerToolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); + expect(await viewerToolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); + expect(await viewerToolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); + expect(await viewerToolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed`); + + await viewerToolbar.closeMoreMenu(); + }); + + it('file opened from Favorites - [C297656]', async () => { + await page.clickFavoritesAndWait(); + await dataTable.doubleClickOnRowByName(docxFile); + await viewer.waitForViewerToOpen(); + + expect(await viewerToolbar.isViewPresent()).toBe(false, `View is displayed`); + expect(await viewerToolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); + expect(await viewerToolbar.isPrintPresent()).toBe(true, `Print is not displayed`); + expect(await viewerToolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); + expect(await viewerToolbar.isSharedLinkSettingsPresent()).toBe(true, 'Shared link settings is not displayed'); + expect(await viewerToolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed`); + + await viewerToolbar.openMoreMenu(); + + expect(await viewerToolbar.menu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed`); + expect(await viewerToolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await viewerToolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove Favorite is not displayed`); + expect(await viewerToolbar.menu.isSharePresent()).toBe(false, `Share is displayed in More Actions`); + expect(await viewerToolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await viewerToolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); + expect(await viewerToolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); + expect(await viewerToolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); + expect(await viewerToolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed`); + + await viewerToolbar.closeMoreMenu(); + }); + + it('file opened from Search Results - [C306992]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFiles(); + await searchInput.searchFor(docxFile); + await dataTable.waitForBody(); + await dataTable.doubleClickOnRowByName(docxFile); + await viewer.waitForViewerToOpen(); + + expect(await viewerToolbar.isViewPresent()).toBe(false, `View is displayed`); + expect(await viewerToolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); + expect(await viewerToolbar.isPrintPresent()).toBe(true, `Print is not displayed`); + expect(await viewerToolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); + expect(await viewerToolbar.isSharedLinkSettingsPresent()).toBe(true, 'Shared link settings is not displayed'); + expect(await viewerToolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed`); + + await viewerToolbar.openMoreMenu(); + + expect(await viewerToolbar.menu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed`); + expect(await viewerToolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); + expect(await viewerToolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); + expect(await viewerToolbar.menu.isSharePresent()).toBe(false, `Share is displayed in More Actions`); + expect(await viewerToolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await viewerToolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); + expect(await viewerToolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); + expect(await viewerToolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); + expect(await viewerToolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed`); + + await viewerToolbar.closeMoreMenu(); + }); + }); + }); + + describe('File locked - lock owner : ', () => { + beforeAll(async (done) => { + await loginPage.loginWith(userDemoted); + done(); + }); + + it('on File Libraries - [C297657]', async () => { + await page.clickFileLibrariesAndWait(); + await dataTable.doubleClickOnRowByName(siteName); + await dataTable.waitForHeader(); + await dataTable.selectItem(fileLocked); + + expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileLocked}`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLocked}`); + expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${fileLocked}`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLocked}`); + expect(await toolbar.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileLocked}`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${fileLocked}`); + expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${fileLocked}`); + expect(await toolbar.menu.isRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, 'Manage versions is not displayed'); + expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, 'Upload new version is not displayed'); + + await toolbar.closeMoreMenu(); + }); + + it('on Shared Files - [C297658]', async () => { + await page.clickSharedFilesAndWait(); + await page.dataTable.selectItem(fileLocked); + + expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileLocked}`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLocked}`); + expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${fileLocked}`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLocked}`); + expect(await toolbar.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileLocked}`); + // TODO: change expect to true when ACA-2173 is done + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${fileLocked}`); + expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${fileLocked}`); + expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, 'Manage versions is not displayed'); + expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, 'Upload new version is not displayed'); + + await toolbar.closeMoreMenu(); + }); + + it('on Favorites - [C297659]', async () => { + await page.clickFavoritesAndWait(); + await dataTable.selectItem(fileLocked); + + expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileLocked}`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLocked}`); + expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${fileLocked}`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLocked}`); + // TODO: replace with isSharedLinkSettingsPresent when ACA-2175 is done + expect(await toolbar.isSharePresent()).toBe(true, `Share is not displayed`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileLocked}`); + // TODO: change expect to true when ACA-2174 is fixed + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLocked}`); + // TODO: change expect to false when ACA-1737 is fixed + expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is displayed for ${fileLocked}`); + // TODO: change expect to false when ACA-1737 is fixed + expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is displayed for ${fileLocked}`); + expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, 'Manage versions is not displayed'); + expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, 'Upload new version is not displayed'); + + await toolbar.closeMoreMenu(); + }); + + it('on Search Results - [C297660]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFiles(); + await searchInput.searchFor(fileLocked); + await dataTable.selectItem(fileLocked); + + expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileLocked}`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLocked}`); + expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${fileLocked}`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLocked}`); + expect(await toolbar.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileLocked}`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${fileLocked}`); + expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${fileLocked}`); + expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, 'Manage versions is not displayed'); + expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, 'Upload new version is not displayed'); + + await toolbar.closeMoreMenu(); + }); + + describe('in the viewer', () => { + beforeEach(async (done) => { + await Utils.pressEscape(); + await dataTable.clearSelection(); + await page.clickPersonalFiles(); + done(); + }); + + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + + it('file opened from File Libraries - [C297661]', async () => { + await page.clickFileLibrariesAndWait(); + await dataTable.doubleClickOnRowByName(siteName); + await dataTable.waitForHeader(); + await dataTable.doubleClickOnRowByName(fileLocked); + await viewer.waitForViewerToOpen(); + + expect(await viewerToolbar.isViewPresent()).toBe(false, `View is displayed`); + expect(await viewerToolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); + expect(await viewerToolbar.isPrintPresent()).toBe(true, `Print is not displayed`); + expect(await viewerToolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); + expect(await viewerToolbar.isSharedLinkSettingsPresent()).toBe(true, 'Shared link settings is not displayed'); + expect(await viewerToolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed`); + + await viewerToolbar.openMoreMenu(); + + expect(await viewerToolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await viewerToolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed`); + expect(await viewerToolbar.menu.isRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); + expect(await viewerToolbar.menu.isSharePresent()).toBe(false, `Share is displayed in More Actions`); + expect(await viewerToolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await viewerToolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); + expect(await viewerToolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); + expect(await viewerToolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); + expect(await viewerToolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed`); + + await viewerToolbar.closeMoreMenu(); + }); + + it('file opened from Shared Files - [C297662]', async () => { + await page.clickSharedFilesAndWait(); + await dataTable.doubleClickOnRowByName(fileLocked); + await viewer.waitForViewerToOpen(); + + expect(await viewerToolbar.isViewPresent()).toBe(false, `View is displayed`); + expect(await viewerToolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); + expect(await viewerToolbar.isPrintPresent()).toBe(true, `Print is not displayed`); + expect(await viewerToolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); + expect(await viewerToolbar.isSharedLinkSettingsPresent()).toBe(true, 'Shared link settings is not displayed'); + expect(await viewerToolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed`); + + await viewerToolbar.openMoreMenu(); + + expect(await viewerToolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await viewerToolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed`); + expect(await viewerToolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); + expect(await viewerToolbar.menu.isSharePresent()).toBe(false, `Share is displayed in More Actions`); + expect(await viewerToolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await viewerToolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); + expect(await viewerToolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); + expect(await viewerToolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); + expect(await viewerToolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed`); + + await viewerToolbar.closeMoreMenu(); + }); + + it('file opened from Favorites - [C297663]', async () => { + await page.clickFavoritesAndWait(); + await dataTable.doubleClickOnRowByName(fileLocked); + await viewer.waitForViewerToOpen(); + + expect(await viewerToolbar.isEmpty()).toBe(false, `viewer toolbar is empty`); + expect(await viewerToolbar.isViewPresent()).toBe(false, `View is displayed`); + expect(await viewerToolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); + expect(await viewerToolbar.isPrintPresent()).toBe(true, `Print is not displayed`); + expect(await viewerToolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); + expect(await viewerToolbar.isSharedLinkSettingsPresent()).toBe(true, 'Shared link settings is not displayed'); + expect(await viewerToolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed`); + + await viewerToolbar.openMoreMenu(); + + expect(await viewerToolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await viewerToolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed`); + expect(await viewerToolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); + expect(await viewerToolbar.menu.isSharePresent()).toBe(false, `Share is displayed in More Actions`); + expect(await viewerToolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await viewerToolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); + expect(await viewerToolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); + expect(await viewerToolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); + expect(await viewerToolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed`); + + await viewerToolbar.closeMoreMenu(); + }); + + it('file opened from Search Results - [C306993]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFiles(); + await searchInput.searchFor(fileLocked); + await dataTable.waitForBody(); + await dataTable.doubleClickOnRowByName(fileLocked); + await viewer.waitForViewerToOpen(); + + expect(await viewerToolbar.isViewPresent()).toBe(false, `View is displayed`); + expect(await viewerToolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); + expect(await viewerToolbar.isPrintPresent()).toBe(true, `Print is not displayed`); + expect(await viewerToolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); + expect(await viewerToolbar.isSharedLinkSettingsPresent()).toBe(true, 'Shared link settings is not displayed'); + expect(await viewerToolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed`); + + await viewerToolbar.openMoreMenu(); + + expect(await viewerToolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await viewerToolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed`); + expect(await viewerToolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); + expect(await viewerToolbar.menu.isSharePresent()).toBe(false, `Share is displayed in More Actions`); + expect(await viewerToolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await viewerToolbar.menu.isMovePresent()).toBe(false, `Move is displayed`); + expect(await viewerToolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed`); + expect(await viewerToolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); + expect(await viewerToolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed`); + + await viewerToolbar.closeMoreMenu(); + }); + }); + }); + + describe('File locked - manager : ', () => { + beforeAll(async (done) => { + await loginPage.loginWithAdmin(); + done(); + }); + + it('on File Libraries - [C297664]', async () => { + await page.clickFileLibrariesAndWait(); + await dataTable.doubleClickOnRowByName(siteName); + await dataTable.waitForHeader(); + await dataTable.selectItem(fileLocked); + + expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileLocked}`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLocked}`); + expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${fileLocked}`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLocked}`); + expect(await toolbar.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileLocked}`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, 'Manage versions is not displayed'); + expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, 'Upload new version is displayed'); + + await toolbar.closeMoreMenu(); + }); + + it('on Shared Files - [C297665]', async () => { + await page.clickSharedFilesAndWait(); + await page.dataTable.selectItem(fileLocked); + + expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileLocked}`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLocked}`); + expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${fileLocked}`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLocked}`); + expect(await toolbar.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileLocked}`); + // TODO: change expect to true when ACA-2173 is done + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, 'Manage versions is not displayed'); + // TODO: change expect to false when ACA-2173 is done + expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, 'Upload new version is displayed'); + + await toolbar.closeMoreMenu(); + }); + + it('on Favorites - [C297666]', async () => { + await page.clickFavoritesAndWait(); + await dataTable.selectItem(fileLocked); + + expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileLocked}`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLocked}`); + expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${fileLocked}`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLocked}`); + // TODO: replace with isSharedLinkSettingsPresent when ACA-2175 is done + expect(await toolbar.isSharePresent()).toBe(true, `Share is not displayed`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileLocked}`); + // TODO: change expect to true when ACA-2174 is fixed + expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, 'Manage versions is not displayed'); + // TODO: change expect to false when ACA-1737 is done + expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, 'Upload new version is displayed'); + + await toolbar.closeMoreMenu(); + }); + + it('on Search Results - [C297667]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFiles(); + await searchInput.searchFor(fileLocked); + await dataTable.selectItem(fileLocked); + + expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileLocked}`); + expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLocked}`); + expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${fileLocked}`); + expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLocked}`); + expect(await toolbar.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed`); + + await toolbar.openMoreMenu(); + + expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileLocked}`); + expect(await toolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${fileLocked} in Search Results`); + expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${fileLocked} in Search Results`); + expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${fileLocked}`); + expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, 'Manage versions is not displayed'); + expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, 'Upload new version is displayed'); + + await toolbar.closeMoreMenu(); + }); + + describe('in the viewer', () => { + beforeEach(async (done) => { + await Utils.pressEscape(); + await dataTable.clearSelection(); + await page.clickPersonalFiles(); + done(); + }); + + afterAll(async (done) => { + await Utils.pressEscape(); + done(); + }); + + it('file opened from File Libraries - [C297671]', async () => { + await page.clickFileLibrariesAndWait(); + await dataTable.doubleClickOnRowByName(siteName); + await dataTable.waitForHeader(); + await dataTable.doubleClickOnRowByName(fileLocked); + await viewer.waitForViewerToOpen(); + + expect(await viewerToolbar.isViewPresent()).toBe(false, `View is displayed`); + expect(await viewerToolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); + expect(await viewerToolbar.isPrintPresent()).toBe(true, `Print is not displayed`); + expect(await viewerToolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); + expect(await viewerToolbar.isSharedLinkSettingsPresent()).toBe(true, 'Shared link settings is not displayed'); + expect(await viewerToolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed`); + + await viewerToolbar.openMoreMenu(); + + expect(await viewerToolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await viewerToolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed`); + expect(await viewerToolbar.menu.isRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); + expect(await viewerToolbar.menu.isSharePresent()).toBe(false, `Share is displayed in More Actions`); + expect(await viewerToolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await viewerToolbar.menu.isMovePresent()).toBe(true, `Move is not displayed`); + expect(await viewerToolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed`); + expect(await viewerToolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); + expect(await viewerToolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); + + await viewerToolbar.closeMoreMenu(); + }); + + it('file opened from Shared Files - [C297672]', async () => { + await page.clickSharedFilesAndWait(); + await dataTable.doubleClickOnRowByName(fileLocked); + await viewer.waitForViewerToOpen(); + + expect(await viewerToolbar.isViewPresent()).toBe(false, `View is displayed`); + expect(await viewerToolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); + expect(await viewerToolbar.isPrintPresent()).toBe(true, `Print is not displayed`); + expect(await viewerToolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); + expect(await viewerToolbar.isSharedLinkSettingsPresent()).toBe(true, 'Shared link settings is not displayed'); + expect(await viewerToolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed`); + + await viewerToolbar.openMoreMenu(); + + expect(await viewerToolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await viewerToolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed`); + expect(await viewerToolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); + expect(await viewerToolbar.menu.isSharePresent()).toBe(false, `Share is displayed in More Actions`); + expect(await viewerToolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await viewerToolbar.menu.isMovePresent()).toBe(true, `Move is not displayed`); + expect(await viewerToolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed`); + expect(await viewerToolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); + expect(await viewerToolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); + + await viewerToolbar.closeMoreMenu(); + }); + + it('file opened from Favorites - [C297673]', async () => { + await page.clickFavoritesAndWait(); + await dataTable.doubleClickOnRowByName(fileLocked); + await viewer.waitForViewerToOpen(); + + expect(await viewerToolbar.isEmpty()).toBe(false, `viewer toolbar is empty`); + expect(await viewerToolbar.isViewPresent()).toBe(false, `View is displayed`); + expect(await viewerToolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); + expect(await viewerToolbar.isPrintPresent()).toBe(true, `Print is not displayed`); + expect(await viewerToolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); + expect(await viewerToolbar.isSharedLinkSettingsPresent()).toBe(true, 'Shared link settings is not displayed'); + expect(await viewerToolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed`); + + await viewerToolbar.openMoreMenu(); + + expect(await viewerToolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await viewerToolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed`); + expect(await viewerToolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); + expect(await viewerToolbar.menu.isSharePresent()).toBe(false, `Share is displayed in More Actions`); + expect(await viewerToolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); + expect(await viewerToolbar.menu.isMovePresent()).toBe(true, `Move is not displayed`); + expect(await viewerToolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed`); + expect(await viewerToolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); + expect(await viewerToolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); + + await viewerToolbar.closeMoreMenu(); + }); + + it('file opened from Search Results - [C306994]', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFiles(); + await searchInput.searchFor(fileLocked); + await dataTable.waitForBody(); + await dataTable.doubleClickOnRowByName(fileLocked); + await viewer.waitForViewerToOpen(); + + expect(await viewerToolbar.isViewPresent()).toBe(false, `View is displayed`); + expect(await viewerToolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); + expect(await viewerToolbar.isPrintPresent()).toBe(true, `Print is not displayed`); + expect(await viewerToolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); + expect(await viewerToolbar.isSharedLinkSettingsPresent()).toBe(true, 'Shared link settings is not displayed'); + expect(await viewerToolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed`); + + await viewerToolbar.openMoreMenu(); + + expect(await viewerToolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); + expect(await viewerToolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed`); + expect(await viewerToolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); + expect(await viewerToolbar.menu.isSharePresent()).toBe(false, `Share is displayed in More Actions`); + expect(await viewerToolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); + // TODO: change expect to true when ACA-2319 is fixed + expect(await viewerToolbar.menu.isMovePresent()).toBe(false, `Move is not displayed`); + // TODO: change expect to true when ACA-2319 is fixed + expect(await viewerToolbar.menu.isDeletePresent()).toBe(false, `Delete is not displayed`); + expect(await viewerToolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); + expect(await viewerToolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); + + await viewerToolbar.closeMoreMenu(); + }); + }); + }); +}); diff --git a/e2e/suites/actions-available/special-permissions/permissions-favorites.test.ts b/e2e/suites/actions-available/special-permissions/permissions-favorites.test.ts new file mode 100755 index 0000000000..a645b9c8ce --- /dev/null +++ b/e2e/suites/actions-available/special-permissions/permissions-favorites.test.ts @@ -0,0 +1,198 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2019 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { LoginPage, BrowsingPage } from '../../../pages/pages'; +import { FILES, SITE_VISIBILITY, SITE_ROLES } from '../../../configs'; +import { RepoClient } from '../../../utilities/repo-client/repo-client'; +import { Utils } from '../../../utilities/utils'; +import * as data from './test-data-permissions'; +import * as testUtil from '../test-util'; + +describe('Special permissions actions : on Favorites : ', () => { + + const site = `site-private-${Utils.random()}`; + + const userConsumer = `consumer-${Utils.random()}`; + + let fileDocxFavId, fileFavId, fileDocxSharedFavId, fileSharedFavId, fileFavLockedId, fileSharedFavLockedId; + let folderFavId, folderFav2Id; + + const file3 = `file-3-${Utils.random()}.txt`; + let file3Id; + + const apis = { + admin: new RepoClient(), + userConsumer: new RepoClient(userConsumer, userConsumer) + }; + + const loginPage = new LoginPage(); + const page = new BrowsingPage(); + + beforeAll(async (done) => { + await apis.admin.people.createUser({ username: userConsumer }); + + await apis.admin.sites.createSite(site, SITE_VISIBILITY.PRIVATE); + const docLibId = await apis.admin.sites.getDocLibId(site); + await apis.admin.sites.addSiteMember(site, userConsumer, SITE_ROLES.SITE_CONSUMER.ROLE); + + fileDocxFavId = (await apis.admin.upload.uploadFileWithRename(FILES.docxFile, docLibId, data.fileDocxFav.name)).entry.id; + fileFavId = (await apis.admin.nodes.createFile(data.fileFav.name, docLibId)).entry.id; + fileDocxSharedFavId = (await apis.admin.upload.uploadFileWithRename(FILES.docxFile, docLibId, data.fileDocxSharedFav.name)).entry.id; + fileSharedFavId = (await apis.admin.nodes.createFile(data.fileSharedFav.name, docLibId)).entry.id; + fileFavLockedId = (await apis.admin.nodes.createFile(data.fileFavLocked.name, docLibId)).entry.id; + fileSharedFavLockedId = (await apis.admin.nodes.createFile(data.fileSharedFavLocked.name, docLibId)).entry.id; + + file3Id = (await apis.admin.nodes.createFile(file3, docLibId)).entry.id; + + folderFavId = (await apis.admin.nodes.createFolder(data.folderFav.name, docLibId)).entry.id; + folderFav2Id = (await apis.admin.nodes.createFolder(data.folderFav2.name, docLibId)).entry.id; + await apis.userConsumer.favorites.addFavoriteById('folder', folderFavId); + await apis.userConsumer.favorites.addFavoriteById('folder', folderFav2Id); + + await apis.userConsumer.favorites.addFavoritesByIds('file', [ + fileDocxFavId, + fileFavId, + fileDocxSharedFavId, + fileSharedFavId, + fileFavLockedId, + fileSharedFavLockedId, + file3Id + ]); + + await apis.userConsumer.shared.shareFilesByIds([ + fileDocxSharedFavId, + fileSharedFavId, + fileSharedFavLockedId, + file3Id + ]); + + await apis.admin.nodes.lockFile(fileFavLockedId); + await apis.admin.nodes.lockFile(fileSharedFavLockedId); + + await apis.admin.nodes.setGranularPermission(file3Id, false, userConsumer, SITE_ROLES.SITE_MANAGER.ROLE); + + await apis.userConsumer.favorites.waitForApi({ expect: 9 }); + await apis.userConsumer.shared.waitForApi({ expect: 4 }); + + await loginPage.loginWith(userConsumer); + done(); + }); + + afterAll(async (done) => { + await apis.admin.sites.deleteSite(site); + done(); + }); + + beforeEach(async (done) => { + await Utils.pressEscape(); + await page.clickFavoritesAndWait(); + done(); + }); + + afterEach(async (done) => { + await Utils.pressEscape(); + done(); + }); + + describe('on a file', () => { + + it('File Office, favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.fileDocxFav.name, data.fileDocxFav.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileDocxFav.name, data.fileDocxFav.favoritesToolbarMore); + await testUtil.checkContextMenu(data.fileDocxFav.name, data.fileDocxFav.favoritesContextMenu); + }); + + it('File favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.fileFav.name, data.fileFav.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileFav.name, data.fileFav.favoritesToolbarMore); + await testUtil.checkContextMenu(data.fileFav.name, data.fileFav.favoritesContextMenu); + }); + + it('File Office, shared, favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.fileDocxSharedFav.name, data.fileDocxSharedFav.favoritesToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileDocxSharedFav.name, data.fileDocxSharedFav.favoritesToolbarMore); + await testUtil.checkContextMenu(data.fileDocxSharedFav.name, data.fileDocxSharedFav.favoritesContextMenu); + }); + + it('File shared, favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.fileSharedFav.name, data.fileSharedFav.favoritesToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileSharedFav.name, data.fileSharedFav.favoritesToolbarMore); + await testUtil.checkContextMenu(data.fileSharedFav.name, data.fileSharedFav.favoritesContextMenu); + }); + + it('File favorite, locked - []', async () => { + await testUtil.checkToolbarPrimary(data.fileFavLocked.name, data.fileFavLocked.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileFavLocked.name, data.fileFavLocked.favoritesToolbarMore); + await testUtil.checkContextMenu(data.fileFavLocked.name, data.fileFavLocked.favoritesContextMenu); + }); + + it('File shared, favorite, locked - []', async () => { + await testUtil.checkToolbarPrimary(data.fileSharedFavLocked.name, data.fileSharedFavLocked.favoritesToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileSharedFavLocked.name, data.fileSharedFavLocked.favoritesToolbarMore); + await testUtil.checkContextMenu(data.fileSharedFavLocked.name, data.fileSharedFavLocked.favoritesContextMenu); + }); + }); + + describe('on a folder', () => { + it('Folder favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.folderFav.name, data.folderFav.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.folderFav.name, data.folderFav.favoritesToolbarMore); + await testUtil.checkContextMenu(data.folderFav.name, data.folderFav.favoritesContextMenu); + }); + }); + + describe('on multiple selection', () => { + it('multiple files - []', async () => { + await testUtil.checkMultipleSelContextMenu([ data.fileDocxFav.name, data.fileDocxSharedFav.name ], data.multipleSelAllFav.favoritesContextMenu); + await testUtil.checkMultipleSelToolbarPrimary([ data.fileDocxFav.name, data.fileDocxSharedFav.name ], data.multipleSelAllFav.toolbarPrimary); + await testUtil.checkMultipleSelToolbarMoreActions([ data.fileDocxFav.name, data.fileDocxSharedFav.name ], data.multipleSelAllFav.favoritesToolbarMore); + }); + + it('multiple locked files - []', async () => { + await testUtil.checkMultipleSelContextMenu([ data.fileFavLocked.name, data.fileSharedFavLocked.name ], data.multipleSelAllFav.favoritesContextMenu); + await testUtil.checkMultipleSelToolbarPrimary([ data.fileFavLocked.name, data.fileSharedFavLocked.name ], data.multipleSelAllFav.toolbarPrimary); + await testUtil.checkMultipleSelToolbarMoreActions([ data.fileFavLocked.name, data.fileSharedFavLocked.name ], data.multipleSelAllFav.favoritesToolbarMore); + }); + + it('multiple folders - []', async () => { + await testUtil.checkMultipleSelContextMenu([ data.folderFav.name, data.folderFav2.name ], data.multipleSelAllFav.favoritesContextMenu); + await testUtil.checkMultipleSelToolbarPrimary([ data.folderFav.name, data.folderFav2.name ], data.multipleSelAllFav.toolbarPrimary); + await testUtil.checkMultipleSelToolbarMoreActions([ data.folderFav.name, data.folderFav2.name ], data.multipleSelAllFav.favoritesToolbarMore); + }); + + it('both files and folders - []', async () => { + await testUtil.checkMultipleSelContextMenu([ data.fileFav.name, data.folderFav.name ], data.multipleSelAllFav.favoritesContextMenu); + await testUtil.checkMultipleSelToolbarPrimary([ data.fileFav.name, data.folderFav.name ], data.multipleSelAllFav.toolbarPrimary); + await testUtil.checkMultipleSelToolbarMoreActions([ data.fileFav.name, data.folderFav.name ], data.multipleSelAllFav.favoritesToolbarMore); + }); + + it('multiple files with different granular permissions - []', async () => { + await testUtil.checkMultipleSelContextMenu([ data.fileFav.name, file3 ], data.multipleSelAllFav.favoritesContextMenu); + await testUtil.checkMultipleSelToolbarPrimary([ data.fileFav.name, file3 ], data.multipleSelAllFav.toolbarPrimary); + await testUtil.checkMultipleSelToolbarMoreActions([ data.fileFav.name, file3 ], data.multipleSelAllFav.favoritesToolbarMore); + }); + }); + +}); diff --git a/e2e/suites/actions-available/special-permissions/permissions-my-libraries.test.ts b/e2e/suites/actions-available/special-permissions/permissions-my-libraries.test.ts new file mode 100755 index 0000000000..bc6abb7a1b --- /dev/null +++ b/e2e/suites/actions-available/special-permissions/permissions-my-libraries.test.ts @@ -0,0 +1,266 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2019 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { LoginPage, BrowsingPage } from '../../../pages/pages'; +import { FILES, SITE_VISIBILITY, SITE_ROLES } from '../../../configs'; +import { RepoClient } from '../../../utilities/repo-client/repo-client'; +import { Utils } from '../../../utilities/utils'; +import * as data from './test-data-permissions'; +import * as testUtil from '../test-util'; + +describe('Special permissions actions : on File Libraries : ', () => { + + const site = `site-private-${Utils.random()}`; + + const userConsumer = `consumer-${Utils.random()}`; + + const file3 = `file-3-${Utils.random()}.txt`; + let file3Id; + + let fileDocxFavId, fileFavId, fileDocxSharedId, fileDocxSharedFavId, fileSharedId, fileSharedFavId, fileLockedId, fileFavLockedId, fileSharedLockedId, fileSharedFavLockedId; + let folderFavId; + + const apis = { + admin: new RepoClient(), + userConsumer: new RepoClient(userConsumer, userConsumer) + }; + + const loginPage = new LoginPage(); + const page = new BrowsingPage(); + const { dataTable } = page; + + beforeAll(async (done) => { + await apis.admin.people.createUser({ username: userConsumer }); + + await apis.admin.sites.createSite(site, SITE_VISIBILITY.PRIVATE); + const docLibId = await apis.admin.sites.getDocLibId(site); + await apis.admin.sites.addSiteMember(site, userConsumer, SITE_ROLES.SITE_CONSUMER.ROLE); + + await apis.admin.upload.uploadFileWithRename(FILES.docxFile, docLibId, data.fileDocx.name ); + fileDocxFavId = (await apis.admin.upload.uploadFileWithRename(FILES.docxFile, docLibId, data.fileDocxFav.name)).entry.id; + await apis.admin.nodes.createFile(data.file.name, docLibId); + fileFavId = (await apis.admin.nodes.createFile(data.fileFav.name, docLibId)).entry.id; + fileDocxSharedId = (await apis.admin.upload.uploadFileWithRename(FILES.docxFile, docLibId, data.fileDocxShared.name)).entry.id; + fileDocxSharedFavId = (await apis.admin.upload.uploadFileWithRename(FILES.docxFile, docLibId, data.fileDocxSharedFav.name)).entry.id; + fileSharedId = (await apis.admin.nodes.createFile(data.fileShared.name, docLibId)).entry.id; + fileSharedFavId = (await apis.admin.nodes.createFile(data.fileSharedFav.name, docLibId)).entry.id; + fileLockedId = (await apis.admin.nodes.createFile(data.fileLocked.name, docLibId)).entry.id; + fileFavLockedId = (await apis.admin.nodes.createFile(data.fileFavLocked.name, docLibId)).entry.id; + fileSharedLockedId = (await apis.admin.nodes.createFile(data.fileSharedLocked.name, docLibId)).entry.id; + fileSharedFavLockedId = (await apis.admin.nodes.createFile(data.fileSharedFavLocked.name, docLibId)).entry.id; + + file3Id = (await apis.admin.nodes.createFile(file3, docLibId)).entry.id; + + await apis.admin.nodes.createFolder(data.folder.name, docLibId); + folderFavId = (await apis.admin.nodes.createFolder(data.folderFav.name, docLibId)).entry.id; + done(); + }); + + beforeAll(async (done) => { + await apis.userConsumer.favorites.addFavoriteById('folder', folderFavId); + + await apis.userConsumer.favorites.addFavoritesByIds('file', [ + fileDocxFavId, + fileFavId, + fileDocxSharedFavId, + fileSharedFavId, + fileFavLockedId, + fileSharedFavLockedId, + file3Id + ]); + + await apis.userConsumer.shared.shareFilesByIds([ + fileDocxSharedId, + fileDocxSharedFavId, + fileSharedId, + fileSharedFavId, + fileSharedLockedId, + fileSharedFavLockedId, + file3Id + ]); + + await apis.admin.nodes.lockFile(fileLockedId); + await apis.admin.nodes.lockFile(fileFavLockedId); + await apis.admin.nodes.lockFile(fileSharedLockedId); + await apis.admin.nodes.lockFile(fileSharedFavLockedId); + + await apis.admin.nodes.setGranularPermission(file3Id, false, userConsumer, SITE_ROLES.SITE_MANAGER.ROLE); + + await apis.userConsumer.favorites.waitForApi({ expect: 8 }); + await apis.userConsumer.shared.waitForApi({ expect: 7 }); + done(); + }); + + beforeAll(async (done) => { + await loginPage.loginWith(userConsumer); + done(); + }); + + afterAll(async (done) => { + await apis.admin.sites.deleteSite(site); + done(); + }); + + beforeEach(async (done) => { + await Utils.pressEscape(); + await page.goToMyLibrariesAndWait(); + await dataTable.doubleClickOnRowByName(site); + await dataTable.waitForHeader(); + done(); + }); + + afterEach(async (done) => { + await Utils.pressEscape(); + done(); + }); + + describe('on a file', () => { + + it('File Office - []', async () => { + await testUtil.checkToolbarPrimary(data.fileDocx.name, data.fileDocx.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileDocx.name, data.fileDocx.toolbarMore); + await testUtil.checkContextMenu(data.fileDocx.name, data.fileDocx.contextMenu); + }); + + it('File Office, favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.fileDocxFav.name, data.fileDocxFav.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileDocxFav.name, data.fileDocxFav.toolbarMore); + await testUtil.checkContextMenu(data.fileDocxFav.name, data.fileDocxFav.contextMenu); + }); + + it('File simple - []', async () => { + await testUtil.checkToolbarPrimary(data.file.name, data.file.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.file.name, data.file.toolbarMore); + await testUtil.checkContextMenu(data.file.name, data.file.contextMenu); + }); + + it('File favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.fileFav.name, data.fileFav.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileFav.name, data.fileFav.toolbarMore); + await testUtil.checkContextMenu(data.fileFav.name, data.fileFav.contextMenu); + }); + + it('File Office, shared - []', async () => { + await testUtil.checkToolbarPrimary(data.fileDocxShared.name, data.fileDocxShared.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileDocxShared.name, data.fileDocxShared.toolbarMore); + await testUtil.checkContextMenu(data.fileDocxShared.name, data.fileDocxShared.contextMenu); + }); + + it('File Office, shared, favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.fileDocxSharedFav.name, data.fileDocxSharedFav.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileDocxSharedFav.name, data.fileDocxSharedFav.toolbarMore); + await testUtil.checkContextMenu(data.fileDocxSharedFav.name, data.fileDocxSharedFav.contextMenu); + }); + + it('File shared - []', async () => { + await testUtil.checkToolbarPrimary(data.fileShared.name, data.fileShared.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileShared.name, data.fileShared.toolbarMore); + await testUtil.checkContextMenu(data.fileShared.name, data.fileShared.contextMenu); + }); + + it('File shared, favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.fileSharedFav.name, data.fileSharedFav.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileSharedFav.name, data.fileSharedFav.toolbarMore); + await testUtil.checkContextMenu(data.fileSharedFav.name, data.fileSharedFav.contextMenu); + }); + + it('File locked - []', async () => { + await testUtil.checkToolbarPrimary(data.fileLocked.name, data.fileLocked.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileLocked.name, data.fileLocked.toolbarMore); + await testUtil.checkContextMenu(data.fileLocked.name, data.fileLocked.contextMenu); + }); + + it('File favorite, locked - []', async () => { + await testUtil.checkToolbarPrimary(data.fileFavLocked.name, data.fileFavLocked.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileFavLocked.name, data.fileFavLocked.toolbarMore); + await testUtil.checkContextMenu(data.fileFavLocked.name, data.fileFavLocked.contextMenu); + }); + + it('File shared, locked - []', async () => { + await testUtil.checkToolbarPrimary(data.fileSharedLocked.name, data.fileSharedLocked.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileSharedLocked.name, data.fileSharedLocked.toolbarMore); + await testUtil.checkContextMenu(data.fileSharedLocked.name, data.fileSharedLocked.contextMenu); + }); + + it('File shared, favorite, locked - []', async () => { + await testUtil.checkToolbarPrimary(data.fileSharedFavLocked.name, data.fileSharedFavLocked.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileSharedFavLocked.name, data.fileSharedFavLocked.toolbarMore); + await testUtil.checkContextMenu(data.fileSharedFavLocked.name, data.fileSharedFavLocked.contextMenu); + }); + }); + + describe('on a folder', () => { + + it('Folder not favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.folder.name, data.folder.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.folder.name, data.folder.toolbarMore); + await testUtil.checkContextMenu(data.folder.name, data.folder.contextMenu); + }); + + it('Folder favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.folderFav.name, data.folderFav.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.folderFav.name, data.folderFav.toolbarMore); + await testUtil.checkContextMenu(data.folderFav.name, data.folderFav.contextMenu); + }); + }); + + describe('on multiple selection', () => { + it('multiple files - []', async () => { + await testUtil.checkMultipleSelContextMenu([ data.fileDocx.name, data.fileDocxSharedFav.name ], data.multipleSel.contextMenu); + await testUtil.checkMultipleSelToolbarPrimary([ data.fileDocx.name, data.fileDocxSharedFav.name ], data.multipleSel.toolbarPrimary); + await testUtil.checkMultipleSelToolbarMoreActions([ data.fileDocx.name, data.fileDocxSharedFav.name ], data.multipleSel.toolbarMore); + }); + + it('multiple files - all favorite - []', async () => { + await testUtil.checkMultipleSelContextMenu([ data.fileDocxFav.name, data.fileDocxSharedFav.name ], data.multipleSelAllFav.contextMenu); + await testUtil.checkMultipleSelToolbarPrimary([ data.fileDocxFav.name, data.fileDocxSharedFav.name ], data.multipleSel.toolbarPrimary); + await testUtil.checkMultipleSelToolbarMoreActions([ data.fileDocxFav.name, data.fileDocxSharedFav.name ], data.multipleSelAllFav.toolbarMore); + }); + + it('multiple locked files - []', async () => { + await testUtil.checkMultipleSelContextMenu([ data.fileLocked.name, data.fileSharedFavLocked.name ], data.multipleSel.contextMenu); + await testUtil.checkMultipleSelToolbarPrimary([ data.fileLocked.name, data.fileSharedFavLocked.name ], data.multipleSel.toolbarPrimary); + await testUtil.checkMultipleSelToolbarMoreActions([ data.fileLocked.name, data.fileSharedFavLocked.name ], data.multipleSel.toolbarMore); + }); + + it('multiple folders - []', async () => { + await testUtil.checkMultipleSelContextMenu([ data.folderFav.name, data.folder.name ], data.multipleSel.contextMenu); + await testUtil.checkMultipleSelToolbarPrimary([ data.folderFav.name, data.folder.name ], data.multipleSel.toolbarPrimary); + await testUtil.checkMultipleSelToolbarMoreActions([ data.folderFav.name, data.folder.name ], data.multipleSel.toolbarMore); + }); + + it('both files and folders - []', async () => { + await testUtil.checkMultipleSelContextMenu([ data.file.name, data.folder.name ], data.multipleSel.contextMenu); + await testUtil.checkMultipleSelToolbarPrimary([ data.file.name, data.folder.name ], data.multipleSel.toolbarPrimary); + await testUtil.checkMultipleSelToolbarMoreActions([ data.file.name, data.folder.name ], data.multipleSel.toolbarMore); + }); + + it('multiple files with different granular permissions - []', async () => { + await testUtil.checkMultipleSelContextMenu([ data.fileDocxFav.name, file3 ], data.multipleSelAllFav.contextMenu); + await testUtil.checkMultipleSelToolbarPrimary([ data.fileDocxFav.name, file3 ], data.multipleSel.toolbarPrimary); + await testUtil.checkMultipleSelToolbarMoreActions([ data.fileDocxFav.name, file3 ], data.multipleSelAllFav.toolbarMore); + }); + }); +}); diff --git a/e2e/suites/actions-available/special-permissions/permissions-search.test.ts b/e2e/suites/actions-available/special-permissions/permissions-search.test.ts new file mode 100755 index 0000000000..6bcfdd7b47 --- /dev/null +++ b/e2e/suites/actions-available/special-permissions/permissions-search.test.ts @@ -0,0 +1,310 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2019 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { LoginPage, BrowsingPage } from '../../../pages/pages'; +import { FILES, SITE_VISIBILITY, SITE_ROLES } from '../../../configs'; +import { RepoClient } from '../../../utilities/repo-client/repo-client'; +import { Utils } from '../../../utilities/utils'; +import * as data from './test-data-permissions'; +import * as testUtil from '../test-util'; + +describe('Special permissions actions : on Search Results : ', () => { + + const site = `site-private-${Utils.random()}`; + + const userConsumer = `consumer-${Utils.random()}`; + + const file3 = `file-3-${Utils.random()}.txt`; + let file3Id; + + let fileDocxFavId, fileFavId, fileDocxSharedId, fileDocxSharedFavId, fileSharedId, fileSharedFavId, fileLockedId, fileFavLockedId, fileSharedLockedId, fileSharedFavLockedId; + let folderFavId; + + const apis = { + admin: new RepoClient(), + userConsumer: new RepoClient(userConsumer, userConsumer) + }; + + const loginPage = new LoginPage(); + const page = new BrowsingPage(); + const { searchInput } = page.header; + + beforeAll(async (done) => { + await apis.admin.people.createUser({ username: userConsumer }); + + await apis.admin.sites.createSite(site, SITE_VISIBILITY.PRIVATE); + const docLibId = await apis.admin.sites.getDocLibId(site); + await apis.admin.sites.addSiteMember(site, userConsumer, SITE_ROLES.SITE_CONSUMER.ROLE); + + await apis.admin.upload.uploadFileWithRename(FILES.docxFile, docLibId, data.fileDocx.name ); + fileDocxFavId = (await apis.admin.upload.uploadFileWithRename(FILES.docxFile, docLibId, data.fileDocxFav.name)).entry.id; + await apis.admin.nodes.createFile(data.file.name, docLibId); + fileFavId = (await apis.admin.nodes.createFile(data.fileFav.name, docLibId)).entry.id; + fileDocxSharedId = (await apis.admin.upload.uploadFileWithRename(FILES.docxFile, docLibId, data.fileDocxShared.name)).entry.id; + fileDocxSharedFavId = (await apis.admin.upload.uploadFileWithRename(FILES.docxFile, docLibId, data.fileDocxSharedFav.name)).entry.id; + fileSharedId = (await apis.admin.nodes.createFile(data.fileShared.name, docLibId)).entry.id; + fileSharedFavId = (await apis.admin.nodes.createFile(data.fileSharedFav.name, docLibId)).entry.id; + fileLockedId = (await apis.admin.nodes.createFile(data.fileLocked.name, docLibId)).entry.id; + fileFavLockedId = (await apis.admin.nodes.createFile(data.fileFavLocked.name, docLibId)).entry.id; + fileSharedLockedId = (await apis.admin.nodes.createFile(data.fileSharedLocked.name, docLibId)).entry.id; + fileSharedFavLockedId = (await apis.admin.nodes.createFile(data.fileSharedFavLocked.name, docLibId)).entry.id; + + file3Id = (await apis.admin.nodes.createFile(file3, docLibId)).entry.id; + + await apis.admin.nodes.createFolder(data.folder.name, docLibId); + folderFavId = (await apis.admin.nodes.createFolder(data.folderFav.name, docLibId)).entry.id; + await apis.userConsumer.favorites.addFavoriteById('folder', folderFavId); + + await apis.userConsumer.favorites.addFavoritesByIds('file', [ + fileDocxFavId, + fileFavId, + fileDocxSharedFavId, + fileSharedFavId, + fileFavLockedId, + fileSharedFavLockedId, + file3Id + ]); + + await apis.userConsumer.shared.shareFilesByIds([ + fileDocxSharedId, + fileDocxSharedFavId, + fileSharedId, + fileSharedFavId, + fileSharedLockedId, + fileSharedFavLockedId, + file3Id + ]); + + await apis.admin.nodes.lockFile(fileLockedId); + await apis.admin.nodes.lockFile(fileFavLockedId); + await apis.admin.nodes.lockFile(fileSharedLockedId); + await apis.admin.nodes.lockFile(fileSharedFavLockedId); + + await apis.admin.nodes.setGranularPermission(file3Id, false, userConsumer, SITE_ROLES.SITE_MANAGER.ROLE); + + await apis.userConsumer.favorites.waitForApi({ expect: 8 }); + await apis.userConsumer.shared.waitForApi({ expect: 7 }); + await apis.userConsumer.search.waitForApi(userConsumer, { expect: 13 }); + + await loginPage.loginWith(userConsumer); + done(); + }); + + afterAll(async (done) => { + await apis.admin.sites.deleteSite(site); + done(); + }); + + describe('on a file', () => { + + beforeEach(async (done) => { + await Utils.pressEscape(); + await page.clickPersonalFiles(); + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFiles(); + await searchInput.searchFor('file-'); + done(); + }); + + afterEach(async (done) => { + await Utils.pressEscape(); + done(); + }); + + it('File Office - []', async () => { + await testUtil.checkToolbarPrimary(data.fileDocx.name, data.fileDocx.searchToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileDocx.name, data.fileDocx.toolbarMore); + await testUtil.checkContextMenu(data.fileDocx.name, data.fileDocx.contextMenu); + }); + + it('File Office, favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.fileDocxFav.name, data.fileDocxFav.searchToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileDocxFav.name, data.fileDocxFav.toolbarMore); + await testUtil.checkContextMenu(data.fileDocxFav.name, data.fileDocxFav.contextMenu); + }); + + it('File simple - []', async () => { + await testUtil.checkToolbarPrimary(data.file.name, data.file.searchToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.file.name, data.file.toolbarMore); + await testUtil.checkContextMenu(data.file.name, data.file.contextMenu); + }); + + it('File favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.fileFav.name, data.fileFav.searchToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileFav.name, data.fileFav.toolbarMore); + await testUtil.checkContextMenu(data.fileFav.name, data.fileFav.contextMenu); + }); + + it('File Office, shared - []', async () => { + await testUtil.checkToolbarPrimary(data.fileDocxShared.name, data.fileDocxShared.searchToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileDocxShared.name, data.fileDocxShared.toolbarMore); + await testUtil.checkContextMenu(data.fileDocxShared.name, data.fileDocxShared.contextMenu); + }); + + it('File Office, shared, favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.fileDocxSharedFav.name, data.fileDocxSharedFav.searchToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileDocxSharedFav.name, data.fileDocxSharedFav.toolbarMore); + await testUtil.checkContextMenu(data.fileDocxSharedFav.name, data.fileDocxSharedFav.contextMenu); + }); + + it('File shared - []', async () => { + await testUtil.checkToolbarPrimary(data.fileShared.name, data.fileShared.searchToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileShared.name, data.fileShared.toolbarMore); + await testUtil.checkContextMenu(data.fileShared.name, data.fileShared.contextMenu); + }); + + it('File shared, favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.fileSharedFav.name, data.fileSharedFav.searchToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileSharedFav.name, data.fileSharedFav.toolbarMore); + await testUtil.checkContextMenu(data.fileSharedFav.name, data.fileSharedFav.contextMenu); + }); + + it('File locked - []', async () => { + await testUtil.checkToolbarPrimary(data.fileLocked.name, data.fileLocked.searchToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileLocked.name, data.fileLocked.toolbarMore); + await testUtil.checkContextMenu(data.fileLocked.name, data.fileLocked.contextMenu); + }); + + it('File favorite, locked - []', async () => { + await testUtil.checkToolbarPrimary(data.fileFavLocked.name, data.fileFavLocked.searchToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileFavLocked.name, data.fileFavLocked.toolbarMore); + await testUtil.checkContextMenu(data.fileFavLocked.name, data.fileFavLocked.contextMenu); + }); + + it('File shared, locked - []', async () => { + await testUtil.checkToolbarPrimary(data.fileSharedLocked.name, data.fileSharedLocked.searchToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileSharedLocked.name, data.fileSharedLocked.toolbarMore); + await testUtil.checkContextMenu(data.fileSharedLocked.name, data.fileSharedLocked.contextMenu); + }); + + it('File shared, favorite, locked - []', async () => { + await testUtil.checkToolbarPrimary(data.fileSharedFavLocked.name, data.fileSharedFavLocked.searchToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileSharedFavLocked.name, data.fileSharedFavLocked.toolbarMore); + await testUtil.checkContextMenu(data.fileSharedFavLocked.name, data.fileSharedFavLocked.contextMenu); + }); + }); + + describe('on a folder', () => { + + beforeEach(async (done) => { + await Utils.pressEscape(); + await page.clickPersonalFiles(); + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFolders(); + await searchInput.searchFor('folder-'); + done(); + }); + + afterEach(async (done) => { + await Utils.pressEscape(); + done(); + }); + + it('Folder not favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.folder.name, data.folder.searchToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.folder.name, data.folder.toolbarMore); + await testUtil.checkContextMenu(data.folder.name, data.folder.contextMenu); + }); + + it('Folder favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.folderFav.name, data.folderFav.searchToolbarPrimary); + await testUtil.checkToolbarMoreActions(data.folderFav.name, data.folderFav.toolbarMore); + await testUtil.checkContextMenu(data.folderFav.name, data.folderFav.contextMenu); + }); + }); + + describe('on multiple selection', () => { + beforeEach(async (done) => { + await Utils.pressEscape(); + await page.clickPersonalFiles(); + done(); + }); + + afterEach(async (done) => { + await Utils.pressEscape(); + done(); + }); + + it('multiple files - []', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFiles(); + await searchInput.searchFor('file-'); + + await testUtil.checkMultipleSelContextMenu([ data.file.name, data.fileDocxShared.name ], data.multipleSel.contextMenu); + await testUtil.checkMultipleSelToolbarPrimary([ data.file.name, data.fileDocxShared.name ], data.multipleSel.searchToolbarPrimary); + await testUtil.checkMultipleSelToolbarMoreActions([ data.file.name, data.fileDocxShared.name ], data.multipleSel.toolbarMore); + }); + + it('multiple files - all favorite - []', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFiles(); + await searchInput.searchFor('file-'); + + await testUtil.checkMultipleSelContextMenu([ data.fileDocxFav.name, data.fileSharedFav.name ], data.multipleSelAllFav.contextMenu); + await testUtil.checkMultipleSelToolbarPrimary([ data.fileDocxFav.name, data.fileSharedFav.name ], data.multipleSel.searchToolbarPrimary); + await testUtil.checkMultipleSelToolbarMoreActions([ data.fileDocxFav.name, data.fileSharedFav.name ], data.multipleSelAllFav.toolbarMore); + }); + + it('multiple locked files - []', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFiles(); + await searchInput.searchFor('file-'); + + await testUtil.checkMultipleSelContextMenu([ data.fileLocked.name, data.fileSharedFavLocked.name ], data.multipleSel.contextMenu); + await testUtil.checkMultipleSelToolbarPrimary([ data.fileLocked.name, data.fileSharedFavLocked.name ], data.multipleSel.searchToolbarPrimary); + await testUtil.checkMultipleSelToolbarMoreActions([ data.fileLocked.name, data.fileSharedFavLocked.name ], data.multipleSel.toolbarMore); + }); + + it('multiple folders - []', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFolders(); + await searchInput.searchFor('folder-'); + + await testUtil.checkMultipleSelContextMenu([ data.folder.name, data.folderFav.name ], data.multipleSel.contextMenu); + await testUtil.checkMultipleSelToolbarPrimary([ data.folder.name, data.folderFav.name ], data.multipleSel.searchToolbarPrimary); + await testUtil.checkMultipleSelToolbarMoreActions([ data.folder.name, data.folderFav.name ], data.multipleSel.toolbarMore); + }); + + it('both files and folders - []', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkFilesAndFolders(); + await searchInput.searchFor(`=${data.file.name} or =${data.folderFav.name}`); + + await testUtil.checkMultipleSelContextMenu([ data.file.name, data.folderFav.name ], data.multipleSel.contextMenu); + await testUtil.checkMultipleSelToolbarPrimary([ data.file.name, data.folderFav.name ], data.multipleSel.searchToolbarPrimary); + await testUtil.checkMultipleSelToolbarMoreActions([ data.file.name, data.folderFav.name ], data.multipleSel.toolbarMore); + }); + + it('multiple files with different granular permissions - []', async () => { + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFiles(); + await searchInput.searchFor('file-'); + + await testUtil.checkMultipleSelContextMenu([ data.fileDocxFav.name, file3 ], data.multipleSelAllFav.contextMenu); + await testUtil.checkMultipleSelToolbarPrimary([ data.fileDocxFav.name, file3 ], data.multipleSel.searchToolbarPrimary); + await testUtil.checkMultipleSelToolbarMoreActions([ data.fileDocxFav.name, file3 ], data.multipleSelAllFav.toolbarMore); + }); + }); +}); diff --git a/e2e/suites/actions-available/special-permissions/permissions-shared.test.ts b/e2e/suites/actions-available/special-permissions/permissions-shared.test.ts new file mode 100755 index 0000000000..6f5404bc0a --- /dev/null +++ b/e2e/suites/actions-available/special-permissions/permissions-shared.test.ts @@ -0,0 +1,179 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2019 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { LoginPage, BrowsingPage } from '../../../pages/pages'; +import { FILES, SITE_VISIBILITY, SITE_ROLES } from '../../../configs'; +import { RepoClient } from '../../../utilities/repo-client/repo-client'; +import { Utils } from '../../../utilities/utils'; +import * as data from './test-data-permissions'; +import * as testUtil from '../test-util'; + +describe('Special permissions actions : on Shared Files : ', () => { + + const site = `site-private-${Utils.random()}`; + + const userConsumer = `consumer-${Utils.random()}`; + + const file3 = `file-3-${Utils.random()}.txt`; + let file3Id; + + let fileDocxSharedId, fileDocxSharedFavId, fileSharedId, fileSharedFavId, fileSharedLockedId, fileSharedFavLockedId; + + const apis = { + admin: new RepoClient(), + userConsumer: new RepoClient(userConsumer, userConsumer) + }; + + const loginPage = new LoginPage(); + const page = new BrowsingPage(); + + beforeAll(async (done) => { + await apis.admin.people.createUser({ username: userConsumer }); + + await apis.admin.sites.createSite(site, SITE_VISIBILITY.PRIVATE); + const docLibId = await apis.admin.sites.getDocLibId(site); + await apis.admin.sites.addSiteMember(site, userConsumer, SITE_ROLES.SITE_CONSUMER.ROLE); + + fileDocxSharedId = (await apis.admin.upload.uploadFileWithRename(FILES.docxFile, docLibId, data.fileDocxShared.name)).entry.id; + fileDocxSharedFavId = (await apis.admin.upload.uploadFileWithRename(FILES.docxFile, docLibId, data.fileDocxSharedFav.name)).entry.id; + fileSharedId = (await apis.admin.nodes.createFile(data.fileShared.name, docLibId)).entry.id; + fileSharedFavId = (await apis.admin.nodes.createFile(data.fileSharedFav.name, docLibId)).entry.id; + fileSharedLockedId = (await apis.admin.nodes.createFile(data.fileSharedLocked.name, docLibId)).entry.id; + fileSharedFavLockedId = (await apis.admin.nodes.createFile(data.fileSharedFavLocked.name, docLibId)).entry.id; + + file3Id = (await apis.admin.nodes.createFile(file3, docLibId)).entry.id; + + await apis.userConsumer.favorites.addFavoritesByIds('file', [ + fileDocxSharedFavId, + fileSharedFavId, + fileSharedFavLockedId, + file3Id + ]); + + await apis.userConsumer.shared.shareFilesByIds([ + fileDocxSharedId, + fileDocxSharedFavId, + fileSharedId, + fileSharedFavId, + fileSharedLockedId, + fileSharedFavLockedId, + file3Id + ]); + + await apis.admin.nodes.lockFile(fileSharedLockedId); + await apis.admin.nodes.lockFile(fileSharedFavLockedId); + + await apis.admin.nodes.setGranularPermission(file3Id, false, userConsumer, SITE_ROLES.SITE_MANAGER.ROLE); + + await apis.userConsumer.favorites.waitForApi({ expect: 7 }); + await apis.userConsumer.shared.waitForApi({ expect: 4 }); + + await loginPage.loginWith(userConsumer); + done(); + }); + + afterAll(async (done) => { + await apis + await apis.admin.sites.deleteSite(site); + done(); + }); + + beforeEach(async (done) => { + await Utils.pressEscape(); + await page.clickSharedFilesAndWait(); + done(); + }); + + afterEach(async (done) => { + await Utils.pressEscape(); + done(); + }); + + describe('single selection', () => { + + it('File Office, shared - []', async () => { + await testUtil.checkToolbarPrimary(data.fileDocxShared.name, data.fileDocxShared.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileDocxShared.name, data.fileDocxShared.sharedToolbarMore); + await testUtil.checkContextMenu(data.fileDocxShared.name, data.fileDocxShared.sharedContextMenu); + }); + + it('File Office, shared, favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.fileDocxSharedFav.name, data.fileDocxSharedFav.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileDocxSharedFav.name, data.fileDocxSharedFav.sharedToolbarMore); + await testUtil.checkContextMenu(data.fileDocxSharedFav.name, data.fileDocxSharedFav.sharedContextMenu); + }); + + it('File shared - []', async () => { + await testUtil.checkToolbarPrimary(data.fileShared.name, data.fileShared.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileShared.name, data.fileShared.sharedToolbarMore); + await testUtil.checkContextMenu(data.fileShared.name, data.fileShared.sharedContextMenu); + }); + + it('File shared, favorite - []', async () => { + await testUtil.checkToolbarPrimary(data.fileSharedFav.name, data.fileSharedFav.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileSharedFav.name, data.fileSharedFav.sharedToolbarMore); + await testUtil.checkContextMenu(data.fileSharedFav.name, data.fileSharedFav.sharedContextMenu); + }); + + it('File shared, locked - []', async () => { + await testUtil.checkToolbarPrimary(data.fileSharedLocked.name, data.fileSharedLocked.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileSharedLocked.name, data.fileSharedLocked.sharedToolbarMore); + await testUtil.checkContextMenu(data.fileSharedLocked.name, data.fileSharedLocked.sharedContextMenu); + }); + + it('File shared, favorite, locked - []', async () => { + await testUtil.checkToolbarPrimary(data.fileSharedFavLocked.name, data.fileSharedFavLocked.toolbarPrimary); + await testUtil.checkToolbarMoreActions(data.fileSharedFavLocked.name, data.fileSharedFavLocked.sharedToolbarMore); + await testUtil.checkContextMenu(data.fileSharedFavLocked.name, data.fileSharedFavLocked.sharedContextMenu); + }); + }); + + describe('multiple selection', () => { + it('multiple files - []', async () => { + await testUtil.checkMultipleSelContextMenu([ data.fileShared.name, data.fileSharedFav.name ], data.multipleSel.contextMenu); + await testUtil.checkMultipleSelToolbarPrimary([ data.fileShared.name, data.fileSharedFav.name ], data.multipleSel.toolbarPrimary); + await testUtil.checkMultipleSelToolbarMoreActions([ data.fileShared.name, data.fileSharedFav.name ], data.multipleSel.toolbarMore); + }); + + it('multiple files - all favorite - []', async () => { + await testUtil.checkMultipleSelContextMenu([ data.fileSharedFav.name, data.fileSharedFavLocked.name ], data.multipleSelAllFav.contextMenu); + await testUtil.checkMultipleSelToolbarPrimary([ data.fileSharedFav.name, data.fileSharedFavLocked.name ], data.multipleSel.toolbarPrimary); + await testUtil.checkMultipleSelToolbarMoreActions([ data.fileSharedFav.name, data.fileSharedFavLocked.name ], data.multipleSelAllFav.toolbarMore); + }); + + it('multiple locked files - []', async () => { + await testUtil.checkMultipleSelContextMenu([ data.fileSharedLocked.name, data.fileSharedFavLocked.name ], data.multipleSel.contextMenu); + await testUtil.checkMultipleSelToolbarPrimary([ data.fileSharedLocked.name, data.fileSharedFavLocked.name ], data.multipleSel.toolbarPrimary); + await testUtil.checkMultipleSelToolbarMoreActions([ data.fileSharedLocked.name, data.fileSharedFavLocked.name ], data.multipleSel.toolbarMore); + }); + + it('multiple files with different granular permissions - []', async () => { + await testUtil.checkMultipleSelContextMenu([ data.fileSharedFav.name, file3 ], data.multipleSelAllFav.contextMenu); + await testUtil.checkMultipleSelToolbarPrimary([ data.fileSharedFav.name, file3 ], data.multipleSel.toolbarPrimary); + await testUtil.checkMultipleSelToolbarMoreActions([ data.fileSharedFav.name, file3 ], data.multipleSelAllFav.toolbarMore); + }); + }); + +}); diff --git a/e2e/suites/actions-available/special-permissions/permissions-viewer.test.ts b/e2e/suites/actions-available/special-permissions/permissions-viewer.test.ts new file mode 100755 index 0000000000..9675361630 --- /dev/null +++ b/e2e/suites/actions-available/special-permissions/permissions-viewer.test.ts @@ -0,0 +1,401 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2019 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { LoginPage, BrowsingPage } from '../../../pages/pages'; +import { FILES, SITE_VISIBILITY, SITE_ROLES } from '../../../configs'; +import { RepoClient } from '../../../utilities/repo-client/repo-client'; +import { Utils } from '../../../utilities/utils'; +import * as data from './test-data-permissions'; +import * as testUtil from '../test-util'; + +describe('Special permissions actions : in the Viewer : ', () => { + + const site = `site-private-${Utils.random()}`; + + const userConsumer = `consumer-${Utils.random()}`; + + let fileDocxFavId, fileFavId, fileDocxSharedId, fileDocxSharedFavId, fileSharedId, fileSharedFavId, fileLockedId, fileFavLockedId, fileSharedLockedId, fileSharedFavLockedId; + + const apis = { + admin: new RepoClient(), + userConsumer: new RepoClient(userConsumer, userConsumer) + }; + + const loginPage = new LoginPage(); + const page = new BrowsingPage(); + const { dataTable } = page; + const { searchInput } = page.header; + + beforeAll(async (done) => { + await apis.admin.people.createUser({ username: userConsumer }); + + await apis.admin.sites.createSite(site, SITE_VISIBILITY.PRIVATE); + const docLibId = await apis.admin.sites.getDocLibId(site); + await apis.admin.sites.addSiteMember(site, userConsumer, SITE_ROLES.SITE_CONSUMER.ROLE); + + await apis.admin.upload.uploadFileWithRename(FILES.docxFile, docLibId, data.fileDocx.name ); + fileDocxFavId = (await apis.admin.upload.uploadFileWithRename(FILES.docxFile, docLibId, data.fileDocxFav.name)).entry.id; + await apis.admin.nodes.createFile(data.file.name, docLibId); + fileFavId = (await apis.admin.nodes.createFile(data.fileFav.name, docLibId)).entry.id; + fileDocxSharedId = (await apis.admin.upload.uploadFileWithRename(FILES.docxFile, docLibId, data.fileDocxShared.name)).entry.id; + fileDocxSharedFavId = (await apis.admin.upload.uploadFileWithRename(FILES.docxFile, docLibId, data.fileDocxSharedFav.name)).entry.id; + fileSharedId = (await apis.admin.nodes.createFile(data.fileShared.name, docLibId)).entry.id; + fileSharedFavId = (await apis.admin.nodes.createFile(data.fileSharedFav.name, docLibId)).entry.id; + fileLockedId = (await apis.admin.nodes.createFile(data.fileLocked.name, docLibId)).entry.id; + fileFavLockedId = (await apis.admin.nodes.createFile(data.fileFavLocked.name, docLibId)).entry.id; + fileSharedLockedId = (await apis.admin.nodes.createFile(data.fileSharedLocked.name, docLibId)).entry.id; + fileSharedFavLockedId = (await apis.admin.nodes.createFile(data.fileSharedFavLocked.name, docLibId)).entry.id; + + done(); + }); + + beforeAll(async (done) => { + await apis.userConsumer.favorites.addFavoritesByIds('file', [ + fileDocxFavId, + fileFavId, + fileDocxSharedFavId, + fileSharedFavId, + fileFavLockedId, + fileSharedFavLockedId + ]); + + await apis.userConsumer.shared.shareFilesByIds([ + fileDocxSharedId, + fileDocxSharedFavId, + fileSharedId, + fileSharedFavId, + fileSharedLockedId, + fileSharedFavLockedId + ]); + + await apis.admin.nodes.lockFile(fileLockedId); + await apis.admin.nodes.lockFile(fileFavLockedId); + await apis.admin.nodes.lockFile(fileSharedLockedId); + await apis.admin.nodes.lockFile(fileSharedFavLockedId); + + await apis.userConsumer.favorites.waitForApi({ expect: 6 }); + await apis.userConsumer.shared.waitForApi({ expect: 6 }); + done(); + }); + + beforeAll(async (done) => { + await loginPage.loginWith(userConsumer); + done(); + }); + + afterAll(async (done) => { + await apis.admin.sites.deleteSite(site); + done(); + }); + + describe('file opened from File Libraries', () => { + + beforeEach(async (done) => { + await Utils.pressEscape(); + await page.goToMyLibrariesAndWait(); + await dataTable.doubleClickOnRowByName(site); + await dataTable.waitForHeader(); + done(); + }); + + afterEach(async (done) => { + await Utils.pressEscape(); + done(); + }); + + it('File Office - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileDocx.name, data.fileDocx.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileDocx.name, data.fileDocx.viewerToolbarMore); + }); + + it('File Office, favorite - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileDocxFav.name, data.fileDocxFav.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileDocxFav.name, data.fileDocxFav.viewerToolbarMore); + }); + + it('File simple - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.file.name, data.file.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.file.name, data.file.viewerToolbarMore); + }); + + it('File favorite - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileFav.name, data.fileFav.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileFav.name, data.fileFav.viewerToolbarMore); + }); + + it('File Office, shared - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileDocxShared.name, data.fileDocxShared.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileDocxShared.name, data.fileDocxShared.viewerToolbarMore); + }); + + it('File Office, shared, favorite - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileDocxSharedFav.name, data.fileDocxSharedFav.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileDocxSharedFav.name, data.fileDocxSharedFav.viewerToolbarMore); + }); + + it('File shared - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileShared.name, data.fileShared.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileShared.name, data.fileShared.viewerToolbarMore); + }); + + it('File shared, favorite - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileSharedFav.name, data.fileSharedFav.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileSharedFav.name, data.fileSharedFav.viewerToolbarMore); + }); + + it('File locked - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileLocked.name, data.fileLocked.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileLocked.name, data.fileLocked.viewerToolbarMore); + }); + + it('File favorite, locked - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileFavLocked.name, data.fileFavLocked.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileFavLocked.name, data.fileFavLocked.viewerToolbarMore); + }); + + it('File shared, locked - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileSharedLocked.name, data.fileSharedLocked.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileSharedLocked.name, data.fileSharedLocked.viewerToolbarMore); + }); + + it('File shared, favorite, locked - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileSharedFavLocked.name, data.fileSharedFavLocked.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileSharedFavLocked.name, data.fileSharedFavLocked.viewerToolbarMore); + }); + }); + + describe('file opened from Favorites', () => { + + beforeEach(async (done) => { + await Utils.pressEscape(); + await page.clickFavoritesAndWait(); + done(); + }); + + afterEach(async (done) => { + await Utils.pressEscape(); + done(); + }); + + it('File Office, favorite - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileDocxFav.name, data.fileDocxFav.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileDocxFav.name, data.fileDocxFav.viewerToolbarMore); + }); + + it('File favorite - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileFav.name, data.fileFav.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileFav.name, data.fileFav.viewerToolbarMore); + }); + + it('File Office, shared, favorite - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileDocxSharedFav.name, data.fileDocxSharedFav.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileDocxSharedFav.name, data.fileDocxSharedFav.viewerToolbarMore); + }); + + it('File shared, favorite - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileSharedFav.name, data.fileSharedFav.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileSharedFav.name, data.fileSharedFav.viewerToolbarMore); + }); + + it('File favorite, locked - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileFavLocked.name, data.fileFavLocked.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileFavLocked.name, data.fileFavLocked.viewerToolbarMore); + }); + + it('File shared, favorite, locked - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileSharedFavLocked.name, data.fileSharedFavLocked.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileSharedFavLocked.name, data.fileSharedFavLocked.viewerToolbarMore); + }); + }); + + describe('file opened from Shared Files', () => { + + beforeEach(async (done) => { + await Utils.pressEscape(); + await page.clickSharedFilesAndWait(); + done(); + }); + + afterEach(async (done) => { + await Utils.pressEscape(); + done(); + }); + + it('File Office, shared - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileDocxShared.name, data.fileDocxShared.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileDocxShared.name, data.fileDocxShared.viewerToolbarMore); + }); + + it('File Office, shared, favorite - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileDocxSharedFav.name, data.fileDocxSharedFav.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileDocxSharedFav.name, data.fileDocxSharedFav.viewerToolbarMore); + }); + + it('File shared - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileShared.name, data.fileShared.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileShared.name, data.fileShared.viewerToolbarMore); + }); + + it('File shared, favorite - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileSharedFav.name, data.fileSharedFav.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileSharedFav.name, data.fileSharedFav.viewerToolbarMore); + }); + + it('File shared, locked - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileSharedLocked.name, data.fileSharedLocked.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileSharedLocked.name, data.fileSharedLocked.viewerToolbarMore); + }); + + it('File shared, favorite, locked - []', async () => { + await testUtil.checkViewerToolbarPrimaryActions(data.fileSharedFavLocked.name, data.fileSharedFavLocked.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileSharedFavLocked.name, data.fileSharedFavLocked.viewerToolbarMore); + }); + }); + + describe('file opened from Search Results', () => { + + beforeAll(async (done) => { + await Utils.pressEscape(); + await page.clickPersonalFiles(); + await searchInput.clickSearchButton(); + await searchInput.checkOnlyFiles(); + await searchInput.searchFor('file-'); + done(); + }); + + afterEach(async (done) => { + await Utils.pressEscape(); + done(); + }); + + it('File Office - []', async () => { + // await searchInput.clickSearchButton(); + // await searchInput.checkOnlyFiles(); + // await searchInput.searchFor('file-'); + + await testUtil.checkViewerToolbarPrimaryActions(data.fileDocx.name, data.fileDocx.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileDocx.name, data.fileDocx.viewerToolbarMore); + }); + + it('File Office, favorite - []', async () => { + // await searchInput.clickSearchButton(); + // await searchInput.checkOnlyFiles(); + // await searchInput.searchFor('file-'); + + await testUtil.checkViewerToolbarPrimaryActions(data.fileDocxFav.name, data.fileDocxFav.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileDocxFav.name, data.fileDocxFav.viewerToolbarMore); + }); + + it('File simple - []', async () => { + // await searchInput.clickSearchButton(); + // await searchInput.checkOnlyFiles(); + // await searchInput.searchFor('file-'); + + await testUtil.checkViewerToolbarPrimaryActions(data.file.name, data.file.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.file.name, data.file.viewerToolbarMore); + }); + + it('File favorite - []', async () => { + // await searchInput.clickSearchButton(); + // await searchInput.checkOnlyFiles(); + // await searchInput.searchFor('file-'); + + await testUtil.checkViewerToolbarPrimaryActions(data.fileFav.name, data.fileFav.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileFav.name, data.fileFav.viewerToolbarMore); + }); + + it('File Office, shared - []', async () => { + // await searchInput.clickSearchButton(); + // await searchInput.checkOnlyFiles(); + // await searchInput.searchFor('file-'); + + await testUtil.checkViewerToolbarPrimaryActions(data.fileDocxShared.name, data.fileDocxShared.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileDocxShared.name, data.fileDocxShared.viewerToolbarMore); + }); + + it('File Office, shared, favorite - []', async () => { + // await searchInput.clickSearchButton(); + // await searchInput.checkOnlyFiles(); + // await searchInput.searchFor('file-'); + + await testUtil.checkViewerToolbarPrimaryActions(data.fileDocxSharedFav.name, data.fileDocxSharedFav.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileDocxSharedFav.name, data.fileDocxSharedFav.viewerToolbarMore); + }); + + it('File shared - []', async () => { + // await searchInput.clickSearchButton(); + // await searchInput.checkOnlyFiles(); + // await searchInput.searchFor('file-'); + + await testUtil.checkViewerToolbarPrimaryActions(data.fileShared.name, data.fileShared.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileShared.name, data.fileShared.viewerToolbarMore); + }); + + it('File shared, favorite - []', async () => { + // await searchInput.clickSearchButton(); + // await searchInput.checkOnlyFiles(); + // await searchInput.searchFor('file-'); + + await testUtil.checkViewerToolbarPrimaryActions(data.fileSharedFav.name, data.fileSharedFav.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileSharedFav.name, data.fileSharedFav.viewerToolbarMore); + }); + + it('File locked - []', async () => { + // await searchInput.clickSearchButton(); + // await searchInput.checkOnlyFiles(); + // await searchInput.searchFor('file-'); + + await testUtil.checkViewerToolbarPrimaryActions(data.fileLocked.name, data.fileLocked.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileLocked.name, data.fileLocked.viewerToolbarMore); + }); + + it('File favorite, locked - []', async () => { + // await searchInput.clickSearchButton(); + // await searchInput.checkOnlyFiles(); + // await searchInput.searchFor('file-'); + + await testUtil.checkViewerToolbarPrimaryActions(data.fileFavLocked.name, data.fileFavLocked.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileFavLocked.name, data.fileFavLocked.viewerToolbarMore); + }); + + it('File shared, locked - []', async () => { + // await searchInput.clickSearchButton(); + // await searchInput.checkOnlyFiles(); + // await searchInput.searchFor('file-'); + + await testUtil.checkViewerToolbarPrimaryActions(data.fileSharedLocked.name, data.fileSharedLocked.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileSharedLocked.name, data.fileSharedLocked.viewerToolbarMore); + }); + + it('File shared, favorite, locked - []', async () => { + // await searchInput.clickSearchButton(); + // await searchInput.checkOnlyFiles(); + // await searchInput.searchFor('file-'); + + await testUtil.checkViewerToolbarPrimaryActions(data.fileSharedFavLocked.name, data.fileSharedFavLocked.viewerToolbarPrimary); + await testUtil.checkViewerToolbarMoreActions(data.fileSharedFavLocked.name, data.fileSharedFavLocked.viewerToolbarMore); + }); + }); +}); diff --git a/e2e/suites/actions-available/special-permissions/test-data-permissions.ts b/e2e/suites/actions-available/special-permissions/test-data-permissions.ts new file mode 100644 index 0000000000..8ee488b663 --- /dev/null +++ b/e2e/suites/actions-available/special-permissions/test-data-permissions.ts @@ -0,0 +1,335 @@ +import { Utils } from '../../../utilities/utils'; + + +// ----- files ----- + +const consumerContextMenu = ['Share', 'Download', 'View', 'Favorite', 'Copy', 'Manage Versions']; +const consumerFavContextMenu = ['Share', 'Download', 'View', 'Remove Favorite', 'Copy', 'Manage Versions']; +const consumerSharedContextMenu = ['Shared Link Settings', 'Download', 'View', 'Favorite', 'Copy', 'Manage Versions']; +const consumerSharedFavContextMenu = ['Shared Link Settings', 'Download', 'View', 'Remove Favorite', 'Copy', 'Manage Versions']; + +const consumerToolbarPrimary = ['Share', 'Download', 'View', 'View Details', 'More Actions']; +const consumerSharedToolbarPrimary = ['Shared Link Settings', 'Download', 'View', 'View Details', 'More Actions']; + +const searchConsumerToolbarPrimary = ['Toggle search filter', 'Share', 'Download', 'View', 'View Details', 'More Actions']; +const searchConsumerSharedToolbarPrimary = ['Toggle search filter', 'Shared Link Settings', 'Download', 'View', 'View Details', 'More Actions']; + +const consumerToolbarMore = ['Favorite', 'Copy', 'Manage Versions']; +const consumerFavToolbarMore = ['Remove Favorite', 'Copy', 'Manage Versions']; + +// ---- VIEWER ---- + +const consumerViewerSharedToolbarPrimary = ['Activate full-screen mode', 'Shared Link Settings', 'Download', 'Print', 'View Details', 'More Actions']; +const consumerViewerToolbarPrimary = ['Activate full-screen mode', 'Share', 'Download', 'Print', 'View Details', 'More Actions']; +const consumerViewerFavToolbarMore = ['Remove Favorite', 'Copy', 'Manage Versions']; +const consumerViewerToolbarMore = ['Favorite', 'Copy', 'Manage Versions']; + +// ---- FAVORITES workarounds ---- + +// TODO: remove 'Move' and 'Delete' when ACA-1737 is done +// TODO: remove 'Upload New Version' when ACA-2175 is done +const favoritesConsumerToolbarMore = ['Upload New Version', 'Remove Favorite', 'Move', 'Copy', 'Delete', 'Manage Versions']; +// TODO: remove 'Move' and 'Delete' when ACA-1737 is done +// TODO: remove 'Upload New Version' when ACA-2175 is done +const favoritesConsumerContextMenu = ['Share', 'Download', 'View', 'Upload New Version', 'Remove Favorite', 'Move', 'Copy', 'Delete', 'Manage Versions']; +// TODO: remove 'Move' and 'Delete' when ACA-1737 is done +// TODO: remove 'Upload New Version' when ACA-2175 is done +// TODO: change 'Share' into 'Shared Link Settings' when ACA-2175 is done +const favoritesConsumerSharedContextMenu = ['Share', 'Download', 'View', 'Upload New Version', 'Remove Favorite', 'Move', 'Copy', 'Delete', 'Manage Versions']; +// TODO: change 'Share' into 'Shared Link Settings' when ACA-2175 is done +const favoritesConsumerSharedToolbarPrimary = ['Share', 'Download', 'View', 'View Details', 'More Actions']; + + +// ---- SHARED FILES workaround ---- + +// TODO: remove 'Upload New Version' when ACA-2173 is done +const sharedConsumerToolbarMore = ['Upload New Version', 'Favorite', 'Copy', 'Manage Versions']; +// TODO: remove 'Upload New Version' when ACA-2173 is done +const sharedConsumerFavToolbarMore = ['Upload New Version', 'Remove Favorite', 'Copy', 'Manage Versions']; +// TODO: remove 'Upload New Version' when ACA-2173 is done +const sharedConsumerContextMenu = ['Shared Link Settings', 'Download', 'View', 'Upload New Version', 'Favorite', 'Copy', 'Manage Versions']; +// TODO: remove 'Upload New Version' when ACA-2173 is done +const sharedConsumerFavContextMenu = ['Shared Link Settings', 'Download', 'View', 'Upload New Version', 'Remove Favorite', 'Copy', 'Manage Versions']; + + +export const fileDocx = { + name: `file-docx-${Utils.random()}.docx`, + description: 'file not shared, not fav, office, not locked', + + contextMenu: consumerContextMenu, + toolbarPrimary: consumerToolbarPrimary, + toolbarMore: consumerToolbarMore, + viewerToolbarPrimary: consumerViewerToolbarPrimary, + viewerToolbarMore: consumerViewerToolbarMore, + + searchToolbarPrimary: searchConsumerToolbarPrimary +}; + +export const fileDocxFav = { + name: `file-docx-fav-${Utils.random()}.docx`, + description: 'file not shared, fav, office, not locked', + + contextMenu: consumerFavContextMenu, + toolbarPrimary: consumerToolbarPrimary, + toolbarMore: consumerFavToolbarMore, + viewerToolbarPrimary: consumerViewerToolbarPrimary, + viewerToolbarMore: consumerViewerFavToolbarMore, + + favoritesToolbarMore: favoritesConsumerToolbarMore, + favoritesContextMenu: favoritesConsumerContextMenu, + + searchToolbarPrimary: searchConsumerToolbarPrimary +}; + +export const file = { + name: `file-${Utils.random()}.txt`, + description: 'file not shared, not fav, not office, not locked', + + contextMenu: consumerContextMenu, + toolbarPrimary: consumerToolbarPrimary, + toolbarMore: consumerToolbarMore, + viewerToolbarPrimary: consumerViewerToolbarPrimary, + viewerToolbarMore: consumerViewerToolbarMore, + + searchToolbarPrimary: searchConsumerToolbarPrimary +}; + +export const fileFav = { + name: `file-fav-${Utils.random()}.txt`, + description: 'file not shared, fav, not office, not locked', + + contextMenu: consumerFavContextMenu, + toolbarPrimary: consumerToolbarPrimary, + toolbarMore: consumerFavToolbarMore, + viewerToolbarPrimary: consumerViewerToolbarPrimary, + viewerToolbarMore: consumerViewerFavToolbarMore, + + favoritesToolbarMore: favoritesConsumerToolbarMore, + favoritesContextMenu: favoritesConsumerContextMenu, + + searchToolbarPrimary: searchConsumerToolbarPrimary +}; + +export const fileDocxShared = { + name: `file-docx-shared-${Utils.random()}.docx`, + description: 'file shared, not fav, office, not locked', + + contextMenu: consumerSharedContextMenu, + toolbarPrimary: consumerSharedToolbarPrimary, + toolbarMore: consumerToolbarMore, + viewerToolbarPrimary: consumerViewerSharedToolbarPrimary, + viewerToolbarMore: consumerViewerToolbarMore, + + sharedToolbarMore: sharedConsumerToolbarMore, + sharedContextMenu: sharedConsumerContextMenu, + + searchToolbarPrimary: searchConsumerSharedToolbarPrimary +}; + +export const fileDocxSharedFav = { + name: `file-docx-shared-fav-${Utils.random()}.docx`, + description: 'file shared, fav, office, not locked', + + contextMenu: consumerSharedFavContextMenu, + toolbarPrimary: consumerSharedToolbarPrimary, + toolbarMore: consumerFavToolbarMore, + viewerToolbarPrimary: consumerViewerSharedToolbarPrimary, + viewerToolbarMore: consumerViewerFavToolbarMore, + + favoritesToolbarMore: favoritesConsumerToolbarMore, + favoritesContextMenu: favoritesConsumerSharedContextMenu, + favoritesToolbarPrimary: favoritesConsumerSharedToolbarPrimary, + + sharedToolbarMore: sharedConsumerFavToolbarMore, + sharedContextMenu: sharedConsumerFavContextMenu, + + searchToolbarPrimary: searchConsumerSharedToolbarPrimary +}; + +export const fileShared = { + name: `file-shared-${Utils.random()}.txt`, + description: 'file shared, not fav, not office, not locked', + + contextMenu: consumerSharedContextMenu, + toolbarPrimary: consumerSharedToolbarPrimary, + toolbarMore: consumerToolbarMore, + viewerToolbarPrimary: consumerViewerSharedToolbarPrimary, + viewerToolbarMore: consumerViewerToolbarMore, + + sharedToolbarMore: sharedConsumerToolbarMore, + sharedContextMenu: sharedConsumerContextMenu, + + searchToolbarPrimary: searchConsumerSharedToolbarPrimary +}; + +export const fileSharedFav = { + name: `file-shared-fav-${Utils.random()}.txt`, + description: 'file shared, fav, not office, not locked', + + contextMenu: consumerSharedFavContextMenu, + toolbarPrimary: consumerSharedToolbarPrimary, + toolbarMore: consumerFavToolbarMore, + viewerToolbarPrimary: consumerViewerSharedToolbarPrimary, + viewerToolbarMore: consumerViewerFavToolbarMore, + + favoritesToolbarMore: favoritesConsumerToolbarMore, + favoritesContextMenu: favoritesConsumerSharedContextMenu, + favoritesToolbarPrimary: favoritesConsumerSharedToolbarPrimary, + + sharedToolbarMore: sharedConsumerFavToolbarMore, + sharedContextMenu: sharedConsumerFavContextMenu, + + searchToolbarPrimary: searchConsumerSharedToolbarPrimary +}; + +export const fileLocked = { + name: `file-locked-${Utils.random()}.txt`, + description: 'file not shared, not fav, not office, locked', + + contextMenu: consumerContextMenu, + toolbarPrimary: consumerToolbarPrimary, + toolbarMore: consumerToolbarMore, + viewerToolbarPrimary: consumerViewerToolbarPrimary, + viewerToolbarMore: consumerViewerToolbarMore, + + searchToolbarPrimary: searchConsumerToolbarPrimary +}; + +export const fileFavLocked = { + name: `file-fav-locked-${Utils.random()}.txt`, + description: 'file not shared, fav, not office, locked', + + contextMenu: consumerFavContextMenu, + toolbarPrimary: consumerToolbarPrimary, + toolbarMore: consumerFavToolbarMore, + viewerToolbarPrimary: consumerViewerToolbarPrimary, + viewerToolbarMore: consumerViewerFavToolbarMore, + + favoritesToolbarMore: favoritesConsumerToolbarMore, + favoritesContextMenu: favoritesConsumerContextMenu, + + searchToolbarPrimary: searchConsumerToolbarPrimary +}; + +export const fileSharedLocked = { + name: `file-shared-locked-${Utils.random()}.txt`, + description: 'file shared, not fav, not office, locked', + + contextMenu: consumerSharedContextMenu, + toolbarPrimary: consumerSharedToolbarPrimary, + toolbarMore: consumerToolbarMore, + viewerToolbarPrimary: consumerViewerSharedToolbarPrimary, + viewerToolbarMore: consumerViewerToolbarMore, + + sharedToolbarMore: sharedConsumerToolbarMore, + sharedContextMenu: sharedConsumerContextMenu, + + searchToolbarPrimary: searchConsumerSharedToolbarPrimary +}; + +export const fileSharedFavLocked = { + name: `file-shared-fav-locked-${Utils.random()}.txt`, + description: 'file shared, fav, not office, locked', + + contextMenu: consumerSharedFavContextMenu, + toolbarPrimary: consumerSharedToolbarPrimary, + toolbarMore: consumerFavToolbarMore, + viewerToolbarPrimary: consumerViewerSharedToolbarPrimary, + viewerToolbarMore: consumerViewerFavToolbarMore, + + favoritesToolbarMore: favoritesConsumerToolbarMore, + favoritesContextMenu: favoritesConsumerSharedContextMenu, + favoritesToolbarPrimary: favoritesConsumerSharedToolbarPrimary, + + sharedToolbarMore: sharedConsumerFavToolbarMore, + sharedContextMenu: sharedConsumerFavContextMenu, + + searchToolbarPrimary: searchConsumerSharedToolbarPrimary +}; + +// ---- folders --- + +const consumerFolderContextMenu = ['Download', 'Favorite', 'Copy']; +const consumerFolderToolbarPrimary = ['Download', 'View Details', 'More Actions']; +const consumerFolderToolbarMore = ['Favorite', 'Copy']; +const searchConsumerFolderToolbarPrimary = ['Toggle search filter', 'Download', 'View Details', 'More Actions']; +const consumerFolderFavContextMenu = ['Download', 'Remove Favorite', 'Copy']; +const consumerFolderFavToolbarMore = ['Remove Favorite', 'Copy']; + +// ---- FAVORITES workarounds ---- + +// TODO: remove 'Edit', 'Move' and 'Delete' when ACA-1737 is done +const favoritesConsumerFolderContextMenu = ['Download', 'Edit', 'Remove Favorite', 'Move', 'Copy', 'Delete']; +// TODO: remove 'Edit', 'Move' and 'Delete' when ACA-1737 is done +const favoritesConsumerFolderToolbarMore = ['Edit', 'Remove Favorite', 'Move', 'Copy', 'Delete']; + +export const folder = { + name: `folder-${Utils.random()}`, + description: 'folder not favorite', + contextMenu: consumerFolderContextMenu, + toolbarPrimary: consumerFolderToolbarPrimary, + toolbarMore: consumerFolderToolbarMore, + + searchToolbarPrimary: searchConsumerFolderToolbarPrimary +}; + +export const folderFav = { + name: `folder-fav-${Utils.random()}`, + description: 'folder favorite', + contextMenu: consumerFolderFavContextMenu, + toolbarPrimary: consumerFolderToolbarPrimary, + toolbarMore: consumerFolderFavToolbarMore, + + favoritesContextMenu: favoritesConsumerFolderContextMenu, + favoritesToolbarMore: favoritesConsumerFolderToolbarMore, + + searchToolbarPrimary: searchConsumerFolderToolbarPrimary, +}; + +export const folderFav2 = { + name: `folder-fav-2-${Utils.random()}`, + description: 'folder 2 favorite' +}; + +// ---- multiple selection --- + +const multipleSelContextMenu = ['Download', 'Favorite', 'Copy']; +const multipleSelAllFavContextMenu = ['Download', 'Remove Favorite', 'Copy']; +const multipleSelToolbarPrimary = ['Download', 'View Details', 'More Actions']; +const multipleSelToolbarMore = ['Favorite', 'Copy']; +const multipleSelAllFavToolbarMore = ['Remove Favorite', 'Copy']; +const searchMultipleSelToolbarPrimary = ['Toggle search filter', 'Download', 'View Details', 'More Actions']; + +// ---- FAVORITES workarounds ---- + +// TODO: remove 'Move' and 'Delete' when ACA-1737 is done +const favoritesMultipleSelContextMenu = ['Download', 'Favorite', 'Move', 'Copy', 'Delete']; +// TODO: remove 'Move' and 'Delete' when ACA-1737 is done +const favoritesMultipleSelToolbarMore = ['Favorite', 'Move', 'Copy', 'Delete']; +// TODO: remove 'Move' and 'Delete' when ACA-1737 is done +const favoritesMultipleSelAllFavContextMenu = ['Download', 'Remove Favorite', 'Move', 'Copy', 'Delete']; +// TODO: remove 'Move' and 'Delete' when ACA-1737 is done +const favoritesMultipleSelAllFavToolbarMore = ['Remove Favorite', 'Move', 'Copy', 'Delete']; + + +export const multipleSel = { + contextMenu: multipleSelContextMenu, + toolbarPrimary: multipleSelToolbarPrimary, + toolbarMore: multipleSelToolbarMore, + + favoritesContextMenu: favoritesMultipleSelContextMenu, + favoritesToolbarMore: favoritesMultipleSelToolbarMore, + + searchToolbarPrimary: searchMultipleSelToolbarPrimary +} + +export const multipleSelAllFav = { + contextMenu: multipleSelAllFavContextMenu, + toolbarPrimary: multipleSelToolbarPrimary, + toolbarMore: multipleSelAllFavToolbarMore, + + favoritesContextMenu: favoritesMultipleSelAllFavContextMenu, + favoritesToolbarMore: favoritesMultipleSelAllFavToolbarMore, + + searchToolbarPrimary: searchMultipleSelToolbarPrimary +} diff --git a/e2e/suites/actions-available/test-util.ts b/e2e/suites/actions-available/test-util.ts new file mode 100644 index 0000000000..1dc54aeb86 --- /dev/null +++ b/e2e/suites/actions-available/test-util.ts @@ -0,0 +1,102 @@ +import { BrowsingPage } from '../../pages/pages'; +import { Viewer } from '../../components/viewer/viewer'; +import { Utils } from '../../utilities/utils'; + +const page = new BrowsingPage(); +const { dataTable, toolbar } = page; +const contextMenu = dataTable.menu; +const viewer = new Viewer(); + + +export async function checkContextMenu(item: string, expectedContextMenu: string[]) { + await dataTable.rightClickOnItem(item); + const actualActions = await contextMenu.getMenuItems(); + expect(actualActions.length).toBe(expectedContextMenu.length, 'Incorrect number of context menu items'); + expect(JSON.stringify(actualActions)).toEqual(JSON.stringify(expectedContextMenu), 'Incorrect context menu actions'); +} + +export async function checkToolbarPrimary(item: string, expectedToolbarPrimary: string[]) { + await dataTable.selectItem(item); + + const actualPrimaryActions = await toolbar.getButtons(); + expect(actualPrimaryActions.length).toBe(expectedToolbarPrimary.length, 'Incorrect number of toolbar primary items'); + expect(JSON.stringify(actualPrimaryActions)).toEqual(JSON.stringify(expectedToolbarPrimary), 'Incorrect toolbar primary actions'); +} + +export async function checkToolbarMoreActions(item: string, expectedToolbarMore: string[]) { + await dataTable.selectItem(item); + + await toolbar.openMoreMenu(); + + const actualMoreActions = await toolbar.menu.getMenuItems(); + expect(actualMoreActions.length).toBe(expectedToolbarMore.length, 'Incorrect number of toolbar More menu items'); + expect(JSON.stringify(actualMoreActions)).toEqual(JSON.stringify(expectedToolbarMore), 'Incorrect toolbar More actions'); + + await toolbar.closeMoreMenu(); +} + +export async function checkMultipleSelContextMenu(items: string[], expectedContextMenu: string[]) { + await dataTable.selectMultipleItems(items); + await dataTable.rightClickOnMultipleSelection(); + + const actualActions = await contextMenu.getMenuItems(); + expect(actualActions.length).toBe(expectedContextMenu.length, 'Incorrect number of context menu items'); + expect(JSON.stringify(actualActions)).toEqual(JSON.stringify(expectedContextMenu), 'Incorrect context menu actions'); +} + +export async function checkMultipleSelToolbarPrimary(items: string[], expectedToolbarPrimary: string[]) { + await dataTable.selectMultipleItems(items); + + const actualPrimaryActions = await toolbar.getButtons(); + expect(actualPrimaryActions.length).toBe(expectedToolbarPrimary.length, 'Incorrect number of toolbar primary items'); + expect(JSON.stringify(actualPrimaryActions)).toEqual(JSON.stringify(expectedToolbarPrimary), 'Incorrect toolbar primary actions'); +} + +export async function checkMultipleSelToolbarMoreActions(items: string[], expectedToolbarMore: string[]) { + await dataTable.selectMultipleItems(items); + + await toolbar.openMoreMenu(); + + const actualMoreActions = await toolbar.menu.getMenuItems(); + expect(actualMoreActions.length).toBe(expectedToolbarMore.length, 'Incorrect number of toolbar More menu items'); + expect(JSON.stringify(actualMoreActions)).toEqual(JSON.stringify(expectedToolbarMore), 'Incorrect toolbar More actions'); + + await toolbar.closeMoreMenu(); +} + +export async function checkViewerToolbarPrimaryActions(item: string, expectedToolbarPrimary: string[]) { + await dataTable.doubleClickOnRowByName(item); + await viewer.waitForViewerToOpen(); + + let actualPrimaryActions = await toolbar.getButtons(); + + actualPrimaryActions = removeClosePreviousNextOldInfo(actualPrimaryActions); + + expect(actualPrimaryActions.length).toBe(expectedToolbarPrimary.length, 'Incorrect number of viewer toolbar primary items'); + expect(JSON.stringify(actualPrimaryActions)).toEqual(JSON.stringify(expectedToolbarPrimary), 'Incorrect viewer toolbar primary actions'); + + await Utils.pressEscape(); +} + +export async function checkViewerToolbarMoreActions(item: string, expectedToolbarMore: string[]) { + await dataTable.doubleClickOnRowByName(item); + await viewer.waitForViewerToOpen(); + await toolbar.openMoreMenu(); + + const actualMoreActions = await toolbar.menu.getMenuItems(); + + expect(actualMoreActions.length).toBe(expectedToolbarMore.length, 'Incorrect number of toolbar More menu items'); + expect(JSON.stringify(actualMoreActions)).toEqual(JSON.stringify(expectedToolbarMore), 'Incorrect toolbar More actions'); + + await toolbar.closeMoreMenu(); + await Utils.pressEscape(); +} + + +function removeClosePreviousNextOldInfo(actions: string[]) { + return actions.filter(elem => { + if ( (elem !== 'Close') && (elem !== 'Previous File') && (elem !== 'Next File') && (elem !== 'View details')) { + return elem; + } + }); +} diff --git a/e2e/suites/actions-available/toolbar-multiple-selection.test.ts b/e2e/suites/actions-available/toolbar-multiple-selection.test.ts deleted file mode 100755 index d151f7f9f7..0000000000 --- a/e2e/suites/actions-available/toolbar-multiple-selection.test.ts +++ /dev/null @@ -1,703 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2019 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { browser, protractor } from 'protractor'; -import { LoginPage, BrowsingPage, SearchResultsPage } from '../../pages/pages'; -import { SITE_VISIBILITY } from '../../configs'; -import { RepoClient } from '../../utilities/repo-client/repo-client'; -import { Utils } from '../../utilities/utils'; - -describe('Toolbar actions - multiple selection : ', () => { - const username = `user-${Utils.random()}`; - - const parent = `parent-${Utils.random()}`; let parentId; - - const file1 = `my-file1-${Utils.random()}.txt`; let file1Id; - const file2 = `my-file2-${Utils.random()}.txt`; let file2Id; - - const folder1 = `my-folder1-${Utils.random()}`; let folder1Id; - const folder2 = `my-folder2-${Utils.random()}`; let folder2Id; - - const fileForDelete1 = `file-${Utils.random()}.txt`; let fileForDelete1Id; - const fileForDelete2 = `file-${Utils.random()}.txt`; let fileForDelete2Id; - const folderForDelete1 = `folder-${Utils.random()}`; let folderForDelete1Id; - const folderForDelete2 = `folder-${Utils.random()}`; let folderForDelete2Id; - - const siteName = `site-${Utils.random()}`; - const file1InSite = `my-fileInSite1-${Utils.random()}.txt`; - const file2InSite = `my-fileInSite2-${Utils.random()}.txt`; - const folder1InSite = `my-folderInSite1-${Utils.random()}`; - const folder2InSite = `my-folderInSite2-${Utils.random()}`; - const fileLocked1InSite = `my-fileLockedInSite1-${Utils.random()}.txt`; let fileLocked1InSiteId; - const fileLocked2InSite = `my-fileLockedInSite2-${Utils.random()}.txt`; let fileLocked2InSiteId; - - const fileLocked1 = `my-fileLocked1-${Utils.random()}.txt`; let fileLocked1Id; - const fileLocked2 = `my-fileLocked2-${Utils.random()}.txt`; let fileLocked2Id; - - const apis = { - admin: new RepoClient(), - user: new RepoClient(username, username) - }; - - const loginPage = new LoginPage(); - const page = new BrowsingPage(); - const { dataTable, toolbar } = page; - const searchResultsPage = new SearchResultsPage(); - const { searchInput } = searchResultsPage.header; - - beforeAll(async (done) => { - await apis.admin.people.createUser({ username }); - - parentId = (await apis.user.nodes.createFolder(parent)).entry.id; - - file1Id = (await apis.user.nodes.createFile(file1, parentId)).entry.id; - file2Id = (await apis.user.nodes.createFile(file2, parentId)).entry.id; - folder1Id = (await apis.user.nodes.createFolder(folder1, parentId)).entry.id; - folder2Id = (await apis.user.nodes.createFolder(folder2, parentId)).entry.id; - fileForDelete1Id = (await apis.user.nodes.createFile(fileForDelete1, parentId)).entry.id; - fileForDelete2Id = (await apis.user.nodes.createFile(fileForDelete2, parentId)).entry.id; - folderForDelete1Id = (await apis.user.nodes.createFolder(folderForDelete1, parentId)).entry.id; - folderForDelete2Id = (await apis.user.nodes.createFolder(folderForDelete2, parentId)).entry.id; - fileLocked1Id = (await apis.user.nodes.createFile(fileLocked1, parentId)).entry.id; - fileLocked2Id = (await apis.user.nodes.createFile(fileLocked2, parentId)).entry.id; - await apis.user.nodes.lockFile(fileLocked1Id); - await apis.user.nodes.lockFile(fileLocked2Id); - - await apis.user.shared.shareFilesByIds([file1Id, file2Id, fileLocked1Id, fileLocked2Id]); - await apis.user.shared.waitForApi({ expect: 4 }); - - await apis.user.favorites.addFavoritesByIds('file', [file1Id, file2Id, fileLocked1Id, fileLocked2Id]); - await apis.user.favorites.addFavoritesByIds('folder', [folder1Id, folder2Id]); - await apis.user.favorites.waitForApi({ expect: 6 }); - - await apis.user.nodes.deleteNodesById([fileForDelete1Id, fileForDelete2Id, folderForDelete1Id, folderForDelete2Id], false); - await apis.user.trashcan.waitForApi({ expect: 4 }); - - await apis.user.sites.createSite(siteName, SITE_VISIBILITY.PRIVATE); - const docLibId = await apis.user.sites.getDocLibId(siteName); - await apis.user.nodes.createFile(file1InSite, docLibId); - await apis.user.nodes.createFile(file2InSite, docLibId); - await apis.user.nodes.createFolder(folder1InSite, docLibId); - await apis.user.nodes.createFolder(folder2InSite, docLibId); - fileLocked1InSiteId = (await apis.user.nodes.createFile(fileLocked1InSite, docLibId)).entry.id; - fileLocked2InSiteId = (await apis.user.nodes.createFile(fileLocked2InSite, docLibId)).entry.id; - - await apis.user.nodes.lockFile(fileLocked1InSiteId); - await apis.user.nodes.lockFile(fileLocked2InSiteId); - - await apis.user.search.waitForApi(username, { expect: 6 }); - - await loginPage.loginWith(username); - done(); - }); - - afterAll(async (done) => { - await Promise.all([ - apis.user.nodes.deleteNodeById(parentId), - apis.user.trashcan.emptyTrash(), - apis.user.sites.deleteSite(siteName) - ]); - done(); - }); - - describe('on Personal Files', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await dataTable.clearSelection(); - await page.clickPersonalFilesAndWait(); - await dataTable.doubleClickOnRowByName(parent); - await dataTable.waitForBody(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('Unselect items with single click - [C280458]', async () => { - await dataTable.selectMultipleItems([file1, file2, folder1, folder2]); - - expect(await dataTable.countSelectedRows()).toEqual(4, 'incorrect selected rows number'); - - await dataTable.selectItem(file1); - - expect(await dataTable.countSelectedRows()).toEqual(1, 'incorrect selected rows number'); - }); - - it('Select / unselect selected items by CMD+click - [C217110]', async () => { - await browser.actions().sendKeys(protractor.Key.COMMAND).perform(); - await dataTable.selectItem(file1); - await dataTable.selectItem(file2); - await dataTable.selectItem(folder1); - await dataTable.selectItem(folder2); - await browser.actions().sendKeys(protractor.Key.NULL).perform(); - - expect(await dataTable.countSelectedRows()).toEqual(4, 'incorrect selected rows number'); - - await browser.actions().sendKeys(protractor.Key.COMMAND).perform(); - await dataTable.selectItem(file1); - await dataTable.selectItem(file2); - await browser.actions().sendKeys(protractor.Key.NULL).perform(); - - expect(await dataTable.countSelectedRows()).toEqual(2, 'incorrect selected rows number'); - }); - - it('correct actions appear when multiple files are selected - [C217112]', async () => { - await dataTable.selectMultipleItems([file1, file2]); - - expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); - expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for selected files`); - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for selected files`); - expect(await toolbar.menu.isRemoveFavoritePresent()).toBe(true, `Remove Favorite is not displayed for selected files`); - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - - await toolbar.closeMoreMenu(); - }); - - it('correct actions appear when multiple locked files are selected - [C297619]', async () => { - await dataTable.selectMultipleItems([fileLocked1, fileLocked2]); - - expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); - expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for selected files`); - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for selected files`); - expect(await toolbar.menu.isRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for selected files`); - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - - await toolbar.closeMoreMenu(); - }); - - it('correct actions appear when multiple folders are selected - [C280459]', async () => { - await dataTable.selectMultipleItems([folder1, folder2]); - - expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); - expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for selected files`); - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for selected files`); - expect(await toolbar.menu.isRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for selected files`); - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - - await toolbar.closeMoreMenu(); - }); - - it('correct actions appear when both files and folders are selected - [C280460]', async () => { - await dataTable.selectMultipleItems([file1, file2, folder1, folder2]); - - expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); - expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for selected files`); - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for selected files`); - expect(await toolbar.menu.isRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for selected files`); - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - - await toolbar.closeMoreMenu(); - }); - }); - - describe('on File Libraries', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await page.goToMyLibrariesAndWait(); - await dataTable.doubleClickOnRowByName(siteName); - await dataTable.waitForHeader(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('correct actions appear when multiple files are selected - [C280461]', async () => { - await dataTable.selectMultipleItems([file1InSite, file2InSite]); - - expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed for selected files'); - expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed for selected files'); - expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed for selected files'); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for selected files`); - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for selected files`); - expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - - await toolbar.closeMoreMenu(); - }); - - it('correct actions appear when multiple locked files are selected - [C297620]', async () => { - await dataTable.selectMultipleItems([fileLocked1InSite, fileLocked2InSite]); - - expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed for selected files'); - expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed for selected files'); - expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed for selected files'); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for selected files`); - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for selected files`); - expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - - await toolbar.closeMoreMenu(); - }); - - it('correct actions appear when multiple folders are selected - [C280462]', async () => { - await dataTable.selectMultipleItems([folder1InSite, folder2InSite]); - - expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); - expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for selected files`); - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for selected files`); - expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - - await toolbar.closeMoreMenu(); - }); - - it('correct actions appear when both files and folders are selected - [C280463]', async () => { - await dataTable.selectMultipleItems([file1InSite, file2InSite, folder1InSite, folder2InSite]); - - expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); - expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for selected files`); - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for selected files`); - expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - - await toolbar.closeMoreMenu(); - }); - }); - - describe('on Shared Files', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await dataTable.clearSelection(); - await page.clickSharedFilesAndWait(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('correct actions appear when multiple files are selected - [C280467]', async () => { - await dataTable.selectMultipleItems([file1, file2]); - - expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); - expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed for selected files'); - expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed for selected files'); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for selected files`); - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for selected files`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for selected files`); - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - - await toolbar.closeMoreMenu(); - }); - - it('correct actions appear when multiple locked files are selected - [C297623]', async () => { - await dataTable.selectMultipleItems([fileLocked1, fileLocked2]); - - expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); - expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed for selected files'); - expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed for selected files'); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for selected files`); - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for selected files`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for selected files`); - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - - await toolbar.closeMoreMenu(); - }); - }); - - describe('on Recent Files', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await dataTable.clearSelection(); - await page.clickRecentFilesAndWait(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('correct actions appear when multiple files are selected - [C280468]', async () => { - await dataTable.selectMultipleItems([file1, file2]); - - expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); - expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for selected files`); - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for selected files`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for selected files`); - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - - await toolbar.closeMoreMenu(); - }); - - it('correct actions appear when multiple locked files are selected - [C297624]', async () => { - await dataTable.selectMultipleItems([fileLocked1, fileLocked2]); - - expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); - expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for selected files`); - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for selected files`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for selected files`); - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - - await toolbar.closeMoreMenu(); - }); - }); - - describe('on Favorites', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await dataTable.clearSelection(); - await page.clickFavoritesAndWait(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('correct actions appear when multiple files are selected - [C280469]', async () => { - await dataTable.selectMultipleItems([file1, file2]); - - expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); - expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for selected files`); - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for selected files`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for selected files`); - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - - await toolbar.closeMoreMenu(); - }); - - it('correct actions appear when multiple locked files are selected - [C297625]', async () => { - await dataTable.selectMultipleItems([fileLocked1, fileLocked2]); - - expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); - expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for selected files`); - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for selected files`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for selected files`); - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - - await toolbar.closeMoreMenu(); - }); - - it('correct actions appear when multiple folders are selected - [C280470]', async () => { - await dataTable.selectMultipleItems([folder1, folder2]); - - expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); - expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for selected files`); - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for selected files`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for selected files`); - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - - await toolbar.closeMoreMenu(); - }); - - it('correct actions appear when both files and folders are selected - [C280471]', async () => { - await dataTable.selectMultipleItems([file1, file2, folder1, folder2]); - - expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); - expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed for selected files'); - expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for selected files`); - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for selected files`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for selected files`); - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - - await toolbar.closeMoreMenu(); - }); - }); - - describe('on Trash', () => { - beforeEach(async (done) => { - await page.clickTrashAndWait(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('correct actions appear when multiple files are selected - [C280472]', async () => { - await dataTable.selectMultipleItems([fileForDelete1, fileForDelete2]); - - expect(await toolbar.isButtonPresent('Permanently Delete')).toBe(true, 'Permanently delete is displayed'); - expect(await toolbar.isButtonPresent('Restore')).toBe(true, 'Restore is not displayed'); - }); - - it('correct actions appear when multiple folders are selected - [C280473]', async () => { - await dataTable.selectMultipleItems([folderForDelete1, folderForDelete2]); - - expect(await toolbar.isButtonPresent('Permanently Delete')).toBe(true, 'Permanently delete is displayed'); - expect(await toolbar.isButtonPresent('Restore')).toBe(true, 'Restore is not displayed'); - }); - - it('correct actions appear when both files and folders are selected - [C280474]', async () => { - await dataTable.selectMultipleItems([fileForDelete1, fileForDelete2, folderForDelete1, folderForDelete2]); - - expect(await toolbar.isButtonPresent('Permanently Delete')).toBe(true, 'Permanently delete is displayed'); - expect(await toolbar.isButtonPresent('Restore')).toBe(true, 'Restore is not displayed'); - }); - }); - - describe('on Search Results', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await page.clickPersonalFilesAndWait(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('correct actions appear when multiple files are selected - [C291820]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkOnlyFiles(); - await searchInput.searchFor('my-fileInSite'); - await dataTable.selectMultipleItems([file1InSite, file2InSite]); - - expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed for selected files'); - expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed for selected files'); - expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed for selected files'); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); - expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for selected files`); - expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for selected files`); - expect(await toolbar.menu.isToggleFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - - await toolbar.closeMoreMenu(); - }); - - it('correct actions appear when multiple locked files are selected - [C297626]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkOnlyFiles(); - await searchInput.searchFor('my-fileLockedInSite'); - await dataTable.selectMultipleItems([fileLocked1InSite, fileLocked2InSite]); - - expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed for selected files'); - expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed for selected files'); - expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed for selected files'); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); - expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for selected files`); - expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for selected files`); - expect(await toolbar.menu.isToggleFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - - await toolbar.closeMoreMenu(); - }); - - it('correct actions appear when multiple folders are selected - [C291821]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkOnlyFolders(); - await searchInput.searchFor('my-folderInSite'); - await dataTable.selectMultipleItems([folder1InSite, folder2InSite]); - - expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); - expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); - expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for selected files`); - expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for selected files`); - expect(await toolbar.menu.isToggleFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - - await toolbar.closeMoreMenu(); - }); - - it('correct actions appear when both files and folders are selected - [C291822]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkFilesAndFolders(); - await searchInput.searchFor('my-f'); - await dataTable.selectMultipleItems([file1InSite, file2InSite, folder1InSite, folder2InSite]); - - expect(await toolbar.isViewPresent()).toBe(false, 'View is displayed'); - expect(await toolbar.isDownloadPresent()).toBe(true, 'Download is not displayed'); - expect(await toolbar.isEditFolderPresent()).toBe(false, 'Edit folder is displayed'); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for selected files`); - expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for selected files`); - expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for selected files`); - expect(await toolbar.menu.isToggleFavoritePresent()).toBe(true, `Favorite is not displayed for selected files`); - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed`); - - await toolbar.closeMoreMenu(); - }); - }); -}); diff --git a/e2e/suites/actions-available/toolbar-single-selection.test.ts b/e2e/suites/actions-available/toolbar-single-selection.test.ts deleted file mode 100755 index 6d65d96092..0000000000 --- a/e2e/suites/actions-available/toolbar-single-selection.test.ts +++ /dev/null @@ -1,760 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2019 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { LoginPage, BrowsingPage, SearchResultsPage } from '../../pages/pages'; -import { SITE_VISIBILITY } from '../../configs'; -import { RepoClient } from '../../utilities/repo-client/repo-client'; -import { Utils } from '../../utilities/utils'; - -describe('Toolbar actions - single selection : ', () => { - const username = `user-${Utils.random()}`; - - const fileUser = `fileUser-${Utils.random()}.txt`; let fileUserId; - const folderUser = `folderUser-${Utils.random()}`; let folderUserId; - const fileForDelete = `fileForDelete-${Utils.random()}.txt`; let fileForDeleteId; - const folderForDelete = `folderForDelete-${Utils.random()}`; let folderForDeleteId; - const fileLocked = `fileLocked-${Utils.random()}.txt`; let fileLockedId; - - const siteName = `site-${Utils.random()}`; - const fileInSite = `file-site-${Utils.random()}.txt`; - const fileLockedInSite = `file-locked-site-${Utils.random()}.txt`; let fileLockedInSiteId; - const folderInSite = `folder-site-${Utils.random()}`; - - const adminPublic = `admin-public-${Utils.random()}`; - const adminModerated = `admin-moderated-${Utils.random()}`; - - const apis = { - admin: new RepoClient(), - user: new RepoClient(username, username) - }; - - const loginPage = new LoginPage(); - const page = new BrowsingPage(); - const { dataTable, toolbar } = page; - const searchResultsPage = new SearchResultsPage(); - const { searchInput } = searchResultsPage.header; - - beforeAll(async (done) => { - await apis.admin.people.createUser({ username }); - - fileUserId = (await apis.user.nodes.createFile(fileUser)).entry.id; - fileForDeleteId = (await apis.user.nodes.createFile(fileForDelete)).entry.id; - folderForDeleteId = (await apis.user.nodes.createFolder(folderForDelete)).entry.id; - folderUserId = (await apis.user.nodes.createFolder(folderUser)).entry.id; - fileLockedId = (await apis.user.nodes.createFile(fileLocked)).entry.id; - - await apis.user.shared.shareFileById(fileUserId); - await apis.user.shared.shareFileById(fileLockedId); - await apis.user.shared.waitForApi({ expect: 2 }); - - await apis.user.favorites.addFavoriteById('file', fileUserId); - await apis.user.favorites.addFavoriteById('folder', folderUserId); - await apis.user.favorites.addFavoriteById('file', fileLockedId); - await apis.user.favorites.waitForApi({ expect: 3 }); - - await apis.user.nodes.lockFile(fileLockedId); - - await apis.user.sites.createSite(siteName, SITE_VISIBILITY.PRIVATE); - const docLibId = await apis.user.sites.getDocLibId(siteName); - await apis.user.nodes.createFile(fileInSite, docLibId); - fileLockedInSiteId = (await apis.user.nodes.createFile(fileLockedInSite, docLibId)).entry.id; - await apis.user.nodes.createFolder(folderInSite, docLibId); - - await apis.user.nodes.lockFile(fileLockedInSiteId); - - await apis.user.nodes.deleteNodeById(fileForDeleteId, false); - await apis.user.nodes.deleteNodeById(folderForDeleteId, false); - - await apis.admin.sites.createSite(adminPublic); - await apis.admin.sites.createSite(adminModerated, SITE_VISIBILITY.MODERATED); - await apis.user.favorites.addFavoriteById('site', adminPublic); - await apis.user.favorites.addFavoriteById('site', adminModerated); - await apis.user.sites.requestToJoin(adminModerated); - - await apis.user.queries.waitForSites(siteName, { expect: 1 }); - - await loginPage.loginWith(username); - done(); - }); - - afterAll(async (done) => { - await Promise.all([ - apis.user.nodes.deleteNodeById(fileUserId), - apis.user.nodes.deleteNodeById(folderUserId), - apis.user.sites.deleteSite(siteName), - apis.admin.sites.deleteSite(adminPublic), - apis.admin.sites.deleteSite(adminModerated), - apis.user.trashcan.emptyTrash() - ]); - done(); - }); - - describe('on Personal Files', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await dataTable.clearSelection(); - await page.clickPersonalFilesAndWait(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('selected row is marked with a check circle icon - [C213134]', async () => { - await dataTable.selectItem(fileUser); - - expect(await dataTable.hasCheckMarkIcon(fileUser)).toBe(true, 'check mark missing'); - }); - - it('actions are not displayed when no item is selected - [C213120]', async () => { - expect(await toolbar.isEmpty()).toBe(true, `actions displayed though nothing selected`); - }); - - it('correct actions appear when a file is selected - [C213122]', async () => { - await dataTable.selectItem(fileUser); - - expect(await toolbar.isEmpty()).toBe(false, `actions not displayed for ${fileUser}`); - expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileUser}`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileUser}`); - expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileUser}`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed for ${fileUser}`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${fileUser}`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileUser}`); - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${fileUser}`); - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for ${fileUser}`); - expect(await toolbar.menu.isRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${fileUser}`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed for ${fileUser}`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload New Version is not displayed for ${fileUser}`); - - await toolbar.closeMoreMenu(); - }); - - it('correct actions appear when a locked file is selected - [C297612]', async () => { - await dataTable.selectItem(fileLocked); - - expect(await toolbar.isEmpty()).toBe(false, `actions not displayed for ${fileLocked}`); - expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileLocked}`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLocked}`); - expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLocked}`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileLocked}`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed for ${fileLocked}`); - - await toolbar.closeMoreMenu(); - }); - - it('correct actions appear when a folder is selected - [C213123]', async () => { - await dataTable.selectItem(folderUser); - - expect(await toolbar.isEmpty()).toBe(false, `actions not displayed for ${folderUser}`); - expect(await toolbar.isViewPresent()).toBe(false, `View is displayed for ${folderUser}`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not enabled for ${folderUser}`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditFolderPresent()).toBe(true, `Edit folder is not displayed for ${folderUser}`); - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${folderUser}`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${folderUser}`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${folderUser}`); - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${folderUser}`); - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for ${folderUser}`); - expect(await toolbar.menu.isRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${folderUser}`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed for ${folderUser}`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed for ${folderUser}`); - - await toolbar.closeMoreMenu(); - }); - }); - - describe('on File Libraries', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await page.goToMyLibrariesAndWait(); - await dataTable.doubleClickOnRowByName(siteName); - await dataTable.waitForHeader(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('actions are not displayed when no item is selected - [C280439]', async () => { - expect(await toolbar.isEmpty()).toBe(true, `actions displayed though nothing selected`); - }); - - it('correct actions appear when a file is selected - [C280440]', async () => { - await dataTable.selectItem(fileInSite); - - expect(await toolbar.isEmpty()).toBe(false, `actions not displayed for ${fileInSite}`); - expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileInSite}`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileInSite}`); - expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileInSite}`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed for ${fileInSite}`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${fileInSite}`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileInSite}`); - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${fileInSite}`); - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for ${fileInSite}`); - expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${fileInSite}`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed for ${fileInSite}`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed for ${fileInSite}`); - - await toolbar.closeMoreMenu(); - }); - - it('correct actions appear when a locked file is selected - [C297614]', async () => { - await dataTable.selectItem(fileLockedInSite); - - expect(await toolbar.isEmpty()).toBe(false, `actions not displayed for ${fileLockedInSite}`); - expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileLockedInSite}`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLockedInSite}`); - expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLockedInSite}`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileLockedInSite}`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed for ${fileLockedInSite}`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLockedInSite}`); - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${fileLockedInSite}`); - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for ${fileLockedInSite}`); - expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${fileLockedInSite}`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed for ${fileLockedInSite}`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed for ${fileLockedInSite}`); - - await toolbar.closeMoreMenu(); - }); - - it('correct actions appear when a folder is selected - [C280441]', async () => { - await dataTable.selectItem(folderInSite); - - expect(await toolbar.isEmpty()).toBe(false, `actions not displayed for ${folderInSite}`); - expect(await toolbar.isViewPresent()).toBe(false, `View is displayed for ${folderInSite}`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not enabled for ${folderInSite}`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditFolderPresent()).toBe(true, `Edit folder is not displayed for ${folderInSite}`); - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${folderInSite}`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${folderInSite}`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${folderInSite}`); - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${folderInSite}`); - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for ${folderInSite}`); - expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed for ${folderInSite}`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed for ${folderInSite}`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed for ${folderInSite}`); - - await toolbar.closeMoreMenu(); - }); - }); - - describe('on a library', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - await page.clickPersonalFiles(); - done(); - }); - - it('Available actions for a library - My Libraries - [C213135]', async () => { - await page.goToMyLibrariesAndWait(); - await dataTable.selectItem(siteName); - - expect(await toolbar.isEmpty()).toBe(false, 'toolbar not displayed'); - expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${siteName}`); - expect(await toolbar.isButtonPresent('Leave library')).toBe(true, `Leave is not displayed for ${siteName}`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${siteName}`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${siteName}`); - - await toolbar.closeMoreMenu(); - }); - - it('Available actions for a library - Favorite Libraries - user is a member - [C289892]', async () => { - await page.goToFavoriteLibrariesAndWait(); - await dataTable.selectItem(siteName); - - expect(await toolbar.isEmpty()).toBe(false, 'toolbar not displayed'); - expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${siteName}`); - expect(await toolbar.isButtonPresent('Leave library')).toBe(true, `Leave is not displayed for ${siteName}`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${siteName}`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${siteName}`); - - await toolbar.closeMoreMenu(); - }); - - it('Available actions for a library - Favorite Libraries - user is not a member - [C290090]', async () => { - await page.goToFavoriteLibrariesAndWait(); - await dataTable.selectItem(adminPublic); - - expect(await toolbar.isEmpty()).toBe(false, 'toolbar not displayed'); - expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${adminPublic}`); - expect(await toolbar.isButtonPresent('Join')).toBe(true, `Join is not displayed for ${adminPublic}`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${adminPublic}`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${adminPublic}`); - - await toolbar.closeMoreMenu(); - }); - - it('Available actions for a moderated library - Favorite Libraries - user requested to join - [C290091]', async () => { - await page.goToFavoriteLibrariesAndWait(); - await dataTable.selectItem(adminModerated); - - expect(await toolbar.isEmpty()).toBe(false, 'toolbar not displayed'); - expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${adminModerated}`); - expect(await toolbar.isButtonPresent('Cancel Join Request')).toBe(true, `Cancel join is not displayed for ${adminModerated}`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${adminModerated}`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${adminModerated}`); - - await toolbar.closeMoreMenu(); - }); - - it('Available actions for a library - Search Results - [C290084]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkLibraries(); - await searchInput.searchFor(siteName); - await dataTable.selectItem(siteName); - - expect(await toolbar.isEmpty()).toBe(false, 'toolbar not displayed'); - expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${siteName}`); - expect(await toolbar.isButtonPresent('Leave library')).toBe(true, `Leave is not displayed for ${siteName}`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${siteName}`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${siteName}`); - - await toolbar.closeMoreMenu(); - }); - - it('Available actions for a library - Search Results - user is not a member - [C290085]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkLibraries(); - await searchInput.searchFor(adminPublic); - await dataTable.selectItem(adminPublic); - - expect(await toolbar.isEmpty()).toBe(false, 'toolbar not displayed'); - expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${adminPublic}`); - expect(await toolbar.isButtonPresent('Join')).toBe(true, `Join is not displayed for ${adminPublic}`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${adminPublic}`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${adminPublic}`); - - await toolbar.closeMoreMenu(); - }); - - it('Available actions for a moderated library - Search Results - user requested to join - [C290086]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkLibraries(); - await searchInput.searchFor(adminModerated); - await dataTable.selectItem(adminModerated); - - expect(await toolbar.isEmpty()).toBe(false, 'toolbar not displayed'); - expect(await toolbar.isViewDetailsPresent()).toBe(true, `View details is not displayed for ${adminModerated}`); - expect(await toolbar.isButtonPresent('Cancel Join Request')).toBe(true, `Cancel join is not displayed for ${adminModerated}`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${adminModerated}`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${adminModerated}`); - - await toolbar.closeMoreMenu(); - }); - }); - - describe('on Shared Files', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await page.clickSharedFilesAndWait(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('actions are not displayed when no item is selected - [C280445]', async () => { - expect(await toolbar.isEmpty()).toBe(true, `actions displayed though nothing selected`); - }); - - it('correct actions appear when a file is selected - [C286265]', async () => { - await page.dataTable.selectItem(fileUser); - - expect(await toolbar.isEmpty()).toBe(false, `actions not displayed for ${fileUser}`); - expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileUser}`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileUser}`); - expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileUser}`); - expect(await toolbar.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed for ${fileUser}`); - - await toolbar.openMoreMenu(); - - // TODO: change expect to true when ACA-2173 is done - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileUser}`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${fileUser}`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileUser}`); - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${fileUser}`); - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for ${fileUser}`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${fileUser}`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed for ${fileUser}`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed for ${fileUser}`); - - await toolbar.closeMoreMenu(); - }); - - it('correct actions appear when a locked file is selected - [C297615]', async () => { - await page.dataTable.selectItem(fileLocked); - - expect(await toolbar.isEmpty()).toBe(false, `actions not displayed for ${fileLocked}`); - expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileLocked}`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLocked}`); - expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLocked}`); - expect(await toolbar.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed for ${fileLocked}`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileLocked}`); - // TODO: change expect to true when ACA-2173 is done - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${fileLocked}`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed for ${fileLocked}`); - - await toolbar.closeMoreMenu(); - }); - }); - - describe('on Recent Files', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await page.clickRecentFilesAndWait(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('actions are not displayed when no item is selected - [C280447]', async () => { - expect(await toolbar.isEmpty()).toBe(true, `actions displayed though nothing selected`); - }); - - it('correct actions appear when a file is selected - [C280448]', async () => { - await dataTable.selectItem(fileUser); - - expect(await toolbar.isEmpty()).toBe(false, `actions not displayed for ${fileUser}`); - expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileUser}`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileUser}`); - expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileUser}`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed for ${fileUser}`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${fileUser}`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileUser}`); - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${fileUser}`); - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for ${fileUser}`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${fileUser}`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed for ${fileUser}`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed for ${fileUser}`); - - await toolbar.closeMoreMenu(); - }); - - it('correct actions appear when a locked file is selected - [C297616]', async () => { - await dataTable.selectItem(fileLocked); - - expect(await toolbar.isEmpty()).toBe(false, `actions not displayed for ${fileLocked}`); - expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileLocked}`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLocked}`); - expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLocked}`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileLocked}`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed for ${fileLocked}`); - - await toolbar.closeMoreMenu(); - }); - }); - - describe('on Favorites', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await page.clickFavoritesAndWait(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('actions are not displayed when no item is selected - [C280449]', async () => { - expect(await toolbar.isEmpty()).toBe(true, `actions displayed though nothing selected`); - }); - - it('correct actions appear when a file is selected - [C280450]', async () => { - await dataTable.selectItem(fileUser); - - expect(await toolbar.isEmpty()).toBe(false, `actions not displayed for ${fileUser}`); - expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileUser}`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileUser}`); - expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileUser}`); - - await toolbar.openMoreMenu(); - - // TODO: change expect to true when ACA-2174 is done - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileUser}`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${fileUser}`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileUser}`); - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${fileUser}`); - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for ${fileUser}`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${fileUser}`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed for ${fileUser}`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed for ${fileUser}`); - - await toolbar.closeMoreMenu(); - }); - - it('correct actions appear when a locked file is selected - [C297617]', async () => { - await dataTable.selectItem(fileLocked); - - expect(await toolbar.isEmpty()).toBe(false, `actions not displayed for ${fileLocked}`); - expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileLocked}`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLocked}`); - expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLocked}`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileLocked}`); - // TODO: change expect to true when ACA-2174 is done - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${fileLocked}`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed for ${fileLocked}`); - - await toolbar.closeMoreMenu(); - }); - - it('correct actions appear when a folder is selected - [C280451]', async () => { - await dataTable.selectItem(folderUser); - - expect(await toolbar.isEmpty()).toBe(false, `actions not displayed for ${folderUser}`); - expect(await toolbar.isViewPresent()).toBe(false, `View is displayed for ${folderUser}`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not enabled for ${folderUser}`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditFolderPresent()).toBe(true, `Edit folder is not displayed for ${folderUser}`); - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${folderUser}`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${folderUser}`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${folderUser}`); - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed for ${folderUser}`); - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed for ${folderUser}`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${folderUser}`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed for ${folderUser}`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed for ${folderUser}`); - - await toolbar.closeMoreMenu(); - }); - }); - - describe('on Trash', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await page.clickTrashAndWait(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('actions are not displayed when no item is selected - [C280452]', async () => { - expect(await toolbar.isEmpty()).toBe(true, `actions displayed though nothing selected`); - }); - - it('correct actions appear when a file is selected - [C280453]', async () => { - await dataTable.selectItem(fileForDelete); - - expect(await toolbar.isEmpty()).toBe(false, `actions not displayed for ${fileForDelete}`); - expect(await toolbar.isPermanentlyDeletePresent()).toBe(true, `Permanently delete is not displayed for file`); - expect(await toolbar.isRestorePresent()).toBe(true, `Restore is not displayed for file`); - }); - - it('correct actions appear when a folder is selected - [C280454]', async () => { - await dataTable.selectItem(folderForDelete); - - expect(await toolbar.isEmpty()).toBe(false, `actions not displayed for ${folderForDelete}`); - expect(await toolbar.isPermanentlyDeletePresent()).toBe(true, `Permanently delete is displayed for folder`); - expect(await toolbar.isRestorePresent()).toBe(true, `Restore is not displayed for folder`); - }); - }); - - describe('on Search Results', () => { - beforeEach(async (done) => { - await Utils.pressEscape(); - await page.clickPersonalFilesAndWait(); - done(); - }); - - afterAll(async (done) => { - await Utils.pressEscape(); - done(); - }); - - it('nodes actions are not displayed when no item is selected - [C291815]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkFilesAndFolders(); - await searchInput.searchFor(fileInSite); - - expect(await toolbar.isToggleSearchFiltersPresent()).toBe(true, `Search filter toggle is not displayed`); - expect(await toolbar.numberOfAvailableActions()).toBe(1, `more than 1 action is present`); - }); - - it('correct actions appear when a file is selected - [C291816]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkOnlyFiles(); - await searchInput.searchFor(fileUser); - await dataTable.selectItem(fileUser); - - expect(await toolbar.isEmpty()).toBe(false, `actions not displayed for ${fileUser}`); - expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileUser}`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileUser}`); - expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileUser}`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed for ${fileUser}`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${fileUser}`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileUser}`); - expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${fileUser}`); - expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${fileUser}`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${fileUser}`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed for ${fileUser}`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed for ${fileUser}`); - - await toolbar.closeMoreMenu(); - }); - - it('correct actions appear when a locked file is selected - [C297618]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkOnlyFiles(); - await searchInput.searchFor(fileLocked); - await dataTable.selectItem(fileLocked); - - expect(await toolbar.isEmpty()).toBe(false, `actions not displayed for ${fileLocked}`); - expect(await toolbar.isViewPresent()).toBe(true, `View is not displayed for ${fileLocked}`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed for ${fileLocked}`); - expect(await toolbar.isEditFolderPresent()).toBe(false, `Edit folder is displayed for ${fileLocked}`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${fileLocked}`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${fileLocked}`); - expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${fileLocked}`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed for ${fileLocked}`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed for ${fileLocked}`); - - await toolbar.closeMoreMenu(); - }); - - it('correct actions appear when a folder is selected - [C291817]', async () => { - await searchInput.clickSearchButton(); - await searchInput.checkOnlyFolders(); - await searchInput.searchFor(folderUser); - await dataTable.selectItem(folderUser); - - expect(await toolbar.isEmpty()).toBe(false, `actions not displayed for ${folderUser}`); - expect(await toolbar.isViewPresent()).toBe(false, `View is displayed for ${folderUser}`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not enabled for ${folderUser}`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditFolderPresent()).toBe(true, `Edit folder is not displayed for ${folderUser}`); - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed for ${folderUser}`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed for ${folderUser}`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed for ${folderUser}`); - expect(await toolbar.menu.isDeletePresent()).toBe(false, `Delete is displayed for ${folderUser}`); - expect(await toolbar.menu.isMovePresent()).toBe(false, `Move is displayed for ${folderUser}`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed for ${folderUser}`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(false, `Manage versions is displayed for ${folderUser}`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(false, `Upload new version is displayed for ${folderUser}`); - - await toolbar.closeMoreMenu(); - }); - }); -}); diff --git a/e2e/suites/actions/library-actions.test.ts b/e2e/suites/actions/library-actions.test.ts index c7d0e01b84..0bf77ad998 100755 --- a/e2e/suites/actions/library-actions.test.ts +++ b/e2e/suites/actions/library-actions.test.ts @@ -250,7 +250,7 @@ describe('Library actions', () => { expect(await confirmDialog.isCancelEnabled()).toBe(true, 'Cancel button is not enabled'); }); - it('Cancel Leave library - [C290111]', async () => { + it('Cancel Leave Library - [C290111]', async () => { await page.goToMyLibrariesAndWait(); await dataTable.selectItem(sitePublic5Admin); await toolbar.clickLeave(); diff --git a/e2e/suites/viewer/viewer-actions.test.ts b/e2e/suites/viewer/viewer-actions.test.ts index 18bc83d1ae..11777415ff 100755 --- a/e2e/suites/viewer/viewer-actions.test.ts +++ b/e2e/suites/viewer/viewer-actions.test.ts @@ -66,7 +66,7 @@ describe('Viewer actions', () => { const destination = `destPF-${Utils.random()}`; let destinationId; const docxPersonalFiles = `docxPF-${Utils.random()}.docx`; let docxFileId; - const docxLockedPersonalFiles = `docxLockedPF-${Utils.random()}.docx`; let docxLockedId; + const xlsxPersonalFiles = `xlsxPF-${Utils.random()}.xlsx`; const pdfPersonalFiles = `pdfPF-${Utils.random()}.pdf`; const filePersonalFiles = docxFile2; let filePersonalFilesId; @@ -80,7 +80,7 @@ describe('Viewer actions', () => { destinationId = (await apis.user.nodes.createFolder(destination)).entry.id; docxFileId = (await apis.user.upload.uploadFileWithRename(docxFile, parentId, docxPersonalFiles)).entry.id; - docxLockedId = (await apis.user.upload.uploadFileWithRename(docxFile, parentId, docxLockedPersonalFiles)).entry.id; + filePersonalFilesId = (await apis.user.upload.uploadFile(docxFile2, parentId)).entry.id; await apis.user.upload.uploadFileWithRename(xlsxFileForMove, parentId, xlsxPersonalFiles); await apis.user.upload.uploadFileWithRename(pdfFileForDelete, parentId, pdfPersonalFiles); @@ -91,7 +91,7 @@ describe('Viewer actions', () => { await apis.user.nodes.lockFile(fileForCancelEditingId); await apis.user.nodes.lockFile(fileForUploadNewVersionId); - await apis.user.nodes.lockFile(docxLockedId); + await loginPage.loginWith(username); done(); @@ -116,58 +116,6 @@ describe('Viewer actions', () => { done(); }); - it('Correct actions appear in the viewer toolbar - [C282025]', async () => { - await dataTable.doubleClickOnRowByName(docxPersonalFiles); - await viewer.waitForViewerToOpen(); - - expect(await toolbar.isEmpty()).toBe(false, `viewer toolbar is empty`); - expect(await toolbar.isViewPresent()).toBe(false, `View is displayed`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); - expect(await toolbar.isPrintPresent()).toBe(true, `Print is not displayed`); - expect(await toolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); - expect(await toolbar.isSharePresent()).toBe(true, `Share is not displayed`); - expect(await toolbar.isViewDetailsPresent()).toBe(true, `view details is not displayed`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed`); - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed`); - - await toolbar.closeMoreMenu(); - }); - - it('Correct actions appear in the viewer toolbar for a locked file - [C297583]', async () => { - await dataTable.doubleClickOnRowByName(docxLockedPersonalFiles); - await viewer.waitForViewerToOpen(); - - expect(await toolbar.isEmpty()).toBe(false, `viewer toolbar is empty`); - expect(await toolbar.isViewPresent()).toBe(false, `View is displayed`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); - expect(await toolbar.isPrintPresent()).toBe(true, `Print is not displayed`); - expect(await toolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); - expect(await toolbar.isSharePresent()).toBe(true, `Share is not displayed`); - expect(await toolbar.isViewDetailsPresent()).toBe(true, `view details is not displayed`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed`); - expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed`); - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed`); - - await toolbar.closeMoreMenu(); - }); - it('Download action - [C268129]', async () => { await dataTable.doubleClickOnRowByName(docxPersonalFiles); await viewer.waitForViewerToOpen(); @@ -321,7 +269,7 @@ describe('Viewer actions', () => { const destination = `destFL-${Utils.random()}`; let destinationId; const docxLibraries = `docxFL-${Utils.random()}.docx`; let docxFileId; - const docxLockedLibraries = `docxLockedFL-${Utils.random()}.docx`; let docxLockedId; + const xlsxLibraries = `xlsxFL-${Utils.random()}.xlsx`; const pdfLibraries = `pdfFL-${Utils.random()}.pdf`; const fileLibraries = docxFile2; let fileLibrariesId; @@ -335,9 +283,9 @@ describe('Viewer actions', () => { const docLibId = await apis.user.sites.getDocLibId(siteName); destinationId = (await apis.user.nodes.createFolder(destination)).entry.id; docxFileId = (await apis.user.upload.uploadFileWithRename(docxFile, docLibId, docxLibraries)).entry.id; - docxLockedId = (await apis.user.upload.uploadFileWithRename(docxFile, docLibId, docxLockedLibraries)).entry.id; + fileLibrariesId = (await apis.user.upload.uploadFile(docxFile2, docLibId)).entry.id; - await apis.user.nodes.lockFile(docxLockedId); + await apis.user.upload.uploadFileWithRename(xlsxFileForMove, docLibId, xlsxLibraries); await apis.user.upload.uploadFileWithRename(pdfFileForDelete, docLibId, pdfLibraries); @@ -371,58 +319,6 @@ describe('Viewer actions', () => { done(); }); - it('Correct actions appear in the viewer toolbar - [C297587]', async () => { - await dataTable.doubleClickOnRowByName(docxLibraries); - await viewer.waitForViewerToOpen(); - - expect(await toolbar.isEmpty()).toBe(false, `viewer toolbar is empty`); - expect(await toolbar.isViewPresent()).toBe(false, `View is displayed`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); - expect(await toolbar.isPrintPresent()).toBe(true, `Print is not displayed`); - expect(await toolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); - expect(await toolbar.isSharePresent()).toBe(true, `Share is not displayed`); - expect(await toolbar.isViewDetailsPresent()).toBe(true, `view details is not displayed`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed`); - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed`); - - await toolbar.closeMoreMenu(); - }); - - it('Correct actions appear in the viewer toolbar for a locked file - [C297588]', async () => { - await dataTable.doubleClickOnRowByName(docxLockedLibraries); - await viewer.waitForViewerToOpen(); - - expect(await toolbar.isEmpty()).toBe(false, `viewer toolbar is empty`); - expect(await toolbar.isViewPresent()).toBe(false, `View is displayed`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); - expect(await toolbar.isPrintPresent()).toBe(true, `Print is not displayed`); - expect(await toolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); - expect(await toolbar.isSharePresent()).toBe(true, `Share is not displayed`); - expect(await toolbar.isViewDetailsPresent()).toBe(true, `view details is not displayed`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed`); - expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed`); - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed`); - - await toolbar.closeMoreMenu(); - }); - it('Download action - [C286369]', async () => { await dataTable.doubleClickOnRowByName(docxLibraries); expect(await viewer.isViewerOpened()).toBe(true, 'Viewer is not opened'); @@ -552,7 +448,7 @@ describe('Viewer actions', () => { const destination = `destRF-${Utils.random()}`; let destinationId; const docxRecentFiles = `docxRF-${Utils.random()}.docx`; let docxFileId; - const docxLockedRecentFiles = `docxLockedRF-${Utils.random()}.docx`; let docxLockedId; + const xlsxRecentFiles = `xlsxRF-${Utils.random()}.xlsx`; const pdfRecentFiles = `pdfRF-${Utils.random()}.pdf`; const fileRecent = docxFile2; let fileRecentId; @@ -566,7 +462,7 @@ describe('Viewer actions', () => { parentId = (await apis.user.nodes.createFolder(parent)).entry.id; destinationId = (await apis.user.nodes.createFolder(destination)).entry.id; docxFileId = (await apis.user.upload.uploadFileWithRename(docxFile, parentId, docxRecentFiles)).entry.id; - docxLockedId = (await apis.user.upload.uploadFileWithRename(docxFile, parentId, docxLockedRecentFiles)).entry.id; + fileRecentId = (await apis.user.upload.uploadFile(docxFile2, parentId)).entry.id; fileForEditOfflineId = (await apis.user.upload.uploadFileWithRename(docxFile, parentId, fileForEditOffline)).entry.id; @@ -576,7 +472,7 @@ describe('Viewer actions', () => { await apis.user.nodes.lockFile(fileForCancelEditingId); await apis.user.nodes.lockFile(fileForUploadNewVersionId); - await apis.user.nodes.lockFile(docxLockedId); + await apis.user.upload.uploadFileWithRename(xlsxFileForMove, parentId, xlsxRecentFiles); await apis.user.upload.uploadFileWithRename(pdfFileForDelete, parentId, pdfRecentFiles); @@ -603,58 +499,6 @@ describe('Viewer actions', () => { done(); }); - it('Correct actions appear in the viewer toolbar - [C297592]', async () => { - await dataTable.doubleClickOnRowByName(docxRecentFiles); - await viewer.waitForViewerToOpen(); - - expect(await toolbar.isEmpty()).toBe(false, `viewer toolbar is empty`); - expect(await toolbar.isViewPresent()).toBe(false, `View is displayed`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); - expect(await toolbar.isPrintPresent()).toBe(true, `Print is not displayed`); - expect(await toolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); - expect(await toolbar.isSharePresent()).toBe(true, `Share is not displayed`); - expect(await toolbar.isViewDetailsPresent()).toBe(true, `view details is not displayed`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await toolbar.menu.isToggleFavoritePresent()).toBe(true, `Favorite is not displayed`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed`); - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed`); - - await toolbar.closeMoreMenu(); - }); - - it('Correct actions appear in the viewer toolbar for a locked file - [C297593]', async () => { - await dataTable.doubleClickOnRowByName(docxLockedRecentFiles); - await viewer.waitForViewerToOpen(); - - expect(await toolbar.isEmpty()).toBe(false, `viewer toolbar is empty`); - expect(await toolbar.isViewPresent()).toBe(false, `View is displayed`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); - expect(await toolbar.isPrintPresent()).toBe(true, `Print is not displayed`); - expect(await toolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); - expect(await toolbar.isSharePresent()).toBe(true, `Share is not displayed`); - expect(await toolbar.isViewDetailsPresent()).toBe(true, `view details is not displayed`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed`); - expect(await toolbar.menu.isToggleFavoritePresent()).toBe(true, `Favorite is not displayed`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed`); - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed`); - - await toolbar.closeMoreMenu(); - }); - it('Download action - [C286383]', async () => { await dataTable.doubleClickOnRowByName(docxRecentFiles); expect(await viewer.isViewerOpened()).toBe(true, 'Viewer is not opened'); @@ -785,7 +629,7 @@ describe('Viewer actions', () => { const destination = `destSF-${Utils.random()}`; let destinationId; const docxSharedFiles = `docxSF-${Utils.random()}.docx`; let docxFileId; - const docxLockedSharedFiles = `docxLockedSF-${Utils.random()}.docx`; let docxLockedId; + const xlsxSharedFiles = `xlsxSF-${Utils.random()}.xlsx`; let xlsxFileId; const pdfSharedFiles = `pdfSF-${Utils.random()}.pdf`; let pdfFileId; const fileShared = docxFile2; let fileSharedId; @@ -798,7 +642,7 @@ describe('Viewer actions', () => { parentId = (await apis.user.nodes.createFolder(parent)).entry.id; destinationId = (await apis.user.nodes.createFolder(destination)).entry.id; docxFileId = (await apis.user.upload.uploadFileWithRename(docxFile, parentId, docxSharedFiles)).entry.id; - docxLockedId = (await apis.user.upload.uploadFileWithRename(docxFile, parentId, docxLockedSharedFiles)).entry.id; + xlsxFileId = (await apis.user.upload.uploadFileWithRename(xlsxFileForMove, parentId, xlsxSharedFiles)).entry.id; pdfFileId = (await apis.user.upload.uploadFileWithRename(pdfFileForDelete, parentId, pdfSharedFiles)).entry.id; fileSharedId = (await apis.user.upload.uploadFile(docxFile2, parentId)).entry.id; @@ -809,9 +653,9 @@ describe('Viewer actions', () => { await apis.user.nodes.lockFile(fileForCancelEditingId); await apis.user.nodes.lockFile(fileForUploadNewVersionId); - await apis.user.nodes.lockFile(docxLockedId); - await apis.user.shared.shareFilesByIds([docxFileId, docxLockedId, xlsxFileId, pdfFileId, fileForCancelEditingId, fileForEditOfflineId, fileForUploadNewVersionId, fileSharedId]) + + await apis.user.shared.shareFilesByIds([docxFileId, xlsxFileId, pdfFileId, fileForCancelEditingId, fileForEditOfflineId, fileForUploadNewVersionId, fileSharedId]) await apis.user.shared.waitForApi({expect: 8}); await loginPage.loginWith(username); @@ -835,58 +679,6 @@ describe('Viewer actions', () => { done(); }); - it('Correct actions appear in the viewer toolbar - [C297597]', async () => { - await dataTable.doubleClickOnRowByName(docxSharedFiles); - await viewer.waitForViewerToOpen(); - - expect(await toolbar.isEmpty()).toBe(false, `viewer toolbar is empty`); - expect(await toolbar.isViewPresent()).toBe(false, `View is displayed`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); - expect(await toolbar.isPrintPresent()).toBe(true, `Print is not displayed`); - expect(await toolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); - expect(await toolbar.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed`); - expect(await toolbar.isViewDetailsPresent()).toBe(true, `view details is not displayed`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed`); - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed`); - - await toolbar.closeMoreMenu(); - }); - - it('Correct actions appear in the viewer toolbar for a locked file - [C297598]', async () => { - await dataTable.doubleClickOnRowByName(docxLockedSharedFiles); - await viewer.waitForViewerToOpen(); - - expect(await toolbar.isEmpty()).toBe(false, `viewer toolbar is empty`); - expect(await toolbar.isViewPresent()).toBe(false, `View is displayed`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); - expect(await toolbar.isPrintPresent()).toBe(true, `Print is not displayed`); - expect(await toolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); - expect(await toolbar.isSharedLinkSettingsPresent()).toBe(true, `Shared link settings is not displayed`); - expect(await toolbar.isViewDetailsPresent()).toBe(true, `view details is not displayed`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed`); - expect(await toolbar.menu.isFavoritePresent()).toBe(true, `Favorite is not displayed`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed`); - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed`); - - await toolbar.closeMoreMenu(); - }); - it('Download action - [C286376]', async () => { await dataTable.doubleClickOnRowByName(docxSharedFiles); expect(await viewer.isViewerOpened()).toBe(true, 'Viewer is not opened'); @@ -1019,7 +811,7 @@ describe('Viewer actions', () => { let destinationId; const docxFavorites = `docxFav-${Utils.random()}.docx`; let docxFileId; - const docxLockedFavorites = `docxLockedFav-${Utils.random()}.docx`; let docxLockedId; + const xlsxFavorites = `xlsxFav-${Utils.random()}.xlsx`; let xlsxFileId; const pdfFavorites = `pdfFav-${Utils.random()}.pdf`; let pdfFileId; const fileFav = docxFile2; let fileFavId; @@ -1032,7 +824,7 @@ describe('Viewer actions', () => { parentId = (await apis.user.nodes.createFolder(parent)).entry.id; destinationId = (await apis.user.nodes.createFolder(destination)).entry.id; docxFileId = (await apis.user.upload.uploadFileWithRename(docxFile, parentId, docxFavorites)).entry.id; - docxLockedId = (await apis.user.upload.uploadFileWithRename(docxFile, parentId, docxLockedFavorites)).entry.id; + xlsxFileId = (await apis.user.upload.uploadFileWithRename(xlsxFileForMove, parentId, xlsxFavorites)).entry.id; pdfFileId = (await apis.user.upload.uploadFileWithRename(pdfFileForDelete, parentId, pdfFavorites)).entry.id; fileFavId = (await apis.user.upload.uploadFile(docxFile2, parentId)).entry.id; @@ -1043,9 +835,9 @@ describe('Viewer actions', () => { await apis.user.nodes.lockFile(fileForCancelEditingId); await apis.user.nodes.lockFile(fileForUploadNewVersionId); - await apis.user.nodes.lockFile(docxLockedId); - await apis.user.favorites.addFavoritesByIds('file', [docxFileId, docxLockedId, xlsxFileId, pdfFileId, fileForEditOfflineId, fileForCancelEditingId, fileForUploadNewVersionId, fileFavId]) + + await apis.user.favorites.addFavoritesByIds('file', [docxFileId, xlsxFileId, pdfFileId, fileForEditOfflineId, fileForCancelEditingId, fileForUploadNewVersionId, fileFavId]) await apis.user.favorites.waitForApi({expect: 8}); await loginPage.loginWith(username); @@ -1069,58 +861,6 @@ describe('Viewer actions', () => { done(); }); - it('Correct actions appear in the viewer toolbar - [C297599]', async () => { - await dataTable.doubleClickOnRowByName(docxFavorites); - await viewer.waitForViewerToOpen(); - - expect(await toolbar.isEmpty()).toBe(false, `viewer toolbar is empty`); - expect(await toolbar.isViewPresent()).toBe(false, `View is displayed`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); - expect(await toolbar.isPrintPresent()).toBe(true, `Print is not displayed`); - expect(await toolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); - expect(await toolbar.isSharePresent()).toBe(true, `Share is not displayed`); - expect(await toolbar.isViewDetailsPresent()).toBe(true, `view details is not displayed`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(true, `Edit offline is not displayed`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(false, `Cancel editing is displayed`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed`); - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed`); - - await toolbar.closeMoreMenu(); - }); - - it('Correct actions appear in the viewer toolbar for a locked file - [C297600]', async () => { - await dataTable.doubleClickOnRowByName(docxLockedFavorites); - await viewer.waitForViewerToOpen(); - - expect(await toolbar.isEmpty()).toBe(false, `viewer toolbar is empty`); - expect(await toolbar.isViewPresent()).toBe(false, `View is displayed`); - expect(await toolbar.isDownloadPresent()).toBe(true, `Download is not displayed`); - expect(await toolbar.isPrintPresent()).toBe(true, `Print is not displayed`); - expect(await toolbar.isFullScreenPresent()).toBe(true, `Full screen is not displayed`); - expect(await toolbar.isSharePresent()).toBe(true, `Share is not displayed`); - expect(await toolbar.isViewDetailsPresent()).toBe(true, `view details is not displayed`); - - await toolbar.openMoreMenu(); - - expect(await toolbar.menu.isEditOfflinePresent()).toBe(false, `Edit offline is displayed`); - expect(await toolbar.menu.isCancelEditingPresent()).toBe(true, `Cancel editing is not displayed`); - expect(await toolbar.menu.isToggleRemoveFavoritePresent()).toBe(true, `Remove favorite is not displayed`); - expect(await toolbar.menu.isCopyPresent()).toBe(true, `Copy is not displayed`); - expect(await toolbar.menu.isMovePresent()).toBe(true, `Move is not displayed`); - expect(await toolbar.menu.isDeletePresent()).toBe(true, `Delete is not displayed`); - expect(await toolbar.menu.isManageVersionsPresent()).toBe(true, `Manage versions is not displayed`); - expect(await toolbar.menu.isUploadNewVersionPresent()).toBe(true, `Upload new version is not displayed`); - - await toolbar.closeMoreMenu(); - }); - it('Download action - [C286390]', async () => { await dataTable.doubleClickOnRowByName(docxFavorites); expect(await viewer.isViewerOpened()).toBe(true, 'Viewer is not opened'); diff --git a/e2e/utilities/repo-client/apis/favorites/favorites-api.ts b/e2e/utilities/repo-client/apis/favorites/favorites-api.ts index 3f119bb045..d884d925cb 100755 --- a/e2e/utilities/repo-client/apis/favorites/favorites-api.ts +++ b/e2e/utilities/repo-client/apis/favorites/favorites-api.ts @@ -67,7 +67,7 @@ export class FavoritesApi extends RepoApi { try { return await this.favoritesApi.createFavorite('-me-', data); } catch (error) { - // console.log('--- add favorite by id catch '); + console.log('--- add favorite by id catch '); } } @@ -116,7 +116,7 @@ export class FavoritesApi extends RepoApi { try { return await this.favoritesApi.deleteFavorite('-me-', nodeId); } catch (error) { - // console.log('--- remove favorite by id catch '); + console.log('--- remove favorite by id catch ', error); } } diff --git a/e2e/utilities/repo-client/apis/nodes/nodes-api.ts b/e2e/utilities/repo-client/apis/nodes/nodes-api.ts index e575686bb9..0cf4613bf6 100755 --- a/e2e/utilities/repo-client/apis/nodes/nodes-api.ts +++ b/e2e/utilities/repo-client/apis/nodes/nodes-api.ts @@ -167,7 +167,11 @@ export class NodesApi extends RepoApi { } async createFile(name: string, parentId: string = '-my-', title: string = '', description: string = '', author: string = '', majorVersion: boolean = true) { + try { return await this.createNode('cm:content', name, parentId, title, description, null, author, majorVersion); + } catch (error) { + console.log('==== catch createFile: ', error); + } } async createImage(name: string, parentId: string = '-my-', title: string = '', description: string = '') { diff --git a/e2e/utilities/repo-client/apis/sites/sites-api.ts b/e2e/utilities/repo-client/apis/sites/sites-api.ts index 36e3bd16bb..037f5c5419 100755 --- a/e2e/utilities/repo-client/apis/sites/sites-api.ts +++ b/e2e/utilities/repo-client/apis/sites/sites-api.ts @@ -74,8 +74,12 @@ export class SitesApi extends RepoApi { id: siteId || title }; - await this.apiAuth(); + try { + await this.apiAuth(); return await this.sitesApi.createSite(site); + } catch (error) { + console.log('=== create site catch: ', error); + } } async createSites(titles: string[], visibility?: string) { diff --git a/e2e/utilities/repo-client/apis/upload/upload-api.ts b/e2e/utilities/repo-client/apis/upload/upload-api.ts index 48d91a0294..b7e9cd5b9f 100644 --- a/e2e/utilities/repo-client/apis/upload/upload-api.ts +++ b/e2e/utilities/repo-client/apis/upload/upload-api.ts @@ -54,8 +54,15 @@ export class UploadApi extends RepoApi { nodeType: 'cm:content' }; - await this.apiAuth(); - return await this.upload.uploadFile(file, '', parentFolderId, null, opts); + try { + await this.apiAuth(); + return await this.upload.uploadFile(file, '', parentFolderId, null, opts); + } catch (error) { + console.log('=== catch upload file with rename: ', error); + } + + + } } diff --git a/protractor.conf.js b/protractor.conf.js index d22f17094f..3dbec5141a 100755 --- a/protractor.conf.js +++ b/protractor.conf.js @@ -43,7 +43,7 @@ exports.config = { './e2e/suites/navigation/*.test.ts', './e2e/suites/pagination/*.test.ts', './e2e/suites/search/*.test.ts', - './e2e/suites/actions-available/*.test.ts', + './e2e/suites/actions-available/**/*.test.ts', './e2e/suites/actions/*.test.ts', './e2e/suites/viewer/*.test.ts', './e2e/suites/info-drawer/*.test.ts', @@ -57,7 +57,7 @@ exports.config = { navigation: './e2e/suites/navigation/*.test.ts', pagination: './e2e/suites/pagination/*.test.ts', search: './e2e/suites/search/*.test.ts', - actionsAvailable: './e2e/suites/actions-available/*.test.ts', + actionsAvailable: './e2e/suites/actions-available/**/*.test.ts', addRemoveContent: [ './e2e/suites/actions/new-menu.test.ts', './e2e/suites/actions/create-folder.test.ts', diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 3eb732f2d1..9f798f6efa 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -209,7 +209,7 @@ "FULLSCREEN": "Activate full-screen mode", "JOIN": "Join", "CANCEL_JOIN": "Cancel Join Request", - "LEAVE": "Leave library", + "LEAVE": "Leave Library", "EDIT_OFFLINE": "Edit Offline", "EDIT_OFFLINE_CANCEL": "Cancel Editing" }, From 896800e434c75094dce9e5faa86efa50ab98433d Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Fri, 5 Jul 2019 11:23:25 +0300 Subject: [PATCH 245/259] i18n update (#1148) --- src/assets/i18n/ar.json | 20 +++++++++++++++++-- src/assets/i18n/cs.json | 20 +++++++++++++++++-- src/assets/i18n/da.json | 20 +++++++++++++++++-- src/assets/i18n/de.json | 20 +++++++++++++++++-- src/assets/i18n/es.json | 22 ++++++++++++++++++--- src/assets/i18n/fi.json | 20 +++++++++++++++++-- src/assets/i18n/fr.json | 20 +++++++++++++++++-- src/assets/i18n/it.json | 20 +++++++++++++++++-- src/assets/i18n/ja.json | 20 +++++++++++++++++-- src/assets/i18n/nl.json | 20 +++++++++++++++++-- src/assets/i18n/pl.json | 20 +++++++++++++++++-- src/assets/i18n/pt-BR.json | 20 +++++++++++++++++-- src/assets/i18n/ru.json | 20 +++++++++++++++++-- src/assets/i18n/sv.json | 20 +++++++++++++++++-- src/assets/i18n/zh-CN.json | 40 ++++++++++++++++++++++++++------------ 15 files changed, 281 insertions(+), 41 deletions(-) diff --git a/src/assets/i18n/ar.json b/src/assets/i18n/ar.json index 822e478187..b49e7f81e9 100644 --- a/src/assets/i18n/ar.json +++ b/src/assets/i18n/ar.json @@ -1,5 +1,6 @@ { "APP": { + "COPYRIGHT": "حقوق الطبع والنشر © 2017 - 2019 Alfresco Software, Inc. جميع الحقوق محفوظة.", "ABOUT": { "VERSION": "الإصدار:", "PLUGINS": { @@ -164,6 +165,7 @@ "FOUND_ONE_RESULT": "تم العثور على {{ number }} نتيجة", "CUSTOM_ROW": { "MODIFIED": "تم التعديل", + "BY_USER": "بواسطة {{ user }}", "LOCATION": "مكان", "SIZE": "الحجم" }, @@ -333,7 +335,8 @@ } }, "CONTENT_METADATA": { - "EXIF_GROUP_TITLE": "صورة EXIF" + "EXIF_GROUP_TITLE": "صورة EXIF", + "EFFECTIVITY_GROUP_TITLE": "الفاعلية" }, "INFO_DRAWER": { "TITLE": "التفاصيل", @@ -456,7 +459,20 @@ "CATEGORIES": { "MODIFIED_DATE": "تاريخ التعديل", "SIZE": "الحجم", + "SIZE_OPTIONS": { + "SMALL": "صغير", + "MEDIUM": "متوسط", + "LARGE": "كبير", + "HUGE": "ضخم" + }, "CREATED_DATE": "تاريخ الإنشاء" + }, + "FACET_QUERIES": { + "TODAY": "اليوم", + "THIS_WEEK": "هذا الأسبوع", + "THIS_MONTH": "هذا الشهر", + "LAST_6_MONTHS": "في آخر 6 أشهر", + "THIS_YEAR": "هذا العام" } }, "CORE": { @@ -484,4 +500,4 @@ } } } -} +} \ No newline at end of file diff --git a/src/assets/i18n/cs.json b/src/assets/i18n/cs.json index 8af664d923..a46078ffe5 100644 --- a/src/assets/i18n/cs.json +++ b/src/assets/i18n/cs.json @@ -1,5 +1,6 @@ { "APP": { + "COPYRIGHT": "© 2017 - 2019 Alfresco Software, Inc. Všechna práva vyhrazena.", "ABOUT": { "VERSION": "Verze:", "PLUGINS": { @@ -164,6 +165,7 @@ "FOUND_ONE_RESULT": "Nalezené výsledky: {{ number }}", "CUSTOM_ROW": { "MODIFIED": "Změněno", + "BY_USER": "od {{ user }}", "LOCATION": "Umístění", "SIZE": "Velikost" }, @@ -333,7 +335,8 @@ } }, "CONTENT_METADATA": { - "EXIF_GROUP_TITLE": "Obraz EXIF" + "EXIF_GROUP_TITLE": "Obraz EXIF", + "EFFECTIVITY_GROUP_TITLE": "Účinnost" }, "INFO_DRAWER": { "TITLE": "Podrobnosti", @@ -456,7 +459,20 @@ "CATEGORIES": { "MODIFIED_DATE": "Datum úpravy", "SIZE": "Velikost", + "SIZE_OPTIONS": { + "SMALL": "Malá", + "MEDIUM": "Střední", + "LARGE": "Velká", + "HUGE": "Obrovská" + }, "CREATED_DATE": "Datum vytvoření" + }, + "FACET_QUERIES": { + "TODAY": "Dnes", + "THIS_WEEK": "Tento týden", + "THIS_MONTH": "Tento měsíc", + "LAST_6_MONTHS": "Za posledních 6 měsíců", + "THIS_YEAR": "Letos" } }, "CORE": { @@ -484,4 +500,4 @@ } } } -} +} \ No newline at end of file diff --git a/src/assets/i18n/da.json b/src/assets/i18n/da.json index 83e6b66a26..77436f7973 100644 --- a/src/assets/i18n/da.json +++ b/src/assets/i18n/da.json @@ -1,5 +1,6 @@ { "APP": { + "COPYRIGHT": "© 2017 - 2019 Alfresco Software, Inc. Alle rettigheder forbeholdes.", "ABOUT": { "VERSION": "Version:", "PLUGINS": { @@ -164,6 +165,7 @@ "FOUND_ONE_RESULT": "{{ number }} resultat fundet", "CUSTOM_ROW": { "MODIFIED": "Ændret", + "BY_USER": "af {{ user }}", "LOCATION": "Placering", "SIZE": "Størrelse" }, @@ -333,7 +335,8 @@ } }, "CONTENT_METADATA": { - "EXIF_GROUP_TITLE": "Billed-EXIF" + "EXIF_GROUP_TITLE": "Billed-EXIF", + "EFFECTIVITY_GROUP_TITLE": "Gældende periode" }, "INFO_DRAWER": { "TITLE": "Detaljer", @@ -456,7 +459,20 @@ "CATEGORIES": { "MODIFIED_DATE": "Ændringsdato", "SIZE": "Størrelse", + "SIZE_OPTIONS": { + "SMALL": "Lille", + "MEDIUM": "Medium", + "LARGE": "Stor", + "HUGE": "Meget stor" + }, "CREATED_DATE": "Oprettelsesdato" + }, + "FACET_QUERIES": { + "TODAY": "I dag", + "THIS_WEEK": "I denne uge", + "THIS_MONTH": "I denne måned", + "LAST_6_MONTHS": "I de sidste 6 måneder", + "THIS_YEAR": "I år" } }, "CORE": { @@ -484,4 +500,4 @@ } } } -} +} \ No newline at end of file diff --git a/src/assets/i18n/de.json b/src/assets/i18n/de.json index ef27c46ba9..8882e029ea 100644 --- a/src/assets/i18n/de.json +++ b/src/assets/i18n/de.json @@ -1,5 +1,6 @@ { "APP": { + "COPYRIGHT": "© 2017 - 2019 Alfresco Software, Inc. Alle Rechte vorbehalten.", "ABOUT": { "VERSION": "Version:", "PLUGINS": { @@ -164,6 +165,7 @@ "FOUND_ONE_RESULT": "{{ number }} Ergebnisse gefunden", "CUSTOM_ROW": { "MODIFIED": "Bearbeitet", + "BY_USER": "von {{ user }}", "LOCATION": "Speicherort", "SIZE": "Größe" }, @@ -333,7 +335,8 @@ } }, "CONTENT_METADATA": { - "EXIF_GROUP_TITLE": "Bild-EXIF" + "EXIF_GROUP_TITLE": "Bild-EXIF", + "EFFECTIVITY_GROUP_TITLE": "Effektivität" }, "INFO_DRAWER": { "TITLE": "Details", @@ -456,7 +459,20 @@ "CATEGORIES": { "MODIFIED_DATE": "Datum der Änderung", "SIZE": "Größe", + "SIZE_OPTIONS": { + "SMALL": "Klein", + "MEDIUM": "Mittel", + "LARGE": "Groß", + "HUGE": "Riesig" + }, "CREATED_DATE": "Datum der Erstellung" + }, + "FACET_QUERIES": { + "TODAY": "Heute", + "THIS_WEEK": "diese Woche", + "THIS_MONTH": "diesen Monat", + "LAST_6_MONTHS": "in den letzten 6 Monaten", + "THIS_YEAR": "dieses Jahr" } }, "CORE": { @@ -484,4 +500,4 @@ } } } -} +} \ No newline at end of file diff --git a/src/assets/i18n/es.json b/src/assets/i18n/es.json index 2311c409a2..545afb029e 100644 --- a/src/assets/i18n/es.json +++ b/src/assets/i18n/es.json @@ -1,5 +1,6 @@ { "APP": { + "COPYRIGHT": "© 2017 - 2019 Alfresco Software, Inc. Todos los derechos reservados.", "ABOUT": { "VERSION": "Versión:", "PLUGINS": { @@ -54,7 +55,7 @@ "TOOLTIP": "Añadir nuevos ficheros o carpetas, o crear una nueva biblioteca de ficheros", "MENU_ITEMS": { "CREATE_FOLDER": "Crear carpeta", - "UPLOAD_FILE": "Cargar fichero", + "UPLOAD_FILE": "Añadir fichero", "UPLOAD_FOLDER": "Cargar carpeta", "CREATE_LIBRARY": "Crear biblioteca" }, @@ -164,6 +165,7 @@ "FOUND_ONE_RESULT": "{{ number }} resultado encontrado", "CUSTOM_ROW": { "MODIFIED": "Modificado", + "BY_USER": "por {{ user }}", "LOCATION": "Ubicación", "SIZE": "Tamaño" }, @@ -333,7 +335,8 @@ } }, "CONTENT_METADATA": { - "EXIF_GROUP_TITLE": "Imagen EXIF" + "EXIF_GROUP_TITLE": "Imagen EXIF", + "EFFECTIVITY_GROUP_TITLE": "Efectividad" }, "INFO_DRAWER": { "TITLE": "Detalles", @@ -456,7 +459,20 @@ "CATEGORIES": { "MODIFIED_DATE": "Fecha de modificación", "SIZE": "Tamaño", + "SIZE_OPTIONS": { + "SMALL": "Pequeño", + "MEDIUM": "Media", + "LARGE": "Grande", + "HUGE": "Enorme" + }, "CREATED_DATE": "Fecha de creación" + }, + "FACET_QUERIES": { + "TODAY": "Hoy", + "THIS_WEEK": "Esta semana", + "THIS_MONTH": "Este mes", + "LAST_6_MONTHS": "En los últimos 6 meses", + "THIS_YEAR": "Este año" } }, "CORE": { @@ -484,4 +500,4 @@ } } } -} +} \ No newline at end of file diff --git a/src/assets/i18n/fi.json b/src/assets/i18n/fi.json index 69a88bd3cd..67b5c27bf8 100644 --- a/src/assets/i18n/fi.json +++ b/src/assets/i18n/fi.json @@ -1,5 +1,6 @@ { "APP": { + "COPYRIGHT": "© 2017 - 2019 Alfresco Software, Inc. Kaikki oikeudet pidätetään.", "ABOUT": { "VERSION": "Versio:", "PLUGINS": { @@ -164,6 +165,7 @@ "FOUND_ONE_RESULT": "Löytyi {{ number }} tulos", "CUSTOM_ROW": { "MODIFIED": "Muokattu", + "BY_USER": "{{ user }}", "LOCATION": "Sijainti", "SIZE": "Koko" }, @@ -333,7 +335,8 @@ } }, "CONTENT_METADATA": { - "EXIF_GROUP_TITLE": "Kuva – EXIF" + "EXIF_GROUP_TITLE": "Kuva – EXIF", + "EFFECTIVITY_GROUP_TITLE": "Voimassaolo" }, "INFO_DRAWER": { "TITLE": "Tiedot", @@ -456,7 +459,20 @@ "CATEGORIES": { "MODIFIED_DATE": "Muokkauspäivämäärä", "SIZE": "Koko", + "SIZE_OPTIONS": { + "SMALL": "Pieni", + "MEDIUM": "Keskikokoinen", + "LARGE": "Suuri", + "HUGE": "Valtava" + }, "CREATED_DATE": "Luontipäivämäärä" + }, + "FACET_QUERIES": { + "TODAY": "Tänään", + "THIS_WEEK": "Tällä viikolla", + "THIS_MONTH": "Tässä kuussa", + "LAST_6_MONTHS": "Viimeisen 6 kuukauden aikana", + "THIS_YEAR": "Tänä vuonna" } }, "CORE": { @@ -484,4 +500,4 @@ } } } -} +} \ No newline at end of file diff --git a/src/assets/i18n/fr.json b/src/assets/i18n/fr.json index 0c63e5631e..40b7d6202d 100644 --- a/src/assets/i18n/fr.json +++ b/src/assets/i18n/fr.json @@ -1,5 +1,6 @@ { "APP": { + "COPYRIGHT": "© 2017 - 2019 Alfresco Software, Inc. Tous droits réservés.", "ABOUT": { "VERSION": "Version :", "PLUGINS": { @@ -164,6 +165,7 @@ "FOUND_ONE_RESULT": "{{ number }} résultat trouvé", "CUSTOM_ROW": { "MODIFIED": "Modifié", + "BY_USER": "par {{ user }}", "LOCATION": "Emplacement", "SIZE": "Taille" }, @@ -333,7 +335,8 @@ } }, "CONTENT_METADATA": { - "EXIF_GROUP_TITLE": "EXIF de l'image" + "EXIF_GROUP_TITLE": "EXIF de l'image", + "EFFECTIVITY_GROUP_TITLE": "Validité" }, "INFO_DRAWER": { "TITLE": "Détails", @@ -456,7 +459,20 @@ "CATEGORIES": { "MODIFIED_DATE": "Date de Modification", "SIZE": "Taille", + "SIZE_OPTIONS": { + "SMALL": "Petite", + "MEDIUM": "Moyenne", + "LARGE": "Grande", + "HUGE": "Énorme" + }, "CREATED_DATE": "Date de création" + }, + "FACET_QUERIES": { + "TODAY": "Aujourd'hui", + "THIS_WEEK": "Cette semaine", + "THIS_MONTH": "Ce mois", + "LAST_6_MONTHS": "Au cours des 6 derniers mois", + "THIS_YEAR": "Cette année" } }, "CORE": { @@ -484,4 +500,4 @@ } } } -} +} \ No newline at end of file diff --git a/src/assets/i18n/it.json b/src/assets/i18n/it.json index 8661bc27f2..68c9472c7f 100644 --- a/src/assets/i18n/it.json +++ b/src/assets/i18n/it.json @@ -1,5 +1,6 @@ { "APP": { + "COPYRIGHT": "© 2017 - 2019 Alfresco Software, Inc. Tutti i diritti riservati.", "ABOUT": { "VERSION": "Versione:", "PLUGINS": { @@ -164,6 +165,7 @@ "FOUND_ONE_RESULT": "{{ number }} risultato trovato", "CUSTOM_ROW": { "MODIFIED": "Modificato", + "BY_USER": "da {{ user }}", "LOCATION": "Località", "SIZE": "Dimensione" }, @@ -333,7 +335,8 @@ } }, "CONTENT_METADATA": { - "EXIF_GROUP_TITLE": "Immagine EXIF" + "EXIF_GROUP_TITLE": "Immagine EXIF", + "EFFECTIVITY_GROUP_TITLE": "Validità" }, "INFO_DRAWER": { "TITLE": "Dettagli", @@ -456,7 +459,20 @@ "CATEGORIES": { "MODIFIED_DATE": "Data di modifica", "SIZE": "Dimensione", + "SIZE_OPTIONS": { + "SMALL": "Piccolo", + "MEDIUM": "Media", + "LARGE": "Grande", + "HUGE": "Enorme" + }, "CREATED_DATE": "Data di creazione" + }, + "FACET_QUERIES": { + "TODAY": "Oggi", + "THIS_WEEK": "Questa settimana", + "THIS_MONTH": "Questo mese", + "LAST_6_MONTHS": "Negli ultimi 6 mesi", + "THIS_YEAR": "Quest'anno" } }, "CORE": { @@ -484,4 +500,4 @@ } } } -} +} \ No newline at end of file diff --git a/src/assets/i18n/ja.json b/src/assets/i18n/ja.json index 0ba0f8e0ad..bc19588599 100644 --- a/src/assets/i18n/ja.json +++ b/src/assets/i18n/ja.json @@ -1,5 +1,6 @@ { "APP": { + "COPYRIGHT": "© 2017 - 2019 Alfresco Software, Inc。 All rights reserved。", "ABOUT": { "VERSION": "バージョン:", "PLUGINS": { @@ -164,6 +165,7 @@ "FOUND_ONE_RESULT": "{{ number }} 件見つかりました", "CUSTOM_ROW": { "MODIFIED": "変更日", + "BY_USER": "変更者: {{ user }}", "LOCATION": "場所", "SIZE": "サイズ" }, @@ -333,7 +335,8 @@ } }, "CONTENT_METADATA": { - "EXIF_GROUP_TITLE": "画像の Exif" + "EXIF_GROUP_TITLE": "画像の Exif", + "EFFECTIVITY_GROUP_TITLE": "有効性" }, "INFO_DRAWER": { "TITLE": "詳細", @@ -456,7 +459,20 @@ "CATEGORIES": { "MODIFIED_DATE": "変更日", "SIZE": "サイズ", + "SIZE_OPTIONS": { + "SMALL": "小", + "MEDIUM": "中", + "LARGE": "大", + "HUGE": "特大" + }, "CREATED_DATE": "作成日" + }, + "FACET_QUERIES": { + "TODAY": "今日", + "THIS_WEEK": "今週", + "THIS_MONTH": "今月", + "LAST_6_MONTHS": "過去 6 か月", + "THIS_YEAR": "今年" } }, "CORE": { @@ -484,4 +500,4 @@ } } } -} +} \ No newline at end of file diff --git a/src/assets/i18n/nl.json b/src/assets/i18n/nl.json index a36c750989..9da09b0e35 100644 --- a/src/assets/i18n/nl.json +++ b/src/assets/i18n/nl.json @@ -1,5 +1,6 @@ { "APP": { + "COPYRIGHT": "© 2017 - 2019 Alfresco Software, Inc. Alle rechten voorbehouden.", "ABOUT": { "VERSION": "Versie:", "PLUGINS": { @@ -164,6 +165,7 @@ "FOUND_ONE_RESULT": "{{ number }} resultaat gevonden", "CUSTOM_ROW": { "MODIFIED": "Aangepast", + "BY_USER": "door {{ user }}", "LOCATION": "Locatie", "SIZE": "Grootte" }, @@ -333,7 +335,8 @@ } }, "CONTENT_METADATA": { - "EXIF_GROUP_TITLE": "EXIF afbeelding" + "EXIF_GROUP_TITLE": "EXIF afbeelding", + "EFFECTIVITY_GROUP_TITLE": "Effectiviteit" }, "INFO_DRAWER": { "TITLE": "Details", @@ -456,7 +459,20 @@ "CATEGORIES": { "MODIFIED_DATE": "Datum gewijzigd", "SIZE": "Grootte", + "SIZE_OPTIONS": { + "SMALL": "Klein", + "MEDIUM": "Gemiddeld", + "LARGE": "Groot", + "HUGE": "Zeer groot" + }, "CREATED_DATE": "Datum gemaakt" + }, + "FACET_QUERIES": { + "TODAY": "Vandaag", + "THIS_WEEK": "Deze week", + "THIS_MONTH": "Deze maand", + "LAST_6_MONTHS": "In de afgelopen 6 maanden", + "THIS_YEAR": "Dit jaar" } }, "CORE": { @@ -484,4 +500,4 @@ } } } -} +} \ No newline at end of file diff --git a/src/assets/i18n/pl.json b/src/assets/i18n/pl.json index c89a4b5332..0bd91f1595 100644 --- a/src/assets/i18n/pl.json +++ b/src/assets/i18n/pl.json @@ -1,5 +1,6 @@ { "APP": { + "COPYRIGHT": "© 2017 - 2019 Alfresco Software, Inc. Wszelkie prawa zastrzeżone.", "ABOUT": { "VERSION": "Wersja:", "PLUGINS": { @@ -164,6 +165,7 @@ "FOUND_ONE_RESULT": "Znaleziono wyników: {{ number }}", "CUSTOM_ROW": { "MODIFIED": "Zmodyfikowane", + "BY_USER": "przez: {{ user }}", "LOCATION": "Lokalizacja", "SIZE": "Rozmiar" }, @@ -333,7 +335,8 @@ } }, "CONTENT_METADATA": { - "EXIF_GROUP_TITLE": "Obraz EXIF" + "EXIF_GROUP_TITLE": "Obraz EXIF", + "EFFECTIVITY_GROUP_TITLE": "Obowiązywanie" }, "INFO_DRAWER": { "TITLE": "Szczegóły", @@ -456,7 +459,20 @@ "CATEGORIES": { "MODIFIED_DATE": "Data modyfikacji", "SIZE": "Rozmiar", + "SIZE_OPTIONS": { + "SMALL": "Mały", + "MEDIUM": "Średni", + "LARGE": "Duży", + "HUGE": "Ogromny" + }, "CREATED_DATE": "Data utworzenia" + }, + "FACET_QUERIES": { + "TODAY": "Dzisiaj", + "THIS_WEEK": "W tym tygodniu", + "THIS_MONTH": "W tym miesiącu", + "LAST_6_MONTHS": "W ciągu ostatnich 6 miesięcy", + "THIS_YEAR": "W tym roku" } }, "CORE": { @@ -484,4 +500,4 @@ } } } -} +} \ No newline at end of file diff --git a/src/assets/i18n/pt-BR.json b/src/assets/i18n/pt-BR.json index fb871726f3..2023e460bb 100644 --- a/src/assets/i18n/pt-BR.json +++ b/src/assets/i18n/pt-BR.json @@ -1,5 +1,6 @@ { "APP": { + "COPYRIGHT": "© 2017 - 2019 Alfresco Software, Inc. Todos os direitos reservados.", "ABOUT": { "VERSION": "Versão:", "PLUGINS": { @@ -164,6 +165,7 @@ "FOUND_ONE_RESULT": "{{ number }} resultados encontrados", "CUSTOM_ROW": { "MODIFIED": "Modificado", + "BY_USER": "por {{ user }}", "LOCATION": "Localização", "SIZE": "Tamanho" }, @@ -333,7 +335,8 @@ } }, "CONTENT_METADATA": { - "EXIF_GROUP_TITLE": "Imagem EXIF" + "EXIF_GROUP_TITLE": "Imagem EXIF", + "EFFECTIVITY_GROUP_TITLE": "Efetividade" }, "INFO_DRAWER": { "TITLE": "Detalhes", @@ -456,7 +459,20 @@ "CATEGORIES": { "MODIFIED_DATE": "Data de modificação", "SIZE": "Tamanho", + "SIZE_OPTIONS": { + "SMALL": "Pequeno", + "MEDIUM": "Médio", + "LARGE": "Grande", + "HUGE": "Enorme" + }, "CREATED_DATE": "Data de criação" + }, + "FACET_QUERIES": { + "TODAY": "Hoje", + "THIS_WEEK": "Esta semana", + "THIS_MONTH": "Este mês", + "LAST_6_MONTHS": "Nos últimos seis meses", + "THIS_YEAR": "Este ano" } }, "CORE": { @@ -484,4 +500,4 @@ } } } -} +} \ No newline at end of file diff --git a/src/assets/i18n/ru.json b/src/assets/i18n/ru.json index 59d69ef409..ec190141d7 100644 --- a/src/assets/i18n/ru.json +++ b/src/assets/i18n/ru.json @@ -1,5 +1,6 @@ { "APP": { + "COPYRIGHT": "© 2017 - 2019 Alfresco Software, Inc. Все права защищены.", "ABOUT": { "VERSION": "Версия:", "PLUGINS": { @@ -164,6 +165,7 @@ "FOUND_ONE_RESULT": "Найден результат: {{ number }}", "CUSTOM_ROW": { "MODIFIED": "Изменено", + "BY_USER": "пользователем {{ user }}", "LOCATION": "Местоположение", "SIZE": "Размер" }, @@ -333,7 +335,8 @@ } }, "CONTENT_METADATA": { - "EXIF_GROUP_TITLE": "EXIF данные изображения" + "EXIF_GROUP_TITLE": "EXIF данные изображения", + "EFFECTIVITY_GROUP_TITLE": "Эффективность" }, "INFO_DRAWER": { "TITLE": "Сведения", @@ -456,7 +459,20 @@ "CATEGORIES": { "MODIFIED_DATE": "Дата изменения", "SIZE": "Размер", + "SIZE_OPTIONS": { + "SMALL": "Маленький", + "MEDIUM": "Средний", + "LARGE": "Большой", + "HUGE": "Огромный" + }, "CREATED_DATE": "Дата создания" + }, + "FACET_QUERIES": { + "TODAY": "Сегодня", + "THIS_WEEK": "На этой неделе", + "THIS_MONTH": "В этом месяце", + "LAST_6_MONTHS": "За последние 6 месяцев", + "THIS_YEAR": "В этом году" } }, "CORE": { @@ -484,4 +500,4 @@ } } } -} +} \ No newline at end of file diff --git a/src/assets/i18n/sv.json b/src/assets/i18n/sv.json index f6a1aad311..b15802d7d8 100644 --- a/src/assets/i18n/sv.json +++ b/src/assets/i18n/sv.json @@ -1,5 +1,6 @@ { "APP": { + "COPYRIGHT": "© 2017 - 2019 Alfresco Software, Inc. Alla rättigheter förbehålls.", "ABOUT": { "VERSION": "Version:", "PLUGINS": { @@ -164,6 +165,7 @@ "FOUND_ONE_RESULT": "{{ number }} resultat hittades", "CUSTOM_ROW": { "MODIFIED": "Modifierad", + "BY_USER": "av {{ user }}", "LOCATION": "Plats", "SIZE": "Storlek" }, @@ -333,7 +335,8 @@ } }, "CONTENT_METADATA": { - "EXIF_GROUP_TITLE": "Bild EXIF" + "EXIF_GROUP_TITLE": "Bild EXIF", + "EFFECTIVITY_GROUP_TITLE": "Giltighet" }, "INFO_DRAWER": { "TITLE": "Detaljer", @@ -456,7 +459,20 @@ "CATEGORIES": { "MODIFIED_DATE": "Modifierad datum", "SIZE": "Storlek", + "SIZE_OPTIONS": { + "SMALL": "Litet", + "MEDIUM": "Medium", + "LARGE": "Stort", + "HUGE": "Jättestort" + }, "CREATED_DATE": "Skapad datum" + }, + "FACET_QUERIES": { + "TODAY": "I dag", + "THIS_WEEK": "Denna vecka", + "THIS_MONTH": "Denna månad", + "LAST_6_MONTHS": "Under de senaste 6 månaderna", + "THIS_YEAR": "Detta år" } }, "CORE": { @@ -484,4 +500,4 @@ } } } -} +} \ No newline at end of file diff --git a/src/assets/i18n/zh-CN.json b/src/assets/i18n/zh-CN.json index 03cd2692ab..ea024e32bb 100644 --- a/src/assets/i18n/zh-CN.json +++ b/src/assets/i18n/zh-CN.json @@ -1,5 +1,6 @@ { "APP": { + "COPYRIGHT": "© 2017 - 2019 Alfresco Software, Inc。保留所有权利。", "ABOUT": { "VERSION": "版本:", "PLUGINS": { @@ -164,8 +165,9 @@ "FOUND_ONE_RESULT": "找到 {{ number }} 个结果", "CUSTOM_ROW": { "MODIFIED": "已修改", + "BY_USER": "由 {{ user }}", "LOCATION": "位置", - "SIZE": "字号(&S)" + "SIZE": "大小" }, "UNKNOWN_LOCATION": "未知", "NO_RESULTS": "您的搜索返回了 0 个结果", @@ -229,7 +231,7 @@ "COLUMNS": { "ID": "ID", "NAME": "名称", - "SIZE": "字号(&S)", + "SIZE": "大小", "MODIFIED_ON": "已修改", "MODIFIED_BY": "修改人", "VISIBILITY": "可见性", @@ -310,11 +312,11 @@ }, "NODE_COPY": { "SINGULAR": "已复制 {{ success }} 项目", - "PLURAL": "已复制 {{ success }} 个项目", + "PLURAL": "已复制 {{ success }} 项目", "PARTIAL_SINGULAR": "已复制 {{ success }} 项目,{{ failed }} 无法复制。", - "PARTIAL_PLURAL": "已复制 {{ success }} 个项目,{{ failed }} 无法复制。", + "PARTIAL_PLURAL": "已复制 {{ success }} 项目,{{ failed }} 无法复制。", "FAIL_SINGULAR": "{{ failed }} 项目无法复制。", - "FAIL_PLURAL": "{{ failed }} 个项目无法复制。" + "FAIL_PLURAL": "{{ failed }} 项目无法复制。" }, "NODE_MOVE": { "SINGULAR": "已移动 {{ success }} 项目。", @@ -333,7 +335,8 @@ } }, "CONTENT_METADATA": { - "EXIF_GROUP_TITLE": "图像EXIF" + "EXIF_GROUP_TITLE": "图像EXIF", + "EFFECTIVITY_GROUP_TITLE": "有效性" }, "INFO_DRAWER": { "TITLE": "详细信息", @@ -347,9 +350,9 @@ }, "NODE_SELECTOR": { "COPY_ITEM": "将 '{{ name }}' 复制到...", - "COPY_ITEMS": "将 {{ number }} 项复制到...", + "COPY_ITEMS": "将 {{ number }} 个项目复制到...", "MOVE_ITEM": "将 '{{ name }}' 移动到...", - "MOVE_ITEMS": "将 {{ number }} 项移动到...", + "MOVE_ITEMS": "将 {{ number }} 个项目移动到...", "SEARCH": "搜索" }, "PERMISSIONS": { @@ -442,7 +445,7 @@ "FILENAME": "文件名", "TITLE": "标题", "MODIFIED_DATE": "修改日期", - "SIZE": "字号(&S)", + "SIZE": "大小", "TYPE": "类型", "MODIFIER": "修改者", "CREATE_DATE": "创建日期" @@ -455,15 +458,28 @@ }, "CATEGORIES": { "MODIFIED_DATE": "修改日期", - "SIZE": "字号(&S)", + "SIZE": "大小", + "SIZE_OPTIONS": { + "SMALL": "小", + "MEDIUM": "中", + "LARGE": "大", + "HUGE": "特大" + }, "CREATED_DATE": "创建日期" + }, + "FACET_QUERIES": { + "TODAY": "今天", + "THIS_WEEK": "本周", + "THIS_MONTH": "本月", + "LAST_6_MONTHS": "最近 6 个月", + "THIS_YEAR": "今年" } }, "CORE": { "METADATA": { "ACTIONS": { "SAVE": "保存更改", - "CANCEL": "丢弃更改" + "CANCEL": "放弃更改" } } }, @@ -484,4 +500,4 @@ } } } -} +} \ No newline at end of file From ff87c7865fe289fe9188406e605200f8e1039171 Mon Sep 17 00:00:00 2001 From: Suzana Dirla Date: Fri, 5 Jul 2019 14:11:29 +0300 Subject: [PATCH 246/259] [ACA-2460] nb.json updated (#1149) --- src/assets/i18n/nb.json | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/assets/i18n/nb.json b/src/assets/i18n/nb.json index dc0008e883..80bb2982f1 100644 --- a/src/assets/i18n/nb.json +++ b/src/assets/i18n/nb.json @@ -1,5 +1,6 @@ { "APP": { + "COPYRIGHT": "© 2017 - 2019 Alfresco Software, Inc. Med enerett.", "ABOUT": { "VERSION": "Versjon:", "PLUGINS": { @@ -164,6 +165,7 @@ "FOUND_ONE_RESULT": "{{ number }} resultat funnet", "CUSTOM_ROW": { "MODIFIED": "Endret", + "BY_USER": "av {{ user }}", "LOCATION": "Sted", "SIZE": "Størrelse" }, @@ -333,7 +335,8 @@ } }, "CONTENT_METADATA": { - "EXIF_GROUP_TITLE": "Bilde-EXIF" + "EXIF_GROUP_TITLE": "Bilde-EXIF", + "EFFECTIVITY_GROUP_TITLE": "Effektivitet" }, "INFO_DRAWER": { "TITLE": "Detaljer", @@ -456,7 +459,20 @@ "CATEGORIES": { "MODIFIED_DATE": "Endringsdato", "SIZE": "Størrelse", + "SIZE_OPTIONS": { + "SMALL": "Liten", + "MEDIUM": "Middels", + "LARGE": "Stor", + "HUGE": "Enorm" + }, "CREATED_DATE": "Opprettelsesdato" + }, + "FACET_QUERIES": { + "TODAY": "I dag", + "THIS_WEEK": "Denne uken", + "THIS_MONTH": "Denne måned", + "LAST_6_MONTHS": "i de siste 6 månedene", + "THIS_YEAR": "Dette året" } }, "CORE": { From db75234b244ee21e4c30b631a4422d78341ad4e7 Mon Sep 17 00:00:00 2001 From: Suzana Dirla Date: Fri, 5 Jul 2019 16:17:58 +0300 Subject: [PATCH 247/259] [ACA-2460] ar.json updated (#1151) --- src/assets/i18n/ar.json | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/assets/i18n/ar.json b/src/assets/i18n/ar.json index b49e7f81e9..e8e65f6b95 100644 --- a/src/assets/i18n/ar.json +++ b/src/assets/i18n/ar.json @@ -166,7 +166,7 @@ "CUSTOM_ROW": { "MODIFIED": "تم التعديل", "BY_USER": "بواسطة {{ user }}", - "LOCATION": "مكان", + "LOCATION": "موقع", "SIZE": "الحجم" }, "UNKNOWN_LOCATION": "غير معروف", @@ -236,7 +236,7 @@ "MODIFIED_BY": "تم التعديل بواسطة", "VISIBILITY": "رؤية", "TITLE": "العنوان", - "LOCATION": "مكان", + "LOCATION": "موقع", "SHARED_BY": "تمت المشاركة بواسطة", "DELETED_ON": "تم الحذف", "DELETED_BY": "تم الحذف بواسطة", @@ -249,7 +249,7 @@ }, "MESSAGES": { "ERRORS": { - "CANNOT_NAVIGATE_LOCATION": "يتعذر فتح هذا المكان", + "CANNOT_NAVIGATE_LOCATION": "يتعذر فتح هذا الموقع", "MISSING_CONTENT": "لم يعد هذا العنصر موجودًا أو ليس لديك إذن لعرضه.", "GENERIC": "كان الإجراء غير ناجح. حاول مرة أخرى أو اتصل بفريق تكنولوجيا المعلومات.", "CONFLICT": "هذا الاسم قيد الاستخدام بالفعل، جرّب اسمًا مختلفًا.", @@ -268,8 +268,8 @@ "SINGULAR": "تعذر حذف {{ name }}" }, "NODES_RESTORE": { - "PARTIAL_PLURAL": "لم تتم استعادة {{ number }} من العناصر بسبب مشكلات في مكان الاستعادة", - "NODE_EXISTS": "تتعذر الاستعادة، يوجد {{ name }} بالفعل", + "PARTIAL_PLURAL": "لم تتم استعادة {{ number }} من العناصر بسبب مشكلات في موقع الاستعادة", + "NODE_EXISTS": "تتعذر استعادة {{ name }}، الموقع الأصلي لم يعد موجودًا", "LOCATION_MISSING": "تتعذر استعادة {{ name }}، المكان الأصلي لم يعد موجودًا", "GENERIC": "حدثت مشكلة في استعادة {{ name }}" } @@ -287,8 +287,8 @@ "CONFLICT": "لم يتم تحميل إصدار جديد، يوجد ملف آخر بنفس الاسم بالفعل.", "500": "خطأ في خادم الإنترنت، حاول مرة أخرى أو اتصل بدعم تكنولوجيا المعلومات [500]", "504": "انتهلت مهلة الخادم، حاول مرة أخرى أو اتصل بدعم تكنولوجيا المعلومات [504]", - "403": "أذونات غير كافية للتحميل في هذا المكان [403]", - "404": "مكان التحميل لم يعد موجودًا [404]" + "403": "ت غير كافية للتحميل في هذا الموقع [403]", + "404": "التحميل لم يعد موجودًا [404]" } }, "INFO": { @@ -454,7 +454,7 @@ "FILE_TYPE": "نوع الملف", "CREATOR": "المنشئ", "MODIFIER": "المعدل", - "LOCATION": "مكان" + "LOCATION": "موقع" }, "CATEGORIES": { "MODIFIED_DATE": "تاريخ التعديل", @@ -500,4 +500,4 @@ } } } -} \ No newline at end of file +} From 229c589596cbf4c89a228d63e2aa631e4fbcb014 Mon Sep 17 00:00:00 2001 From: Suzana Dirla Date: Fri, 5 Jul 2019 18:07:19 +0300 Subject: [PATCH 248/259] [ACA-2654] show ellipsis for long Size column headers (#1150) * allow display of ellipsis for Size column also * styles will be available on next ADF version --- src/assets/app.extensions.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/assets/app.extensions.json b/src/assets/app.extensions.json index fb754c4fb4..9f08bdab08 100644 --- a/src/assets/app.extensions.json +++ b/src/assets/app.extensions.json @@ -1110,7 +1110,7 @@ "key": "content.sizeInBytes", "title": "APP.DOCUMENT_LIST.COLUMNS.SIZE", "type": "fileSize", - "class": "adf-no-grow-cell", + "class": "adf-no-grow-cell adf-ellipsis-cell", "sortable": true, "desktopOnly": true }, @@ -1245,7 +1245,7 @@ "key": "content.sizeInBytes", "title": "APP.DOCUMENT_LIST.COLUMNS.SIZE", "type": "fileSize", - "class": "adf-no-grow-cell", + "class": "adf-no-grow-cell adf-ellipsis-cell", "sortable": true, "desktopOnly": true }, @@ -1311,7 +1311,7 @@ "key": "content.sizeInBytes", "title": "APP.DOCUMENT_LIST.COLUMNS.SIZE", "type": "fileSize", - "class": "adf-no-grow-cell", + "class": "adf-no-grow-cell adf-ellipsis-cell", "sortable": true, "desktopOnly": true }, @@ -1359,7 +1359,7 @@ "key": "sizeInBytes", "title": "APP.DOCUMENT_LIST.COLUMNS.SIZE", "type": "fileSize", - "class": "adf-no-grow-cell", + "class": "adf-no-grow-cell adf-ellipsis-cell", "sortable": true, "desktopOnly": true }, @@ -1416,7 +1416,7 @@ "key": "content.sizeInBytes", "title": "APP.DOCUMENT_LIST.COLUMNS.SIZE", "type": "fileSize", - "class": "adf-no-grow-cell", + "class": "adf-no-grow-cell adf-ellipsis-cell", "sortable": true, "desktopOnly": true }, From b80c296125179871d1852f634fe5f35f7ae9c8e5 Mon Sep 17 00:00:00 2001 From: Suzana Dirla Date: Fri, 5 Jul 2019 19:23:34 +0300 Subject: [PATCH 249/259] [ACA-2460] es.json updated (#1152) --- src/assets/i18n/es.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/assets/i18n/es.json b/src/assets/i18n/es.json index 545afb029e..f9bb686987 100644 --- a/src/assets/i18n/es.json +++ b/src/assets/i18n/es.json @@ -461,7 +461,7 @@ "SIZE": "Tamaño", "SIZE_OPTIONS": { "SMALL": "Pequeño", - "MEDIUM": "Media", + "MEDIUM": "Mediano", "LARGE": "Grande", "HUGE": "Enorme" }, @@ -500,4 +500,4 @@ } } } -} \ No newline at end of file +} From 8a161d7828004f2609431555acbd795e37aaf32d Mon Sep 17 00:00:00 2001 From: Suzana Dirla Date: Mon, 8 Jul 2019 14:02:14 +0300 Subject: [PATCH 250/259] [ACA-2460] translation small update (#1154) --- src/assets/i18n/it.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/assets/i18n/it.json b/src/assets/i18n/it.json index 68c9472c7f..14373cc794 100644 --- a/src/assets/i18n/it.json +++ b/src/assets/i18n/it.json @@ -460,7 +460,7 @@ "MODIFIED_DATE": "Data di modifica", "SIZE": "Dimensione", "SIZE_OPTIONS": { - "SMALL": "Piccolo", + "SMALL": "Piccola", "MEDIUM": "Media", "LARGE": "Grande", "HUGE": "Enorme" @@ -500,4 +500,4 @@ } } } -} \ No newline at end of file +} From de46b7f1fb6687c3f74338c842e119ef0328abdd Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Tue, 9 Jul 2019 14:32:17 +0300 Subject: [PATCH 251/259] remove OAUTH check (#1156) --- projects/adf-office-services-ext/src/lib/evaluators.ts | 7 ------- 1 file changed, 7 deletions(-) diff --git a/projects/adf-office-services-ext/src/lib/evaluators.ts b/projects/adf-office-services-ext/src/lib/evaluators.ts index 037df58511..10aa26aa6d 100644 --- a/projects/adf-office-services-ext/src/lib/evaluators.ts +++ b/projects/adf-office-services-ext/src/lib/evaluators.ts @@ -1,5 +1,4 @@ import { RuleContext, RuleParameter } from '@alfresco/adf-extensions'; -import { AuthenticationService } from '@alfresco/adf-core'; import { getFileExtension, supportedExtensions } from './utils'; export function canOpenWithOffice( @@ -14,12 +13,6 @@ export function canOpenWithOffice( return false; } - // todo: needs to have typed access via SDK (1.8) - const auth: AuthenticationService = (context).auth; - if (auth && auth.isOauth()) { - return false; - } - if (!context || !context.selection) { return false; } From 16291f9ad66b21b83ef512587dee960ae2a9d381 Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Tue, 9 Jul 2019 17:06:49 +0300 Subject: [PATCH 252/259] remove sign out action (#1157) --- src/assets/plugins/app.header.json | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/assets/plugins/app.header.json b/src/assets/plugins/app.header.json index d8ed5e753a..8e582c1317 100644 --- a/src/assets/plugins/app.header.json +++ b/src/assets/plugins/app.header.json @@ -47,15 +47,6 @@ "actions": { "click": "app.actions.about" } - }, - { - "id": "app.header.logout", - "title": "APP.SIGN_OUT", - "description": "APP.SIGN_OUT", - "icon": "exit_to_app", - "actions": { - "click": "LOGOUT" - } } ] } From ea022ba2e86ce737f1db2f5fda768a388d14d966 Mon Sep 17 00:00:00 2001 From: john-knowles <18680913+john-knowles@users.noreply.github.com> Date: Wed, 10 Jul 2019 07:43:21 +0100 Subject: [PATCH 253/259] Add files via upload (#1159) --- alfresco.png | Bin 9661 -> 7578 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/alfresco.png b/alfresco.png index fc2bcdeccb3c2620219a0f2c727212fa64f3b727..ad238ea3579932890defa6be87f242042b87b687 100644 GIT binary patch literal 7578 zcmV;L9cAK)P) zcX(7){{LTRCT)^H3MuqJKmkFTqM!)q>MF8gMGyrW_ElHKc6WE~&P8YKYeC&r0bLM# zS&^>_D2lqcDhMc2rHX+hgcMSzoZlbk4s$b^mJrFKxkgIaAQgO4%Acf^3#616NGX$!RQm}e&>j%&U7?h6Fz_TWw!!OX<<4q$ z9B81t)5>UB2e?rP(bS&(Ng#p4MY|D1O8I->sSh_*@cVylrK-Uj zSL3&x(w%!w?TLVQfs2F?Eg6+S0{EvKb zd3~!ov2aZ({R`5$VPw}Cz>JXF9x3HA;7K9GhpnnOfdmc{F;@^Nr2uXNX4QFo>5Dg3 zuzYJJ8_VjbtoM?UVy921G}0Oyn0e+=6z69!_uCR&OLx-X^~cu>DM@N<RDR6}l;+MmC=L8an8&L@&rAz}}k#OEitM>BOPj*pJ z-%_`b^$qw+N7DOZnaJOGFamHJlcz?tGsFlcu#%AYr2OAjg{)7}8{Oz3ZM5lh?+o`X>v-A(hnmu{IYY9hV0!JEQ2_mKJ2{@lwxrZg255%lQ zdRtm%8|xc6=g}2R=%34PkIrd!&tFrEzos^9UElAnMr0I3Zmgja?+P8He>iY$%+4i{ zz+oWL418xrohS9-&wh@t78%~IyL-<8Uif?`w~g)|B$|}?D!SNe#`P~iR_=(|rY!v-K%{YTcQj6D zy3qspUC8B7|4e(dlLRaS?k2d>B=Elo;RrGaU|mUg9U&YG!jIV;M*1r>paZ z$Y$Tn4i0+drQ_ebDvnkqvSKU1fVevvKdz?bcXO_$8~N?r&Q-uj^SBE56EFcd4@H^; z{>uobgJf4X`kFcUl5K))M-oCnWxbasUvr(q)*%D`fvSkQ$j0Kih#)~(dOiIO%c(yJ!9}k`3v9j*{U7LkkH(p zfpwer^3sxx^zWU|g6mJzDXS_92@*@%KOo?w>Y-Gm4Y&E_Q-VVk^o( z^hj5UBcaGkMfA!*R(cWH#QxW~Lc12}Ag zXu6SYIc@J%FoAZ$p{ZR;c?mFYLus9D+&|W^Vn+>wflQiAv*bZ$a@P7bF08+|c!2C^RbztQzoIItQVrnu z`nY56SJZoaEWBg@mn_`C7t&lwJW-OSOmf_Gavq)!Z$viiz&<<&QlpDw07$TPp27Bt zuUWSBNgBKd8P#*TA*KALts(KI$u*#y*8>X!_uMY$W=%I%0;7O*RLK87+R(-Xl(G+y zVY!v1>Be~>#s32wYqnSAb~%@asV@g*b?gNEI1cEAa%$EBCBV19o4|W+m$MZj1ZcX^9XJ~3h{^-1KsjdHoCjo1VgrCK=B0XI ztJ~%LDatc}$aTAUX?0+#UsUh$+b@586P1BXK%2ncDH~sD^f)X4q~uTYzX9N%llwDi z!H=wh$Rr7nBcL-LvELIceGAxx^XVbIMFA}?F>}%Twh=cuu0R6>28lk(B0k;5`0lmW%@oT#AAJq5!vfJg1nWAcvcq&Q~7)2O2hNc^Pfj5B1+%D&iklUxC ztd^5d#2;ppQVs(KJ-u=dKkaYs#1okr*s?mr>X(8^l2^al%^Q~;!*NB~;l(W>&@Vkc zNRFC~ts_UB1N%`A@$H^BDXH0T=<>%~pG4yC1x$;tq86|!=P!i0{~9U;1mHMLH-?5O zb3~!(MvA5zF9RQ-9Hij}K&GiPeTJIt!;u5js`Gnbqox}XouHa-+=fbr4v=FHYO=T+ zHQPRba&`tpjefuiO*eiMrOs=BZNQ%iPY%p?8)dfjA5AxoiBz9i=P+Om@DeJzBGQ2B z4BQNC)^tNR&H4d!0k)Wbn}8Z2rCi+P^Phd}-&Rpk7k*{*S5!tc;f6xkY&?1GD9#<$ zRjnjDD|!0dK6J=T-8{V# zwMqn(t1MJV3BV6PXrF7%z64f~VdnGaTFR6FUjqApk5L148E}H7%zLPnYa`09lW*2_ zEpWW0oYU=c&I;-O2;eK!VDq3>q`!xo%{ATV1w2PEB&P)E?{+z>EoB7o6mXN}(M_lc z>2vd$B-Dy}mf6R^idzkgjvz)(L``6U$)E6*bs9p$K;+Fe2ppndEjko6Oj` ztAOPwk*`}4F!IYC)e*@7V9U)$q&x8MKY(nEkpSiQbIWrp;o4EWaoI6UTJR&?I%VLO zFn3Zv&MHoAJvka|2*=sj23*62(q(+G>A@D{0N7IgImNjnM@cC&Tbai`gW$lO6OJ4v zUL;76X_{`_*_wbtx64@-IM#H-ddn9^qzf%`9YJzz01V)Ds~(~0#ybSbQ371%b~!%@ zsdgvut)?3Bf`5zkuN={p3weHwL?1&O;)!N#Zwv6!X$z;A*$axi6&7 z-KZ7jSxq;l0nehu!-*&|UFvo@_iDN^A4See;Nc`7du>VVu_V$`v3Ki?Y-~c-Hz-qX zK!Fcqak}G`we-x-|vsqUKl_=!TlvCIR!~Y3DGJ zf)YmnUInfUC8nku7okE_01g0S+%D(VNEMos!1J1J>_Ulb0yTI(vM9%aKu`~Ab%+Xc z7QPJ##0pKuB#5RPCs^J=0++a5&evnq_p_!O<59k-Le#8&8K#9%(~T6AGdDnvmx0UO zE@xEBlH28+uj$4X;1j?BOx1K_k=x~b)zrtH50te5wtY468y!Sy3byQy*b6#g?^2*X zh50Q${!Y1E@#bcJEUl$iP8vec1YjS01xcg-Ow!qLQo>X zk$gy3N(QL+RPo05GpTGSiTI3^ewuuBarLPkaGm9NPQ+3{%tMI=0An@X=o{}~JWP0i z>mm$*6M=!|@z-vb^X*pF{UC57%A|ZH@R)ghKZ=-nnr;kmyPO*$JRgcX2~Ikxrham& zd0qu*t?b`?;1QHrd4#4L4!6r$Z}vHWJIrgX!EDt3{}_}JVmz?OS|ACiD9lWW8t|8y zV&|Sydopc!0sHH>vwX)w7XP%3gPw!tzhT7pvQqQdQRZqan(OM>FZ z44ThGM+ytvF6XWY_pG@p^CFaq2)D~wuIa`{DAV#FO*gu@UCt7e;yl?b_Nt~E(_MSS(M=b z)cdy}$h!Xd>Ej|*GOTMRFHP=GMZ;R|TsD*KRh2PA359@Ta~deA-p`o9f1}Y?%i7)V zF{)@f|6F|yQwBf5%_q2-`SDC@J+TLWhh#s!J2a7(7Jck`4JORva<*GT_ za=f@LopZaKk6F((-MGqf`aiAB_OxITL4u49y_p1jG`3InxYQ&YjUoG3jqa7j!b=9Q z;QL2-cgtsS?U)!KN4Ly0E*|_CUTJ6Us$1xjqsYFix`J2N-O7}~Pw>cZ9*K)2H69!5 zD$*!)co~r07%>Xv=)5ri|BlCkWh&>^FF79ZDuCBf)*lB-l$e0>6&y*diE=Nnk)Id1 zD8%{|FNRr;j|G;xUCz~-ZcGQ}0;wp&gcERTy0H;h0sI?S>2^6cN2%ND>sZ;A&V@m7 zd(`Q6Id^KhQHIjLdWGIk0$%QzYQJyFkbL_~tAdhA@7y%zUEGi7R=fCc`?qm5CJ2&a z(y@;qN#PGmZlbuu!9xUDTag9?N%GKX4>R-Qnbdn@vu|I05>0-=(A)+y(mja0^j;L@ z90zK4j|b-yl#{){+ie_JpjM(IO^|3}V?abs0{+$xZ5@g=bGw`iHQiW^GAo}?Fu=9H z`MDNA(~WYJ&*UB8l@NU(Ap6!GPWVU&@+`-3iPTZB8%2<0O*cAPeK$5C#BN~T-Q#*T z+r#S734Qo_&pUk73UUm{X*@)Zw4^+4UwSiDP0dZ*eyK?EbIpEUU3V+FX&rHon?;&E zzHNdJG}_r(lM-@O@SDE3BCu^knf>B{RXI-rhP3iyO`{xd#uFVe#PGL-ej$g8W;xVu zmvf`r<-8a*p#&y_vXE!;P~kdrfNf@YN&umCGz^Q$+8Cm4u(s$;^mAVulM^T5=L*%&mqifl3rq_lfAS#mVPeZVu*T27= zsY7P-*HdS4@A5y>5L!44em355i9*CumJwuiCB*D<2| zWB^SFu`FhX6|A=YH{CAh)Ht7O22D5aK$#x_uGDnn{&xE3w-#lnXx(g0H!|EVXZ#xq z90p89eJilQ^mm+r@^=K{)Sl9G<192oED|*k%V=ZiJ_-(AP1vX9Y5Kg|4d z=P|ke=?u#2Lf4E83e(dl&dOm-_W?LZ|A9H@yhUN=Q2Gxec^3_ z>E(UTa_O2#Wsfkdq2(8~v5r3hx0;_yO*bCVbmLR=(=FagOpp6*mP;qm+`rV;=z{KhlkYFg$0IRuYiu>L?AO}=`TZGD_M-%ev|`Et(dH<^b|e}OsY zyv~ag-{R@<3%K*7`{|sX#rqrYW5t2YrPVWd{+p>h@#WdP`NLgoC|!mhKZICZqCwM* zeyD#qsDI##@je>`OHiI%P$ETJ^HJIib0vGtJk3OfP{ajO2dR~byd2sm0cbp^z$=flO}g(FB!irqny zEj7%o<`CEzkbfGlt$&Vazm=0>lhk{aX*o5Da(AeLaYukU{%hS#LA?L2j&W74ex089T?-p9|^`rU!>{Aqan#aEnqrJ=b=()0oD_o zG~Pw|hd@OO98dhX-f|q+;NlsAr0W7K)pR3LvQ(gd4pfBh5cAR+f)hc&NMLndEsTdG znr`HxJo*9W=q{QEL>@vof_w>(pHUpii<(5m~vIg6VxdcUuV>I0u6|L}*fSEpOod9kJzR+}I zoF$?bP@Cgvx^V{Te;u&kH2~8CAu|?}E~r^{v8Eg2qV+-34Wa4AEd<3KFJ>5rX&t%% z6?F^B^0Y?NjXTW&Ypus-hPi)DF#M$&m=-2?#7$5%ascmWy77{x8v{eiq3K4trW;qI z64V0kQVm=XE*}TN?4#R?*Xr~qmPcRm}tExLH`NLJsm zCrXf3_w-;4-}=%eOdfa*$ze4g1+PCokNWU#7l7KPD?Hm;!aBRoce|YJ{hRF86=|}j z8*wJ{w=di-=S!#zJgem>A2on~hq5YJ$*~9+?shp_1UZ@^7h_Rbf&olKDaYGTR;2wX zGwzcF$#D?4%I$JKMF`Aj;FC}rHUuJrZ74BnyxCrW91^ut$`H59`DK)M_PJfo+s$YH zZMoGG<;0wT5+eiTs03VQy-|HKkv6cpCnKfP(Wo7rK4qc8M#{|oeH5#IA@!~RPS(^0 z55GlO-||t!s6vr?CGcUqsnQXLqm**5UwR8)TX#D@SFHT*K&DU2z;mYY7fjO|rbgyO`4dNPtCi&&22EG`@REZL5(Yk(0#i1JZQAGX+Nb0w=%9M=;`m0?&bLW z`mp2xkob9j!z@aw*YWh(^BG?}g22Y_`Dwn0_wdwE1+v~1YM2|cE8a?zDk zHCFKY`Z*+veKdLY(BQ2h$(Bl1T4#D>4`oo{ndE2m0VU&KC4`8X_L)Ee?Sc4AMu3#^ zMwHDt+}4@wss4di*4%=mb&(q#Qwur1`y`I-Jb@H@*k7vhpuE+y+q&;=0tvJgaT6o} zDP<?v-Y4&eHW}PdC#_F%VW_V4~yd5k(@v9er&=%4;5FGgR*Aq0=^SM{AydA zB#?j=ttLn$NGWdtp7>$khb-Ol7+!yTZiYdHXYt#k@4zmS7XjzTW428ofnN*lMi2lg z<<-E`mG!@*e!k-cHkExEQRFJjJetwHuA(@1B&fWK8S!KTCXm3diFPFjfRyrBlvj0J zo#y~M4t&dj`aRS&RgjvLNr%(|dSneDFQYf8WcfRV5U)k8G=T*Ee}j~Aq?GarDdid| wWxZ7JNh!BWDPNINUL>WAJ5)V^1pXWNe}uK;jG3$o^#A|>07*qoM6N<$f-Jn00RR91 literal 9661 zcmX|nbyU;u`~GMorKP*O9Ni^2x>E&2K)Qv|(%lWxN(s`f(hVcWMkBoeO4oPq&pE%} z^T)Pxc3#ixJl9>2{yBF8;UgJ%P_HVOWnb6VoOU1PK^z_KZu@kJ0**Vk_IEJ!3=%PIC!_`=6 zULVKNmsT@{qq8gvg_|l!&8-U92Zn@%6m-D4{M;6B!Q0kpA_u<$~~N}iiy2Gu%3J0E1RiHV7mp9FO^TTC=%>oa(a1;l+W zzIAtMs|qV~i|;EWFa7@gdwcI)pJ}(|SKcs>i@1WXT5;FYSF5Jqzhu-^EO0SNPwFHu z<`Nvtrt#jjvCH$~3Nf^+LYn6uggO4(JmNFB-ak|S3hnZqkR5iphL=TU%m$N}-Plet zAll9%!#{O~F7-?1RZ<|1JOcd7<6NN+bmOM}CBvI%eerHKcm|qqf@QMa)u9=x5RGr% zXgtnG9`EZm^MKj9dIli`r}g?gE;dQyzsq8G81~Wp@7>6j(<3tUAHuvs%R(Yv1#UqzU3meKfd{-C=#=C#`E3>~9z^Y}i) zHdvD(Mdc6Jx3Oq2ZLJIEuUG&yPimK`9}#FD!om-L|Lp%Aw@g?zmc5F|?X;8L-gEnt z7v|En)KG|@Db17dfgzOy|*sUps9C+MuR#`|A&28xtw){A(2o`XMON>4`c1t zghTIc9kNYazjL1Vn;-dK2$aP&=$=fQQ8wS^>f>lg{jsudp8T044^OpCA4v6k zA!twi-fD_XV~^wDX@SZfcQ0rB4DVq=xRY zT`Jx~aSxZkGyrQoP5SH|8d(_`86uuEvu;-M0`T8*`=H)RiL;`Gg~XR9Fuk#_#1lLJ zT=_dTmoF37Om-=%f1M<@Qn?CZD2&U>Ty`8fe|<1jKQSdy$!N&N`p>K*&rQyFD$D_8 z9Kmgg#91$mlM<`z;yVH$e+pr;XE+Fk`Pe^`ES5wU7s8nW3NE0!``KF6`@aiDdeT>D zx)<=U{50a3|4g{SlsXt_<2+?#&VL&aMA{8^j?4TwmPTKey{q&vWhTqOL&M$z@6nzKqD2HAsW++dR z4fXNgt}G8#Ppz)t8@r%F?SuM^+s~Db^5rj=clIkEm}XYNH(zY2bzW{RuLFSXf^MFC zWqODCu2A~W@h~|BtrA@S(Z&SHKyml~La-013(P`=OK& zx$oruFWML3$WL$jtqD;cy`92TlnbRe6@+JX?*JpSQi*!6jghx56_{X}LW{~WCnwS| z8gE0iZ~n61yuHrJmW)ey;sBi$GRr$Kh2Mb?N(nz3+(nQyu|LTO`eE2;zv+hAn~PqF z=;-L-pCB0%WdVh^W~Pd*ZbfQUFzVlPv-LzC{5TO&h6=)~frfjpC3r{mqTu4jMHhMAuY0@0C(2!ne{Tvfu5J=3AT zcM6rLH!-Wo3|c&!X)(gizHrYU9&IC@($V4^V}(@yN0`oC205eA0L>6&?U$u)PX0LN%kM1S~tvo zO6+rZ5ENWbqFdb7jQyfimv5Y3Q4oWyemQ8h>Kj@r`uNZvOrm>_O#gvBV!?dWfREn# zI1D)*QD^wAB`u@sE^9wt;+?GSo;TFs=-%BtDJ}@CEVINczQo|?#C4QAb<{PB=BW>J z$*eAH`CxVeXu8@jPrNC-3&ani=F92Rl9($D(u+#0NZ4Y+-H zPE|pLTbHr&?(_6Wk>J~R#`WBGdr2Z=<2)<9JsHSsm-iF-`1>;NNS|_g3!+27m^wx4 zh0VtV&G*J21`XG7zCSM<`p3S`3kFg(VO(SX*`&>hUKA$t3{OE&?dFrI9HCNTA4P9) zbeKG@dzt=WeNP8SVI;(}#}yj5`dh+TF!}2ARARvK%~|IOg9CZy z5@uB2BP;$ALTQ10s-mv0{w=I){d}{HHm9yw`|tbU`lo6AZxq#~};l7-NrrDidl;z1!*d zgwsy6PjrvBoS)GU(L1IMbYYyK{t)qcO0^$vSR{?jn$dED#iP{dz&z{aUY;>z<=-W8vU8*`MVVbN& zhC3BYW;Kd!on${BjPKGhAV-pPIwmLh!yyla4f&VxB&*}86H&UtBaHOp%iwJv2qL*% zrV~Rv$^Ks0={}nI@xWSvm(BJas}SR;vVhi0U3jw&hAUbWVD{&jKD?O|gSg_{8ynsX z3Hv#stS!w#1|`~1e^Y5o&6_?Nld`MM(M^_;kk6!xRSS^A>hY^Lj%b zVT}pN`m$Bg!;frpTVTo$XW87mv@()P&YAJwsuQS%;@`uE=nI5Av27CQCgi7)Q!##7 z1{Mvv((m>#9PAxV4@Q2B@INL&lYN?BqBS#c^H?eTB`k#&k9PaG0ZwP*8p(J5UAB!P zZUrmm0U(I}zIsRgPlakp74OQQbQ_!lc-1+7uhMUJM-BRuCzCVfl!8Y+-U(MP3Dg^+8(2#Ix?Y#CnvB7 zx)T@{c_cYfssGhO+fJzWNq81?r@Y}iEE4?sdouAThcGUVjBTSO@FX?KzMHb~Yq%o*kLJ3BvO zvFR+`u&GJ(`s4g_s0m-G?-2cmI`D@ceJ??P?ixeL(rRwcA-CqY9TFFxiB={?$;iy@LtCR{cfqW_OyAAo-MA3;9%1M{`>J0ZcWbg|Kt}@T`1TW2*I*#}H5m4@Dd3JWj@>;Dx&+A6ClB4EcAm zP+n?W6^wyp8Lok+M9)7Jt(o;J!J7q>yhaQ{^r&{x zA*M%!i8sW0+jMA;2)n@ic4 z>M2%k@%Od@$(U372M1MtFOy+Gl0^~GGoKI1S*fXM8|*c$p5H{{YjB!vCpxS~C&{Rk zsx%6Q| zEAv-}E1-#PJf=vO7|$DmKws7nhCFD~`Wl3nS1P%wYa--czr zx_FHT-8_2!v{wdNkP-4CbnwlV(E8MGq9qi+k(*3PcP|#U=0>_N&O9|ui+S4}b0`M*)L|@Um%DE+Qo)t;QIEfTZ;Rylf7f?`D%!@2dc9oqb0sntg_`_bJ5(kB=Ce z7t=0D_T}>o(>*%OpNo@TCqzq0r)KI1GKC1*8zGd?@dHgU)`!~xD1PE zt8Eb{M(EwerVLt`8e3)m)1oT1jelP-C!XDV@?&J2AT2xhJ~ubB<)R!X2+xe>@8r-Z zA1r4Xt47ywp4`CPDpGSUzwM`o)0LBCW^_PQ7ThNiuQa^niO=wng6o?y z!y@n1-Msm;A+YR*;WPDNTkP+I9%KZHpLBxIEEBo9mV6)#e@xYWVIFJ58v{>1{`%R+ zjjF2ik!L|snCKXYb|zTD2kM#me+|GCf@B#JZO!z#pK;Cyg7YBh3s<8v`-Kx;Gwy<; zmYqO)p)0){mQHu04nFd%4jgV>yO5rX zc<#@BBcqKcu5zxi6=$j|t;~7E>U#@57vyct{Zmyr3&&i!%-%`_@)ELj>*p?#ht-d7_QmMq-Bb@__@P;ariWE@I?5Bh z_U5yFh4(JxRr~(V14mL-()WDM`7(*-+iNB%AP_6SsMB#8AfS4GI;r21bA|19o{K)u zvgE~|c4dWcI^wW{jM1vZ6QUpYm)tU?&mE9vLS&+<@wK4v3@FfdV0;|Lv~>_8zDmaJ z<3~5{&-yb(`mpkW!JRbi=tLsxEQSj z>lTOan`FW&oY_z5Pn?%T0>qs($AYo@41@k)ddEWU`fo{k_N{Kmp1M6Rjp=)jsae zs1Wpe2uxo#FACb4IOR>6s`*mi%9(uyj!YbspJVCauW1cYbpea_9R$$YxR{UKPu8T3 zY5wJgIxNgG|43p3`;LqsW2QYzsh!*s*XShgSGi&=PPpkeF8_AK2X7|!; z*AzT|RsuY%1bdL}G8{Z2o^|p5ol>e@UmFqeCKu8Kp0vam-EyBwo+>9ilBRCwt`9V- zK)AP%SbuPvSu4-cz7ABzV|}papT} zz^ZvltntlqNn$TA(XPspkQ`+!-W@G)Y+zDvKTfA(L*fK^>^re7^*&MwEPoL21f&7% zbxuX1z9Q>S2w@fNu2A@M`KQ=^VvV&+jF`K_U^^D%F+(3f&v!ia&DpBP>0gZvR(SKe zPi7UdUQRJ<@$XM;E~kzgC?cxky<3D^t8OeBq6%|u>pcI&8h2$iQ1VIgu+v6)jvDFL z!2QQ*c2e~TGgmkGbNfF5bh&v@AlJEM$XF(sK5UrTb(~Pcce)CpLwsd@qQVi)!{Ul4 zC~^^LaLz9r%9@MvNC?&0{)+#}{oS7V57DX7(W zfZJJ*vsH@d zO;M$z2gn0hO?gw>DtkcwNBJ@Al7TKi!GHW=q%`vH_HjC1*8?QUzSf<0yWT5Ai5jaA zR-E$L=FnV|SlzHe^%noCR$4y?%*^YVnLa#S;t!wiF7}29D9&Lj7e|{Rc8s=6ht}aP z$ivDW!rbq@sF+EMnND_vK4Cw8$@e|le@%dbP?h``m7&NxR|)!K{5?m3s1T31XWZsq zS)3koFA=e~&zq;IU}KkwS{3gLkn&Exk25s$P!kTq(LAj$8)G9}@S2_6Uw z3ly`9eyygJ8e1iq7G4c=?t;JtamMQ|Y{ETq$+icgSNVwj3?`vE^8S4DUgbw~K>bGa7`{-<$S+@&Xa_|ik z*gP)t{$X*qR^Ut&ykd(PM0B4Rbd&^0cg z?gQwv^y4ogYWb9oT~d|GYYp%JHpa-*KO@-&t2M`0<6Sd3t@;k!;!^{bFie_p1s;8&P0TU89-_?*2Zy zagD(fiibj&qD098@w2E9vai>v8*cTs)LuT2U>ei%{L6fVq`c1+b$qQrR#$ye)s;xu zF55=Wi}eG)6lCf!G!@0ZJU90u}RKz+zpYt%{rc z6+Pyf(I20hx5gfCU}C#-8JVs#oSJP0@d5W#IZ~TE5r^*(M<0@0&f6bw{8NdBz&s_G)5%@z;0O<#S)TVc|Q; zzKU7NKl1$Vi%2_m{C_njxLsa6Ln*xRHIZoE5ZC1E&kaf(eDXr(z!N1Jo@n&Tsb2|v z`7j9SdU#A9u?oVq*6w;a^VKi7M&_;&DsX(gnr&~+1e6hXN1cv+B&jF*7?#x2oOIFq zhpLSF7dbJ%S#2b;gpISUSxwO0P|XagFX&1i(ICgIR}898gOD)W7*?*7gkb-ZO!cHOh`md*97xTZ5 zV4i;2yvo4`&Z9~=ir)bEV)x$YM7ly-A~Wv@?}Ori=ZfB7_iX>KrCMfgMCWMc1!KZV z-j|<<{HG?f!So(R_l52Yv>GM+9`!ccXRlTG4zc=+Nwi>lV@`%@h3H>QRfS2kx*~E! zQ!7Ha7=&{q7JF@}MSUQTFP<%b&f}g`;QNCeX99F7KH`WO?1;p8&m>Tz!Q1{k0JflQ zve==*Wesm`z#2m_W!wZ*J0vxC&y~9c8hE|o*6G;h!)L4Y&j(dPiAhKDuw`oVFR5Y# z?@5-%dZtr{jN1+>>CZE#*M2v46DKTy?vQ$B%0S3zFF3STszE(NC?@1abb#<&yPNFz z5yv^txH_ZLQzO~fV7Op)0qA!j02PmRtkJ(?_?+Q7{09r=uf&VT=7a0+9}>qp2Y62x z*wIR|xV6;MDMvPDe-!OaQTN%dT=G9l#^9=(<*NOcT5PS8e4j4aHEe^%@geWhGEKRG zqnmFHqK@pwx+gPxw5ra(Luub5XB0&H5JyY?Q_-A()iZF6p%cCa7E$kcY7sp8* zMBlw3^-9KZOU%Vuu$YkPn7-`xCBUgOytzufLlb+yQg*#D0Si?fh$j|6t4iU9oJ=)g z=`2&vM3`Z(m-jzl+@m^`5N1gj71@H@Aid7?%!BunO|e>nJ-yHXAzd$W>{=zeDv^qX zH_3)fpad1%c<^Qi7R}z|E|+vyC@t)+Q`(j@5Bml!uM&h)-|PFP>vlNWcROO2tXi{F z0?k~!#z7&N@TBRyy?eck+=%>3NG+#PC$n)jrm0P3PVfv3zP`B+Sw zF{VVt_{Du|^5=D`9JOQZH?t^V%!keI)xdz2QY24U9y8?{_K~JTd0e@+VK{|RF52`Pk1A27 zuNNvaI_dmfpiPahZ6tFicje-0z=S*z7&JRCYpTHS>G|^)wjuYHD^JhDAL(3gHaIk$ zX=rH86bJk7o$BTPn62Gi}Br{K| z7vI-gE+LJHre#U(%!E}S&5^x4ew0MHXX&WwnfKv|tqGfj62BjPSOmLs)eT3P?IlL+4w1ly`jN5G7$1@do%U3aieq`?LwBJWm&D~oSdS}#!ufGqc zEm4iOyjJd2fETh=3_Y_eY^8csBu*|L7>}96ST<`cYNhu1H(9e;?rTK1+L?!Tvp~0A znMby2G}~oAiD<63m9~DZsIBw(@~Bl!Q^Y9i1W#ALF6YOsq;*aRS*Cb?2h!x}%`a8t z-}CQhGTuX6YQ=JCXTPoAZK)bi2SCZ@7m(%MpE&!&?KGFz=i;1xl_k)kB%+{S_CGLS z8MVa`e$VAe``zKqE>?M;hX+6r0h#VZ$OsgX>*{URwYxUABHcG&K4+Nn!U+0O6-@W+ zweQ3J*${-T@uM@eST5rsc`YwwE{EcG%DN6qa})CSvp1UHb^auLl4Hbm7`@CMxBMASBC zdAkM>xcul!&&-NvOk7yq6LCAy42GVGvm1T3^qUa1tK8*qp*c1;$Zi*Go1M|?t&&kU zJ+Rbicl#OqyOE$G|I$c9p`5VkA5D3F>$3@>o0mRc_a*Voh%SAIiz6@xm1H8X>%uk4 zueUI>e6iCo6FCJR$%2-y5$= zzU15{4$e6h$E6ynriioRD^tr8Ta%V#O2>DvvW<{$X0wt_o7sa`dZnifKT%qK=4(K+ zer9GCILaF%$VJ$$1U%_OVC25?Fi6%`tX(hC0KCK2-Q|eIdH&?Q^W;x7SKs(jX^I>e zQ`a(axr={s8$yssR8j|NmwI#xT#m!s(c+pgxK+N!Pfm%r}YK zFfOmcz>jveU)oZ|zL|>N;ttpg;hpiDYq;CfrXe77K&r(Gf>94pi%wJYFdA!7&09(Z z?N3e~`K~vd-`)Q@Jo5tQci?YsedG6@I3V?t53Qqk2@TI6;b5JM?x3&4XHB^m~mPxpV;9`M>Nwc~D6*ybt^ z(BrCVYzYK2S9Ia)o%YC79C=hfhiol~o%CsPOSMYGF}@7RG1R#GBb)nue=zbcl5aV2 zQ0v;hiucq}XW-YY(u}=>(l2SZg;6Pk!9!3sWix$-@;|- zY3i&b^QM%y;W69#j=E%Hp8hXJU5?{S`|48SzOroG?ax78h>)M62vh@$-pQ)N3~Gy*Tk;4O0;a6f6U%W!Uy#g1S3ej31zqB1aHgi}>8`xQ&!2Tm2=c-nrn+JtOezg)ls$1R#!q3)*l+QCpG zzIcO*KT8|szF);NrOH5}k=v7yFuJ)9xJJT)46tp!XV+`fuCcTc?=Y4Ib#-`}6^ zADe*(RRvDImm*_+s9^B+S9%KC{S-)ha;Hv&T%8jQ_gt}W(4=3!{6?<Q>m|n2lZ&eh4m=|+VZhH9NRXrssk2MIghEv2faxh5oz{o1i-@4oNcIln=fwy*q zi=&+Cdbd*^jxFzOa#nK1_mAwh)4^e^rTXq(WdER85*>eA2oS#b{i1o5vbpXK|C?b* zD3AXHf;?g-IInke0vYbmAMm3-H{tsJsC5^xGQTVb8&k>=O4%)Vygs_tq$;Vbj|28~ zrBAZQ2W%CXblg%YkNR5Vw2a5lmkW#>OlCe5Z|qDh0ib1KL9aXhyJ2Ql#B=$8Suw9$ zzOD0P3`&|s6+Bg$#-3s5qO81q%=$Fe^b6~?nMj<%m_EA@@cVDK8>79WXSbp`ZNXAL zJ{DX&HtH^5ii5C^=OX{9blZ;Ua0<51`^F&1mVE8xZ(G6BCK{PbAh+MmlGuqXlNGnP zi0sV0j(Q7iS|Ez%6B>T(yNp=YKj&Zn7z9kp7~-n9{`9bV|NTb!*6+p8Xko+81}tS+ zGv#9?n$>Qid(Ockl*^#z2-rcv-EozUtf|nD4E>(eDxpwvq5X)i#2423EtwRmHe#>p zON$r+IJcL=rBi}yjWj9@Iw~Cl@Aw4&2WylpxSj%#SIMvDbcv>`3E#iMf~B4`uoUPyd<0-MUKs z@S9vckempGbBx>x8Q z!jt%e&oD5DuP-HFRtTObdb&=;3vk#&E4zx!Kse9W+1GAdfFo5%$q0NpdmKKLBck Date: Wed, 10 Jul 2019 08:31:04 +0100 Subject: [PATCH 254/259] Update README.md (#1158) * Update README.md * small fix * ACA version --- README.md | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 80560493a1..095b75fdad 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -

Alfresco - make business flow

+

Alfresco - Simply a better way to create amazing digital experiences

# Alfresco Content Application @@ -32,10 +32,10 @@ Please include a clear description, steps to reproduce and screenshots where app #### Features added in the latest release -- Edit Offline - lock and download files whilst editing -- Edit Online - edit files directly in Microsoft Office -- [Alfresco Full Text Search (FTS) syntax](https://alfresco-content-app.netlify.com/#/features/search-results?id=alfresco-full-text-search) - enhanced search input to support the Alfresco Search Query Language -- [Single Sign-On](https://alfresco-content-app.netlify.com/#/getting-started/sso) (SSO) support with Alfresco Identity Service and ADF 3.0.0, basic Kerberos support +- New language translations (Arabic, Czech, Danish, Finnish, Polish and Swedish) +- Automatic display of metadata aspects and properties +- Search result facet improvements +- Various extensibility improvements and enhancements Please refer to the [release notes] for details of all changes. @@ -47,11 +47,8 @@ Please refer to the [release notes] for details of all changes. - Folder rule creation - File/Folder linking via secondary association - File Library Management - - For managers: manage Library users and requests to join - Enhanced UI and user experience - - New language translations (Arabic, Czech, Danish, Finnish, Polish and Swedish). - Accessibility WCAG AA compliance - - Search result facet improvements - Search query input assistance - Metadata information drawer enhancements @@ -64,6 +61,7 @@ Read up on our guidelines for [contributing] and then check out one of our issue | ACA Version | Built with | Tested on | | ----------- | ---------- | --------- | +| ACA 1.8 | ADF 3.3.0 | ACS 6.1 | | ACA 1.7 | ADF 3.0.0 | ACS 6.1 | | ACA 1.6 | ADF 2.6.1 | ACS 6.1 | | ACA 1.5 | ADF 2.6.0 | ACS 6.0 | @@ -96,7 +94,11 @@ Read up on our guidelines for [contributing] and then check out one of our issue | 1.7 | Edit Offline | Lock and unlock for editing, download current version, upload new version. | | 1.7 | Edit with Microsoft Office | Extension to edit online with Alfresco Office Services (AOS) | | 1.7 | Single Sign-On (SSO) | Support for Alfresco Identity Service, with ADF 3.0.0 | -| 1.7 | Search Query Language | Enhanced search input using the Alfresco Search Query Language | +| 1.7 | Search Query Language | Enhanced search input using the Alfresco Search Query Language | +| 1.8 | Localizations . | Arabic, Czech, Danish, Finnish, Polish and Swedish | +| 1.8 | Metadata improvements | Automatic display of aspects and properties | +| 1.8 | Search facet improvements | Facet intervals and grouped facet queries | +| 1.8 | Extensibility improvements | Various - see [release notes](https://github.com/Alfresco/alfresco-content-app/releases) for details | [contributing]: https://github.com/Alfresco/alfresco-content-app/blob/master/CONTRIBUTING.md [github]: https://github.com/Alfresco/alfresco-content-app/issues From 8b7da657fe2493c385a3d15019b97f366c9ee6ee Mon Sep 17 00:00:00 2001 From: Suzana Dirla Date: Wed, 10 Jul 2019 17:05:31 +0300 Subject: [PATCH 255/259] [ACA-2652] ellipsis fix (#1160) --- src/app/ui/application.scss | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/app/ui/application.scss b/src/app/ui/application.scss index d6d67a516c..c2e53045dc 100644 --- a/src/app/ui/application.scss +++ b/src/app/ui/application.scss @@ -21,6 +21,9 @@ body { } // todo: move this to corresponding component theme files +.adf-container-full-width { + overflow: hidden; +} app-root, app-about, adf-layout-container, From 4125bd554873edf266d4e75db0d20cd7d2658c33 Mon Sep 17 00:00:00 2001 From: john-knowles <18680913+john-knowles@users.noreply.github.com> Date: Wed, 10 Jul 2019 16:12:28 +0100 Subject: [PATCH 256/259] Update README.md (#1162) --- docs/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/README.md b/docs/README.md index 82495c962d..51b3ed9169 100644 --- a/docs/README.md +++ b/docs/README.md @@ -24,6 +24,7 @@ The documentation is divided into the following sections: | ACA Version | Built with | Tested on | | ----------- | ---------- | --------- | +| ACA 1.8 | ADF 3.3.0 | ACS 6.1 | | ACA 1.7 | ADF 3.0.0 | ACS 6.1 | | ACA 1.6 | ADF 2.6.1 | ACS 6.1 | | ACA 1.5 | ADF 2.6.0 | ACS 6.0 | From 588a189ea16599ac56352198c8036b48b55d75d4 Mon Sep 17 00:00:00 2001 From: Suzana Dirla Date: Wed, 10 Jul 2019 18:13:02 +0300 Subject: [PATCH 257/259] update app prerequisites section (#1161) --- docs/getting-started/prerequisites.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/getting-started/prerequisites.md b/docs/getting-started/prerequisites.md index 5cb03903d0..96da8251c8 100644 --- a/docs/getting-started/prerequisites.md +++ b/docs/getting-started/prerequisites.md @@ -6,11 +6,11 @@ Title: Prerequisites This application uses the latest releases from Alfresco: -- [Alfresco ADF (2.6.0)](https://community.alfresco.com/community/application-development-framework/pages/get-started) -- [Alfresco Content Services (6.0)](https://www.alfresco.com/platform/content-services-ecm) - or [Alfresco Community Edition (6.0 - General Release: 201806)](https://www.alfresco.com/products/community/download) +- [Alfresco ADF (3.3.0)](https://community.alfresco.com/community/application-development-framework/pages/get-started) +- [Alfresco Content Services (6.1)](https://www.alfresco.com/platform/content-services-ecm) + or [Alfresco Community Edition (6.1 - General Availability 201901)](https://www.alfresco.com/products/community/download) **Note:** You also need [Node.js](https://nodejs.org/en/) (LTS) installed to build it locally from source code. The latest version of the Alfresco Content platform is required -due to the application using the latest [REST APIs](https://docs.alfresco.com/5.2/pra/1/topics/pra-welcome.html) developments. \ No newline at end of file +due to the application using the latest [REST APIs](https://docs.alfresco.com/5.2/pra/1/topics/pra-welcome.html) developments. From 5e3ea943c4384a68e7c08614fad364762febfc54 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Wed, 10 Jul 2019 16:35:01 +0100 Subject: [PATCH 258/259] update PR template --- .github/PULL_REQUEST_TEMPLATE.md | 46 +++++--------------------------- 1 file changed, 7 insertions(+), 39 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 5ccd541087..946326776e 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,44 +1,12 @@ -## PR Checklist -Please check if your PR fulfills the following requirements: +## Definition of Done -``` -- [ ] The commit message follows our guidelines: https://github.com/Alfresco/alfresco-content-app/blob/master/CONTRIBUTING.md#commit -- [ ] Tests for the changes have been added (for bug fixes / features) -- [ ] Docs have been added / updated (for bug fixes / features) -``` +- Technical Documentation +- Code compliant with Clean Coding rules and tslint +- Unit tests +- Automation tests -## PR Type -What kind of change does this PR introduce? - - -``` -[ ] Bugfix -[ ] Feature -[ ] Code style update (formatting, local variables) -[ ] Refactoring (no functional changes, no api changes) -[ ] Build related changes -[ ] CI related changes -[ ] Documentation content changes -[ ] Application / Infrastructure changes -[ ] Other... Please describe: -``` - -## What is the current behavior? - +## Current behavior Issue Number: N/A - -## What is the new behavior? - - -## Does this PR introduce a breaking change? -``` -[ ] Yes -[ ] No -``` - - - - -## Other information +## New behavior From f1fca4ae22e328f04f7dcd9680061c47634e2bd7 Mon Sep 17 00:00:00 2001 From: john-knowles <18680913+john-knowles@users.noreply.github.com> Date: Wed, 10 Jul 2019 17:45:42 +0100 Subject: [PATCH 259/259] Update internationalization.md (#1163) --- docs/getting-started/internationalization.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/getting-started/internationalization.md b/docs/getting-started/internationalization.md index de9ebbaf52..7b7d91eedc 100644 --- a/docs/getting-started/internationalization.md +++ b/docs/getting-started/internationalization.md @@ -17,6 +17,12 @@ The Content Application provides support for the following languages: - Brazilian Portuguese (`pt-BR`) - Russian (`ru`) - Simplified Chinese (`zh-CN`) +- Arabic (`ar`) +- Czech (`cs`) +- Danish (`da`) +- Finnish (`fi`) +- Polish (`pl`) +- Swedish (`sv`) The default language is English, however the current browser language is taken as the default one automatically when the application starts.