diff --git a/frontend/config/webpack.config.js b/frontend/config/webpack.config.js index 9995d0556a..2413dd6b22 100644 --- a/frontend/config/webpack.config.js +++ b/frontend/config/webpack.config.js @@ -23,6 +23,7 @@ const modules = require('./modules'); const ModuleNotFoundPlugin = require('react-dev-utils/ModuleNotFoundPlugin'); const NodePolyfillPlugin = require('node-polyfill-webpack-plugin'); const webpackBundleTracker = require('webpack-bundle-tracker'); +const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; const ForkTsCheckerWebpackPlugin = process.env.TSC_COMPILE_ON_ERROR === 'true' @@ -90,6 +91,23 @@ const hasJsxRuntime = (() => { } })(); +// Load third-party packages on demand +const excludedChunkNames = [ + 'sharedFileViewAudio', + 'sharedFileViewVideo', + 'fileView', + 'viewFileSdoc', + 'sharedFileViewSdoc', + 'sdocPublishedRevision', + 'sdocFileHistory', + 'wiki2', + 'sharedFileViewText', + 'viewFileText', + 'sharedFileViewMarkdown', + 'markdownEditor', + 'plainMarkdownEditor', +]; + // This is the production and development configuration. // It is focused on developer experience, fast rebuilds, and a minimal bundle. module.exports = function (webpackEnv) { @@ -298,7 +316,9 @@ module.exports = function (webpackEnv) { // https://twitter.com/wSokra/status/969633336732905474 // https://medium.com/webpack/webpack-4-code-splitting-chunk-graph-and-the-splitchunks-optimization-be739a861366 splitChunks: { - chunks: 'all', + chunks(chunk) { + return !excludedChunkNames.includes(chunk.name); + }, automaticNameDelimiter: '-', cacheGroups: { default: false, @@ -309,7 +329,7 @@ module.exports = function (webpackEnv) { priority: 30000, reuseExistingChunk: true, }, - } + }, }, // Keep the runtime chunk separated to enable long term caching // https://twitter.com/wSokra/status/969679223278505985 @@ -317,6 +337,7 @@ module.exports = function (webpackEnv) { runtimeChunk: { name: 'runtime', }, + // concatenateModules: false, }, resolve: { // This allows you to set a fallback for where webpack should look for modules. @@ -807,6 +828,7 @@ module.exports = function (webpackEnv) { filename: isEnvProduction ? './webpack-stats.pro.json' : './webpack-stats.dev.json', publicPath: isEnvProduction ? '' : paths.publicUrlOrPath }), + // new BundleAnalyzerPlugin(), ].filter(Boolean), // Turn off performance processing because we utilize // our own hints via the FileSizeReporter diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 1c6ceb29c7..08050a67a3 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -18,12 +18,12 @@ "@seafile/resumablejs": "1.1.16", "@seafile/sdoc-editor": "1.0.106", "@seafile/seafile-calendar": "0.0.28", - "@seafile/seafile-editor": "^1.0.121", - "@seafile/sf-metadata-ui-component": "^0.0.43", + "@seafile/seafile-editor": "^1.0.122", + "@seafile/sf-metadata-ui-component": "^0.0.45", "@uiw/codemirror-extensions-langs": "^4.19.4", "@uiw/react-codemirror": "^4.19.4", "axios": "^1.7.4", - "chart.js": "2.9.4", + "chart.js": "3.6.0", "classnames": "^2.2.6", "codemirror": "^6.0.1", "copy-to-clipboard": "^3.0.8", @@ -36,17 +36,16 @@ "i18next-xhr-backend": "^3.1.2", "is-hotkey": "0.2.0", "MD5": "^1.3.0", - "moment": "^2.22.2", "object-assign": "4.1.1", - "prop-types": "15.8.1", + "prop-types": "^15.8.1", "qrcode.react": "^1.0.1", - "react": "17.0.0", + "react": "17.0.2", "react-app-polyfill": "^2.0.0", - "react-chartjs-2": "^2.8.0", + "react-chartjs-2": "4.0.0", "react-cookies": "^0.1.0", "react-dnd": "^2.6.0", "react-dnd-html5-backend": "^2.6.0", - "react-dom": "17.0.0", + "react-dom": "17.0.2", "react-i18next": "^10.12.2", "react-responsive": "9.0.2", "react-select": "5.7.0", @@ -117,6 +116,7 @@ "url-loader": "4.1.1", "web-vitals": "2.1.4", "webpack": "^5.64.4", + "webpack-bundle-analyzer": "^4.10.2", "webpack-bundle-tracker": "1.7.0", "webpack-dev-server": "^4.6.0", "webpack-manifest-plugin": "^4.0.2", @@ -2870,6 +2870,15 @@ "postcss-selector-parser": "^6.0.10" } }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/@emoji-mart/data": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@emoji-mart/data/-/data-1.2.1.tgz", @@ -2949,14 +2958,14 @@ "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==" }, "node_modules/@emotion/react": { - "version": "11.13.0", - "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.13.0.tgz", - "integrity": "sha512-WkL+bw1REC2VNV1goQyfxjx1GYJkcc23CRQkXX+vZNLINyfI7o+uUn/rTGPt/xJ3bJHd5GcljgnxHf4wRw5VWQ==", + "version": "11.13.3", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.13.3.tgz", + "integrity": "sha512-lIsdU6JNrmYfJ5EbUCf4xW1ovy5wKQ2CkPRM4xogziOxH1nXxBSjpC9YqbFAP7circxMfYp+6x676BqWcEiixg==", "dependencies": { "@babel/runtime": "^7.18.3", "@emotion/babel-plugin": "^11.12.0", "@emotion/cache": "^11.13.0", - "@emotion/serialize": "^1.3.0", + "@emotion/serialize": "^1.3.1", "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", "@emotion/utils": "^1.4.0", "@emotion/weak-memoize": "^0.4.0", @@ -2985,14 +2994,14 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "node_modules/@emotion/serialize": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.0.tgz", - "integrity": "sha512-jACuBa9SlYajnpIVXB+XOXnfJHyckDfe6fOpORIM6yhBDlqGuExvDdZYHDQGoDf3bZXGv7tNr+LpLjJqiEQ6EA==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.2.tgz", + "integrity": "sha512-grVnMvVPK9yUVE6rkKfAJlYZgo0cu3l9iMC77V7DW6E1DUIrU68pSEXRmFZFOFB1QFo57TncmOcvcbMDWsL4yA==", "dependencies": { "@emotion/hash": "^0.9.2", "@emotion/memoize": "^0.9.0", - "@emotion/unitless": "^0.9.0", - "@emotion/utils": "^1.4.0", + "@emotion/unitless": "^0.10.0", + "@emotion/utils": "^1.4.1", "csstype": "^3.0.2" } }, @@ -3002,9 +3011,9 @@ "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==" }, "node_modules/@emotion/unitless": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.9.0.tgz", - "integrity": "sha512-TP6GgNZtmtFaFcsOgExdnfxLLpRDla4Q66tnenA9CktvVSdNKDvMVuUah4QvWPIpNjrWsGg3qeGo9a43QooGZQ==" + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", + "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==" }, "node_modules/@emotion/use-insertion-effect-with-fallbacks": { "version": "1.1.0", @@ -3015,9 +3024,9 @@ } }, "node_modules/@emotion/utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.0.tgz", - "integrity": "sha512-spEnrA1b6hDR/C68lC2M7m6ALPUHZC0lIY7jAS/B/9DuuO1ZP04eov8SMv/6fwRd8pzmsn2AuJEznRREWlQrlQ==" + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.1.tgz", + "integrity": "sha512-BymCXzCG3r72VKJxaYVwOXATqXIZ85cuvg0YOUDxMGNrKc1DJRZk8MgV5wyXRyEayIMd4FuXJIUgTBXvDNW5cA==" }, "node_modules/@emotion/weak-memoize": { "version": "0.4.0", @@ -3138,26 +3147,26 @@ } }, "node_modules/@floating-ui/core": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.7.tgz", - "integrity": "sha512-yDzVT/Lm101nQ5TCVeK65LtdN7Tj4Qpr9RTXJ2vPFLqtLxwOrpoxAHAJI8J3yYWUc40J0BDBheaitK5SJmno2g==", + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.8.tgz", + "integrity": "sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==", "dependencies": { - "@floating-ui/utils": "^0.2.7" + "@floating-ui/utils": "^0.2.8" } }, "node_modules/@floating-ui/dom": { - "version": "1.6.10", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.10.tgz", - "integrity": "sha512-fskgCFv8J8OamCmyun8MfjB1Olfn+uZKjOKZ0vhYF3gRmEUXcGOjxWL8bBr7i4kIuPZ2KD2S3EUIOxnjC8kl2A==", + "version": "1.6.11", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.11.tgz", + "integrity": "sha512-qkMCxSR24v2vGkhYDo/UzxfJN3D4syqSjyuTFz6C7XcpU1pASPRieNI0Kj5VP3/503mOfYiGY891ugBX1GlABQ==", "dependencies": { "@floating-ui/core": "^1.6.0", - "@floating-ui/utils": "^0.2.7" + "@floating-ui/utils": "^0.2.8" } }, "node_modules/@floating-ui/utils": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.7.tgz", - "integrity": "sha512-X8R8Oj771YRl/w+c1HqAC1szL8zWQRwFvgDwT129k9ACdBoud/+/rX9V0qiMl6LWUdP9voC2nDVZYPMQQsb6eA==" + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.8.tgz", + "integrity": "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==" }, "node_modules/@formatjs/intl-unified-numberformat": { "version": "3.3.7", @@ -4618,6 +4627,12 @@ } } }, + "node_modules/@polka/url": { + "version": "1.0.0-next.28", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.28.tgz", + "integrity": "sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==", + "dev": true + }, "node_modules/@replit/codemirror-lang-csharp": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/@replit/codemirror-lang-csharp/-/codemirror-lang-csharp-6.2.0.tgz", @@ -4983,9 +4998,9 @@ } }, "node_modules/@seafile/seafile-editor": { - "version": "1.0.121", - "resolved": "https://registry.npmjs.org/@seafile/seafile-editor/-/seafile-editor-1.0.121.tgz", - "integrity": "sha512-aGzZwMviihevdajTkcDo8kAqaAi/tnKmdUJD6sIzQsB2acOrThJI1YEh3IYqYpSY4QAt8kivhYOzZl/Ngh7WMw==", + "version": "1.0.122", + "resolved": "https://registry.npmjs.org/@seafile/seafile-editor/-/seafile-editor-1.0.122.tgz", + "integrity": "sha512-I1/wAkx0PQKlWC4IjlKDUNvSoO8/q0WF2xMQLEIuI50E1gtln5u/cQv6ylcfhD0lRj5EARHTgFI3EJ80NgzaPw==", "dependencies": { "@seafile/react-image-lightbox": "2.0.5", "classnames": "2.3.2", @@ -5093,12 +5108,12 @@ } }, "node_modules/@seafile/sf-metadata-ui-component": { - "version": "0.0.43", - "resolved": "https://registry.npmjs.org/@seafile/sf-metadata-ui-component/-/sf-metadata-ui-component-0.0.43.tgz", - "integrity": "sha512-p3MNjZ3ExLf02GRxe7/daU6MCMiRPGiP1cjnJeff1UPEodHISejw21vOsB08wTqPuvlN/PjEte8rgcyKmhkXMg==", + "version": "0.0.45", + "resolved": "https://registry.npmjs.org/@seafile/sf-metadata-ui-component/-/sf-metadata-ui-component-0.0.45.tgz", + "integrity": "sha512-8gYtcXVuJ2mvPxVWPjsTFZSnhZtVcBKL9WR+ZN1lcks9/fDRXKl9riS30hkg0BWNqSgPcF2csE0LT/rnza2zrQ==", "dependencies": { "@seafile/seafile-calendar": "0.0.28", - "@seafile/seafile-editor": "~1.0.121", + "@seafile/seafile-editor": "^1.0.122", "classnames": "2.3.2", "dayjs": "1.10.7", "escape-html": "^1.0.3", @@ -5106,7 +5121,6 @@ "intl-messageformat": "^7.8.4", "invariant": "^2.2.2", "is-hotkey": "0.2.0", - "prop-types": "^15.8.1", "react-app-polyfill": "^3.0.0", "react-responsive": "9.0.2", "react-select": "5.7.0", @@ -5115,9 +5129,9 @@ }, "peerDependencies": { "lodash-es": "^4.17.21", - "prop-types": "15.8.1", - "react": "17.0.0", - "react-dom": "17.0.0" + "prop-types": "^15.8.1", + "react": "17.0.2", + "react-dom": "17.0.2" } }, "node_modules/@seafile/sf-metadata-ui-component/node_modules/classnames": { @@ -6133,9 +6147,9 @@ "dev": true }, "node_modules/@types/prop-types": { - "version": "15.7.12", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", - "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==" + "version": "15.7.13", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz", + "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==" }, "node_modules/@types/q": { "version": "1.5.8", @@ -6156,9 +6170,9 @@ "dev": true }, "node_modules/@types/react": { - "version": "18.3.3", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz", - "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==", + "version": "18.3.11", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.11.tgz", + "integrity": "sha512-r6QZ069rFTjrEYgFdOck1gK7FLVsgJE7tTz0pQBczlBNUhBNk0MQH4UbnFSwjpQLMkLzgqvBBa+qGpLje16eTQ==", "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -8594,30 +8608,9 @@ } }, "node_modules/chart.js": { - "version": "2.9.4", - "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-2.9.4.tgz", - "integrity": "sha512-B07aAzxcrikjAPyV+01j7BmOpxtQETxTSlQ26BEYJ+3iUkbNKaOJ/nDbT6JjyqYxseM0ON12COHYdU2cTIjC7A==", - "dependencies": { - "chartjs-color": "^2.1.0", - "moment": "^2.10.2" - } - }, - "node_modules/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==", - "dependencies": { - "chartjs-color-string": "^0.6.0", - "color-convert": "^1.9.3" - } - }, - "node_modules/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==", - "dependencies": { - "color-name": "^1.0.0" - } + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-3.6.0.tgz", + "integrity": "sha512-iOzzDKePL+bj+ccIsVAgWQehCXv8xOKGbaU2fO/myivH736zcx535PGJzQGanvcSGVOqX6yuLZsN3ygcQ35UgQ==" }, "node_modules/check-types": { "version": "11.2.3", @@ -8865,7 +8858,8 @@ "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "node_modules/colord": { "version": "2.9.3", @@ -9749,6 +9743,12 @@ "integrity": "sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig==", "license": "MIT" }, + "node_modules/debounce": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", + "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==", + "dev": true + }, "node_modules/debug": { "version": "4.3.6", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", @@ -10325,31 +10325,6 @@ "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" }, - "node_modules/dtable-ui-component/node_modules/react": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", - "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", - "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/dtable-ui-component/node_modules/react-dom": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", - "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", - "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "scheduler": "^0.20.2" - }, - "peerDependencies": { - "react": "17.0.2" - } - }, "node_modules/dtable-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/dtable-utils/-/dtable-utils-4.4.0.tgz", @@ -19085,14 +19060,6 @@ "mkdirp": "bin/cmd.js" } }, - "node_modules/moment": { - "version": "2.30.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", - "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", - "engines": { - "node": "*" - } - }, "node_modules/mpd-parser": { "version": "0.22.1", "resolved": "https://registry.npmjs.org/mpd-parser/-/mpd-parser-0.22.1.tgz", @@ -19107,6 +19074,15 @@ "mpd-to-m3u8-json": "bin/parse.js" } }, + "node_modules/mrmime": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", + "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -19719,6 +19695,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "dev": true, + "bin": { + "opener": "bin/opener-bin.js" + } + }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -22057,9 +22042,9 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "node_modules/react": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/react/-/react-17.0.0.tgz", - "integrity": "sha512-rG9bqS3LMuetoSUKHN8G3fMNuQOePKDThK6+2yXFWtoeTDLVNh/QCaxT+Jr+rNf4lwNXpx+atdn3Aa0oi8/6eQ==", + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", + "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", "dependencies": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" @@ -22108,17 +22093,12 @@ "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" }, "node_modules/react-chartjs-2": { - "version": "2.11.2", - "resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-2.11.2.tgz", - "integrity": "sha512-hcPS9vmRJeAALPPf0uo02BiD8BDm0HNmneJYTZVR74UKprXOpql+Jy1rVuj93rKw0Jfx77mkcRfXPxTe5K83uw==", - "dependencies": { - "lodash": "^4.17.19", - "prop-types": "^15.7.2" - }, + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-4.0.0.tgz", + "integrity": "sha512-0kx41EVO6wIoeU6zvdwovX9kKcdrs7O62DGTSNmwAXZeLGJ3U+n4XijO1kxcMmAi4I6PQJWGD5oRwxVixHSp6g==", "peerDependencies": { - "chart.js": "^2.3", - "react": "^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0", - "react-dom": "^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + "chart.js": "^3.5.0", + "react": "^16.8.0 || ^17.0.0" } }, "node_modules/react-color": { @@ -22353,16 +22333,16 @@ } }, "node_modules/react-dom": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.0.tgz", - "integrity": "sha512-OGnFbxCjI2TMAZYMVxi4hqheJiN8rCEVVrL7XIGzCB6beNc4Am8M47HtkvxODZw9QgjmAPKpLba9FTu4fC1byA==", + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", + "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", "dependencies": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", - "scheduler": "^0.20.0" + "scheduler": "^0.20.2" }, "peerDependencies": { - "react": "17.0.0" + "react": "17.0.2" } }, "node_modules/react-error-overlay": { @@ -24753,6 +24733,20 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, + "node_modules/sirv": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", + "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", + "dev": true, + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">= 10" + } + }, "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", @@ -26793,6 +26787,15 @@ "node": ">=0.6" } }, + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/tough-cookie": { "version": "4.1.4", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", @@ -27937,6 +27940,65 @@ } } }, + "node_modules/webpack-bundle-analyzer": { + "version": "4.10.2", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.2.tgz", + "integrity": "sha512-vJptkMm9pk5si4Bv922ZbKLV8UTT4zib4FPgXMhgzUny0bfDDkLXAVQs3ly3fS4/TN9ROFtb0NFrm04UXFE/Vw==", + "dev": true, + "dependencies": { + "@discoveryjs/json-ext": "0.5.7", + "acorn": "^8.0.4", + "acorn-walk": "^8.0.0", + "commander": "^7.2.0", + "debounce": "^1.2.1", + "escape-string-regexp": "^4.0.0", + "gzip-size": "^6.0.0", + "html-escaper": "^2.0.2", + "opener": "^1.5.2", + "picocolors": "^1.0.0", + "sirv": "^2.0.3", + "ws": "^7.3.1" + }, + "bin": { + "webpack-bundle-analyzer": "lib/bin/analyzer.js" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/webpack-bundle-analyzer/node_modules/acorn-walk": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "dev": true, + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/webpack-bundle-analyzer/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/webpack-bundle-analyzer/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/webpack-bundle-tracker": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/webpack-bundle-tracker/-/webpack-bundle-tracker-1.7.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index 58b015ab98..4aae51f318 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -13,12 +13,12 @@ "@seafile/resumablejs": "1.1.16", "@seafile/sdoc-editor": "1.0.106", "@seafile/seafile-calendar": "0.0.28", - "@seafile/seafile-editor": "^1.0.121", - "@seafile/sf-metadata-ui-component": "^0.0.43", + "@seafile/seafile-editor": "^1.0.122", + "@seafile/sf-metadata-ui-component": "^0.0.45", "@uiw/codemirror-extensions-langs": "^4.19.4", "@uiw/react-codemirror": "^4.19.4", "axios": "^1.7.4", - "chart.js": "2.9.4", + "chart.js": "3.6.0", "classnames": "^2.2.6", "codemirror": "^6.0.1", "copy-to-clipboard": "^3.0.8", @@ -31,17 +31,16 @@ "i18next-xhr-backend": "^3.1.2", "is-hotkey": "0.2.0", "MD5": "^1.3.0", - "moment": "^2.22.2", "object-assign": "4.1.1", - "prop-types": "15.8.1", + "prop-types": "^15.8.1", "qrcode.react": "^1.0.1", - "react": "17.0.0", + "react": "17.0.2", "react-app-polyfill": "^2.0.0", - "react-chartjs-2": "^2.8.0", + "react-chartjs-2": "4.0.0", "react-cookies": "^0.1.0", "react-dnd": "^2.6.0", "react-dnd-html5-backend": "^2.6.0", - "react-dom": "17.0.0", + "react-dom": "17.0.2", "react-i18next": "^10.12.2", "react-responsive": "9.0.2", "react-select": "5.7.0", @@ -168,6 +167,7 @@ "url-loader": "4.1.1", "web-vitals": "2.1.4", "webpack": "^5.64.4", + "webpack-bundle-analyzer": "^4.10.2", "webpack-bundle-tracker": "1.7.0", "webpack-dev-server": "^4.6.0", "webpack-manifest-plugin": "^4.0.2", diff --git a/frontend/src/components/common/notice-item.js b/frontend/src/components/common/notice-item.js index f1f94b53e2..b9df6d2fcb 100644 --- a/frontend/src/components/common/notice-item.js +++ b/frontend/src/components/common/notice-item.js @@ -1,6 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; -import moment from 'moment'; +import dayjs from 'dayjs'; +import relativeTime from 'dayjs/plugin/relativeTime'; import { gettext, siteRoot } from '../../utils/constants'; import { Utils } from '../../utils/utils'; @@ -23,6 +24,8 @@ const MSG_TYPE_SAML_SSO_FAILED = 'saml_sso_failed'; const MSG_TYPE_REPO_SHARE_PERM_CHANGE = 'repo_share_perm_change'; const MSG_TYPE_REPO_SHARE_PERM_DELETE = 'repo_share_perm_delete'; +dayjs.extend(relativeTime); + class NoticeItem extends React.Component { generatorNoticeInfo() { @@ -390,7 +393,7 @@ class NoticeItem extends React.Component {

- {moment(noticeItem.time).fromNow()} + {dayjs(noticeItem.time).fromNow()} ) : ( @@ -400,7 +403,7 @@ class NoticeItem extends React.Component {

-

{moment(noticeItem.time).fromNow()}

+

{dayjs(noticeItem.time).fromNow()}

); diff --git a/frontend/src/components/date-and-time-picker.js b/frontend/src/components/date-and-time-picker.js index d22b07e2e6..8207073262 100644 --- a/frontend/src/components/date-and-time-picker.js +++ b/frontend/src/components/date-and-time-picker.js @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import moment from 'moment'; +import dayjs from 'dayjs'; import Calendar from '@seafile/seafile-calendar'; import DatePicker from '@seafile/seafile-calendar/lib/Picker'; import { translateCalendar } from '../utils/date-format-utils'; @@ -19,7 +19,7 @@ class Picker extends React.Component { componentDidMount() { let lang = window.app.config.lang; - this.defaultCalendarValue = moment().locale(lang).clone(); + this.defaultCalendarValue = dayjs().locale(lang).clone(); } diff --git a/frontend/src/components/dialog/commit-details.js b/frontend/src/components/dialog/commit-details.js index 66eb202ecf..1dade2f761 100644 --- a/frontend/src/components/dialog/commit-details.js +++ b/frontend/src/components/dialog/commit-details.js @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Modal, ModalHeader, ModalBody } from 'reactstrap'; -import moment from 'moment'; +import dayjs from 'dayjs'; import { gettext } from '../../utils/constants'; import { seafileAPI } from '../../utils/seafile-api'; import { Utils } from '../../utils/utils'; @@ -48,7 +48,7 @@ class CommitDetails extends React.Component { {gettext('Modification Details')} -

{moment(commitTime).format('YYYY-MM-DD HH:mm:ss')}

+

{dayjs(commitTime).format('YYYY-MM-DD HH:mm:ss')}

diff --git a/frontend/src/components/dialog/file-access-log.js b/frontend/src/components/dialog/file-access-log.js index b5fc8e5f21..1428fa4653 100644 --- a/frontend/src/components/dialog/file-access-log.js +++ b/frontend/src/components/dialog/file-access-log.js @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import moment from 'moment'; +import dayjs from 'dayjs'; import { Modal, ModalHeader, ModalBody } from 'reactstrap'; import { Utils } from '../../utils/utils'; import { gettext, siteRoot } from '../../utils/constants'; @@ -11,7 +11,7 @@ import EmptyTip from '../empty-tip'; import '../../css/file-access-log.css'; -moment.locale(window.app.config.lang); +dayjs.locale(window.app.config.lang); const propTypes = { repoID: PropTypes.string.isRequired, @@ -118,7 +118,7 @@ class FileAccessLog extends React.Component { {`${item.ip}${item.device ? '/' + item.device : ''}`} - {moment(item.time).format('YYYY-MM-DD HH:mm:ss')} + {dayjs(item.time).format('YYYY-MM-DD HH:mm:ss')} ); })} diff --git a/frontend/src/components/dialog/generate-upload-link.js b/frontend/src/components/dialog/generate-upload-link.js index fdd10e4544..85286f2339 100644 --- a/frontend/src/components/dialog/generate-upload-link.js +++ b/frontend/src/components/dialog/generate-upload-link.js @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import copy from 'copy-to-clipboard'; -import moment from 'moment'; +import dayjs from 'dayjs'; import { Button, Form, FormGroup, Label, Input, InputGroup, InputGroupAddon, Alert } from 'reactstrap'; import { gettext, shareLinkForceUsePassword, shareLinkPasswordMinLength, shareLinkPasswordStrengthLevel, canSendShareLinkEmail, uploadLinkExpireDaysMin, uploadLinkExpireDaysMax, uploadLinkExpireDaysDefault } from '../../utils/constants'; import { seafileAPI } from '../../utils/seafile-api'; @@ -117,7 +117,7 @@ class GenerateUploadLink extends React.Component { let expirationTime = ''; if (isExpireChecked) { if (expType == 'by-days') { - expirationTime = moment().add(parseInt(expireDays), 'days').format(); + expirationTime = dayjs().add(parseInt(expireDays), 'days').format(); } else { expirationTime = expDate.format(); } @@ -228,7 +228,7 @@ class GenerateUploadLink extends React.Component { let expirationTime = ''; if (expType == 'by-days') { - expirationTime = moment().add(parseInt(expireDays), 'days').format(); + expirationTime = dayjs().add(parseInt(expireDays), 'days').format(); } else { expirationTime = expDate.format(); } @@ -337,7 +337,7 @@ class GenerateUploadLink extends React.Component { ) : ( - + {errorMessage &&
{errorMessage}
} diff --git a/frontend/src/pages/org-admin/statistic/statistic-storage.js b/frontend/src/pages/org-admin/statistic/statistic-storage.js index ad2f7d5fe7..d41889867d 100644 --- a/frontend/src/pages/org-admin/statistic/statistic-storage.js +++ b/frontend/src/pages/org-admin/statistic/statistic-storage.js @@ -1,5 +1,5 @@ import React, { Fragment } from 'react'; -import moment from 'moment'; +import dayjs from 'dayjs'; import MainPanelTopbar from '../main-panel-topbar'; import StatisticNav from './statistic-nav'; import StatisticCommonTool from './statistic-common-tool'; @@ -29,7 +29,7 @@ class OrgStatisticStorage extends React.Component { let data = res.data; if (Array.isArray(data)) { data.forEach(item => { - labels.push(moment(item.datetime).format('YYYY-MM-DD')); + labels.push(dayjs(item.datetime).format('YYYY-MM-DD')); totalStorage.push(item.total_storage); }); let total_storage = { diff --git a/frontend/src/pages/org-admin/statistic/statistic-traffic-users.js b/frontend/src/pages/org-admin/statistic/statistic-traffic-users.js index a6ad9945d5..3092136993 100644 --- a/frontend/src/pages/org-admin/statistic/statistic-traffic-users.js +++ b/frontend/src/pages/org-admin/statistic/statistic-traffic-users.js @@ -1,10 +1,10 @@ import React, { Fragment } from 'react'; import { Input } from 'reactstrap'; +import dayjs from 'dayjs'; import TrafficTable from './traffic-table'; import TrafficTableBody from './traffic-table-body'; import { seafileAPI } from '../../../utils/seafile-api'; import Paginator from '../../../components/paginator'; -import moment from 'moment'; import Loading from '../../../components/loading'; import { gettext, orgID } from '../../../utils/constants'; import { Utils } from '../../../utils/utils'; @@ -19,14 +19,14 @@ class UsersTraffic extends React.Component { hasNextPage: false, perPage: 100, currentPage: 1, - month: moment().format('YYYYMM'), + month: dayjs().format('YYYYMM'), isLoading: false, errorMessage: '', sortBy: 'link_file_download', sortOrder: 'desc' }; this.initPage = 1; - this.initMonth = moment().format('YYYYMM'); + this.initMonth = dayjs().format('YYYYMM'); } componentDidMount() { @@ -122,7 +122,7 @@ class UsersTraffic extends React.Component { {gettext('Month:')} diff --git a/frontend/src/pages/org-admin/statistic/statistic-traffic.js b/frontend/src/pages/org-admin/statistic/statistic-traffic.js index 106691a7ac..6034ed0ca0 100644 --- a/frontend/src/pages/org-admin/statistic/statistic-traffic.js +++ b/frontend/src/pages/org-admin/statistic/statistic-traffic.js @@ -1,5 +1,5 @@ import React, { Fragment } from 'react'; -import moment from 'moment'; +import dayjs from 'dayjs'; import { gettext, orgID } from '../../../utils/constants'; import { seafileAPI } from '../../../utils/seafile-api'; import MainPanelTopbar from '../main-panel-topbar'; @@ -44,7 +44,7 @@ class OrgStatisticTraffic extends React.Component { let data = res.data; if (Array.isArray(data)) { data.forEach(item => { - labels.push(moment(item.datetime).format('YYYY-MM-DD')); + labels.push(dayjs(item.datetime).format('YYYY-MM-DD')); link_upload.push(item['link-file-upload']); link_download.push(item['link-file-download']); sync_upload.push(item['sync-file-upload']); diff --git a/frontend/src/pages/org-admin/statistic/statistic-users.js b/frontend/src/pages/org-admin/statistic/statistic-users.js index 5be52674b4..8e24476f7e 100644 --- a/frontend/src/pages/org-admin/statistic/statistic-users.js +++ b/frontend/src/pages/org-admin/statistic/statistic-users.js @@ -1,5 +1,5 @@ import React, { Fragment } from 'react'; -import moment from 'moment'; +import dayjs from 'dayjs'; import { gettext, orgID } from '../../../utils/constants'; import MainPanelTopbar from '../main-panel-topbar'; import StatisticNav from './statistic-nav'; @@ -29,7 +29,7 @@ class OrgStatisticUsers extends React.Component { let data = res.data; if (Array.isArray(data)) { data.forEach(item => { - labels.push(moment(item.datetime).format('YYYY-MM-DD')); + labels.push(dayjs(item.datetime).format('YYYY-MM-DD')); count.push(item.count); }); let userCount = { diff --git a/frontend/src/pages/sdoc/sdoc-file-history/history-version.js b/frontend/src/pages/sdoc/sdoc-file-history/history-version.js index 50d4c78f33..80ada97ce8 100644 --- a/frontend/src/pages/sdoc/sdoc-file-history/history-version.js +++ b/frontend/src/pages/sdoc/sdoc-file-history/history-version.js @@ -1,6 +1,6 @@ -import moment from 'moment'; import React from 'react'; import PropTypes from 'prop-types'; +import dayjs from 'dayjs'; import { Dropdown, DropdownToggle, DropdownMenu, DropdownItem, Modal, ModalBody } from 'reactstrap'; import classnames from 'classnames'; import { gettext, filePath } from '../../../utils/constants'; @@ -10,7 +10,7 @@ import { isMobile } from '../../../utils/utils'; import '../../../css/history-record-item.css'; -moment.locale(window.app.config.lang); +dayjs.locale(window.app.config.lang); class HistoryVersion extends React.Component { @@ -58,7 +58,7 @@ class HistoryVersion extends React.Component { onItemCopy = () => { const { historyVersion } = this.props; - historyVersion.ctime_format = moment(historyVersion.ctime).format('YYYY-MM-DD HH:mm'); + historyVersion.ctime_format = dayjs(historyVersion.ctime).format('YYYY-MM-DD HH:mm'); this.props.onCopy(historyVersion); }; @@ -114,7 +114,7 @@ class HistoryVersion extends React.Component { :
{name}
} -
{moment(ctime).format('YYYY-MM-DD HH:mm')}
+
{dayjs(ctime).format('YYYY-MM-DD HH:mm')}
{creator_name} diff --git a/frontend/src/pages/sdoc/sdoc-file-history/index.js b/frontend/src/pages/sdoc/sdoc-file-history/index.js index afcfaa8cbd..f744d06b0f 100644 --- a/frontend/src/pages/sdoc/sdoc-file-history/index.js +++ b/frontend/src/pages/sdoc/sdoc-file-history/index.js @@ -5,7 +5,7 @@ import i18n from '../../../_i18n/i18n-sdoc-editor'; import { UncontrolledTooltip } from 'reactstrap'; import classnames from 'classnames'; import { DiffViewer } from '@seafile/sdoc-editor'; -import moment from 'moment'; +import dayjs from 'dayjs'; import { seafileAPI } from '../../../utils/seafile-api'; import SDocServerApi from '../../../utils/sdoc-server-api'; import { PER_PAGE, gettext, historyRepoID } from '../../../utils/constants'; @@ -331,7 +331,7 @@ class SdocFileHistory extends React.Component { const newHistoryGroups = oldHistoryGroups.slice(0); histories.forEach(history => { const { date } = history; - const momentDate = moment(date); + const momentDate = dayjs(date); const month = momentDate.format('YYYY-MM'); const monthItem = newHistoryGroups.find(item => item.month === month); if (monthItem) { diff --git a/frontend/src/pages/sdoc/sdoc-file-history/side-panel.js b/frontend/src/pages/sdoc/sdoc-file-history/side-panel.js index e42f6a9cc2..cdb1acf877 100644 --- a/frontend/src/pages/sdoc/sdoc-file-history/side-panel.js +++ b/frontend/src/pages/sdoc/sdoc-file-history/side-panel.js @@ -1,6 +1,6 @@ import React, { Component, Fragment } from 'react'; -import moment from 'moment'; import PropTypes from 'prop-types'; +import dayjs from 'dayjs'; import classnames from 'classnames'; import Loading from '../../../components/loading'; import { gettext, historyRepoID, PER_PAGE } from '../../../utils/constants'; @@ -12,7 +12,7 @@ import HistoryVersion from './history-version'; import Switch from '../../../components/common/switch'; import { getCurrentAndLastVersion, getLastVersion } from './helper'; -moment.locale(window.app.config.lang); +dayjs.locale(window.app.config.lang); const { docUuid } = window.fileHistory.pageOptions; @@ -37,7 +37,7 @@ class SidePanel extends Component { const newHistoryGroups = oldHistoryGroups.slice(0); histories.forEach(history => { const { date } = history; - const momentDate = moment(date); + const momentDate = dayjs(date); const month = momentDate.format('YYYY-MM'); const monthItem = newHistoryGroups.find(item => item.month === month); if (monthItem) { @@ -235,7 +235,7 @@ class SidePanel extends Component { let lastVersion; if (nextShowChanges) { const { date } = currentVersion; - const momentDate = moment(date); + const momentDate = dayjs(date); const month = momentDate.format('YYYY-MM'); const day = momentDate.format('YYYY-MM-DD'); const monthIndex = historyGroups.findIndex(item => item.month === month); diff --git a/frontend/src/pages/search/advanced-search.js b/frontend/src/pages/search/advanced-search.js index 7f8a4dd92a..52fd3b41ba 100644 --- a/frontend/src/pages/search/advanced-search.js +++ b/frontend/src/pages/search/advanced-search.js @@ -1,7 +1,7 @@ import React, { Fragment } from 'react'; import PropTypes from 'prop-types'; import MediaQuery from 'react-responsive'; -import moment from 'moment'; +import dayjs from 'dayjs'; import { Button, Col, Collapse, CustomInput, FormGroup, Input, Label, Row, InputGroupAddon, InputGroup } from 'reactstrap'; import { gettext } from '../../utils/constants'; import DateTimePicker from '../../components/date-and-time-picker'; @@ -30,7 +30,7 @@ class AdvancedSearch extends React.Component { return false; } - const isAfterToday = startValue.isAfter(moment(), 'day'); + const isAfterToday = startValue.isAfter(dayjs(), 'day'); const { time_to } = this.props.stateAndValues; const endValue = time_to; if (!endValue) { @@ -44,7 +44,7 @@ class AdvancedSearch extends React.Component { return false; } - const isAfterToday = endValue.isAfter(moment(), 'day'); + const isAfterToday = endValue.isAfter(dayjs(), 'day'); const { time_from } = this.props.stateAndValues; const startValue = time_from; if (!startValue) { diff --git a/frontend/src/pages/search/search-results.js b/frontend/src/pages/search/search-results.js index de30d12746..10f7883e74 100644 --- a/frontend/src/pages/search/search-results.js +++ b/frontend/src/pages/search/search-results.js @@ -1,6 +1,6 @@ import React from 'react'; -import moment from 'moment'; import PropTypes from 'prop-types'; +import dayjs from 'dayjs'; import { Utils } from '../../utils/utils'; import { siteRoot, gettext } from '../../utils/constants'; @@ -45,7 +45,7 @@ class ResultsItem extends React.Component { {item.repo_name}{this.handlerParentDirPath(item)}
- {Utils.bytesToSize(item.size) + ' ' + moment(item.last_modified * 1000).format('YYYY-MM-DD')} + {Utils.bytesToSize(item.size) + ' ' + dayjs(item.last_modified * 1000).format('YYYY-MM-DD')}
diff --git a/frontend/src/pages/share-admin/share-links.js b/frontend/src/pages/share-admin/share-links.js index fc34f53eb4..f359ad1fa9 100644 --- a/frontend/src/pages/share-admin/share-links.js +++ b/frontend/src/pages/share-admin/share-links.js @@ -1,7 +1,7 @@ import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; import { Link } from '@gatsbyjs/reach-router'; -import moment from 'moment'; +import dayjs from 'dayjs'; import { Dropdown, DropdownToggle, DropdownItem } from 'reactstrap'; import { seafileAPI } from '../../utils/seafile-api'; import { Utils } from '../../utils/utils'; @@ -221,8 +221,8 @@ class Item extends Component { if (!item.expire_date) { return '--'; } - const expire_date = moment(item.expire_date).format('YYYY-MM-DD'); - const expire_time = moment(item.expire_date).format('YYYY-MM-DD HH:mm:ss'); + const expire_date = dayjs(item.expire_date).format('YYYY-MM-DD'); + const expire_time = dayjs(item.expire_date).format('YYYY-MM-DD HH:mm:ss'); return ({expire_date}); }; diff --git a/frontend/src/pages/share-admin/upload-links.js b/frontend/src/pages/share-admin/upload-links.js index 83a733fdac..0f9b610584 100644 --- a/frontend/src/pages/share-admin/upload-links.js +++ b/frontend/src/pages/share-admin/upload-links.js @@ -1,7 +1,7 @@ import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; import { Link } from '@gatsbyjs/reach-router'; -import moment from 'moment'; +import dayjs from 'dayjs'; import { Dropdown, DropdownToggle, DropdownItem } from 'reactstrap'; import { gettext, siteRoot, canGenerateShareLink } from '../../utils/constants'; import { seafileAPI } from '../../utils/seafile-api'; @@ -128,8 +128,8 @@ class Item extends Component { if (!item.expire_date) { return '--'; } - const expire_date = moment(item.expire_date).format('YYYY-MM-DD'); - const expire_time = moment(item.expire_date).format('YYYY-MM-DD HH:mm:ss'); + const expire_date = dayjs(item.expire_date).format('YYYY-MM-DD'); + const expire_time = dayjs(item.expire_date).format('YYYY-MM-DD HH:mm:ss'); return ({expire_date}); }; diff --git a/frontend/src/pages/share-with-ocm/remote-dir-content.js b/frontend/src/pages/share-with-ocm/remote-dir-content.js index d5958163f9..e428a3d3ed 100644 --- a/frontend/src/pages/share-with-ocm/remote-dir-content.js +++ b/frontend/src/pages/share-with-ocm/remote-dir-content.js @@ -1,11 +1,14 @@ import React, { Fragment } from 'react'; import PropTypes from 'prop-types'; import { Link } from '@gatsbyjs/reach-router'; -import moment from 'moment'; +import dayjs from 'dayjs'; +import relativeTime from 'dayjs/plugin/relativeTime'; import { gettext } from '../../utils/constants'; import { Utils } from '../../utils/utils'; import Loading from '../../components/loading'; +dayjs.extend(relativeTime); + class DirentItem extends React.Component { constructor(props) { @@ -57,7 +60,7 @@ class DirentItem extends React.Component { } {Utils.bytesToSize(dirent.size)} - {moment(dirent.mtime).fromNow()} + {dayjs(dirent.mtime).fromNow()} ); diff --git a/frontend/src/pages/share-with-ocm/shared-with-ocm.js b/frontend/src/pages/share-with-ocm/shared-with-ocm.js index f4ace825f9..97d03d65f3 100644 --- a/frontend/src/pages/share-with-ocm/shared-with-ocm.js +++ b/frontend/src/pages/share-with-ocm/shared-with-ocm.js @@ -1,6 +1,7 @@ import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; -import moment from 'moment'; +import dayjs from 'dayjs'; +import relativeTime from 'dayjs/plugin/relativeTime'; import { Link } from '@gatsbyjs/reach-router'; import { gettext, siteRoot } from '../../utils/constants'; import { seafileAPI } from '../../utils/seafile-api'; @@ -9,6 +10,8 @@ import toaster from '../../components/toast'; import Loading from '../../components/loading'; import EmptyTip from '../../components/empty-tip'; +dayjs.extend(relativeTime); + class Content extends Component { render() { @@ -103,7 +106,7 @@ class Item extends Component { {item.repo_name} {item.from_user} {item.from_server_url} - {moment(item.ctime).fromNow()} + {dayjs(item.ctime).fromNow()} diff --git a/frontend/src/pages/shared-libs/shared-libs.js b/frontend/src/pages/shared-libs/shared-libs.js index 05be4d7fa3..a6a08115ef 100644 --- a/frontend/src/pages/shared-libs/shared-libs.js +++ b/frontend/src/pages/shared-libs/shared-libs.js @@ -1,7 +1,8 @@ import React, { Component, Fragment } from 'react'; import { Dropdown, DropdownToggle, DropdownMenu, DropdownItem } from 'reactstrap'; import PropTypes from 'prop-types'; -import moment from 'moment'; +import dayjs from 'dayjs'; +import relativeTime from 'dayjs/plugin/relativeTime'; import cookie from 'react-cookies'; import { Link, navigate } from '@gatsbyjs/reach-router'; import { gettext, siteRoot, isPro } from '../../utils/constants'; @@ -20,6 +21,8 @@ import { GRID_MODE, LIST_MODE } from '../../components/dir-view-mode/constants'; import ContextMenu from '../../components/context-menu/context-menu'; import { hideMenu, handleContextClick } from '../../components/context-menu/actions'; +dayjs.extend(relativeTime); + class Content extends Component { constructor(props) { @@ -392,7 +395,7 @@ class Item extends Component { } {data.size} - {moment(data.last_modified).fromNow()} + {dayjs(data.last_modified).fromNow()} {data.owner_name} ) : ( @@ -472,7 +475,7 @@ class Item extends Component {
{data.owner_name} {data.size} - {moment(data.last_modified).fromNow()} + {dayjs(data.last_modified).fromNow()} diff --git a/frontend/src/pages/starred/starred.js b/frontend/src/pages/starred/starred.js index 3ad72d2ddc..72ab575805 100644 --- a/frontend/src/pages/starred/starred.js +++ b/frontend/src/pages/starred/starred.js @@ -2,7 +2,8 @@ import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; import { Dropdown, DropdownToggle, DropdownItem } from 'reactstrap'; import { Link, navigate } from '@gatsbyjs/reach-router'; -import moment from 'moment'; +import dayjs from 'dayjs'; +import relativeTime from 'dayjs/plugin/relativeTime'; import { seafileAPI } from '../../utils/seafile-api'; import { Utils } from '../../utils/utils'; import { gettext, siteRoot, enableVideoThumbnail, enablePDFThumbnail, thumbnailDefaultSize } from '../../utils/constants'; @@ -10,6 +11,8 @@ import EmptyTip from '../../components/empty-tip'; import Loading from '../../components/loading'; import toaster from '../../components/toast'; +dayjs.extend(relativeTime); + class Content extends Component { render() { @@ -281,7 +284,7 @@ class Item extends Component { item.dirent_view_url = item.dirent_view_url.replace(/\/+$/, ''); } - item.mtime_relative = item.mtime ? moment(item.mtime).fromNow() : '--'; + item.mtime_relative = item.mtime ? dayjs(item.mtime).fromNow() : '--'; if (this.state.unstarred) { return null; diff --git a/frontend/src/pages/sys-admin/abuse-reports.js b/frontend/src/pages/sys-admin/abuse-reports.js index 4e0b10e54b..37f77af5ce 100644 --- a/frontend/src/pages/sys-admin/abuse-reports.js +++ b/frontend/src/pages/sys-admin/abuse-reports.js @@ -1,8 +1,8 @@ import React, { Component, Fragment } from 'react'; +import dayjs from 'dayjs'; import { gettext, siteRoot } from '../../utils/constants'; import { seafileAPI } from '../../utils/seafile-api'; import toaster from '../../components/toast'; -import moment from 'moment'; import MainPanelTopbar from './main-panel-topbar'; class AbuseReports extends Component { @@ -64,7 +64,7 @@ class AbuseReports extends Component { {item.reporter} {item.abuse_type} {item.description} - {moment(item.time).format('YYYY-MM-DD')} + {dayjs(item.time).format('YYYY-MM-DD')}

{item.login_ip} {item.login_success ? gettext('Success') : gettext('Failed')} - {moment(item.login_time).fromNow()} + {dayjs(item.login_time).fromNow()} ); } diff --git a/frontend/src/pages/sys-admin/admin-logs/operation-logs.js b/frontend/src/pages/sys-admin/admin-logs/operation-logs.js index 843a0b3aab..90428b94d9 100644 --- a/frontend/src/pages/sys-admin/admin-logs/operation-logs.js +++ b/frontend/src/pages/sys-admin/admin-logs/operation-logs.js @@ -1,16 +1,19 @@ import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; +import dayjs from 'dayjs'; +import relativeTime from 'dayjs/plugin/relativeTime'; import { seafileAPI } from '../../../utils/seafile-api'; import { gettext, siteRoot, enableSysAdminViewRepo, isPro } from '../../../utils/constants'; import { Utils } from '../../../utils/utils'; import EmptyTip from '../../../components/empty-tip'; -import moment from 'moment'; import Loading from '../../../components/loading'; import Paginator from '../../../components/paginator'; import LogsNav from './logs-nav'; import MainPanelTopbar from '../main-panel-topbar'; import UserLink from '../user-link'; +dayjs.extend(relativeTime); + class Content extends Component { constructor(props) { @@ -203,7 +206,7 @@ class Item extends Component { - {moment(item.datetime).fromNow()} + {dayjs(item.datetime).fromNow()} ); } diff --git a/frontend/src/pages/sys-admin/departments/department-libraries.js b/frontend/src/pages/sys-admin/departments/department-libraries.js index 2706b63956..5f40a36895 100644 --- a/frontend/src/pages/sys-admin/departments/department-libraries.js +++ b/frontend/src/pages/sys-admin/departments/department-libraries.js @@ -1,6 +1,6 @@ import React, { Fragment } from 'react'; import PropTypes from 'prop-types'; -import moment from 'moment'; +import dayjs from 'dayjs'; import { seafileAPI } from '../../../utils/seafile-api'; import { Utils } from '../../../utils/utils'; import toaster from '../../../components/toast'; @@ -12,7 +12,7 @@ import Department from './department'; import EmptyTip from '../../../components/empty-tip'; import '../../../css/org-department-item.css'; -moment.locale(lang); +dayjs.locale(lang); const DepartmentDetailPropTypes = { groupID: PropTypes.string, diff --git a/frontend/src/pages/sys-admin/departments/department-list.js b/frontend/src/pages/sys-admin/departments/department-list.js index 876d9e5573..a47442a6ed 100644 --- a/frontend/src/pages/sys-admin/departments/department-list.js +++ b/frontend/src/pages/sys-admin/departments/department-list.js @@ -1,5 +1,5 @@ import React, { Fragment } from 'react'; -import moment from 'moment'; +import dayjs from 'dayjs'; import { seafileAPI } from '../../../utils/seafile-api'; import MainPanelTopbar from '../main-panel-topbar'; import ModalPortal from '../../../components/modal-portal'; @@ -9,7 +9,7 @@ import GroupItem from './group-item'; import EmptyTip from '../../../components/empty-tip'; import '../../../css/org-department-item.css'; -moment.locale(lang); +dayjs.locale(lang); class DepartmentList extends React.Component { diff --git a/frontend/src/pages/sys-admin/departments/department-members.js b/frontend/src/pages/sys-admin/departments/department-members.js index 3d2b21e22c..b9e17105fb 100644 --- a/frontend/src/pages/sys-admin/departments/department-members.js +++ b/frontend/src/pages/sys-admin/departments/department-members.js @@ -1,6 +1,6 @@ import React, { Fragment } from 'react'; import PropTypes from 'prop-types'; -import moment from 'moment'; +import dayjs from 'dayjs'; import Paginator from '../../../components/paginator'; import { seafileAPI } from '../../../utils/seafile-api'; import { Utils } from '../../../utils/utils'; @@ -12,7 +12,7 @@ import Department from './department'; import EmptyTip from '../../../components/empty-tip'; import '../../../css/org-department-item.css'; -moment.locale(lang); +dayjs.locale(lang); const DepartmentMembersPropTypes = { groupID: PropTypes.string, diff --git a/frontend/src/pages/sys-admin/departments/department.js b/frontend/src/pages/sys-admin/departments/department.js index 01b68757b3..302758e72e 100644 --- a/frontend/src/pages/sys-admin/departments/department.js +++ b/frontend/src/pages/sys-admin/departments/department.js @@ -1,6 +1,6 @@ import React, { Fragment } from 'react'; import PropTypes from 'prop-types'; -import moment from 'moment'; +import dayjs from 'dayjs'; import { Link } from '@gatsbyjs/reach-router'; import { seafileAPI } from '../../../utils/seafile-api'; import { Utils } from '../../../utils/utils'; @@ -15,7 +15,7 @@ import { siteRoot, gettext, lang } from '../../../utils/constants'; import '../../../css/org-department-item.css'; -moment.locale(lang); +dayjs.locale(lang); const DepartmentDetailPropTypes = { groupID: PropTypes.string, diff --git a/frontend/src/pages/sys-admin/departments/group-item.js b/frontend/src/pages/sys-admin/departments/group-item.js index 179c71f0bf..910177804e 100644 --- a/frontend/src/pages/sys-admin/departments/group-item.js +++ b/frontend/src/pages/sys-admin/departments/group-item.js @@ -1,6 +1,7 @@ import React, { Fragment } from 'react'; import PropTypes from 'prop-types'; -import moment from 'moment'; +import dayjs from 'dayjs'; +import relativeTime from 'dayjs/plugin/relativeTime'; import { Link } from '@gatsbyjs/reach-router'; import { Utils } from '../../../utils/utils'; import { siteRoot, gettext } from '../../../utils/constants'; @@ -20,6 +21,8 @@ const GroupItemPropTypes = { onSetDepartmentQuota: PropTypes.func.isRequired }; +dayjs.extend(relativeTime); + class GroupItem extends React.Component { constructor(props) { @@ -114,7 +117,7 @@ class GroupItem extends React.Component { {group.name} - {moment(group.created_at).fromNow()} + {dayjs(group.created_at).fromNow()} {Utils.bytesToSize(group.quota)}{' '} diff --git a/frontend/src/pages/sys-admin/departments/sub-departments.js b/frontend/src/pages/sys-admin/departments/sub-departments.js index 89874c1ae6..6999b58bb3 100644 --- a/frontend/src/pages/sys-admin/departments/sub-departments.js +++ b/frontend/src/pages/sys-admin/departments/sub-departments.js @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import moment from 'moment'; +import dayjs from 'dayjs'; import { seafileAPI } from '../../../utils/seafile-api'; import { Utils } from '../../../utils/utils'; import toaster from '../../../components/toast'; @@ -11,7 +11,7 @@ import EmptyTip from '../../../components/empty-tip'; import '../../../css/org-department-item.css'; -moment.locale(lang); +dayjs.locale(lang); const SubDepartmentsPropTypes = { groupID: PropTypes.string diff --git a/frontend/src/pages/sys-admin/devices/devices-by-platform.js b/frontend/src/pages/sys-admin/devices/devices-by-platform.js index 45599bdb19..297df7cb84 100644 --- a/frontend/src/pages/sys-admin/devices/devices-by-platform.js +++ b/frontend/src/pages/sys-admin/devices/devices-by-platform.js @@ -1,15 +1,18 @@ import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; +import dayjs from 'dayjs'; +import relativeTime from 'dayjs/plugin/relativeTime'; import { seafileAPI } from '../../../utils/seafile-api'; import { gettext } from '../../../utils/constants'; import toaster from '../../../components/toast'; import { Utils } from '../../../utils/utils'; import EmptyTip from '../../../components/empty-tip'; -import moment from 'moment'; import Loading from '../../../components/loading'; import Paginator from '../../../components/paginator'; import SysAdminUnlinkDevice from '../../../components/dialog/sysadmin-dialog/sysadmin-unlink-device-dialog'; +dayjs.extend(relativeTime); + class Content extends Component { constructor(props) { @@ -144,7 +147,7 @@ class Item extends Component { {item.device_name} {item.last_login_ip} - {moment(item.last_accessed).fromNow()} + {dayjs(item.last_accessed).fromNow()} diff --git a/frontend/src/pages/sys-admin/devices/devices-errors.js b/frontend/src/pages/sys-admin/devices/devices-errors.js index b23ead55cf..d9aa20d08c 100644 --- a/frontend/src/pages/sys-admin/devices/devices-errors.js +++ b/frontend/src/pages/sys-admin/devices/devices-errors.js @@ -1,12 +1,13 @@ import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; import { Button } from 'reactstrap'; +import dayjs from 'dayjs'; +import relativeTime from 'dayjs/plugin/relativeTime'; import { seafileAPI } from '../../../utils/seafile-api'; import { siteRoot, gettext } from '../../../utils/constants'; import toaster from '../../../components/toast'; import { Utils } from '../../../utils/utils'; import EmptyTip from '../../../components/empty-tip'; -import moment from 'moment'; import Loading from '../../../components/loading'; import { Link } from '@gatsbyjs/reach-router'; import DevicesNav from './devices-nav'; @@ -14,6 +15,8 @@ import MainPanelTopbar from '../main-panel-topbar'; import UserLink from '../user-link'; import Paginator from '../../../components/paginator'; +dayjs.extend(relativeTime); + class Content extends Component { constructor(props) { @@ -114,7 +117,7 @@ class Item extends Component { {item.repo_name} {item.error_msg} - {moment(item.error_time).fromNow()} + {dayjs(item.error_time).fromNow()} ); diff --git a/frontend/src/pages/sys-admin/groups/groups-content.js b/frontend/src/pages/sys-admin/groups/groups-content.js index 78811cdaf8..5b7e100522 100644 --- a/frontend/src/pages/sys-admin/groups/groups-content.js +++ b/frontend/src/pages/sys-admin/groups/groups-content.js @@ -1,7 +1,8 @@ import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; import { Link } from '@gatsbyjs/reach-router'; -import moment from 'moment'; +import dayjs from 'dayjs'; +import relativeTime from 'dayjs/plugin/relativeTime'; import { Utils } from '../../../utils/utils'; import { siteRoot, gettext } from '../../../utils/constants'; import Loading from '../../../components/loading'; @@ -13,6 +14,8 @@ import SysAdminTransferGroupDialog from '../../../components/dialog/sysadmin-dia import ChangeGroupDialog from '../../../components/dialog/change-group-dialog'; import UserLink from '../user-link'; +dayjs.extend(relativeTime); + class Content extends Component { constructor(props) { @@ -232,7 +235,7 @@ class Item extends Component { } - {moment(item.created_at).fromNow()} + {dayjs(item.created_at).fromNow()} {(isOpIconShown && item.owner != 'system admin') && diff --git a/frontend/src/pages/sys-admin/institutions/institution-admins.js b/frontend/src/pages/sys-admin/institutions/institution-admins.js index 2ed4b2179e..7ec0910d3e 100644 --- a/frontend/src/pages/sys-admin/institutions/institution-admins.js +++ b/frontend/src/pages/sys-admin/institutions/institution-admins.js @@ -1,6 +1,7 @@ import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; -import moment from 'moment'; +import dayjs from 'dayjs'; +import relativeTime from 'dayjs/plugin/relativeTime'; import { Utils } from '../../../utils/utils'; import { seafileAPI } from '../../../utils/seafile-api'; import { gettext } from '../../../utils/constants'; @@ -13,6 +14,8 @@ import UserLink from '../user-link'; import MainPanelTopbar from '../main-panel-topbar'; import InstitutionNav from './institution-nav'; +dayjs.extend(relativeTime); + class Content extends Component { constructor(props) { @@ -172,7 +175,7 @@ class Item extends Component { {`${Utils.bytesToSize(item.quota_usage)} / ${item.quota_total > 0 ? Utils.bytesToSize(item.quota_total) : '--'}`} - {moment(item.create_time).format('YYYY-MM-DD HH:mm:ss')}{' / '}{item.last_login ? moment(item.last_login).fromNow() : '--'} + {dayjs(item.create_time).format('YYYY-MM-DD HH:mm:ss')}{' / '}{item.last_login ? dayjs(item.last_login).fromNow() : '--'} {isOpIconShown && diff --git a/frontend/src/pages/sys-admin/institutions/institution-users.js b/frontend/src/pages/sys-admin/institutions/institution-users.js index 501ef9c94b..6dd247275f 100644 --- a/frontend/src/pages/sys-admin/institutions/institution-users.js +++ b/frontend/src/pages/sys-admin/institutions/institution-users.js @@ -1,7 +1,8 @@ import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; import { Button } from 'reactstrap'; -import moment from 'moment'; +import dayjs from 'dayjs'; +import relativeTime from 'dayjs/plugin/relativeTime'; import { Utils } from '../../../utils/utils'; import { seafileAPI } from '../../../utils/seafile-api'; import { gettext } from '../../../utils/constants'; @@ -16,6 +17,8 @@ import UserLink from '../user-link'; import MainPanelTopbar from '../main-panel-topbar'; import InstitutionNav from './institution-nav'; +dayjs.extend(relativeTime); + class Content extends Component { constructor(props) { @@ -208,7 +211,7 @@ class Item extends Component { {`${Utils.bytesToSize(item.quota_usage)} / ${item.quota_total > 0 ? Utils.bytesToSize(item.quota_total) : '--'}`} - {moment(item.create_time).format('YYYY-MM-DD HH:mm:ss')}{' / '}{item.last_login ? moment(item.last_login).fromNow() : '--'} + {dayjs(item.create_time).format('YYYY-MM-DD HH:mm:ss')}{' / '}{item.last_login ? dayjs(item.last_login).fromNow() : '--'} {isOpIconShown && diff --git a/frontend/src/pages/sys-admin/institutions/institutions.js b/frontend/src/pages/sys-admin/institutions/institutions.js index c07600ad91..c933841b4e 100644 --- a/frontend/src/pages/sys-admin/institutions/institutions.js +++ b/frontend/src/pages/sys-admin/institutions/institutions.js @@ -2,7 +2,8 @@ import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; import { Link } from '@gatsbyjs/reach-router'; import { Button } from 'reactstrap'; -import moment from 'moment'; +import dayjs from 'dayjs'; +import relativeTime from 'dayjs/plugin/relativeTime'; import { Utils } from '../../../utils/utils'; import { seafileAPI } from '../../../utils/seafile-api'; import { siteRoot, gettext } from '../../../utils/constants'; @@ -14,6 +15,8 @@ import MainPanelTopbar from '../main-panel-topbar'; import SysAdminAddInstitutionDialog from '../../../components/dialog/sysadmin-dialog/sysadmin-add-institution-dialog'; import Paginator from '../../../components/paginator'; +dayjs.extend(relativeTime); + class Content extends Component { constructor(props) { @@ -129,7 +132,7 @@ class Item extends Component { {item.name} - {moment(item.ctime).fromNow()} + {dayjs(item.ctime).fromNow()} diff --git a/frontend/src/pages/sys-admin/invitations/invitations.js b/frontend/src/pages/sys-admin/invitations/invitations.js index 47b6deb5d9..b04b487fff 100644 --- a/frontend/src/pages/sys-admin/invitations/invitations.js +++ b/frontend/src/pages/sys-admin/invitations/invitations.js @@ -1,7 +1,8 @@ import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; import { Button } from 'reactstrap'; -import moment from 'moment'; +import dayjs from 'dayjs'; +import relativeTime from 'dayjs/plugin/relativeTime'; import { Utils } from '../../../utils/utils'; import { seafileAPI } from '../../../utils/seafile-api'; import { gettext } from '../../../utils/constants'; @@ -13,6 +14,8 @@ import OpMenu from '../../../components/dialog/op-menu'; import MainPanelTopbar from '../main-panel-topbar'; import UserLink from '../user-link'; +dayjs.extend(relativeTime); + class Content extends Component { constructor(props) { @@ -207,18 +210,18 @@ class Item extends Component { {this.getInviteTypeText()} - {moment(item.invite_time).fromNow()} + {dayjs(item.invite_time).fromNow()} {item.accept_time ? - {moment(item.accept_time).fromNow()} : + {dayjs(item.accept_time).fromNow()} : '--' } {item.is_expired ? - {moment(item.expire_time).format('YYYY-MM-DD HH:mm')} : - moment(item.expire_time).format('YYYY-MM-DD HH:mm') + {dayjs(item.expire_time).format('YYYY-MM-DD HH:mm')} : + dayjs(item.expire_time).format('YYYY-MM-DD HH:mm') } diff --git a/frontend/src/pages/sys-admin/links/share-links.js b/frontend/src/pages/sys-admin/links/share-links.js index d448b4cb5e..9f6ed1e5e9 100644 --- a/frontend/src/pages/sys-admin/links/share-links.js +++ b/frontend/src/pages/sys-admin/links/share-links.js @@ -1,18 +1,21 @@ import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; import { navigate } from '@gatsbyjs/reach-router'; +import dayjs from 'dayjs'; +import relativeTime from 'dayjs/plugin/relativeTime'; import { seafileAPI } from '../../../utils/seafile-api'; import { gettext } from '../../../utils/constants'; import toaster from '../../../components/toast'; import { Utils } from '../../../utils/utils'; import EmptyTip from '../../../components/empty-tip'; -import moment from 'moment'; import Loading from '../../../components/loading'; import Paginator from '../../../components/paginator'; import LinksNav from './links-nav'; import MainPanelTopbar from '../main-panel-topbar'; import UserLink from '../user-link'; +dayjs.extend(relativeTime); + class Content extends Component { constructor(props) { @@ -147,8 +150,8 @@ class Item extends Component { if (!item.expire_date) { return '--'; } - const expire_date = moment(item.expire_date).format('YYYY-MM-DD'); - const expire_time = moment(item.expire_date).format('YYYY-MM-DD HH:mm:ss'); + const expire_date = dayjs(item.expire_date).format('YYYY-MM-DD'); + const expire_time = dayjs(item.expire_date).format('YYYY-MM-DD HH:mm:ss'); return ({expire_date}); }; @@ -161,7 +164,7 @@ class Item extends Component { {item.obj_name} {item.token} - {moment(item.ctime).fromNow()} + {dayjs(item.ctime).fromNow()} {item.view_cnt} {this.renderExpiration()} diff --git a/frontend/src/pages/sys-admin/links/upload-links.js b/frontend/src/pages/sys-admin/links/upload-links.js index 824fd23b27..373f7f902e 100644 --- a/frontend/src/pages/sys-admin/links/upload-links.js +++ b/frontend/src/pages/sys-admin/links/upload-links.js @@ -1,17 +1,19 @@ import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; +import dayjs from 'dayjs'; +import relativeTime from 'dayjs/plugin/relativeTime'; import { seafileAPI } from '../../../utils/seafile-api'; import { gettext } from '../../../utils/constants'; import toaster from '../../../components/toast'; import { Utils } from '../../../utils/utils'; import EmptyTip from '../../../components/empty-tip'; -import moment from 'moment'; import Loading from '../../../components/loading'; import Paginator from '../../../components/paginator'; import LinksNav from './links-nav'; import MainPanelTopbar from '../main-panel-topbar'; import UserLink from '../user-link'; +dayjs.extend(relativeTime); class Content extends Component { @@ -124,8 +126,8 @@ class Item extends Component { if (!item.expire_date) { return '--'; } - const expire_date = moment(item.expire_date).format('YYYY-MM-DD'); - const expire_time = moment(item.expire_date).format('YYYY-MM-DD HH:mm:ss'); + const expire_date = dayjs(item.expire_date).format('YYYY-MM-DD'); + const expire_time = dayjs(item.expire_date).format('YYYY-MM-DD HH:mm:ss'); return ({expire_date}); }; @@ -139,7 +141,7 @@ class Item extends Component { {item.path} {item.token} - {moment(item.ctime).fromNow()} + {dayjs(item.ctime).fromNow()} {item.view_cnt} {this.renderExpiration()} diff --git a/frontend/src/pages/sys-admin/logs-page/file-access-logs.js b/frontend/src/pages/sys-admin/logs-page/file-access-logs.js index 82cf0ec64b..71d9c95906 100644 --- a/frontend/src/pages/sys-admin/logs-page/file-access-logs.js +++ b/frontend/src/pages/sys-admin/logs-page/file-access-logs.js @@ -1,12 +1,13 @@ import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; +import { Button } from 'reactstrap'; +import { navigate } from '@gatsbyjs/reach-router'; +import dayjs from 'dayjs'; +import relativeTime from 'dayjs/plugin/relativeTime'; import { seafileAPI } from '../../../utils/seafile-api'; import { gettext } from '../../../utils/constants'; import { Utils } from '../../../utils/utils'; import EmptyTip from '../../../components/empty-tip'; -import { Button } from 'reactstrap'; -import { navigate } from '@gatsbyjs/reach-router'; -import moment from 'moment'; import Loading from '../../../components/loading'; import Paginator from '../../../components/paginator'; import LogsExportExcelDialog from '../../../components/dialog/sysadmin-dialog/sysadmin-logs-export-excel-dialog'; @@ -17,6 +18,7 @@ import ToggleFilter from './file-access-toggle-filter'; import MainPanelTopbar from '../main-panel-topbar'; import UserLink from '../user-link'; +dayjs.extend(relativeTime); class Content extends Component { @@ -206,7 +208,7 @@ class Item extends Component { {item.event_type} {item.ip}{' / '}{item.device || '--'} - {moment(item.time).fromNow()} + {dayjs(item.time).fromNow()} {item.repo_name ? item.repo_name : gettext('Deleted')} {isOpIconShown && item.repo_name && !repoFilteredBy && ( diff --git a/frontend/src/pages/sys-admin/logs-page/file-update-logs.js b/frontend/src/pages/sys-admin/logs-page/file-update-logs.js index 5c2e85e0ab..c93bcf62ec 100644 --- a/frontend/src/pages/sys-admin/logs-page/file-update-logs.js +++ b/frontend/src/pages/sys-admin/logs-page/file-update-logs.js @@ -1,20 +1,23 @@ import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; +import dayjs from 'dayjs'; +import relativeTime from 'dayjs/plugin/relativeTime'; +import { Button } from 'reactstrap'; import { seafileAPI } from '../../../utils/seafile-api'; import { gettext } from '../../../utils/constants'; import { Utils } from '../../../utils/utils'; import EmptyTip from '../../../components/empty-tip'; -import moment from 'moment'; import Loading from '../../../components/loading'; import Paginator from '../../../components/paginator'; import LogsNav from './logs-nav'; -import { Button } from 'reactstrap'; import MainPanelTopbar from '../main-panel-topbar'; import UserLink from '../user-link'; import ModalPortal from '../../../components/modal-portal'; import CommitDetails from '../../../components/dialog/commit-details'; import LogsExportExcelDialog from '../../../components/dialog/sysadmin-dialog/sysadmin-logs-export-excel-dialog'; +dayjs.extend(relativeTime); + class Content extends Component { getPreviousPage = () => { @@ -128,7 +131,7 @@ class Item extends Component { - {moment(item.time).fromNow()} + {dayjs(item.time).fromNow()} {item.repo_name ? item.repo_name : gettext('Deleted')} {item.file_operation} diff --git a/frontend/src/pages/sys-admin/logs-page/login-logs.js b/frontend/src/pages/sys-admin/logs-page/login-logs.js index d0299b59bc..1266fbd01c 100644 --- a/frontend/src/pages/sys-admin/logs-page/login-logs.js +++ b/frontend/src/pages/sys-admin/logs-page/login-logs.js @@ -1,11 +1,12 @@ import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; +import dayjs from 'dayjs'; +import relativeTime from 'dayjs/plugin/relativeTime'; import { seafileAPI } from '../../../utils/seafile-api'; import { gettext } from '../../../utils/constants'; import { Utils } from '../../../utils/utils'; import { Button } from 'reactstrap'; import EmptyTip from '../../../components/empty-tip'; -import moment from 'moment'; import Loading from '../../../components/loading'; import Paginator from '../../../components/paginator'; import LogsNav from './logs-nav'; @@ -14,6 +15,7 @@ import UserLink from '../user-link'; import LogsExportExcelDialog from '../../../components/dialog/sysadmin-dialog/sysadmin-logs-export-excel-dialog'; import ModalPortal from '../../../components/modal-portal'; +dayjs.extend(relativeTime); class Content extends Component { @@ -114,7 +116,7 @@ class Item extends Component { {item.login_ip} {item.log_success ? gettext('Success') : gettext('Failed')} - {moment(item.login_time).fromNow()} + {dayjs(item.login_time).fromNow()} ); } diff --git a/frontend/src/pages/sys-admin/logs-page/share-permission-logs.js b/frontend/src/pages/sys-admin/logs-page/share-permission-logs.js index a713c4afb8..ace92d9b48 100644 --- a/frontend/src/pages/sys-admin/logs-page/share-permission-logs.js +++ b/frontend/src/pages/sys-admin/logs-page/share-permission-logs.js @@ -1,7 +1,8 @@ import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; import { Link } from '@gatsbyjs/reach-router'; -import moment from 'moment'; +import dayjs from 'dayjs'; +import relativeTime from 'dayjs/plugin/relativeTime'; import { Button } from 'reactstrap'; import { seafileAPI } from '../../../utils/seafile-api'; import { gettext, siteRoot } from '../../../utils/constants'; @@ -15,6 +16,8 @@ import MainPanelTopbar from '../main-panel-topbar'; import UserLink from '../user-link'; import LogsNav from './logs-nav'; +dayjs.extend(relativeTime); + class Content extends Component { getPreviousPage = () => { @@ -146,7 +149,7 @@ class Item extends Component { {Utils.sharePerms(item.permission)} {item.repo_name ? item.repo_name : gettext('Deleted')} {item.folder} - {moment(item.date).fromNow()} + {dayjs(item.date).fromNow()} ); } diff --git a/frontend/src/pages/sys-admin/orgs/org-groups.js b/frontend/src/pages/sys-admin/orgs/org-groups.js index a5f5964425..bc4f2260de 100644 --- a/frontend/src/pages/sys-admin/orgs/org-groups.js +++ b/frontend/src/pages/sys-admin/orgs/org-groups.js @@ -1,6 +1,6 @@ import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; -import moment from 'moment'; +import dayjs from 'dayjs'; import { Utils } from '../../../utils/utils'; import { seafileAPI } from '../../../utils/seafile-api'; import { siteRoot, gettext } from '../../../utils/constants'; @@ -114,7 +114,7 @@ class Item extends Component { {item.group_name} - {moment(item.created_at).format('YYYY-MM-DD HH:mm:ss')} + {dayjs(item.created_at).format('YYYY-MM-DD HH:mm:ss')} diff --git a/frontend/src/pages/sys-admin/orgs/org-users.js b/frontend/src/pages/sys-admin/orgs/org-users.js index d21f8422b3..fa84a5da1a 100644 --- a/frontend/src/pages/sys-admin/orgs/org-users.js +++ b/frontend/src/pages/sys-admin/orgs/org-users.js @@ -1,7 +1,8 @@ import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; import { Button } from 'reactstrap'; -import moment from 'moment'; +import dayjs from 'dayjs'; +import relativeTime from 'dayjs/plugin/relativeTime'; import { Utils } from '../../../utils/utils'; import { seafileAPI } from '../../../utils/seafile-api'; import { gettext, username } from '../../../utils/constants'; @@ -16,6 +17,8 @@ import MainPanelTopbar from '../main-panel-topbar'; import UserLink from '../user-link'; import OrgNav from './org-nav'; +dayjs.extend(relativeTime); + class Content extends Component { constructor(props) { @@ -275,7 +278,7 @@ class Item extends Component { {`${Utils.bytesToSize(item.quota_usage)} / ${item.quota_total > 0 ? Utils.bytesToSize(item.quota_total) : '--'}`} - {moment(item.create_time).format('YYYY-MM-DD HH:mm:ss')}{' / '}{item.last_login ? moment(item.last_login).fromNow() : '--'} + {dayjs(item.create_time).format('YYYY-MM-DD HH:mm:ss')}{' / '}{item.last_login ? dayjs(item.last_login).fromNow() : '--'} {(isOpIconShown && item.email != username) && diff --git a/frontend/src/pages/sys-admin/orgs/orgs-content.js b/frontend/src/pages/sys-admin/orgs/orgs-content.js index 94941d4ecc..78e9ad66bc 100644 --- a/frontend/src/pages/sys-admin/orgs/orgs-content.js +++ b/frontend/src/pages/sys-admin/orgs/orgs-content.js @@ -1,7 +1,7 @@ import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; import { Link } from '@gatsbyjs/reach-router'; -import moment from 'moment'; +import dayjs from 'dayjs'; import { Utils } from '../../../utils/utils'; import { siteRoot, gettext } from '../../../utils/constants'; import EmptyTip from '../../../components/empty-tip'; @@ -199,7 +199,7 @@ class Item extends Component { /> {`${Utils.bytesToSize(item.quota_usage)} / ${item.quota > 0 ? Utils.bytesToSize(item.quota) : '--'}`} - {moment(item.ctime).format('YYYY-MM-DD HH:mm:ss')} + {dayjs(item.ctime).format('YYYY-MM-DD HH:mm:ss')} diff --git a/frontend/src/pages/sys-admin/repos/dir-content.js b/frontend/src/pages/sys-admin/repos/dir-content.js index 8e71f183cd..0c7f6c6f94 100644 --- a/frontend/src/pages/sys-admin/repos/dir-content.js +++ b/frontend/src/pages/sys-admin/repos/dir-content.js @@ -1,11 +1,14 @@ import React, { Fragment } from 'react'; import PropTypes from 'prop-types'; import { Link } from '@gatsbyjs/reach-router'; -import moment from 'moment'; +import dayjs from 'dayjs'; +import relativeTime from 'dayjs/plugin/relativeTime'; import { gettext } from '../../../utils/constants'; import { Utils } from '../../../utils/utils'; import Loading from '../../../components/loading'; +dayjs.extend(relativeTime); + class DirentItem extends React.Component { constructor(props) { @@ -65,7 +68,7 @@ class DirentItem extends React.Component { } {dirent.size} - {moment(dirent.mtime).fromNow()} + {dayjs(dirent.mtime).fromNow()} ); diff --git a/frontend/src/pages/sys-admin/repos/trash-repos.js b/frontend/src/pages/sys-admin/repos/trash-repos.js index 810705cf9e..cf3e5ab552 100644 --- a/frontend/src/pages/sys-admin/repos/trash-repos.js +++ b/frontend/src/pages/sys-admin/repos/trash-repos.js @@ -1,7 +1,8 @@ import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; import { Button } from 'reactstrap'; -import moment from 'moment'; +import dayjs from 'dayjs'; +import relativeTime from 'dayjs/plugin/relativeTime'; import { Utils } from '../../../utils/utils'; import { seafileAPI } from '../../../utils/seafile-api'; import { gettext } from '../../../utils/constants'; @@ -19,6 +20,8 @@ import ReposNav from './repos-nav'; const { trashReposExpireDays } = window.sysadmin.pageOptions; +dayjs.extend(relativeTime); + class Content extends Component { constructor(props) { @@ -235,7 +238,7 @@ class Item extends Component { : repo.group_name} - {moment(repo.delete_time).fromNow()} + {dayjs(repo.delete_time).fromNow()} {isOpIconShown && ( ; + } return ( - + <> + + ); } } diff --git a/frontend/src/pages/sys-admin/statistic/statistic-common-tool.js b/frontend/src/pages/sys-admin/statistic/statistic-common-tool.js index 3b087877a0..b5bb347ff3 100644 --- a/frontend/src/pages/sys-admin/statistic/statistic-common-tool.js +++ b/frontend/src/pages/sys-admin/statistic/statistic-common-tool.js @@ -1,7 +1,7 @@ import React, { Fragment } from 'react'; import PropTypes from 'prop-types'; import { Button } from 'reactstrap'; -import moment from 'moment'; +import dayjs from 'dayjs'; import { gettext } from '../../../utils/constants'; import Picker from './picker'; @@ -22,9 +22,9 @@ class StatisticCommonTool extends React.Component { } componentDidMount() { - let today = moment().format('YYYY-MM-DD 00:00:00'); + let today = dayjs().format('YYYY-MM-DD 00:00:00'); let endTime = today; - let startTime = moment().subtract(6, 'd').format('YYYY-MM-DD 00:00:00'); + let startTime = dayjs().subtract(6, 'd').format('YYYY-MM-DD 00:00:00'); let group_by = 'day'; this.props.getActiviesFiles(startTime, endTime, group_by); } @@ -34,18 +34,18 @@ class StatisticCommonTool extends React.Component { if (statisticType === statisticTypeName) { return; } - let today = moment().format('YYYY-MM-DD 00:00:00'); + let today = dayjs().format('YYYY-MM-DD 00:00:00'); let endTime = today; let startTime; switch (statisticTypeName) { case 'oneWeek' : - startTime = moment().subtract(6, 'd').format('YYYY-MM-DD 00:00:00'); + startTime = dayjs().subtract(6, 'd').format('YYYY-MM-DD 00:00:00'); break; case 'oneMonth' : - startTime = moment().subtract(29, 'd').format('YYYY-MM-DD 00:00:00'); + startTime = dayjs().subtract(29, 'd').format('YYYY-MM-DD 00:00:00'); break; case 'oneYear' : - startTime = moment().subtract(364, 'd').format('YYYY-MM-DD 00:00:00'); + startTime = dayjs().subtract(364, 'd').format('YYYY-MM-DD 00:00:00'); break; } this.setState({ @@ -59,27 +59,27 @@ class StatisticCommonTool extends React.Component { if (!startValue) { return false; } - let today = moment().format(); + let today = dayjs().format(); const endValue = this.state.endValue; if (!endValue) { - let startTime = moment(startValue).format(); + let startTime = dayjs(startValue).format(); return today < startTime; } - return endValue.isBefore(startValue) || moment(startValue).format() > today; + return endValue.isBefore(startValue) || dayjs(startValue).format() > today; }; disabledEndDate = (endValue) => { if (!endValue) { return false; } - let today = moment().format(); + let today = dayjs().format(); const startValue = this.state.startValue; if (!startValue) { - let endTime = moment(endValue).format(); + let endTime = dayjs(endValue).format(); return today < endTime; } - return endValue.isBefore(startValue) || moment(endValue).format() > today; + return endValue.isBefore(startValue) || dayjs(endValue).format() > today; }; onChange = (field, value) => { @@ -96,8 +96,8 @@ class StatisticCommonTool extends React.Component { this.setState({ statisticType: 'itemButton', }); - let startTime = moment(startValue).format('YYYY-MM-DD 00:00:00'); - let endTime = moment(endValue).format('YYYY-MM-DD 00:00:00'); + let startTime = dayjs(startValue).format('YYYY-MM-DD 00:00:00'); + let endTime = dayjs(endValue).format('YYYY-MM-DD 00:00:00'); let group_by = 'day'; this.props.getActiviesFiles(startTime, endTime, group_by); }; diff --git a/frontend/src/pages/sys-admin/statistic/statistic-file.js b/frontend/src/pages/sys-admin/statistic/statistic-file.js index 6f2568205b..3a5a4947d1 100644 --- a/frontend/src/pages/sys-admin/statistic/statistic-file.js +++ b/frontend/src/pages/sys-admin/statistic/statistic-file.js @@ -1,5 +1,5 @@ import React, { Fragment } from 'react'; -import moment from 'moment'; +import dayjs from 'dayjs'; import MainPanelTopbar from '../main-panel-topbar'; import StatisticNav from './statistic-nav'; import StatisticCommonTool from './statistic-common-tool'; @@ -34,7 +34,7 @@ class StatisticFile extends React.Component { let data = res.data; if (Array.isArray(data)) { data.forEach(item => { - labels.push(moment(item.datetime).format('YYYY-MM-DD')); + labels.push(dayjs(item.datetime).format('YYYY-MM-DD')); added.push(item.added); deleted.push(item.deleted); modified.push(item.modified); diff --git a/frontend/src/pages/sys-admin/statistic/statistic-reports.js b/frontend/src/pages/sys-admin/statistic/statistic-reports.js index 13b980f33c..8750373ce9 100644 --- a/frontend/src/pages/sys-admin/statistic/statistic-reports.js +++ b/frontend/src/pages/sys-admin/statistic/statistic-reports.js @@ -1,6 +1,6 @@ import React, { Fragment } from 'react'; +import dayjs from 'dayjs'; import MainPanelTopbar from '../main-panel-topbar'; -import moment from 'moment'; import StatisticNav from './statistic-nav'; import { Button, Input } from 'reactstrap'; import { siteRoot, gettext } from '../../../utils/constants'; @@ -10,7 +10,7 @@ class StatisticReports extends React.Component { constructor(props) { super(props); this.state = { - month: moment().format('YYYYMM'), + month: dayjs().format('YYYYMM'), errorMessage: '' }; } @@ -69,7 +69,7 @@ class StatisticReports extends React.Component {

{gettext('Monthly User Traffic')}
{gettext('Month:')} - +
{errorMessage &&
{errorMessage}
} diff --git a/frontend/src/pages/sys-admin/statistic/statistic-storage.js b/frontend/src/pages/sys-admin/statistic/statistic-storage.js index 2c3c31a988..31425eeb3c 100644 --- a/frontend/src/pages/sys-admin/statistic/statistic-storage.js +++ b/frontend/src/pages/sys-admin/statistic/statistic-storage.js @@ -1,5 +1,5 @@ import React, { Fragment } from 'react'; -import moment from 'moment'; +import dayjs from 'dayjs'; import MainPanelTopbar from '../main-panel-topbar'; import StatisticNav from './statistic-nav'; import StatisticCommonTool from './statistic-common-tool'; @@ -29,7 +29,7 @@ class StatisticStorage extends React.Component { let data = res.data; if (Array.isArray(data)) { data.forEach(item => { - labels.push(moment(item.datetime).format('YYYY-MM-DD')); + labels.push(dayjs(item.datetime).format('YYYY-MM-DD')); totalStorage.push(item.total_storage); }); let total_storage = { diff --git a/frontend/src/pages/sys-admin/statistic/statistic-traffic-orgs.js b/frontend/src/pages/sys-admin/statistic/statistic-traffic-orgs.js index 12e89ca41c..e4c843a599 100644 --- a/frontend/src/pages/sys-admin/statistic/statistic-traffic-orgs.js +++ b/frontend/src/pages/sys-admin/statistic/statistic-traffic-orgs.js @@ -1,6 +1,6 @@ import React, { Fragment } from 'react'; import { Input } from 'reactstrap'; -import moment from 'moment'; +import dayjs from 'dayjs'; import { gettext } from '../../../utils/constants'; import TrafficTable from './traffic-table'; import TrafficTableBody from './traffic-table-body'; @@ -19,14 +19,14 @@ class OrgsTraffic extends React.Component { perPage: 100, currentPage: 1, hasNextPage: false, - month: moment().format('YYYYMM'), + month: dayjs().format('YYYYMM'), isLoading: false, errorMessage: '', sortBy: 'link_file_download', sortOrder: 'desc' }; this.initPage = 1; - this.initMonth = moment().format('YYYYMM'); + this.initMonth = dayjs().format('YYYYMM'); } componentDidMount() { @@ -119,7 +119,7 @@ class OrgsTraffic extends React.Component { {gettext('Month:')} diff --git a/frontend/src/pages/sys-admin/statistic/statistic-traffic-users.js b/frontend/src/pages/sys-admin/statistic/statistic-traffic-users.js index 592d65a911..714d033184 100644 --- a/frontend/src/pages/sys-admin/statistic/statistic-traffic-users.js +++ b/frontend/src/pages/sys-admin/statistic/statistic-traffic-users.js @@ -1,10 +1,10 @@ import React, { Fragment } from 'react'; import { Input } from 'reactstrap'; +import dayjs from 'dayjs'; import TrafficTable from './traffic-table'; import TrafficTableBody from './traffic-table-body'; import { seafileAPI } from '../../../utils/seafile-api'; import Paginator from '../../../components/paginator'; -import moment from 'moment'; import Loading from '../../../components/loading'; import { gettext } from '../../../utils/constants'; import { Utils } from '../../../utils/utils'; @@ -19,14 +19,14 @@ class UsersTraffic extends React.Component { hasNextPage: false, perPage: 100, currentPage: 1, - month: moment().format('YYYYMM'), + month: dayjs().format('YYYYMM'), isLoading: false, errorMessage: '', sortBy: 'link_file_download', sortOrder: 'desc' }; this.initPage = 1; - this.initMonth = moment().format('YYYYMM'); + this.initMonth = dayjs().format('YYYYMM'); } componentDidMount() { @@ -122,7 +122,7 @@ class UsersTraffic extends React.Component { {gettext('Month:')} diff --git a/frontend/src/pages/sys-admin/statistic/statistic-traffic.js b/frontend/src/pages/sys-admin/statistic/statistic-traffic.js index 5dd047d091..33c160fabf 100644 --- a/frontend/src/pages/sys-admin/statistic/statistic-traffic.js +++ b/frontend/src/pages/sys-admin/statistic/statistic-traffic.js @@ -1,5 +1,5 @@ import React, { Fragment } from 'react'; -import moment from 'moment'; +import dayjs from 'dayjs'; import { gettext } from '../../../utils/constants'; import { seafileAPI } from '../../../utils/seafile-api'; import MainPanelTopbar from '../main-panel-topbar'; @@ -45,7 +45,7 @@ class StatisticTraffic extends React.Component { let data = res.data; if (Array.isArray(data)) { data.forEach(item => { - labels.push(moment(item.datetime).format('YYYY-MM-DD')); + labels.push(dayjs(item.datetime).format('YYYY-MM-DD')); link_upload.push(item['link-file-upload']); link_download.push(item['link-file-download']); sync_upload.push(item['sync-file-upload']); diff --git a/frontend/src/pages/sys-admin/statistic/statistic-users.js b/frontend/src/pages/sys-admin/statistic/statistic-users.js index 3664f3b373..fc1c49217b 100644 --- a/frontend/src/pages/sys-admin/statistic/statistic-users.js +++ b/frontend/src/pages/sys-admin/statistic/statistic-users.js @@ -1,5 +1,5 @@ import React, { Fragment } from 'react'; -import moment from 'moment'; +import dayjs from 'dayjs'; import { gettext } from '../../../utils/constants'; import MainPanelTopbar from '../main-panel-topbar'; import StatisticNav from './statistic-nav'; @@ -29,7 +29,7 @@ class StatisticUsers extends React.Component { let data = res.data; if (Array.isArray(data)) { data.forEach(item => { - labels.push(moment(item.datetime).format('YYYY-MM-DD')); + labels.push(dayjs(item.datetime).format('YYYY-MM-DD')); count.push(item.count); }); let userCount = { diff --git a/frontend/src/pages/sys-admin/terms-and-conditions/item.js b/frontend/src/pages/sys-admin/terms-and-conditions/item.js index de252488d4..8283f9d05d 100644 --- a/frontend/src/pages/sys-admin/terms-and-conditions/item.js +++ b/frontend/src/pages/sys-admin/terms-and-conditions/item.js @@ -1,6 +1,7 @@ import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; -import moment from 'moment'; +import dayjs from 'dayjs'; +import relativeTime from 'dayjs/plugin/relativeTime'; import { processor } from '@seafile/seafile-editor'; import { gettext } from '../../../utils/constants'; import { Utils } from '../../../utils/utils'; @@ -11,6 +12,8 @@ import TermsPerviewDialog from '../../../components/dialog/terms-preview-dialog' import ModalPortal from '../../../components/modal-portal'; import OpMenu from '../../../components/dialog/op-menu'; +dayjs.extend(relativeTime); + class Item extends Component { constructor(props) { @@ -131,8 +134,8 @@ class Item extends Component { {previewContent.previewText} - {moment(item.ctime).fromNow()} - {item.activate_time ? moment(item.activate_time).fromNow() : '--'} + {dayjs(item.ctime).fromNow()} + {item.activate_time ? dayjs(item.activate_time).fromNow() : '--'} {this.state.isOpIconShown && 0 ? Utils.bytesToSize(item.quota_total) : '--'}`} - {item.last_login ? moment(item.last_login).fromNow() : '--'} + {item.last_login ? dayjs(item.last_login).fromNow() : '--'} diff --git a/frontend/src/pages/sys-admin/users/user-groups.js b/frontend/src/pages/sys-admin/users/user-groups.js index 681a59132d..8832270583 100644 --- a/frontend/src/pages/sys-admin/users/user-groups.js +++ b/frontend/src/pages/sys-admin/users/user-groups.js @@ -1,7 +1,7 @@ import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; import { Link } from '@gatsbyjs/reach-router'; -import moment from 'moment'; +import dayjs from 'dayjs'; import { Utils } from '../../../utils/utils'; import { seafileAPI } from '../../../utils/seafile-api'; import { siteRoot, gettext } from '../../../utils/constants'; @@ -137,7 +137,7 @@ class Item extends Component { {item.name} {this.getRoleText()} - {moment(item.created_at).format('YYYY-MM-DD HH:mm')} + {dayjs(item.created_at).format('YYYY-MM-DD HH:mm')} ); diff --git a/frontend/src/pages/sys-admin/users/user-repos.js b/frontend/src/pages/sys-admin/users/user-repos.js index 1f72b9cf7b..cea6cc6a5f 100644 --- a/frontend/src/pages/sys-admin/users/user-repos.js +++ b/frontend/src/pages/sys-admin/users/user-repos.js @@ -1,7 +1,8 @@ import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; import { Link } from '@gatsbyjs/reach-router'; -import moment from 'moment'; +import dayjs from 'dayjs'; +import relativeTime from 'dayjs/plugin/relativeTime'; import { Utils } from '../../../utils/utils'; import { seafileAPI } from '../../../utils/seafile-api'; import { isPro, siteRoot, gettext } from '../../../utils/constants'; @@ -15,6 +16,7 @@ import MainPanelTopbar from '../main-panel-topbar'; import Nav from './user-nav'; const { enableSysAdminViewRepo } = window.sysadmin.pageOptions; +dayjs.extend(relativeTime); class Content extends Component { @@ -196,7 +198,7 @@ class Item extends Component { {iconTitle} {this.renderRepoName()} {Utils.bytesToSize(item.size)} - {moment(item.last_modified).fromNow()} + {dayjs(item.last_modified).fromNow()} {isOpIconShown && {this.renderRepoName()} {this.getOwnerLink()} {Utils.bytesToSize(item.size)} - {moment(item.last_modify).fromNow()} + {dayjs(item.last_modify).fromNow()} ); diff --git a/frontend/src/pages/sys-admin/users/users-content.js b/frontend/src/pages/sys-admin/users/users-content.js index bca130e7a0..6f5e70849c 100644 --- a/frontend/src/pages/sys-admin/users/users-content.js +++ b/frontend/src/pages/sys-admin/users/users-content.js @@ -1,6 +1,7 @@ import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; -import moment from 'moment'; +import dayjs from 'dayjs'; +import relativeTime from 'dayjs/plugin/relativeTime'; import { Link } from '@gatsbyjs/reach-router'; import { Utils } from '../../../utils/utils'; import { seafileAPI } from '../../../utils/seafile-api'; @@ -17,6 +18,7 @@ import UserLink from '../user-link'; import UsersFilterBar from './users-filter-bar'; const { availableRoles, availableAdminRoles, institutions } = window.sysadmin.pageOptions; +dayjs.extend(relativeTime); class Content extends Component { @@ -545,11 +547,11 @@ class Item extends Component { } - {`${item.create_time ? moment(item.create_time).format('YYYY-MM-DD HH:mm') : '--'} /`} + {`${item.create_time ? dayjs(item.create_time).format('YYYY-MM-DD HH:mm') : '--'} /`}
- {`${item.last_login ? moment(item.last_login).fromNow() : '--'}`} + {`${item.last_login ? dayjs(item.last_login).fromNow() : '--'}`}
- {`${item.last_access_time ? moment(item.last_access_time).fromNow() : '--'}`} + {`${item.last_access_time ? dayjs(item.last_access_time).fromNow() : '--'}`} {(item.email != username && isOpIconShown) && diff --git a/frontend/src/pages/wiki/index.js b/frontend/src/pages/wiki/index.js index 5590fb58ad..9fb9f614c7 100644 --- a/frontend/src/pages/wiki/index.js +++ b/frontend/src/pages/wiki/index.js @@ -1,5 +1,6 @@ import React, { Component } from 'react'; -import moment from 'moment'; +import dayjs from 'dayjs'; +import relativeTime from 'dayjs/plugin/relativeTime'; import MediaQuery from 'react-responsive'; import { Modal } from 'reactstrap'; import { Utils } from '../../utils/utils'; @@ -17,7 +18,8 @@ import '../../css/toolbar.css'; import '../../css/search.css'; import './wiki.css'; -moment.locale(lang); +dayjs.locale(lang); +dayjs.extend(relativeTime); class Wiki extends Component { constructor(props) { @@ -149,7 +151,7 @@ class Wiki extends Component { isDataLoading: false, content: data.content, permission: data.permission, - lastModified: moment.unix(data.last_modified).fromNow(), + lastModified: dayjs.unix(data.last_modified).fromNow(), latestContributor: data.latest_contributor, }); }); diff --git a/frontend/src/pages/wiki2/index.js b/frontend/src/pages/wiki2/index.js index be07317ea3..a373037707 100644 --- a/frontend/src/pages/wiki2/index.js +++ b/frontend/src/pages/wiki2/index.js @@ -1,5 +1,5 @@ import React, { Component } from 'react'; -import moment from 'moment'; +import dayjs from 'dayjs'; import MediaQuery from 'react-responsive'; import { Modal } from 'reactstrap'; import { Utils } from '../../utils/utils'; @@ -20,7 +20,7 @@ import '../../css/toolbar.css'; import '../../css/search.css'; import './wiki.css'; -moment.locale(lang); +dayjs.locale(lang); class Wiki extends Component { constructor(props) { diff --git a/frontend/src/pages/wiki2/wiki-trash-dialog.js b/frontend/src/pages/wiki2/wiki-trash-dialog.js index cb1c7c2399..0bcbcb26a2 100644 --- a/frontend/src/pages/wiki2/wiki-trash-dialog.js +++ b/frontend/src/pages/wiki2/wiki-trash-dialog.js @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Modal, ModalHeader, ModalBody } from 'reactstrap'; -import moment from 'moment'; +import dayjs from 'dayjs'; import { Utils } from '../../utils/utils'; import { gettext, wikiId } from '../../utils/constants'; import wikiAPI from '../../utils/wiki-api'; @@ -250,7 +250,7 @@ class Item extends React.Component { {item.name} {Utils.bytesToSize(item.size)} - {moment(item.deleted_time).format('YYYY-MM-DD')} + {dayjs(item.deleted_time).format('YYYY-MM-DD')} {isAdmin && {gettext('Restore')} diff --git a/frontend/src/repo-folder-trash.js b/frontend/src/repo-folder-trash.js index f412a4f198..2d068fd058 100644 --- a/frontend/src/repo-folder-trash.js +++ b/frontend/src/repo-folder-trash.js @@ -2,7 +2,7 @@ import React from 'react'; import ReactDom from 'react-dom'; import PropTypes from 'prop-types'; import { navigate } from '@gatsbyjs/reach-router'; -import moment from 'moment'; +import dayjs from 'dayjs'; import { Utils } from './utils/utils'; import { gettext, siteRoot, mediaUrl, logoPath, logoWidth, logoHeight, siteTitle } from './utils/constants'; import { seafileAPI } from './utils/seafile-api'; @@ -358,7 +358,7 @@ class Item extends React.Component { {gettext('Folder')} {item.obj_name} {item.parent_dir} - {moment(item.deleted_time).format('YYYY-MM-DD')} + {dayjs(item.deleted_time).format('YYYY-MM-DD')} {gettext('Restore')} @@ -369,7 +369,7 @@ class Item extends React.Component { {gettext('File')} {item.obj_name} {item.parent_dir} - {moment(item.deleted_time).format('YYYY-MM-DD')} + {dayjs(item.deleted_time).format('YYYY-MM-DD')} {Utils.bytesToSize(item.size)} {gettext('Restore')} diff --git a/frontend/src/repo-history.js b/frontend/src/repo-history.js index f783411c11..3d0a690837 100644 --- a/frontend/src/repo-history.js +++ b/frontend/src/repo-history.js @@ -2,7 +2,7 @@ import React from 'react'; import ReactDom from 'react-dom'; import PropTypes from 'prop-types'; import { navigate } from '@gatsbyjs/reach-router'; -import moment from 'moment'; +import dayjs from 'dayjs'; import { Utils } from './utils/utils'; import { gettext, siteRoot, mediaUrl, logoPath, logoWidth, logoHeight, siteTitle } from './utils/constants'; import { seafileAPI } from './utils/seafile-api'; @@ -292,7 +292,7 @@ class Item extends React.Component { {gettext('Details')} } - {moment(item.time).format('YYYY-MM-DD')} + {dayjs(item.time).format('YYYY-MM-DD')} {name} {item.client_version ? `${item.device_name} / ${item.client_version}` : 'API / --'} diff --git a/frontend/src/shared-dir-view.js b/frontend/src/shared-dir-view.js index 27213f9e98..1830703cdd 100644 --- a/frontend/src/shared-dir-view.js +++ b/frontend/src/shared-dir-view.js @@ -3,7 +3,8 @@ import PropTypes from 'prop-types'; import MD5 from 'MD5'; import ReactDom from 'react-dom'; import { Button, Dropdown, DropdownToggle, DropdownItem, UncontrolledTooltip } from 'reactstrap'; -import moment from 'moment'; +import dayjs from 'dayjs'; +import relativeTime from 'dayjs/plugin/relativeTime'; import Account from './components/common/account'; import { useGoFileserver, fileServerRoot, gettext, siteRoot, mediaUrl, logoPath, logoWidth, logoHeight, siteTitle, thumbnailSizeForOriginal } from './utils/constants'; import { Utils } from './utils/utils'; @@ -23,7 +24,8 @@ import { GRID_MODE, LIST_MODE } from './components/dir-view-mode/constants'; import './css/shared-dir-view.css'; import './css/grid-view.css'; -moment.locale(window.app.config.lang); +dayjs.locale(window.app.config.lang); +dayjs.extend(relativeTime); let loginUser = window.app.pageOptions.name; let { @@ -403,7 +405,7 @@ class SharedDirView extends React.Component { file_name: name, file_path: Utils.joinPath(relativePath, name), is_dir: false, - last_modified: moment().format(), + last_modified: dayjs().format(), size: size }; const folderItems = this.state.items.filter(item => { return item.is_dir; }); @@ -770,7 +772,7 @@ class Item extends React.Component { - {moment(item.last_modified).fromNow()} + {dayjs(item.last_modified).fromNow()} {showDownloadIcon && @@ -784,7 +786,7 @@ class Item extends React.Component { {item.folder_name}
- {moment(item.last_modified).fromNow()} + {dayjs(item.last_modified).fromNow()} {showDownloadIcon && @@ -845,7 +847,7 @@ class Item extends React.Component { )} {Utils.bytesToSize(item.size)} - {moment(item.last_modified).fromNow()} + {dayjs(item.last_modified).fromNow()} {showDownloadIcon && @@ -864,7 +866,7 @@ class Item extends React.Component { {item.file_name}
{Utils.bytesToSize(item.size)} - {moment(item.last_modified).fromNow()} + {dayjs(item.last_modified).fromNow()} {showDownloadIcon && diff --git a/frontend/src/view-file-sdoc.js b/frontend/src/view-file-sdoc.js index 93235e99bd..cb300f998b 100644 --- a/frontend/src/view-file-sdoc.js +++ b/frontend/src/view-file-sdoc.js @@ -52,7 +52,7 @@ window.seafile = { ReactDom.render( }> - +