From 70e77ed35ddf3c03044a13af6846fd4fc7ddb28e Mon Sep 17 00:00:00 2001 From: korelstar Date: Wed, 19 Feb 2020 21:35:19 +0100 Subject: [PATCH] refactoring maintenance --- .babelrc.js | 13 +- .eslintrc.js | 2 +- .scrutinizer.yml | 17 - Makefile | 9 +- README.md | 4 +- package-lock.json | 309 ++++++++------- package.json | 15 +- src/App.vue | 17 +- src/NotesService.js | 416 ++++++++++---------- src/components/AppSettings.vue | 7 +- src/components/NavigationCategoriesItem.vue | 10 +- src/components/NavigationList.vue | 7 +- src/components/NavigationNoteItem.vue | 17 +- src/components/Note.vue | 13 +- src/components/Sidebar.vue | 17 +- src/main.js | 2 - templates/main.php | 1 - .phan/config.php => tests/phan-config.php | 0 phpcs.xml => tests/phpcs.xml | 0 webpack.common.js | 14 +- 20 files changed, 445 insertions(+), 445 deletions(-) delete mode 100644 .scrutinizer.yml rename .phan/config.php => tests/phan-config.php (100%) rename phpcs.xml => tests/phpcs.xml (100%) diff --git a/.babelrc.js b/.babelrc.js index a1690d0d..1b585cfd 100644 --- a/.babelrc.js +++ b/.babelrc.js @@ -1,13 +1,8 @@ module.exports = { - plugins: ['@babel/plugin-syntax-dynamic-import'], + plugins: [ + '@babel/plugin-syntax-dynamic-import', + ], presets: [ - [ - '@babel/preset-env', - { - targets: { - browsers: ['last 2 versions', 'ie >= 11'] - } - } - ] + [ '@babel/preset-env', { useBuiltIns: 'usage', corejs: 3 } ], ] } diff --git a/.eslintrc.js b/.eslintrc.js index 7e0a54ea..565d05ce 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -7,6 +7,6 @@ module.exports = { }, rules: { // no ending html tag on a new line (was warn in "vue/strongly-recommended") - 'vue/html-closing-bracket-newline': ['error', { multiline: 'always' }] + 'vue/html-closing-bracket-newline': ['error', { multiline: 'always' }], }, } diff --git a/.scrutinizer.yml b/.scrutinizer.yml deleted file mode 100644 index 798ba6ce..00000000 --- a/.scrutinizer.yml +++ /dev/null @@ -1,17 +0,0 @@ -filter: - excluded_paths: - - 'js/*' - - 'templates/*' - - 'l10n/*' - - 'tests/*' - -build: - nodes: - analysis: - tests: - override: - - php-scrutinizer-run - -tools: - external_code_coverage: false - js_hint: false diff --git a/Makefile b/Makefile index 80369acd..42a9292f 100644 --- a/Makefile +++ b/Makefile @@ -14,9 +14,7 @@ appstore: clean lint build-js-production rsync -a \ --exclude=.babelrc.js \ --exclude=build \ - --exclude=composer.json \ - --exclude=composer.lock \ - --exclude=composer.phar \ + --exclude=composer.* \ --exclude=CONTRIBUTING.md \ --exclude=.editorconfig \ --exclude=.eslintrc.js \ @@ -27,7 +25,6 @@ appstore: clean lint build-js-production --exclude=Makefile \ --exclude=node_modules \ --exclude=package*.json \ - --exclude=phpcs.xml \ --exclude=phpunit*xml \ --exclude=.scrutinizer.yml \ --exclude=src \ @@ -108,11 +105,11 @@ lint-php-ncversion: lint-php-phan: # PHAN - vendor/bin/phan --allow-polyfill-parser -k .phan/config.php --no-progress-bar -m checkstyle | vendor/bin/cs2pr + vendor/bin/phan --allow-polyfill-parser -k tests/phan-config.php --no-progress-bar -m checkstyle | vendor/bin/cs2pr lint-php-phpcs: # PHP CodeSniffer - vendor/bin/phpcs --standard=phpcs.xml appinfo/ lib/ --report=checkstyle | vendor/bin/cs2pr + vendor/bin/phpcs --standard=tests/phpcs.xml appinfo/ lib/ --report=checkstyle | vendor/bin/cs2pr lint-js: diff --git a/README.md b/README.md index 48a353fc..5b4f9042 100644 --- a/README.md +++ b/README.md @@ -22,8 +22,8 @@ Before reporting bugs: ## :busts_in_silhouette: Maintainers - [Kristof Hamann](https://github.com/korelstar) -- [Hendrik Leppelsack](https://github.com/Henni) -- [Lukas Reschke](https://github.com/LukasReschke) +- [Hendrik Leppelsack](https://github.com/Henni) (formerly) +- [Lukas Reschke](https://github.com/LukasReschke) (formerly) ## :warning: Developer Info diff --git a/package-lock.json b/package-lock.json index 481caf2b..eb93a5bb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1964,15 +1964,6 @@ "@babel/helper-plugin-utils": "^7.8.3" } }, - "@babel/polyfill": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/polyfill/-/polyfill-7.8.3.tgz", - "integrity": "sha512-0QEgn2zkCzqGIkSWWAEmvxD7e00Nm9asTtQvi7HdlYvMhjy/J38V/1Y9ode0zEJeIuxAI0uftiAzqc7nVeWUGg==", - "requires": { - "core-js": "^2.6.5", - "regenerator-runtime": "^0.13.2" - } - }, "@babel/preset-env": { "version": "7.8.4", "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.8.4.tgz", @@ -2184,6 +2175,22 @@ "integrity": "sha512-f+sKpdLZXkODV+OY39K1M+Spmd4RgxmtEXmNn4Bviv4R7uBFHXuw+JX9ZdfDeOryfHjJ/TRQxQEp0GMpBwZFUw==", "dev": true }, + "@nextcloud/dialogs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@nextcloud/dialogs/-/dialogs-1.1.0.tgz", + "integrity": "sha512-RjA+AEBwIkT2YEtMcfni3KQxn8o2SgbnVGp0n00z9tEhuvx9g3Z7Eh5+bY7zzanedFqryJSazMhk0voUyxr8Ow==", + "requires": { + "core-js": "3.6.4", + "toastify-js": "^1.6.2" + }, + "dependencies": { + "core-js": { + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.4.tgz", + "integrity": "sha512-4paDGScNgZP2IXXilaffL9X7968RuvwlkK3xWtZRVqgd8SYNiVKRJvkFd1aqqEuPfN7E68ZHEp9hDj6lHj4Hyw==" + } + } + }, "@nextcloud/eslint-config": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@nextcloud/eslint-config/-/eslint-config-1.0.0.tgz", @@ -2303,9 +2310,9 @@ "dev": true }, "@types/node": { - "version": "13.7.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.7.0.tgz", - "integrity": "sha512-GnZbirvmqZUzMgkFn70c74OQpTTUcCzlhQliTzYjQMqg+hVKcDnxdL19Ne3UdYzdMA/+W3eb646FWn/ZaT1NfQ==", + "version": "13.7.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.7.4.tgz", + "integrity": "sha512-oVeL12C6gQS/GAExndigSaLxTrKpQPxewx9bOcwfvJiJge4rr7wNaph4J+ns5hrmIV2as5qxqN8YKthn9qh0jw==", "dev": true }, "@types/normalize-package-data": { @@ -3184,14 +3191,14 @@ } }, "browserslist": { - "version": "4.8.6", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.8.6.tgz", - "integrity": "sha512-ZHao85gf0eZ0ESxLfCp73GG9O/VTytYDIkIiZDlURppLTI9wErSM/5yAKEq6rcUdxBLjMELmrYUJGg5sxGKMHg==", + "version": "4.8.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.8.7.tgz", + "integrity": "sha512-gFOnZNYBHrEyUML0xr5NJ6edFaaKbTFX9S9kQHlYfCP0Rit/boRIz4G+Avq6/4haEKJXdGGUnoolx+5MWW2BoA==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001023", - "electron-to-chromium": "^1.3.341", - "node-releases": "^1.1.47" + "caniuse-lite": "^1.0.30001027", + "electron-to-chromium": "^1.3.349", + "node-releases": "^1.1.49" } }, "buffer": { @@ -3316,9 +3323,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001027", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001027.tgz", - "integrity": "sha512-7xvKeErvXZFtUItTHgNtLgS9RJpVnwBlWX8jSo/BO8VsF6deszemZSkJJJA1KOKrXuzZH4WALpAJdq5EyfgMLg==", + "version": "1.0.30001028", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001028.tgz", + "integrity": "sha512-Vnrq+XMSHpT7E+LWoIYhs3Sne8h9lx9YJV3acH3THNCwU/9zV93/ta4xVfzTtnqd3rvnuVpVjE3DFqf56tr3aQ==", "dev": true }, "caseless": { @@ -3688,9 +3695,10 @@ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" }, "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==" + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.4.tgz", + "integrity": "sha512-4paDGScNgZP2IXXilaffL9X7968RuvwlkK3xWtZRVqgd8SYNiVKRJvkFd1aqqEuPfN7E68ZHEp9hDj6lHj4Hyw==", + "dev": true }, "core-js-compat": { "version": "3.6.4", @@ -4111,15 +4119,6 @@ "domelementtype": "1" } }, - "dot-prop": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", - "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", - "dev": true, - "requires": { - "is-obj": "^1.0.0" - } - }, "duplexify": { "version": "3.7.1", "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", @@ -4153,9 +4152,9 @@ } }, "electron-to-chromium": { - "version": "1.3.348", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.348.tgz", - "integrity": "sha512-6O0IInybavGdYtcbI4ryF/9e3Qi8/soi6C68ELRseJuTwQPKq39uGgVVeQHG28t69Sgsky09nXBRhUiFXsZyFQ==", + "version": "1.3.355", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.355.tgz", + "integrity": "sha512-zKO/wS+2ChI/jz9WAo647xSW8t2RmgRLFdbUb/77cORkUTargO+SCj4ctTHjBn2VeNFrsLgDT7IuDVrd3F8mLQ==", "dev": true }, "elliptic": { @@ -4180,9 +4179,9 @@ "dev": true }, "emojis-list": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", - "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", "dev": true }, "end-of-stream": { @@ -4864,12 +4863,6 @@ "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", "dev": true }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", - "dev": true - }, "fast-glob": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.1.1.tgz", @@ -4945,35 +4938,39 @@ } }, "file-loader": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-5.0.2.tgz", - "integrity": "sha512-QMiQ+WBkGLejKe81HU8SZ9PovsU/5uaLo0JdTCEXOYv7i7jfAjHZi1tcwp9tSASJPOmmHZtbdCervFmXMH/Dcg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-5.1.0.tgz", + "integrity": "sha512-u/VkLGskw3Ue59nyOwUwXI/6nuBCo7KBkniB/l7ICwr/7cPNGsL1WCXUp3GB0qgOOKU1TiP49bv4DZF/LJqprg==", "dev": true, "requires": { - "loader-utils": "^1.2.3", + "loader-utils": "^1.4.0", "schema-utils": "^2.5.0" }, "dependencies": { - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", "dev": true, "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "minimist": "^1.2.0" } }, - "schema-utils": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.0.tgz", - "integrity": "sha512-UlPB1ME4i/71cih/Rv92gK8043CrJTc2mjkyxDp4pdJ7ZfzY0g0hdGjjDB23jX3X+NXSneCdQbScGhn6K2tbpQ==", + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", "dev": true, "requires": { - "ajv": "^6.10.2", - "ajv-keywords": "^3.4.1" + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" } } } @@ -5898,13 +5895,13 @@ "dev": true }, "globule": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.0.tgz", - "integrity": "sha512-YlD4kdMqRCQHrhVdonet4TdRtv1/sZKepvoxNT4Nrhrp5HI8XFfc8kFlGlBn2myBo80aGp8Eft259mbcUJhgSg==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.1.tgz", + "integrity": "sha512-OVyWOHgw29yosRHCHo7NncwR1hW5ew0W/UrvtwvjefVJeQ26q4/8r8FmPsSF1hJ93IgWkyv16pCTz6WblMzm/g==", "dev": true, "requires": { "glob": "~7.1.1", - "lodash": "~4.17.10", + "lodash": "~4.17.12", "minimatch": "~3.0.2" } }, @@ -6107,9 +6104,9 @@ }, "dependencies": { "readable-stream": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.5.0.tgz", - "integrity": "sha512-gSz026xs2LfxBPudDuI41V1lka8cxg64E66SGe78zJlsUofOg/yqwezdIcdfwik6B4h8LFmWPA9ef9X3FiNFLA==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, "requires": { "inherits": "^2.0.3", @@ -6478,12 +6475,6 @@ } } }, - "is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", - "dev": true - }, "is-plain-obj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", @@ -6823,13 +6814,13 @@ "dev": true }, "loader-utils": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", - "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", "dev": true, "requires": { "big.js": "^5.2.2", - "emojis-list": "^2.0.0", + "emojis-list": "^3.0.0", "json5": "^1.0.1" }, "dependencies": { @@ -7241,6 +7232,12 @@ "brorand": "^1.0.1" } }, + "mime": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", + "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==", + "dev": true + }, "mime-db": { "version": "1.43.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz", @@ -7491,9 +7488,9 @@ } }, "node-releases": { - "version": "1.1.48", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.48.tgz", - "integrity": "sha512-Hr8BbmUl1ujAST0K0snItzEA5zkJTQup8VNTKNfT6Zw8vTJkIiagUPNfxHmgDOyfFYNfKAul40sD0UEYTvwebw==", + "version": "1.1.49", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.49.tgz", + "integrity": "sha512-xH8t0LS0disN0mtRCh+eByxFPie+msJUBL/lJDBuap53QGiYPa9joh83K4pCZgWJ+2L4b9h88vCVdXQ60NO2bg==", "dev": true, "requires": { "semver": "^6.3.0" @@ -7696,9 +7693,9 @@ } }, "object-hash": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.0.1.tgz", - "integrity": "sha512-HgcGMooY4JC2PBt9sdUdJ6PMzpin+YtY3r/7wg0uTifP+HJWW8rammseSEHuyt0UeShI183UGssCJqm1bJR7QA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.0.3.tgz", + "integrity": "sha512-JPKn0GMu+Fa3zt3Bmr66JhokJU5BaNBIh4ZeTlaCBzrBsOeXzwcKKAK1tbLiPKgvwmPXsDvvLHoWh5Bm7ofIYg==", "dev": true }, "object-inspect": { @@ -8051,9 +8048,9 @@ "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" }, "postcss": { - "version": "7.0.26", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.26.tgz", - "integrity": "sha512-IY4oRjpXWYshuTDFxMVkJDtWIk2LhsTlu8bZnbEJA4+bYT16Lvpo8Qv6EvDumhYRgzjZl489pmsY3qVgJQ08nA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -8246,12 +8243,12 @@ } }, "postcss-selector-parser": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz", - "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz", + "integrity": "sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg==", "dev": true, "requires": { - "dot-prop": "^4.1.1", + "cssesc": "^3.0.0", "indexes-of": "^1.0.1", "uniq": "^1.0.1" } @@ -8263,9 +8260,9 @@ "dev": true }, "postcss-value-parser": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.0.2.tgz", - "integrity": "sha512-LmeoohTpp/K4UiyQCwuGWlONxXamGzCMtFxLq4W1nZVGIQLYvMCJx3yAF9qyyuFpflABI9yVdtJAqbihOsCsJQ==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.0.3.tgz", + "integrity": "sha512-N7h4pG+Nnu5BEIzyeaaIYWs0LI5XC40OrRh5L60z0QjFsqGWcHcbkBvpe1WYpcIS9yQ8sOi/vIPt1ejQCrMVrg==", "dev": true }, "prelude-ls": { @@ -8619,9 +8616,9 @@ "integrity": "sha512-5qxzGZjDs9w4tzT3TPhCJqWdCc3RLYwy9J2NB0nm5Lz+S273lvWcpjaTGHsT1dc6Hhfq41uSEOw8wBmxrKOuyg==" }, "regjsparser": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.2.tgz", - "integrity": "sha512-E9ghzUtoLwDekPT0DYCp+c4h+bvuUpe6rRHCTYn6eGoqj1LgKXxT6I0Il4WbjhQkOghzi/V+y03bPKvbllL93Q==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.3.tgz", + "integrity": "sha512-8uZvYbnfAtEm9Ab8NTb3hdLwL4g/LQzEYP7Xs27T96abJCCE2d6r3cPZPQEsLKy0vRSGVNG+/zVGtLr86HQduA==", "requires": { "jsesc": "~0.5.0" }, @@ -8720,9 +8717,9 @@ "dev": true }, "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", "dev": true, "requires": { "aws-sign2": "~0.7.0", @@ -8732,7 +8729,7 @@ "extend": "~3.0.2", "forever-agent": "~0.6.1", "form-data": "~2.3.2", - "har-validator": "~5.1.0", + "har-validator": "~5.1.3", "http-signature": "~1.2.0", "is-typedarray": "~1.0.0", "isstream": "~0.1.2", @@ -8742,7 +8739,7 @@ "performance-now": "^2.1.0", "qs": "~6.5.2", "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", + "tough-cookie": "~2.5.0", "tunnel-agent": "^0.6.0", "uuid": "^3.3.2" } @@ -8766,9 +8763,9 @@ "dev": true }, "resolve": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.0.tgz", - "integrity": "sha512-+hTmAldEGE80U2wJJDC1lebb5jWqvTYAfm3YZ1ckk1gBr0MnCqUKlwK1e+anaFljIl+F5tR5IoZcm4ZDA1zMQw==", + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", + "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", "requires": { "path-parse": "^1.0.6" } @@ -9495,9 +9492,9 @@ "dev": true }, "stylelint": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-13.1.0.tgz", - "integrity": "sha512-Ei+nCSQTyZYrsLSUIxq48/QfzCQD9r9sQiBqy7Z4IpIMcj+E0R6b0CHrSFeE7jNgREpBfJKJd6DpstuDrwUiew==", + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-13.2.0.tgz", + "integrity": "sha512-isf31yjkm0DQesx+Yk1b/WQpFkf1MicwaAVR22Hprx9HRFGhhEkWdrVCyrkK6HFymL0rhzynG97Tu53q/WCsAg==", "dev": true, "requires": { "autoprefixer": "^9.7.4", @@ -9534,7 +9531,7 @@ "postcss-safe-parser": "^4.0.1", "postcss-sass": "^0.4.2", "postcss-scss": "^2.0.0", - "postcss-selector-parser": "^3.1.0", + "postcss-selector-parser": "^6.0.2", "postcss-syntax": "^0.36.2", "postcss-value-parser": "^4.0.2", "resolve-from": "^5.0.0", @@ -9664,9 +9661,9 @@ "dev": true }, "meow": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-6.0.0.tgz", - "integrity": "sha512-x4rYsjigPBDAxY+BGuK83YLhUIqui5wYyZoqb6QJCUOs+0fiYq+i/NV4Jt8OgIfObZFxG9iTyvLDu4UTohGTFw==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-6.0.1.tgz", + "integrity": "sha512-kxGTFgT/b7/oSRSQsJ0qsT5IMU+bgZ1eAdSA3kIV7onkW0QWo/hL5RbGlMfvBjHJKPE1LaPX0kdecYFiqYWjUw==", "dev": true, "requires": { "@types/minimist": "^1.2.0", @@ -10146,22 +10143,19 @@ "repeat-string": "^1.6.1" } }, + "toastify-js": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/toastify-js/-/toastify-js-1.6.2.tgz", + "integrity": "sha512-ECQzgjTjxaElfwp/8e8qoIYx7U5rU2G54e5aiPMv+UtmGOYEitrtNp/Kr8uMgntnQNrDZEQJNGjBtoNnEgR5EA==" + }, "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", "dev": true, "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - } + "psl": "^1.1.28", + "punycode": "^2.1.1" } }, "trim": { @@ -10479,6 +10473,17 @@ } } }, + "url-loader": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-3.0.0.tgz", + "integrity": "sha512-a84JJbIA5xTFTWyjjcPdnsu+41o/SNE8SpXMdUvXs6Q+LuhCD9E2+0VCiuDWqgo3GGXVlFHzArDmBpj9PgWn4A==", + "dev": true, + "requires": { + "loader-utils": "^1.2.3", + "mime": "^2.4.4", + "schema-utils": "^2.5.0" + } + }, "use": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", @@ -10670,9 +10675,9 @@ "dev": true }, "vue-loader": { - "version": "15.8.3", - "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.8.3.tgz", - "integrity": "sha512-yFksTFbhp+lxlm92DrKdpVIWMpranXnTEuGSc0oW+Gk43M9LWaAmBTnfj5+FCdve715mTHvo78IdaXf5TbiTJg==", + "version": "15.9.0", + "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.9.0.tgz", + "integrity": "sha512-FeDHvTSpwyLeF7LIV1PYkvqUQgTJ8UmOxhSlCyRSxaXCKk+M6NF4tDQsLsPPNeDPyR7TfRQ8MLg6v+8PsDV9xQ==", "dev": true, "requires": { "@vue/component-compiler-utils": "^3.1.0", @@ -10868,9 +10873,9 @@ } }, "webpack-cli": { - "version": "3.3.10", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.10.tgz", - "integrity": "sha512-u1dgND9+MXaEt74sJR4PR7qkPxXUSQ0RXYq8x1L6Jg1MYVEmGPrH6Ah6C4arD4r0J1P5HKjRqpab36k0eIzPqg==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.11.tgz", + "integrity": "sha512-dXlfuml7xvAFwYUPsrtQAA9e4DOe58gnzSxhgrO/ZM/gyXTBowrsYeubyN4mqGhYdpXMFNyQ6emjJS9M7OBd4g==", "dev": true, "requires": { "chalk": "2.4.2", @@ -10892,12 +10897,6 @@ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, "cliui": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", @@ -10909,6 +10908,12 @@ "wrap-ansi": "^5.1.0" } }, + "emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", + "dev": true + }, "enhanced-resolve": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz", @@ -10932,6 +10937,15 @@ "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", "dev": true }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, "lcid": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", @@ -10941,6 +10955,17 @@ "invert-kv": "^2.0.0" } }, + "loader-utils": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", + "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" + } + }, "memory-fs": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", @@ -11074,12 +11099,6 @@ } } }, - "webpack-node-externals": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/webpack-node-externals/-/webpack-node-externals-1.7.2.tgz", - "integrity": "sha512-ajerHZ+BJKeCLviLUUmnyd5B4RavLF76uv3cs6KNuO8W+HuQaEs0y0L7o40NQxdPy5w0pcv8Ew7yPUAQG0UdCg==", - "dev": true - }, "webpack-sources": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", diff --git a/package.json b/package.json index ea6c2d83..e86518c4 100644 --- a/package.json +++ b/package.json @@ -12,8 +12,8 @@ "stylelint:fix": "stylelint 'src/**/*.vue' 'css/**/*.scss' --fix" }, "dependencies": { - "@babel/polyfill": "^7.8.3", "@nextcloud/axios": "^1.3.1", + "@nextcloud/dialogs": "^1.1.0", "@nextcloud/vue": "1.2.7", "easymde": "^2.9.0", "markdown-it": "^10.0.0", @@ -37,6 +37,7 @@ "@nextcloud/eslint-plugin": "^1.1.0", "babel-eslint": "^10.0.3", "babel-loader": "^8.0.6", + "core-js": "^3.6.4", "css-loader": "^3.4.2", "eslint": "^5.16.0", "eslint-config-standard": "^12.0.0", @@ -47,17 +48,17 @@ "eslint-plugin-promise": "^4.2.1", "eslint-plugin-standard": "^4.0.1", "eslint-plugin-vue": "^5.2.3", - "file-loader": "^5.0.2", + "file-loader": "^5.1.0", "node-sass": "^4.13.1", "sass-loader": "^8.0.2", - "stylelint": "^13.1.0", + "stylelint": "^13.2.0", "stylelint-config-recommended-scss": "^4.2.0", "stylelint-scss": "^3.14.2", - "vue-loader": "^15.8.3", + "url-loader": "^3.0.0", + "vue-loader": "^15.9.0", "vue-template-compiler": "^2.6.11", "webpack": "^4.41.6", - "webpack-cli": "^3.3.10", - "webpack-merge": "^4.2.2", - "webpack-node-externals": "^1.7.2" + "webpack-cli": "^3.3.11", + "webpack-merge": "^4.2.2" } } diff --git a/src/App.vue b/src/App.vue index 5e998c51..b3a7f569 100644 --- a/src/App.vue +++ b/src/App.vue @@ -40,11 +40,12 @@ import { AppNavigationNew, Content, } from '@nextcloud/vue' + +import { fetchNotes, noteExists, createNote } from './NotesService' +import { openNavbar } from './nextcloud' import AppSettings from './components/AppSettings' import NavigationList from './components/NavigationList' -import NotesService from './NotesService' import store from './store' -import { openNavbar } from './nextcloud' export default { name: 'App', @@ -128,7 +129,7 @@ export default { methods: { loadNotes() { this.loading.notes = true - NotesService.fetchNotes() + fetchNotes() .then(data => { if (data.notes !== null) { this.error = false @@ -140,7 +141,7 @@ export default { .catch(() => { this.error = true }) - .finally(() => { + .then(() => { this.loading.notes = false }) }, @@ -154,8 +155,8 @@ export default { }, routeDefault(defaultNoteId) { - if (this.$route.name !== 'note' || !NotesService.noteExists(this.$route.params.noteId)) { - if (NotesService.noteExists(defaultNoteId)) { + if (this.$route.name !== 'note' || !noteExists(this.$route.params.noteId)) { + if (noteExists(defaultNoteId)) { this.routeToNote(defaultNoteId) } else { this.routeFirst() @@ -194,13 +195,13 @@ export default { return } this.loading.create = true - NotesService.createNote(this.filter.category) + createNote(this.filter.category) .then(note => { this.routeToNote(note.id) }) .catch(() => { }) - .finally(() => { + .then(() => { this.loading.create = false }) }, diff --git a/src/NotesService.js b/src/NotesService.js index 6ee0fca3..7c7786ae 100644 --- a/src/NotesService.js +++ b/src/NotesService.js @@ -2,214 +2,212 @@ import AppGlobal from './mixins/AppGlobal' import store from './store' import axios from '@nextcloud/axios' -export default { +const t = AppGlobal.methods.t - t: AppGlobal.methods.t, - - url(url) { - url = `/apps/notes${url}` - return OC.generateUrl(url) - }, - - handleSyncError(message) { - OC.Notification.showTemporary(message + ' ' + this.t('notes', 'See JavaScript console for details.')) - }, - - handleInsufficientStorage() { - OC.Notification.showTemporary(this.t('notes', 'Saving the note has failed due to insufficient storage.')) - }, - - setSettings(settings) { - return axios - .put(this.url('/settings'), settings) - .then(response => { - const settings = response.data - store.commit('setSettings', settings) - return settings - }) - .catch(err => { - console.error(err) - this.handleSyncError(this.t('notes', 'Updating settings has failed.')) - throw err - }) - }, - - fetchNotes() { - return axios - .get(this.url('/notes')) - .then(response => { - store.commit('setSettings', response.data.settings) - if (response.data.notes !== null) { - store.dispatch('addAll', response.data.notes) - } - if (response.data.errorMessage) { - OC.Notification.showTemporary(response.data.errorMessage) - } - return response.data - }) - .catch(err => { - console.error(err) - this.handleSyncError(this.t('notes', 'Fetching notes has failed.')) - throw err - }) - }, - - fetchNote(noteId) { - return axios - .get(this.url('/notes/' + noteId)) - .then(response => { - const localNote = store.getters.getNote(parseInt(noteId)) - // only overwrite if there are no unsaved changes - if (!localNote || !localNote.unsaved) { - store.commit('add', response.data) - } - return response.data - }) - .catch(err => { - if (err.response.status === 404) { - throw err - } else { - console.error(err) - const msg = this.t('notes', 'Fetching note {id} has failed.', { id: noteId }) - store.commit('setNoteAttribute', { noteId: noteId, attribute: 'error', value: true }) - store.commit('setNoteAttribute', { noteId: noteId, attribute: 'errorMessage', value: msg }) - return store.getter.getNote(noteId) - } - }) - }, - - createNote(category) { - return axios - .post(this.url('/notes'), { category: category }) - .then(response => { - store.commit('add', response.data) - return response.data - }) - .catch(err => { - console.error(err) - if (err.response.status === 507) { - this.handleInsufficientStorage() - } else { - this.handleSyncError(this.t('notes', 'Creating new note has failed.')) - } - throw err - }) - }, - - _updateNote(note) { - return axios - .put(this.url('/notes/' + note.id), { content: note.content }) - .then(response => { - const updated = response.data - note.saveError = false - note.title = updated.title - note.modified = updated.modified - if (updated.content === note.content) { - note.unsaved = false - } - store.commit('add', note) - return note - }) - .catch(err => { - store.commit('setNoteAttribute', { noteId: note.id, attribute: 'saveError', value: true }) - console.error(err) - if (err.response.status === 507) { - this.handleInsufficientStorage() - } else { - this.handleSyncError(this.t('notes', 'Updating note {id} has failed.', { id: note.id })) - } - }) - }, - - prepareDeleteNote(noteId) { - store.commit('setNoteAttribute', { noteId: noteId, attribute: 'deleting', value: 'prepare' }) - }, - - undoDeleteNote(noteId) { - store.commit('setNoteAttribute', { noteId: noteId, attribute: 'deleting', value: null }) - }, - - deleteNote(noteId) { - store.commit('setNoteAttribute', { noteId: noteId, attribute: 'deleting', value: 'deleting' }) - return axios - .delete(this.url('/notes/' + noteId)) - .then(() => { - store.commit('remove', noteId) - }) - .catch(err => { - console.error(err) - this.handleSyncError(this.t('notes', 'Deleting note {id} has failed.', { id: noteId })) - this.undoDeleteNote(noteId) - throw err - }) - }, - - setFavorite(noteId, favorite) { - return axios - .put(this.url('/notes/' + noteId + '/favorite'), { favorite: favorite }) - .then(response => { - store.commit('setNoteAttribute', { noteId: noteId, attribute: 'favorite', value: response.data }) - }) - .catch(err => { - console.error(err) - this.handleSyncError(this.t('notes', 'Toggling favorite for note {id} has failed.', { id: noteId })) - throw err - }) - }, - - setCategory(noteId, category) { - return axios - .put(this.url('/notes/' + noteId + '/category'), { category: category }) - .then(response => { - const realCategory = response.data - if (category !== realCategory) { - this.handleSyncError(this.t('notes', 'Updating the note\'s category has failed. Is the target directory writable?')) - } - store.commit('setNoteAttribute', { noteId: noteId, attribute: 'category', value: realCategory }) - }) - .catch(err => { - console.error(err) - this.handleSyncError(this.t('notes', 'Updating the category for note {id} has failed.', { id: noteId })) - throw err - }) - }, - - saveNote(noteId, manualSave = false) { - store.commit('addUnsaved', noteId) - if (manualSave) { - store.commit('setManualSave', true) - } - this._saveNotes() - }, - _saveNotes() { - const unsavedNotes = Object.values(store.state.unsaved) - if (store.state.isSaving || unsavedNotes.length === 0) { - return - } - store.commit('setSaving', true) - const promises = unsavedNotes.map(note => this._updateNote(note)) - store.commit('clearUnsaved') - Promise.all(promises).finally(() => { - store.commit('setSaving', false) - store.commit('setManualSave', false) - this._saveNotes() - }) - }, - - saveNoteManually(noteId) { - store.commit('setNoteAttribute', { noteId: noteId, attribute: 'saveError', value: false }) - this.saveNote(noteId, true) - }, - - noteExists(noteId) { - return store.getters.noteExists(noteId) - }, - - getCategories(maxLevel, details) { - return store.getters.getCategories(maxLevel, details) - }, - - categoryLabel(category) { - return category === '' ? this.t('notes', 'Uncategorized') : category.replace(/\//g, ' / ') - }, +function url(url) { + url = `/apps/notes${url}` + return OC.generateUrl(url) +} + +function handleSyncError(message) { + OC.Notification.showTemporary(message + ' ' + t('notes', 'See JavaScript console for details.')) +} + +function handleInsufficientStorage() { + OC.Notification.showTemporary(t('notes', 'Saving the note has failed due to insufficient storage.')) +} + +export const setSettings = settings => { + return axios + .put(url('/settings'), settings) + .then(response => { + const settings = response.data + store.commit('setSettings', settings) + return settings + }) + .catch(err => { + console.error(err) + handleSyncError(t('notes', 'Updating settings has failed.')) + throw err + }) +} + +export const fetchNotes = () => { + return axios + .get(url('/notes')) + .then(response => { + store.commit('setSettings', response.data.settings) + if (response.data.notes !== null) { + store.dispatch('addAll', response.data.notes) + } + if (response.data.errorMessage) { + OC.Notification.showTemporary(response.data.errorMessage) + } + return response.data + }) + .catch(err => { + console.error(err) + handleSyncError(t('notes', 'Fetching notes has failed.')) + throw err + }) +} + +export const fetchNote = noteId => { + return axios + .get(url('/notes/' + noteId)) + .then(response => { + const localNote = store.getters.getNote(parseInt(noteId)) + // only overwrite if there are no unsaved changes + if (!localNote || !localNote.unsaved) { + store.commit('add', response.data) + } + return response.data + }) + .catch(err => { + if (err.response.status === 404) { + throw err + } else { + console.error(err) + const msg = t('notes', 'Fetching note {id} has failed.', { id: noteId }) + store.commit('setNoteAttribute', { noteId: noteId, attribute: 'error', value: true }) + store.commit('setNoteAttribute', { noteId: noteId, attribute: 'errorMessage', value: msg }) + return store.getter.getNote(noteId) + } + }) +} + +export const createNote = category => { + return axios + .post(url('/notes'), { category: category }) + .then(response => { + store.commit('add', response.data) + return response.data + }) + .catch(err => { + console.error(err) + if (err.response.status === 507) { + handleInsufficientStorage() + } else { + handleSyncError(t('notes', 'Creating new note has failed.')) + } + throw err + }) +} + +function _updateNote(note) { + return axios + .put(url('/notes/' + note.id), { content: note.content }) + .then(response => { + const updated = response.data + note.saveError = false + note.title = updated.title + note.modified = updated.modified + if (updated.content === note.content) { + note.unsaved = false + } + store.commit('add', note) + return note + }) + .catch(err => { + store.commit('setNoteAttribute', { noteId: note.id, attribute: 'saveError', value: true }) + console.error(err) + if (err.response.status === 507) { + handleInsufficientStorage() + } else { + handleSyncError(t('notes', 'Updating note {id} has failed.', { id: note.id })) + } + }) +} + +export const prepareDeleteNote = noteId => { + store.commit('setNoteAttribute', { noteId: noteId, attribute: 'deleting', value: 'prepare' }) +} + +export const undoDeleteNote = noteId => { + store.commit('setNoteAttribute', { noteId: noteId, attribute: 'deleting', value: null }) +} + +export const deleteNote = noteId => { + store.commit('setNoteAttribute', { noteId: noteId, attribute: 'deleting', value: 'deleting' }) + return axios + .delete(url('/notes/' + noteId)) + .then(() => { + store.commit('remove', noteId) + }) + .catch(err => { + console.error(err) + handleSyncError(t('notes', 'Deleting note {id} has failed.', { id: noteId })) + undoDeleteNote(noteId) + throw err + }) +} + +export const setFavorite = (noteId, favorite) => { + return axios + .put(url('/notes/' + noteId + '/favorite'), { favorite: favorite }) + .then(response => { + store.commit('setNoteAttribute', { noteId: noteId, attribute: 'favorite', value: response.data }) + }) + .catch(err => { + console.error(err) + handleSyncError(t('notes', 'Toggling favorite for note {id} has failed.', { id: noteId })) + throw err + }) +} + +export const setCategory = (noteId, category) => { + return axios + .put(url('/notes/' + noteId + '/category'), { category: category }) + .then(response => { + const realCategory = response.data + if (category !== realCategory) { + handleSyncError(t('notes', 'Updating the note\'s category has failed. Is the target directory writable?')) + } + store.commit('setNoteAttribute', { noteId: noteId, attribute: 'category', value: realCategory }) + }) + .catch(err => { + console.error(err) + handleSyncError(t('notes', 'Updating the category for note {id} has failed.', { id: noteId })) + throw err + }) +} + +export const saveNote = (noteId, manualSave = false) => { + store.commit('addUnsaved', noteId) + if (manualSave) { + store.commit('setManualSave', true) + } + _saveNotes() +} + +function _saveNotes() { + const unsavedNotes = Object.values(store.state.unsaved) + if (store.state.isSaving || unsavedNotes.length === 0) { + return + } + store.commit('setSaving', true) + const promises = unsavedNotes.map(note => _updateNote(note)) + store.commit('clearUnsaved') + Promise.all(promises).then(() => { + store.commit('setSaving', false) + store.commit('setManualSave', false) + _saveNotes() + }) +} + +export const saveNoteManually = (noteId) => { + store.commit('setNoteAttribute', { noteId: noteId, attribute: 'saveError', value: false }) + saveNote(noteId, true) +} + +export const noteExists = (noteId) => { + return store.getters.noteExists(noteId) +} + +export const getCategories = (maxLevel, details) => { + return store.getters.getCategories(maxLevel, details) +} + +export const categoryLabel = (category) => { + return category === '' ? t('notes', 'Uncategorized') : category.replace(/\//g, ' / ') } diff --git a/src/components/AppSettings.vue b/src/components/AppSettings.vue index 74e9c003..d0318026 100644 --- a/src/components/AppSettings.vue +++ b/src/components/AppSettings.vue @@ -31,7 +31,8 @@ import { AppNavigationSettings, } from '@nextcloud/vue' -import NotesService from '../NotesService' + +import { setSettings } from '../NotesService' import store from '../store' export default { @@ -60,10 +61,10 @@ export default { methods: { onChangeSettings() { this.saving = true - return NotesService.setSettings(this.settings) + return setSettings(this.settings) .catch(() => { }) - .finally(() => { + .then(() => { this.saving = false }) }, diff --git a/src/components/NavigationCategoriesItem.vue b/src/components/NavigationCategoriesItem.vue index c40cd1aa..013a3aa2 100644 --- a/src/components/NavigationCategoriesItem.vue +++ b/src/components/NavigationCategoriesItem.vue @@ -38,7 +38,9 @@ import { AppNavigationItem, AppNavigationCounter, } from '@nextcloud/vue' -import NotesService from '../NotesService' + +import { getCategories, categoryLabel } from '../NotesService' + import store from '../store' export default { @@ -68,17 +70,17 @@ export default { }, categories() { - return NotesService.getCategories(1, true) + return getCategories(1, true) }, title() { - return this.selectedCategory === null ? this.t('notes', 'Categories') : NotesService.categoryLabel(this.selectedCategory) + return this.selectedCategory === null ? this.t('notes', 'Categories') : categoryLabel(this.selectedCategory) }, }, methods: { categoryTitle(category) { - return NotesService.categoryLabel(category) + return categoryLabel(category) }, onToggleCategories() { diff --git a/src/components/NavigationList.vue b/src/components/NavigationList.vue index a9c4ec79..8ca9ff06 100644 --- a/src/components/NavigationList.vue +++ b/src/components/NavigationList.vue @@ -59,9 +59,10 @@ import { AppNavigationCaption, AppNavigationItem, } from '@nextcloud/vue' + +import { categoryLabel } from '../NotesService' import NavigationCategoriesItem from './NavigationCategoriesItem' import NavigationNoteItem from './NavigationNoteItem' -import NotesService from '../NotesService' import store from '../store' import { ObserveVisibility } from 'vue-observe-visibility' @@ -176,11 +177,11 @@ export default { }, categoryTitle(category) { - return NotesService.categoryLabel(category) + return categoryLabel(category) }, categoryToLabel(category) { - return NotesService.categoryLabel(category.substring(this.category.length + 1)) + return categoryLabel(category.substring(this.category.length + 1)) }, getTimeslotFromNote(note) { diff --git a/src/components/NavigationNoteItem.vue b/src/components/NavigationNoteItem.vue index 691ce9a8..e8e7858e 100644 --- a/src/components/NavigationNoteItem.vue +++ b/src/components/NavigationNoteItem.vue @@ -27,7 +27,8 @@ import { ActionButton, AppNavigationItem, } from '@nextcloud/vue' -import NotesService from '../NotesService' + +import { categoryLabel, setFavorite, prepareDeleteNote, undoDeleteNote, deleteNote } from '../NotesService' export default { name: 'NavigationNoteItem', @@ -91,7 +92,7 @@ export default { }, actionCategoryText() { - return NotesService.categoryLabel(this.note.category) + return categoryLabel(this.note.category) }, actionDeleteIcon() { @@ -102,10 +103,10 @@ export default { methods: { onToggleFavorite() { this.loading.favorite = true - NotesService.setFavorite(this.note.id, !this.note.favorite) + setFavorite(this.note.id, !this.note.favorite) .catch(() => { }) - .finally(() => { + .then(() => { this.loading.favorite = false this.actionsOpen = false }) @@ -118,24 +119,24 @@ export default { onDeleteNote() { this.actionsOpen = false - NotesService.prepareDeleteNote(this.note.id) + prepareDeleteNote(this.note.id) this.undoTimer = setTimeout(this.onDeleteNoteFinally, 7000) this.$emit('note-deleted') }, onUndoDeleteNote() { clearTimeout(this.undoTimer) - NotesService.undoDeleteNote(this.note.id) + undoDeleteNote(this.note.id) }, onDeleteNoteFinally() { this.loading.delete = true - NotesService.deleteNote(this.note.id) + deleteNote(this.note.id) .then(() => { }) .catch(() => { }) - .finally(() => { + .then(() => { this.loading.delete = false }) }, diff --git a/src/components/Note.vue b/src/components/Note.vue index 49d2bf3f..cab58fee 100644 --- a/src/components/Note.vue +++ b/src/components/Note.vue @@ -57,11 +57,12 @@ import { AppContent, Tooltip, } from '@nextcloud/vue' + +import { fetchNote, saveNote, saveNoteManually } from '../NotesService' +import { closeNavbar } from '../nextcloud' import TheEditor from './EditorEasyMDE' import ThePreview from './EditorMarkdownIt' -import NotesService from '../NotesService' import store from '../store' -import { closeNavbar } from '../nextcloud' export default { name: 'Note', @@ -137,7 +138,7 @@ export default { this.onUpdateTitle(this.title) this.loading = true this.preview = false - NotesService.fetchNote(this.noteId) + fetchNote(this.noteId) .then((note) => { if (note.errorMessage) { OC.Notification.showTemporary(note.errorMessage) @@ -146,7 +147,7 @@ export default { .catch(() => { // note not found }) - .finally(() => { + .then(() => { this.loading = false }) }, @@ -213,7 +214,7 @@ export default { unsaved: true, } store.commit('add', note) - setTimeout(NotesService.saveNote.bind(NotesService, note.id), 1000) + setTimeout(saveNote.bind(this, note.id), 1000) } }, @@ -229,7 +230,7 @@ export default { }, onManualSave() { - NotesService.saveNoteManually(this.note.id) + saveNoteManually(this.note.id) }, }, } diff --git a/src/components/Sidebar.vue b/src/components/Sidebar.vue index 028e2db6..906b5b32 100644 --- a/src/components/Sidebar.vue +++ b/src/components/Sidebar.vue @@ -59,7 +59,8 @@ import { Multiselect, Tooltip, } from '@nextcloud/vue' -import NotesService from '../NotesService' + +import { categoryLabel, getCategories, setFavorite, setCategory, saveNoteManually } from '../NotesService' import store from '../store' export default { @@ -77,7 +78,7 @@ export default { filters: { categoryOptionLabel: function(obj) { const category = obj.isTag ? obj.label : obj - return NotesService.categoryLabel(category) + return categoryLabel(category) }, }, @@ -128,7 +129,7 @@ export default { return t('notes', 'You can create subcategories by using “/” as delimiter between parent category and subcategory, e.g. “{parent}/{sub}”.', { parent: t('notes', 'Category'), sub: t('notes', 'Subcategory') }) }, categories() { - return [ '', ...NotesService.getCategories(0, false) ] + return [ '', ...getCategories(0, false) ] }, sidebarOpen() { return store.state.sidebarOpen @@ -152,10 +153,10 @@ export default { onSetFavorite(favorite) { this.loading.favorite = true - NotesService.setFavorite(this.note.id, favorite) + setFavorite(this.note.id, favorite) .catch(() => { }) - .finally(() => { + .then(() => { this.loading.favorite = false }) }, @@ -165,17 +166,17 @@ export default { if (category !== null && this.note.category !== category) { this.loading.category = true this.note.category = category - NotesService.setCategory(this.note.id, category) + setCategory(this.note.id, category) .catch(() => { }) - .finally(() => { + .then(() => { this.loading.category = false }) } }, onManualSave() { - NotesService.saveNoteManually(this.note.id) + saveNoteManually(this.note.id) }, }, diff --git a/src/main.js b/src/main.js index 9c780398..1fbe1855 100644 --- a/src/main.js +++ b/src/main.js @@ -1,5 +1,3 @@ -import '@babel/polyfill' - import Vue from 'vue' import App from './App' import router from './router' diff --git a/templates/main.php b/templates/main.php index cc25ea62..248c485c 100644 --- a/templates/main.php +++ b/templates/main.php @@ -2,4 +2,3 @@ script('notes', 'notes'); style('notes', 'notes'); ?> -
diff --git a/.phan/config.php b/tests/phan-config.php similarity index 100% rename from .phan/config.php rename to tests/phan-config.php diff --git a/phpcs.xml b/tests/phpcs.xml similarity index 100% rename from phpcs.xml rename to tests/phpcs.xml diff --git a/webpack.common.js b/webpack.common.js index 571ad457..b8634f61 100644 --- a/webpack.common.js +++ b/webpack.common.js @@ -12,26 +12,27 @@ module.exports = { rules: [ { test: /\.css$/, - use: ['vue-style-loader', 'css-loader'] + use: ['vue-style-loader', 'css-loader'], }, { test: /\.scss$/, - use: ['vue-style-loader', 'css-loader', 'sass-loader'] + use: ['vue-style-loader', 'css-loader', 'sass-loader'], }, { test: /\.vue$/, - loader: 'vue-loader' + loader: 'vue-loader', }, { test: /\.js$/, loader: 'babel-loader', - exclude: /node_modules/ + exclude: /node_modules/, }, { test: /\.(png|jpg|gif|svg)$/, - loader: 'file-loader', + loader: 'url-loader', options: { - name: '[name].[ext]?[hash]' + name: '[name].[ext]?[hash]', + limit: 8192, } }, ], @@ -41,5 +42,6 @@ module.exports = { ], resolve: { extensions: ['*', '.js', '.vue', '.json'], + symlinks: false, }, }