diff --git a/catalog-rest-service/src/main/resources/ui/package-lock.json b/catalog-rest-service/src/main/resources/ui/package-lock.json index 8617aea8bb7..14bdb2671d0 100644 --- a/catalog-rest-service/src/main/resources/ui/package-lock.json +++ b/catalog-rest-service/src/main/resources/ui/package-lock.json @@ -4,6 +4,43 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@ant-design/colors": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-6.0.0.tgz", + "integrity": "sha512-qAZRvPzfdWHtfameEGP2Qvuf838NhergR35o+EuVyB5XvSA98xod5r4utvi4TJ3ywmevm290g9nsCG5MryrdWQ==", + "requires": { + "@ctrl/tinycolor": "^3.4.0" + } + }, + "@ant-design/icons": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@ant-design/icons/-/icons-4.7.0.tgz", + "integrity": "sha512-aoB4Z7JA431rt6d4u+8xcNPPCrdufSRMUOpxa1ab6mz1JCQZOEVolj2WVs/tDFmN62zzK30mNelEsprLYsSF3g==", + "requires": { + "@ant-design/colors": "^6.0.0", + "@ant-design/icons-svg": "^4.2.1", + "@babel/runtime": "^7.11.2", + "classnames": "^2.2.6", + "rc-util": "^5.9.4" + } + }, + "@ant-design/icons-svg": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@ant-design/icons-svg/-/icons-svg-4.2.1.tgz", + "integrity": "sha512-EB0iwlKDGpG93hW8f85CTJTs4SvMX7tt5ceupvhALp1IF44SeUFOMhKUOYqpsoYWQKAOuTRDMqn75rEaKDp0Xw==" + }, + "@ant-design/react-slick": { + "version": "0.28.4", + "resolved": "https://registry.npmjs.org/@ant-design/react-slick/-/react-slick-0.28.4.tgz", + "integrity": "sha512-j9eAHTn7GxbXUFNknJoHS2ceAsqrQi2j8XykjZE1IXCD8kJF+t28EvhBLniDpbOsBk/3kjalnhriTfZcjBHNqg==", + "requires": { + "@babel/runtime": "^7.10.4", + "classnames": "^2.2.5", + "json2mq": "^0.2.0", + "lodash": "^4.17.21", + "resize-observer-polyfill": "^1.5.0" + } + }, "@babel/code-frame": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", @@ -1304,6 +1341,11 @@ "webpack-merge": "^4.2.2" } }, + "@ctrl/tinycolor": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.4.0.tgz", + "integrity": "sha512-JZButFdZ1+/xAfpguQHoabIXkcqRRKpMrWKBkpEZZyxfY9C1DpADFB8PEqGSTeFr135SaTRfKqGKx5xSCLI7ZQ==" + }, "@deuex-solutions/redoc": { "version": "2.0.0-rc.27", "resolved": "https://registry.npmjs.org/@deuex-solutions/redoc/-/redoc-2.0.0-rc.27.tgz", @@ -4659,6 +4701,54 @@ "color-convert": "^1.9.0" } }, + "antd": { + "version": "4.16.13", + "resolved": "https://registry.npmjs.org/antd/-/antd-4.16.13.tgz", + "integrity": "sha512-EMPD3fzKe7oayx9keD/GA1oKatcx7j5CGlkJj5eLS0/eEDDEkxVj3DFmKOPuHYt4BK7ltTzMFS+quSTmqUXPiw==", + "requires": { + "@ant-design/colors": "^6.0.0", + "@ant-design/icons": "^4.6.3", + "@ant-design/react-slick": "~0.28.1", + "@babel/runtime": "^7.12.5", + "array-tree-filter": "^2.1.0", + "classnames": "^2.2.6", + "copy-to-clipboard": "^3.2.0", + "lodash": "^4.17.21", + "moment": "^2.25.3", + "rc-cascader": "~1.4.0", + "rc-checkbox": "~2.3.0", + "rc-collapse": "~3.1.0", + "rc-dialog": "~8.6.0", + "rc-drawer": "~4.3.0", + "rc-dropdown": "~3.2.0", + "rc-field-form": "~1.20.0", + "rc-image": "~5.2.5", + "rc-input-number": "~7.1.0", + "rc-mentions": "~1.6.1", + "rc-menu": "~9.0.12", + "rc-motion": "^2.4.0", + "rc-notification": "~4.5.7", + "rc-pagination": "~3.1.9", + "rc-picker": "~2.5.10", + "rc-progress": "~3.1.0", + "rc-rate": "~2.9.0", + "rc-resize-observer": "^1.0.0", + "rc-select": "~12.1.6", + "rc-slider": "~9.7.1", + "rc-steps": "~4.1.0", + "rc-switch": "~3.2.0", + "rc-table": "~7.15.1", + "rc-tabs": "~11.10.0", + "rc-textarea": "~0.3.0", + "rc-tooltip": "~5.1.1", + "rc-tree": "~4.2.1", + "rc-tree-select": "~4.3.0", + "rc-trigger": "^5.2.10", + "rc-upload": "~4.3.0", + "rc-util": "^5.13.1", + "scroll-into-view-if-needed": "^2.2.25" + } + }, "anymatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", @@ -4743,6 +4833,11 @@ "is-string": "^1.0.5" } }, + "array-tree-filter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-tree-filter/-/array-tree-filter-2.1.0.tgz", + "integrity": "sha512-4ROwICNlNw/Hqa9v+rk5h22KjmzB1JGTMVKP2AKJBOCgb0yL0ASf0+YvCcLNNwquOHNX48jkeZIJ3a+oOQqKcw==" + }, "array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", @@ -4841,6 +4936,11 @@ "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", "dev": true }, + "async-validator": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-3.5.2.tgz", + "integrity": "sha512-8eLCg00W9pIRZSB781UUX/H6Oskmm8xloZfr09lz5bikRpBVDlJ3hRVuxxP1SxcwsEYfJ4IU8Q19Y8/893r3rQ==" + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -6281,6 +6381,14 @@ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", "dev": true }, + "copy-to-clipboard": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.1.tgz", + "integrity": "sha512-i13qo6kIHTTpCm8/Wup+0b1mVWETvu2kIMzKoK8FpkLkFxlt0znUAHcMzox+T8sPlqtZXq3CulEjQHsYiGFJUw==", + "requires": { + "toggle-selection": "^1.0.6" + } + }, "copy-webpack-plugin": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-7.0.0.tgz", @@ -6412,6 +6520,11 @@ } } }, + "cronstrue": { + "version": "1.122.0", + "resolved": "https://registry.npmjs.org/cronstrue/-/cronstrue-1.122.0.tgz", + "integrity": "sha512-PFuhZd+iPQQ0AWTXIEYX+t3nFGzBrWxmTWUKJOrsGRewaBSLKZ4I1f8s2kryU75nNxgyugZgiGh2OJsCTA/XlA==" + }, "cross-fetch": { "version": "3.1.4", "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz", @@ -6826,6 +6939,16 @@ "whatwg-url": "^8.0.0" } }, + "date-fns": { + "version": "2.25.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.25.0.tgz", + "integrity": "sha512-ovYRFnTrbGPD4nqaEqescPEv1mNwvt+UTqI3Ay9SzNtey9NZnYu6E2qCcBBgJ6/2VF1zGGygpyTDITqpQQ5e+w==" + }, + "dayjs": { + "version": "1.10.7", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.7.tgz", + "integrity": "sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig==" + }, "debug": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", @@ -7137,6 +7260,11 @@ "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.3.0.tgz", "integrity": "sha512-PzwHEmsRP3IGY4gv/Ug+rMeaTIyTJvadCb+ujYXYeIylbHJezIyNToe8KfEgHTCEYyC+/bUghYOGg8yMGlZ6vA==" }, + "dom-align": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/dom-align/-/dom-align-1.12.2.tgz", + "integrity": "sha512-pHuazgqrsTFrGU2WLDdXxCFabkdQDx72ddkraZNih1KsMcN5qsRSTR9O4VJRlwTPCPb5COYg3LOfiMHHcPInHg==" + }, "dom-converter": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", @@ -15977,6 +16105,11 @@ "resolved": "https://registry.npmjs.org/modern-normalize/-/modern-normalize-1.1.0.tgz", "integrity": "sha512-2lMlY1Yc1+CUy0gw4H95uNN7vjbpoED7NNRSBHE25nWfLBdmMzFCsPshlzbxHz+gYMcBEUN8V4pU16prcdPSgA==" }, + "moment": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", + "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -17558,6 +17691,384 @@ "unpipe": "1.0.0" } }, + "rc-align": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/rc-align/-/rc-align-4.0.11.tgz", + "integrity": "sha512-n9mQfIYQbbNTbefyQnRHZPWuTEwG1rY4a9yKlIWHSTbgwI+XUMGRYd0uJ5pE2UbrNX0WvnMBA1zJ3Lrecpra/A==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "dom-align": "^1.7.0", + "lodash": "^4.17.21", + "rc-util": "^5.3.0", + "resize-observer-polyfill": "^1.5.1" + } + }, + "rc-cascader": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/rc-cascader/-/rc-cascader-1.4.3.tgz", + "integrity": "sha512-Q4l9Mv8aaISJ+giVnM9IaXxDeMqHUGLvi4F+LksS6pHlaKlN4awop/L+IMjIXpL+ug/ojaCyv/ixcVopJYYCVA==", + "requires": { + "@babel/runtime": "^7.12.5", + "array-tree-filter": "^2.1.0", + "rc-trigger": "^5.0.4", + "rc-util": "^5.0.1", + "warning": "^4.0.1" + } + }, + "rc-checkbox": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/rc-checkbox/-/rc-checkbox-2.3.2.tgz", + "integrity": "sha512-afVi1FYiGv1U0JlpNH/UaEXdh6WUJjcWokj/nUN2TgG80bfG+MDdbfHKlLcNNba94mbjy2/SXJ1HDgrOkXGAjg==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.1" + } + }, + "rc-collapse": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/rc-collapse/-/rc-collapse-3.1.2.tgz", + "integrity": "sha512-HujcKq7mghk/gVKeI6EjzTbb8e19XUZpakrYazu1MblEZ3Hu3WBMSN4A3QmvbF6n1g7x6lUlZvsHZ5shABWYOQ==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-motion": "^2.3.4", + "rc-util": "^5.2.1", + "shallowequal": "^1.1.0" + } + }, + "rc-dialog": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/rc-dialog/-/rc-dialog-8.6.0.tgz", + "integrity": "sha512-GSbkfqjqxpZC5/zc+8H332+q5l/DKUhpQr0vdX2uDsxo5K0PhvaMEVjyoJUTkZ3+JstEADQji1PVLVb/2bJeOQ==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.6", + "rc-motion": "^2.3.0", + "rc-util": "^5.6.1" + } + }, + "rc-drawer": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/rc-drawer/-/rc-drawer-4.3.1.tgz", + "integrity": "sha512-GMfFy4maqxS9faYXEhQ+0cA1xtkddEQzraf6SAdzWbn444DrrLogwYPk1NXSpdXjLCLxgxOj9MYtyYG42JsfXg==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.6", + "rc-util": "^5.7.0" + } + }, + "rc-dropdown": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/rc-dropdown/-/rc-dropdown-3.2.0.tgz", + "integrity": "sha512-j1HSw+/QqlhxyTEF6BArVZnTmezw2LnSmRk6I9W7BCqNCKaRwleRmMMs1PHbuaG8dKHVqP6e21RQ7vPBLVnnNw==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.6", + "rc-trigger": "^5.0.4" + } + }, + "rc-field-form": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/rc-field-form/-/rc-field-form-1.20.1.tgz", + "integrity": "sha512-f64KEZop7zSlrG4ef/PLlH12SLn6iHDQ3sTG+RfKBM45hikwV1i8qMf53xoX12NvXXWg1VwchggX/FSso4bWaA==", + "requires": { + "@babel/runtime": "^7.8.4", + "async-validator": "^3.0.3", + "rc-util": "^5.8.0" + } + }, + "rc-image": { + "version": "5.2.5", + "resolved": "https://registry.npmjs.org/rc-image/-/rc-image-5.2.5.tgz", + "integrity": "sha512-qUfZjYIODxO0c8a8P5GeuclYXZjzW4hV/5hyo27XqSFo1DmTCs2HkVeQObkcIk5kNsJtgsj1KoPThVsSc/PXOw==", + "requires": { + "@babel/runtime": "^7.11.2", + "classnames": "^2.2.6", + "rc-dialog": "~8.6.0", + "rc-util": "^5.0.6" + } + }, + "rc-input-number": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/rc-input-number/-/rc-input-number-7.1.4.tgz", + "integrity": "sha512-EG4iqkqyqzLRu/Dq+fw2od7nlgvXLEatE+J6uhi3HXE1qlM3C7L6a7o/hL9Ly9nimkES2IeQoj3Qda3I0izj3Q==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.5", + "rc-util": "^5.9.8" + } + }, + "rc-mentions": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/rc-mentions/-/rc-mentions-1.6.1.tgz", + "integrity": "sha512-LDzGI8jJVGnkhpTZxZuYBhMz3avcZZqPGejikchh97xPni/g4ht714Flh7DVvuzHQ+BoKHhIjobHnw1rcP8erg==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.6", + "rc-menu": "^9.0.0", + "rc-textarea": "^0.3.0", + "rc-trigger": "^5.0.4", + "rc-util": "^5.0.1" + } + }, + "rc-menu": { + "version": "9.0.14", + "resolved": "https://registry.npmjs.org/rc-menu/-/rc-menu-9.0.14.tgz", + "integrity": "sha512-CIox5mZeLDAi32SlHrV7UeSjv7tmJJhwRyxQtZCKt351w3q59XlL4WMFOmtT9gwIfP9h0XoxdBZUMe/xzkp78A==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-motion": "^2.4.3", + "rc-overflow": "^1.2.0", + "rc-trigger": "^5.1.2", + "rc-util": "^5.12.0", + "shallowequal": "^1.1.0" + } + }, + "rc-motion": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/rc-motion/-/rc-motion-2.4.4.tgz", + "integrity": "sha512-ms7n1+/TZQBS0Ydd2Q5P4+wJTSOrhIrwNxLXCZpR7Fa3/oac7Yi803HDALc2hLAKaCTQtw9LmQeB58zcwOsqlQ==", + "requires": { + "@babel/runtime": "^7.11.1", + "classnames": "^2.2.1", + "rc-util": "^5.2.1" + } + }, + "rc-notification": { + "version": "4.5.7", + "resolved": "https://registry.npmjs.org/rc-notification/-/rc-notification-4.5.7.tgz", + "integrity": "sha512-zhTGUjBIItbx96SiRu3KVURcLOydLUHZCPpYEn1zvh+re//Tnq/wSxN4FKgp38n4HOgHSVxcLEeSxBMTeBBDdw==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-motion": "^2.2.0", + "rc-util": "^5.0.1" + } + }, + "rc-overflow": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/rc-overflow/-/rc-overflow-1.2.2.tgz", + "integrity": "sha512-X5kj9LDU1ue5wHkqvCprJWLKC+ZLs3p4He/oxjZ1Q4NKaqKBaYf5OdSzRSgh3WH8kSdrfU8LjvlbWnHgJOEkNQ==", + "requires": { + "@babel/runtime": "^7.11.1", + "classnames": "^2.2.1", + "rc-resize-observer": "^1.0.0", + "rc-util": "^5.5.1" + } + }, + "rc-pagination": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/rc-pagination/-/rc-pagination-3.1.9.tgz", + "integrity": "sha512-IKBKaJ4icVPeEk9qRHrFBJmHxBUrCp3+nENBYob4Ofqsu3RXjBOy4N36zONO7oubgLyiG3PxVmyAuVlTkoc7Jg==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.1" + } + }, + "rc-picker": { + "version": "2.5.19", + "resolved": "https://registry.npmjs.org/rc-picker/-/rc-picker-2.5.19.tgz", + "integrity": "sha512-u6myoCu/qiQ0vLbNzSzNrzTQhs7mldArCpPHrEI6OUiifs+IPXmbesqSm0zilJjfzrZJLgYeyyOMSznSlh0GKA==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.1", + "date-fns": "2.x", + "dayjs": "1.x", + "moment": "^2.24.0", + "rc-trigger": "^5.0.4", + "rc-util": "^5.4.0", + "shallowequal": "^1.1.0" + } + }, + "rc-progress": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/rc-progress/-/rc-progress-3.1.4.tgz", + "integrity": "sha512-XBAif08eunHssGeIdxMXOmRQRULdHaDdIFENQ578CMb4dyewahmmfJRyab+hw4KH4XssEzzYOkAInTLS7JJG+Q==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.6" + } + }, + "rc-rate": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/rc-rate/-/rc-rate-2.9.1.tgz", + "integrity": "sha512-MmIU7FT8W4LYRRHJD1sgG366qKtSaKb67D0/vVvJYR0lrCuRrCiVQ5qhfT5ghVO4wuVIORGpZs7ZKaYu+KMUzA==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.5", + "rc-util": "^5.0.1" + } + }, + "rc-resize-observer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/rc-resize-observer/-/rc-resize-observer-1.0.1.tgz", + "integrity": "sha512-OxO2mJI9e8610CAWBFfm52SPvWib0eNKjaSsRbbKHmLaJIxw944P+D61DlLJ/w2vuOjGNcalJu8VdqyNm/XCRg==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.1", + "rc-util": "^5.0.0", + "resize-observer-polyfill": "^1.5.1" + } + }, + "rc-select": { + "version": "12.1.13", + "resolved": "https://registry.npmjs.org/rc-select/-/rc-select-12.1.13.tgz", + "integrity": "sha512-cPI+aesP6dgCAaey4t4upDbEukJe+XN0DK6oO/6flcCX5o28o7KNZD7JAiVtC/6fCwqwI/kSs7S/43dvHmBl+A==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-motion": "^2.0.1", + "rc-overflow": "^1.0.0", + "rc-trigger": "^5.0.4", + "rc-util": "^5.9.8", + "rc-virtual-list": "^3.2.0" + } + }, + "rc-slider": { + "version": "9.7.4", + "resolved": "https://registry.npmjs.org/rc-slider/-/rc-slider-9.7.4.tgz", + "integrity": "sha512-pjLKLiDKiaL7/pNywfIBD+lDo5TtVo05KuIBSWEIoqu6FHh6IMWvthCiaODuYaVs3RLeF2nXOP5AjkD2Lt2Rwg==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.5", + "rc-tooltip": "^5.0.1", + "rc-util": "^5.0.0", + "shallowequal": "^1.1.0" + } + }, + "rc-steps": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/rc-steps/-/rc-steps-4.1.4.tgz", + "integrity": "sha512-qoCqKZWSpkh/b03ASGx1WhpKnuZcRWmvuW+ZUu4mvMdfvFzVxblTwUM+9aBd0mlEUFmt6GW8FXhMpHkK3Uzp3w==", + "requires": { + "@babel/runtime": "^7.10.2", + "classnames": "^2.2.3", + "rc-util": "^5.0.1" + } + }, + "rc-switch": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/rc-switch/-/rc-switch-3.2.2.tgz", + "integrity": "sha512-+gUJClsZZzvAHGy1vZfnwySxj+MjLlGRyXKXScrtCTcmiYNPzxDFOxdQ/3pK1Kt/0POvwJ/6ALOR8gwdXGhs+A==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.1", + "rc-util": "^5.0.1" + } + }, + "rc-table": { + "version": "7.15.2", + "resolved": "https://registry.npmjs.org/rc-table/-/rc-table-7.15.2.tgz", + "integrity": "sha512-TAs7kCpIZwc2mtvD8CMrXSM6TqJDUsy0rUEV1YgRru33T8bjtAtc+9xW/KC1VWROJlHSpU0R0kXjFs9h/6+IzQ==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.5", + "rc-resize-observer": "^1.0.0", + "rc-util": "^5.13.0", + "shallowequal": "^1.1.0" + } + }, + "rc-tabs": { + "version": "11.10.3", + "resolved": "https://registry.npmjs.org/rc-tabs/-/rc-tabs-11.10.3.tgz", + "integrity": "sha512-rPxsci+76/nnJowNOBO3LTi4eL6trG49cR9yPc4XbuyHXhCHUujN5F4+jFl7trISy+yVN6gCZ/wiTtVnkcR/UA==", + "requires": { + "@babel/runtime": "^7.11.2", + "classnames": "2.x", + "rc-dropdown": "^3.2.0", + "rc-menu": "^9.0.0", + "rc-resize-observer": "^1.0.0", + "rc-util": "^5.5.0" + } + }, + "rc-textarea": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/rc-textarea/-/rc-textarea-0.3.5.tgz", + "integrity": "sha512-qa+k5vDn9ct65qr+SgD2KwJ9Xz6P84lG2z+TDht/RBr71WnM/K61PqHUAcUyU6YqTJD26IXgjPuuhZR7HMw7eA==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.1", + "rc-resize-observer": "^1.0.0", + "rc-util": "^5.7.0" + } + }, + "rc-tooltip": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/rc-tooltip/-/rc-tooltip-5.1.1.tgz", + "integrity": "sha512-alt8eGMJulio6+4/uDm7nvV+rJq9bsfxFDCI0ljPdbuoygUscbsMYb6EQgwib/uqsXQUvzk+S7A59uYHmEgmDA==", + "requires": { + "@babel/runtime": "^7.11.2", + "rc-trigger": "^5.0.0" + } + }, + "rc-tree": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/rc-tree/-/rc-tree-4.2.2.tgz", + "integrity": "sha512-V1hkJt092VrOVjNyfj5IYbZKRMHxWihZarvA5hPL/eqm7o2+0SNkeidFYm7LVVBrAKBpOpa0l8xt04uiqOd+6w==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-motion": "^2.0.1", + "rc-util": "^5.0.0", + "rc-virtual-list": "^3.0.1" + } + }, + "rc-tree-select": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/rc-tree-select/-/rc-tree-select-4.3.3.tgz", + "integrity": "sha512-0tilOHLJA6p+TNg4kD559XnDX3PTEYuoSF7m7ryzFLAYvdEEPtjn0QZc5z6L0sMKBiBlj8a2kf0auw8XyHU3lA==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-select": "^12.0.0", + "rc-tree": "^4.0.0", + "rc-util": "^5.0.5" + } + }, + "rc-trigger": { + "version": "5.2.10", + "resolved": "https://registry.npmjs.org/rc-trigger/-/rc-trigger-5.2.10.tgz", + "integrity": "sha512-FkUf4H9BOFDaIwu42fvRycXMAvkttph9AlbCZXssZDVzz2L+QZ0ERvfB/4nX3ZFPh1Zd+uVGr1DEDeXxq4J1TA==", + "requires": { + "@babel/runtime": "^7.11.2", + "classnames": "^2.2.6", + "rc-align": "^4.0.0", + "rc-motion": "^2.0.0", + "rc-util": "^5.5.0" + } + }, + "rc-upload": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/rc-upload/-/rc-upload-4.3.2.tgz", + "integrity": "sha512-v0HdwC/19xKAn1OYZ4hTMUSqSs/IA0n1v4p/cioSSnKubHrdpcCXC45N+TFMSOZtBlf4+xMNCFo3KDih31lAMg==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.5", + "rc-util": "^5.2.0" + } + }, + "rc-util": { + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.15.0.tgz", + "integrity": "sha512-8RI8sjOCXD3FhD3dzQNBQetpGol6BBd3sHQ/8jSGk9NPT0CH3JGtBfPODnASyE7AdDpCFQMOmgcp9CBs3S/1hg==", + "requires": { + "@babel/runtime": "^7.12.5", + "react-is": "^16.12.0", + "shallowequal": "^1.1.0" + } + }, + "rc-virtual-list": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/rc-virtual-list/-/rc-virtual-list-3.4.2.tgz", + "integrity": "sha512-OyVrrPvvFcHvV0ssz5EDZ+7Rf5qLat/+mmujjchNw5FfbJWNDwkpQ99EcVE6+FtNRmX9wFa1LGNpZLUTvp/4GQ==", + "requires": { + "classnames": "^2.2.6", + "rc-resize-observer": "^1.0.0", + "rc-util": "^5.0.7" + } + }, "react": { "version": "16.14.0", "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", @@ -17699,6 +18210,11 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "react-js-cron": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/react-js-cron/-/react-js-cron-1.2.1.tgz", + "integrity": "sha512-3iesosu5l/JsmbSZj8kb3OPcGFA+yM6WvetbsDk8SC8mgaxyAWU+1VS27rrd1OPCnCAHjx42trBxAteQRbtYqg==" + }, "react-js-pagination": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/react-js-pagination/-/react-js-pagination-3.0.3.tgz", @@ -20681,6 +21197,11 @@ "is-number": "^7.0.0" } }, + "toggle-selection": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", + "integrity": "sha1-bkWxJj8gF/oKzH2J14sVuL932jI=" + }, "toidentifier": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", diff --git a/catalog-rest-service/src/main/resources/ui/package.json b/catalog-rest-service/src/main/resources/ui/package.json index 936029b6b0d..ea37fa0f210 100644 --- a/catalog-rest-service/src/main/resources/ui/package.json +++ b/catalog-rest-service/src/main/resources/ui/package.json @@ -17,6 +17,7 @@ "@types/react-dom": "^17.0.5", "@typescript-eslint/eslint-plugin": "^2.10.0", "@typescript-eslint/parser": "^2.10.0", + "antd": "^4.16.13", "autoprefixer": "^9.8.6", "axios": "^0.21.1", "babel-plugin-named-asset-import": "^0.3.6", @@ -26,6 +27,7 @@ "codemirror": "^5.62.3", "cookie-storage": "^6.1.0", "core-js": "^3.10.1", + "cronstrue": "^1.122.0", "diff": "^5.0.0", "draft-js": "^0.11.7", "eslint": "^6.6.0", @@ -59,6 +61,7 @@ "react-dom": "^16.14.0", "react-draft-wysiwyg": "^1.14.7", "react-flow-renderer": "^9.6.8", + "react-js-cron": "^1.2.1", "react-js-pagination": "^3.0.3", "react-markdown": "^6.0.3", "react-oidc": "^1.0.3", diff --git a/catalog-rest-service/src/main/resources/ui/src/assets/svg/deploy-icon.svg b/catalog-rest-service/src/main/resources/ui/src/assets/svg/deploy-icon.svg new file mode 100644 index 00000000000..d1ee599b366 --- /dev/null +++ b/catalog-rest-service/src/main/resources/ui/src/assets/svg/deploy-icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/catalog-rest-service/src/main/resources/ui/src/axiosAPIs/ingestionWorkflowAPI.ts b/catalog-rest-service/src/main/resources/ui/src/axiosAPIs/ingestionWorkflowAPI.ts new file mode 100644 index 00000000000..3902c8731d2 --- /dev/null +++ b/catalog-rest-service/src/main/resources/ui/src/axiosAPIs/ingestionWorkflowAPI.ts @@ -0,0 +1,81 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 { AxiosResponse } from 'axios'; +import { Operation } from 'fast-json-patch'; +import { IngestionData } from '../components/Ingestion/ingestion.interface'; +import { getURLWithQueryFields } from '../utils/APIUtils'; +import APIClient from './index'; + +const operationsBaseUrl = '/api/operations/v1'; + +export const addIngestionWorkflow = ( + data: IngestionData +): Promise => { + const url = '/ingestion'; + + return APIClient({ + method: 'post', + url, + baseURL: operationsBaseUrl, + data: data, + }); +}; + +export const getIngestionWorkflows = ( + arrQueryFields: Array, + paging?: string +): Promise => { + const url = `${getURLWithQueryFields('/ingestion', arrQueryFields)}${ + paging ? paging : '' + }`; + + return APIClient({ method: 'get', url, baseURL: operationsBaseUrl }); +}; + +export const triggerIngestionWorkflowsById = ( + id: string, + arrQueryFields = '' +): Promise => { + const url = getURLWithQueryFields(`/ingestion/trigger/${id}`, arrQueryFields); + + return APIClient({ method: 'post', url, baseURL: operationsBaseUrl }); +}; + +export const deleteIngestionWorkflowsById = ( + id: string, + arrQueryFields = '' +): Promise => { + const url = getURLWithQueryFields(`/ingestion/${id}`, arrQueryFields); + + return APIClient({ method: 'delete', url, baseURL: operationsBaseUrl }); +}; + +export const patchIngestionWorkflowBtId = ( + id: string, + data: Array +): Promise => { + const url = `/ingestion/${id}`; + + return APIClient({ + method: 'patch', + url, + baseURL: operationsBaseUrl, + data: data, + headers: { 'Content-type': 'application/json-patch+json' }, + }); +}; diff --git a/catalog-rest-service/src/main/resources/ui/src/components/Ingestion/Ingestion.component.tsx b/catalog-rest-service/src/main/resources/ui/src/components/Ingestion/Ingestion.component.tsx new file mode 100644 index 00000000000..3fdb44b7718 --- /dev/null +++ b/catalog-rest-service/src/main/resources/ui/src/components/Ingestion/Ingestion.component.tsx @@ -0,0 +1,460 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 classNames from 'classnames'; +import cronstrue from 'cronstrue'; +import { compare } from 'fast-json-patch'; +import { capitalize, isNil, lowerCase } from 'lodash'; +import React, { useCallback, useState } from 'react'; +import { Link } from 'react-router-dom'; +import { + getServiceDetailsPath, + TITLE_FOR_NON_ADMIN_ACTION, +} from '../../constants/constants'; +import { NoDataFoundPlaceHolder } from '../../constants/services.const'; +import { useAuth } from '../../hooks/authHooks'; +import { isEven } from '../../utils/CommonUtils'; +import { Button } from '../buttons/Button/Button'; +import NextPrevious from '../common/next-previous/NextPrevious'; +import NonAdminAction from '../common/non-admin-action/NonAdminAction'; +import PopOver from '../common/popover/PopOver'; +import Searchbar from '../common/searchbar/Searchbar'; +import PageContainer from '../containers/PageContainer'; +import IngestionModal from '../IngestionModal/IngestionModal.component'; +import Loader from '../Loader/Loader'; +import ConfirmationModal from '../Modals/ConfirmationModal/ConfirmationModal'; +import { IngestionData, Props } from './ingestion.interface'; + +const Ingestion: React.FC = ({ + ingestionList, + serviceList, + deleteIngestion, + triggerIngestion, + addIngestion, + updateIngestion, + paging, + pagingHandler, +}: Props) => { + const { isAdminUser, isAuthDisabled } = useAuth(); + const [searchText, setSearchText] = useState(''); + const [currTriggerId, setCurrTriggerId] = useState({ id: '', state: '' }); + const [isAdding, setIsAdding] = useState(false); + const [isUpdating, setIsUpdating] = useState(false); + const [isConfirmationModalOpen, setIsConfirmationModalOpen] = useState(false); + const [deleteSelection, setDeleteSelection] = useState({ + id: '', + name: '', + state: '', + }); + const [updateSelection, setUpdateSelection] = useState({ + id: '', + name: '', + state: '', + ingestion: {} as IngestionData, + }); + + const handleSearchAction = (searchValue: string) => { + setSearchText(searchValue); + }; + + const handleTriggerIngestion = (id: string, displayName: string) => { + setCurrTriggerId({ id, state: 'waiting' }); + triggerIngestion(id, displayName) + .then(() => { + setCurrTriggerId({ id, state: 'success' }); + setTimeout(() => setCurrTriggerId({ id: '', state: '' }), 1500); + }) + .catch(() => setCurrTriggerId({ id: '', state: '' })); + }; + + const handleCancelConfirmationModal = () => { + setIsConfirmationModalOpen(false); + setDeleteSelection({ + id: '', + name: '', + state: '', + }); + }; + + const handleUpdate = (ingestion: IngestionData) => { + setUpdateSelection({ + id: ingestion.id as string, + name: ingestion.displayName, + state: '', + ingestion: ingestion, + }); + setIsUpdating(true); + }; + + const handleCancelUpdate = () => { + setUpdateSelection({ + id: '', + name: '', + state: '', + ingestion: {} as IngestionData, + }); + setIsUpdating(false); + }; + const handleUpdateIngestion = ( + data: IngestionData, + triggerIngestion?: boolean + ) => { + const { service, owner } = updateSelection.ingestion; + const updatedData = { + ...updateSelection.ingestion, + ...data, + service, + owner, + }; + const patch = compare(updateSelection.ingestion, updatedData); + setUpdateSelection((prev) => ({ ...prev, state: 'waiting' })); + updateIngestion( + updateSelection.id, + updateSelection.name, + patch, + triggerIngestion + ) + .then(() => { + setTimeout(() => { + setUpdateSelection((prev) => ({ ...prev, state: 'success' })); + handleCancelUpdate(); + }, 500); + }) + .catch(() => { + handleCancelUpdate(); + }); + }; + + const handleDelete = (id: string, displayName: string) => { + setDeleteSelection({ id, name: displayName, state: 'waiting' }); + deleteIngestion(id, displayName) + .then(() => { + setTimeout(() => { + setDeleteSelection({ id, name: displayName, state: 'success' }); + handleCancelConfirmationModal(); + }, 500); + }) + .catch(() => { + handleCancelConfirmationModal(); + }); + }; + + const ConfirmDelete = (id: string, name: string) => { + setDeleteSelection({ + id, + name, + state: '', + }); + setIsConfirmationModalOpen(true); + }; + + const getServiceTypeFromName = (serviceName = ''): string => { + return ( + serviceList.find((service) => service.name === serviceName) + ?.serviceType || '' + ); + }; + + const getSearchedIngestions = useCallback(() => { + const sText = lowerCase(searchText); + + return sText + ? ingestionList.filter( + (ing) => + lowerCase(ing.displayName).includes(sText) || + lowerCase(ing.name).includes(sText) + ) + : ingestionList; + }, [searchText, ingestionList]); + + const getStatuses = (ingestion: IngestionData) => { + const lastFiveIngestions = ingestion.ingestionStatuses + ?.sort((a, b) => { + // Turn your strings into millis, and then subtract them + // to get a value that is either negative, positive, or zero. + const date1 = new Date(a.startDate); + const date2 = new Date(b.startDate); + + return date1.getTime() - date2.getTime(); + }) + .slice(Math.max(ingestion.ingestionStatuses.length - 5, 0)); + + return lastFiveIngestions?.map((r, i) => { + return ( + + {r.startDate ? ( +

Start Date: {new Date(r.startDate).toUTCString()}

+ ) : null} + {r.endDate ? ( +

End Date: {new Date(r.endDate).toUTCString()}

+ ) : null} + + } + key={i} + position="bottom" + theme="light" + trigger="mouseenter"> + {i === lastFiveIngestions.length - 1 ? ( +

+ {capitalize(r.state)} +

+ ) : ( +

+ )} + + ); + }); + }; + + return ( + +

+
+
+ {searchText || getSearchedIngestions().length > 0 ? ( + + ) : null} +
+
+ + + +
+
+ {getSearchedIngestions().length ? ( +
+ + + + + + + + + {/* */} + + + + + {getSearchedIngestions().map((ingestion, index) => ( + + + + + + + {/* */} + + + ))} + +
NameTypeServiceScheduleRecent RunsNext RunActions
{ingestion.displayName} + {ingestion.ingestionType} + + + {ingestion.service.name} + + + + {cronstrue.toString( + ingestion.scheduleInterval || '', + { + use24HourTimeFormat: true, + verbose: true, + } + )} + + } + position="bottom" + theme="light" + trigger="mouseenter"> + {ingestion.scheduleInterval} + + +
{getStatuses(ingestion)}
+
+ {ingestion.nextExecutionDate || '--'} + + +
+
+ handleTriggerIngestion( + ingestion.id as string, + ingestion.displayName + ) + }> + {currTriggerId.id === ingestion.id ? ( + currTriggerId.state === 'success' ? ( +
+ {Boolean(!isNil(paging.after) || !isNil(paging.before)) && ( + + )} +
+ ) : ( +
+
+ No Service +
+
+

+ {`No ingestion workflows found ${ + searchText ? `for "${searchText}"` : '' + }`} +

+
+
+ )} +
+ {isAdding ? ( + { + setIsAdding(false); + addIngestion(data, triggerIngestion); + }} + header="Add Ingestion" + ingestionList={ingestionList} + name="" + service="" + serviceList={serviceList.map((s) => ({ + name: s.name, + serviceType: s.serviceType, + }))} + type="" + onCancel={() => setIsAdding(false)} + /> + ) : null} + {isUpdating ? ( + {`Edit ${updateSelection.name}`}

} + ingestionList={ingestionList} + selectedIngestion={updateSelection.ingestion} + serviceList={serviceList.map((s) => ({ + name: s.name, + serviceType: s.serviceType, + }))} + updateIngestion={(data, triggerIngestion) => { + setIsUpdating(false); + handleUpdateIngestion(data, triggerIngestion); + }} + onCancel={() => handleCancelUpdate()} + /> + ) : null} + {isConfirmationModalOpen && ( + + ) : deleteSelection.state === 'success' ? ( +