From 3bbffab9486ecfd48ec5507b4e495d6ccc91bc9b Mon Sep 17 00:00:00 2001 From: petkir Date: Mon, 22 Jun 2020 01:02:32 +0200 Subject: [PATCH] Property Pane with PNP Conttrolls --- samples/react-kanban-board/config/config.json | 6 +- samples/react-kanban-board/package-lock.json | 699 +++++++++++++++++- samples/react-kanban-board/package.json | 2 + .../src/kanban/KanbanBucket.tsx | 1 - .../src/kanban/KanbanBucketConfigurator.tsx | 4 +- .../kanbanBoard/KanbanBoardWebPart.ts | 254 +++++-- .../components/KanbanBoardV2.module.scss | 4 + .../kanbanBoard/components/KanbanBoardV2.tsx | 166 +++++ .../components/PropertyPaneBucketConfig.tsx | 82 ++ .../kanbanBoard/components/bucketOrder.tsx | 12 + .../webparts/kanbanBoard/components/helper.ts | 29 + samples/react-kanban-board/tsconfig.json | 2 +- 12 files changed, 1177 insertions(+), 84 deletions(-) create mode 100644 samples/react-kanban-board/src/webparts/kanbanBoard/components/KanbanBoardV2.module.scss create mode 100644 samples/react-kanban-board/src/webparts/kanbanBoard/components/KanbanBoardV2.tsx create mode 100644 samples/react-kanban-board/src/webparts/kanbanBoard/components/PropertyPaneBucketConfig.tsx create mode 100644 samples/react-kanban-board/src/webparts/kanbanBoard/components/bucketOrder.tsx create mode 100644 samples/react-kanban-board/src/webparts/kanbanBoard/components/helper.ts diff --git a/samples/react-kanban-board/config/config.json b/samples/react-kanban-board/config/config.json index 9eab31564..497b8daca 100644 --- a/samples/react-kanban-board/config/config.json +++ b/samples/react-kanban-board/config/config.json @@ -14,6 +14,8 @@ "externals": {}, "localizedResources": { "KanbanBoardStrings": "lib/kanban/loc/{locale}.js", - "KanbanBoardWebPartStrings": "lib/webparts/kanbanBoard/loc/{locale}.js" + "KanbanBoardWebPartStrings": "lib/webparts/kanbanBoard/loc/{locale}.js", + "ControlStrings": "node_modules/@pnp/spfx-controls-react/lib/loc/{locale}.js", + "PropertyControlStrings": "node_modules/@pnp/spfx-property-controls/lib/loc/{locale}.js" } -} +} \ No newline at end of file diff --git a/samples/react-kanban-board/package-lock.json b/samples/react-kanban-board/package-lock.json index 154582a61..62483eb0c 100644 --- a/samples/react-kanban-board/package-lock.json +++ b/samples/react-kanban-board/package-lock.json @@ -2104,6 +2104,249 @@ "tslib": "1.9.3" } }, + "@pnp/sp-clientsvc": { + "version": "1.3.11", + "resolved": "https://registry.npmjs.org/@pnp/sp-clientsvc/-/sp-clientsvc-1.3.11.tgz", + "integrity": "sha512-eIUnmDWjizcWJzhWxAbfsxEyHF1dabkGlihnDnlcYGhtvh8BwuM67A57qc5fbxzCS59c0YU57szB1EucoNmV4A==", + "requires": { + "tslib": "1.10.0" + }, + "dependencies": { + "tslib": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" + } + } + }, + "@pnp/sp-taxonomy": { + "version": "1.3.11", + "resolved": "https://registry.npmjs.org/@pnp/sp-taxonomy/-/sp-taxonomy-1.3.11.tgz", + "integrity": "sha512-shzCSjmOlr6mojCXJkfD8Xf9lJnhphq4Fj6mdUQGwpak+VIU+Fogf6AI0j6AReCKtKsKyqfud9X7C8tH07C3DA==", + "requires": { + "tslib": "1.10.0" + }, + "dependencies": { + "tslib": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" + } + } + }, + "@pnp/spfx-controls-react": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/@pnp/spfx-controls-react/-/spfx-controls-react-1.19.0.tgz", + "integrity": "sha512-W3PS6I8NsdbOZjE9I9djloYutQW17QHd4nT7jFwPyJFoxnt1MDfWyN6nrPhaeGnnPde3t3TlUbWP4HKLXChFiw==", + "requires": { + "@pnp/common": "1.0.1", + "@pnp/logging": "1.0.1", + "@pnp/odata": "1.0.1", + "@pnp/sp": "1.0.1", + "@pnp/telemetry-js": "2.0.0", + "@types/chart.js": "2.7.40", + "chart.js": "2.7.3", + "color": "^3.1.2", + "lodash": "4.17.13", + "office-ui-fabric-react": "5.131.0", + "react-quill": "1.3.3" + }, + "dependencies": { + "@pnp/common": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@pnp/common/-/common-1.0.1.tgz", + "integrity": "sha1-T+cuONHexjlQSvxxQclSEh5YqOk=", + "requires": { + "tslib": "1.8.1" + } + }, + "@pnp/logging": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@pnp/logging/-/logging-1.0.1.tgz", + "integrity": "sha1-Nl1/dmiW943xIMgd9D3dlrCgojY=", + "requires": { + "tslib": "1.8.1" + } + }, + "@pnp/odata": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@pnp/odata/-/odata-1.0.1.tgz", + "integrity": "sha1-yE5s/MV2VdZj2IEFlgGT8yiOwAI=", + "requires": { + "tslib": "1.8.1" + } + }, + "@pnp/sp": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@pnp/sp/-/sp-1.0.1.tgz", + "integrity": "sha1-5XXJVqZWk9KRkI4yEdzWbc5KFWM=", + "requires": { + "tslib": "1.8.1" + } + }, + "@uifabric/icons": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@uifabric/icons/-/icons-5.8.0.tgz", + "integrity": "sha512-EUhKxYlIPJshg4fQvCNTYSk0p7RhzEWeEAJBV4sao1SKmN0/pZBnkLbDqWjU5VUfdwZZYiIdaLRpM+pyzhniZw==", + "requires": { + "@uifabric/styling": ">=5.30.1 <6.0.0", + "tslib": "^1.7.1" + } + }, + "@uifabric/merge-styles": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/@uifabric/merge-styles/-/merge-styles-5.17.1.tgz", + "integrity": "sha512-4/EtO6Ns7kNtKxC+6InShwVQeNQEDT5H8Ex7m/i4OrT9i7csje4YwBQPkkpm31qJwEZEyD7bbAwyLezI63sLhg==", + "requires": { + "tslib": "^1.7.1" + } + }, + "@uifabric/styling": { + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/@uifabric/styling/-/styling-5.37.0.tgz", + "integrity": "sha512-3hC0itW/hWSD5J4uANzUKk8XVGWUNkU+VLjEjWsQ6i5lvwFGaanR6Qy0bTkZdFGqFWMXe91CkBHV7HnvEx7tCA==", + "requires": { + "@microsoft/load-themed-styles": "^1.7.13", + "@uifabric/merge-styles": ">=5.17.1 <6.0.0", + "@uifabric/utilities": ">=5.34.2 <6.0.0", + "tslib": "^1.7.1" + } + }, + "@uifabric/utilities": { + "version": "5.34.3", + "resolved": "https://registry.npmjs.org/@uifabric/utilities/-/utilities-5.34.3.tgz", + "integrity": "sha512-6dERFkNNCUrPUuNG1nxlDDvt7DN5hxb41zp9AmKhK5cXZTYCblmlLBvb/qyielCnicfoagoA+lqH9NgnSE8u/A==", + "requires": { + "@uifabric/merge-styles": ">=5.17.1 <6.0.0", + "prop-types": "^15.5.10", + "tslib": "^1.7.1" + } + }, + "color": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/color/-/color-3.1.2.tgz", + "integrity": "sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==", + "requires": { + "color-convert": "^1.9.1", + "color-string": "^1.5.2" + } + }, + "color-string": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", + "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", + "requires": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "office-ui-fabric-react": { + "version": "5.131.0", + "resolved": "https://registry.npmjs.org/office-ui-fabric-react/-/office-ui-fabric-react-5.131.0.tgz", + "integrity": "sha512-QOYu1uf92qhTTIlBAj8teKvRpCmpliRZjynYtgeeUbDm4C4GtXdb/O1rPNFsfT0PNtPC8dCNeQ7/CXjQenUkyw==", + "requires": { + "@microsoft/load-themed-styles": "^1.7.13", + "@uifabric/icons": ">=5.8.0 <6.0.0", + "@uifabric/merge-styles": ">=5.17.1 <6.0.0", + "@uifabric/styling": ">=5.36.0 <6.0.0", + "@uifabric/utilities": ">=5.34.2 <6.0.0", + "prop-types": "^15.5.10", + "tslib": "^1.7.1" + } + }, + "tslib": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.8.1.tgz", + "integrity": "sha1-aUavLR1lGnsYY7Ux1uWvpBqkTqw=" + } + } + }, + "@pnp/spfx-property-controls": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/@pnp/spfx-property-controls/-/spfx-property-controls-1.19.0.tgz", + "integrity": "sha512-C1mkTy8lo+s9NgW9vgkdhP8ZU0SsGxkWSzZ6xNjt7ZvV7ghSLob+LpcGxq3QSHv9hd1BrRSZNJt7A5FStXavSg==", + "requires": { + "@pnp/common": "^1.2.8", + "@pnp/logging": "^1.2.8", + "@pnp/odata": "^1.2.8", + "@pnp/sp": "^1.2.8", + "@pnp/sp-clientsvc": "^1.2.8", + "@pnp/sp-taxonomy": "^1.2.8", + "@pnp/telemetry-js": "2.0.0", + "lodash.omit": "^4.5.0", + "office-ui-fabric-react": "5.131.0", + "react-ace": "5.8.0" + }, + "dependencies": { + "@uifabric/icons": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@uifabric/icons/-/icons-5.8.0.tgz", + "integrity": "sha512-EUhKxYlIPJshg4fQvCNTYSk0p7RhzEWeEAJBV4sao1SKmN0/pZBnkLbDqWjU5VUfdwZZYiIdaLRpM+pyzhniZw==", + "requires": { + "@uifabric/styling": ">=5.30.1 <6.0.0", + "tslib": "^1.7.1" + } + }, + "@uifabric/merge-styles": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/@uifabric/merge-styles/-/merge-styles-5.17.1.tgz", + "integrity": "sha512-4/EtO6Ns7kNtKxC+6InShwVQeNQEDT5H8Ex7m/i4OrT9i7csje4YwBQPkkpm31qJwEZEyD7bbAwyLezI63sLhg==", + "requires": { + "tslib": "^1.7.1" + } + }, + "@uifabric/styling": { + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/@uifabric/styling/-/styling-5.37.0.tgz", + "integrity": "sha512-3hC0itW/hWSD5J4uANzUKk8XVGWUNkU+VLjEjWsQ6i5lvwFGaanR6Qy0bTkZdFGqFWMXe91CkBHV7HnvEx7tCA==", + "requires": { + "@microsoft/load-themed-styles": "^1.7.13", + "@uifabric/merge-styles": ">=5.17.1 <6.0.0", + "@uifabric/utilities": ">=5.34.2 <6.0.0", + "tslib": "^1.7.1" + } + }, + "@uifabric/utilities": { + "version": "5.34.3", + "resolved": "https://registry.npmjs.org/@uifabric/utilities/-/utilities-5.34.3.tgz", + "integrity": "sha512-6dERFkNNCUrPUuNG1nxlDDvt7DN5hxb41zp9AmKhK5cXZTYCblmlLBvb/qyielCnicfoagoA+lqH9NgnSE8u/A==", + "requires": { + "@uifabric/merge-styles": ">=5.17.1 <6.0.0", + "prop-types": "^15.5.10", + "tslib": "^1.7.1" + } + }, + "office-ui-fabric-react": { + "version": "5.131.0", + "resolved": "https://registry.npmjs.org/office-ui-fabric-react/-/office-ui-fabric-react-5.131.0.tgz", + "integrity": "sha512-QOYu1uf92qhTTIlBAj8teKvRpCmpliRZjynYtgeeUbDm4C4GtXdb/O1rPNFsfT0PNtPC8dCNeQ7/CXjQenUkyw==", + "requires": { + "@microsoft/load-themed-styles": "^1.7.13", + "@uifabric/icons": ">=5.8.0 <6.0.0", + "@uifabric/merge-styles": ">=5.17.1 <6.0.0", + "@uifabric/styling": ">=5.36.0 <6.0.0", + "@uifabric/utilities": ">=5.34.2 <6.0.0", + "prop-types": "^15.5.10", + "tslib": "^1.7.1" + } + } + } + }, + "@pnp/telemetry-js": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@pnp/telemetry-js/-/telemetry-js-2.0.0.tgz", + "integrity": "sha512-qFNm3mTerTnxgTR6c/4iMMt8EUKrQn5z0XG/IQtpNlp6m7KXRDFR87mQKeBVtSv2LhxGO0VNFndKJIibBw52zQ==", + "requires": { + "whatwg-fetch": "2.0.4" + }, + "dependencies": { + "whatwg-fetch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz", + "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==" + } + } + }, "@pnpm/link-bins": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@pnpm/link-bins/-/link-bins-1.0.3.tgz", @@ -2206,6 +2449,11 @@ "integrity": "sha1-ox10JBprHtu5c8822XooloNKUfk=", "dev": true }, + "@types/chart.js": { + "version": "2.7.40", + "resolved": "https://registry.npmjs.org/@types/chart.js/-/chart.js-2.7.40.tgz", + "integrity": "sha512-yC8Ff5vsHFTClGCWXoAmNCh33cNYfP2/yFANBLjLiso4jTKsLfQ0KQuBEuKxOWTRoOSLyT6v+ZYcvz0uonvvsA==" + }, "@types/es6-promise": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/@types/es6-promise/-/es6-promise-0.0.33.tgz", @@ -2360,6 +2608,14 @@ "integrity": "sha1-vShOV8hPEyXacCur/IKlMoGQwMU=", "dev": true }, + "@types/quill": { + "version": "1.3.10", + "resolved": "https://registry.npmjs.org/@types/quill/-/quill-1.3.10.tgz", + "integrity": "sha512-IhW3fPW+bkt9MLNlycw8u8fWb7oO7W5URC9MfZYHBlA24rex9rs23D5DETChu1zvgVdc5ka64ICjJOgQMr6Shw==", + "requires": { + "parchment": "^1.1.2" + } + }, "@types/ramda": { "version": "0.25.51", "resolved": "https://registry.npmjs.org/@types/ramda/-/ramda-0.25.51.tgz", @@ -3096,8 +3352,7 @@ "asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", - "dev": true + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" }, "asn1": { "version": "0.2.4", @@ -3697,6 +3952,11 @@ "individual": "~3.0.0" } }, + "brace": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/brace/-/brace-0.11.1.tgz", + "integrity": "sha1-SJb8ydVE7vRfS7dmDbMg07N5/lg=" + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -4072,6 +4332,32 @@ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, + "chart.js": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-2.7.3.tgz", + "integrity": "sha512-3+7k/DbR92m6BsMUYP6M0dMsMVZpMnwkUyNSAbqolHKsbIzH2Q4LWVEHHYq7v0fmEV8whXE0DrjANulw9j2K5g==", + "requires": { + "chartjs-color": "^2.1.0", + "moment": "^2.10.2" + } + }, + "chartjs-color": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chartjs-color/-/chartjs-color-2.4.1.tgz", + "integrity": "sha512-haqOg1+Yebys/Ts/9bLo/BqUcONQOdr/hoEr2LLTRl6C5LXctUdHxsCYfvQVg5JIxITrfCNUDr4ntqmQk9+/0w==", + "requires": { + "chartjs-color-string": "^0.6.0", + "color-convert": "^1.9.3" + } + }, + "chartjs-color-string": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/chartjs-color-string/-/chartjs-color-string-0.6.0.tgz", + "integrity": "sha512-TIB5OKn1hPJvO7JcteW4WY/63v6KwEdt6udfnDE9iCAZgy+V4SrbSxoIbTw/xkUIapjEI4ExGtD0+6D3KyFd7A==", + "requires": { + "color-name": "^1.0.0" + } + }, "chokidar": { "version": "2.1.6", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.6.tgz", @@ -4363,7 +4649,6 @@ "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" } @@ -4371,8 +4656,7 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "color-string": { "version": "0.3.0", @@ -4582,6 +4866,16 @@ "sha.js": "^2.4.8" } }, + "create-react-class": { + "version": "15.6.3", + "resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.6.3.tgz", + "integrity": "sha512-M+/3Q6E6DLO6Yx3OwrWjwHBnvfXXYA7W+dFjt/ZDBemHO1DDZhsalX/NUtnTYclN6GfnBDRh4qRHjcDHmlJBJg==", + "requires": { + "fbjs": "^0.8.9", + "loose-envify": "^1.3.1", + "object-assign": "^4.1.1" + } + }, "cross-spawn": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", @@ -5171,6 +5465,19 @@ "esprima": "4.0.1" } }, + "deep-equal": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", + "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", + "requires": { + "is-arguments": "^1.0.4", + "is-date-object": "^1.0.1", + "is-regex": "^1.0.4", + "object-is": "^1.0.1", + "object-keys": "^1.1.1", + "regexp.prototype.flags": "^1.2.0" + } + }, "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", @@ -5210,7 +5517,6 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, "requires": { "object-keys": "^1.0.12" } @@ -5817,6 +6123,11 @@ "through": "^2.3.8" } }, + "eventemitter3": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz", + "integrity": "sha1-teEHm1n7XhuidxwKmTvgYKWMmbo=" + }, "events": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz", @@ -6030,8 +6341,7 @@ "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, "extend-shallow": { "version": "3.0.2", @@ -6154,6 +6464,11 @@ "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", "dev": true }, + "fast-diff": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.1.2.tgz", + "integrity": "sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig==" + }, "fast-json-stable-stringify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", @@ -6200,7 +6515,6 @@ "version": "0.8.17", "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.17.tgz", "integrity": "sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=", - "dev": true, "requires": { "core-js": "^1.0.0", "isomorphic-fetch": "^2.1.1", @@ -6214,8 +6528,7 @@ "core-js": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", - "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=", - "dev": true + "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=" } } }, @@ -7032,8 +7345,7 @@ "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, "gauge": { "version": "2.7.4", @@ -7731,7 +8043,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, "requires": { "function-bind": "^1.1.1" } @@ -7763,8 +8074,7 @@ "has-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", - "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", - "dev": true + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=" }, "has-unicode": { "version": "2.0.1", @@ -8298,6 +8608,11 @@ } } }, + "is-arguments": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", + "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==" + }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -8357,8 +8672,7 @@ "is-date-object": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", - "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", - "dev": true + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=" }, "is-descriptor": { "version": "0.1.6", @@ -8517,7 +8831,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", - "dev": true, "requires": { "has": "^1.0.1" } @@ -8549,7 +8862,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", - "dev": true, "requires": { "has-symbols": "^1.0.0" } @@ -10490,8 +10802,7 @@ "lodash": { "version": "4.17.13", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.13.tgz", - "integrity": "sha512-vm3/XWXfWtRua0FkUyEHBZy8kCPjErNBT9fJx8Zvs+U6zjqPbTUOpkaoum3O5uiA8sm+yNMHXfYkTUHFoMxFNA==", - "dev": true + "integrity": "sha512-vm3/XWXfWtRua0FkUyEHBZy8kCPjErNBT9fJx8Zvs+U6zjqPbTUOpkaoum3O5uiA8sm+yNMHXfYkTUHFoMxFNA==" }, "lodash._baseclone": { "version": "4.5.7", @@ -10662,6 +10973,11 @@ "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", "dev": true }, + "lodash.omit": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz", + "integrity": "sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA=" + }, "lodash.rest": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/lodash.rest/-/lodash.rest-4.0.5.tgz", @@ -11122,6 +11438,11 @@ "mkdirp": "*" } }, + "moment": { + "version": "2.27.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.27.0.tgz", + "integrity": "sha512-al0MUK7cpIcglMv3YF13qSgdAIqxHTO7brRtaz3DlSULbqfazqkc5kEjNrLDOM7fsjshoFIihnU8snrP7zUvhQ==" + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -11687,11 +12008,72 @@ } } }, + "object-inspect": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", + "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==" + }, + "object-is": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.2.tgz", + "integrity": "sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ==", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", + "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.0", + "is-regex": "^1.1.0", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==" + }, + "is-callable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==" + }, + "is-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", + "requires": { + "has-symbols": "^1.0.1" + } + } + } + }, "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" }, "object-visit": { "version": "1.0.1", @@ -11702,6 +12084,17 @@ "isobject": "^3.0.0" } }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, "object.defaults": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", @@ -11997,6 +12390,11 @@ "no-case": "^2.2.0" } }, + "parchment": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/parchment/-/parchment-1.1.4.tgz", + "integrity": "sha512-J5FBQt/pM2inLzg4hEWmzQx/8h8D0CiDxaG3vyp9rKrQRSDgBlhjdP5jQGgosEajXPSQouXGHOmVdgo7QmJuOg==" + }, "parse-asn1": { "version": "5.1.4", "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.4.tgz", @@ -14248,7 +14646,6 @@ "version": "7.3.1", "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", - "dev": true, "requires": { "asap": "~2.0.3" } @@ -14363,6 +14760,36 @@ "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", "dev": true }, + "quill": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/quill/-/quill-1.3.7.tgz", + "integrity": "sha512-hG/DVzh/TiknWtE6QmWAF/pxoZKYxfe3J/d/+ShUWkDvvkZQVTPeVmUJVu1uE6DDooC4fWTiCLh84ul89oNz5g==", + "requires": { + "clone": "^2.1.1", + "deep-equal": "^1.0.1", + "eventemitter3": "^2.0.3", + "extend": "^3.0.2", + "parchment": "^1.1.4", + "quill-delta": "^3.6.2" + }, + "dependencies": { + "clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=" + } + } + }, + "quill-delta": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/quill-delta/-/quill-delta-3.6.3.tgz", + "integrity": "sha512-wdIGBlcX13tCHOXGMVnnTVFtGRLoP0imqxM696fIPwIf5ODIYUHIvHbZcyvGlZFiFhK5XzDC2lpjbxRhnM05Tg==", + "requires": { + "deep-equal": "^1.0.1", + "extend": "^3.0.2", + "fast-diff": "1.1.2" + } + }, "ramda": { "version": "0.25.0", "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.25.0.tgz", @@ -14447,6 +14874,17 @@ "scheduler": "^0.12.0" } }, + "react-ace": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/react-ace/-/react-ace-5.8.0.tgz", + "integrity": "sha1-hy2e6LZkMA7Vq57axiNLvpCDaDY=", + "requires": { + "brace": "^0.11.0", + "lodash.get": "^4.4.2", + "lodash.isequal": "^4.1.1", + "prop-types": "^15.5.8" + } + }, "react-dom": { "version": "16.7.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.7.0.tgz", @@ -14458,6 +14896,11 @@ "scheduler": "^0.12.0" } }, + "react-dom-factories": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/react-dom-factories/-/react-dom-factories-1.0.2.tgz", + "integrity": "sha1-63cFxNs2+1AbOqOP91lhaqD/luA=" + }, "react-html-parser": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/react-html-parser/-/react-html-parser-2.0.2.tgz", @@ -14472,6 +14915,20 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz", "integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==" }, + "react-quill": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/react-quill/-/react-quill-1.3.3.tgz", + "integrity": "sha512-T9RubLaWJ8gCfp7sOqmFupjiTiEp/EdGqhCG+PWGKc5UHiK6xIWNKWYsOHHEhQ+sZCKs8u/DPx47gc1VfFmcLg==", + "requires": { + "@types/quill": "1.3.10", + "@types/react": "*", + "create-react-class": "^15.6.0", + "lodash": "^4.17.4", + "prop-types": "^15.5.10", + "quill": "^1.2.6", + "react-dom-factories": "^1.0.0" + } + }, "read": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", @@ -14737,6 +15194,63 @@ "safe-regex": "^1.1.0" } }, + "regexp.prototype.flags": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", + "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", + "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.0", + "is-regex": "^1.1.0", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==" + }, + "is-callable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==" + }, + "is-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", + "requires": { + "has-symbols": "^1.0.1" + } + } + } + }, "regexpu-core": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz", @@ -15329,8 +15843,7 @@ "setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" }, "setprototypeof": { "version": "1.1.0", @@ -15381,6 +15894,21 @@ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true }, + "simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "requires": { + "is-arrayish": "^0.3.1" + }, + "dependencies": { + "is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + } + } + }, "sisteransi": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-0.1.1.tgz", @@ -15944,6 +16472,120 @@ } } }, + "string.prototype.trimend": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", + "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", + "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.0", + "is-regex": "^1.1.0", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==" + }, + "is-callable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==" + }, + "is-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", + "requires": { + "has-symbols": "^1.0.1" + } + } + } + }, + "string.prototype.trimstart": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", + "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", + "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.0", + "is-regex": "^1.1.0", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==" + }, + "is-callable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==" + }, + "is-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", + "requires": { + "has-symbols": "^1.0.1" + } + } + } + }, "string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", @@ -16604,8 +17246,7 @@ "ua-parser-js": { "version": "0.7.20", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.20.tgz", - "integrity": "sha512-8OaIKfzL5cpx8eCMAhhvTlft8GYF8b2eQr6JkCyVdrgjcytyOmPCXrqXFcUnhonRpLlh5yxEZVohm6mzaowUOw==", - "dev": true + "integrity": "sha512-8OaIKfzL5cpx8eCMAhhvTlft8GYF8b2eQr6JkCyVdrgjcytyOmPCXrqXFcUnhonRpLlh5yxEZVohm6mzaowUOw==" }, "uglify-js": { "version": "3.6.0", diff --git a/samples/react-kanban-board/package.json b/samples/react-kanban-board/package.json index 9ed0fd7f7..f147305c1 100644 --- a/samples/react-kanban-board/package.json +++ b/samples/react-kanban-board/package.json @@ -21,6 +21,8 @@ "@pnp/odata": "^1.3.3", "@pnp/polyfill-ie11": "^2.0.2", "@pnp/sp": "^1.3.3", + "@pnp/spfx-controls-react": "1.19.0", + "@pnp/spfx-property-controls": "1.19.0", "@types/es6-promise": "0.0.33", "@types/react": "16.7.22", "@types/react-dom": "16.8.0", diff --git a/samples/react-kanban-board/src/kanban/KanbanBucket.tsx b/samples/react-kanban-board/src/kanban/KanbanBucket.tsx index dad9fc380..0fe7931e1 100644 --- a/samples/react-kanban-board/src/kanban/KanbanBucket.tsx +++ b/samples/react-kanban-board/src/kanban/KanbanBucket.tsx @@ -55,7 +55,6 @@ export default class KanbanBucket extends React.Component + {/* + TODO editmapping { @@ -110,6 +112,7 @@ export default class KanbanBucketConfigurator extends React.Component + */} { this.setState({ useColor: checked }); }} /> @@ -160,7 +163,6 @@ export default class KanbanBucketConfigurator extends React.Component; + hideWPTitle: boolean; + title: string; + buckets: IKanbanBucket[]; + listId: string; + listTitle: string; //was the name if upgrade support than (remap title to id) loaded: boolean; } export default class KanbanBoardWebPart extends BaseClientSideWebPart { + private kanbanComponent = null; + public onInit(): Promise < void> { - public onInit(): Promise { + return super.onInit().then(_ => { - return super.onInit().then(_ => { - - sp.setup({ - spfxContext: this.context - }); - + sp.setup({ + spfxContext: this.context }); - } + + }); +} public render(): void { - + /* const element: React.ReactElement = React.createElement( @@ -47,56 +59,198 @@ export default class KanbanBoardWebPart extends BaseClientSideWebPart = React.createElement( MockKanban, { } ); - - ReactDom.render(element, this.domElement); +*/ + const element: React.ReactElement < IKanbanBoardV2Props > = React.createElement( + KanbanBoardV2, + { + hideWPTitle: this.properties.hideWPTitle, + title: this.properties.title, + displayMode: this.displayMode, + updateProperty: (value: string) => { + this.properties.title = value; + }, + context: this.context, + listId: this.properties.listId, + configuredBuckets: this.properties.buckets + } + ); - } + + this.kanbanComponent = ReactDom.render(element, this.domElement); + +} protected onDispose(): void { - ReactDom.unmountComponentAtNode(this.domElement); - } + ReactDom.unmountComponentAtNode(this.domElement); +} protected get dataVersion(): Version { - return Version.parse('1.0'); - } + return Version.parse('1.0'); +} protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration { - return { - pages: [ - { - groups: [ - { - groupName: strings.BasicGroupName, - groupFields: [ - PropertyPaneDropdown('listTitle',{ - label: strings.ListTitleFieldLabel, - options: this.properties.lists - }) - ] + const propertypages = []; + + const generalgroups = []; + generalgroups.push( + { + groupName: strings.BasicGroupName, + groupFields: [ + PropertyPaneToggle('hideWPTitle', { + label: 'Hide WP Title', + checked: this.properties.hideWPTitle + }), + PropertyFieldListPicker('listId', { + label: 'Select a list', + selectedList: this.properties.listId, + includeHidden: false, + orderBy: PropertyFieldListPickerOrderBy.Title, + disabled: false, + onPropertyChange: this.listConfigurationChanged.bind(this), + properties: this.properties, + context: this.context, + onGetErrorMessage: null, + deferredValidationTime: 0, + key: 'listPickerFieldId', + onListsRetrieved: (lists) => { + //TODO Check from TS Definition it should be a string but i get a number + // with Typesafe equal it fails + const alists = lists.filter((l: any) => { + return (l.BaseTemplate === 171 || l.BaseTemplate === 107); } - ] - } + ); + return alists; + } + }) ] - }; + }); + + if (this.properties.listId && this.properties.buckets && this.properties.buckets.length > 1) { + generalgroups.push( + { + groupName: "Order Buckets", + groupFields: [ + PropertyFieldOrder("orderedItems", { + key: "orderedItems", + label: "Ordered Items", + items: this.properties.buckets, + properties: this.properties, + onPropertyChange: this.onPropertyPaneFieldChanged, + onRenderItem: bucketOrder, + }) + ] + } + ); } - protected onPropertyPaneConfigurationStart(){ - // Use the list template ID to locate both the old style task lists (107) and newer task lists (171) - sp.web.lists.filter("BaseTemplate eq 171 or BaseTemplate eq 107").select("Title").get().then(res => { - this.properties.lists = res.map((val,index) => { - return { - key: val.Title, - text: val.Title - }; - }); - this.context.propertyPane.refresh(); + + + propertypages.push({ + groups: generalgroups + }); + + if (this.properties.buckets && this.properties.buckets.length > 0) { + this.properties.buckets.forEach((b, i) => { + propertypages.push({ + key: { i }, + header: { + description: "Bucket Configuration" + }, + groups: [{ + groupName: b.bucketheadline ? b.bucketheadline : b.bucket, + groupFields: [ + PropertyPaneBucketConfigComponent('bucket_' + i, { + key: 'bucket_' + i, + properties: cloneDeep(b), + onPropertyChange: this.bucketConfigurationChanged.bind(this) + }) + ] + } + ] }); + }); + } + + + return { + pages: propertypages + }; +} + + private listConfigurationChanged(propertyPath: string, oldValue: any, newValue: any) { + this.onPropertyPaneFieldChanged(propertyPath, oldValue, newValue); + this.refreshBucket(); + +} + private bucketConfigurationChanged(propertyPath: string, oldValue: any, newValue: any) { + //its an array part !!!!! + if (propertyPath.indexOf('bucket_') !== -1) { + const newbuckets: IKanbanBucket[] = cloneDeep(this.properties.buckets); + const bucketindex: number = +propertyPath.split('_')[1]; + newbuckets[bucketindex] = newValue; + //merge and every else is good + // + console.log('buckes updated old saved'); + console.log(oldValue); + // this.onPropertyPaneFieldChanged('buckets', this.properties.buckets, newbuckets); + this.properties.buckets = cloneDeep(newbuckets); + // array child Properties change dows not trigger rerender + // i think this is better as an Property With da DateTimeValue to force Rerender + console.log('old'); + console.log(this.properties.buckets); + console.log('new'); + console.log(newbuckets); + this.kanbanComponent.forceUpdate(); + } else { + throw "propertypath is not a bucket"; + + } + + + +} + + private refreshBucket(): void { + const listId = this.properties.listId; + if(!listId || listId.length === 0) { return; } + +sp.web.lists.getById(listId).fields.getByInternalNameOrTitle("Status").get() + .then(status => { + + const cols: string[] = status.Choices.map((val, index) => { + return val; + }); + //matching with existing configured buckets + const currentbuckets: IKanbanBucket[] = mergeBucketsWithChoices(this.properties.buckets, cols); + if (!currentbuckets) { + return; + } + this.properties.buckets = currentbuckets; + this.context.propertyPane.refresh(); + }); + + } + + protected onPropertyPaneConfigurationStart() { + // Use the list template ID to locate both the old style task lists (107) and newer task lists (171) + /* + sp.web.lists.filter("BaseTemplate eq 171 or BaseTemplate eq 107").select("Title").get().then(res => { + this.properties.lists = res.map((val, index) => { + return { + key: val.Title, + text: val.Title + }; + }); + this.context.propertyPane.refresh(); + }); + */ +} } diff --git a/samples/react-kanban-board/src/webparts/kanbanBoard/components/KanbanBoardV2.module.scss b/samples/react-kanban-board/src/webparts/kanbanBoard/components/KanbanBoardV2.module.scss new file mode 100644 index 000000000..b7e5d174a --- /dev/null +++ b/samples/react-kanban-board/src/webparts/kanbanBoard/components/KanbanBoardV2.module.scss @@ -0,0 +1,4 @@ +.ordercolor { + width: 10px; + height: 10px; +} diff --git a/samples/react-kanban-board/src/webparts/kanbanBoard/components/KanbanBoardV2.tsx b/samples/react-kanban-board/src/webparts/kanbanBoard/components/KanbanBoardV2.tsx new file mode 100644 index 000000000..9daa4ea57 --- /dev/null +++ b/samples/react-kanban-board/src/webparts/kanbanBoard/components/KanbanBoardV2.tsx @@ -0,0 +1,166 @@ +import * as React from 'react'; +import styles from './KanbanBoardV2.module.scss'; +import { DisplayMode, Guid } from '@microsoft/sp-core-library'; +import { WebPartTitle } from "@pnp/spfx-controls-react/lib/WebPartTitle"; +import { Placeholder } from "@pnp/spfx-controls-react/lib/Placeholder"; +import { WebPartContext } from '@microsoft/sp-webpart-base'; +import { Spinner } from 'office-ui-fabric-react/lib/Spinner'; +import { IKanbanBucket } from '../../../kanban/IKanbanBucket'; +import { IKanbanTask } from '../../../kanban/IKanbanTask'; +import KanbanComponent from '../../../kanban/KanbanComponent'; +import { findIndex, clone, isEqual } from '@microsoft/sp-lodash-subset'; +import { sp } from '@pnp/sp'; +import { mergeBucketsWithChoices } from './helper'; + +export interface IKanbanBoardV2Props { + hideWPTitle: boolean; + title: string; + displayMode: DisplayMode; + updateProperty: (value: string) => void; + context: WebPartContext; + listId: string; + configuredBuckets: IKanbanBucket[]; // need mearge with current readed +} + +export interface IKanbanBoardV2State { + loading: boolean; + isConfigured: boolean; + buckets: IKanbanBucket[]; + tasks: IKanbanTask[]; + errorMessage?: string; + +} + +export default class KanbanBoardV2 extends React.Component { + private choices: string[] = []; + constructor(props: IKanbanBoardV2Props) { + super(props); + + this.state = { + loading: false, + isConfigured: false, + buckets: [], + tasks: [] + }; + } + public componentDidMount(): void { + this._getData(); + } + public shouldComponentUpdate(nextProps: IKanbanBoardV2Props, nextState: IKanbanBoardV2State): boolean { + + if (!isEqual(this.state, nextState)) { return true; } + if (!isEqual(this.props, nextProps)) { + console.log('change in Props found') + return true; } + return false; + } + public componentDidUpdate(prevProps: IKanbanBoardV2Props) { + console.log('componentDidUpdate'); + if (this.props.listId !== prevProps.listId) { + this._getData(); + } + + const currentbuckets: IKanbanBucket[] = mergeBucketsWithChoices(this.props.configuredBuckets, this.choices); + console.log(this.props.configuredBuckets); + console.log(currentbuckets); + console.log(this.state.buckets); + if (!isEqual(this.state.buckets, currentbuckets)) { + + this.setState({ buckets: currentbuckets }); + + } + } + + public render(): React.ReactElement { + const { buckets, tasks, errorMessage } = this.state; + const { hideWPTitle, displayMode } = this.props; + const isConfigured: boolean = this.state.isConfigured; + const isLoading: boolean = this.state.loading; + + return ( +
+ {!hideWPTitle && ( + )} + {!isConfigured && !isLoading && ( + )} + {isConfigured && isLoading && ( + + )} + {isConfigured && !isLoading && ( + ) + } + {!!errorMessage && (
{errorMessage}
)} +
+ ); + } + + private _onConfigure = () => { + this.props.context.propertyPane.open(); + } + + + private _moved(taskId: string, targetBucket: IKanbanBucket): void { + const elementsIndex = findIndex(this.state.tasks, element => element.taskId == taskId); + let newArray = [...this.state.tasks]; // same as Clone + newArray[elementsIndex].bucket = targetBucket.bucket; + this.setState({ tasks: newArray }); + + } + + + + private _getData(): void { + if (!this.props.listId || this.props.listId.length == 0) { + this.setState({ isConfigured: false, loading: false }); + } else { + const listId: string = this.props.listId; + sp.web.lists.getById(listId).fields.getByInternalNameOrTitle("Status").get() + .then(status => { + + this.choices = status.Choices.map((val, index) => { + return val; + }); + //matching with existing configured buckets + const currentbuckets: IKanbanBucket[] = mergeBucketsWithChoices(this.props.configuredBuckets, this.choices); + if (!currentbuckets) { + this.setState({ isConfigured: false, loading: false, errorMessage: 'No Buckets found' }); + return; + } + sp.web.lists.getById(listId).items.getAll().then(res => { + //Map Items to task + this.setState({ + isConfigured: true, + loading: false, + errorMessage: undefined, + buckets: currentbuckets, + tasks: [] + }); + }); + + + }); + this.setState({ isConfigured: true, loading: true }); + } + + } +} diff --git a/samples/react-kanban-board/src/webparts/kanbanBoard/components/PropertyPaneBucketConfig.tsx b/samples/react-kanban-board/src/webparts/kanbanBoard/components/PropertyPaneBucketConfig.tsx new file mode 100644 index 000000000..4803b1ed1 --- /dev/null +++ b/samples/react-kanban-board/src/webparts/kanbanBoard/components/PropertyPaneBucketConfig.tsx @@ -0,0 +1,82 @@ +import * as React from 'react'; +import * as ReactDom from 'react-dom'; +import { + IPropertyPaneField, + PropertyPaneFieldType +} from '@microsoft/sp-property-pane'; + +import KanbanBucketConfigurator, { IKanbanBucketConfiguratorProps } from '../../../kanban/KanbanBucketConfigurator'; +import { IKanbanBucket } from '../../../kanban/IKanbanBucket'; + +export interface IPropertyPaneBucketConfig { + key: string; + properties: IKanbanBucket; + onPropertyChange(propertyPath: string, oldValue: any, newValue: any): void; +} + +export interface IPropertyPaneBucketConfigInternal extends IPropertyPaneBucketConfig { + targetProperty: string; + onRender(elem: HTMLElement, ctx, changeCallback): void; + onDispose(elem: HTMLElement): void; + onChanged(targetProperty: string, value: IKanbanBucket): void; +} + + + + +class PropertyPaneBucketConfigBuilder implements IPropertyPaneField { + // Properties defined by IPropertyPaneField + public type: PropertyPaneFieldType = PropertyPaneFieldType.Custom; + public targetProperty: string; + public properties: IPropertyPaneBucketConfigInternal; + private elem: HTMLElement; + // Custom properties + private customProperties: any; + private onPropertyChange: (propertyPath: string, oldValue: any, newValue: any) => void; + + public constructor(_targetProperty: string, _properties: IPropertyPaneBucketConfigInternal) { + + this.customProperties = _properties.properties; + this.targetProperty = _targetProperty; + this.onPropertyChange = _properties.onPropertyChange; + this.properties = _properties; + this.properties.onRender = this.render.bind(this); + this.properties.onDispose = this.dispose; + } + + private render(elem: HTMLElement, ctx?, changeCallback?: (targetProperty: string, value: any) => void): void { + if (!this.elem) { + this.elem = elem; + } + const configprops: IKanbanBucketConfiguratorProps = { + index: 1, + bucket: this.customProperties, + update: this.saveBucketConfig.bind(this) + }; + const element: React.ReactElement = React.createElement(KanbanBucketConfigurator, + { ...configprops } + + ); + ReactDom.render(element, elem); + } + private saveBucketConfig(index: number, value: IKanbanBucket): void { + if (this.onPropertyChange) { + this.onPropertyChange(this.targetProperty, this.customProperties, value); + } + } + private dispose(elem: HTMLElement): void { } +} + +export default function PropertyPaneBucketConfigComponent(targetProperty: string, properties: IPropertyPaneBucketConfig): + IPropertyPaneField { + var newProperties: IPropertyPaneBucketConfigInternal = { + key: properties.key, + properties: properties.properties, + targetProperty: targetProperty, + onPropertyChange: properties.onPropertyChange, + onDispose: null, + onRender: null, + onChanged: null + }; + return new PropertyPaneBucketConfigBuilder(targetProperty, newProperties); +} \ No newline at end of file diff --git a/samples/react-kanban-board/src/webparts/kanbanBoard/components/bucketOrder.tsx b/samples/react-kanban-board/src/webparts/kanbanBoard/components/bucketOrder.tsx new file mode 100644 index 000000000..0f05baf2b --- /dev/null +++ b/samples/react-kanban-board/src/webparts/kanbanBoard/components/bucketOrder.tsx @@ -0,0 +1,12 @@ +import * as React from 'react'; +import { IKanbanBucket } from '../../../kanban/IKanbanBucket'; +import styles from './KanbanBoardV2.module.scss'; + +export const bucketOrder = (item:IKanbanBucket, index:number): JSX.Element => { + return ( + + {} + {item.bucketheadline?item.bucketheadline:item.bucket} + + ); +}; \ No newline at end of file diff --git a/samples/react-kanban-board/src/webparts/kanbanBoard/components/helper.ts b/samples/react-kanban-board/src/webparts/kanbanBoard/components/helper.ts new file mode 100644 index 000000000..4b7057ee3 --- /dev/null +++ b/samples/react-kanban-board/src/webparts/kanbanBoard/components/helper.ts @@ -0,0 +1,29 @@ +import { IKanbanBucket } from "../../../kanban/IKanbanBucket"; + +export function mergeBucketsWithChoices(inB: IKanbanBucket[], choices: string[]): IKanbanBucket[] { + const currentbuckets: IKanbanBucket[] = []; + if (inB && + inB.length > 0 && + choices && choices.length > 0) { + inB.forEach((b) => { + if (choices.filter((c) => c === b.bucket).length === 1) { + currentbuckets.push(b); + } + }); + return currentbuckets; + + } else if (choices && choices.length) { + //Adding with default values + choices.forEach((x) => { + currentbuckets.push({ + bucket: x, + bucketheadline: x, + percentageComplete: 0 + }); + }); + return currentbuckets; + } else { + + return undefined; + } +} \ No newline at end of file diff --git a/samples/react-kanban-board/tsconfig.json b/samples/react-kanban-board/tsconfig.json index 131c5bb80..bdd2cb4d2 100644 --- a/samples/react-kanban-board/tsconfig.json +++ b/samples/react-kanban-board/tsconfig.json @@ -29,7 +29,7 @@ ] }, "include": [ - "src/**/*.ts" + "src/**/*.ts", "src/webparts/kanbanBoard/components/bucketOrder.tsx" ], "exclude": [ "node_modules",