diff --git a/package-lock.json b/package-lock.json index 9a1dc456e..ec9056f7d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,7 @@ "js-cookie": "^2.2.1", "js-sha256": "^0.9.0", "libphonenumber-js": "^1.10.44", + "pinia": "^2.1.7", "prismjs": "^1.24.1", "qrcode": "^1.5.1", "query-builder-vue": "^1.2.0", @@ -36,10 +37,9 @@ "vue-notion": "^3.0.0-beta.1", "vue-router": "^4.2.5", "vue-signature-pad": "^3.0.2", - "vue2-editor": "^2.10.3", + "vue3-editor": "^0.1.1", "vue3-vt-notifications": "^1.0.0", - "vuedraggable": "^4.1.0", - "vuex": "^4.1.0" + "vuedraggable": "^4.1.0" }, "devDependencies": { "@babel/core": "^7.20.12", @@ -104,12 +104,12 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", - "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", "dev": true, "dependencies": { - "@babel/highlight": "^7.22.13", + "@babel/highlight": "^7.23.4", "chalk": "^2.4.2" }, "engines": { @@ -117,30 +117,30 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.3.tgz", - "integrity": "sha512-BmR4bWbDIoFJmJ9z2cZ8Gmm2MXgEDgjdWgpKmKWUt54UGFJdlj31ECtbaDvCG/qVdG3AQ1SfpZEs01lUFbzLOQ==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", + "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.3.tgz", - "integrity": "sha512-Jg+msLuNuCJDyBvFv5+OKOUjWMZgd85bKjbICd3zWrKAo+bJ49HJufi7CQE0q0uR8NGyO6xkCACScNqyjHSZew==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.5.tgz", + "integrity": "sha512-Cwc2XjUrG4ilcfOw4wBAK+enbdgwAcAJCfGUItPBKR7Mjw4aEfAFYrLxeRp4jWgtNIKn3n2AlBOfwwafl+42/g==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.23.3", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.5", "@babel/helper-compilation-targets": "^7.22.15", "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.23.2", - "@babel/parser": "^7.23.3", + "@babel/helpers": "^7.23.5", + "@babel/parser": "^7.23.5", "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.3", - "@babel/types": "^7.23.3", + "@babel/traverse": "^7.23.5", + "@babel/types": "^7.23.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -174,12 +174,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.3.tgz", - "integrity": "sha512-keeZWAV4LU3tW0qRi19HRpabC/ilM0HRBBzf9/k8FFiG4KVpiv0FIy4hHfLfFQZNhziCTPTmd59zoyv6DNISzg==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.5.tgz", + "integrity": "sha512-BPssCHrBD+0YrxviOa3QzpqwhNIXKEtOa2jQrm4FlmkC2apYgRnQcmPWiGZDlGxiNtltnUFolMe8497Esry+jA==", "dev": true, "dependencies": { - "@babel/types": "^7.23.3", + "@babel/types": "^7.23.5", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -229,17 +229,17 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.15.tgz", - "integrity": "sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.23.5.tgz", + "integrity": "sha512-QELlRWxSpgdwdJzSJn4WAhKC+hvw/AtHbbrIoncKHkhKKR/luAlKkgBDcri1EzWAo8f8VvYVryEHN4tax/V67A==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", - "@babel/helper-member-expression-to-functions": "^7.22.15", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-member-expression-to-functions": "^7.23.0", "@babel/helper-optimise-call-expression": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.9", + "@babel/helper-replace-supers": "^7.22.20", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", "semver": "^6.3.1" @@ -453,9 +453,9 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", - "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", "dev": true, "engines": { "node": ">=6.9.0" @@ -471,9 +471,9 @@ } }, "node_modules/@babel/helper-validator-option": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz", - "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", + "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", "dev": true, "engines": { "node": ">=6.9.0" @@ -494,23 +494,23 @@ } }, "node_modules/@babel/helpers": { - "version": "7.23.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.2.tgz", - "integrity": "sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.5.tgz", + "integrity": "sha512-oO7us8FzTEsG3U6ag9MfdF1iA/7Z6dz+MtFhifZk8C8o453rGJFFWUP1t+ULM9TUIAzC9uxXEiXjOiVMyd7QPg==", "dev": true, "dependencies": { "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.2", - "@babel/types": "^7.23.0" + "@babel/traverse": "^7.23.5", + "@babel/types": "^7.23.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", - "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.22.20", @@ -522,9 +522,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.3.tgz", - "integrity": "sha512-uVsWNvlVsIninV2prNz/3lHCb+5CJ+e+IUBfbjToAHODtfGYLfCFuY4AU7TskI+dAKk+njsPiBjq1gKTvZOBaw==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.5.tgz", + "integrity": "sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ==", "bin": { "parser": "bin/babel-parser.js" }, @@ -843,9 +843,9 @@ } }, "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.3.tgz", - "integrity": "sha512-59GsVNavGxAXCDDbakWSMJhajASb4kBCqDjqJsv+p5nKdbz7istmZ3HrX3L2LuiI80+zsOADCvooqQH3qGCucQ==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.4.tgz", + "integrity": "sha512-efdkfPhHYTtn0G6n2ddrESE91fgXxjlqLsnUtPWnJs4a4mZIbUaK7ffqKIIUKXSHwcDvaCVX6GXkaJJFqtX7jw==", "dev": true, "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", @@ -893,9 +893,9 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.3.tgz", - "integrity": "sha512-QPZxHrThbQia7UdvfpaRRlq/J9ciz1J4go0k+lPBXbgaNeY7IQrBj/9ceWjvMMI07/ZBzHl/F0R/2K0qH7jCVw==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.4.tgz", + "integrity": "sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" @@ -924,9 +924,9 @@ } }, "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.23.3.tgz", - "integrity": "sha512-PENDVxdr7ZxKPyi5Ffc0LjXdnJyrJxyqF5T5YjlVg4a0VFfQHW0r8iAtRiDXkfHlu1wwcvdtnndGYIeJLSuRMQ==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.23.4.tgz", + "integrity": "sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ==", "dev": true, "dependencies": { "@babel/helper-create-class-features-plugin": "^7.22.15", @@ -941,9 +941,9 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.3.tgz", - "integrity": "sha512-FGEQmugvAEu2QtgtU0uTASXevfLMFfBeVCIIdcQhn/uBQsMTjBajdnAtanQlOcuihWh10PZ7+HWvc7NtBwP74w==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.5.tgz", + "integrity": "sha512-jvOTR4nicqYC9yzOHIhXG5emiFEOpappSJAl73SDSEDcybD+Puuze8Tnpb9p9qEyYup24tq891gkaygIFvWDqg==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", @@ -1026,9 +1026,9 @@ } }, "node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.23.3.tgz", - "integrity": "sha512-vTG+cTGxPFou12Rj7ll+eD5yWeNl5/8xvQvF08y5Gv3v4mZQoyFf8/n9zg4q5vvCWt5jmgymfzMAldO7orBn7A==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.23.4.tgz", + "integrity": "sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", @@ -1058,9 +1058,9 @@ } }, "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.23.3.tgz", - "integrity": "sha512-yCLhW34wpJWRdTxxWtFZASJisihrfyMOTOQexhVzA78jlU+dH7Dw+zQgcPepQ5F3C6bAIiblZZ+qBggJdHiBAg==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.23.4.tgz", + "integrity": "sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", @@ -1106,9 +1106,9 @@ } }, "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.23.3.tgz", - "integrity": "sha512-H9Ej2OiISIZowZHaBwF0tsJOih1PftXJtE8EWqlEIwpc7LMTGq0rPOrywKLQ4nefzx8/HMR0D3JGXoMHYvhi0A==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.23.4.tgz", + "integrity": "sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", @@ -1137,9 +1137,9 @@ } }, "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.23.3.tgz", - "integrity": "sha512-+pD5ZbxofyOygEp+zZAfujY2ShNCXRpDRIPOiBmTO693hhyOEteZgl876Xs9SAHPQpcV0vz8LvA/T+w8AzyX8A==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.23.4.tgz", + "integrity": "sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", @@ -1266,9 +1266,9 @@ } }, "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.23.3.tgz", - "integrity": "sha512-xzg24Lnld4DYIdysyf07zJ1P+iIfJpxtVFOzX4g+bsJ3Ng5Le7rXx9KwqKzuyaUeRnt+I1EICwQITqc0E2PmpA==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.23.4.tgz", + "integrity": "sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", @@ -1282,9 +1282,9 @@ } }, "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.23.3.tgz", - "integrity": "sha512-s9GO7fIBi/BLsZ0v3Rftr6Oe4t0ctJ8h4CCXfPoEJwmvAPMyNrfkOOJzm6b9PX9YXcCJWWQd/sBF/N26eBiMVw==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.23.4.tgz", + "integrity": "sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", @@ -1298,9 +1298,9 @@ } }, "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.23.3.tgz", - "integrity": "sha512-VxHt0ANkDmu8TANdE9Kc0rndo/ccsmfe2Cx2y5sI4hu3AukHQ5wAu4cM7j3ba8B9548ijVyclBU+nuDQftZsog==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.23.4.tgz", + "integrity": "sha512-9x9K1YyeQVw0iOXJlIzwm8ltobIIv7j2iLyP2jIhEbqPRQ7ScNgwQufU2I0Gq11VjyG4gI4yMXt2VFags+1N3g==", "dev": true, "dependencies": { "@babel/compat-data": "^7.23.3", @@ -1333,9 +1333,9 @@ } }, "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.23.3.tgz", - "integrity": "sha512-LxYSb0iLjUamfm7f1D7GpiS4j0UAC8AOiehnsGAP8BEsIX8EOi3qV6bbctw8M7ZvLtcoZfZX5Z7rN9PlWk0m5A==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.23.4.tgz", + "integrity": "sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", @@ -1349,9 +1349,9 @@ } }, "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.3.tgz", - "integrity": "sha512-zvL8vIfIUgMccIAK1lxjvNv572JHFJIKb4MWBz5OGdBQA0fB0Xluix5rmOby48exiJc987neOmP/m9Fnpkz3Tg==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.4.tgz", + "integrity": "sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", @@ -1397,9 +1397,9 @@ } }, "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.23.3.tgz", - "integrity": "sha512-a5m2oLNFyje2e/rGKjVfAELTVI5mbA0FeZpBnkOWWV7eSmKQ+T/XW0Vf+29ScLzSxX+rnsarvU0oie/4m6hkxA==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.23.4.tgz", + "integrity": "sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", @@ -1600,15 +1600,15 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.3.tgz", - "integrity": "sha512-ovzGc2uuyNfNAs/jyjIGxS8arOHS5FENZaNn4rtE7UdKMMkqHCvboHfcuhWLZNX5cB44QfcGNWjaevxMzzMf+Q==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.5.tgz", + "integrity": "sha512-0d/uxVD6tFGWXGDSfyMD1p2otoaKmu6+GD+NfAx0tMaH+dxORnp7T9TaVQ6mKyya7iBtCIVxHjWT7MuzzM9z+A==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.23.3", + "@babel/compat-data": "^7.23.5", "@babel/helper-compilation-targets": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-option": "^7.22.15", + "@babel/helper-validator-option": "^7.23.5", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.23.3", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.23.3", "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.23.3", @@ -1632,25 +1632,25 @@ "@babel/plugin-syntax-top-level-await": "^7.14.5", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.23.3", - "@babel/plugin-transform-async-generator-functions": "^7.23.3", + "@babel/plugin-transform-async-generator-functions": "^7.23.4", "@babel/plugin-transform-async-to-generator": "^7.23.3", "@babel/plugin-transform-block-scoped-functions": "^7.23.3", - "@babel/plugin-transform-block-scoping": "^7.23.3", + "@babel/plugin-transform-block-scoping": "^7.23.4", "@babel/plugin-transform-class-properties": "^7.23.3", - "@babel/plugin-transform-class-static-block": "^7.23.3", - "@babel/plugin-transform-classes": "^7.23.3", + "@babel/plugin-transform-class-static-block": "^7.23.4", + "@babel/plugin-transform-classes": "^7.23.5", "@babel/plugin-transform-computed-properties": "^7.23.3", "@babel/plugin-transform-destructuring": "^7.23.3", "@babel/plugin-transform-dotall-regex": "^7.23.3", "@babel/plugin-transform-duplicate-keys": "^7.23.3", - "@babel/plugin-transform-dynamic-import": "^7.23.3", + "@babel/plugin-transform-dynamic-import": "^7.23.4", "@babel/plugin-transform-exponentiation-operator": "^7.23.3", - "@babel/plugin-transform-export-namespace-from": "^7.23.3", + "@babel/plugin-transform-export-namespace-from": "^7.23.4", "@babel/plugin-transform-for-of": "^7.23.3", "@babel/plugin-transform-function-name": "^7.23.3", - "@babel/plugin-transform-json-strings": "^7.23.3", + "@babel/plugin-transform-json-strings": "^7.23.4", "@babel/plugin-transform-literals": "^7.23.3", - "@babel/plugin-transform-logical-assignment-operators": "^7.23.3", + "@babel/plugin-transform-logical-assignment-operators": "^7.23.4", "@babel/plugin-transform-member-expression-literals": "^7.23.3", "@babel/plugin-transform-modules-amd": "^7.23.3", "@babel/plugin-transform-modules-commonjs": "^7.23.3", @@ -1658,15 +1658,15 @@ "@babel/plugin-transform-modules-umd": "^7.23.3", "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", "@babel/plugin-transform-new-target": "^7.23.3", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.23.3", - "@babel/plugin-transform-numeric-separator": "^7.23.3", - "@babel/plugin-transform-object-rest-spread": "^7.23.3", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.23.4", + "@babel/plugin-transform-numeric-separator": "^7.23.4", + "@babel/plugin-transform-object-rest-spread": "^7.23.4", "@babel/plugin-transform-object-super": "^7.23.3", - "@babel/plugin-transform-optional-catch-binding": "^7.23.3", - "@babel/plugin-transform-optional-chaining": "^7.23.3", + "@babel/plugin-transform-optional-catch-binding": "^7.23.4", + "@babel/plugin-transform-optional-chaining": "^7.23.4", "@babel/plugin-transform-parameters": "^7.23.3", "@babel/plugin-transform-private-methods": "^7.23.3", - "@babel/plugin-transform-private-property-in-object": "^7.23.3", + "@babel/plugin-transform-private-property-in-object": "^7.23.4", "@babel/plugin-transform-property-literals": "^7.23.3", "@babel/plugin-transform-regenerator": "^7.23.3", "@babel/plugin-transform-reserved-words": "^7.23.3", @@ -1714,9 +1714,9 @@ "dev": true }, "node_modules/@babel/runtime": { - "version": "7.23.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.2.tgz", - "integrity": "sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.5.tgz", + "integrity": "sha512-NdUTHcPe4C99WxPub+K9l9tK5/lV4UXIoaHSYgzco9BCyjKAAwzdBI+wWtYqHt7LJdbo74ZjRPJgzVweq1sz0w==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -1739,19 +1739,19 @@ } }, "node_modules/@babel/traverse": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.3.tgz", - "integrity": "sha512-+K0yF1/9yR0oHdE0StHuEj3uTPzwwbrLGfNOndVJVV2TqA5+j3oljJUb4nmB954FLGjNem976+B+eDuLIjesiQ==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.5.tgz", + "integrity": "sha512-czx7Xy5a6sapWWRx61m1Ke1Ra4vczu1mCTtJam5zRTBOonfdJ+S/B6HYmGYu3fJtr8GGET3si6IhgWVBhJ/m8w==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.23.3", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.5", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.3", - "@babel/types": "^7.23.3", + "@babel/parser": "^7.23.5", + "@babel/types": "^7.23.5", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -1760,12 +1760,12 @@ } }, "node_modules/@babel/types": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.3.tgz", - "integrity": "sha512-OZnvoH2l8PK5eUvEcUyCt/sXgr/h+UWpVuBbOljwcrAgUl6lpchoQ++PHGyQy1AtYnVA6CEq3y5xeEI10brpXw==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.5.tgz", + "integrity": "sha512-ON5kSOJwVO6xXVRTvOI0eOnWe7VdUcIpsovGo9U/Br4Ie4UVFQTboO2cYnDhAGU6Fp+UxSiT+pMft0SMHfuq6w==", "dev": true, "dependencies": { - "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-string-parser": "^7.23.4", "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" }, @@ -2330,14 +2330,14 @@ } }, "node_modules/@sentry-internal/tracing": { - "version": "7.80.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.80.0.tgz", - "integrity": "sha512-P1Ab9gamHLsbH9D82i1HY8xfq9dP8runvc4g50AAd6OXRKaJ45f2KGRZUmnMEVqBQ7YoPYp2LFMkrhNYbcZEoQ==", + "version": "7.84.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.84.0.tgz", + "integrity": "sha512-y9bGYA0OM6PEREfd+nk4UURZy29tpIw+7vQwpxWfEVs2fqq0/5TBFX/tKFb8AKUI9lVM8v0bcF0bNSCnuPQZHQ==", "dev": true, "dependencies": { - "@sentry/core": "7.80.0", - "@sentry/types": "7.80.0", - "@sentry/utils": "7.80.0" + "@sentry/core": "7.84.0", + "@sentry/types": "7.84.0", + "@sentry/utils": "7.84.0" }, "engines": { "node": ">=8" @@ -2393,12 +2393,12 @@ } }, "node_modules/@sentry/bundler-plugin-core": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/@sentry/bundler-plugin-core/-/bundler-plugin-core-2.10.0.tgz", - "integrity": "sha512-bjcYvMrCQgqTiRRkWGNpeZ7EJOu0JQFYj+rrcQpwaVO+ll1eWNGW1nNveU+8vpnXrlaIAvieBxCrcCj5V9y1+Q==", + "version": "2.10.2", + "resolved": "https://registry.npmjs.org/@sentry/bundler-plugin-core/-/bundler-plugin-core-2.10.2.tgz", + "integrity": "sha512-7IoekLtROlJZqTxtHQ3IhocBuf9dsEq+JjqlHMyZXoq+QKuvJFvMd/4T+r6KjZ15kMZOIkR+spK3V7duH201hw==", "dev": true, "dependencies": { - "@sentry/cli": "^2.21.2", + "@sentry/cli": "^2.22.3", "@sentry/node": "^7.60.0", "@sentry/utils": "^7.60.0", "dotenv": "^16.3.1", @@ -2412,11 +2412,10 @@ } }, "node_modules/@sentry/cli": { - "version": "2.21.3", - "resolved": "https://registry.npmjs.org/@sentry/cli/-/cli-2.21.3.tgz", - "integrity": "sha512-gv8SNaMVNggiE/+6fPxEj8+y5uj9PqAQ8QS277aZ/HSXFgoidnNecE4QGHh4n+AkT0qCSQ/byxZsojVXkwkC7g==", + "version": "2.22.3", + "resolved": "https://registry.npmjs.org/@sentry/cli/-/cli-2.22.3.tgz", + "integrity": "sha512-VFHdtrHsMyTRSZhDLeMyXvit7xB4e81KugIEwMve95c7h5HO672bfmCcM/403CAugj4NzvQ+IR2NKF/2SsEPlg==", "dev": true, - "hasInstallScript": true, "dependencies": { "https-proxy-agent": "^5.0.0", "node-fetch": "^2.6.7", @@ -2429,15 +2428,139 @@ }, "engines": { "node": ">= 10" + }, + "optionalDependencies": { + "@sentry/cli-darwin": "2.22.3", + "@sentry/cli-linux-arm": "2.22.3", + "@sentry/cli-linux-arm64": "2.22.3", + "@sentry/cli-linux-i686": "2.22.3", + "@sentry/cli-linux-x64": "2.22.3", + "@sentry/cli-win32-i686": "2.22.3", + "@sentry/cli-win32-x64": "2.22.3" + } + }, + "node_modules/@sentry/cli-darwin": { + "version": "2.22.3", + "resolved": "https://registry.npmjs.org/@sentry/cli-darwin/-/cli-darwin-2.22.3.tgz", + "integrity": "sha512-A1DwFTffg3+fF68qujaJI07dk/1H1pRuihlvS5WQ9sD7nQLnXZGoLUht4eULixhDzZYinWHKkcWzQ6k40UTvNA==", + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@sentry/cli-linux-arm": { + "version": "2.22.3", + "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm/-/cli-linux-arm-2.22.3.tgz", + "integrity": "sha512-mDtLVbqbCu/5b/v2quTAMzY/atGlJVvrqO2Wvpro0Jb/LYhn7Y1pVBdoXEDcnOX82/pseFkLT8PFfq/OcezPhA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux", + "freebsd" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@sentry/cli-linux-arm64": { + "version": "2.22.3", + "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm64/-/cli-linux-arm64-2.22.3.tgz", + "integrity": "sha512-PnBPb4LJ+A2LlqLjtVFn4mEizcVdxBSLZvB85pEGzq9DRXjZ6ZEuGWFHTVnWvjd79TB/s0me29QnLc3n4B6lgA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux", + "freebsd" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@sentry/cli-linux-i686": { + "version": "2.22.3", + "resolved": "https://registry.npmjs.org/@sentry/cli-linux-i686/-/cli-linux-i686-2.22.3.tgz", + "integrity": "sha512-wxvbpQ2hiw4hwJWfJMp7K45BV40nXL62f91jLuftFXIbieKX1Li57NNKNu2JUVn7W1bJxkwz/PKGGTXSgeJlRw==", + "cpu": [ + "x86", + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux", + "freebsd" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@sentry/cli-linux-x64": { + "version": "2.22.3", + "resolved": "https://registry.npmjs.org/@sentry/cli-linux-x64/-/cli-linux-x64-2.22.3.tgz", + "integrity": "sha512-0GxsYNO5GyRWifeOpng+MmdUFZRA64bgA1n1prsEsXnoeLcm3Zj4Q63hBZmiwz9Qbhf5ibohkpf94a7dI7pv3A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux", + "freebsd" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@sentry/cli-win32-i686": { + "version": "2.22.3", + "resolved": "https://registry.npmjs.org/@sentry/cli-win32-i686/-/cli-win32-i686-2.22.3.tgz", + "integrity": "sha512-YERPsd7ClBrxKcmCUw+ZrAvQfbyIZFrqh269hgDuXFodpsB7LPGnI33ilo0uzmKdq2vGppTb6Z3gf1Rbq0Hadg==", + "cpu": [ + "x86", + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@sentry/cli-win32-x64": { + "version": "2.22.3", + "resolved": "https://registry.npmjs.org/@sentry/cli-win32-x64/-/cli-win32-x64-2.22.3.tgz", + "integrity": "sha512-NUh56xWvgJo2KuC9lI6o6nTPXdzbpQUB4qGwJ73L9NP3HT2P1I27jtHyrC2zlXTVlYE23gQZGrL3wgW4Jy80QA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" } }, "node_modules/@sentry/core": { - "version": "7.80.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.80.0.tgz", - "integrity": "sha512-nJiiymdTSEyI035/rdD3VOq6FlOZ2wWLR5bit9LK8a3rzHU3UXkwScvEo6zYgs0Xp1sC0yu1S9+0BEiYkmi29A==", + "version": "7.84.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.84.0.tgz", + "integrity": "sha512-tbuwunbBx2kSex15IHCqHDnrMfIlqPc6w/76fwkGqokz3oh9GSEGlLICwmBWL8AypWimUg13IDtFpD0TJTriWA==", "dependencies": { - "@sentry/types": "7.80.0", - "@sentry/utils": "7.80.0" + "@sentry/types": "7.84.0", + "@sentry/utils": "7.84.0" }, "engines": { "node": ">=8" @@ -2477,13 +2600,13 @@ } }, "node_modules/@sentry/integrations": { - "version": "7.80.0", - "resolved": "https://registry.npmjs.org/@sentry/integrations/-/integrations-7.80.0.tgz", - "integrity": "sha512-9xI+jtqSBrAG/Y2f4OyeJhl6WZR3i0qCXRwqCZoCFCDgN4ZQORc4VBwaC3nW2s9jgfb13FC2FQToGOVrRnsetg==", + "version": "7.84.0", + "resolved": "https://registry.npmjs.org/@sentry/integrations/-/integrations-7.84.0.tgz", + "integrity": "sha512-aUu95BhnHSf/W/F4BvsFnf4x+piHiah5a180YTMqWcHMkJr7MnCWNIad9RJuHlcINSfyHtUr5+Z4Bajzqg60lw==", "dependencies": { - "@sentry/core": "7.80.0", - "@sentry/types": "7.80.0", - "@sentry/utils": "7.80.0", + "@sentry/core": "7.84.0", + "@sentry/types": "7.84.0", + "@sentry/utils": "7.84.0", "localforage": "^1.8.1" }, "engines": { @@ -2512,15 +2635,15 @@ } }, "node_modules/@sentry/node": { - "version": "7.80.0", - "resolved": "https://registry.npmjs.org/@sentry/node/-/node-7.80.0.tgz", - "integrity": "sha512-J35fqe8J5ac/17ZXT0ML3opYGTOclqYNE9Sybs1y9n6BqacHyzH8By72YrdI03F7JJDHwrcGw+/H8hGpkCwi0Q==", + "version": "7.84.0", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-7.84.0.tgz", + "integrity": "sha512-Xm3fIXT3TZOQi+6uQBavI8iOehD3PkY7v0y3hog0d4lQTH88vQK9BBsI+jZEq81Em+RG/u7vZNiFo6YMTnWF7Q==", "dev": true, "dependencies": { - "@sentry-internal/tracing": "7.80.0", - "@sentry/core": "7.80.0", - "@sentry/types": "7.80.0", - "@sentry/utils": "7.80.0", + "@sentry-internal/tracing": "7.84.0", + "@sentry/core": "7.84.0", + "@sentry/types": "7.84.0", + "@sentry/utils": "7.84.0", "https-proxy-agent": "^5.0.0" }, "engines": { @@ -2563,31 +2686,31 @@ } }, "node_modules/@sentry/types": { - "version": "7.80.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.80.0.tgz", - "integrity": "sha512-4bpMO+2jWiWLDa8zbTASWWNLWe6yhjfPsa7/6VH5y9x1NGtL8oRbqUsTgsvjF3nmeHEMkHQsC8NHPaQ/ibFmZQ==", + "version": "7.84.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.84.0.tgz", + "integrity": "sha512-VqGLIF3JOUrk7yIXjLXJvAORkZL1e3dDX0Q1okRehwyt/5CRE+mdUTeJZkBo9P9mBwgMyvtwklzOGGrzjb4eMA==", "engines": { "node": ">=8" } }, "node_modules/@sentry/utils": { - "version": "7.80.0", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.80.0.tgz", - "integrity": "sha512-XbBCEl6uLvE50ftKwrEo6XWdDaZXHXu+kkHXTPWQEcnbvfZKLuG9V0Hxtxxq3xQgyWmuF05OH1GcqYqiO+v5Yg==", + "version": "7.84.0", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.84.0.tgz", + "integrity": "sha512-qdUVuxnRBvaf05AU+28R+xYtZmi/Ymf8os3Njq9g4XuA+QEkZLbzmIpRK5W9Ja7vUtjOeg29Xgg43A8znde9LQ==", "dependencies": { - "@sentry/types": "7.80.0" + "@sentry/types": "7.84.0" }, "engines": { "node": ">=8" } }, "node_modules/@sentry/vite-plugin": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/@sentry/vite-plugin/-/vite-plugin-2.10.0.tgz", - "integrity": "sha512-jOJQnu3ox+HcD1HCul5LBy6YEhS0oVFjrFshoFD2PtHI5sMldbwNWrkkTXcknNy/0o4d5cAtdsEuVzEnbdd+Gg==", + "version": "2.10.2", + "resolved": "https://registry.npmjs.org/@sentry/vite-plugin/-/vite-plugin-2.10.2.tgz", + "integrity": "sha512-30uu0L8ZCpAKOxAXmtyqwL06sG8UEBXGY5mxUDITyQYDf8pKuiOEf5018KlEDjhYVypfMQH3jq5xXUUka+/ipg==", "dev": true, "dependencies": { - "@sentry/bundler-plugin-core": "2.10.0", + "@sentry/bundler-plugin-core": "2.10.2", "unplugin": "1.0.1" }, "engines": { @@ -2676,9 +2799,9 @@ } }, "node_modules/@types/eslint": { - "version": "8.44.7", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.7.tgz", - "integrity": "sha512-f5ORu2hcBbKei97U73mf+l9t4zTGl74IqZ0GQk4oVea/VS8tQZYkUveSYojk+frraAVYId0V2WC9O4PTNru2FQ==", + "version": "8.44.8", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.8.tgz", + "integrity": "sha512-4K8GavROwhrYl2QXDXm0Rv9epkA8GBFu0EI+XrrnnuCl7u8CWBRusX7fXJfanhZTDWSAL24gDI/UqXyUM0Injw==", "dev": true, "peer": true, "dependencies": { @@ -2705,9 +2828,9 @@ "peer": true }, "node_modules/@types/imagemin": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@types/imagemin/-/imagemin-8.0.4.tgz", - "integrity": "sha512-t7vady38h/FTQAxFe6gJvaTxjgi/uw54ZrDbqyKx3yOMPu3NQjQexCoLxBR03FRv0HcKJMV2MqGLeY7BuPl6/A==", + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/@types/imagemin/-/imagemin-8.0.5.tgz", + "integrity": "sha512-tah3dm+5sG+fEDAz6CrQ5evuEaPX9K6DF3E5a01MPOKhA2oGBoC+oA5EJzSugB905sN4DE19EDzldT2Cld2g6Q==", "dev": true, "dependencies": { "@types/node": "*" @@ -2763,9 +2886,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.9.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.9.0.tgz", - "integrity": "sha512-nekiGu2NDb1BcVofVcEKMIwzlx4NjHlcjhoxxKBNLtz15Y1z7MYf549DFvkHSId02Ax6kGwWntIBPC3l/JZcmw==", + "version": "20.10.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.1.tgz", + "integrity": "sha512-T2qwhjWwGH81vUEx4EXmBKsTJRXFXNZTL4v0gi01+zyBmCwzE6TyHszqX01m+QHTEq+EZNo13NeJIdEqf+Myrg==", "dev": true, "dependencies": { "undici-types": "~5.26.4" @@ -2778,14 +2901,14 @@ "dev": true }, "node_modules/@types/sortablejs": { - "version": "1.15.5", - "resolved": "https://registry.npmjs.org/@types/sortablejs/-/sortablejs-1.15.5.tgz", - "integrity": "sha512-qqqbEFbB1EZt08I1Ok2BA3Sx0zlI8oizdIguMsajk4Yo/iHgXhCb3GM6N09JOJqT9xIMYM9LTFy8vit3RNY71Q==" + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/sortablejs/-/sortablejs-1.15.7.tgz", + "integrity": "sha512-PvgWCx1Lbgm88FdQ6S7OGvLIjWS66mudKPlfdrWil0TjsO5zmoZmzoKiiwRShs1dwPgrlkr0N4ewuy0/+QUXYQ==" }, "node_modules/@types/source-list-map": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.5.tgz", - "integrity": "sha512-cHBTLeIGIREJx839cDfMLKWao+FaJOlaPz4mnFHXUzShS8sXhzw6irhvIpYvp28TbTmTeAt3v+QgHMANsGbQtA==", + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.6.tgz", + "integrity": "sha512-5JcVt1u5HDmlXkwOD2nslZVllBBc7HDuOICfiZah2Z0is8M8g+ddAEawbmd3VjedfDHBzxCaXLs07QEmb7y54g==", "dev": true }, "node_modules/@types/svgo": { @@ -2799,9 +2922,9 @@ } }, "node_modules/@types/tapable": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.11.tgz", - "integrity": "sha512-R3ltemSqZ/TKOBeyy+GBfZCLX3AYpxqarIbUMNe7+lxdazJp4iWLFpmjgBeZoRiKrWNImer1oWOlG2sDR6vGaw==", + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.12.tgz", + "integrity": "sha512-bTHG8fcxEqv1M9+TD14P8ok8hjxoOCkfKc8XXLaaD05kI7ohpeI956jtDOD3XHKBQrlyPughUtzm1jtVhHpA5Q==", "dev": true }, "node_modules/@types/uglify-js": { @@ -2819,9 +2942,9 @@ "integrity": "sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==" }, "node_modules/@types/webpack": { - "version": "4.41.36", - "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.36.tgz", - "integrity": "sha512-pF+DVW1pMLmgsPXqJr5QimdxIzOhe8oGKB98gdqAm0egKBy1lOLD5mRxbYboMQRkpYcG7BYcpqYblpKyvE7vhQ==", + "version": "4.41.38", + "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.38.tgz", + "integrity": "sha512-oOW7E931XJU1mVfCnxCVgv8GLFL768pDO5u2Gzk82i8yTIgX6i7cntyZOkZYb/JtYM8252SN9bQp9tgkVDSsRw==", "dev": true, "dependencies": { "@types/node": "*", @@ -2853,62 +2976,62 @@ } }, "node_modules/@vitejs/plugin-vue": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.4.1.tgz", - "integrity": "sha512-HCQG8VDFDM7YDAdcj5QI5DvUi+r6xvo9LgvYdk7LSkUNwdpempdB5horkMSZsbdey9Ywsf5aaU8kEPw9M5kREA==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.5.1.tgz", + "integrity": "sha512-DaUzYFr+2UGDG7VSSdShKa9sIWYBa1LL8KC0MNOf2H5LjcTPjob0x8LbkqXWmAtbANJCkpiQTj66UVcQkN2s3g==", "dev": true, "engines": { "node": "^14.18.0 || >=16.0.0" }, "peerDependencies": { - "vite": "^4.0.0", + "vite": "^4.0.0 || ^5.0.0", "vue": "^3.2.25" } }, "node_modules/@vue/compat": { - "version": "3.3.8", - "resolved": "https://registry.npmjs.org/@vue/compat/-/compat-3.3.8.tgz", - "integrity": "sha512-ywp40WMF1DKZ4X/HbLPd5gHDyxDk/itDHp8JiSodvI9OyiA53HQS2hstLCh652HDue58gTQlo80HJwQCj+hYRw==", + "version": "3.3.9", + "resolved": "https://registry.npmjs.org/@vue/compat/-/compat-3.3.9.tgz", + "integrity": "sha512-Ut7sKNk9o/ApJCr4SppyMlUbwy+5n/CCcmJKCvnsoJSOe3WfX2/dBJYVZZQzJtB2e2XV7jRrya4aKRkOp5+KfQ==", "dependencies": { - "@babel/parser": "^7.23.0", + "@babel/parser": "^7.23.3", "estree-walker": "^2.0.2", "source-map-js": "^1.0.2" }, "peerDependencies": { - "vue": "3.3.8" + "vue": "3.3.9" } }, "node_modules/@vue/compiler-core": { - "version": "3.3.8", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.3.8.tgz", - "integrity": "sha512-hN/NNBUECw8SusQvDSqqcVv6gWq8L6iAktUR0UF3vGu2OhzRqcOiAno0FmBJWwxhYEXRlQJT5XnoKsVq1WZx4g==", + "version": "3.3.9", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.3.9.tgz", + "integrity": "sha512-+/Lf68Vr/nFBA6ol4xOtJrW+BQWv3QWKfRwGSm70jtXwfhZNF4R/eRgyVJYoxFRhdCTk/F6g99BP0ffPgZihfQ==", "dependencies": { - "@babel/parser": "^7.23.0", - "@vue/shared": "3.3.8", + "@babel/parser": "^7.23.3", + "@vue/shared": "3.3.9", "estree-walker": "^2.0.2", "source-map-js": "^1.0.2" } }, "node_modules/@vue/compiler-dom": { - "version": "3.3.8", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.3.8.tgz", - "integrity": "sha512-+PPtv+p/nWDd0AvJu3w8HS0RIm/C6VGBIRe24b9hSyNWOAPEUosFZ5diwawwP8ip5sJ8n0Pe87TNNNHnvjs0FQ==", + "version": "3.3.9", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.3.9.tgz", + "integrity": "sha512-nfWubTtLXuT4iBeDSZ5J3m218MjOy42Vp2pmKVuBKo2/BLcrFUX8nCSr/bKRFiJ32R8qbdnnnBgRn9AdU5v0Sg==", "dependencies": { - "@vue/compiler-core": "3.3.8", - "@vue/shared": "3.3.8" + "@vue/compiler-core": "3.3.9", + "@vue/shared": "3.3.9" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.3.8", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.3.8.tgz", - "integrity": "sha512-WMzbUrlTjfYF8joyT84HfwwXo+8WPALuPxhy+BZ6R4Aafls+jDBnSz8PDz60uFhuqFbl3HxRfxvDzrUf3THwpA==", - "dependencies": { - "@babel/parser": "^7.23.0", - "@vue/compiler-core": "3.3.8", - "@vue/compiler-dom": "3.3.8", - "@vue/compiler-ssr": "3.3.8", - "@vue/reactivity-transform": "3.3.8", - "@vue/shared": "3.3.8", + "version": "3.3.9", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.3.9.tgz", + "integrity": "sha512-wy0CNc8z4ihoDzjASCOCsQuzW0A/HP27+0MDSSICMjVIFzk/rFViezkR3dzH+miS2NDEz8ywMdbjO5ylhOLI2A==", + "dependencies": { + "@babel/parser": "^7.23.3", + "@vue/compiler-core": "3.3.9", + "@vue/compiler-dom": "3.3.9", + "@vue/compiler-ssr": "3.3.9", + "@vue/reactivity-transform": "3.3.9", + "@vue/shared": "3.3.9", "estree-walker": "^2.0.2", "magic-string": "^0.30.5", "postcss": "^8.4.31", @@ -2927,12 +3050,12 @@ } }, "node_modules/@vue/compiler-ssr": { - "version": "3.3.8", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.3.8.tgz", - "integrity": "sha512-hXCqQL/15kMVDBuoBYpUnSYT8doDNwsjvm3jTefnXr+ytn294ySnT8NlsFHmTgKNjwpuFy7XVV8yTeLtNl/P6w==", + "version": "3.3.9", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.3.9.tgz", + "integrity": "sha512-NO5oobAw78R0G4SODY5A502MGnDNiDjf6qvhn7zD7TJGc8XDeIEw4fg6JU705jZ/YhuokBKz0A5a/FL/XZU73g==", "dependencies": { - "@vue/compiler-dom": "3.3.8", - "@vue/shared": "3.3.8" + "@vue/compiler-dom": "3.3.9", + "@vue/shared": "3.3.9" } }, "node_modules/@vue/component-compiler-utils": { @@ -2999,21 +3122,21 @@ "integrity": "sha512-+KpckaAQyfbvshdDW5xQylLni1asvNSGme1JFs8I1+/H5pHEhqUKMEQD/qn3Nx5+/nycBq11qAEi8lk+LXI2dA==" }, "node_modules/@vue/reactivity": { - "version": "3.3.8", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.3.8.tgz", - "integrity": "sha512-ctLWitmFBu6mtddPyOKpHg8+5ahouoTCRtmAHZAXmolDtuZXfjL2T3OJ6DL6ezBPQB1SmMnpzjiWjCiMYmpIuw==", + "version": "3.3.9", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.3.9.tgz", + "integrity": "sha512-VmpIqlNp+aYDg2X0xQhJqHx9YguOmz2UxuUJDckBdQCNkipJvfk9yA75woLWElCa0Jtyec3lAAt49GO0izsphw==", "dependencies": { - "@vue/shared": "3.3.8" + "@vue/shared": "3.3.9" } }, "node_modules/@vue/reactivity-transform": { - "version": "3.3.8", - "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.3.8.tgz", - "integrity": "sha512-49CvBzmZNtcHua0XJ7GdGifM8GOXoUMOX4dD40Y5DxI3R8OUhMlvf2nvgUAcPxaXiV5MQQ1Nwy09ADpnLQUqRw==", + "version": "3.3.9", + "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.3.9.tgz", + "integrity": "sha512-HnUFm7Ry6dFa4Lp63DAxTixUp8opMtQr6RxQCpDI1vlh12rkGIeYqMvJtK+IKyEfEOa2I9oCkD1mmsPdaGpdVg==", "dependencies": { - "@babel/parser": "^7.23.0", - "@vue/compiler-core": "3.3.8", - "@vue/shared": "3.3.8", + "@babel/parser": "^7.23.3", + "@vue/compiler-core": "3.3.9", + "@vue/shared": "3.3.9", "estree-walker": "^2.0.2", "magic-string": "^0.30.5" } @@ -3030,48 +3153,48 @@ } }, "node_modules/@vue/runtime-core": { - "version": "3.3.8", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.3.8.tgz", - "integrity": "sha512-qurzOlb6q26KWQ/8IShHkMDOuJkQnQcTIp1sdP4I9MbCf9FJeGVRXJFr2mF+6bXh/3Zjr9TDgURXrsCr9bfjUw==", + "version": "3.3.9", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.3.9.tgz", + "integrity": "sha512-xxaG9KvPm3GTRuM4ZyU8Tc+pMVzcu6eeoSRQJ9IE7NmCcClW6z4B3Ij6L4EDl80sxe/arTtQ6YmgiO4UZqRc+w==", "dependencies": { - "@vue/reactivity": "3.3.8", - "@vue/shared": "3.3.8" + "@vue/reactivity": "3.3.9", + "@vue/shared": "3.3.9" } }, "node_modules/@vue/runtime-dom": { - "version": "3.3.8", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.3.8.tgz", - "integrity": "sha512-Noy5yM5UIf9UeFoowBVgghyGGPIDPy1Qlqt0yVsUdAVbqI8eeMSsTqBtauaEoT2UFXUk5S64aWVNJN4MJ2vRdA==", + "version": "3.3.9", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.3.9.tgz", + "integrity": "sha512-e7LIfcxYSWbV6BK1wQv9qJyxprC75EvSqF/kQKe6bdZEDNValzeRXEVgiX7AHI6hZ59HA4h7WT5CGvm69vzJTQ==", "dependencies": { - "@vue/runtime-core": "3.3.8", - "@vue/shared": "3.3.8", + "@vue/runtime-core": "3.3.9", + "@vue/shared": "3.3.9", "csstype": "^3.1.2" } }, "node_modules/@vue/server-renderer": { - "version": "3.3.8", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.3.8.tgz", - "integrity": "sha512-zVCUw7RFskvPuNlPn/8xISbrf0zTWsTSdYTsUTN1ERGGZGVnRxM2QZ3x1OR32+vwkkCm0IW6HmJ49IsPm7ilLg==", + "version": "3.3.9", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.3.9.tgz", + "integrity": "sha512-w0zT/s5l3Oa3ZjtLW88eO4uV6AQFqU8X5GOgzq7SkQQu6vVr+8tfm+OI2kDBplS/W/XgCBuFXiPw6T5EdwXP0A==", "dependencies": { - "@vue/compiler-ssr": "3.3.8", - "@vue/shared": "3.3.8" + "@vue/compiler-ssr": "3.3.9", + "@vue/shared": "3.3.9" }, "peerDependencies": { - "vue": "3.3.8" + "vue": "3.3.9" } }, "node_modules/@vue/shared": { - "version": "3.3.8", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.3.8.tgz", - "integrity": "sha512-8PGwybFwM4x8pcfgqEQFy70NaQxASvOC5DJwLQfpArw1UDfUXrJkdxD3BhVTMS+0Lef/TU7YO0Jvr0jJY8T+mw==" + "version": "3.3.9", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.3.9.tgz", + "integrity": "sha512-ZE0VTIR0LmYgeyhurPTpy4KzKsuDyQbMSdM49eKkMnT5X4VfFBLysMzjIZhLEFQYjjOVVfbvUDHckwjDFiO2eA==" }, "node_modules/@vueuse/components": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/@vueuse/components/-/components-10.6.0.tgz", - "integrity": "sha512-vc9cmt3fd+wpMjhlq/wuXvEafSRY1XWlgzrxaExfVCRpWyLeqZ57hQ7rmcxbLkIbeaYqOO6Swc1OiT700hyR+A==", + "version": "10.6.1", + "resolved": "https://registry.npmjs.org/@vueuse/components/-/components-10.6.1.tgz", + "integrity": "sha512-Yx7h201xJG3V4+rY1wRAYy8EI9Q1r+gpwCJzgyZ0CWPyDWyZCxPXNjPhBJsXcSzJ1h1ph9tE5cVqEXHtEs6bjg==", "dependencies": { - "@vueuse/core": "10.6.0", - "@vueuse/shared": "10.6.0", + "@vueuse/core": "10.6.1", + "@vueuse/shared": "10.6.1", "vue-demi": ">=0.14.6" } }, @@ -3101,13 +3224,13 @@ } }, "node_modules/@vueuse/core": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.6.0.tgz", - "integrity": "sha512-+Yee+g9+9BEbvkyGdn4Bf4yZx9EfocAytpV2ZlrlP7xcz+qznLmZIDqDroTvc5vtMkWZicisgEv8dt3+jL+HQg==", + "version": "10.6.1", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.6.1.tgz", + "integrity": "sha512-Pc26IJbqgC9VG1u6VY/xrXXfxD33hnvxBnKrLlA2LJlyHII+BSrRoTPJgGYq7qZOu61itITFUnm6QbacwZ4H8Q==", "dependencies": { "@types/web-bluetooth": "^0.0.20", - "@vueuse/metadata": "10.6.0", - "@vueuse/shared": "10.6.0", + "@vueuse/metadata": "10.6.1", + "@vueuse/shared": "10.6.1", "vue-demi": ">=0.14.6" }, "funding": { @@ -3140,17 +3263,17 @@ } }, "node_modules/@vueuse/metadata": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.6.0.tgz", - "integrity": "sha512-mzKHkHoiK6xVz01VzQjM2l6ofUanEaofgEGPgDHcAzlvOTccPRTIdEuzneOUTYxgfm1vkDikS6rtrEw/NYlaTQ==", + "version": "10.6.1", + "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.6.1.tgz", + "integrity": "sha512-qhdwPI65Bgcj23e5lpGfQsxcy0bMjCAsUGoXkJ7DsoeDUdasbZ2DBa4dinFCOER3lF4gwUv+UD2AlA11zdzMFw==", "funding": { "url": "https://github.com/sponsors/antfu" } }, "node_modules/@vueuse/shared": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.6.0.tgz", - "integrity": "sha512-0t4MVE18sO+/4Gh0jfeOXBTjKeV4606N9kIrDOLPjFl8Rwnlodn+QC5A4LfJuysK7aOsTMjF3KnzNeueaI0xlQ==", + "version": "10.6.1", + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.6.1.tgz", + "integrity": "sha512-TECVDTIedFlL0NUfHWncf3zF9Gc4VfdxfQc8JFwoVZQmxpONhLxFrlm0eHQeidHj4rdTPL3KXJa0TZCk1wnc5Q==", "dependencies": { "vue-demi": ">=0.14.6" }, @@ -4583,9 +4706,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001561", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001561.tgz", - "integrity": "sha512-NTt0DNoKe958Q0BE0j0c1V9jbUzhBxHIEJy7asmGrpE0yG63KTV7PLHPnK2E1O9RsQrQ081I3NLuXGS6zht3cw==", + "version": "1.0.30001565", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001565.tgz", + "integrity": "sha512-xrE//a3O7TP0vaJ8ikzkD2c2NgcVUvsEe2IvFTntV4Yd1Z9FVzh+gW+enX96L0psrbaFMcVcH2l90xNuGDWc8w==", "dev": true, "funding": [ { @@ -4813,9 +4936,9 @@ } }, "node_modules/codemirror": { - "version": "5.65.15", - "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.15.tgz", - "integrity": "sha512-YC4EHbbwQeubZzxLl5G4nlbLc1T21QTrKGaOal/Pkm9dVDMZXMH7+ieSPEOZCtO9I68i8/oteJKOxzHC2zR+0g==" + "version": "5.65.16", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.16.tgz", + "integrity": "sha512-br21LjYmSlVL0vFCPWPfhzUCT34FM/pAdK7rRIZwa0rrtrIdotvP4Oh4GUHsu2E3IrQMCfRkL/fN3ytMNxVQvg==" }, "node_modules/collection-visit": { "version": "1.0.0", @@ -4855,10 +4978,13 @@ } }, "node_modules/component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", + "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/compose-function": { "version": "3.0.3", @@ -4940,9 +5066,9 @@ "hasInstallScript": true }, "node_modules/core-js-compat": { - "version": "3.33.2", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.33.2.tgz", - "integrity": "sha512-axfo+wxFVxnqf8RvxTzoAlzW4gRoacrHeoFlc9n0x50+7BEyZL/Rt3hicaED1/CEd7I6tPCPVUYcJwCMO5XUYw==", + "version": "3.33.3", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.33.3.tgz", + "integrity": "sha512-cNzGqFsh3Ot+529GIXacjTJ7kegdt5fPXxCBVS1G0iaZpuo/tBz399ymceLJveQhFFZ8qThHiP3fzuoQjKN2ow==", "dev": true, "dependencies": { "browserslist": "^4.22.1" @@ -5637,9 +5763,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.580", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.580.tgz", - "integrity": "sha512-T5q3pjQon853xxxHUq3ZP68ZpvJHuSMY2+BZaW3QzjS4HvNuvsMmZ/+lU+nCrftre1jFZ+OSlExynXWBihnXzw==", + "version": "1.4.600", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.600.tgz", + "integrity": "sha512-KD6CWjf1BnQG+NsXuyiTDDT1eV13sKuYsOUioXkQweYTQIbgHkXPry9K7M+7cKtYHnSUPitVaLrXYB1jTkkYrw==", "dev": true }, "node_modules/emoji-regex": { @@ -5778,9 +5904,9 @@ "dev": true }, "node_modules/es-module-lexer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.0.tgz", - "integrity": "sha512-lcCr3v3OLezdfFyx9r5NRYHOUTQNnFEQ9E87Mx8Kc+iqyJNkO7MJoB4GQRTlIMw9kLLTwGw0OAkm4BQQud/d9g==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", + "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==", "dev": true, "peer": true }, @@ -6136,9 +6262,9 @@ } }, "node_modules/eslint-plugin-node/node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", + "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", "dev": true, "engines": { "node": ">= 4" @@ -7064,9 +7190,9 @@ } }, "node_modules/flat-cache": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.1.tgz", - "integrity": "sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dev": true, "dependencies": { "flatted": "^3.2.9", @@ -7074,7 +7200,7 @@ "rimraf": "^3.0.2" }, "engines": { - "node": ">=12.0.0" + "node": "^10.12.0 || >=12.0.0" } }, "node_modules/flatted": { @@ -9019,9 +9145,9 @@ } }, "node_modules/libphonenumber-js": { - "version": "1.10.49", - "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.10.49.tgz", - "integrity": "sha512-gvLtyC3tIuqfPzjvYLH9BmVdqzGDiSi4VjtWe2fAgSdBf0yt8yPmbNnRIHNbR5IdtVkm0ayGuzwQKTWmU0hdjQ==" + "version": "1.10.51", + "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.10.51.tgz", + "integrity": "sha512-vY2I+rQwrDQzoPds0JeTEpeWzbUJgqoV0O4v31PauHBb/e+1KCXKylHcDnBMgJZ9fH9mErsEbROJY3Z3JtqEmg==" }, "node_modules/lie": { "version": "3.1.1", @@ -9562,9 +9688,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", - "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", "dev": true }, "node_modules/normalize-package-data": { @@ -9810,13 +9936,13 @@ } }, "node_modules/object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", "has-symbols": "^1.0.3", "object-keys": "^1.1.1" }, @@ -10172,9 +10298,9 @@ } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", - "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", + "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", "dev": true, "engines": { "node": "14 || >=16.14" @@ -10242,6 +10368,56 @@ "node": ">=6" } }, + "node_modules/pinia": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.1.7.tgz", + "integrity": "sha512-+C2AHFtcFqjPih0zpYuvof37SFxMQ7OEG2zV9jRI12i9BOy3YQVAHwdKtyyc8pDcDyIc33WCIsZaCFWU7WWxGQ==", + "dependencies": { + "@vue/devtools-api": "^6.5.0", + "vue-demi": ">=0.14.5" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "@vue/composition-api": "^1.4.0", + "typescript": ">=4.4.4", + "vue": "^2.6.14 || ^3.3.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/pinia/node_modules/vue-demi": { + "version": "0.14.6", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz", + "integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==", + "hasInstallScript": true, + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, "node_modules/pinkie": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", @@ -10457,21 +10633,27 @@ } }, "node_modules/postcss-load-config": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.1.tgz", - "integrity": "sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "dependencies": { - "lilconfig": "^2.0.5", - "yaml": "^2.1.1" + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" }, "engines": { "node": ">= 14" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, "peerDependencies": { "postcss": ">=8.0.9", "ts-node": ">=9.0.0" @@ -10485,6 +10667,15 @@ } } }, + "node_modules/postcss-load-config/node_modules/lilconfig": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.0.0.tgz", + "integrity": "sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==", + "dev": true, + "engines": { + "node": ">=14" + } + }, "node_modules/postcss-modules-extract-imports": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", @@ -10732,9 +10923,9 @@ } }, "node_modules/query-builder-vue/node_modules/core-js": { - "version": "3.33.2", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.33.2.tgz", - "integrity": "sha512-XeBzWI6QL3nJQiHmdzbAOiMYqjrb7hwU7A39Qhvd/POSa/t9E1AeZyEZx3fNvp/vtM8zXwhoL0FsiS0hD0pruQ==", + "version": "3.33.3", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.33.3.tgz", + "integrity": "sha512-lo0kOocUlLKmm6kv/FswQL8zbkH7mVsLJ/FULClOhv8WRVmKLVcs6XPNQAzstfeJTCHMyButEwG+z1kHxHoDZw==", "hasInstallScript": true, "funding": { "type": "opencollective", @@ -11998,9 +12189,9 @@ } }, "node_modules/sortablejs": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.15.0.tgz", - "integrity": "sha512-bv9qgVMjUMf89wAvM6AxVvS/4MX3sPeN0+agqShejLU5z5GX4C75ow1O2e5k4L6XItUyAK3gH6AxSbXrOM5e8w==" + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.15.1.tgz", + "integrity": "sha512-P5Cjvb0UG1ZVNiDPj/n4V+DinttXG6K8n7vM/HQf0C25K3YKQTQY6fsr/sEGsJGpQ9exmPxluHxKBc0mLKU1lQ==" }, "node_modules/source-list-map": { "version": "2.0.1", @@ -12464,15 +12655,16 @@ } }, "node_modules/svgo": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.0.3.tgz", - "integrity": "sha512-X4UZvLhOglD5Xrp834HzGHf8RKUW0Ahigg/08yRO1no9t2NxffOkMiQ0WmaMIbaGlVTlSst2zWANsdhz5ybXgA==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.0.5.tgz", + "integrity": "sha512-HQKHEo73pMNOlDlBcLgZRcHW2+1wo7bFYayAXkGN0l/2+h68KjlfZyMRhdhaGvoHV2eApOovl12zoFz42sT6rQ==", "dev": true, "dependencies": { "@trysound/sax": "0.2.0", "commander": "^7.2.0", "css-select": "^5.1.0", "css-tree": "^2.2.1", + "css-what": "^6.1.0", "csso": "5.0.5", "picocolors": "^1.0.0" }, @@ -13476,28 +13668,25 @@ } }, "node_modules/vite-plugin-full-reload": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/vite-plugin-full-reload/-/vite-plugin-full-reload-1.0.5.tgz", - "integrity": "sha512-kVZFDFWr0DxiHn6MuDVTQf7gnWIdETGlZh0hvTiMXzRN80vgF4PKbONSq8U1d0WtHsKaFODTQgJeakLacoPZEQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vite-plugin-full-reload/-/vite-plugin-full-reload-1.1.0.tgz", + "integrity": "sha512-3cObNDzX6DdfhD9E7kf6w2mNunFpD7drxyNgHLw+XwIYAgb+Xt16SEXo0Up4VH+TMf3n+DSVJZtW2POBGcBYAA==", "dev": true, "dependencies": { "picocolors": "^1.0.0", "picomatch": "^2.3.1" - }, - "peerDependencies": { - "vite": "^2 || ^3 || ^4" } }, "node_modules/vue": { - "version": "3.3.8", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.3.8.tgz", - "integrity": "sha512-5VSX/3DabBikOXMsxzlW8JyfeLKlG9mzqnWgLQLty88vdZL7ZJgrdgBOmrArwxiLtmS+lNNpPcBYqrhE6TQW5w==", + "version": "3.3.9", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.3.9.tgz", + "integrity": "sha512-sy5sLCTR8m6tvUk1/ijri3Yqzgpdsmxgj6n6yl7GXXCXqVbmW2RCXe9atE4cEI6Iv7L89v5f35fZRRr5dChP9w==", "dependencies": { - "@vue/compiler-dom": "3.3.8", - "@vue/compiler-sfc": "3.3.8", - "@vue/runtime-dom": "3.3.8", - "@vue/server-renderer": "3.3.8", - "@vue/shared": "3.3.8" + "@vue/compiler-dom": "3.3.9", + "@vue/compiler-sfc": "3.3.9", + "@vue/runtime-dom": "3.3.9", + "@vue/server-renderer": "3.3.9", + "@vue/shared": "3.3.9" }, "peerDependencies": { "typescript": "*" @@ -13697,12 +13886,26 @@ "integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==", "dev": true }, - "node_modules/vue2-editor": { - "version": "2.10.3", - "resolved": "https://registry.npmjs.org/vue2-editor/-/vue2-editor-2.10.3.tgz", - "integrity": "sha512-99rWL93xfGeFRrq8NY5L7U+Cog/Uenx+UOOJragtxtbhBE9Rv5/C3P/YhJhjMECSbQyHFjUriqv1S3mghvU9Kg==", + "node_modules/vue3-editor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/vue3-editor/-/vue3-editor-0.1.1.tgz", + "integrity": "sha512-rH1U28wi+mHQlJFr4mvMW3D0oILnjV/BY9TslzWc6zM5zwv48I8LQk4sVzggN2KTDIGAdlDsmdReAd+7fhMYmQ==", "dependencies": { - "quill": "^1.3.6" + "core-js": "^3.6.5", + "quill": "^1.3.7" + }, + "peerDependencies": { + "vue": "^3.0.0" + } + }, + "node_modules/vue3-editor/node_modules/core-js": { + "version": "3.33.3", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.33.3.tgz", + "integrity": "sha512-lo0kOocUlLKmm6kv/FswQL8zbkH7mVsLJ/FULClOhv8WRVmKLVcs6XPNQAzstfeJTCHMyButEwG+z1kHxHoDZw==", + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" } }, "node_modules/vue3-vt-notifications": { @@ -13729,17 +13932,6 @@ "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.14.0.tgz", "integrity": "sha512-pBXvQCs5/33fdN1/39pPL0NZF20LeRbLQ5jtnheIPN9JQAaufGjKdWduZn4U7wCtVuzKhmRkI0DFYHYRbB2H1w==" }, - "node_modules/vuex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/vuex/-/vuex-4.1.0.tgz", - "integrity": "sha512-hmV6UerDrPcgbSy9ORAtNXDr9M4wlNP4pEFKye4ujJF8oqgFFuxDCdOLS3eNoRTtq5O3hoBDh9Doj1bQMYHRbQ==", - "dependencies": { - "@vue/devtools-api": "^6.0.0-beta.11" - }, - "peerDependencies": { - "vue": "^3.2.0" - } - }, "node_modules/watchpack": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", diff --git a/package.json b/package.json index cf316bd52..be0bfae5e 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "js-cookie": "^2.2.1", "js-sha256": "^0.9.0", "libphonenumber-js": "^1.10.44", + "pinia": "^2.1.7", "prismjs": "^1.24.1", "qrcode": "^1.5.1", "query-builder-vue": "^1.2.0", @@ -38,8 +39,7 @@ "vue-signature-pad": "^3.0.2", "vue3-editor": "^0.1.1", "vue3-vt-notifications": "^1.0.0", - "vuedraggable": "^4.1.0", - "vuex": "^4.1.0" + "vuedraggable": "^4.1.0" }, "devDependencies": { "@babel/core": "^7.20.12", diff --git a/resources/js/app.js b/resources/js/app.js index 6ab82ac20..d935a7ac4 100644 --- a/resources/js/app.js +++ b/resources/js/app.js @@ -1,5 +1,5 @@ import { createApp, configureCompat, ref } from 'vue' -import store from '~/store' +import { createPinia } from 'pinia' import router from '~/router' import App from '~/components/App.vue' import Base from './base.js' @@ -11,9 +11,10 @@ import '~/components' import '../sass/app.scss' +const pinia = createPinia() const app = createApp(App) .use(router) - .use(store) + .use(pinia) .mixin(Base) registerPlugin(app) @@ -25,7 +26,9 @@ configureCompat({ // GLOBAL_MOUNT: false, COMPONENT_V_MODEL: false, INSTANCE_SET: false, - INSTANCE_DELETE: false + INSTANCE_DELETE: false, + ATTR_FALSE_VALUE: false, + WATCH_ARRAY: false }) router.app = app diff --git a/resources/js/components/App.vue b/resources/js/components/App.vue index d6f39cb47..c9fd48f20 100644 --- a/resources/js/components/App.vue +++ b/resources/js/components/App.vue @@ -37,6 +37,8 @@ </template> <script> +import { computed } from 'vue' +import { useAppStore } from '../stores/app' import Loading from './Loading.vue' import Hotjar from './service/Hotjar.vue' import Amplitude from './service/Amplitude.vue' @@ -44,7 +46,6 @@ import Crisp from './service/Crisp.vue' import StopImpersonation from './pages/StopImpersonation.vue' import Notifications from './common/Notifications.vue' import SeoMeta from '../mixins/seo-meta.js' -import { mapState } from 'vuex' // Load layout components dynamically. const requireContext = import.meta.glob('../layouts/**.vue', { eager: true }) @@ -74,6 +75,13 @@ export default { mixins: [SeoMeta], + setup () { + const appStore = useAppStore() + return { + layout : computed(() => appStore.layout) + } + }, + data: () => ({ metaTitle: 'OpnForm', metaDescription: 'Create beautiful forms for free. Unlimited fields, unlimited submissions. It\'s free and it takes less than 1 minute to create your first form.', @@ -95,9 +103,6 @@ export default { isOnboardingPage () { return this.$route.name === 'onboarding' }, - ...mapState({ - layout: state => state.app.layout - }), layoutComponent () { return layouts[this.layout] } diff --git a/resources/js/components/Loading.vue b/resources/js/components/Loading.vue index a7bc69870..672053da5 100644 --- a/resources/js/components/Loading.vue +++ b/resources/js/components/Loading.vue @@ -10,7 +10,8 @@ <script> // https://github.com/nuxt/nuxt.js/blob/master/lib/app/components/nuxt-loading.vue -import { mapState } from 'vuex' +import { computed } from 'vue' +import { useAppStore } from '../stores/app'; export default { data: () => ({ @@ -19,12 +20,13 @@ export default { failedColor: 'red' }), - computed: { - ...mapState({ - percent: state => state.app.loader.percent, - canSuccess: state => state.app.loader.canSuccess, - show: state => state.app.loader.show - }) + setup () { + const appStore = useAppStore() + return { + percent : computed(() => appStore.loader.percent), + canSuccess : computed(() => appStore.loader.canSuccess), + show : computed(() => appStore.loader.show) + } } } </script> diff --git a/resources/js/components/LoginWithGithub.vue b/resources/js/components/LoginWithGithub.vue index 5f9974b39..e505a244d 100644 --- a/resources/js/components/LoginWithGithub.vue +++ b/resources/js/components/LoginWithGithub.vue @@ -14,9 +14,18 @@ </template> <script> +import { useAuthStore } from '../stores/auth' + export default { name: 'LoginWithGithub', + setup () { + const authStore = useAuthStore() + return { + authStore + } + }, + computed: { githubAuth: () => window.config.githubAuth, url: () => '/api/oauth/github' @@ -34,9 +43,7 @@ export default { async login () { const newWindow = openWindow('', 'Login') - const url = await this.$store.dispatch('auth/fetchOauthUrl', { - provider: 'github' - }) + const url = await this.authStore.fetchOauthUrl('github') newWindow.location.href = url }, @@ -49,9 +56,7 @@ export default { return } - this.$store.dispatch('auth/saveToken', { - token: e.data.token - }) + this.authStore.saveToken(e.data.token) this.$router.push({ name: 'home' }) } diff --git a/resources/js/components/Navbar.vue b/resources/js/components/Navbar.vue index 47645c892..62036358c 100644 --- a/resources/js/components/Navbar.vue +++ b/resources/js/components/Navbar.vue @@ -132,7 +132,10 @@ </template> <script> -import { mapGetters } from 'vuex' +import { computed } from 'vue' +import { useAuthStore } from '../stores/auth'; +import { useFormsStore } from '../stores/forms'; +import { useWorkspacesStore } from '../stores/workspaces'; import Dropdown from './common/Dropdown.vue' import WorkspaceDropdown from './WorkspaceDropdown.vue' @@ -142,6 +145,18 @@ export default { Dropdown }, + setup () { + const authStore = useAuthStore() + const formsStore = useFormsStore() + const workspacesStore = useWorkspacesStore() + return { + authStore, + formsStore, + workspacesStore, + user : computed(() => authStore.user) + } + }, + data: () => ({ appName: window.config.appName }), @@ -151,12 +166,12 @@ export default { helpUrl: () => window.config.links.help_url, form () { if (this.$route.name && this.$route.name.startsWith('forms.show_public')) { - return this.$store.getters['open/forms/getBySlug'](this.$route.params.slug) + return this.formsStore.getBySlug(this.$route.params.slug) } return null }, workspace () { - return this.$store.getters['open/workspaces/getCurrent']() + return this.workspacesStore.getCurrent() }, paidPlansEnabled () { return window.config.paid_plans_enabled @@ -182,9 +197,6 @@ export default { isIframe () { return window.location !== window.parent.location || window.frameElement }, - ...mapGetters({ - user: 'auth/user' - }), userOnboarded () { return this.user && this.user.workspaces_count > 0 }, @@ -196,11 +208,11 @@ export default { methods: { async logout () { // Log out the user. - await this.$store.dispatch('auth/logout') + await this.authStore.logout() // Reset store - this.$store.dispatch('open/workspaces/resetState') - this.$store.dispatch('open/forms/resetState') + this.workspacesStore.resetState() + this.formsStore.resetState() // Redirect to login. this.$router.push({ name: 'login' }) diff --git a/resources/js/components/WorkspaceDropdown.vue b/resources/js/components/WorkspaceDropdown.vue index 96a4e052d..266ba6192 100644 --- a/resources/js/components/WorkspaceDropdown.vue +++ b/resources/js/components/WorkspaceDropdown.vue @@ -41,8 +41,11 @@ </template> <script> +import { computed } from 'vue' +import { useAuthStore } from '../stores/auth' +import { useFormsStore } from '../stores/forms' +import { useWorkspacesStore } from '../stores/workspaces' import Dropdown from './common/Dropdown.vue' -import { mapGetters, mapState } from 'vuex' export default { @@ -51,20 +54,26 @@ export default { Dropdown }, + setup () { + const authStore = useAuthStore() + const formsStore = useFormsStore() + const workspacesStore = useWorkspacesStore() + return { + formsStore, + workspacesStore, + user : computed(() => authStore.user), + workspaces : computed(() => workspacesStore.content), + loading : computed(() => workspacesStore.loading) + } + }, + data: () => ({ appName: window.config.appName }), computed: { - ...mapState({ - workspaces: state => state['open/workspaces'].content, - loading: state => state['open/workspaces'].loading - }), - ...mapGetters({ - user: 'auth/user' - }), workspace () { - return this.$store.getters['open/workspaces/getCurrent']() + return this.workspacesStore.getCurrent() } }, @@ -76,12 +85,12 @@ export default { methods: { switchWorkspace (workspace) { - this.$store.commit('open/workspaces/setCurrentId', workspace.id) + this.workspacesStore.setCurrentId(workspace.id) this.$refs.dropdown.close() if (this.$route.name !== 'home') { this.$router.push({ name: 'home' }) } - this.$store.dispatch('open/forms/load', workspace.id) + this.formsStore.load(workspace.id) }, isUrl (str) { try { diff --git a/resources/js/components/common/Breadcrumb.vue b/resources/js/components/common/Breadcrumb.vue index ee6d46b5a..782fda712 100644 --- a/resources/js/components/common/Breadcrumb.vue +++ b/resources/js/components/common/Breadcrumb.vue @@ -54,7 +54,8 @@ </template> <script> -import { mapGetters } from 'vuex' +import { computed } from 'vue' +import { useAuthStore } from '../../stores/auth'; export default { name: 'Breadcrumb', @@ -66,20 +67,22 @@ export default { path: { type: Array } }, + setup () { + const authStore = useAuthStore() + return { + authenticated : computed(() => authStore.check) + } + }, + data () { return { displayHome: true } }, - computed: { - ...mapGetters({ - authenticated: 'auth/check' - }) - }, + computed: {}, - mounted () { - }, + mounted () {}, methods: {} } diff --git a/resources/js/components/common/ProTag.vue b/resources/js/components/common/ProTag.vue index 1cc39eeb9..e5c16fd9e 100644 --- a/resources/js/components/common/ProTag.vue +++ b/resources/js/components/common/ProTag.vue @@ -37,8 +37,10 @@ </template> <script> +import { computed } from 'vue' import Modal from '../Modal.vue' -import {mapGetters} from 'vuex' +import { useAuthStore } from '../../stores/auth'; +import { useWorkspacesStore } from '../../stores/workspaces'; import PricingTable from "../pages/pricing/PricingTable.vue"; export default { @@ -46,6 +48,15 @@ export default { components: {PricingTable, Modal}, props: {}, + setup () { + const authStore = useAuthStore() + const workspacesStore = useWorkspacesStore() + return { + user : computed(() => authStore.user), + currentWorkSpace : computed(() => workspacesStore.getCurrent()) + } + }, + data() { return { showPremiumModal: false, @@ -54,10 +65,6 @@ export default { }, computed: { - ...mapGetters({ - user: 'auth/user', - currentWorkSpace: 'open/workspaces/getCurrent', - }), shouldDisplayProTag() { if (!window.config.paid_plans_enabled) return false if (!this.user || !this.currentWorkSpace) return true diff --git a/resources/js/components/forms/PhoneInput.vue b/resources/js/components/forms/PhoneInput.vue index ab84778c4..1d118ce45 100644 --- a/resources/js/components/forms/PhoneInput.vue +++ b/resources/js/components/forms/PhoneInput.vue @@ -11,7 +11,7 @@ :data="countries" :disabled="disabled || countries.length===1" :searchable="true" :search-keys="['name']" :option-key="'code'" :color="color" :has-error="hasValidation && form.errors.has(name)" - :placeholder="'Select a country'" :uppercase-labels="true" :theme="theme" @input="onChangeCountryCode" + :placeholder="'Select a country'" :uppercase-labels="true" :theme="theme" @update:model-value="onChangeCountryCode" > <template #option="props"> <div class="flex items-center space-x-2 hover:text-white"> @@ -29,7 +29,7 @@ </v-select> <input v-model="inputVal" type="text" class="inline-flex-grow !border-l-0 !rounded-l-none" :disabled="disabled" :class="[theme.default.input, { '!ring-red-500 !ring-2': hasValidation && form.errors.has(name), '!cursor-not-allowed !bg-gray-200': disabled }]" - :placeholder="placeholder" :style="inputStyle" @input="onInput" + :placeholder="placeholder" :style="inputStyle" @update:model-value="onInput" > </div> diff --git a/resources/js/components/forms/components/InputWrapper.vue b/resources/js/components/forms/components/InputWrapper.vue index d99cef580..c8703be35 100644 --- a/resources/js/components/forms/components/InputWrapper.vue +++ b/resources/js/components/forms/components/InputWrapper.vue @@ -22,7 +22,7 @@ </input-help> </slot> <slot name="error"> - <has-error v-if="hasValidation" :form="form" :field="name" /> + <has-error v-if="hasValidation && form" :form="form" :field="name" /> </slot> </div> </template> diff --git a/resources/js/components/open/components/RecordOperations.vue b/resources/js/components/open/components/RecordOperations.vue index 11de34940..972bff6af 100644 --- a/resources/js/components/open/components/RecordOperations.vue +++ b/resources/js/components/open/components/RecordOperations.vue @@ -16,8 +16,6 @@ </template> <script> -import { mapState } from 'vuex' -import store from '~/store' import axios from 'axios' export default { diff --git a/resources/js/components/open/forms/OpenForm.vue b/resources/js/components/open/forms/OpenForm.vue index d6a0abd99..d140afa9c 100644 --- a/resources/js/components/open/forms/OpenForm.vue +++ b/resources/js/components/open/forms/OpenForm.vue @@ -62,6 +62,9 @@ <script> import axios from 'axios' import Form from 'vform' +import { computed } from 'vue' +import { useRecordsStore } from '../../../stores/records' +import { useWorkingFormStore } from '../../../stores/working_form' import OpenFormButton from './OpenFormButton.vue' import clonedeep from 'clone-deep' import FormLogicPropertyResolver from '../../../forms/FormLogicPropertyResolver.js' @@ -100,6 +103,16 @@ export default { }, adminPreview: { type: Boolean, default: false } // If used in FormEditorPreview }, + + setup () { + const recordsStore = useRecordsStore() + const workingFormStore = useWorkingFormStore() + return { + recordsStore, + workingFormStore + } + }, + data () { return { dataForm: null, @@ -154,8 +167,8 @@ export default { newFields.push(...group) } }) - // set the properties on working_form vuex - this.$store.commit('open/working_form/setProperties', newFields) + // set the properties on working_form store + this.workingFormStore.setProperties(newFields) } }, /** @@ -293,12 +306,12 @@ export default { if (!this.form || !this.form.editable_submissions || !this.form.submission_id) { return null } - await this.$store.dispatch('open/records/loadRecord', + await this.recordsStore.loadRecord( axios.get('/api/forms/' + this.form.slug + '/submissions/' + this.form.submission_id).then((response) => { return { submission_id: this.form.submission_id, ...response.data.data } }) ) - return this.$store.getters['open/records/getById'](this.form.submission_id) + return this.recordsStore.getById(this.form.submission_id) }, async initForm () { if (this.isPublicFormPage && this.form.editable_submissions) { diff --git a/resources/js/components/open/forms/OpenFormField.vue b/resources/js/components/open/forms/OpenFormField.vue index b96ae6d91..d77dda902 100644 --- a/resources/js/components/open/forms/OpenFormField.vue +++ b/resources/js/components/open/forms/OpenFormField.vue @@ -78,9 +78,10 @@ </template> <script> +import { computed } from 'vue' +import { useWorkingFormStore } from '../../../stores/working_form'; import FormLogicPropertyResolver from '../../../forms/FormLogicPropertyResolver.js' import FormPendingSubmissionKey from '../../../mixins/forms/form-pending-submission-key.js' -import {mapState} from "vuex"; export default { name: 'OpenFormField', @@ -113,15 +114,21 @@ export default { }, adminPreview: {type: Boolean, default: false} // If used in FormEditorPreview }, + + setup () { + const workingFormStore = useWorkingFormStore() + return { + workingFormStore, + selectedFieldIndex : computed(() => workingFormStore.selectedFieldIndex), + showEditFieldSidebar : computed(() => workingFormStore.showEditFieldSidebar) + } + }, + data() { return {} }, computed: { - ...mapState({ - selectedFieldIndex: state => state['open/working_form'].selectedFieldIndex, - showEditFieldSidebar: state => state['open/working_form'].showEditFieldSidebar - }), fieldComponents() { return { text: 'TextInput', @@ -214,10 +221,10 @@ export default { methods: { editFieldOptions() { - this.$store.commit('open/working_form/openSettingsForField', this.field) + this.workingFormStore.openSettingsForField(this.field) }, openAddFieldSidebar() { - this.$store.commit('open/working_form/openAddFieldSidebar', this.field) + this.workingFormStore.openAddFieldSidebar(this.field) }, /** * Get the right input component for the field/options combination diff --git a/resources/js/components/open/forms/components/AdvancedFormUrlSettings.vue b/resources/js/components/open/forms/components/AdvancedFormUrlSettings.vue index 0cce1d600..03ba81c1a 100644 --- a/resources/js/components/open/forms/components/AdvancedFormUrlSettings.vue +++ b/resources/js/components/open/forms/components/AdvancedFormUrlSettings.vue @@ -13,12 +13,12 @@ label="Hide Form Title" :disabled="form.hide_title===true" :help="hideTitleHelp" - @input="onChangeHideTitle" + @update:model-value="onChangeHideTitle" /> <toggle-switch-input :value="value.auto_submit" name="auto_submit" class="mt-4" label="Auto Submit Form" help="Form will auto submit immediate after open URL" - @input="onChangeAutoSubmit" + @update:model-value="onChangeAutoSubmit" /> </collapse> </template> diff --git a/resources/js/components/open/forms/components/FormEditor.vue b/resources/js/components/open/forms/components/FormEditor.vue index 01c6eed33..4ab59ff63 100644 --- a/resources/js/components/open/forms/components/FormEditor.vue +++ b/resources/js/components/open/forms/components/FormEditor.vue @@ -85,7 +85,11 @@ </template> <script> -import { mapGetters } from 'vuex' +import { computed } from 'vue' +import { useAuthStore } from '../../../../stores/auth'; +import { useFormsStore } from '../../../../stores/forms'; +import { useWorkingFormStore } from '../../../../stores/working_form'; +import { useWorkspacesStore } from '../../../../stores/workspaces'; import AddFormBlockSidebar from './form-components/AddFormBlockSidebar.vue' import FormFieldEditSidebar from '../fields/FormFieldEditSidebar.vue' import FormErrorModal from './form-components/FormErrorModal.vue' @@ -143,6 +147,19 @@ export default { } }, + setup () { + const authStore = useAuthStore() + const formsStore = useFormsStore() + const workingFormStore = useWorkingFormStore() + const workspacesStore = useWorkspacesStore() + return { + formsStore, + workingFormStore, + workspacesStore, + user : computed(() => authStore.user) + } + }, + data () { return { showFormErrorModal: false, @@ -153,23 +170,20 @@ export default { }, computed: { - ...mapGetters({ - user: 'auth/user' - }), form: { get () { - return this.$store.state['open/working_form'].content + return this.workingFormStore.content }, /* We add a setter */ set (value) { - this.$store.commit('open/working_form/set', value) + this.workingFormStore.set(value) } }, createdForm () { - return this.$store.getters['open/forms/getById'](this.createdFormId) + return this.formsStore.getById(this.createdFormId) }, workspace () { - return this.$store.getters['open/workspaces/getCurrent']() + return this.workspacesStore.getCurrent() }, steps () { return [ @@ -245,7 +259,7 @@ export default { this.validationErrorResponse = null this.form.put('/api/open/forms/{id}/'.replace('{id}', this.form.id)).then((response) => { const data = response.data - this.$store.commit('open/forms/addOrUpdate', data.form) + this.formsStore.addOrUpdate(data.form) this.$emit('on-save') this.$router.push({ name: 'forms.show', params: { slug: this.form.slug } }) this.$logEvent('form_saved', { form_id: this.form.id, form_slug: this.form.slug }) @@ -266,7 +280,7 @@ export default { this.updateFormLoading = true this.form.post('/api/open/forms').then((response) => { - this.$store.commit('open/forms/addOrUpdate', response.data.form) + this.formsStore.addOrUpdate(response.data.form) this.$emit('on-save') this.createdFormId = response.data.form.id diff --git a/resources/js/components/open/forms/components/FormFieldsEditor.vue b/resources/js/components/open/forms/components/FormFieldsEditor.vue index 9d8c0e291..f524c02d3 100644 --- a/resources/js/components/open/forms/components/FormFieldsEditor.vue +++ b/resources/js/components/open/forms/components/FormFieldsEditor.vue @@ -166,6 +166,8 @@ </template> <script> +import { computed } from 'vue' +import { useWorkingFormStore } from '../../../../stores/working_form' import draggable from 'vuedraggable' import ProTag from '../../../common/ProTag.vue' import clonedeep from 'clone-deep' @@ -182,6 +184,13 @@ export default { EditableDiv }, + setup () { + const workingFormStore = useWorkingFormStore() + return { + workingFormStore + } + }, + data () { return { formFields: [], @@ -192,11 +201,11 @@ export default { computed: { form: { get () { - return this.$store.state['open/working_form'].content + return this.workingFormStore.content }, /* We add a setter */ set (value) { - this.$store.commit('open/working_form/set', value) + this.workingFormStore.set(value) } } }, @@ -313,7 +322,7 @@ export default { return type }, editOptions (index) { - this.$store.commit('open/working_form/openSettingsForField', index) + this.workingFormStore.openSettingsForField(index) }, removeBlock (blockIndex) { const newFields = clonedeep(this.formFields) @@ -322,10 +331,10 @@ export default { this.closeSidebar() }, closeSidebar () { - this.$store.commit('open/working_form/closeEditFieldSidebar') + this.workingFormStore.closeEditFieldSidebar() }, openAddFieldSidebar () { - this.$store.commit('open/working_form/openAddFieldSidebar', null) + this.workingFormStore.openAddFieldSidebar(null) } } } diff --git a/resources/js/components/open/forms/components/FormSubmissions.vue b/resources/js/components/open/forms/components/FormSubmissions.vue index e1fce1dd2..3700f7ca7 100644 --- a/resources/js/components/open/forms/components/FormSubmissions.vue +++ b/resources/js/components/open/forms/components/FormSubmissions.vue @@ -25,7 +25,7 @@ </h4> <div v-for="field in properties" :key="field.id" class="p-2 border"> {{ field.name }} - <v-switch v-model="displayColumns[field.id]" class="float-right" @input="onChangeDisplayColumns" /> + <v-switch v-model="displayColumns[field.id]" class="float-right" @update:model-value="onChangeDisplayColumns" /> </div> </template> <template v-if="removed_properties.length > 0"> @@ -34,7 +34,7 @@ </h4> <div v-for="field in removed_properties" :key="field.id" class="p-2 border"> {{ field.name }} - <v-switch v-model="displayColumns[field.id]" class="float-right" @input="onChangeDisplayColumns" /> + <v-switch v-model="displayColumns[field.id]" class="float-right" @update:model-value="onChangeDisplayColumns" /> </div> </template> </div> @@ -83,6 +83,7 @@ import axios from 'axios' import Fuse from 'fuse.js' import Form from 'vform' +import { useWorkingFormStore } from '../../../../stores/working_form' import ScrollShadow from '../../../common/ScrollShadow.vue' import OpenTable from '../../tables/OpenTable.vue' import clonedeep from 'clone-deep' @@ -92,6 +93,15 @@ export default { name: 'FormSubmissions', components: { ScrollShadow, OpenTable, VSwitch }, props: {}, + + setup () { + const workingFormStore = useWorkingFormStore() + return { + workingFormStore + } + }, + + data () { return { formInitDone: false, @@ -111,10 +121,10 @@ export default { computed: { form: { get () { - return this.$store.state['open/working_form'].content + return this.workingFormStore.content }, set (value) { - this.$store.commit('open/working_form/set', value) + this.workingFormStore.set(value) } }, exportUrl () { diff --git a/resources/js/components/open/forms/components/form-components/AddFormBlockSidebar.vue b/resources/js/components/open/forms/components/form-components/AddFormBlockSidebar.vue index f07f48657..fe5806d4f 100644 --- a/resources/js/components/open/forms/components/form-components/AddFormBlockSidebar.vue +++ b/resources/js/components/open/forms/components/form-components/AddFormBlockSidebar.vue @@ -30,7 +30,7 @@ <div class="mx-auto"> <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-gray-500" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" v-html="block.icon" - /> + ></svg> </div> <p class="w-full text-xs text-gray-500 uppercase text-center font-semibold mt-1"> {{ block.title }} @@ -50,7 +50,7 @@ <div class="mx-auto"> <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-gray-500" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" v-html="block.icon" - /> + ></svg> </div> <p class="w-full text-xs text-gray-500 uppercase text-center font-semibold mt-1"> {{ block.title }} @@ -63,14 +63,26 @@ </template> <script> -import { mapState } from 'vuex' import Form from 'vform' import clonedeep from 'clone-deep' +import { computed } from 'vue' +import { useWorkingFormStore } from '../../../../../stores/working_form' export default { name: 'AddFormBlockSidebar', components: {}, props: {}, + + setup () { + const workingFormStore = useWorkingFormStore() + return { + workingFormStore, + selectedFieldIndex : computed(() => workingFormStore.selectedFieldIndex), + showAddFieldSidebar : computed(() => workingFormStore.showAddFieldSidebar) + } + }, + + data () { return { blockForm: null, @@ -162,17 +174,13 @@ export default { }, computed: { - ...mapState({ - selectedFieldIndex: state => state['open/working_form'].selectedFieldIndex, - showAddFieldSidebar: state => state['open/working_form'].showAddFieldSidebar - }), form: { get () { - return this.$store.state['open/working_form'].content + return this.workingFormStore.content }, /* We add a setter */ set (value) { - this.$store.commit('open/working_form/set', value) + this.workingFormStore.set(value) } }, showSidebar () { @@ -209,7 +217,7 @@ export default { methods: { closeSidebar () { - this.$store.commit('open/working_form/closeAddFieldSidebar') + this.workingFormStore.closeAddFieldSidebar() }, reset () { this.blockForm = new Form({ @@ -231,12 +239,12 @@ export default { const newFields = clonedeep(this.form.properties) newFields.push(newBlock) this.form.properties = newFields - this.$store.commit('open/working_form/openSettingsForField', this.form.properties.length - 1) + this.workingFormStore.openSettingsForField(this.form.properties.length - 1) } else { const newFields = clonedeep(this.form.properties) newFields.splice(this.selectedFieldIndex + 1, 0, newBlock) this.form.properties = newFields - this.$store.commit('open/working_form/openSettingsForField', this.selectedFieldIndex + 1) + this.workingFormStore.openSettingsForField(this.selectedFieldIndex + 1) } this.reset() }, diff --git a/resources/js/components/open/forms/components/form-components/FormAboutSubmission.vue b/resources/js/components/open/forms/components/form-components/FormAboutSubmission.vue index 4d90b492e..66440d1a4 100644 --- a/resources/js/components/open/forms/components/form-components/FormAboutSubmission.vue +++ b/resources/js/components/open/forms/components/form-components/FormAboutSubmission.vue @@ -129,6 +129,7 @@ </template> <script> +import { useWorkingFormStore } from '../../../../../stores/working_form' import EditorOptionsPanel from '../../../editors/EditorOptionsPanel.vue' import ProTag from '../../../../common/ProTag.vue' import VTransition from '../../../../common/transitions/VTransition.vue' @@ -136,6 +137,12 @@ import VTransition from '../../../../common/transitions/VTransition.vue' export default { components: {EditorOptionsPanel, ProTag, VTransition}, props: {}, + setup () { + const workingFormStore = useWorkingFormStore() + return { + workingFormStore + } + }, data () { return { submissionOptions: {} @@ -145,11 +152,11 @@ export default { computed: { form: { get () { - return this.$store.state['open/working_form'].content + return this.workingFormStore.content }, /* We add a setter */ set (value) { - this.$store.commit('open/working_form/set', value) + this.workingFormStore.set(value) } }, /** diff --git a/resources/js/components/open/forms/components/form-components/FormAccess.vue b/resources/js/components/open/forms/components/form-components/FormAccess.vue index 9f6575158..356fd73c2 100644 --- a/resources/js/components/open/forms/components/form-components/FormAccess.vue +++ b/resources/js/components/open/forms/components/form-components/FormAccess.vue @@ -38,11 +38,18 @@ </template> <script> +import { useWorkingFormStore } from '../../../../../stores/working_form' import EditorOptionsPanel from '../../../editors/EditorOptionsPanel.vue' export default { components: { EditorOptionsPanel }, props: {}, + setup () { + const workingFormStore = useWorkingFormStore() + return { + workingFormStore + } + }, data () { return { } @@ -50,11 +57,11 @@ export default { computed: { form: { get () { - return this.$store.state['open/working_form'].content + return this.workingFormStore.content }, /* We add a setter */ set (value) { - this.$store.commit('open/working_form/set', value) + this.workingFormStore.set(value) } } }, diff --git a/resources/js/components/open/forms/components/form-components/FormCustomCode.vue b/resources/js/components/open/forms/components/form-components/FormCustomCode.vue index f15767dab..6ea69b3f9 100644 --- a/resources/js/components/open/forms/components/form-components/FormCustomCode.vue +++ b/resources/js/components/open/forms/components/form-components/FormCustomCode.vue @@ -17,12 +17,18 @@ </template> <script> +import { useWorkingFormStore } from '../../../../../stores/working_form' import EditorOptionsPanel from '../../../editors/EditorOptionsPanel.vue' import CodeInput from '../../../../forms/CodeInput.vue' export default { components: { EditorOptionsPanel, CodeInput }, - props: { + props: {}, + setup () { + const workingFormStore = useWorkingFormStore() + return { + workingFormStore + } }, data () { return { @@ -32,11 +38,11 @@ export default { computed: { form: { get () { - return this.$store.state['open/working_form'].content + return this.workingFormStore.content }, /* We add a setter */ set (value) { - this.$store.commit('open/working_form/set', value) + this.workingFormStore.set(value) } } }, diff --git a/resources/js/components/open/forms/components/form-components/FormCustomSeo.vue b/resources/js/components/open/forms/components/form-components/FormCustomSeo.vue index 44a136c3f..4fe2d2d07 100644 --- a/resources/js/components/open/forms/components/form-components/FormCustomSeo.vue +++ b/resources/js/components/open/forms/components/form-components/FormCustomSeo.vue @@ -23,11 +23,18 @@ </template> <script> +import { useWorkingFormStore } from '../../../../../stores/working_form' import EditorOptionsPanel from '../../../editors/EditorOptionsPanel.vue' export default { components: { EditorOptionsPanel }, props: {}, + setup () { + const workingFormStore = useWorkingFormStore() + return { + workingFormStore + } + }, data () { return { } @@ -35,11 +42,11 @@ export default { computed: { form: { get () { - return this.$store.state['open/working_form'].content + return this.workingFormStore.content }, /* We add a setter */ set (value) { - this.$store.commit('open/working_form/set', value) + this.workingFormStore.set(value) } } }, diff --git a/resources/js/components/open/forms/components/form-components/FormCustomization.vue b/resources/js/components/open/forms/components/form-components/FormCustomization.vue index cd5540553..15e10d71a 100644 --- a/resources/js/components/open/forms/components/form-components/FormCustomization.vue +++ b/resources/js/components/open/forms/components/form-components/FormCustomization.vue @@ -71,7 +71,7 @@ /> <toggle-switch-input name="confetti_on_submission" :form="form" class="mt-4" label="Confetti on successful submisison" - @input="onChangeConfettiOnSubmission" + @update:model-value="onChangeConfettiOnSubmission" /> <toggle-switch-input name="auto_save" :form="form" label="Auto save form response" @@ -81,6 +81,7 @@ </template> <script> +import { useWorkingFormStore } from '../../../../../stores/working_form' import EditorOptionsPanel from '../../../editors/EditorOptionsPanel.vue' import ProTag from '../../../../common/ProTag.vue' @@ -88,6 +89,12 @@ export default { components: { EditorOptionsPanel, ProTag }, props: { }, + setup () { + const workingFormStore = useWorkingFormStore() + return { + workingFormStore + } + }, data () { return { isMounted: false @@ -97,11 +104,11 @@ export default { computed: { form: { get () { - return this.$store.state['open/working_form'].content + return this.workingFormStore.content }, /* We add a setter */ set (value) { - this.$store.commit('open/working_form/set', value) + this.workingFormStore.set(value) } } }, diff --git a/resources/js/components/open/forms/components/form-components/FormEditorPreview.vue b/resources/js/components/open/forms/components/form-components/FormEditorPreview.vue index 43c22e79a..fd10eddb3 100644 --- a/resources/js/components/open/forms/components/form-components/FormEditorPreview.vue +++ b/resources/js/components/open/forms/components/form-components/FormEditorPreview.vue @@ -59,12 +59,18 @@ </template> <script> +import { useWorkingFormStore } from '../../../../../stores/working_form' import VSwitch from '../../../../forms/components/VSwitch.vue' import OpenCompleteForm from '../../OpenCompleteForm.vue' export default { components: { OpenCompleteForm, VSwitch }, - props: { + props: {}, + setup () { + const workingFormStore = useWorkingFormStore() + return { + workingFormStore + } }, data () { return { @@ -75,11 +81,11 @@ export default { computed: { form: { get () { - return this.$store.state['open/working_form'].content + return this.workingFormStore.content }, /* We add a setter */ set (value) { - this.$store.commit('open/working_form/set', value) + this.workingFormStore.set(value) } }, creating () { // returns true if we are creating a form diff --git a/resources/js/components/open/forms/components/form-components/FormInformation.vue b/resources/js/components/open/forms/components/form-components/FormInformation.vue index e73d6cd75..0f5e53d67 100644 --- a/resources/js/components/open/forms/components/form-components/FormInformation.vue +++ b/resources/js/components/open/forms/components/form-components/FormInformation.vue @@ -66,14 +66,27 @@ </template> <script> +import { computed } from 'vue' +import clonedeep from 'clone-deep' +import { useFormsStore } from '../../../../../stores/forms' +import { useWorkingFormStore } from '../../../../../stores/working_form' import EditorOptionsPanel from '../../../editors/EditorOptionsPanel.vue' import SelectInput from '../../../../forms/SelectInput.vue' -import { mapState } from 'vuex' -import clonedeep from 'clone-deep' export default { components: { SelectInput, EditorOptionsPanel }, props: {}, + + setup () { + const formsStore = useFormsStore() + const workingFormStore = useWorkingFormStore() + return { + formsStore, + workingFormStore, + forms : computed(() => formsStore.content) + } + }, + data () { return { showCopyFormSettingsModal: false, @@ -106,20 +119,17 @@ export default { } }) }, - ...mapState({ - forms: state => state['open/forms'].content - }), form: { get () { - return this.$store.state['open/working_form'].content + return this.workingFormStore.content }, /* We add a setter */ set (value) { - this.$store.commit('open/working_form/set', value) + this.workingFormStore.set(value) } }, allTagsOptions () { - return this.$store.getters['open/forms/getAllTags'].map((tagname) => { + return this.formsStore.getAllTags.map((tagname) => { return { name: tagname, value: tagname diff --git a/resources/js/components/open/forms/components/form-components/FormNotifications.vue b/resources/js/components/open/forms/components/form-components/FormNotifications.vue index fd275d24a..5685cebe3 100644 --- a/resources/js/components/open/forms/components/form-components/FormNotifications.vue +++ b/resources/js/components/open/forms/components/form-components/FormNotifications.vue @@ -31,6 +31,7 @@ </template> <script> +import { useWorkingFormStore } from '../../../../../stores/working_form' import EditorOptionsPanel from '../../../editors/EditorOptionsPanel.vue' import FormNotificationsOption from './components/FormNotificationsOption.vue' import FormNotificationsSlack from './components/FormNotificationsSlack.vue' @@ -40,7 +41,12 @@ import FormNotificationsWebhook from './components/FormNotificationsWebhook.vue' export default { components: { FormNotificationsSubmissionConfirmation, FormNotificationsSlack, FormNotificationsDiscord, FormNotificationsOption, EditorOptionsPanel, FormNotificationsWebhook }, - props: { + props: {}, + setup () { + const workingFormStore = useWorkingFormStore() + return { + workingFormStore + } }, data () { return { @@ -50,11 +56,11 @@ export default { computed: { form: { get () { - return this.$store.state['open/working_form'].content + return this.workingFormStore.content }, /* We add a setter */ set (value) { - this.$store.commit('open/working_form/set', value) + this.workingFormStore.set(value) } }, zapierUrl: () => window.config.links.zapier_integration diff --git a/resources/js/components/open/forms/components/form-components/FormSecurityPrivacy.vue b/resources/js/components/open/forms/components/form-components/FormSecurityPrivacy.vue index e736d25cd..884f1be26 100644 --- a/resources/js/components/open/forms/components/form-components/FormSecurityPrivacy.vue +++ b/resources/js/components/open/forms/components/form-components/FormSecurityPrivacy.vue @@ -17,11 +17,17 @@ </template> <script> +import { useWorkingFormStore } from '../../../../../stores/working_form' import EditorOptionsPanel from '../../../editors/EditorOptionsPanel.vue' export default { components: { EditorOptionsPanel }, - props: { + props: {}, + setup () { + const workingFormStore = useWorkingFormStore() + return { + workingFormStore + } }, data () { return { @@ -30,11 +36,11 @@ export default { computed: { form: { get () { - return this.$store.state['open/working_form'].content + return this.workingFormStore.content }, /* We add a setter */ set (value) { - this.$store.commit('open/working_form/set', value) + this.workingFormStore.set(value) } } }, diff --git a/resources/js/components/open/forms/components/form-components/FormStructure.vue b/resources/js/components/open/forms/components/form-components/FormStructure.vue index 20b901fa5..56e5dd602 100644 --- a/resources/js/components/open/forms/components/form-components/FormStructure.vue +++ b/resources/js/components/open/forms/components/form-components/FormStructure.vue @@ -11,12 +11,18 @@ </template> <script> +import { useWorkingFormStore } from '../../../../../stores/working_form' import EditorOptionsPanel from '../../../editors/EditorOptionsPanel.vue' import FormFieldsEditor from '../FormFieldsEditor.vue' export default { components: { EditorOptionsPanel, FormFieldsEditor }, - props: { + props: {}, + setup () { + const workingFormStore = useWorkingFormStore() + return { + workingFormStore + } }, data () { return { @@ -26,11 +32,11 @@ export default { computed: { form: { get () { - return this.$store.state['open/working_form'].content + return this.workingFormStore.content }, /* We add a setter */ set (value) { - this.$store.commit('open/working_form/set', value) + this.workingFormStore.set(value) } } } diff --git a/resources/js/components/open/forms/components/form-components/components/FormNotificationsDiscord.vue b/resources/js/components/open/forms/components/form-components/components/FormNotificationsDiscord.vue index 16ae57f57..8d9e8a5e1 100644 --- a/resources/js/components/open/forms/components/form-components/components/FormNotificationsDiscord.vue +++ b/resources/js/components/open/forms/components/form-components/components/FormNotificationsDiscord.vue @@ -46,12 +46,19 @@ </template> <script> +import { useWorkingFormStore } from '../../../../../../stores/working_form' import ProTag from '../../../../../common/ProTag.vue' import FormNotificationsMessageActions from './FormNotificationsMessageActions.vue' export default { components: { ProTag, FormNotificationsMessageActions }, props: {}, + setup () { + const workingFormStore = useWorkingFormStore() + return { + workingFormStore + } + }, data () { return { showModal: false @@ -61,11 +68,11 @@ export default { computed: { form: { get () { - return this.$store.state['open/working_form'].content + return this.workingFormStore.content }, /* We add a setter */ set (value) { - this.$store.commit('open/working_form/set', value) + this.workingFormStore.set(value) } } }, diff --git a/resources/js/components/open/forms/components/form-components/components/FormNotificationsOption.vue b/resources/js/components/open/forms/components/form-components/components/FormNotificationsOption.vue index df478c42d..d2d5628b5 100644 --- a/resources/js/components/open/forms/components/form-components/components/FormNotificationsOption.vue +++ b/resources/js/components/open/forms/components/form-components/components/FormNotificationsOption.vue @@ -50,11 +50,18 @@ </template> <script> +import { useWorkingFormStore } from '../../../../../../stores/working_form' import ProTag from '../../../../../common/ProTag.vue' export default { components: { ProTag }, props: {}, + setup () { + const workingFormStore = useWorkingFormStore() + return { + workingFormStore + } + }, data () { return { showModal: false @@ -64,11 +71,11 @@ export default { computed: { form: { get () { - return this.$store.state['open/working_form'].content + return this.workingFormStore.content }, /* We add a setter */ set (value) { - this.$store.commit('open/working_form/set', value) + this.workingFormStore.set(value) } }, replayToEmailField () { diff --git a/resources/js/components/open/forms/components/form-components/components/FormNotificationsSlack.vue b/resources/js/components/open/forms/components/form-components/components/FormNotificationsSlack.vue index dde15fcc1..a230c537d 100644 --- a/resources/js/components/open/forms/components/form-components/components/FormNotificationsSlack.vue +++ b/resources/js/components/open/forms/components/form-components/components/FormNotificationsSlack.vue @@ -47,12 +47,19 @@ </template> <script> +import { useWorkingFormStore } from '../../../../../../stores/working_form' import ProTag from '../../../../../common/ProTag.vue' import FormNotificationsMessageActions from './FormNotificationsMessageActions.vue' export default { components: { ProTag, FormNotificationsMessageActions }, props: {}, + setup () { + const workingFormStore = useWorkingFormStore() + return { + workingFormStore + } + }, data () { return { showModal: false @@ -62,11 +69,11 @@ export default { computed: { form: { get () { - return this.$store.state['open/working_form'].content + return this.workingFormStore.content }, /* We add a setter */ set (value) { - this.$store.commit('open/working_form/set', value) + this.workingFormStore.set(value) } } }, diff --git a/resources/js/components/open/forms/components/form-components/components/FormNotificationsSubmissionConfirmation.vue b/resources/js/components/open/forms/components/form-components/components/FormNotificationsSubmissionConfirmation.vue index 92eaf4d6f..8fe9e7f43 100644 --- a/resources/js/components/open/forms/components/form-components/components/FormNotificationsSubmissionConfirmation.vue +++ b/resources/js/components/open/forms/components/form-components/components/FormNotificationsSubmissionConfirmation.vue @@ -62,11 +62,18 @@ </template> <script> +import { useWorkingFormStore } from '../../../../../../stores/working_form' import ProTag from '../../../../../common/ProTag.vue' export default { components: { ProTag }, props: {}, + setup () { + const workingFormStore = useWorkingFormStore() + return { + workingFormStore + } + }, data () { return { showModal: false @@ -76,11 +83,11 @@ export default { computed: { form: { get () { - return this.$store.state['open/working_form'].content + return this.workingFormStore.content }, /* We add a setter */ set (value) { - this.$store.commit('open/working_form/set', value) + this.workingFormStore.set(value) } }, emailSubmissionConfirmationField () { diff --git a/resources/js/components/open/forms/components/form-components/components/FormNotificationsWebhook.vue b/resources/js/components/open/forms/components/form-components/components/FormNotificationsWebhook.vue index eec910275..bcaca9fb4 100644 --- a/resources/js/components/open/forms/components/form-components/components/FormNotificationsWebhook.vue +++ b/resources/js/components/open/forms/components/form-components/components/FormNotificationsWebhook.vue @@ -43,11 +43,18 @@ </template> <script> +import { useWorkingFormStore } from '../../../../../../stores/working_form' import ProTag from '../../../../../common/ProTag.vue' export default { components: { ProTag }, props: {}, + setup () { + const workingFormStore = useWorkingFormStore() + return { + workingFormStore + } + }, data () { return { showModal: false @@ -57,11 +64,11 @@ export default { computed: { form: { get () { - return this.$store.state['open/working_form'].content + return this.workingFormStore.content }, /* We add a setter */ set (value) { - this.$store.commit('open/working_form/set', value) + this.workingFormStore.set(value) } } }, diff --git a/resources/js/components/open/forms/components/form-logic-components/FormBlockLogicEditor.vue b/resources/js/components/open/forms/components/form-logic-components/FormBlockLogicEditor.vue index fce7cdbcc..fb78ab0af 100644 --- a/resources/js/components/open/forms/components/form-logic-components/FormBlockLogicEditor.vue +++ b/resources/js/components/open/forms/components/form-logic-components/FormBlockLogicEditor.vue @@ -38,7 +38,7 @@ :multiple="true" class="mt-1" placeholder="Actions..." help="Action(s) triggerred when above conditions are true" :options="actionOptions" - @input="onActionInput" + @update:model-value="onActionInput" /> <modal :show="showCopyFormModal" @close="showCopyFormModal = false"> diff --git a/resources/js/components/open/forms/components/templates/FormTemplateModal.vue b/resources/js/components/open/forms/components/templates/FormTemplateModal.vue index 0ce7f8a3c..65a87a5f0 100644 --- a/resources/js/components/open/forms/components/templates/FormTemplateModal.vue +++ b/resources/js/components/open/forms/components/templates/FormTemplateModal.vue @@ -72,10 +72,11 @@ </template> <script> -import Form from 'vform' -import store from '~/store' -import { mapState, mapGetters } from 'vuex' import axios from 'axios' +import Form from 'vform' +import { computed } from 'vue' +import { useAuthStore } from '../../../../../stores/auth' +import { useTemplatesStore } from '../../../../../stores/templates' import QuestionsEditor from './QuestionsEditor.vue' export default { @@ -87,6 +88,18 @@ export default { template: { type: Object, required: false, default: () => {} } }, + setup () { + const authStore = useAuthStore() + const templatesStore = useTemplatesStore() + return { + templatesStore, + user : computed(() => authStore.user), + templates : computed(() => templatesStore.content), + industries : computed(() => templatesStore.industries), + types : computed(() => templatesStore.types) + } + }, + data: () => ({ templateForm: null }), @@ -104,18 +117,10 @@ export default { related_templates: null, questions: [] }) - store.dispatch('open/templates/loadIfEmpty') + this.templatesStore.loadIfEmpty() }, computed: { - ...mapState({ - templates: state => state['open/templates'].content, - industries: state => state['open/templates'].industries, - types: state => state['open/templates'].types - }), - ...mapGetters({ - user: 'auth/user' - }), typesOptions () { return Object.values(this.types).map((type) => { return { @@ -156,7 +161,7 @@ export default { if (response.data.message) { this.alertSuccess(response.data.message) } - this.$store.commit('open/templates/addOrUpdate', response.data.data) + this.templatesStore.addOrUpdate(response.data.data) this.$emit('close') }) }, @@ -166,7 +171,7 @@ export default { if (response.data.message) { this.alertSuccess(response.data.message) } - this.$store.commit('open/templates/addOrUpdate', response.data.data) + this.templatesStore.addOrUpdate(response.data.data) this.$emit('close') }) }, @@ -177,7 +182,7 @@ export default { this.alertSuccess(response.data.message) } this.$router.push({ name: 'templates' }) - this.$store.commit('open/templates/remove', this.template) + this.templatesStore.remove(this.template) this.$emit('close') }) } diff --git a/resources/js/components/open/forms/fields/FormFieldEditSidebar.vue b/resources/js/components/open/forms/fields/FormFieldEditSidebar.vue index 05bad871d..101e87f9c 100644 --- a/resources/js/components/open/forms/fields/FormFieldEditSidebar.vue +++ b/resources/js/components/open/forms/fields/FormFieldEditSidebar.vue @@ -70,8 +70,9 @@ </template> <script> -import { mapState } from 'vuex' +import { computed } from 'vue' import clonedeep from 'clone-deep' +import { useWorkingFormStore } from '../../../../stores/working_form' import ChangeFieldType from './components/ChangeFieldType.vue' import FieldOptions from './components/FieldOptions.vue' import BlockOptions from './components/BlockOptions.vue' @@ -80,6 +81,14 @@ export default { name: 'FormFieldEditSidebar', components: { ChangeFieldType, FieldOptions, BlockOptions }, props: {}, + setup () { + const workingFormStore = useWorkingFormStore() + return { + workingFormStore, + selectedFieldIndex : computed(() => workingFormStore.selectedFieldIndex), + showEditFieldSidebar : computed(() => workingFormStore.showEditFieldSidebar) + } + }, data () { return { @@ -87,17 +96,13 @@ export default { }, computed: { - ...mapState({ - selectedFieldIndex: state => state['open/working_form'].selectedFieldIndex, - showEditFieldSidebar: state => state['open/working_form'].showEditFieldSidebar - }), form: { get () { - return this.$store.state['open/working_form'].content + return this.workingFormStore.content }, /* We add a setter */ set (value) { - this.$store.commit('open/working_form/set', value) + this.workingFormStore.set(value) } }, field () { @@ -145,7 +150,7 @@ export default { this.closeSidebar() }, closeSidebar () { - this.$store.commit('open/working_form/closeEditFieldSidebar') + this.workingFormStore.closeEditFieldSidebar() }, generateUUID () { let d = new Date().getTime()// Timestamp diff --git a/resources/js/components/open/forms/fields/components/FieldOptions.vue b/resources/js/components/open/forms/fields/components/FieldOptions.vue index f1f16cbab..6f1db50b3 100644 --- a/resources/js/components/open/forms/fields/components/FieldOptions.vue +++ b/resources/js/components/open/forms/fields/components/FieldOptions.vue @@ -186,7 +186,7 @@ <text-area-input v-model="optionsText" :name="field.id+'_options_text'" class="mt-3" label="Set selection options" help="Add one option per line" - @input="onFieldOptionsChange" + @update:model-value="onFieldOptionsChange" /> <v-checkbox v-model="field.allow_creation" name="allow_creation" help="" @update:model-value="onFieldAllowCreationChange" diff --git a/resources/js/components/open/tables/OpenTable.vue b/resources/js/components/open/tables/OpenTable.vue index 39737b7db..388d94748 100644 --- a/resources/js/components/open/tables/OpenTable.vue +++ b/resources/js/components/open/tables/OpenTable.vue @@ -78,6 +78,7 @@ </template> <script> +import { useWorkingFormStore } from '../../../stores/working_form' import OpenText from './components/OpenText.vue' import OpenUrl from './components/OpenUrl.vue' import OpenSelect from './components/OpenSelect.vue' @@ -119,6 +120,13 @@ export default { } }, + setup () { + const workingFormStore = useWorkingFormStore() + return { + workingFormStore + } + }, + data () { return { tableHash: null, @@ -129,10 +137,11 @@ export default { computed: { form: { get () { - return this.$store.state['open/working_form'].content + return this.workingFormStore.content }, + /* We add a setter */ set (value) { - this.$store.commit('open/working_form/set', value) + this.workingFormStore.set(value) } }, hasActions () { diff --git a/resources/js/components/pages/OpenFormFooter.vue b/resources/js/components/pages/OpenFormFooter.vue index 6bfd698d0..c2e04bc27 100644 --- a/resources/js/components/pages/OpenFormFooter.vue +++ b/resources/js/components/pages/OpenFormFooter.vue @@ -31,18 +31,23 @@ </template> <script> -import { mapGetters } from 'vuex' +import { computed } from 'vue' +import { useAuthStore } from '../../stores/auth' export default { + setup () { + const authStore = useAuthStore() + return { + user : computed(() => authStore.user) + } + }, + data: () => ({ appName: window.config.appName, currYear: new Date().getFullYear(), }), computed: { - ...mapGetters({ - user: 'auth/user' - }), helpUrl: () => window.config.links.help_url, githubUrl: () => window.config.links.github_url, forumUrl: () => window.config.links.github_forum_url, diff --git a/resources/js/components/pages/StopImpersonation.vue b/resources/js/components/pages/StopImpersonation.vue index e8db87fdf..d336c0a88 100644 --- a/resources/js/components/pages/StopImpersonation.vue +++ b/resources/js/components/pages/StopImpersonation.vue @@ -24,28 +24,34 @@ </template> <script> -import { mapGetters } from 'vuex' +import { computed } from 'vue' +import { useAuthStore } from '../../stores/auth'; +import { useWorkspacesStore } from '../../stores/workspaces'; export default { + setup () { + const authStore = useAuthStore() + const workspacesStore = useWorkspacesStore() + return { + authStore, + workspacesStore, + isImpersonating : computed(() => authStore.isImpersonating), + } + }, + data: () => ({ loading: false }), - computed: { - ...mapGetters({ - isImpersonating: 'auth/isImpersonating' - }) - }, + computed: {}, - mounted () { - }, + mounted () {}, methods: { reverseImpersonation () { this.loading = true - this.$store.dispatch('auth/stopImpersonating') - .then(() => { - this.$store.commit('open/workspaces/set', []) + this.authStore.stopImpersonating().then(() => { + this.workspacesStore.set([]) this.$router.push({ name: 'settings.admin' }) this.loading = false }) diff --git a/resources/js/components/pages/forms/NewFeatures.vue b/resources/js/components/pages/forms/NewFeatures.vue index 8af3a8923..13408145e 100644 --- a/resources/js/components/pages/forms/NewFeatures.vue +++ b/resources/js/components/pages/forms/NewFeatures.vue @@ -62,14 +62,22 @@ </template> <script> +import { computed } from 'vue' import axios from 'axios' -import { mapGetters } from 'vuex' +import { useAuthStore } from '../../../stores/auth'; import VTransition from '../../common/transitions/VTransition.vue' export default { components: { VTransition }, props: {}, + setup () { + const authStore = useAuthStore() + return { + user : computed(() => authStore.user) + } + }, + data: () => ({ changelogEntries: [], showNewFeatures: false @@ -80,9 +88,6 @@ export default { }, computed: { - ...mapGetters({ - user: 'auth/user' - }), requestFeatureLink () { return window.config.links.feature_requests }, diff --git a/resources/js/components/pages/forms/show/ExtraMenu.vue b/resources/js/components/pages/forms/show/ExtraMenu.vue index d59a55a4e..703ad77ce 100644 --- a/resources/js/components/pages/forms/show/ExtraMenu.vue +++ b/resources/js/components/pages/forms/show/ExtraMenu.vue @@ -122,8 +122,10 @@ </template> <script> +import { computed } from 'vue' import axios from 'axios' -import {mapGetters, mapState} from 'vuex' +import { useAuthStore } from '../../../../stores/auth' +import { useFormsStore } from '../../../../stores/forms' import Dropdown from '../../../common/Dropdown.vue' import FormTemplateModal from '../../../open/forms/components/templates/FormTemplateModal.vue' @@ -135,6 +137,15 @@ export default { isMainPage: { type: Boolean, required: false, default: false } }, + setup () { + const authStore = useAuthStore() + const formsStore = useFormsStore() + return { + formsStore, + user : computed(() => authStore.user) + } + }, + data: () => ({ loadingDuplicate: false, loadingDelete: false, @@ -143,9 +154,6 @@ export default { }), computed: { - ...mapGetters({ - user: 'auth/user' - }), formEndpoint: () => '/api/open/forms/{id}', }, @@ -163,7 +171,7 @@ export default { if (this.loadingDuplicate) return this.loadingDuplicate = true axios.post(this.formEndpoint.replace('{id}', this.form.id) + '/duplicate').then((response) => { - this.$store.commit('open/forms/addOrUpdate', response.data.new_form) + this.formsStore.addOrUpdate(response.data.new_form) this.$router.push({name: 'forms.show', params: {slug: response.data.new_form.slug}}) this.alertSuccess('Form was successfully duplicated.') this.loadingDuplicate = false @@ -173,7 +181,7 @@ export default { if (this.loadingDelete) return this.loadingDelete = true axios.delete(this.formEndpoint.replace('{id}', this.form.id)).then(() => { - this.$store.commit('open/forms/remove', this.form) + this.formsStore.remove(this.form) this.$router.push({name: 'home'}) this.alertSuccess('Form was deleted.') this.loadingDelete = false diff --git a/resources/js/components/pages/forms/show/RegenerateFormLink.vue b/resources/js/components/pages/forms/show/RegenerateFormLink.vue index d967a6ac6..3d35ef1ed 100644 --- a/resources/js/components/pages/forms/show/RegenerateFormLink.vue +++ b/resources/js/components/pages/forms/show/RegenerateFormLink.vue @@ -72,7 +72,9 @@ </template> <script> +import { computed } from 'vue' import axios from 'axios' +import { useFormsStore } from '../../../../stores/forms' export default { name: 'RegenerateFormLink', @@ -81,6 +83,13 @@ export default { form: { type: Object, required: true } }, + setup () { + const formsStore = useFormsStore() + return { + formsStore + } + }, + data: () => ({ loadingNewLink: false, showGenerateFormLinkModal: false, @@ -95,7 +104,7 @@ export default { if (this.loadingNewLink) return this.loadingNewLink = true axios.put(this.formEndpoint.replace('{id}', this.form.id) + '/regenerate-link/' + option).then((response) => { - this.$store.commit('open/forms/addOrUpdate', response.data.form) + this.formsStore.addOrUpdate(response.data.form) this.$router.push({name: 'forms.show', params: {slug: response.data.form.slug}}) this.alertSuccess(response.data.message) this.loadingNewLink = false diff --git a/resources/js/components/pages/pricing/CheckoutDetailsModal.vue b/resources/js/components/pages/pricing/CheckoutDetailsModal.vue index 251bccba5..ed5341a64 100644 --- a/resources/js/components/pages/pricing/CheckoutDetailsModal.vue +++ b/resources/js/components/pages/pricing/CheckoutDetailsModal.vue @@ -11,14 +11,14 @@ </template> <script> -import { mapGetters } from 'vuex' -import TextInput from '../../forms/TextInput.vue' +import { computed } from 'vue' +import axios from 'axios' import Form from 'vform' +import { useAuthStore } from '../../../stores/auth' +import TextInput from '../../forms/TextInput.vue' import VButton from '../../common/Button.vue' -import axios from 'axios' export default { - components: { VButton, TextInput }, props: { show: { @@ -34,6 +34,14 @@ export default { default: true } }, + + setup () { + const authStore = useAuthStore() + return { + user : computed(() => authStore.user) + } + }, + data: () => ({ form: new Form({ name: '', @@ -88,10 +96,6 @@ export default { } }, - computed: { - ...mapGetters({ - user: 'auth/user' - }) - } + computed: {} } </script> diff --git a/resources/js/components/pages/pricing/PricingTable.vue b/resources/js/components/pages/pricing/PricingTable.vue index 599eb12ca..13b3bb201 100644 --- a/resources/js/components/pages/pricing/PricingTable.vue +++ b/resources/js/components/pages/pricing/PricingTable.vue @@ -107,7 +107,8 @@ </template> <script> -import { mapGetters } from 'vuex' +import { computed } from 'vue' +import { useAuthStore } from '../../../stores/auth' import axios from 'axios' import MonthlyYearlySelector from './MonthlyYearlySelector.vue' import CheckoutDetailsModal from './CheckoutDetailsModal.vue' @@ -127,6 +128,13 @@ export default { default: false } }, + setup () { + const authStore = useAuthStore() + return { + authenticated : computed(() => authStore.check), + user : computed(() => authStore.user) + } + }, data: () => ({ isYearly: true, selectedPlan: 'pro', @@ -160,11 +168,6 @@ export default { } }, - computed: { - ...mapGetters({ - authenticated: 'auth/check', - user: 'auth/user' - }) - } + computed: {} } </script> diff --git a/resources/js/components/pages/templates/SingleTemplate.vue b/resources/js/components/pages/templates/SingleTemplate.vue index e1938ebd3..cd8208df6 100644 --- a/resources/js/components/pages/templates/SingleTemplate.vue +++ b/resources/js/components/pages/templates/SingleTemplate.vue @@ -39,7 +39,8 @@ </template> <script> -import store from '~/store' +import { computed } from 'vue' +import { useTemplatesStore } from '../../../stores/templates' import TemplateTags from './TemplateTags.vue' export default { @@ -52,22 +53,29 @@ export default { } }, + setup () { + const templatesStore = useTemplatesStore() + return { + templatesStore + } + }, + data: () => ({}), computed: { template () { - return this.$store.getters['open/templates/getBySlug'](this.slug) + return this.templatesStore.getBySlug(this.slug) } }, watch: { slug () { - store.dispatch('open/templates/loadTemplate', this.slug) + this.templatesStore.loadTemplate(this.slug) } }, mounted () { - store.dispatch('open/templates/loadTemplate', this.slug) + this.templatesStore.loadTemplate(this.slug) }, methods: { diff --git a/resources/js/components/pages/templates/TemplateTags.vue b/resources/js/components/pages/templates/TemplateTags.vue index deac70898..b84cf7b1a 100644 --- a/resources/js/components/pages/templates/TemplateTags.vue +++ b/resources/js/components/pages/templates/TemplateTags.vue @@ -41,6 +41,9 @@ </template> <script> +import { computed } from 'vue' +import { useTemplatesStore } from '../../../stores/templates' + export default { props: { slug: { @@ -53,19 +56,26 @@ export default { } }, + setup () { + const templatesStore = useTemplatesStore() + return { + templatesStore + } + }, + data: () => ({}), computed: { template () { - return this.$store.getters['open/templates/getBySlug'](this.slug) + return this.templatesStore.getBySlug(this.slug) }, types () { if (!this.template) return null - return this.$store.getters['open/templates/getTemplateTypes'](this.template.types) + return this.templatesStore.getTemplateTypes(this.template.types) }, industries () { if (!this.template) return null - return this.$store.getters['open/templates/getTemplateIndustries'](this.template.industries) + return this.templatesStore.getTemplateIndustries(this.template.industries) } }, diff --git a/resources/js/components/pages/templates/TemplatesList.vue b/resources/js/components/pages/templates/TemplatesList.vue index 5b34ec306..5a2468f74 100644 --- a/resources/js/components/pages/templates/TemplatesList.vue +++ b/resources/js/components/pages/templates/TemplatesList.vue @@ -79,24 +79,25 @@ </template> <script> -import store from '~/store' -import { mapGetters, mapState } from 'vuex' +import { computed } from 'vue' +import { useAuthStore } from '../../../stores/auth' +import { useTemplatesStore } from '../../../stores/templates' import Form from 'vform' import Fuse from 'fuse.js' import SingleTemplate from './SingleTemplate.vue' const loadTemplates = function (onlyMy) { + const templatesStore = useTemplatesStore() if(onlyMy){ - store.dispatch('open/templates/loadAll', {'onlymy':true}) + templatesStore.loadAll({'onlymy':true}) } else { - store.dispatch('open/templates/loadIfEmpty') + templatesStore.loadIfEmpty() } } export default { name: 'TemplatesList', components: { SingleTemplate }, - props: { onlyMy: { type: Boolean, @@ -104,6 +105,18 @@ export default { } }, + setup () { + const authStore = useAuthStore() + const templatesStore = useTemplatesStore() + return { + user : computed(() => authStore.user), + templates : computed(() => templatesStore.content), + templatesLoading : computed(() => templatesStore.loading), + industries : computed(() => templatesStore.industries), + types : computed(() => templatesStore.types) + } + }, + data: () => ({ selectedType: 'all', selectedIndustry: 'all', @@ -119,15 +132,6 @@ export default { }, computed: { - ...mapState({ - templates: state => state['open/templates'].content, - templatesLoading: state => state['open/templates'].loading, - industries: state => state['open/templates'].industries, - types: state => state['open/templates'].types - }), - ...mapGetters({ - user: 'auth/user' - }), industriesOptions () { return [{ name: 'All Industries', value: 'all' }].concat(Object.values(this.industries).map((industry) => { return { diff --git a/resources/js/components/pages/welcome/AiFeature.vue b/resources/js/components/pages/welcome/AiFeature.vue index c24fdad14..ca599490a 100644 --- a/resources/js/components/pages/welcome/AiFeature.vue +++ b/resources/js/components/pages/welcome/AiFeature.vue @@ -87,16 +87,19 @@ </template> <script> -import {mapGetters} from 'vuex' +import { computed } from 'vue' +import { useAuthStore } from '../../../stores/auth' export default { - props: {}, - data: () => ({}), - computed: { - ...mapGetters({ - authenticated: 'auth/check' - }), - }, - methods: {} + setup () { + const authStore = useAuthStore() + return { + authenticated : computed(() => authStore.check) + } + }, + props: {}, + data: () => ({}), + computed: {}, + methods: {} } </script> diff --git a/resources/js/components/pages/welcome/TemplatesSlider.vue b/resources/js/components/pages/welcome/TemplatesSlider.vue index d3f0b2e0f..eb6725ecf 100644 --- a/resources/js/components/pages/welcome/TemplatesSlider.vue +++ b/resources/js/components/pages/welcome/TemplatesSlider.vue @@ -36,19 +36,23 @@ </template> <script> -import store from '~/store' -import { mapGetters, mapState } from 'vuex' +import { computed } from 'vue' +import { useTemplatesStore } from '../../../stores/templates' import SingleTemplate from '../templates/SingleTemplate.vue' export default { components: { SingleTemplate }, props: { }, + setup () { + const templatesStore = useTemplatesStore() + return { + templatesStore, + templates : computed(() => templatesStore.content) + } + }, data: () => ({}), computed: { - ...mapState({ - templates: state => state['open/templates'].content - }), sliderTemplates () { return this.templates.slice(0, 20) } @@ -66,7 +70,7 @@ export default { }, mounted() { - store.dispatch('open/templates/loadAll', { limit: 20 }) + this.templatesStore.loadAll({ limit: 20 }) }, methods: { diff --git a/resources/js/components/service/Amplitude.vue b/resources/js/components/service/Amplitude.vue index 30c3b7c1a..12afcbedf 100644 --- a/resources/js/components/service/Amplitude.vue +++ b/resources/js/components/service/Amplitude.vue @@ -1,12 +1,21 @@ <template /> <script> -import { mapGetters } from 'vuex' +import { computed } from 'vue' +import { useAuthStore } from '../../stores/auth' export default { - name: 'Amplitude', + setup () { + const authStore = useAuthStore() + return { + authStore, + authenticated : computed(() => authStore.check), + user : computed(() => authStore.user) + } + }, + data: function () { return { loaded: false, @@ -14,12 +23,7 @@ export default { } }, - computed: { - ...mapGetters({ - authenticated: 'auth/check', - user: 'auth/user' - }) - }, + computed: {}, watch: { $route () { diff --git a/resources/js/components/service/Hotjar.vue b/resources/js/components/service/Hotjar.vue index 66e54ab49..3c782bc31 100644 --- a/resources/js/components/service/Hotjar.vue +++ b/resources/js/components/service/Hotjar.vue @@ -1,12 +1,19 @@ <template /> <script> -import { mapGetters } from 'vuex' +import { computed } from 'vue' +import { useAuthStore } from '../../stores/auth' export default { - name: 'Hotjar', + setup () { + const authStore = useAuthStore() + return { + authenticated : computed(() => authStore.check), + } + }, + watch: { authenticated () { if (this.authenticated) { @@ -38,9 +45,6 @@ export default { }, computed: { - ...mapGetters({ - authenticated: 'auth/check' - }), isIframe () { return window.location !== window.parent.location || window.frameElement } diff --git a/resources/js/components/vendor/appsumo/AppSumoBilling.vue b/resources/js/components/vendor/appsumo/AppSumoBilling.vue index 5dcffbd71..24c1aac2a 100644 --- a/resources/js/components/vendor/appsumo/AppSumoBilling.vue +++ b/resources/js/components/vendor/appsumo/AppSumoBilling.vue @@ -21,23 +21,27 @@ </template> <script> -import { mapGetters } from 'vuex' +import { computed } from 'vue' +import { useAuthStore } from '../../../stores/auth' import VButton from '../../common/Button.vue' export default { - name: 'AppSumoBilling', components: { VButton }, + setup () { + const authStore = useAuthStore() + return { + user : computed(() => authStore.user), + } + }, + data () { return { } }, computed: { - ...mapGetters({ - user: 'auth/user' - }), licenseTier () { return this.user?.active_license?.meta?.tier }, @@ -67,10 +71,9 @@ export default { mounted () {}, - created () { - }, - destroyed () { - }, + created () {}, + + destroyed () {}, methods: {} } diff --git a/resources/js/middleware/admin.js b/resources/js/middleware/admin.js index 52145a6b9..097608027 100644 --- a/resources/js/middleware/admin.js +++ b/resources/js/middleware/admin.js @@ -1,7 +1,8 @@ -import store from '~/store' +import { useAuthStore } from '../stores/auth'; export default (to, from, next) => { - if (!store.getters['auth/user'].admin) { + const authStore = useAuthStore() + if (!authStore.user?.admin) { next({ name: 'home' }) } else { next() diff --git a/resources/js/middleware/auth.js b/resources/js/middleware/auth.js index 2bc1d7a30..d634d772e 100644 --- a/resources/js/middleware/auth.js +++ b/resources/js/middleware/auth.js @@ -1,8 +1,9 @@ -import store from '~/store' +import { useAuthStore } from '../stores/auth'; import Cookies from 'js-cookie' export default async (to, from, next) => { - if (!store.getters['auth/check']) { + const authStore = useAuthStore() + if (!authStore.check) { Cookies.set('intended_url', to.path) next({ name: 'login' }) diff --git a/resources/js/middleware/check-auth.js b/resources/js/middleware/check-auth.js index 8f6b10947..954a55d6d 100644 --- a/resources/js/middleware/check-auth.js +++ b/resources/js/middleware/check-auth.js @@ -1,4 +1,4 @@ -import store from '~/store' +import { useAuthStore } from '../stores/auth'; import * as Sentry from '@sentry/vue' export function initCrisp (user) { @@ -36,12 +36,13 @@ export function initSentry (user) { } export default async (to, from, next) => { - if (!store.getters['auth/check'] && - store.getters['auth/token'] !== null && - store.getters['auth/token'] !== undefined + const authStore = useAuthStore() + if (!authStore.check && + authStore.token !== null && + authStore.token !== undefined ) { try { - store.dispatch('auth/fetchUser').then((user) => { + authStore.fetchUser().then((user) => { initCrisp(user) initSentry(user) }) diff --git a/resources/js/middleware/guest.js b/resources/js/middleware/guest.js index dc45d6880..c6c78a7e4 100644 --- a/resources/js/middleware/guest.js +++ b/resources/js/middleware/guest.js @@ -1,7 +1,8 @@ -import store from '~/store' +import { useAuthStore } from '../stores/auth'; export default (to, from, next) => { - if (store.getters['auth/check']) { + const authStore = useAuthStore() + if (authStore.check) { next({ name: 'home' }) } else { next() diff --git a/resources/js/middleware/notion-connection.js b/resources/js/middleware/notion-connection.js index 1054cdcad..4a0d1792d 100644 --- a/resources/js/middleware/notion-connection.js +++ b/resources/js/middleware/notion-connection.js @@ -1,7 +1,8 @@ -import store from '~/store' +import { useAuthStore } from '../stores/auth'; export default async (to, from, next) => { - if (store.getters['auth/check'] && store.getters['auth/user'].workspaces_count === 0) { + const authStore = useAuthStore() + if (authStore.check && authStore.user?.workspaces_count === 0) { if ([ 'forms.create', 'forms.show', diff --git a/resources/js/middleware/role.js b/resources/js/middleware/role.js index c63a6cedb..a4f935282 100644 --- a/resources/js/middleware/role.js +++ b/resources/js/middleware/role.js @@ -1,4 +1,4 @@ -import store from '~/store' +import { useAuthStore } from '../stores/auth'; /** * This is middleware to check the current user role. @@ -7,14 +7,13 @@ import store from '~/store' */ export default (to, from, next, roles) => { - // Grab the user - const user = store.getters['auth/user'] - + const authStore = useAuthStore() + // Split roles into an array roles = roles.split(',') // Check if the user has one of the required roles... - if (!roles.includes(user.role)) { + if (!roles.includes(authStore.user?.role)) { next('/unauthorized') } diff --git a/resources/js/middleware/subscribed.js b/resources/js/middleware/subscribed.js index b8b4ba588..6b2f866e3 100644 --- a/resources/js/middleware/subscribed.js +++ b/resources/js/middleware/subscribed.js @@ -1,7 +1,8 @@ -import store from '~/store' +import { useAuthStore } from '../stores/auth'; export default (to, from, next) => { - if (!store.getters['auth/user'].is_subscribed) { + const authStore = useAuthStore() + if (!authStore.user?.is_subscribed) { next({ name: 'pricing' }) } else { next() diff --git a/resources/js/pages/ai-form-builder.vue b/resources/js/pages/ai-form-builder.vue index 304019441..e2d08a6c2 100644 --- a/resources/js/pages/ai-form-builder.vue +++ b/resources/js/pages/ai-form-builder.vue @@ -476,7 +476,8 @@ </template> <script> -import {mapGetters} from 'vuex' +import { computed } from 'vue' +import { useAuthStore } from '../stores/auth' import OpenFormFooter from '../components/pages/OpenFormFooter.vue' import SeoMeta from '../mixins/seo-meta.js' @@ -484,6 +485,14 @@ export default { components: {OpenFormFooter}, layout: 'default', mixins: [SeoMeta], + + setup () { + const authStore = useAuthStore() + return { + authenticated : computed(() => authStore.check), + } + }, + data: () => ({ title: window.config.appName, metaTitle: 'AI form builder for free', @@ -494,9 +503,6 @@ export default { methods: {}, computed: { - ...mapGetters({ - authenticated: 'auth/check' - }), configLinks: () => window.config.links } } diff --git a/resources/js/pages/auth/components/LoginForm.vue b/resources/js/pages/auth/components/LoginForm.vue index 9760fb448..63c008fc9 100644 --- a/resources/js/pages/auth/components/LoginForm.vue +++ b/resources/js/pages/auth/components/LoginForm.vue @@ -41,8 +41,10 @@ </template> <script> +import { computed } from 'vue' import Form from 'vform' import Cookies from 'js-cookie' +import { useAuthStore } from '../../../stores/auth' import OpenFormFooter from '../../../components/pages/OpenFormFooter.vue' import Testimonials from '../../../components/pages/welcome/Testimonials.vue' import ForgotPasswordModal from '../ForgotPasswordModal.vue' @@ -62,6 +64,13 @@ export default { } }, + setup () { + const authStore = useAuthStore() + return { + authStore + } + }, + data: () => ({ form: new Form({ email: '', @@ -77,13 +86,10 @@ export default { const { data } = await this.form.post('/api/login') // Save the token. - this.$store.dispatch('auth/saveToken', { - token: data.token, - remember: this.remember - }) + this.authStore.saveToken(data.token, this.remember) // Fetch the user. - await this.$store.dispatch('auth/fetchUser') + await this.authStore.fetchUser() // Redirect home. this.redirect() diff --git a/resources/js/pages/auth/components/RegisterForm.vue b/resources/js/pages/auth/components/RegisterForm.vue index d76048336..9eaab50d5 100644 --- a/resources/js/pages/auth/components/RegisterForm.vue +++ b/resources/js/pages/auth/components/RegisterForm.vue @@ -48,7 +48,9 @@ </template> <script> +import { computed } from 'vue' import Form from 'vform' +import { useAuthStore } from '../../../stores/auth' import { initCrisp } from '../../../middleware/check-auth.js' export default { @@ -62,6 +64,13 @@ export default { } }, + setup () { + const authStore = useAuthStore() + return { + authStore + } + }, + data: () => ({ form: new Form({ name: '', @@ -112,10 +121,10 @@ export default { const { data: { token } } = await this.form.post('/api/login') // Save the token. - this.$store.dispatch('auth/saveToken', { token }) + this.authStore.saveToken(token) // Update the user. - await this.$store.dispatch('auth/updateUser', { user: data }) + await this.authStore.updateUser(data) // Track event this.$logEvent('register', { source: this.form.hear_about_us }) diff --git a/resources/js/pages/forms/create-guest.vue b/resources/js/pages/forms/create-guest.vue index 35bc20057..c7fa539de 100644 --- a/resources/js/pages/forms/create-guest.vue +++ b/resources/js/pages/forms/create-guest.vue @@ -24,18 +24,21 @@ </template> <script> -import store from '~/store' +import { computed } from 'vue' import Form from 'vform' -import { mapState, mapActions } from 'vuex' +import { useTemplatesStore } from '../../stores/templates' +import { useWorkingFormStore } from '../../stores/working_form' +import { useWorkspacesStore } from '../../stores/workspaces' import QuickRegister from '../auth/components/QuickRegister.vue' import initForm from '../../mixins/form_editor/initForm.js' import SeoMeta from '../../mixins/seo-meta.js' import CreateFormBaseModal from '../../components/pages/forms/create/CreateFormBaseModal.vue' const loadTemplates = function () { - store.commit('open/templates/startLoading') - store.dispatch('open/templates/loadIfEmpty').then(() => { - store.commit('open/templates/stopLoading') + const templatesStore = useTemplatesStore() + templatesStore.startLoading() + templatesStore.loadIfEmpty().then(() => { + templatesStore.stopLoading() }) } @@ -45,13 +48,25 @@ export default { QuickRegister, CreateFormBaseModal }, mixins: [initForm, SeoMeta], + middleware: 'guest', beforeRouteEnter (to, from, next) { loadTemplates() next() }, - middleware: 'guest', + setup () { + const templatesStore = useTemplatesStore() + const workingFormStore = useWorkingFormStore() + const workspacesStore = useWorkspacesStore() + return { + templatesStore, + workingFormStore, + workspacesStore, + workspaces : computed(() => workspacesStore.content), + workspacesLoading : computed(() => workspacesStore.loading) + } + }, data () { return { @@ -66,21 +81,17 @@ export default { }, computed: { - ...mapState({ - workspaces: state => state['open/workspaces'].content, - workspacesLoading: state => state['open/workspaces'].loading - }), form: { get () { - return this.$store.state['open/working_form'].content + return this.workingFormStore.content }, /* We add a setter */ set (value) { - this.$store.commit('open/working_form/set', value) + this.workingFormStore.set(value) } }, workspace () { - return this.$store.getters['open/workspaces/getCurrent']() + return this.workspacesStore.getCurrent() } }, @@ -100,12 +111,12 @@ export default { is_enterprise: false, is_pro: false } - this.$store.commit('open/workspaces/set', [guestWorkspace]) - this.$store.commit('open/workspaces/setCurrentId', guestWorkspace.id) + this.workspacesStore.set([guestWorkspace]) + this.workspacesStore.setCurrentId(guestWorkspace.id) this.initForm() if (this.$route.query.template !== undefined && this.$route.query.template) { - const template = this.$store.getters['open/templates/getBySlug'](this.$route.query.template) + const template = this.templatesStore.getBySlug(this.$route.query.template) if (template && template.structure) { this.form = new Form({ ...this.form.data(), ...template.structure }) } @@ -121,16 +132,13 @@ export default { unmounted () {}, methods: { - ...mapActions({ - loadWorkspaces: 'open/workspaces/load' - }), openRegister () { this.registerModal = true }, afterLogin () { this.registerModal = false this.isGuest = false - this.loadWorkspaces() + this.workspacesStore.load() setTimeout(() => { if (this.$refs.editor) { this.$refs.editor.saveFormCreate() diff --git a/resources/js/pages/forms/create.vue b/resources/js/pages/forms/create.vue index 1490b38fd..07510d9d6 100644 --- a/resources/js/pages/forms/create.vue +++ b/resources/js/pages/forms/create.vue @@ -19,17 +19,21 @@ </template> <script> -import store from '~/store' import Form from 'vform' -import { mapState, mapActions } from 'vuex' +import { computed } from 'vue' +import { useAuthStore } from '../../stores/auth' +import { useTemplatesStore } from '../../stores/templates' +import { useWorkingFormStore } from '../../stores/working_form' +import { useWorkspacesStore } from '../../stores/workspaces' import initForm from '../../mixins/form_editor/initForm.js' import SeoMeta from '../../mixins/seo-meta.js' import CreateFormBaseModal from '../../components/pages/forms/create/CreateFormBaseModal.vue' const loadTemplates = function () { - store.commit('open/templates/startLoading') - store.dispatch('open/templates/loadIfEmpty').then(() => { - store.commit('open/templates/stopLoading') + const templatesStore = useTemplatesStore() + templatesStore.startLoading() + templatesStore.loadIfEmpty().then(() => { + templatesStore.stopLoading() }) } @@ -38,6 +42,7 @@ export default { components: { CreateFormBaseModal }, mixins: [initForm, SeoMeta], + middleware: 'auth', beforeRouteEnter (to, from, next) { loadTemplates() @@ -54,7 +59,20 @@ export default { next() }, - middleware: 'auth', + setup () { + const authStore = useAuthStore() + const templatesStore = useTemplatesStore() + const workingFormStore = useWorkingFormStore() + const workspacesStore = useWorkspacesStore() + return { + templatesStore, + workingFormStore, + workspacesStore, + user: computed(() => authStore.user), + workspaces : computed(() => workspacesStore.content), + workspacesLoading : computed(() => workspacesStore.loading) + } + }, data () { return { @@ -68,22 +86,17 @@ export default { }, computed: { - ...mapState({ - workspaces: state => state['open/workspaces'].content, - workspacesLoading: state => state['open/workspaces'].loading, - user: state => state.auth.user - }), form: { get () { - return this.$store.state['open/working_form'].content + return this.workingFormStore.content }, /* We add a setter */ set (value) { - this.$store.commit('open/working_form/set', value) + this.workingFormStore.set(value) } }, workspace () { - return this.$store.getters['open/workspaces/getCurrent']() + return this.workspacesStore.getCurrent() } }, @@ -108,7 +121,7 @@ export default { this.initForm() this.formInitialHash = this.hashString(JSON.stringify(this.form.data())) if (this.$route.query.template !== undefined && this.$route.query.template) { - const template = this.$store.getters['open/templates/getBySlug'](this.$route.query.template) + const template = this.templatesStore.getBySlug(this.$route.query.template) if (template && template.structure) { this.form = new Form({ ...this.form.data(), ...template.structure }) } @@ -117,7 +130,7 @@ export default { this.showInitialFormModal = true } this.closeAlert() - this.loadWorkspaces() + this.workspacesStore.loadIfEmpty() this.stateReady = this.user !== null }, @@ -126,9 +139,6 @@ export default { unmounted () {}, methods: { - ...mapActions({ - loadWorkspaces: 'open/workspaces/loadIfEmpty' - }), formGenerated (form) { this.form = new Form({ ...this.form.data(), ...form }) }, diff --git a/resources/js/pages/forms/edit.vue b/resources/js/pages/forms/edit.vue index 6e8cb61a2..a55d5589e 100644 --- a/resources/js/pages/forms/edit.vue +++ b/resources/js/pages/forms/edit.vue @@ -14,17 +14,20 @@ </template> <script> -import axios from 'axios' -import store from '~/store' -import Breadcrumb from '../../components/common/Breadcrumb.vue' +import { computed } from 'vue' import Form from 'vform' -import { mapState } from 'vuex' +import { useFormsStore } from '../../stores/forms' +import { useWorkingFormStore } from '../../stores/working_form' +import { useWorkspacesStore } from '../../stores/workspaces' +import Breadcrumb from '../../components/common/Breadcrumb.vue' import SeoMeta from '../../mixins/seo-meta.js' const loadForms = function () { - store.commit('open/forms/startLoading') - store.dispatch('open/workspaces/loadIfEmpty').then(() => { - store.dispatch('open/forms/load', store.state['open/workspaces'].currentId) + const formsStore = useFormsStore() + const workspacesStore = useWorkspacesStore() + formsStore.startLoading() + workspacesStore.loadIfEmpty().then(() => { + formsStore.load(workspacesStore.currentId) }) } @@ -32,12 +35,15 @@ export default { name: 'EditForm', components: { Breadcrumb }, mixins: [SeoMeta], + middleware: 'auth', beforeRouteEnter (to, from, next) { - if (!store.getters['open/forms/getBySlug'](to.params.slug)) { + const formsStore = useFormsStore() + const workingFormStore = useWorkingFormStore() + if (!formsStore.getBySlug(to.params.slug)) { loadForms() } - store.commit('open/working_form/set', null) // Reset old working form + workingFormStore.set(null) // Reset old working form next() }, @@ -51,7 +57,17 @@ export default { next() }, - middleware: 'auth', + setup () { + const formsStore = useFormsStore() + const workingFormStore = useWorkingFormStore() + const workspacesStore = useWorkspacesStore() + return { + formsStore, + workingFormStore, + workspacesStore, + formsLoading : computed(() => formsStore.loading) + } + }, data () { return { @@ -62,20 +78,17 @@ export default { }, computed: { - ...mapState({ - formsLoading: state => state['open/forms'].loading - }), updatedForm: { get () { - return this.$store.state['open/working_form'].content + return this.workingFormStore.content }, /* We add a setter */ set (value) { - this.$store.commit('open/working_form/set', value) + this.workingFormStore.set(value) } }, form () { - return this.$store.getters['open/forms/getBySlug'](this.$route.params.slug) + return this.formsStore.getBySlug(this.$route.params.slug) }, pageLoaded () { return !this.loading && this.updatedForm !== null diff --git a/resources/js/pages/forms/show-public.vue b/resources/js/pages/forms/show-public.vue index 176c5c4f2..154fcb461 100644 --- a/resources/js/pages/forms/show-public.vue +++ b/resources/js/pages/forms/show-public.vue @@ -50,8 +50,9 @@ <script> import axios from 'axios' -import store from '~/store' -import { mapState } from 'vuex' +import { computed } from 'vue' +import { useFormsStore } from '../../stores/forms' +import { useRecordsStore } from '../../stores/records' import OpenCompleteForm from '../../components/open/forms/OpenCompleteForm.vue' import Cookies from 'js-cookie' import sha256 from 'js-sha256' @@ -93,11 +94,12 @@ function handleTransparentMode (form) { } function loadForm (slug) { - if (store.state['open/forms'].loading) return - store.commit('open/forms/startLoading') + const formsStore = useFormsStore() + if (formsStore.loading) return + formsStore.startLoading() return axios.get('/api/forms/' + slug).then((response) => { const form = response.data - store.commit('open/forms/set', [response.data]) + formsStore.set([response.data]) // Custom code injection if (form.custom_code) { @@ -108,9 +110,9 @@ function loadForm (slug) { handleDarkMode(form) handleTransparentMode(form) - store.commit('open/forms/stopLoading') + formsStore.stopLoading() }).catch(() => { - store.commit('open/forms/stopLoading') + formsStore.stopLoading() }) } @@ -132,6 +134,17 @@ export default { next() }, + setup () { + const formsStore = useFormsStore() + const recordsStore = useRecordsStore() + return { + formsStore, + forms : computed(() => formsStore.content), + formLoading : computed(() => formsStore.loading), + recordLoading : computed(() => recordsStore.loading) + } + }, + data () { return { submitted: false @@ -166,16 +179,11 @@ export default { }, computed: { - ...mapState({ - forms: state => state['open/forms'].content, - formLoading: state => state['open/forms'].loading, - recordLoading: state => state['open/records'].loading - }), formSlug () { return this.$route.params.slug }, form () { - return this.$store.getters['open/forms/getBySlug'](this.formSlug) + return this.formsStore.getBySlug(this.formSlug) }, isIframe () { return window.location !== window.parent.location || window.frameElement diff --git a/resources/js/pages/forms/show/index.vue b/resources/js/pages/forms/show/index.vue index 095eb5301..48539af87 100644 --- a/resources/js/pages/forms/show/index.vue +++ b/resources/js/pages/forms/show/index.vue @@ -116,10 +116,12 @@ </template> <script> -import axios from 'axios' -import store from '~/store' +import { computed } from 'vue' import Form from 'vform' -import {mapGetters, mapState} from 'vuex' +import { useAuthStore } from '../../../stores/auth' +import { useFormsStore } from '../../../stores/forms' +import { useWorkingFormStore } from '../../../stores/working_form' +import { useWorkspacesStore } from '../../../stores/workspaces' import ProTag from '../../../components/common/ProTag.vue' import VButton from "../../../components/common/Button.vue"; import ExtraMenu from '../../../components/pages/forms/show/ExtraMenu.vue' @@ -127,9 +129,11 @@ import SeoMeta from '../../../mixins/seo-meta.js' import FormCleanings from '../../../components/pages/forms/show/FormCleanings.vue' const loadForms = function () { - store.commit('open/forms/startLoading') - store.dispatch('open/workspaces/loadIfEmpty').then(() => { - store.dispatch('open/forms/loadIfEmpty', store.state['open/workspaces'].currentId) + const formsStore = useFormsStore() + const workspacesStore = useWorkspacesStore() + formsStore.startLoading() + workspacesStore.loadIfEmpty().then(() => { + formsStore.loadIfEmpty(workspacesStore.currentId) }) } @@ -154,6 +158,21 @@ export default { }, middleware: 'auth', + setup () { + const authStore = useAuthStore() + const formsStore = useFormsStore() + const workingFormStore = useWorkingFormStore() + const workspacesStore = useWorkspacesStore() + return { + formsStore, + workingFormStore, + workspacesStore, + user : computed(() => authStore.user), + formsLoading : computed(() => formsStore.loading), + workspacesLoading : computed(() => workspacesStore.loading) + } + }, + data() { return { metaTitle: 'Home', @@ -175,27 +194,21 @@ export default { }, computed: { - ...mapGetters({ - user: 'auth/user' - }), - ...mapState({ - formsLoading: state => state['open/forms'].loading, - workspacesLoading: state => state['open/workspaces'].loading - }), workingForm: { - get() { - return this.$store.state['open/working_form'].content + get () { + return this.workingFormStore.content }, - set(value) { - this.$store.commit('open/working_form/set', value) + /* We add a setter */ + set (value) { + this.workingFormStore.set(value) } }, workspace() { if (!this.form) return null - return this.$store.getters['open/workspaces/getById'](this.form.workspace_id) + return this.workspacesStore.getById(this.form.workspace_id) }, form() { - return this.$store.getters['open/forms/getBySlug'](this.$route.params.slug) + return this.formsStore.getBySlug(this.$route.params.slug) }, formEndpoint: () => '/api/open/forms/{id}', loading() { diff --git a/resources/js/pages/home.vue b/resources/js/pages/home.vue index d87826250..2779761c2 100644 --- a/resources/js/pages/home.vue +++ b/resources/js/pages/home.vue @@ -104,8 +104,10 @@ </template> <script> -import store from '~/store' -import { mapGetters, mapState } from 'vuex' +import { computed } from 'vue' +import { useAuthStore } from '../stores/auth'; +import { useFormsStore } from '../stores/forms'; +import { useWorkspacesStore } from '../stores/workspaces'; import Fuse from 'fuse.js' import Form from 'vform' import TextInput from '../components/forms/TextInput.vue' @@ -113,9 +115,11 @@ import OpenFormFooter from '../components/pages/OpenFormFooter.vue' import ExtraMenu from '../components/pages/forms/show/ExtraMenu.vue' const loadForms = function () { - store.commit('open/forms/startLoading') - store.dispatch('open/workspaces/loadIfEmpty').then(() => { - store.dispatch('open/forms/loadIfEmpty', store.state['open/workspaces'].currentId) + const formsStore = useFormsStore() + const workspacesStore = useWorkspacesStore() + formsStore.startLoading() + workspacesStore.loadIfEmpty().then(() => { + formsStore.loadIfEmpty(workspacesStore.currentId) }) } @@ -133,6 +137,19 @@ export default { metaDescription: { type: String, default: 'All of your OpnForm are here. Create new forms, or update your existing one!' } }, + setup () { + const authStore = useAuthStore() + const formsStore = useFormsStore() + const workspacesStore = useWorkspacesStore() + return { + formsStore, + workspacesStore, + user : computed(() => authStore.user), + forms : computed(() => formsStore.content), + formsLoading : computed(() => formsStore.loading) + } + }, + data () { return { showEditFormModal: false, @@ -165,19 +182,12 @@ export default { }, computed: { - ...mapGetters({ - user: 'auth/user' - }), - ...mapState({ - forms: state => state['open/forms'].content, - formsLoading: state => state['open/forms'].loading - }), isFilteringForms () { return (this.searchForm.search !== '' && this.searchForm.search !== null) || this.selectedTags.length > 0 }, enrichedForms () { let enrichedForms = this.forms.map((form) => { - form.workspace = this.$store.getters['open/workspaces/getById'](form.workspace_id) + form.workspace = this.workspacesStore.getById(form.workspace_id) return form }) @@ -206,7 +216,7 @@ export default { }) }, allTags () { - return this.$store.getters['open/forms/getAllTags'] + return this.formsStore.getAllTags } } } diff --git a/resources/js/pages/pricing.vue b/resources/js/pages/pricing.vue index a83b22c92..7c371d013 100644 --- a/resources/js/pages/pricing.vue +++ b/resources/js/pages/pricing.vue @@ -236,14 +236,14 @@ </template> <script> -import {mapGetters} from 'vuex' +import { computed } from 'vue' +import { useAuthStore } from '../stores/auth'; import OpenFormFooter from '../components/pages/OpenFormFooter.vue' import PricingTable from '../components/pages/pricing/PricingTable.vue' import SeoMeta from '../mixins/seo-meta.js' export default { components: {OpenFormFooter, PricingTable}, - mixins: [SeoMeta], layout: 'default', @@ -257,20 +257,23 @@ export default { next() }, + setup () { + const authStore = useAuthStore() + return { + user : computed(() => authStore.user), + authenticated : computed(() => authStore.check) + } + }, + data: () => ({ metaTitle: 'Pricing', metaDescription: 'All of our core features are free, and there is no quantity limit. You can also created more advanced and customized forms with OpnForms Pro.', }), - mounted() { - }, + mounted() {}, + + computed: {}, - computed: { - ...mapGetters({ - authenticated: 'auth/check', - user: 'auth/user' - }) - }, methods: { contactUs() { window.$crisp.push(['do', 'chat:show']) diff --git a/resources/js/pages/settings/account.vue b/resources/js/pages/settings/account.vue index 7c23d355a..6cb4f690e 100644 --- a/resources/js/pages/settings/account.vue +++ b/resources/js/pages/settings/account.vue @@ -18,12 +18,20 @@ <script> import Form from 'vform' import axios from 'axios' +import { useAuthStore } from '../../stores/auth' import SeoMeta from '../../mixins/seo-meta.js' export default { scrollToTop: false, mixins: [SeoMeta], + setup () { + const authStore = useAuthStore() + return { + authStore + } + }, + data: () => ({ metaTitle: 'Account', form: new Form({ @@ -39,7 +47,7 @@ export default { this.loading = false this.alertSuccess(response.data.message) // Log out the user. - await this.$store.dispatch('auth/logout') + await this.authStore.logout() // Redirect to login. this.$router.push({ name: 'login' }) diff --git a/resources/js/pages/settings/admin.vue b/resources/js/pages/settings/admin.vue index 17afc959f..0781f64db 100644 --- a/resources/js/pages/settings/admin.vue +++ b/resources/js/pages/settings/admin.vue @@ -37,6 +37,8 @@ <script> import Form from 'vform' import axios from 'axios' +import { useAuthStore } from '../../stores/auth' +import { useWorkspacesStore } from '../../stores/workspaces' import SeoMeta from '../../mixins/seo-meta.js' export default { @@ -45,6 +47,15 @@ export default { scrollToTop: false, mixins: [SeoMeta], + setup () { + const authStore = useAuthStore() + const workspacesStore = useWorkspacesStore() + return { + authStore, + workspacesStore + } + }, + data: () => ({ metaTitle: 'Admin', form: new Form({ @@ -56,21 +67,18 @@ export default { methods: { async impersonate () { this.loading = true - this.$store.commit('auth/startImpersonating') + this.authStore.startImpersonating() axios.get('/api/admin/impersonate/' + encodeURI(this.form.identifier)).then(async (response) => { this.loading = false // Save the token. - this.$store.dispatch('auth/saveToken', { - token: response.data.token, - remember: false - }) + this.authStore.saveToken(response.data.token, false) // Fetch the user. - await this.$store.dispatch('auth/fetchUser') + await this.authStore.fetchUser() // Redirect to the dashboard. - this.$store.commit('open/workspaces/set', []) + this.workspacesStore.set([]) this.$router.push({ name: 'home' }) }).catch((error) => { this.alertError(error.response.data.message) diff --git a/resources/js/pages/settings/billing.vue b/resources/js/pages/settings/billing.vue index 47a497f2c..1ba8ef795 100644 --- a/resources/js/pages/settings/billing.vue +++ b/resources/js/pages/settings/billing.vue @@ -21,9 +21,10 @@ <script> import axios from 'axios' +import { computed } from 'vue' +import { useAuthStore } from '../../stores/auth' import VButton from '../../components/common/Button.vue' import SeoMeta from '../../mixins/seo-meta.js' -import { mapGetters } from 'vuex' import AppSumoBilling from '../../components/vendor/appsumo/AppSumoBilling.vue' export default { @@ -31,6 +32,13 @@ export default { mixins: [SeoMeta], scrollToTop: false, + setup () { + const authStore = useAuthStore() + return { + user : computed(() => authStore.user) + } + }, + data: () => ({ metaTitle: 'Billing', billingLoading: false @@ -50,10 +58,6 @@ export default { } }, - computed: { - ...mapGetters({ - user: 'auth/user' - }) - } + computed: {} } </script> diff --git a/resources/js/pages/settings/index.vue b/resources/js/pages/settings/index.vue index b371a513d..457d9983e 100644 --- a/resources/js/pages/settings/index.vue +++ b/resources/js/pages/settings/index.vue @@ -38,20 +38,25 @@ </template> <script> -import { mapGetters } from 'vuex' +import { computed } from 'vue' +import { useAuthStore } from '../../stores/auth' export default { middleware: 'auth', + setup () { + const authStore = useAuthStore() + return { + user : computed(() => authStore.user) + } + }, + data () { return { } }, computed: { - ...mapGetters({ - user: 'auth/user' - }), tabsList () { const tabs = [ { diff --git a/resources/js/pages/settings/profile.vue b/resources/js/pages/settings/profile.vue index a7287511a..efb114b6d 100644 --- a/resources/js/pages/settings/profile.vue +++ b/resources/js/pages/settings/profile.vue @@ -24,13 +24,22 @@ <script> import Form from 'vform' -import { mapGetters } from 'vuex' +import { computed } from 'vue' +import { useAuthStore } from '../../stores/auth' import SeoMeta from '../../mixins/seo-meta.js' export default { mixins: [SeoMeta], scrollToTop: false, + setup () { + const authStore = useAuthStore() + return { + authStore, + user : computed(() => authStore.user) + } + }, + data: () => ({ metaTitle: 'Profile', form: new Form({ @@ -39,10 +48,6 @@ export default { }) }), - computed: mapGetters({ - user: 'auth/user' - }), - created () { // Fill the form with user data. this.form.keys().forEach(key => { @@ -54,7 +59,7 @@ export default { async update () { const { data } = await this.form.patch('/api/settings/profile') - this.$store.dispatch('auth/updateUser', { user: data }) + this.authStore.updateUser(data) } } } diff --git a/resources/js/pages/settings/workspace.vue b/resources/js/pages/settings/workspace.vue index d0094deea..231763a59 100644 --- a/resources/js/pages/settings/workspace.vue +++ b/resources/js/pages/settings/workspace.vue @@ -73,8 +73,10 @@ </template> <script> +import { computed } from 'vue' import Form from 'vform' -import {mapActions, mapState} from 'vuex' +import { useFormsStore } from '../../stores/forms' +import { useWorkspacesStore } from '../../stores/workspaces' import SeoMeta from '../../mixins/seo-meta.js' export default { @@ -82,6 +84,17 @@ export default { scrollToTop: false, mixins: [SeoMeta], + setup () { + const formsStore = useFormsStore() + const workspacesStore = useWorkspacesStore() + return { + formsStore, + workspacesStore, + workspaces: computed(() => workspacesStore.content), + loading: computed(() => workspacesStore.loading) + } + }, + data: () => ({ metaTitle: 'Workspaces', form: new Form({ @@ -92,28 +105,20 @@ export default { }), mounted() { - this.loadWorkspaces() + this.workspacesStore.loadIfEmpty() }, - computed: { - ...mapState({ - workspaces: state => state['open/workspaces'].content, - loading: state => state['open/workspaces'].loading - }) - }, + computed: {}, methods: { - ...mapActions({ - loadWorkspaces: 'open/workspaces/loadIfEmpty' - }), switchWorkspace(workspace) { - this.$store.commit('open/workspaces/setCurrentId', workspace.id) + this.workspacesStore.setCurrentId(workspace.id) this.$router.push({name: 'home'}) - this.$store.dispatch('open/forms/load', workspace.id) + this.formsStore.load(workspace.id) }, deleteWorkspace(workspace) { this.alertConfirm('Do you really want to delete this workspace? All forms created in this workspace will be removed.', () => { - this.$store.dispatch('open/workspaces/delete', workspace.id).then(() => { + this.workspacesStore.delete(workspace.id).then(() => { this.alertSuccess('Workspace successfully removed.') }) }) @@ -129,7 +134,7 @@ export default { }, async createWorkspace() { const {data} = await this.form.post('/api/open/workspaces/create') - this.$store.dispatch('open/workspaces/load') + this.workspacesStore.load() this.workspaceModal = false } } diff --git a/resources/js/pages/subscriptions/error.vue b/resources/js/pages/subscriptions/error.vue index 894ad634b..fc33a4227 100644 --- a/resources/js/pages/subscriptions/error.vue +++ b/resources/js/pages/subscriptions/error.vue @@ -1,7 +1,8 @@ <template /> <script> -import { mapGetters } from 'vuex' +import { computed } from 'vue' +import { useAuthStore } from '../../stores/auth' import SeoMeta from '../../mixins/seo-meta.js' export default { @@ -10,6 +11,13 @@ export default { middleware: 'auth', mixins: [SeoMeta], + setup () { + const authStore = useAuthStore() + return { + authenticated : computed(() => authStore.check), + } + }, + data: () => ({ metaTitle: 'Error', }), @@ -19,10 +27,6 @@ export default { this.alertError('Unfortunately we could not confirm your subscription. Please try again and contact us if the issue persists.') }, - computed: { - ...mapGetters({ - authenticated: 'auth/check' - }) - } + computed: {} } </script> diff --git a/resources/js/pages/subscriptions/success.vue b/resources/js/pages/subscriptions/success.vue index b70467a3b..e8d976f64 100644 --- a/resources/js/pages/subscriptions/success.vue +++ b/resources/js/pages/subscriptions/success.vue @@ -16,7 +16,8 @@ </template> <script> -import { mapGetters } from 'vuex' +import { computed } from 'vue' +import { useAuthStore } from '../../stores/auth' import OpenFormFooter from '../../components/pages/OpenFormFooter.vue' import SeoMeta from '../../mixins/seo-meta.js' @@ -26,6 +27,15 @@ export default { layout: 'default', middleware: 'auth', + setup () { + const authStore = useAuthStore() + return { + authStore, + authenticated : computed(() => authStore.check), + user : computed(() => authStore.user) + } + }, + data: () => ({ metaTitle: 'Subscription Success', interval: null @@ -43,7 +53,7 @@ export default { methods: { async checkSubscription () { // Fetch the user. - await this.$store.dispatch('auth/fetchUser') + await this.authStore.fetchUser() this.redirectIfSubscribed() }, redirectIfSubscribed () { @@ -63,11 +73,6 @@ export default { } }, - computed: { - ...mapGetters({ - authenticated: 'auth/check', - user: 'auth/user' - }) - } + computed: {} } </script> diff --git a/resources/js/pages/templates/industries-show.vue b/resources/js/pages/templates/industries-show.vue index cee4b6394..ecfff178e 100644 --- a/resources/js/pages/templates/industries-show.vue +++ b/resources/js/pages/templates/industries-show.vue @@ -93,19 +93,21 @@ </template> <script> -import store from '~/store' import Form from 'vform' import Fuse from 'fuse.js' -import { mapGetters, mapState } from 'vuex' +import { computed } from 'vue' +import { useAuthStore } from '../../stores/auth' +import { useTemplatesStore } from '../../stores/templates' import SeoMeta from '../../mixins/seo-meta.js' import OpenFormFooter from '../../components/pages/OpenFormFooter.vue' import Breadcrumb from '../../components/common/Breadcrumb.vue' import SingleTemplate from '../../components/pages/templates/SingleTemplate.vue' const loadTemplates = function () { - store.commit('open/templates/startLoading') - store.dispatch('open/templates/loadIfEmpty').then(() => { - store.commit('open/templates/stopLoading') + const templatesStore = useTemplatesStore() + templatesStore.startLoading() + templatesStore.loadIfEmpty().then(() => { + templatesStore.stopLoading() }) } @@ -118,6 +120,20 @@ export default { next() }, + setup () { + const authStore = useAuthStore() + const templatesStore = useTemplatesStore() + return { + authStore, + authenticated : computed(() => authStore.check), + user : computed(() => authStore.user), + templates : computed(() => templatesStore.content), + templatesLoading : computed(() => templatesStore.loading), + industries : computed(() => templatesStore.industries), + types : computed(() => templatesStore.types) + } + }, + data () { return { selectedType: 'all', @@ -130,16 +146,6 @@ export default { mounted () {}, computed: { - ...mapGetters({ - authenticated: 'auth/check', - user: 'auth/user' - }), - ...mapState({ - templates: state => state['open/templates'].content, - templatesLoading: state => state['open/templates'].loading, - industries: state => state['open/templates'].industries, - types: state => state['open/templates'].types - }), breadcrumbs () { if (!this.industry) { return [{ route: { name: 'templates' }, label: 'Templates' }] diff --git a/resources/js/pages/templates/show.vue b/resources/js/pages/templates/show.vue index 204c79ac4..c1fed685b 100644 --- a/resources/js/pages/templates/show.vue +++ b/resources/js/pages/templates/show.vue @@ -196,9 +196,10 @@ </template> <script> -import store from '~/store' import Form from 'vform' -import { mapGetters, mapState } from 'vuex' +import { computed } from 'vue' +import { useAuthStore } from '../../stores/auth' +import { useTemplatesStore } from '../../stores/templates' import OpenFormFooter from '../../components/pages/OpenFormFooter.vue' import OpenCompleteForm from '../../components/open/forms/OpenCompleteForm.vue' import Breadcrumb from '../../components/common/Breadcrumb.vue' @@ -213,21 +214,32 @@ export default { mixins: [SeoMeta], beforeRouteEnter (to, from, next) { + const templatesStore = useTemplatesStore() if (to.params?.slug) { - store.dispatch('open/templates/loadTemplate', to.params?.slug) - store.dispatch('open/templates/loadTypesAndIndustries') + templatesStore.loadTemplate(to.params?.slug) + templatesStore.loadTypesAndIndustries() } next() }, + setup () { + const authStore = useAuthStore() + const templatesStore = useTemplatesStore() + return { + templatesStore, + authenticated : computed(() => authStore.check), + user : computed(() => authStore.user), + templatesLoading : computed(() => templatesStore.loading) + } + }, + data () { return { showFormTemplateModal: false } }, - mounted () { - }, + mounted () {}, methods: { cleanQuotes (str) { @@ -247,13 +259,6 @@ export default { }, computed: { - ...mapGetters({ - authenticated: 'auth/check', - user: 'auth/user' - }), - ...mapState({ - templatesLoading: state => state['open/templates'].loading - }), breadcrumbs () { if (!this.template) { return [{ route: { name: 'templates' }, label: 'Templates' }] @@ -261,7 +266,7 @@ export default { return [{ route: { name: 'templates' }, label: 'Templates' }, { label: this.template.name }] }, template () { - return this.$store.getters['open/templates/getBySlug'](this.$route.params.slug) + return this.templatesStore.getBySlug(this.$route.params.slug) }, form () { return this.template ? new Form(this.template.structure) : null diff --git a/resources/js/pages/templates/types-show.vue b/resources/js/pages/templates/types-show.vue index b91ef873d..805633c29 100644 --- a/resources/js/pages/templates/types-show.vue +++ b/resources/js/pages/templates/types-show.vue @@ -93,19 +93,21 @@ </template> <script> -import store from '~/store' import Form from 'vform' import Fuse from 'fuse.js' -import { mapGetters, mapState } from 'vuex' +import { computed } from 'vue' +import { useAuthStore } from '../../stores/auth' +import { useTemplatesStore } from '../../stores/templates' import SeoMeta from '../../mixins/seo-meta.js' import OpenFormFooter from '../../components/pages/OpenFormFooter.vue' import Breadcrumb from '../../components/common/Breadcrumb.vue' import SingleTemplate from '../../components/pages/templates/SingleTemplate.vue' const loadTemplates = function () { - store.commit('open/templates/startLoading') - store.dispatch('open/templates/loadIfEmpty').then(() => { - store.commit('open/templates/stopLoading') + const templatesStore = useTemplatesStore() + templatesStore.startLoading() + templatesStore.loadIfEmpty().then(() => { + templatesStore.stopLoading() }) } @@ -118,6 +120,19 @@ export default { next() }, + setup () { + const authStore = useAuthStore() + const templatesStore = useTemplatesStore() + return { + authenticated : computed(() => authStore.check), + user : computed(() => authStore.user), + templates : computed(() => templatesStore.content), + templatesLoading : computed(() => templatesStore.loading), + industries : computed(() => templatesStore.industries), + types : computed(() => templatesStore.types) + } + }, + data () { return { selectedIndustry: 'all', @@ -130,16 +145,6 @@ export default { mounted () {}, computed: { - ...mapGetters({ - authenticated: 'auth/check', - user: 'auth/user' - }), - ...mapState({ - templates: state => state['open/templates'].content, - templatesLoading: state => state['open/templates'].loading, - industries: state => state['open/templates'].industries, - types: state => state['open/templates'].types - }), breadcrumbs () { if (!this.type) { return [{ route: { name: 'templates' }, label: 'Templates' }] diff --git a/resources/js/pages/welcome.vue b/resources/js/pages/welcome.vue index 58bce1119..fbc76f026 100644 --- a/resources/js/pages/welcome.vue +++ b/resources/js/pages/welcome.vue @@ -181,7 +181,8 @@ </template> <script> -import { mapGetters } from 'vuex' +import { computed } from 'vue' +import { useAuthStore } from '../stores/auth' import Features from '~/components/pages/welcome/Features.vue' import MoreFeatures from '~/components/pages/welcome/MoreFeatures.vue' import PricingTable from '../components/pages/pricing/PricingTable.vue' @@ -193,11 +194,16 @@ import SeoMeta from '../mixins/seo-meta.js' export default { components: { Testimonials, OpenFormFooter, Features, MoreFeatures, PricingTable, AiFeature, TemplatesSlider }, - mixins: [SeoMeta], - layout: 'default', + setup () { + const authStore = useAuthStore() + return { + authenticated : computed(() => authStore.check) + } + }, + data: () => ({ title: window.config.appName, metaTitle: 'Create beautiful & open-source forms for free' @@ -215,9 +221,6 @@ export default { }, computed: { - ...mapGetters({ - authenticated: 'auth/check' - }), configLinks: () => window.config.links, paidPlansEnabled () { return window.config.paid_plans_enabled diff --git a/resources/js/plugins/axios.js b/resources/js/plugins/axios.js index 7cab8dfab..f5f525fc2 100644 --- a/resources/js/plugins/axios.js +++ b/resources/js/plugins/axios.js @@ -1,5 +1,5 @@ import axios from 'axios' -import store from '~/store' +import { useAuthStore } from '../stores/auth'; import router from '~/router' import Cookies from 'js-cookie' @@ -17,16 +17,13 @@ function addPasswordToFormRequest (request) { // Request interceptor axios.interceptors.request.use(request => { - const token = store.getters['auth/token'] + const authStore = useAuthStore() + const token = authStore.token if (token) { request.headers.common.Authorization = `Bearer ${token}` } - const locale = store.getters['lang/locale'] - if (locale) { - request.headers.common['Accept-Language'] = locale - } - + request.headers.common['Accept-Language'] = 'en-US' // request.headers['X-Socket-Id'] = Echo.socketId() request = addPasswordToFormRequest(request) @@ -36,14 +33,14 @@ axios.interceptors.request.use(request => { // Response interceptor axios.interceptors.response.use(response => response, error => { + const authStore = useAuthStore() const { status } = error.response if (status >= 500) { console.log(status) } - if (status === 401 && store.getters['auth/check']) { - store.commit('auth/LOGOUT') - + if (status === 401 && authStore.check) { + authStore.logout() router.push({ name: 'login' }) } diff --git a/resources/js/router/index.js b/resources/js/router/index.js index a9c8ffc3c..b9dec2a21 100644 --- a/resources/js/router/index.js +++ b/resources/js/router/index.js @@ -1,7 +1,7 @@ import routes from './routes' import { createWebHistory, createRouter } from 'vue-router' import * as Sentry from '@sentry/vue' -import store from '../store' +import { useAppStore } from '../stores/app' import { defineComponent, nextTick } from 'vue' // The middleware for every page of the application. @@ -45,6 +45,8 @@ async function getMatchedComponents (to) { * @param {Function} next */ async function beforeEach (to, from, next) { + const appStore = useAppStore() + // Sentry tracking if (window.config.sentry_dsn) { Sentry.configureScope((scope) => scope.setTransactionName(to?.name || 'Unknown route name')) @@ -75,7 +77,7 @@ async function beforeEach (to, from, next) { // Start the loading bar. if (components[components.length - 1].loading !== false) { - nextTick(() => store.commit('app/loaderStart')) + nextTick(() => appStore.loaderStart()) } // Get the middleware for all the matched components. @@ -86,11 +88,11 @@ async function beforeEach (to, from, next) { // Set the application layout only if "next()" was called with no args. if (args.length === 0) { if (components[0].layout) { - store.commit('app/setLayout', components[0].layout) + appStore.setLayout(components[0].layout) } else if (components[0].default && components[0].default.layout) { - store.commit('app/setLayout', components[0].default.layout) + appStore.setLayout(components[0].default.layout) } else { - store.commit('app/setLayout', null) + appStore.setLayout(null) } } @@ -106,7 +108,8 @@ async function beforeEach (to, from, next) { * @param {Function} next */ async function afterEach (to, from, next) { - nextTick(() => store.commit('app/loaderFinish')) + const appStore = useAppStore() + nextTick(() => appStore.loaderFinish()) } /** @@ -118,13 +121,14 @@ async function afterEach (to, from, next) { * @param {Function} next */ function callMiddleware (middleware, to, from, next) { + const appStore = useAppStore() const stack = middleware.reverse() const _next = (...args) => { // Stop if "_next" was called with an argument or the stack is empty. if (args.length > 0 || stack.length === 0) { if (args.length > 0) { - store.commit('app/loaderFinish') + appStore.loaderFinish() } return next(...args) diff --git a/resources/js/store/index.js b/resources/js/store/index.js deleted file mode 100644 index baa637ffd..000000000 --- a/resources/js/store/index.js +++ /dev/null @@ -1,22 +0,0 @@ -import Vue from 'vue' -import Vuex from 'vuex' - -Vue.use(Vuex) - -// Load store modules dynamically. -const requireContext = import.meta.glob('./modules/**/*.js', {eager: true}) -const modules = Object.keys(requireContext) - - .map(file => - [file.replace(/(^.\/)|(\.js$)/g, '').replace('modules/',''), requireContext[file]] - ) - .reduce((modules, [name, module]) => { - if (module.namespaced === undefined) { - module = {...module, namespaced: true} - } - - return { ...modules, [name]: module } - }, {}) -export default new Vuex.Store({ - modules -}) diff --git a/resources/js/store/modules/app.js b/resources/js/store/modules/app.js deleted file mode 100644 index 5a459331d..000000000 --- a/resources/js/store/modules/app.js +++ /dev/null @@ -1,73 +0,0 @@ -import { nextTick } from 'vue' - -export const state = { - layout: 'default', - - // App Loader - loader: { - percent: 0, - show: false, - canSuccess: true, - duration: 3000, - _timer: null, - _cut: null - } -} - -export const mutations = { - setLayout (state, layout) { - state.layout = layout ?? 'default' - }, - loaderStart (state) { - state.loader.show = true - state.loader.canSuccess = true - if (state.loader._timer) { - clearInterval(state.loader._timer) - state.loader.percent = 0 - } - state.loader._cut = 10000 / Math.floor(state.loader.duration) - }, - loaderIncrease (state, num) { - state.loader.percent = state.loader.percent + Math.floor(num) - }, - loaderDecrease (state, num) { - state.loader.percent = state.loader.percent - Math.floor(num) - }, - loaderFinish (state) { - state.loader.percent = 100 - mutations.loaderHide(state) - }, - loaderSetTimer (state, timerVal) { - state._timer = timerVal - }, - loaderPause (state) { - clearInterval(state.loader._timer) - }, - loaderHide (state) { - clearInterval(state.loader._timer) - state.loader._timer = null - setTimeout(() => { - state.loader.show = false - nextTick(() => { - setTimeout(() => { - state.loader.percent = 0 - }, 200) - }) - }, 500) - }, - loaderFail () { - state.loader.canSuccess = false - } -} - -export const actions = { - loaderStart ({ commit, dispatch }) { - mutations.loaderStart() - mutations.loaderSetTimer(setInterval(() => { - mutations.loaderIncrease(state.loader._cut * Math.random()) - if (state.loader.percent > 95) { - mutations.loaderFinish() - } - }, 100)) - } -} diff --git a/resources/js/store/modules/auth.js b/resources/js/store/modules/auth.js deleted file mode 100644 index f76cf4a57..000000000 --- a/resources/js/store/modules/auth.js +++ /dev/null @@ -1,104 +0,0 @@ -import axios from 'axios' -import Cookies from 'js-cookie' -import * as types from '../mutation-types' - -// state -export const state = { - user: null, - token: Cookies.get('token'), - - // For admin impersonation - admin_token: Cookies.get('admin_token') ?? null -} - -// getters -export const getters = { - user: state => state.user, - token: state => state.token, - check: state => state.user !== null, - isImpersonating: state => state.admin_token !== null -} - -// mutations -export const mutations = { - [types.SAVE_TOKEN] (state, { token, remember }) { - state.token = token - Cookies.set('token', token, { expires: remember ? 365 : null }) - }, - - [types.FETCH_USER_SUCCESS] (state, { user }) { - state.user = user - }, - - [types.FETCH_USER_FAILURE] (state) { - state.token = null - Cookies.remove('token') - }, - - [types.LOGOUT] (state) { - state.user = null - state.token = null - - Cookies.remove('token') - }, - - [types.UPDATE_USER] (state, { user }) { - state.user = user - }, - - // Stores admin token temporarily for impersonation - startImpersonating (state) { - state.admin_token = state.token - Cookies.set('admin_token', state.token, { expires: 365 }) - }, - - // Stores admin token temporarily for impersonation - stopImpersonating (state) { - state.token = state.admin_token - state.admin_token = null - Cookies.set('token', state.token, { expires: 365 }) - Cookies.remove('admin_token') - } -} - -// actions -export const actions = { - saveToken ({ commit, dispatch }, payload) { - commit(types.SAVE_TOKEN, payload) - }, - - async fetchUser ({ commit }) { - try { - const { data } = await axios.get('/api/user') - - commit(types.FETCH_USER_SUCCESS, { user: data }) - return data - } catch (e) { - commit(types.FETCH_USER_FAILURE) - } - }, - - updateUser ({ commit }, payload) { - commit(types.UPDATE_USER, payload) - }, - - async logout ({ commit }) { - try { - await axios.post('/api/logout') - } catch (e) { } - - commit(types.LOGOUT) - }, - - async fetchOauthUrl (ctx, { provider }) { - const { data } = await axios.post(`/api/oauth/${provider}`) - - return data.url - }, - - // Reverse admin impersonation - stopImpersonating ({ commit, dispatch }, payload) { - commit('stopImpersonating') - return dispatch('fetchUser') - } -} diff --git a/resources/js/store/modules/blog/guides.js b/resources/js/store/modules/blog/guides.js deleted file mode 100644 index fad7068d9..000000000 --- a/resources/js/store/modules/blog/guides.js +++ /dev/null @@ -1,35 +0,0 @@ -import Vue from 'vue' - -export const namespaced = true - -// state -export const state = { - content: [] -} - -// getters -export const getters = { - getById: (state) => (id) => { - if (state.content.length === 0) return null - return state.content.find(item => item.id === id) - } -} - -// mutations -export const mutations = { - set (state, items) { - state.content = items - }, - addOrUpdate (state, item) { - state.content = state.content.filter((val) => val.id !== item.id) - state.content.push(item) - }, - remove (state, item) { - state.content = state.content.filter((val) => val.id !== item.id) - } -} - -// actions -export const actions = { - -} diff --git a/resources/js/store/modules/open/errors.js b/resources/js/store/modules/open/errors.js deleted file mode 100644 index 45226a3d4..000000000 --- a/resources/js/store/modules/open/errors.js +++ /dev/null @@ -1,27 +0,0 @@ -import Vue from 'vue' - -export const namespaced = true - -// state -export const state = { - content: null -} - -// getters -export const getters = { -} - -// mutations -export const mutations = { - set (state, error) { - state.content = error - }, - clear (state) { - state.content = null - } -} - -// actions -export const actions = { - -} diff --git a/resources/js/store/modules/open/forms.js b/resources/js/store/modules/open/forms.js deleted file mode 100644 index ae9b237d0..000000000 --- a/resources/js/store/modules/open/forms.js +++ /dev/null @@ -1,85 +0,0 @@ -import axios from 'axios' - -export const formsEndpoint = '/api/open/workspaces/{workspaceId}/forms' -export const namespaced = true -export let currentPage = 1 - -// state -export const state = { - content: [], - loading: false -} - -// getters -export const getters = { - getById: (state) => (id) => { - if (state.content.length === 0) return null - return state.content.find(item => item.id === id) - }, - getBySlug: (state) => (slug) => { - if (state.content.length === 0) return null - return state.content.find(item => item.slug === slug) - }, - getAllTags: (state) => { - if (state.content.length === 0) return [] - let allTags = [] - state.content.forEach(form => { - if(form.tags && form.tags.length > 0){ - allTags = allTags.concat(form.tags) - } - }) - return allTags.filter((item, i, ar) => ar.indexOf(item) === i) - } -} - -// mutations -export const mutations = { - set (state, items) { - state.content = items - }, - append (state, items) { - state.content = state.content.concat(items) - }, - addOrUpdate (state, item) { - state.content = state.content.filter((val) => val.id !== item.id) - state.content.push(item) - }, - remove (state, item) { - state.content = state.content.filter((val) => val.id !== item.id) - }, - startLoading (state) { - state.loading = true - }, - stopLoading (state) { - state.loading = false - } -} - -// actions -export const actions = { - resetState (context) { - context.commit('set', []) - context.commit('stopLoading') - currentPage = 1 - }, - load (context, workspaceId) { - context.commit('startLoading') - return axios.get(formsEndpoint.replace('{workspaceId}', workspaceId)+'?page='+currentPage).then((response) => { - context.commit((currentPage == 1) ? 'set' : 'append', response.data.data) - if (currentPage < response.data.meta.last_page) { - currentPage += 1 - context.dispatch('load', workspaceId) - } else { - context.commit('stopLoading') - currentPage = 1 - } - }) - }, - loadIfEmpty (context, workspaceId) { - if (context.state.content.length === 0) { - return context.dispatch('load', workspaceId) - } - context.commit('stopLoading') - return Promise.resolve() - } -} diff --git a/resources/js/store/modules/open/records.js b/resources/js/store/modules/open/records.js deleted file mode 100644 index 8bb0e8844..000000000 --- a/resources/js/store/modules/open/records.js +++ /dev/null @@ -1,58 +0,0 @@ -import axios from 'axios' - -export const namespaced = true -export const workspaceEndpoint = '/api/open/records/' - -/** - * Loads records from database - */ - -// state -export const state = { - content: [], - loading: false -} - -// getters -export const getters = { - getById: (state) => (id) => { - if (state.content.length === 0) return null - return state.content.find(item => item.submission_id === id) - } -} - -// mutations -export const mutations = { - set (state, items) { - state.content = items - }, - addOrUpdate (state, item) { - state.content = state.content.filter((val) => val.id !== item.id) - state.content.push(item) - }, - remove (state, itemId) { - state.content = state.content.filter((val) => val.id !== itemId) - }, - startLoading () { - state.loading = true - }, - stopLoading () { - state.loading = false - } -} - -// actions -export const actions = { - resetState (context) { - context.commit('set', []) - context.commit('stopLoading') - }, - loadRecord (context, request) { - context.commit('set', []) - context.commit('startLoading') - return request.then((data) => { - context.commit('addOrUpdate', data) - context.commit('stopLoading') - }) - } -} \ No newline at end of file diff --git a/resources/js/store/modules/open/templates.js b/resources/js/store/modules/open/templates.js deleted file mode 100644 index 15f96de67..000000000 --- a/resources/js/store/modules/open/templates.js +++ /dev/null @@ -1,126 +0,0 @@ -import axios from 'axios' - -export const templatesEndpoint = '/api/templates' -export const namespaced = true - -// state -export const state = { - content: [], - industries: {}, - types: {}, - allLoaded: false, - loading: false -} - -// getters -export const getters = { - getBySlug: (state) => (slug) => { - if (state.content.length === 0) return null - return state.content.find(item => item.slug === slug) - }, - getTemplateTypes: (state) => (slugs) => { - if (state.types.length === 0) return null - return Object.values(state.types).filter((val) => slugs.includes(val.slug)).map((item) => { return item.name }) - }, - getTemplateIndustries: (state) => (slugs) => { - if (state.industries.length === 0) return null - return Object.values(state.industries).filter((val) => slugs.includes(val.slug)).map((item) => { return item.name }) - } -} - -// mutations -export const mutations = { - set (state, items) { - state.content = items - state.allLoaded = true - }, - append (state, items) { - const ids = items.map((item) => { return item.id }) - state.content = state.content.filter((val) => !ids.includes(val.id)) - state.content = state.content.concat(items) - }, - addOrUpdate (state, item) { - state.content = state.content.filter((val) => val.id !== item.id) - state.content.push(item) - }, - remove (state, item) { - state.content = state.content.filter((val) => val.id !== item.id) - }, - startLoading (state) { - state.loading = true - }, - stopLoading (state) { - state.loading = false - }, - setAllLoaded (state, val) { - state.allLoaded = val - } -} - -// actions -export const actions = { - resetState (context) { - context.commit('set', []) - context.commit('stopLoading') - }, - loadTypesAndIndustries (context) { - if (Object.keys(context.state.industries).length === 0) { - import('@/data/forms/templates/industries.json').then((module) => { - context.state.industries = module.default - }) - } - if (Object.keys(context.state.types).length === 0) { - import('@/data/forms/templates/types.json').then((module) => { - context.state.types = module.default - }) - } - }, - loadTemplate (context, slug) { - context.commit('startLoading') - context.dispatch('loadTypesAndIndustries') - - if (context.getters.getBySlug(slug)) { - context.commit('stopLoading') - return Promise.resolve() - } - - return axios.get(templatesEndpoint + '/' + slug).then((response) => { - context.commit('addOrUpdate', response.data) - context.commit('stopLoading') - }).catch((error) => { - context.commit('stopLoading') - }) - }, - loadAll (context, options=null) { - context.commit('startLoading') - context.dispatch('loadTypesAndIndustries') - - // Prepare with options - let queryStr = '' - if(options !== null){ - for (const [key, value] of Object.entries(options)) { - queryStr += '&' + encodeURIComponent(key) + '=' + encodeURIComponent(value) - } - queryStr = queryStr.slice(1) - } - return axios.get((queryStr) ? templatesEndpoint + '?' + queryStr : templatesEndpoint).then((response) => { - if(options !== null){ - context.commit('set', response.data) - context.commit('setAllLoaded', false) - } else { - context.commit('append', response.data) - context.commit('setAllLoaded', true) - } - context.commit('stopLoading') - }).catch((error) => { - context.commit('stopLoading') - }) - }, - loadIfEmpty (context) { - if (!context.state.allLoaded) { - return context.dispatch('loadAll') - } - context.commit('stopLoading') - return Promise.resolve() - } -} diff --git a/resources/js/store/modules/open/working_form.js b/resources/js/store/modules/open/working_form.js deleted file mode 100644 index 045b2e948..000000000 --- a/resources/js/store/modules/open/working_form.js +++ /dev/null @@ -1,49 +0,0 @@ -export const namespaced = true - -// state -export const state = { - content: null, - - // Field being edited - selectedFieldIndex: null, - showEditFieldSidebar: null, - showAddFieldSidebar: null -} - -// mutations -export const mutations = { - set (state, form) { - state.content = form - }, - setProperties (state, properties) { - state.content.properties = properties - }, - openSettingsForField (state, index) { - // If field is passed, compute index - if (typeof index === 'object') { - index = state.content.properties.findIndex(prop => prop.id === index.id) - } - state.selectedFieldIndex = index - state.showEditFieldSidebar = true - state.showAddFieldSidebar = false - }, - closeEditFieldSidebar (state) { - state.selectedFieldIndex = null - state.showEditFieldSidebar = false - state.showAddFieldSidebar = false - }, - openAddFieldSidebar (state, index) { - // If field is passed, compute index - if (index !== null && typeof index === 'object') { - index = state.content.properties.findIndex(prop => prop.id === index.id) - } - state.selectedFieldIndex = index - state.showAddFieldSidebar = true - state.showEditFieldSidebar = false - }, - closeAddFieldSidebar (state) { - state.selectedFieldIndex = null - state.showAddFieldSidebar = false - state.showEditFieldSidebar = false - }, -} diff --git a/resources/js/store/modules/open/workspaces.js b/resources/js/store/modules/open/workspaces.js deleted file mode 100644 index c14becf19..000000000 --- a/resources/js/store/modules/open/workspaces.js +++ /dev/null @@ -1,100 +0,0 @@ -import Vue from 'vue' -import axios from 'axios' - -export const namespaced = true -export const workspaceEndpoint = '/api/open/workspaces/' - -const localStorageCurrentWorkspaceKey = 'currentWorkspace' - -// state -export const state = { - content: [], - currentId: null, - loading: false -} - -// getters -export const getters = { - getById: (state) => (id) => { - if (state.content.length === 0) return null - return state.content.find(item => item.id === id) - }, - getCurrent: (state) => () => { - if (state.content.length === 0 || state.currentId === null) return null - return state.content.find(item => item.id === state.currentId) - } -} - -// mutations -export const mutations = { - set (state, items) { - state.content = items - if (state.currentId == null && state.content.length > 0) { - // If one only, set it - if (state.content.length === 1) { - state.currentId = items[0].id - localStorage.setItem(localStorageCurrentWorkspaceKey, state.currentId) - } else if (localStorage.getItem(localStorageCurrentWorkspaceKey) && state.content.find(item => item.id === parseInt(localStorage.getItem(localStorageCurrentWorkspaceKey)))) { - // Check local storage for current workspace, or take first - state.currentId = parseInt(localStorage.getItem(localStorageCurrentWorkspaceKey)) - localStorage.setItem(localStorageCurrentWorkspaceKey, state.currentId) - } else { - // Else, take first - state.currentId = items[0].id - localStorage.setItem(localStorageCurrentWorkspaceKey, state.currentId) - } - } else { - localStorage.removeItem(localStorageCurrentWorkspaceKey) - } - }, - setCurrentId (state, id) { - state.currentId = id - localStorage.setItem(localStorageCurrentWorkspaceKey, id) - }, - addOrUpdate (state, item) { - state.content = state.content.filter((val) => val.id !== item.id) - state.content.push(item) - if (state.currentId == null) { - state.currentId = item.id - localStorage.setItem(localStorageCurrentWorkspaceKey, state.currentId) - } - }, - remove (state, itemId) { - state.content = state.content.filter((val) => val.id !== itemId) - }, - startLoading () { - state.loading = true - }, - stopLoading () { - state.loading = false - } -} - -// actions -export const actions = { - resetState (context) { - context.commit('set', []) - context.commit('stopLoading') - }, - load (context) { - context.commit('set', []) - context.commit('startLoading') - return axios.get(workspaceEndpoint).then((response) => { - context.commit('set', response.data) - context.commit('stopLoading') - }) - }, - loadIfEmpty ({ context, dispatch, state }) { - if (state.content.length === 0) { - return dispatch('load') - } - return Promise.resolve() - }, - delete ({ commit, dispatch, state }, id) { - commit('startLoading') - return axios.delete(workspaceEndpoint + id).then((response) => { - commit('remove', response.data.workspace_id) - commit('stopLoading') - }) - } -} diff --git a/resources/js/store/mutation-types.js b/resources/js/store/mutation-types.js deleted file mode 100644 index 23ccf7b83..000000000 --- a/resources/js/store/mutation-types.js +++ /dev/null @@ -1,10 +0,0 @@ -// auth.js -export const LOGOUT = 'LOGOUT' -export const SAVE_TOKEN = 'SAVE_TOKEN' -export const FETCH_USER = 'FETCH_USER' -export const FETCH_USER_SUCCESS = 'FETCH_USER_SUCCESS' -export const FETCH_USER_FAILURE = 'FETCH_USER_FAILURE' -export const UPDATE_USER = 'UPDATE_USER' - -// lang.js -export const SET_LOCALE = 'SET_LOCALE' diff --git a/resources/js/stores/app.js b/resources/js/stores/app.js new file mode 100644 index 000000000..c4bce816f --- /dev/null +++ b/resources/js/stores/app.js @@ -0,0 +1,71 @@ + +import { defineStore } from 'pinia' +import { nextTick } from 'vue' + +export const useAppStore = defineStore('app', { + state: () => ({ + layout: 'default', + + // App Loader + loader: { + percent: 0, + show: false, + canSuccess: true, + duration: 3000, + _timer: null, + _cut: null + } + }), + actions: { + setLayout (layout) { + this.layout = layout ?? 'default' + }, + loaderIncrease (num) { + this.loader.percent = this.loader.percent + Math.floor(num) + }, + loaderDecrease (num) { + this.loader.percent = this.loader.percent - Math.floor(num) + }, + loaderFinish () { + this.loader.percent = 100 + this.loaderHide() + }, + loaderSetTimer (timerVal) { + this._timer = timerVal + }, + loaderPause () { + clearInterval(this.loader._timer) + }, + loaderHide () { + clearInterval(this.loader._timer) + this.loader._timer = null + setTimeout(() => { + this.loader.show = false + nextTick(() => { + setTimeout(() => { + this.loader.percent = 0 + }, 200) + }) + }, 500) + }, + loaderFail () { + this.loader.canSuccess = false + }, + loaderStart () { + this.loader.show = true + this.loader.canSuccess = true + if (this.loader._timer) { + clearInterval(this.loader._timer) + this.loader.percent = 0 + } + this.loader._cut = 10000 / Math.floor(this.loader.duration) + + this.loaderSetTimer(setInterval(() => { + this.loaderIncrease(this.loader._cut * Math.random()) + if (this.loader.percent > 95) { + this.loaderFinish() + } + }, 100)) + } + } +}) \ No newline at end of file diff --git a/resources/js/stores/auth.js b/resources/js/stores/auth.js new file mode 100644 index 000000000..48c16363c --- /dev/null +++ b/resources/js/stores/auth.js @@ -0,0 +1,67 @@ +import { defineStore } from 'pinia' +import axios from 'axios' +import Cookies from 'js-cookie' + +export const useAuthStore = defineStore('auth', { + state: () => ({ + user: null, + token: Cookies.get('token'), + + // For admin impersonation + admin_token: Cookies.get('admin_token') ?? null + }), + getters: { + check: (state) => (state.user !== null && state.user !== undefined), + isImpersonating: (state) => (state.admin_token !== null && state.admin_token !== undefined) + }, + actions: { + // Stores admin token temporarily for impersonation + startImpersonating () { + this.admin_token = this.token + Cookies.set('admin_token', this.token, { expires: 365 }) + }, + // Stop admin impersonation + stopImpersonating () { + this.token = this.admin_token + this.admin_token = null + Cookies.set('token', this.token, { expires: 365 }) + Cookies.remove('admin_token') + this.fetchUser() + }, + + saveToken (token, remember) { + this.token = token + Cookies.set('token', token, { expires: remember ? 365 : null }) + }, + + async fetchUser () { + try { + const { data } = await axios.get('/api/user') + this.user = data + return data + } catch (e) { + this.token = null + Cookies.remove('token') + } + }, + + updateUser (payload) { + this.user = payload + }, + + async logout () { + try { + await axios.post('/api/logout') + } catch (e) { } + + this.user = null + this.token = null + Cookies.remove('token') + }, + + async fetchOauthUrl (provider) { + const { data } = await axios.post(`/api/oauth/${provider}`) + return data.url + } + } +}) \ No newline at end of file diff --git a/resources/js/stores/errors.js b/resources/js/stores/errors.js new file mode 100644 index 000000000..6b22a90e1 --- /dev/null +++ b/resources/js/stores/errors.js @@ -0,0 +1,17 @@ +import { defineStore } from 'pinia' + +export const namespaced = true + +export const useErrorsStore = defineStore('errors', { + state: () => ({ + content: null + }), + actions: { + set (error) { + this.content = error + }, + clear () { + this.content = null + } + } +}) \ No newline at end of file diff --git a/resources/js/stores/forms.js b/resources/js/stores/forms.js new file mode 100644 index 000000000..62ec89182 --- /dev/null +++ b/resources/js/stores/forms.js @@ -0,0 +1,83 @@ +import { defineStore } from 'pinia' +import axios from 'axios' + +export const formsEndpoint = '/api/open/workspaces/{workspaceId}/forms' +export const namespaced = true +export let currentPage = 1 + +export const useFormsStore = defineStore('forms', { + state: () => ({ + content: [], + loading: false + }), + getters: { + getById: (state) => (id) => { + if (state.content.length === 0) return null + return state.content.find(item => item.id === id) + }, + getBySlug: (state) => (slug) => { + if (state.content.length === 0) return null + return state.content.find(item => item.slug === slug) + }, + getAllTags: (state) => { + if (state.content.length === 0) return [] + let allTags = [] + state.content.forEach(form => { + if(form.tags && form.tags.length > 0){ + allTags = allTags.concat(form.tags) + } + }) + return allTags.filter((item, i, ar) => ar.indexOf(item) === i) + } + }, + actions: { + set (items) { + this.content = items + }, + append (items) { + this.content = this.content.concat(items) + }, + addOrUpdate (item) { + this.content = this.content.filter((val) => val.id !== item.id) + this.content.push(item) + }, + remove (item) { + this.content = this.content.filter((val) => val.id !== item.id) + }, + startLoading () { + this.loading = true + }, + stopLoading () { + this.loading = false + }, + resetState () { + this.set([]) + this.stopLoading() + currentPage = 1 + }, + load (workspaceId) { + this.startLoading() + return axios.get(formsEndpoint.replace('{workspaceId}', workspaceId)+'?page='+currentPage).then((response) => { + if (currentPage == 1) { + this.set(response.data.data) + } else { + this.append(response.data.data) + } + if (currentPage < response.data.meta.last_page) { + currentPage += 1 + this.load(workspaceId) + } else { + this.stopLoading() + currentPage = 1 + } + }) + }, + loadIfEmpty (workspaceId) { + if (this.content.length === 0) { + return this.load(workspaceId) + } + this.stopLoading() + return Promise.resolve() + } + } +}) \ No newline at end of file diff --git a/resources/js/stores/records.js b/resources/js/stores/records.js new file mode 100644 index 000000000..b5d7c1f93 --- /dev/null +++ b/resources/js/stores/records.js @@ -0,0 +1,49 @@ +import { defineStore } from 'pinia' + +export const namespaced = true + +/** + * Loads records from database + */ +export const useRecordsStore = defineStore('records', { + state: () => ({ + content: [], + loading: false + }), + getters: { + getById: (state) => (id) => { + if (state.content.length === 0) return null + return state.content.find(item => item.submission_id === id) + } + }, + actions: { + set (items) { + this.content = items + }, + addOrUpdate (item) { + this.content = this.content.filter((val) => val.id !== item.id) + this.content.push(item) + }, + remove (itemId) { + this.content = this.content.filter((val) => val.id !== itemId) + }, + startLoading () { + this.loading = true + }, + stopLoading () { + this.loading = false + }, + resetState () { + this.set([]) + this.stopLoading() + }, + loadRecord (request) { + this.set([]) + this.startLoading() + return request.then((data) => { + this.addOrUpdate(data) + this.stopLoading() + }) + } + } +}) \ No newline at end of file diff --git a/resources/js/stores/templates.js b/resources/js/stores/templates.js new file mode 100644 index 000000000..922f31f97 --- /dev/null +++ b/resources/js/stores/templates.js @@ -0,0 +1,120 @@ +import axios from 'axios' +import { defineStore } from 'pinia' + +export const templatesEndpoint = '/api/templates' +export const namespaced = true + +export const useTemplatesStore = defineStore('templates', { + state: () => ({ + content: [], + industries: {}, + types: {}, + allLoaded: false, + loading: false + }), + getters: { + getBySlug: (state) => (slug) => { + if (state.content.length === 0) return null + return state.content.find(item => item.slug === slug) + }, + getTemplateTypes: (state) => (slugs) => { + if (state.types.length === 0) return null + return Object.values(state.types).filter((val) => slugs.includes(val.slug)).map((item) => { return item.name }) + }, + getTemplateIndustries: (state) => (slugs) => { + if (state.industries.length === 0) return null + return Object.values(state.industries).filter((val) => slugs.includes(val.slug)).map((item) => { return item.name }) + } + }, + actions: { + set (items) { + this.content = items + this.allLoaded = true + }, + append (items) { + const ids = items.map((item) => { return item.id }) + this.content = this.content.filter((val) => !ids.includes(val.id)) + this.content = this.content.concat(items) + }, + addOrUpdate (item) { + this.content = this.content.filter((val) => val.id !== item.id) + this.content.push(item) + }, + remove (item) { + this.content = this.content.filter((val) => val.id !== item.id) + }, + startLoading () { + this.loading = true + }, + stopLoading () { + this.loading = false + }, + setAllLoaded (val) { + this.allLoaded = val + }, + resetState () { + this.set([]) + this.stopLoading() + }, + loadTypesAndIndustries () { + if (Object.keys(this.industries).length === 0) { + import('@/data/forms/templates/industries.json').then((module) => { + this.industries = module.default + }) + } + if (Object.keys(this.types).length === 0) { + import('@/data/forms/templates/types.json').then((module) => { + this.types = module.default + }) + } + }, + loadTemplate (slug) { + this.startLoading() + this.loadTypesAndIndustries() + + if (this.getBySlug(slug)) { + this.stopLoading() + return Promise.resolve() + } + + return axios.get(templatesEndpoint + '/' + slug).then((response) => { + this.addOrUpdate(response.data) + this.stopLoading() + }).catch((error) => { + this.stopLoading() + }) + }, + loadAll (options=null) { + this.startLoading() + this.loadTypesAndIndustries() + + // Prepare with options + let queryStr = '' + if(options !== null){ + for (const [key, value] of Object.entries(options)) { + queryStr += '&' + encodeURIComponent(key) + '=' + encodeURIComponent(value) + } + queryStr = queryStr.slice(1) + } + return axios.get((queryStr) ? templatesEndpoint + '?' + queryStr : templatesEndpoint).then((response) => { + if(options !== null){ + this.set(response.data) + this.setAllLoaded(false) + } else { + this.append(response.data) + this.setAllLoaded(true) + } + this.stopLoading() + }).catch((error) => { + this.stopLoading() + }) + }, + loadIfEmpty () { + if (!this.allLoaded) { + return this.loadAll() + } + this.stopLoading() + return Promise.resolve() + } + } +}) diff --git a/resources/js/stores/working_form.js b/resources/js/stores/working_form.js new file mode 100644 index 000000000..181180ce0 --- /dev/null +++ b/resources/js/stores/working_form.js @@ -0,0 +1,50 @@ +import { defineStore } from 'pinia' + +export const namespaced = true + +export const useWorkingFormStore = defineStore('working_form', { + state: () => ({ + content: null, + + // Field being edited + selectedFieldIndex: null, + showEditFieldSidebar: null, + showAddFieldSidebar: null + }), + actions: { + set (form) { + this.content = form + }, + setProperties (properties) { + this.content.properties = properties + }, + openSettingsForField (index) { + // If field is passed, compute index + if (typeof index === 'object') { + index = this.content.properties.findIndex(prop => prop.id === index.id) + } + this.selectedFieldIndex = index + this.showEditFieldSidebar = true + this.showAddFieldSidebar = false + }, + closeEditFieldSidebar () { + this.selectedFieldIndex = null + this.showEditFieldSidebar = false + this.showAddFieldSidebar = false + }, + openAddFieldSidebar (index) { + // If field is passed, compute index + if (index !== null && typeof index === 'object') { + index = this.content.properties.findIndex(prop => prop.id === index.id) + } + this.selectedFieldIndex = index + this.showAddFieldSidebar = true + this.showEditFieldSidebar = false + }, + closeAddFieldSidebar () { + this.selectedFieldIndex = null + this.showAddFieldSidebar = false + this.showEditFieldSidebar = false + } + } +}) \ No newline at end of file diff --git a/resources/js/stores/workspaces.js b/resources/js/stores/workspaces.js new file mode 100644 index 000000000..96c4df6e8 --- /dev/null +++ b/resources/js/stores/workspaces.js @@ -0,0 +1,93 @@ +import axios from 'axios' +import { defineStore } from 'pinia' + +export const namespaced = true +export const workspaceEndpoint = '/api/open/workspaces/' + +const localStorageCurrentWorkspaceKey = 'currentWorkspace' + +export const useWorkspacesStore = defineStore('workspaces', { + state: () => ({ + content: [], + currentId: null, + loading: false + }), + getters: { + getById: (state) => (id) => { + if (state.content.length === 0) return null + return state.content.find(item => item.id === id) + }, + getCurrent: (state) => () => { + if (state.content.length === 0 || state.currentId === null) return null + return state.content.find(item => item.id === state.currentId) + } + }, + actions: { + set (items) { + this.content = items + if (this.currentId == null && this.content.length > 0) { + // If one only, set it + if (this.content.length === 1) { + this.currentId = items[0].id + localStorage.setItem(localStorageCurrentWorkspaceKey, this.currentId) + } else if (localStorage.getItem(localStorageCurrentWorkspaceKey) && this.content.find(item => item.id === parseInt(localStorage.getItem(localStorageCurrentWorkspaceKey)))) { + // Check local storage for current workspace, or take first + this.currentId = parseInt(localStorage.getItem(localStorageCurrentWorkspaceKey)) + localStorage.setItem(localStorageCurrentWorkspaceKey, this.currentId) + } else { + // Else, take first + this.currentId = items[0].id + localStorage.setItem(localStorageCurrentWorkspaceKey, this.currentId) + } + } else { + localStorage.removeItem(localStorageCurrentWorkspaceKey) + } + }, + setCurrentId (id) { + this.currentId = id + localStorage.setItem(localStorageCurrentWorkspaceKey, id) + }, + addOrUpdate (item) { + this.content = this.content.filter((val) => val.id !== item.id) + this.content.push(item) + if (this.currentId == null) { + this.currentId = item.id + localStorage.setItem(localStorageCurrentWorkspaceKey, this.currentId) + } + }, + remove (itemId) { + this.content = this.content.filter((val) => val.id !== itemId) + }, + startLoading () { + this.loading = true + }, + stopLoading () { + this.loading = false + }, + resetState () { + this.set([]) + this.stopLoading() + }, + load () { + this.set([]) + this.startLoading() + return axios.get(workspaceEndpoint).then((response) => { + this.set(response.data) + this.stopLoading() + }) + }, + loadIfEmpty () { + if (this.content.length === 0) { + return this.load() + } + return Promise.resolve() + }, + delete (id) { + this.startLoading() + return axios.delete(workspaceEndpoint + id).then((response) => { + this.remove(response.data.workspace_id) + this.stopLoading() + }) + } + } +}) \ No newline at end of file