Browse Source

refactoring maintenance

pull/470/head
korelstar 1 year ago
parent
commit
70e77ed35d
  1. 13
      .babelrc.js
  2. 2
      .eslintrc.js
  3. 17
      .scrutinizer.yml
  4. 9
      Makefile
  5. 4
      README.md
  6. 309
      package-lock.json
  7. 15
      package.json
  8. 17
      src/App.vue
  9. 412
      src/NotesService.js
  10. 7
      src/components/AppSettings.vue
  11. 10
      src/components/NavigationCategoriesItem.vue
  12. 7
      src/components/NavigationList.vue
  13. 17
      src/components/NavigationNoteItem.vue
  14. 13
      src/components/Note.vue
  15. 17
      src/components/Sidebar.vue
  16. 2
      src/main.js
  17. 1
      templates/main.php
  18. 0
      tests/phan-config.php
  19. 0
      tests/phpcs.xml
  20. 14
      webpack.common.js

13
.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 } ],
]
}

2
.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' }],
},
}

17
.scrutinizer.yml

@ -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

9
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:

4
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

309
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",

15
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"
}
}

17
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
})
},

412
src/NotesService.js

@ -2,214 +2,212 @@ import AppGlobal from './mixins/AppGlobal'
import store from './store'
import axios from '@nextcloud/axios'
export default {
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 => {
const t = AppGlobal.methods.t
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 => {
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 }))
}
return response.data
})
.catch(err => {
if (err.response.status === 404) {
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 => {
} else {
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, ' / ')
},
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, ' / ')
}

7
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
})
},

10
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() {

7
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) {

17
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
})
},

13
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<