mirror of
https://github.com/VueFileManager/vuefilemanager.git
synced 2026-04-05 18:23:48 +00:00
added prettier
This commit is contained in:
5
.prettierrc.yaml
Normal file
5
.prettierrc.yaml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
trailingComma: "es5"
|
||||||
|
tabWidth: 4
|
||||||
|
semi: false
|
||||||
|
singleQuote: true
|
||||||
|
printWidth: 120
|
||||||
222
package-lock.json
generated
222
package-lock.json
generated
@@ -1968,6 +1968,15 @@
|
|||||||
"integrity": "sha512-e0hDa9H2Z9AwFkk2qDlwhoMYE4eToKarchkQHovNdLTCYMHZHeRjI71crOh+dio4K6u1IcwubQqo79Ga4CyAQA==",
|
"integrity": "sha512-e0hDa9H2Z9AwFkk2qDlwhoMYE4eToKarchkQHovNdLTCYMHZHeRjI71crOh+dio4K6u1IcwubQqo79Ga4CyAQA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"argparse": {
|
||||||
|
"version": "1.0.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
|
||||||
|
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"sprintf-js": "~1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"array-find-index": {
|
"array-find-index": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
|
||||||
@@ -2449,6 +2458,12 @@
|
|||||||
"integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
|
"integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"builtin-modules": {
|
||||||
|
"version": "3.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz",
|
||||||
|
"integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"builtin-status-codes": {
|
"builtin-status-codes": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
|
||||||
@@ -2471,6 +2486,32 @@
|
|||||||
"get-intrinsic": "^1.0.2"
|
"get-intrinsic": "^1.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"caller-callsite": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz",
|
||||||
|
"integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"callsites": "^2.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"callsites": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
|
||||||
|
"integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"caller-path": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz",
|
||||||
|
"integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"caller-callsite": "^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"callsites": {
|
"callsites": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
|
||||||
@@ -3431,6 +3472,12 @@
|
|||||||
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=",
|
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"detect-newline": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz",
|
||||||
|
"integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"detect-node": {
|
"detect-node": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz",
|
||||||
@@ -3710,6 +3757,12 @@
|
|||||||
"estraverse": "^4.1.1"
|
"estraverse": "^4.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"esprima": {
|
||||||
|
"version": "4.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
|
||||||
|
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"esrecurse": {
|
"esrecurse": {
|
||||||
"version": "4.3.0",
|
"version": "4.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
|
||||||
@@ -4049,6 +4102,18 @@
|
|||||||
"pkg-dir": "^4.1.0"
|
"pkg-dir": "^4.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"find-line-column": {
|
||||||
|
"version": "0.5.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/find-line-column/-/find-line-column-0.5.2.tgz",
|
||||||
|
"integrity": "sha1-2wAjj/hoVRoYLnShA0FtKVqYyMo=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"find-root": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"find-up": {
|
"find-up": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
|
||||||
@@ -4713,6 +4778,107 @@
|
|||||||
"resolve-cwd": "^3.0.0"
|
"resolve-cwd": "^3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"import-sort": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/import-sort/-/import-sort-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-XUwSQMGAGmcW/wfshFE0gXgb1NPF6ibbQD6wDr3KRDykZf/lZj0jf58Bwa02xNb8EE59oz7etFe9OHnJocUW5Q==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"detect-newline": "^2.1.0",
|
||||||
|
"import-sort-parser": "^6.0.0",
|
||||||
|
"import-sort-style": "^6.0.0",
|
||||||
|
"is-builtin-module": "^3.0.0",
|
||||||
|
"resolve": "^1.8.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"import-sort-config": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/import-sort-config/-/import-sort-config-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-FJpF2F3+30JXqH1rJKeajxoSCHCueai3/0ntDN4y3GJL5pjnLDt/VjCy5FzjH7u0NHnllL/zVEf1wfmsVxJlPQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"cosmiconfig": "^5.0.5",
|
||||||
|
"find-root": "^1.0.0",
|
||||||
|
"minimatch": "^3.0.4",
|
||||||
|
"resolve-from": "^4.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"cosmiconfig": {
|
||||||
|
"version": "5.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz",
|
||||||
|
"integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"import-fresh": "^2.0.0",
|
||||||
|
"is-directory": "^0.3.1",
|
||||||
|
"js-yaml": "^3.13.1",
|
||||||
|
"parse-json": "^4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"import-fresh": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz",
|
||||||
|
"integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"caller-path": "^2.0.0",
|
||||||
|
"resolve-from": "^3.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"resolve-from": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
|
||||||
|
"integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"parse-json": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
|
||||||
|
"integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"error-ex": "^1.3.1",
|
||||||
|
"json-parse-better-errors": "^1.0.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"import-sort-parser": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/import-sort-parser/-/import-sort-parser-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-H5L+d6HnqHvThB0GmAA3/43Sv74oCwL0iMk3/ixOv0LRJ69rCyHXeG/+UadMHrD2FefEmgPIWboEPAG7gsQrkA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"import-sort-parser-babylon": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/import-sort-parser-babylon/-/import-sort-parser-babylon-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-NyShTiNhTh4Vy7kJUVe6CuvOaQAzzfSIT72wtp3CzGjz8bHjNj59DCAjncuviicmDOgVAgmLuSh1WMcLYAMWGg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@babel/core": "^7.2.2",
|
||||||
|
"@babel/parser": "^7.0.0-beta.54",
|
||||||
|
"@babel/traverse": "^7.0.0-beta.54",
|
||||||
|
"@babel/types": "^7.0.0-beta.54",
|
||||||
|
"find-line-column": "^0.5.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"import-sort-parser-typescript": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/import-sort-parser-typescript/-/import-sort-parser-typescript-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-pgxnr3I156DonupQriNsgDb2zJN9TxrqCCIN1rwT/6SDO1rkJb+a0fjqshCjlgacTSA92oPAp1eAwmQUeZi3dw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"typescript": "^3.2.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"import-sort-style": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/import-sort-style/-/import-sort-style-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-z0H5PKs7YoDeKxNYXv2AA1mjjZFY07fjeNCXUdTM3ymJtWeeEoTm8CQkFm2l+KPZoMczIvdwzJpWkkOamBnsPw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"in-publish": {
|
"in-publish": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.1.tgz",
|
||||||
@@ -4788,6 +4954,15 @@
|
|||||||
"integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
|
"integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"is-builtin-module": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-OV7JjAgOTfAFJmHZLvpSTb4qi0nIILDV1gWPYDnDJUTNFM5aGlRAhk4QcT8i7TuAleeEV5Fdkqn3t4mS+Q11fg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"builtin-modules": "^3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"is-core-module": {
|
"is-core-module": {
|
||||||
"version": "2.8.1",
|
"version": "2.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz",
|
||||||
@@ -4805,6 +4980,12 @@
|
|||||||
"has-tostringtag": "^1.0.0"
|
"has-tostringtag": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"is-directory": {
|
||||||
|
"version": "0.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz",
|
||||||
|
"integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"is-docker": {
|
"is-docker": {
|
||||||
"version": "2.2.1",
|
"version": "2.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
|
||||||
@@ -4967,6 +5148,16 @@
|
|||||||
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
|
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"js-yaml": {
|
||||||
|
"version": "3.14.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
|
||||||
|
"integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"argparse": "^1.0.7",
|
||||||
|
"esprima": "^4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"jsbn": {
|
"jsbn": {
|
||||||
"version": "0.1.1",
|
"version": "0.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
|
||||||
@@ -6812,8 +7003,25 @@
|
|||||||
"version": "2.5.1",
|
"version": "2.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz",
|
||||||
"integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==",
|
"integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"prettier-plugin-import-sort": {
|
||||||
|
"version": "0.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/prettier-plugin-import-sort/-/prettier-plugin-import-sort-0.0.7.tgz",
|
||||||
|
"integrity": "sha512-O0KlUSq+lwvh+UiN3wZDT6wWkf7TNxTVv2/XXE5KqpRNbFJq3nRg2ftzBYFFO8QGpdWIrOB0uCTCtFjIxmVKQw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"requires": {
|
||||||
|
"import-sort": "^6.0.0",
|
||||||
|
"import-sort-config": "^6.0.0",
|
||||||
|
"import-sort-parser-babylon": "^6.0.0",
|
||||||
|
"import-sort-parser-typescript": "^6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"prettier-plugin-tailwindcss": {
|
||||||
|
"version": "0.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.1.4.tgz",
|
||||||
|
"integrity": "sha512-kt3YFWqxcG9+bilBI0hPF7RjQZNtgBRvjJZGw6B2MNAjPqlfcYIiZnNaIEnq4XimKLTzZYxz6jQnUXmSQ/5njg==",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"pretty-time": {
|
"pretty-time": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
@@ -7744,6 +7952,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"sprintf-js": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
||||||
|
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"sshpk": {
|
"sshpk": {
|
||||||
"version": "1.17.0",
|
"version": "1.17.0",
|
||||||
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz",
|
||||||
@@ -8219,6 +8433,12 @@
|
|||||||
"mime-types": "~2.1.24"
|
"mime-types": "~2.1.24"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"typescript": {
|
||||||
|
"version": "3.9.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz",
|
||||||
|
"integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"unicode-canonical-property-names-ecmascript": {
|
"unicode-canonical-property-names-ecmascript": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz",
|
||||||
|
|||||||
@@ -15,6 +15,9 @@
|
|||||||
"cross-env": "^5.1",
|
"cross-env": "^5.1",
|
||||||
"laravel-mix": "^6.0.41",
|
"laravel-mix": "^6.0.41",
|
||||||
"postcss": "^8.4.5",
|
"postcss": "^8.4.5",
|
||||||
|
"prettier": "^2.5.1",
|
||||||
|
"prettier-plugin-import-sort": "0.0.7",
|
||||||
|
"prettier-plugin-tailwindcss": "^0.1.4",
|
||||||
"resolve-url-loader": "^2.3.1",
|
"resolve-url-loader": "^2.3.1",
|
||||||
"sass": "^1.49.0",
|
"sass": "^1.49.0",
|
||||||
"sass-loader": "^8.0.2",
|
"sass-loader": "^8.0.2",
|
||||||
|
|||||||
@@ -1,139 +1,123 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
|
|
||||||
<!--UI components-->
|
<!--UI components-->
|
||||||
<Alert />
|
<Alert />
|
||||||
<ToasterWrapper />
|
<ToasterWrapper />
|
||||||
<CookieDisclaimer />
|
<CookieDisclaimer />
|
||||||
|
|
||||||
<!--Show spinner before translations is loaded-->
|
<!--Show spinner before translations is loaded-->
|
||||||
<Spinner v-if="! isLoaded" />
|
<Spinner v-if="!isLoaded" />
|
||||||
|
|
||||||
<!--Show warning bar when user functionality is restricted-->
|
<!--Show warning bar when user functionality is restricted-->
|
||||||
<RestrictionWarningBar />
|
<RestrictionWarningBar />
|
||||||
|
|
||||||
<!--App view-->
|
<!--App view-->
|
||||||
<router-view v-if="isLoaded" />
|
<router-view v-if="isLoaded" />
|
||||||
|
|
||||||
<!--Background under popups-->
|
<!--Background under popups-->
|
||||||
<Vignette />
|
<Vignette />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ToasterWrapper from "./components/Others/Notifications/ToasterWrapper";
|
import ToasterWrapper from './components/Others/Notifications/ToasterWrapper'
|
||||||
import CookieDisclaimer from "./components/Others/CookieDisclaimer";
|
import CookieDisclaimer from './components/Others/CookieDisclaimer'
|
||||||
import Spinner from "./components/FilesView/Spinner";
|
import Spinner from './components/FilesView/Spinner'
|
||||||
import Vignette from "./components/Others/Vignette";
|
import Vignette from './components/Others/Vignette'
|
||||||
import Alert from "./components/FilesView/Alert";
|
import Alert from './components/FilesView/Alert'
|
||||||
import RestrictionWarningBar from "./RestrictionWarningBar"
|
import RestrictionWarningBar from './RestrictionWarningBar'
|
||||||
import {mapGetters} from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
import {events} from './bus'
|
import { events } from './bus'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'App',
|
name: 'App',
|
||||||
components: {
|
components: {
|
||||||
RestrictionWarningBar,
|
RestrictionWarningBar,
|
||||||
CookieDisclaimer,
|
CookieDisclaimer,
|
||||||
ToasterWrapper,
|
ToasterWrapper,
|
||||||
Vignette,
|
Vignette,
|
||||||
Spinner,
|
Spinner,
|
||||||
Alert
|
Alert,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isLoaded: false
|
isLoaded: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters([
|
...mapGetters(['config', 'user']),
|
||||||
'config',
|
},
|
||||||
'user',
|
watch: {
|
||||||
]),
|
'config.defaultThemeMode': function () {
|
||||||
},
|
this.handleDarkMode()
|
||||||
watch: {
|
},
|
||||||
'config.defaultThemeMode': function () {
|
},
|
||||||
this.handleDarkMode()
|
methods: {
|
||||||
}
|
spotlightListener(e) {
|
||||||
},
|
if (e.key === 'k' && e.metaKey) {
|
||||||
methods: {
|
events.$emit('spotlight:show')
|
||||||
spotlightListener(e) {
|
}
|
||||||
if (e.key === 'k' && e.metaKey) {
|
},
|
||||||
events.$emit('spotlight:show');
|
handleDarkMode() {
|
||||||
}
|
const app = document.getElementsByTagName('html')[0]
|
||||||
},
|
const prefersDarkScheme = window.matchMedia('(prefers-color-scheme: dark)')
|
||||||
handleDarkMode() {
|
|
||||||
const app = document.getElementsByTagName("html")[0];
|
|
||||||
const prefersDarkScheme = window.matchMedia('(prefers-color-scheme: dark)');
|
|
||||||
|
|
||||||
if (this.config.defaultThemeMode === 'dark') {
|
if (this.config.defaultThemeMode === 'dark') {
|
||||||
|
app.classList.add('dark')
|
||||||
|
this.$store.commit('UPDATE_DARK_MODE_STATUS', true)
|
||||||
|
} else if (this.config.defaultThemeMode === 'light') {
|
||||||
|
app.classList.remove('dark')
|
||||||
|
this.$store.commit('UPDATE_DARK_MODE_STATUS', false)
|
||||||
|
} else if (this.config.defaultThemeMode === 'system' && prefersDarkScheme.matches) {
|
||||||
|
app.classList.add('dark')
|
||||||
|
this.$store.commit('UPDATE_DARK_MODE_STATUS', true)
|
||||||
|
} else if (this.config.defaultThemeMode === 'system' && !prefersDarkScheme.matches) {
|
||||||
|
app.classList.remove('dark')
|
||||||
|
this.$store.commit('UPDATE_DARK_MODE_STATUS', false)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
beforeMount() {
|
||||||
|
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
|
||||||
|
this.handleDarkMode()
|
||||||
|
})
|
||||||
|
|
||||||
app.classList.add("dark")
|
// Get installation state
|
||||||
this.$store.commit('UPDATE_DARK_MODE_STATUS', true)
|
let installation = this.$root.$data.config.installation
|
||||||
|
|
||||||
} else if (this.config.defaultThemeMode === 'light') {
|
if (['setup-disclaimer', 'setup-database'].includes(installation)) this.isLoaded = true
|
||||||
|
|
||||||
app.classList.remove("dark")
|
// Redirect to database verify code
|
||||||
this.$store.commit('UPDATE_DARK_MODE_STATUS', false)
|
if (installation === 'setup-database') this.$router.push({ name: 'StatusCheck' })
|
||||||
|
|
||||||
} else if (this.config.defaultThemeMode === 'system' && prefersDarkScheme.matches) {
|
// Redirect to starting installation process
|
||||||
|
if (installation === 'setup-disclaimer') this.$router.push({ name: 'InstallationDisclaimer' })
|
||||||
|
|
||||||
app.classList.add("dark")
|
if (installation === 'setup-done')
|
||||||
this.$store.commit('UPDATE_DARK_MODE_STATUS', true)
|
this.$store.dispatch('getLanguageTranslations', this.$root.$data.config.locale).then(() => {
|
||||||
|
this.isLoaded = true
|
||||||
|
|
||||||
} else if (this.config.defaultThemeMode === 'system' && !prefersDarkScheme.matches) {
|
// Store config to vuex
|
||||||
|
this.$store.commit('INIT', {
|
||||||
|
config: this.$root.$data.config,
|
||||||
|
rootDirectory: {
|
||||||
|
name: this.$t('locations.home'),
|
||||||
|
location: 'base',
|
||||||
|
id: undefined,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
if (this.$isWindows()) {
|
||||||
|
document.body.classList.add('windows')
|
||||||
|
}
|
||||||
|
|
||||||
app.classList.remove("dark")
|
window.addEventListener('keydown', this.spotlightListener)
|
||||||
this.$store.commit('UPDATE_DARK_MODE_STATUS', false)
|
},
|
||||||
}
|
destroyed() {
|
||||||
}
|
window.removeEventListener('keydown', this.spotlightListener)
|
||||||
},
|
},
|
||||||
beforeMount() {
|
|
||||||
window.matchMedia('(prefers-color-scheme: dark)')
|
|
||||||
.addEventListener('change', () => {
|
|
||||||
this.handleDarkMode()
|
|
||||||
});
|
|
||||||
|
|
||||||
// Get installation state
|
|
||||||
let installation = this.$root.$data.config.installation
|
|
||||||
|
|
||||||
if (['setup-disclaimer', 'setup-database'].includes(installation))
|
|
||||||
this.isLoaded = true
|
|
||||||
|
|
||||||
// Redirect to database verify code
|
|
||||||
if (installation === 'setup-database')
|
|
||||||
this.$router.push({name: 'StatusCheck'})
|
|
||||||
|
|
||||||
// Redirect to starting installation process
|
|
||||||
if (installation === 'setup-disclaimer')
|
|
||||||
this.$router.push({name: 'InstallationDisclaimer'})
|
|
||||||
|
|
||||||
if (installation === 'setup-done')
|
|
||||||
this.$store.dispatch('getLanguageTranslations', this.$root.$data.config.locale)
|
|
||||||
.then(() => {
|
|
||||||
this.isLoaded = true
|
|
||||||
|
|
||||||
// Store config to vuex
|
|
||||||
this.$store.commit('INIT', {
|
|
||||||
config: this.$root.$data.config,
|
|
||||||
rootDirectory: {
|
|
||||||
name: this.$t('locations.home'),
|
|
||||||
location: 'base',
|
|
||||||
id: undefined
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
if (this.$isWindows()) {
|
|
||||||
document.body.classList.add('windows')
|
|
||||||
}
|
|
||||||
|
|
||||||
window.addEventListener("keydown", this.spotlightListener);
|
|
||||||
},
|
|
||||||
destroyed() {
|
|
||||||
window.removeEventListener("keydown", this.spotlightListener);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -143,53 +127,59 @@ export default {
|
|||||||
@import '../sass/vuefilemanager/mixins';
|
@import '../sass/vuefilemanager/mixins';
|
||||||
|
|
||||||
input:-webkit-autofill {
|
input:-webkit-autofill {
|
||||||
transition-delay: 999999999999s;
|
transition-delay: 999999999999s;
|
||||||
}
|
}
|
||||||
|
|
||||||
[v-cloak],
|
[v-cloak],
|
||||||
[v-cloak] > * {
|
[v-cloak] > * {
|
||||||
display: none
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
* {
|
* {
|
||||||
outline: 0;
|
outline: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
font-family: 'Nunito', sans-serif;
|
font-family: 'Nunito', sans-serif;
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: $text;
|
color: $text;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vue-feather {
|
.vue-feather {
|
||||||
path, circle, line, rect, polyline, ellipse, polygon {
|
path,
|
||||||
color: inherit;
|
circle,
|
||||||
}
|
line,
|
||||||
|
rect,
|
||||||
|
polyline,
|
||||||
|
ellipse,
|
||||||
|
polygon {
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#auth {
|
#auth {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dark mode support
|
// Dark mode support
|
||||||
.dark {
|
.dark {
|
||||||
|
* {
|
||||||
|
color: $dark_mode_text_primary;
|
||||||
|
}
|
||||||
|
|
||||||
* {
|
body,
|
||||||
color: $dark_mode_text_primary;
|
html {
|
||||||
}
|
background: $dark_mode_background;
|
||||||
|
color: $dark_mode_text_primary;
|
||||||
|
|
||||||
body, html {
|
img {
|
||||||
background: $dark_mode_background;
|
opacity: 0.95;
|
||||||
color: $dark_mode_text_primary;
|
}
|
||||||
|
}
|
||||||
img {
|
|
||||||
opacity: .95;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="$store.getters.isLimitedUser" class="bg-red-500 text-center py-1">
|
<div v-if="$store.getters.isLimitedUser" class="bg-red-500 py-1 text-center">
|
||||||
<router-link :to="{name: 'Billing'}" class="text-white font-bold text-xs">
|
<router-link :to="{ name: 'Billing' }" class="text-xs font-bold text-white">
|
||||||
{{ $t('Your functionality is restricted. Please review your billing settings.') }}
|
{{ $t('Your functionality is restricted. Please review your billing settings.') }}
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'RestrictionWarningBar',
|
name: 'RestrictionWarningBar',
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
6
resources/js/bootstrap.js
vendored
6
resources/js/bootstrap.js
vendored
@@ -1,4 +1,4 @@
|
|||||||
window._ = require('lodash');
|
window._ = require('lodash')
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We'll load the axios HTTP library which allows us to easily issue requests
|
* We'll load the axios HTTP library which allows us to easily issue requests
|
||||||
@@ -6,9 +6,9 @@ window._ = require('lodash');
|
|||||||
* CSRF token as a header based on the value of the "XSRF" token cookie.
|
* CSRF token as a header based on the value of the "XSRF" token cookie.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
window.axios = require('axios');
|
window.axios = require('axios')
|
||||||
|
|
||||||
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
|
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Echo exposes an expressive API for subscribing to channels and listening
|
* Echo exposes an expressive API for subscribing to channels and listening
|
||||||
|
|||||||
@@ -1,36 +1,28 @@
|
|||||||
<template>
|
<template>
|
||||||
<div :class="{'mb-7': !isLast}" class="sm:flex justify-between sm:space-x-8 sm:space-x-2 sm:space-y-0 space-y-4 w-full">
|
<div :class="{ 'mb-7': !isLast }" class="w-full justify-between space-y-4 sm:flex sm:space-x-8 sm:space-x-2 sm:space-y-0">
|
||||||
|
<!--Label for input-->
|
||||||
|
<div class="leading-5">
|
||||||
|
<label class="mb-1.5 block text-sm font-bold text-gray-700 dark:text-gray-200"> {{ title }}: </label>
|
||||||
|
|
||||||
<!--Label for input-->
|
<!--Input Description-->
|
||||||
<div class="leading-5">
|
<span v-if="description" class="block text-xs leading-4 text-gray-500" v-html="description"></span>
|
||||||
<label class="text-sm font-bold dark:text-gray-200 text-gray-700 mb-1.5 block">
|
|
||||||
{{ title }}:
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<!--Input Description-->
|
<!--Input Description-->
|
||||||
<span v-if="description" class="text-xs text-gray-500 leading-4 block" v-html="description"></span>
|
<span v-if="error" class="error-message">
|
||||||
|
{{ error }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!--Input Description-->
|
<!--Form element-->
|
||||||
<span v-if="error" class="error-message">
|
<div>
|
||||||
{{ error }}
|
<slot></slot>
|
||||||
</span>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!--Form element-->
|
|
||||||
<div>
|
|
||||||
<slot></slot>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'AppInputButton',
|
name: 'AppInputButton',
|
||||||
props: [
|
props: ['description', 'isLast', 'title', 'error'],
|
||||||
'description',
|
}
|
||||||
'isLast',
|
</script>
|
||||||
'title',
|
|
||||||
'error',
|
|
||||||
]
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|||||||
@@ -1,36 +1,28 @@
|
|||||||
<template>
|
<template>
|
||||||
<div :class="{'mb-7': !isLast}" class="flex items-center justify-between sm:space-x-8 space-x-2 w-full">
|
<div :class="{ 'mb-7': !isLast }" class="flex w-full items-center justify-between space-x-2 sm:space-x-8">
|
||||||
|
<!--Label for input-->
|
||||||
|
<div class="leading-5">
|
||||||
|
<label class="mb-1.5 block text-sm font-bold text-gray-700 dark:text-gray-200"> {{ title }}: </label>
|
||||||
|
|
||||||
<!--Label for input-->
|
<!--Input Description-->
|
||||||
<div class="leading-5">
|
<span v-if="description" class="block text-xs leading-4 text-gray-500" v-html="description"></span>
|
||||||
<label class="text-sm font-bold dark:text-gray-200 text-gray-700 mb-1.5 block">
|
|
||||||
{{ title }}:
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<!--Input Description-->
|
<!--Input Description-->
|
||||||
<span v-if="description" class="text-xs text-gray-500 leading-4 block" v-html="description"></span>
|
<span v-if="error" class="error-message">
|
||||||
|
{{ error }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!--Input Description-->
|
<!--Form element-->
|
||||||
<span v-if="error" class="error-message">
|
<div>
|
||||||
{{ error }}
|
<slot></slot>
|
||||||
</span>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!--Form element-->
|
|
||||||
<div>
|
|
||||||
<slot></slot>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'AppInputSwitch',
|
name: 'AppInputSwitch',
|
||||||
props: [
|
props: ['description', 'isLast', 'title', 'error'],
|
||||||
'description',
|
}
|
||||||
'isLast',
|
</script>
|
||||||
'title',
|
|
||||||
'error',
|
|
||||||
]
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|||||||
@@ -1,32 +1,24 @@
|
|||||||
<template>
|
<template>
|
||||||
<div :class="{'mb-7': !isLast}">
|
<div :class="{ 'mb-7': !isLast }">
|
||||||
|
<!--Label for input-->
|
||||||
|
<label v-if="title" class="mb-1.5 block text-sm font-bold text-gray-700 dark:text-gray-200"> {{ title }}: </label>
|
||||||
|
|
||||||
<!--Label for input-->
|
<!--Form element-->
|
||||||
<label v-if="title" class="text-sm font-bold dark:text-gray-200 text-gray-700 mb-1.5 block">
|
<slot></slot>
|
||||||
{{ title }}:
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<!--Form element-->
|
<!--Input Description-->
|
||||||
<slot></slot>
|
<span v-if="error" class="pt-2 text-xs text-red-800">
|
||||||
|
{{ error }}
|
||||||
|
</span>
|
||||||
|
|
||||||
<!--Input Description-->
|
<!--Input Description-->
|
||||||
<span v-if="error" class="text-red-800 pt-2 text-xs">
|
<small v-if="description" class="block pt-2 text-xs leading-4 text-gray-500" v-html="description"></small>
|
||||||
{{ error }}
|
</div>
|
||||||
</span>
|
|
||||||
|
|
||||||
<!--Input Description-->
|
|
||||||
<small v-if="description" class="text-xs text-gray-500 pt-2 leading-4 block" v-html="description"></small>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'AppInputText',
|
name: 'AppInputText',
|
||||||
props: [
|
props: ['description', 'isLast', 'title', 'error'],
|
||||||
'description',
|
}
|
||||||
'isLast',
|
</script>
|
||||||
'title',
|
|
||||||
'error',
|
|
||||||
]
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|||||||
@@ -1,45 +1,50 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="card-navigation" style="height: 62px" class="mb-7">
|
<div id="card-navigation" style="height: 62px" class="mb-7">
|
||||||
<div :class="{'fixed top-0 left-0 right-0 px-6 rounded-none backdrop-filter backdrop-blur-lg dark:bg-dark-foreground bg-white bg-opacity-50 z-10': fixedNav}">
|
<div
|
||||||
<div class="whitespace-nowrap overflow-x-auto">
|
:class="{
|
||||||
<router-link
|
'fixed top-0 left-0 right-0 z-10 rounded-none bg-white bg-opacity-50 px-6 backdrop-blur-lg backdrop-filter dark:bg-dark-foreground': fixedNav,
|
||||||
class="inline-block text-sm font-bold px-4 py-5 border-b-2 border-transparent border-bottom-theme"
|
}"
|
||||||
:class="{'text-theme': routeName === page.route, 'dark:text-gray-100 text-gray-600': routeName !== page.route}"
|
>
|
||||||
v-for="(page, i) in pages"
|
<div class="overflow-x-auto whitespace-nowrap">
|
||||||
:to="{name: page.route}"
|
<router-link
|
||||||
:key="i"
|
class="border-bottom-theme inline-block border-b-2 border-transparent px-4 py-5 text-sm font-bold"
|
||||||
replace
|
:class="{
|
||||||
>
|
'text-theme': routeName === page.route,
|
||||||
{{ page.title }}
|
'text-gray-600 dark:text-gray-100': routeName !== page.route,
|
||||||
</router-link>
|
}"
|
||||||
</div>
|
v-for="(page, i) in pages"
|
||||||
</div>
|
:to="{ name: page.route }"
|
||||||
</div>
|
:key="i"
|
||||||
|
replace
|
||||||
|
>
|
||||||
|
{{ page.title }}
|
||||||
|
</router-link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'CardNavigation',
|
name: 'CardNavigation',
|
||||||
props: [
|
props: ['pages'],
|
||||||
'pages'
|
computed: {
|
||||||
],
|
routeName() {
|
||||||
computed: {
|
return this.$route.name
|
||||||
routeName() {
|
},
|
||||||
return this.$route.name
|
},
|
||||||
}
|
data() {
|
||||||
},
|
return {
|
||||||
data() {
|
fixedNav: false,
|
||||||
return {
|
}
|
||||||
fixedNav: false,
|
},
|
||||||
}
|
created() {
|
||||||
},
|
// Handle fixed mobile navigation
|
||||||
created() {
|
window.addEventListener('scroll', () => {
|
||||||
// Handle fixed mobile navigation
|
let card = document.getElementById('card-navigation')
|
||||||
window.addEventListener("scroll", () => {
|
|
||||||
let card = document.getElementById('card-navigation')
|
|
||||||
|
|
||||||
this.fixedNav = card.getBoundingClientRect().top < 0;
|
this.fixedNav = card.getBoundingClientRect().top < 0
|
||||||
});
|
})
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -8,61 +8,57 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'DotLabel',
|
name: 'DotLabel',
|
||||||
props: [
|
props: ['color', 'title'],
|
||||||
'color',
|
}
|
||||||
'title',
|
|
||||||
],
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
.label {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
.label {
|
.label-dot {
|
||||||
display: flex;
|
margin-right: 10px;
|
||||||
align-items: center;
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
display: block;
|
||||||
|
border-radius: 8px;
|
||||||
|
flex: none;
|
||||||
|
|
||||||
.label-dot {
|
&.success {
|
||||||
margin-right: 10px;
|
background: #0abb87;
|
||||||
width: 8px;
|
|
||||||
height: 8px;
|
|
||||||
display: block;
|
|
||||||
border-radius: 8px;
|
|
||||||
flex: none;
|
|
||||||
|
|
||||||
&.success {
|
|
||||||
background: #0ABB87;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.danger {
|
|
||||||
background: #fd397a;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.warning {
|
|
||||||
background: #ffb822;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.info {
|
|
||||||
background: #5578eb;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.primary {
|
|
||||||
background: red;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.purple {
|
|
||||||
background: #9d66fe;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.secondary {
|
|
||||||
background: #e1e1ef;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.label-title {
|
&.danger {
|
||||||
font-size: 16px;
|
background: #fd397a;
|
||||||
font-weight: 700;
|
}
|
||||||
|
|
||||||
|
&.warning {
|
||||||
|
background: #ffb822;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.info {
|
||||||
|
background: #5578eb;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.primary {
|
||||||
|
background: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.purple {
|
||||||
|
background: #9d66fe;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.secondary {
|
||||||
|
background: #e1e1ef;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.label-title {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,91 +1,101 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="flex items-center mb-4 rounded dark:bg-2x-dark-foreground bg-light-300 h-2.5">
|
<div class="mb-4 flex h-2.5 items-center rounded bg-light-300 dark:bg-2x-dark-foreground">
|
||||||
<div v-for="(chart, i) in data" :key="i" :style="{width: (chart.progress > 1 ? chart.progress : 0) + '%'}" class="chart-wrapper">
|
<div
|
||||||
<!--<DotLabel class="label" :class="{'offset-top': chart.progress < 5}" :color="chart.color" :title="chart.value" />-->
|
v-for="(chart, i) in data"
|
||||||
|
:key="i"
|
||||||
|
:style="{
|
||||||
|
width: (chart.progress > 1 ? chart.progress : 0) + '%',
|
||||||
|
}"
|
||||||
|
class="chart-wrapper"
|
||||||
|
>
|
||||||
|
<!--<DotLabel class="label" :class="{'offset-top': chart.progress < 5}" :color="chart.color" :title="chart.value" />-->
|
||||||
|
|
||||||
<!--Only singe line-->
|
<!--Only singe line-->
|
||||||
<span
|
<span
|
||||||
v-if="data.length === 1"
|
v-if="data.length === 1"
|
||||||
:class="[{
|
:class="[
|
||||||
'border-r-2 dark:border-gray-800 border-white rounded-tl-lg rounded-bl-lg': chart.progress < 100,
|
{
|
||||||
'border-none rounded-lg': chart.progress >= 100
|
'rounded-tl-lg rounded-bl-lg border-r-2 border-white dark:border-gray-800': chart.progress < 100,
|
||||||
}, chart.color]"
|
'rounded-lg border-none': chart.progress >= 100,
|
||||||
class="chart-progress w-full h-2.5 block"
|
},
|
||||||
>
|
chart.color,
|
||||||
|
]"
|
||||||
|
class="chart-progress block h-2.5 w-full"
|
||||||
|
>
|
||||||
|
</span>
|
||||||
|
|
||||||
</span>
|
<!--Multiple line-->
|
||||||
|
<span
|
||||||
<!--Multiple line-->
|
v-if="data.length > 1 && chart.progress > 0"
|
||||||
<span
|
:class="[
|
||||||
v-if="data.length > 1 && chart.progress > 0"
|
{
|
||||||
:class="[{
|
'rounded-tl-lg rounded-bl-lg border-r-2 border-white dark:border-gray-800': i === 0,
|
||||||
'rounded-tl-lg rounded-bl-lg border-r-2 dark:border-gray-800 border-white': i === 0,
|
'border-r-2 border-white dark:border-gray-800': i < data.length - 1,
|
||||||
'border-r-2 dark:border-gray-800 border-white': i < (data.length - 1),
|
'rounded-tr-lg rounded-br-lg': i === data.length - 1,
|
||||||
'rounded-tr-lg rounded-br-lg': i === (data.length - 1),
|
},
|
||||||
}, chart.color]"
|
chart.color,
|
||||||
class="chart-progress w-full h-2.5 block"
|
]"
|
||||||
></span>
|
class="chart-progress block h-2.5 w-full"
|
||||||
|
></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<footer class="flex items-center w-full overflow-x-auto">
|
<footer class="flex w-full items-center overflow-x-auto">
|
||||||
<DotLabel v-for="(chart, i) in data" :key="i" :color="chart.color" :title="chart.title" class="mr-5" />
|
<DotLabel v-for="(chart, i) in data" :key="i" :color="chart.color" :title="chart.title" class="mr-5" />
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import DotLabel from "./DotLabel";
|
import DotLabel from './DotLabel'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ProgressLine',
|
name: 'ProgressLine',
|
||||||
props: [
|
props: ['data'],
|
||||||
'data',
|
components: {
|
||||||
],
|
DotLabel,
|
||||||
components: {
|
},
|
||||||
DotLabel,
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.chart-progress {
|
.chart-progress {
|
||||||
&.success {
|
&.success {
|
||||||
background: #0ABB87;
|
background: #0abb87;
|
||||||
box-shadow: 0 3px 10px rgba(#0ABB87, 0.5);
|
box-shadow: 0 3px 10px rgba(#0abb87, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.danger {
|
&.danger {
|
||||||
background: #fd397a;
|
background: #fd397a;
|
||||||
box-shadow: 0 3px 10px rgba(#fd397a, 0.5);
|
box-shadow: 0 3px 10px rgba(#fd397a, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.warning {
|
&.warning {
|
||||||
background: #ffb822;
|
background: #ffb822;
|
||||||
box-shadow: 0 3px 10px rgba(#ffb822, 0.5);
|
box-shadow: 0 3px 10px rgba(#ffb822, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.info {
|
&.info {
|
||||||
background: #5578eb;
|
background: #5578eb;
|
||||||
box-shadow: 0 3px 10px rgba(#5578eb, 0.5);
|
box-shadow: 0 3px 10px rgba(#5578eb, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.purple {
|
&.purple {
|
||||||
background: #9d66fe;
|
background: #9d66fe;
|
||||||
box-shadow: 0 3px 10px rgba(#9d66fe, 0.5);
|
box-shadow: 0 3px 10px rgba(#9d66fe, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.secondary {
|
&.secondary {
|
||||||
background: #e1e1ef;
|
background: #e1e1ef;
|
||||||
box-shadow: 0 3px 10px rgba(#e1e1ef, 0.5);
|
box-shadow: 0 3px 10px rgba(#e1e1ef, 0.5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark .chart-progress {
|
.dark .chart-progress {
|
||||||
&.secondary {
|
&.secondary {
|
||||||
background: #282A2F !important;
|
background: #282a2f !important;
|
||||||
box-shadow: 0 3px 10px rgba(#282A2F, 0.5) !important;
|
box-shadow: 0 3px 10px rgba(#282a2f, 0.5) !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,313 +1,339 @@
|
|||||||
<template>
|
<template>
|
||||||
<DatatableWrapper @init="isLoading = false" api="/api/admin/dashboard/newbies" :paginator="false" :columns="columns" class="overflow-x-auto mt-6">
|
<DatatableWrapper @init="isLoading = false" api="/api/admin/dashboard/newbies" :paginator="false" :columns="columns" class="mt-6 overflow-x-auto">
|
||||||
<template slot-scope="{ row }">
|
<template slot-scope="{ row }">
|
||||||
<!--Not a subscription-->
|
<!--Not a subscription-->
|
||||||
<tr v-if="config.subscriptionType === 'none'" class="border-b dark:border-opacity-5 border-light border-dashed whitespace-nowrap">
|
<tr v-if="config.subscriptionType === 'none'" class="whitespace-nowrap border-b border-dashed border-light dark:border-opacity-5">
|
||||||
<td class="py-3 md:pr-1 pr-3">
|
<td class="py-3 pr-3 md:pr-1">
|
||||||
<router-link :to="{name: 'UserDetail', params: {id: row.data.id}}">
|
<router-link
|
||||||
<div class="flex items-center">
|
:to="{
|
||||||
<MemberAvatar
|
name: 'UserDetail',
|
||||||
:is-border="false"
|
params: { id: row.data.id },
|
||||||
:size="44"
|
}"
|
||||||
:member="row.data.relationships.settings"
|
>
|
||||||
/>
|
<div class="flex items-center">
|
||||||
<div class="ml-3 pr-10">
|
<MemberAvatar :is-border="false" :size="44" :member="row.data.relationships.settings" />
|
||||||
<b class="text-sm font-bold block max-w-1 overflow-hidden text-ellipsis whitespace-nowrap" style="max-width: 155px;">
|
<div class="ml-3 pr-10">
|
||||||
{{ row.data.relationships.settings.data.attributes.name }}
|
<b class="max-w-1 block overflow-hidden text-ellipsis whitespace-nowrap text-sm font-bold" style="max-width: 155px">
|
||||||
</b>
|
{{ row.data.relationships.settings.data.attributes.name }}
|
||||||
<span class="block text-xs dark:text-gray-500 text-gray-600">
|
</b>
|
||||||
{{ row.data.attributes.email }}
|
<span class="block text-xs text-gray-600 dark:text-gray-500">
|
||||||
</span>
|
{{ row.data.attributes.email }}
|
||||||
</div>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</router-link>
|
</div>
|
||||||
</td>
|
</router-link>
|
||||||
<td class="md:px-1 px-3">
|
</td>
|
||||||
<ColorLabel :color="$getUserRoleColor(row.data.attributes.role)">
|
<td class="px-3 md:px-1">
|
||||||
{{ row.data.attributes.role }}
|
<ColorLabel :color="$getUserRoleColor(row.data.attributes.role)">
|
||||||
</ColorLabel>
|
{{ row.data.attributes.role }}
|
||||||
</td>
|
</ColorLabel>
|
||||||
<td class="md:px-1 px-3">
|
</td>
|
||||||
<span v-if="row.data.attributes.storage.capacity !== 0" class="text-sm font-bold">
|
<td class="px-3 md:px-1">
|
||||||
{{ row.data.attributes.storage.used_formatted }}
|
<span v-if="row.data.attributes.storage.capacity !== 0" class="text-sm font-bold">
|
||||||
</span>
|
{{ row.data.attributes.storage.used_formatted }}
|
||||||
<span v-if="row.data.attributes.storage.capacity === 0" class="text-sm font-bold">
|
</span>
|
||||||
-
|
<span v-if="row.data.attributes.storage.capacity === 0" class="text-sm font-bold"> - </span>
|
||||||
</span>
|
</td>
|
||||||
</td>
|
<td class="px-3 md:px-1" v-if="config.storageLimit">
|
||||||
<td class="md:px-1 px-3" v-if="config.storageLimit">
|
<span v-if="row.data.attributes.storage.capacity !== 0" class="text-sm font-bold">
|
||||||
<span v-if="row.data.attributes.storage.capacity !== 0" class="text-sm font-bold">
|
{{ row.data.attributes.storage.capacity_formatted }}
|
||||||
{{ row.data.attributes.storage.capacity_formatted }}
|
</span>
|
||||||
</span>
|
<span v-if="row.data.attributes.storage.capacity === 0" class="text-sm font-bold"> - </span>
|
||||||
<span v-if="row.data.attributes.storage.capacity === 0" class="text-sm font-bold">
|
</td>
|
||||||
-
|
<td class="px-3 md:px-1">
|
||||||
</span>
|
<span class="text-sm font-bold">
|
||||||
</td>
|
{{ row.data.attributes.created_at }}
|
||||||
<td class="md:px-1 px-3">
|
</span>
|
||||||
<span class="text-sm font-bold">
|
</td>
|
||||||
{{ row.data.attributes.created_at }}
|
<td class="pl-3 text-right md:pl-1">
|
||||||
</span>
|
<div class="flex w-full justify-end space-x-2">
|
||||||
</td>
|
<router-link
|
||||||
<td class="md:pl-1 pl-3 text-right">
|
class="flex h-8 w-8 items-center justify-center rounded-md bg-light-background transition-colors hover:bg-green-100 dark:bg-2x-dark-foreground"
|
||||||
<div class="flex space-x-2 w-full justify-end">
|
:to="{
|
||||||
<router-link class="flex items-center justify-center w-8 h-8 rounded-md hover:bg-green-100 dark:bg-2x-dark-foreground bg-light-background transition-colors" :to="{name: 'UserDetail', params: {id: row.data.id}}">
|
name: 'UserDetail',
|
||||||
<Edit2Icon size="15" class="opacity-75" />
|
params: { id: row.data.id },
|
||||||
</router-link>
|
}"
|
||||||
<router-link class="flex items-center justify-center w-8 h-8 rounded-md hover:bg-red-100 dark:bg-2x-dark-foreground bg-light-background transition-colors" :to="{name: 'UserDelete', params: {id: row.data.id}}">
|
>
|
||||||
<Trash2Icon size="15" class="opacity-75" />
|
<Edit2Icon size="15" class="opacity-75" />
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
<router-link
|
||||||
</td>
|
class="flex h-8 w-8 items-center justify-center rounded-md bg-light-background transition-colors hover:bg-red-100 dark:bg-2x-dark-foreground"
|
||||||
</tr>
|
:to="{
|
||||||
|
name: 'UserDelete',
|
||||||
|
params: { id: row.data.id },
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<Trash2Icon size="15" class="opacity-75" />
|
||||||
|
</router-link>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
<!--Fixed subscription-->
|
<!--Fixed subscription-->
|
||||||
<tr v-if="config.subscriptionType === 'fixed'" class="border-b dark:border-opacity-5 border-light border-dashed whitespace-nowrap">
|
<tr v-if="config.subscriptionType === 'fixed'" class="whitespace-nowrap border-b border-dashed border-light dark:border-opacity-5">
|
||||||
<td class="py-3 md:pr-1 pr-3">
|
<td class="py-3 pr-3 md:pr-1">
|
||||||
<router-link :to="{name: 'UserDetail', params: {id: row.data.id}}">
|
<router-link
|
||||||
<div class="flex items-center">
|
:to="{
|
||||||
<MemberAvatar
|
name: 'UserDetail',
|
||||||
:is-border="false"
|
params: { id: row.data.id },
|
||||||
:size="44"
|
}"
|
||||||
:member="row.data.relationships.settings"
|
>
|
||||||
/>
|
<div class="flex items-center">
|
||||||
<div class="ml-3 pr-10">
|
<MemberAvatar :is-border="false" :size="44" :member="row.data.relationships.settings" />
|
||||||
<b class="text-sm font-bold block max-w-1 overflow-hidden text-ellipsis whitespace-nowrap" style="max-width: 155px;">
|
<div class="ml-3 pr-10">
|
||||||
{{ row.data.relationships.settings.data.attributes.name }}
|
<b class="max-w-1 block overflow-hidden text-ellipsis whitespace-nowrap text-sm font-bold" style="max-width: 155px">
|
||||||
</b>
|
{{ row.data.relationships.settings.data.attributes.name }}
|
||||||
<span class="block text-xs dark:text-gray-500 text-gray-600">
|
</b>
|
||||||
{{ row.data.attributes.email }}
|
<span class="block text-xs text-gray-600 dark:text-gray-500">
|
||||||
</span>
|
{{ row.data.attributes.email }}
|
||||||
</div>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</router-link>
|
</div>
|
||||||
</td>
|
</router-link>
|
||||||
<td class="md:px-1 px-3">
|
</td>
|
||||||
<ColorLabel :color="$getUserRoleColor(row.data.attributes.role)">
|
<td class="px-3 md:px-1">
|
||||||
{{ row.data.attributes.role }}
|
<ColorLabel :color="$getUserRoleColor(row.data.attributes.role)">
|
||||||
</ColorLabel>
|
{{ row.data.attributes.role }}
|
||||||
</td>
|
</ColorLabel>
|
||||||
<td class="md:px-1 px-3" v-if="config.isSaaS">
|
</td>
|
||||||
<span class="text-sm font-bold">
|
<td class="px-3 md:px-1" v-if="config.isSaaS">
|
||||||
{{ row.data.relationships.subscription ? $t('global.premium') : $t('global.free') }}
|
<span class="text-sm font-bold">
|
||||||
</span>
|
{{ row.data.relationships.subscription ? $t('global.premium') : $t('global.free') }}
|
||||||
</td>
|
</span>
|
||||||
<td class="md:px-1 px-3">
|
</td>
|
||||||
<span v-if="row.data.attributes.storage.capacity !== 0" class="text-sm font-bold">
|
<td class="px-3 md:px-1">
|
||||||
{{ row.data.attributes.storage.used_formatted }}
|
<span v-if="row.data.attributes.storage.capacity !== 0" class="text-sm font-bold">
|
||||||
</span>
|
{{ row.data.attributes.storage.used_formatted }}
|
||||||
<span v-if="row.data.attributes.storage.capacity === 0" class="text-sm font-bold">
|
</span>
|
||||||
-
|
<span v-if="row.data.attributes.storage.capacity === 0" class="text-sm font-bold"> - </span>
|
||||||
</span>
|
</td>
|
||||||
</td>
|
<td class="px-3 md:px-1" v-if="config.storageLimit">
|
||||||
<td class="md:px-1 px-3" v-if="config.storageLimit">
|
<span v-if="row.data.attributes.storage.capacity !== 0" class="text-sm font-bold">
|
||||||
<span v-if="row.data.attributes.storage.capacity !== 0" class="text-sm font-bold">
|
{{ row.data.attributes.storage.capacity_formatted }}
|
||||||
{{ row.data.attributes.storage.capacity_formatted }}
|
</span>
|
||||||
</span>
|
<span v-if="row.data.attributes.storage.capacity === 0" class="text-sm font-bold"> - </span>
|
||||||
<span v-if="row.data.attributes.storage.capacity === 0" class="text-sm font-bold">
|
</td>
|
||||||
-
|
<td class="px-3 md:px-1">
|
||||||
</span>
|
<span class="text-sm font-bold">
|
||||||
</td>
|
{{ row.data.attributes.created_at }}
|
||||||
<td class="md:px-1 px-3">
|
</span>
|
||||||
<span class="text-sm font-bold">
|
</td>
|
||||||
{{ row.data.attributes.created_at }}
|
<td class="pl-3 text-right md:pl-1">
|
||||||
</span>
|
<div class="flex w-full justify-end space-x-2">
|
||||||
</td>
|
<router-link
|
||||||
<td class="md:pl-1 pl-3 text-right">
|
class="flex h-8 w-8 items-center justify-center rounded-md bg-light-background transition-colors hover:bg-green-100 dark:bg-2x-dark-foreground"
|
||||||
<div class="flex space-x-2 w-full justify-end">
|
:to="{
|
||||||
<router-link class="flex items-center justify-center w-8 h-8 rounded-md hover:bg-green-100 dark:bg-2x-dark-foreground bg-light-background transition-colors" :to="{name: 'UserDetail', params: {id: row.data.id}}">
|
name: 'UserDetail',
|
||||||
<Edit2Icon size="15" class="opacity-75" />
|
params: { id: row.data.id },
|
||||||
</router-link>
|
}"
|
||||||
<router-link class="flex items-center justify-center w-8 h-8 rounded-md hover:bg-red-100 dark:bg-2x-dark-foreground bg-light-background transition-colors" :to="{name: 'UserDelete', params: {id: row.data.id}}">
|
>
|
||||||
<Trash2Icon size="15" class="opacity-75" />
|
<Edit2Icon size="15" class="opacity-75" />
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
<router-link
|
||||||
</td>
|
class="flex h-8 w-8 items-center justify-center rounded-md bg-light-background transition-colors hover:bg-red-100 dark:bg-2x-dark-foreground"
|
||||||
</tr>
|
:to="{
|
||||||
|
name: 'UserDelete',
|
||||||
|
params: { id: row.data.id },
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<Trash2Icon size="15" class="opacity-75" />
|
||||||
|
</router-link>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
<!--Metered subscription-->
|
<!--Metered subscription-->
|
||||||
<tr v-if="config.subscriptionType === 'metered'" class="border-b dark:border-opacity-5 border-light border-dashed whitespace-nowrap">
|
<tr v-if="config.subscriptionType === 'metered'" class="whitespace-nowrap border-b border-dashed border-light dark:border-opacity-5">
|
||||||
<td class="py-3 md:pr-1 pr-3">
|
<td class="py-3 pr-3 md:pr-1">
|
||||||
<router-link :to="{name: 'UserDetail', params: {id: row.data.id}}">
|
<router-link
|
||||||
<div class="flex items-center">
|
:to="{
|
||||||
<MemberAvatar
|
name: 'UserDetail',
|
||||||
:is-border="false"
|
params: { id: row.data.id },
|
||||||
:size="44"
|
}"
|
||||||
:member="row.data.relationships.settings"
|
>
|
||||||
/>
|
<div class="flex items-center">
|
||||||
<div class="ml-3 pr-10">
|
<MemberAvatar :is-border="false" :size="44" :member="row.data.relationships.settings" />
|
||||||
<b class="text-sm font-bold block max-w-1 overflow-hidden text-ellipsis whitespace-nowrap" style="max-width: 155px;">
|
<div class="ml-3 pr-10">
|
||||||
{{ row.data.relationships.settings.data.attributes.name }}
|
<b class="max-w-1 block overflow-hidden text-ellipsis whitespace-nowrap text-sm font-bold" style="max-width: 155px">
|
||||||
</b>
|
{{ row.data.relationships.settings.data.attributes.name }}
|
||||||
<span class="block text-xs dark:text-gray-500 text-gray-600">
|
</b>
|
||||||
{{ row.data.attributes.email }}
|
<span class="block text-xs text-gray-600 dark:text-gray-500">
|
||||||
</span>
|
{{ row.data.attributes.email }}
|
||||||
</div>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</router-link>
|
</div>
|
||||||
</td>
|
</router-link>
|
||||||
<td class="md:px-1 px-3">
|
</td>
|
||||||
<ColorLabel :color="$getUserRoleColor(row.data.attributes.role)">
|
<td class="px-3 md:px-1">
|
||||||
{{ row.data.attributes.role }}
|
<ColorLabel :color="$getUserRoleColor(row.data.attributes.role)">
|
||||||
</ColorLabel>
|
{{ row.data.attributes.role }}
|
||||||
</td>
|
</ColorLabel>
|
||||||
<td class="md:px-1 px-3">
|
</td>
|
||||||
<span class="text-sm font-bold">
|
<td class="px-3 md:px-1">
|
||||||
{{ row.data.meta.usages.featureEstimates.storage.usage }}
|
<span class="text-sm font-bold">
|
||||||
</span>
|
{{ row.data.meta.usages.featureEstimates.storage.usage }}
|
||||||
</td>
|
</span>
|
||||||
<td class="md:px-1 px-3">
|
</td>
|
||||||
<span class="text-sm font-bold">
|
<td class="px-3 md:px-1">
|
||||||
{{ row.data.meta.usages.costEstimate }}
|
<span class="text-sm font-bold">
|
||||||
</span>
|
{{ row.data.meta.usages.costEstimate }}
|
||||||
</td>
|
</span>
|
||||||
<td class="md:px-1 px-3">
|
</td>
|
||||||
<span class="text-sm font-bold">
|
<td class="px-3 md:px-1">
|
||||||
{{ row.data.attributes.created_at }}
|
<span class="text-sm font-bold">
|
||||||
</span>
|
{{ row.data.attributes.created_at }}
|
||||||
</td>
|
</span>
|
||||||
<td class="md:pl-1 pl-3 text-right">
|
</td>
|
||||||
<div class="flex space-x-2 w-full justify-end">
|
<td class="pl-3 text-right md:pl-1">
|
||||||
<router-link class="flex items-center justify-center w-8 h-8 rounded-md hover:bg-green-100 dark:bg-2x-dark-foreground bg-light-background transition-colors" :to="{name: 'UserDetail', params: {id: row.data.id}}">
|
<div class="flex w-full justify-end space-x-2">
|
||||||
<Edit2Icon size="15" class="opacity-75" />
|
<router-link
|
||||||
</router-link>
|
class="flex h-8 w-8 items-center justify-center rounded-md bg-light-background transition-colors hover:bg-green-100 dark:bg-2x-dark-foreground"
|
||||||
<router-link class="flex items-center justify-center w-8 h-8 rounded-md hover:bg-red-100 dark:bg-2x-dark-foreground bg-light-background transition-colors" :to="{name: 'UserDelete', params: {id: row.data.id}}">
|
:to="{
|
||||||
<Trash2Icon size="15" class="opacity-75" />
|
name: 'UserDetail',
|
||||||
</router-link>
|
params: { id: row.data.id },
|
||||||
</div>
|
}"
|
||||||
</td>
|
>
|
||||||
</tr>
|
<Edit2Icon size="15" class="opacity-75" />
|
||||||
</template>
|
</router-link>
|
||||||
</DatatableWrapper>
|
<router-link
|
||||||
|
class="flex h-8 w-8 items-center justify-center rounded-md bg-light-background transition-colors hover:bg-red-100 dark:bg-2x-dark-foreground"
|
||||||
|
:to="{
|
||||||
|
name: 'UserDelete',
|
||||||
|
params: { id: row.data.id },
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<Trash2Icon size="15" class="opacity-75" />
|
||||||
|
</router-link>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</template>
|
||||||
|
</DatatableWrapper>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import DatatableCellImage from "../Others/Tables/DatatableCellImage";
|
import DatatableCellImage from '../Others/Tables/DatatableCellImage'
|
||||||
import DatatableWrapper from "../Others/Tables/DatatableWrapper";
|
import DatatableWrapper from '../Others/Tables/DatatableWrapper'
|
||||||
import ColorLabel from "../Others/ColorLabel";
|
import ColorLabel from '../Others/ColorLabel'
|
||||||
import {Trash2Icon, Edit2Icon} from "vue-feather-icons"
|
import { Trash2Icon, Edit2Icon } from 'vue-feather-icons'
|
||||||
import MemberAvatar from "../FilesView/MemberAvatar";
|
import MemberAvatar from '../FilesView/MemberAvatar'
|
||||||
import { mapGetters } from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'WidgetLatestRegistrations',
|
name: 'WidgetLatestRegistrations',
|
||||||
props: [
|
props: ['icon', 'title'],
|
||||||
'icon',
|
components: {
|
||||||
'title'
|
DatatableCellImage,
|
||||||
],
|
DatatableWrapper,
|
||||||
components: {
|
MemberAvatar,
|
||||||
DatatableCellImage,
|
Trash2Icon,
|
||||||
DatatableWrapper,
|
ColorLabel,
|
||||||
MemberAvatar,
|
Edit2Icon,
|
||||||
Trash2Icon,
|
},
|
||||||
ColorLabel,
|
computed: {
|
||||||
Edit2Icon,
|
...mapGetters(['config']),
|
||||||
},
|
columns() {
|
||||||
computed: {
|
|
||||||
...mapGetters([
|
|
||||||
'config',
|
|
||||||
]),
|
|
||||||
columns() {
|
|
||||||
return {
|
|
||||||
metered: [
|
|
||||||
{
|
|
||||||
label: this.$t('admin_page_user.table.name'),
|
|
||||||
field: 'email',
|
|
||||||
sortable: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: this.$t('admin_page_user.table.role'),
|
|
||||||
field: 'role',
|
|
||||||
sortable: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: this.$t('admin_page_user.table.storage_used'),
|
|
||||||
sortable: false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: this.$t('Billing Est.'),
|
|
||||||
sortable: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: this.$t('admin_page_user.table.created_at'),
|
|
||||||
field: 'created_at',
|
|
||||||
sortable: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: this.$t('admin_page_user.table.action'),
|
|
||||||
sortable: false
|
|
||||||
},
|
|
||||||
],
|
|
||||||
fixed: [
|
|
||||||
{
|
|
||||||
label: this.$t('admin_page_user.table.name'),
|
|
||||||
field: 'email',
|
|
||||||
sortable: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: this.$t('admin_page_user.table.role'),
|
|
||||||
field: 'role',
|
|
||||||
sortable: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: this.$t('admin_page_user.table.plan'),
|
|
||||||
sortable: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: this.$t('admin_page_user.table.storage_used'),
|
|
||||||
sortable: false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: this.$t('Max Storage'),
|
|
||||||
sortable: false,
|
|
||||||
hidden: ! this.config.storageLimit,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: this.$t('admin_page_user.table.created_at'),
|
|
||||||
field: 'created_at',
|
|
||||||
sortable: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: this.$t('admin_page_user.table.action'),
|
|
||||||
sortable: false
|
|
||||||
},
|
|
||||||
],
|
|
||||||
none: [
|
|
||||||
{
|
|
||||||
label: this.$t('admin_page_user.table.name'),
|
|
||||||
field: 'email',
|
|
||||||
sortable: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: this.$t('admin_page_user.table.role'),
|
|
||||||
field: 'role',
|
|
||||||
sortable: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: this.$t('admin_page_user.table.storage_used'),
|
|
||||||
sortable: false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: this.$t('Max Storage'),
|
|
||||||
sortable: false,
|
|
||||||
hidden: ! this.config.storageLimit,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: this.$t('admin_page_user.table.created_at'),
|
|
||||||
field: 'created_at',
|
|
||||||
sortable: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: this.$t('admin_page_user.table.action'),
|
|
||||||
sortable: false
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}[this.config.subscriptionType]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
return {
|
||||||
isLoading: false,
|
metered: [
|
||||||
}
|
{
|
||||||
|
label: this.$t('admin_page_user.table.name'),
|
||||||
|
field: 'email',
|
||||||
|
sortable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: this.$t('admin_page_user.table.role'),
|
||||||
|
field: 'role',
|
||||||
|
sortable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: this.$t('admin_page_user.table.storage_used'),
|
||||||
|
sortable: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: this.$t('Billing Est.'),
|
||||||
|
sortable: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: this.$t('admin_page_user.table.created_at'),
|
||||||
|
field: 'created_at',
|
||||||
|
sortable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: this.$t('admin_page_user.table.action'),
|
||||||
|
sortable: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
fixed: [
|
||||||
|
{
|
||||||
|
label: this.$t('admin_page_user.table.name'),
|
||||||
|
field: 'email',
|
||||||
|
sortable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: this.$t('admin_page_user.table.role'),
|
||||||
|
field: 'role',
|
||||||
|
sortable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: this.$t('admin_page_user.table.plan'),
|
||||||
|
sortable: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: this.$t('admin_page_user.table.storage_used'),
|
||||||
|
sortable: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: this.$t('Max Storage'),
|
||||||
|
sortable: false,
|
||||||
|
hidden: !this.config.storageLimit,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: this.$t('admin_page_user.table.created_at'),
|
||||||
|
field: 'created_at',
|
||||||
|
sortable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: this.$t('admin_page_user.table.action'),
|
||||||
|
sortable: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
none: [
|
||||||
|
{
|
||||||
|
label: this.$t('admin_page_user.table.name'),
|
||||||
|
field: 'email',
|
||||||
|
sortable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: this.$t('admin_page_user.table.role'),
|
||||||
|
field: 'role',
|
||||||
|
sortable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: this.$t('admin_page_user.table.storage_used'),
|
||||||
|
sortable: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: this.$t('Max Storage'),
|
||||||
|
sortable: false,
|
||||||
|
hidden: !this.config.storageLimit,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: this.$t('admin_page_user.table.created_at'),
|
||||||
|
field: 'created_at',
|
||||||
|
sortable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: this.$t('admin_page_user.table.action'),
|
||||||
|
sortable: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}[this.config.subscriptionType]
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
isLoading: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,135 +1,122 @@
|
|||||||
<template>
|
<template>
|
||||||
<DatatableWrapper
|
<DatatableWrapper api="/api/admin/dashboard/transactions" :columns="columns" class="overflow-x-auto">
|
||||||
api="/api/admin/dashboard/transactions"
|
<template slot-scope="{ row }">
|
||||||
:columns="columns"
|
<tr class="whitespace-nowrap border-b border-dashed border-light dark:border-opacity-5">
|
||||||
class="overflow-x-auto"
|
<td class="py-5 pr-3 md:pr-1">
|
||||||
>
|
<span class="text-sm font-bold">
|
||||||
<template slot-scope="{ row }">
|
{{ row.data.attributes.note }}
|
||||||
<tr class="border-b dark:border-opacity-5 border-light border-dashed whitespace-nowrap">
|
</span>
|
||||||
<td class="py-5 md:pr-1 pr-3">
|
</td>
|
||||||
<span class="text-sm font-bold">
|
<td class="px-3 md:px-1">
|
||||||
{{ row.data.attributes.note }}
|
<div v-if="row.data.relationships.user" class="flex items-center">
|
||||||
</span>
|
<MemberAvatar :is-border="false" :size="36" :member="row.data.relationships.user" />
|
||||||
</td>
|
<div class="ml-3 pr-10">
|
||||||
<td class="md:px-1 px-3">
|
<b class="max-w-1 block overflow-hidden text-ellipsis whitespace-nowrap text-sm font-bold" style="max-width: 155px">
|
||||||
<div v-if="row.data.relationships.user" class="flex items-center">
|
{{ row.data.relationships.user.data.attributes.name }}
|
||||||
<MemberAvatar
|
</b>
|
||||||
:is-border="false"
|
<span class="block text-xs text-gray-600 dark:text-gray-500">
|
||||||
:size="36"
|
{{ row.data.relationships.user.data.attributes.email }}
|
||||||
:member="row.data.relationships.user"
|
</span>
|
||||||
/>
|
</div>
|
||||||
<div class="ml-3 pr-10">
|
</div>
|
||||||
<b class="text-sm font-bold block max-w-1 overflow-hidden text-ellipsis whitespace-nowrap" style="max-width: 155px;">
|
<span v-if="!row.data.relationships.user" class="text-xs font-bold text-gray-500">
|
||||||
{{ row.data.relationships.user.data.attributes.name }}
|
{{ $t('User was deleted') }}
|
||||||
</b>
|
</span>
|
||||||
<span class="block text-xs dark:text-gray-500 text-gray-600">
|
</td>
|
||||||
{{ row.data.relationships.user.data.attributes.email }}
|
<td class="px-3 md:px-1">
|
||||||
</span>
|
<ColorLabel v-if="config.subscriptionType === 'fixed'" :color="$getTransactionStatusColor(row.data.attributes.status)">
|
||||||
</div>
|
{{ row.data.attributes.status }}
|
||||||
</div>
|
</ColorLabel>
|
||||||
<span v-if="! row.data.relationships.user" class="text-xs text-gray-500 font-bold">
|
<ColorLabel v-if="config.subscriptionType === 'metered'" :color="$getTransactionTypeColor(row.data.attributes.type)">
|
||||||
{{ $t('User was deleted') }}
|
{{ row.data.attributes.type }}
|
||||||
</span>
|
</ColorLabel>
|
||||||
</td>
|
</td>
|
||||||
<td class="md:px-1 px-3">
|
<td class="px-3 md:px-1">
|
||||||
<ColorLabel v-if="config.subscriptionType === 'fixed'" :color="$getTransactionStatusColor(row.data.attributes.status)">
|
<span class="text-sm font-bold" :class="$getTransactionTypeTextColor(row.data.attributes.type)">
|
||||||
{{ row.data.attributes.status }}
|
{{ $getTransactionMark(row.data.attributes.type) + row.data.attributes.price }}
|
||||||
</ColorLabel>
|
</span>
|
||||||
<ColorLabel v-if="config.subscriptionType === 'metered'" :color="$getTransactionTypeColor(row.data.attributes.type)">
|
</td>
|
||||||
{{ row.data.attributes.type }}
|
<td class="px-3 md:px-1">
|
||||||
</ColorLabel>
|
<span class="text-sm font-bold">
|
||||||
</td>
|
{{ row.data.attributes.created_at }}
|
||||||
<td class="md:px-1 px-3">
|
</span>
|
||||||
<span class="text-sm font-bold" :class="$getTransactionTypeTextColor(row.data.attributes.type)">
|
</td>
|
||||||
{{ $getTransactionMark(row.data.attributes.type) + row.data.attributes.price }}
|
<td class="pl-3 md:pl-1">
|
||||||
</span>
|
<div class="w-32 text-right md:w-full">
|
||||||
</td>
|
<img class="w-32 md:inline-block" :src="$getPaymentLogo(row.data.attributes.driver)" :alt="row.data.attributes.driver" />
|
||||||
<td class="md:px-1 px-3">
|
</div>
|
||||||
<span class="text-sm font-bold">
|
</td>
|
||||||
{{ row.data.attributes.created_at }}
|
</tr>
|
||||||
</span>
|
</template>
|
||||||
</td>
|
|
||||||
<td class="md:pl-1 pl-3">
|
|
||||||
<div class="text-right md:w-full w-32">
|
|
||||||
<img class="w-32 md:inline-block" :src="$getPaymentLogo(row.data.attributes.driver)" :alt="row.data.attributes.driver">
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<!--Empty page-->
|
<!--Empty page-->
|
||||||
<template v-slot:empty-page>
|
<template v-slot:empty-page>
|
||||||
<InfoBox style="margin-bottom: 0">
|
<InfoBox style="margin-bottom: 0">
|
||||||
<p>{{ $t("There aren't any transactions.") }}</p>
|
<p>{{ $t("There aren't any transactions.") }}</p>
|
||||||
</InfoBox>
|
</InfoBox>
|
||||||
</template>
|
</template>
|
||||||
</DatatableWrapper>
|
</DatatableWrapper>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import DatatableCellImage from "../Others/Tables/DatatableCellImage";
|
import DatatableCellImage from '../Others/Tables/DatatableCellImage'
|
||||||
import DatatableWrapper from "../Others/Tables/DatatableWrapper";
|
import DatatableWrapper from '../Others/Tables/DatatableWrapper'
|
||||||
import ColorLabel from "../Others/ColorLabel";
|
import ColorLabel from '../Others/ColorLabel'
|
||||||
import {Trash2Icon, Edit2Icon} from "vue-feather-icons"
|
import { Trash2Icon, Edit2Icon } from 'vue-feather-icons'
|
||||||
import MemberAvatar from "../FilesView/MemberAvatar"
|
import MemberAvatar from '../FilesView/MemberAvatar'
|
||||||
import InfoBox from "../Others/Forms/InfoBox"
|
import InfoBox from '../Others/Forms/InfoBox'
|
||||||
import { mapGetters } from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'WidgetLatestTransactions',
|
name: 'WidgetLatestTransactions',
|
||||||
props: [
|
props: ['icon', 'title'],
|
||||||
'icon',
|
components: {
|
||||||
'title'
|
DatatableCellImage,
|
||||||
],
|
DatatableWrapper,
|
||||||
components: {
|
MemberAvatar,
|
||||||
DatatableCellImage,
|
Trash2Icon,
|
||||||
DatatableWrapper,
|
ColorLabel,
|
||||||
MemberAvatar,
|
Edit2Icon,
|
||||||
Trash2Icon,
|
InfoBox,
|
||||||
ColorLabel,
|
},
|
||||||
Edit2Icon,
|
computed: {
|
||||||
InfoBox,
|
...mapGetters(['config']),
|
||||||
},
|
},
|
||||||
computed: {
|
data() {
|
||||||
...mapGetters([
|
return {
|
||||||
'config',
|
columns: [
|
||||||
]),
|
{
|
||||||
},
|
label: this.$t('Note'),
|
||||||
data() {
|
field: 'note',
|
||||||
return {
|
sortable: true,
|
||||||
columns: [
|
},
|
||||||
{
|
{
|
||||||
label: this.$t('Note'),
|
label: this.$t('User'),
|
||||||
field: 'note',
|
field: 'user_id',
|
||||||
sortable: true
|
sortable: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: this.$t('User'),
|
label: this.$t('Status'),
|
||||||
field: 'user_id',
|
field: 'status',
|
||||||
sortable: true
|
sortable: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: this.$t('Status'),
|
label: this.$t('admin_page_invoices.table.total'),
|
||||||
field: 'status',
|
field: 'amount',
|
||||||
sortable: true
|
sortable: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: this.$t('admin_page_invoices.table.total'),
|
label: this.$t('Payed At'),
|
||||||
field: 'amount',
|
field: 'created_at',
|
||||||
sortable: true
|
sortable: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: this.$t('Payed At'),
|
label: this.$t('Service'),
|
||||||
field: 'created_at',
|
field: 'driver',
|
||||||
sortable: true
|
sortable: true,
|
||||||
},
|
},
|
||||||
{
|
],
|
||||||
label: this.$t('Service'),
|
}
|
||||||
field: 'driver',
|
},
|
||||||
sortable: true
|
}
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="widget-card w-full">
|
<div class="widget-card w-full">
|
||||||
<div class="widget-content dark:bg-dark-foreground bg-white">
|
<div class="widget-content bg-white dark:bg-dark-foreground">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<users-icon v-if="icon === 'users'" size="16" class="vue-feather text-theme mr-3 "/>
|
<users-icon v-if="icon === 'users'" size="16" class="vue-feather text-theme mr-3" />
|
||||||
<star-icon v-if="icon === 'star'" size="16" class="vue-feather text-theme mr-3 "/>
|
<star-icon v-if="icon === 'star'" size="16" class="vue-feather text-theme mr-3" />
|
||||||
<hard-drive-icon v-if="icon === 'hard-drive'" size="16" class="vue-feather text-theme mr-3 "/>
|
<hard-drive-icon v-if="icon === 'hard-drive'" size="16" class="vue-feather text-theme mr-3" />
|
||||||
<b class="font-bold text-base">
|
<b class="text-base font-bold">
|
||||||
{{ title }}
|
{{ title }}
|
||||||
</b>
|
</b>
|
||||||
</div>
|
</div>
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
@@ -15,16 +15,16 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { UsersIcon, StarIcon, HardDriveIcon, ChevronRightIcon } from 'vue-feather-icons'
|
import { UsersIcon, StarIcon, HardDriveIcon, ChevronRightIcon } from 'vue-feather-icons'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'WidgetWrapper',
|
name: 'WidgetWrapper',
|
||||||
props: ['icon', 'title'],
|
props: ['icon', 'title'],
|
||||||
components: {
|
components: {
|
||||||
ChevronRightIcon,
|
ChevronRightIcon,
|
||||||
HardDriveIcon,
|
HardDriveIcon,
|
||||||
StarIcon,
|
StarIcon,
|
||||||
UsersIcon
|
UsersIcon,
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,51 +1,45 @@
|
|||||||
<template>
|
<template>
|
||||||
<button class="group flex items-center border-2 dark:border-gray-300 border-black rounded-lg inline-block mx-auto px-7 py-2.5 whitespace-nowrap">
|
<button class="group mx-auto inline-block flex items-center whitespace-nowrap rounded-lg border-2 border-black px-7 py-2.5 dark:border-gray-300">
|
||||||
<span class="font-extrabold text-lg pr-1">
|
<span class="pr-1 text-lg font-extrabold">
|
||||||
{{ text }}
|
{{ text }}
|
||||||
</span>
|
</span>
|
||||||
<refresh-cw-icon v-if="loading" size="20" class="vue-feather text-theme -mr-1 sync-alt"/>
|
<refresh-cw-icon v-if="loading" size="20" class="vue-feather text-theme sync-alt -mr-1" />
|
||||||
<chevron-right-icon v-if="! loading && icon" size="20" class="vue-feather text-theme -mr-1"/>
|
<chevron-right-icon v-if="!loading && icon" size="20" class="vue-feather text-theme -mr-1" />
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { ChevronRightIcon, RefreshCwIcon } from 'vue-feather-icons'
|
import { ChevronRightIcon, RefreshCwIcon } from 'vue-feather-icons'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'AuthContent',
|
name: 'AuthContent',
|
||||||
props: [
|
props: ['loading', 'icon', 'text'],
|
||||||
'loading',
|
components: {
|
||||||
'icon',
|
ChevronRightIcon,
|
||||||
'text'
|
RefreshCwIcon,
|
||||||
],
|
},
|
||||||
components: {
|
data() {
|
||||||
ChevronRightIcon,
|
return {
|
||||||
RefreshCwIcon,
|
isVisible: false,
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
isVisible: false,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.isVisible = this.visible
|
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
created() {
|
||||||
|
this.isVisible = this.visible
|
||||||
|
},
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
.sync-alt {
|
||||||
|
animation: spin 1s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
.sync-alt {
|
@keyframes spin {
|
||||||
animation: spin 1s linear infinite;
|
0% {
|
||||||
|
transform: rotate(0);
|
||||||
}
|
}
|
||||||
|
100% {
|
||||||
@keyframes spin {
|
transform: rotate(360deg);
|
||||||
0% {
|
|
||||||
transform: rotate(0);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,23 +1,20 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="isVisible" class="text-center w-full max-w-xl">
|
<div v-if="isVisible" class="w-full max-w-xl text-center">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'AuthContent',
|
name: 'AuthContent',
|
||||||
props: [
|
props: ['visible', 'name'],
|
||||||
'visible',
|
data() {
|
||||||
'name'
|
return {
|
||||||
],
|
isVisible: false,
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
isVisible: false,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.isVisible = this.visible
|
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
</script>
|
created() {
|
||||||
|
this.isVisible = this.visible
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex justify-center items-center md:px-0 px-5">
|
<div class="flex items-center justify-center px-5 md:px-0">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'AuthContentWrapper',
|
name: 'AuthContentWrapper',
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="config.allowedFacebookLogin || config.allowedGoogleLogin || config.allowedGithubLogin" class="flex items-center justify-center mb-10">
|
<div v-if="config.allowedFacebookLogin || config.allowedGoogleLogin || config.allowedGithubLogin" class="mb-10 flex items-center justify-center">
|
||||||
<div v-if="config.allowedFacebookLogin" class="mx-5 cursor-pointer">
|
<div v-if="config.allowedFacebookLogin" class="mx-5 cursor-pointer">
|
||||||
<facebook-icon @click="socialiteRedirect('facebook')" />
|
<facebook-icon @click="socialiteRedirect('facebook')" />
|
||||||
</div>
|
</div>
|
||||||
@@ -9,32 +9,30 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="config.allowedGoogleLogin" class="mx-5 cursor-pointer">
|
<div v-if="config.allowedGoogleLogin" class="mx-5 cursor-pointer">
|
||||||
<span @click="socialiteRedirect('google')" class="font-semibold text-3xl">G</span>
|
<span @click="socialiteRedirect('google')" class="text-3xl font-semibold">G</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { FacebookIcon, GithubIcon } from 'vue-feather-icons'
|
import { FacebookIcon, GithubIcon } from 'vue-feather-icons'
|
||||||
import {mapGetters} from "vuex";
|
import { mapGetters } from 'vuex'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name:'SocialiteAuthenticationButtons',
|
name: 'SocialiteAuthenticationButtons',
|
||||||
components: {
|
components: {
|
||||||
FacebookIcon,
|
FacebookIcon,
|
||||||
GithubIcon,
|
GithubIcon,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters([
|
...mapGetters(['config']),
|
||||||
'config'
|
},
|
||||||
])
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
socialiteRedirect(provider) {
|
socialiteRedirect(provider) {
|
||||||
this.isLoading = true
|
this.isLoading = true
|
||||||
|
|
||||||
this.$store.dispatch('socialiteRedirect', provider)
|
this.$store.dispatch('socialiteRedirect', provider)
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,47 +1,41 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="isVisible">
|
<div v-if="isVisible">
|
||||||
<!--Overlay component-->
|
<!--Overlay component-->
|
||||||
<div
|
<div
|
||||||
@click.capture="hidePopover"
|
@click.capture="hidePopover"
|
||||||
class="absolute top-12 z-20 w-60 dark:bg-dark-foreground bg-white shadow-xl rounded-lg overflow-hidden"
|
class="absolute top-12 z-20 w-60 overflow-hidden rounded-lg bg-white shadow-xl dark:bg-dark-foreground"
|
||||||
:class="{'right-0': side === 'left', 'left-0': side === 'right'}"
|
:class="{ 'right-0': side === 'left', 'left-0': side === 'right' }"
|
||||||
>
|
>
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!--Clickable layer to close overlays-->
|
<!--Clickable layer to close overlays-->
|
||||||
<div
|
<div @click="hidePopover" class="fixed top-0 left-0 right-0 bottom-0 z-10 cursor-pointer"></div>
|
||||||
@click="hidePopover"
|
</div>
|
||||||
class="fixed top-0 left-0 right-0 bottom-0 z-10 cursor-pointer"
|
|
||||||
></div>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {events} from "../../bus";
|
import { events } from '../../bus'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'PopoverItem',
|
name: 'PopoverItem',
|
||||||
props: [
|
props: ['side', 'name'],
|
||||||
'side',
|
data() {
|
||||||
'name',
|
return {
|
||||||
],
|
isVisible: false,
|
||||||
data() {
|
}
|
||||||
return {
|
},
|
||||||
isVisible: false,
|
methods: {
|
||||||
}
|
hidePopover() {
|
||||||
},
|
setTimeout(() => (this.isVisible = false), 10)
|
||||||
methods: {
|
},
|
||||||
hidePopover() {
|
},
|
||||||
setTimeout(() => this.isVisible = false, 10)
|
mounted() {
|
||||||
}
|
events.$on('popover:open', (name) => {
|
||||||
},
|
if (this.name === name) {
|
||||||
mounted() {
|
this.isVisible = !this.isVisible
|
||||||
events.$on('popover:open', name => {
|
}
|
||||||
if (this.name === name) {
|
})
|
||||||
this.isVisible = !this.isVisible
|
},
|
||||||
}
|
}
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,18 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="popover-wrapper">
|
<div class="popover-wrapper">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'PopoverWrapper',
|
name: 'PopoverWrapper',
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
.popover-wrapper {
|
||||||
.popover-wrapper {
|
position: relative;
|
||||||
position: relative;
|
}
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,28 +1,25 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="toolbar-button-wrapper">
|
<div class="toolbar-button-wrapper">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'ToolbarWrapper',
|
name: 'ToolbarWrapper',
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
.toolbar-button-wrapper {
|
||||||
|
margin-left: 28px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
.toolbar-button-wrapper {
|
@media only screen and (max-width: 1024px) {
|
||||||
margin-left: 28px;
|
.toolbar-button-wrapper {
|
||||||
display: flex;
|
margin-left: 25px;
|
||||||
align-items: center;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: 1024px) {
|
|
||||||
|
|
||||||
.toolbar-button-wrapper {
|
|
||||||
margin-left: 25px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="toolbar-tools">
|
<div class="toolbar-tools">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'ToolbarWrapper',
|
name: 'ToolbarWrapper',
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "resources/sass/vuefilemanager/_variables";
|
@import 'resources/sass/vuefilemanager/_variables';
|
||||||
@import "resources/sass/vuefilemanager/_mixins";
|
@import 'resources/sass/vuefilemanager/_mixins';
|
||||||
|
|
||||||
.toolbar-tools {
|
.toolbar-tools {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
display: flex;;
|
display: flex;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,71 +1,63 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div v-if="isFullPreview" class="file-preview z-40" ref="filePreview" tabindex="-1" @keydown.esc="closeFilePreview" @keydown.right="next" @keydown.left="prev">
|
||||||
v-if="isFullPreview"
|
<FilePreviewToolbar />
|
||||||
class="file-preview z-40"
|
<FilePreviewMedia />
|
||||||
ref="filePreview"
|
</div>
|
||||||
tabindex="-1"
|
|
||||||
@keydown.esc="closeFilePreview"
|
|
||||||
@keydown.right="next"
|
|
||||||
@keydown.left="prev"
|
|
||||||
>
|
|
||||||
<FilePreviewToolbar />
|
|
||||||
<FilePreviewMedia />
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import FilePreviewToolbar from "./FilePreviewToolbar";
|
import FilePreviewToolbar from './FilePreviewToolbar'
|
||||||
import FilePreviewMedia from "./FilePreviewMedia";
|
import FilePreviewMedia from './FilePreviewMedia'
|
||||||
import {events} from "../../bus";
|
import { events } from '../../bus'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'FilePreview',
|
name: 'FilePreview',
|
||||||
components: {
|
components: {
|
||||||
FilePreviewToolbar,
|
FilePreviewToolbar,
|
||||||
FilePreviewMedia,
|
FilePreviewMedia,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isFullPreview: false
|
isFullPreview: false,
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
closeFilePreview() {
|
|
||||||
this.isFullPreview = false
|
|
||||||
this.$store.commit('FAST_PREVIEW_CLEAR')
|
|
||||||
},
|
|
||||||
next() {
|
|
||||||
events.$emit('file-preview:next')
|
|
||||||
},
|
|
||||||
prev() {
|
|
||||||
events.$emit('file-preview:prev')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
updated() {
|
|
||||||
if (this.isFullPreview) {
|
|
||||||
this.$refs.filePreview.focus()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
events.$on('file-preview:show', () => this.isFullPreview = true)
|
|
||||||
events.$on('file-preview:hide', () => this.closeFilePreview())
|
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
methods: {
|
||||||
|
closeFilePreview() {
|
||||||
|
this.isFullPreview = false
|
||||||
|
this.$store.commit('FAST_PREVIEW_CLEAR')
|
||||||
|
},
|
||||||
|
next() {
|
||||||
|
events.$emit('file-preview:next')
|
||||||
|
},
|
||||||
|
prev() {
|
||||||
|
events.$emit('file-preview:prev')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
updated() {
|
||||||
|
if (this.isFullPreview) {
|
||||||
|
this.$refs.filePreview.focus()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
events.$on('file-preview:show', () => (this.isFullPreview = true))
|
||||||
|
events.$on('file-preview:hide', () => this.closeFilePreview())
|
||||||
|
},
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import '../../../sass/vuefilemanager/variables';
|
@import '../../../sass/vuefilemanager/variables';
|
||||||
|
|
||||||
|
.file-preview {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
position: fixed;
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark {
|
||||||
.file-preview {
|
.file-preview {
|
||||||
width: 100%;
|
background-color: $dark_mode_background;
|
||||||
height: 100%;
|
|
||||||
position: fixed;
|
|
||||||
background-color: white;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
.dark {
|
</style>
|
||||||
.file-preview {
|
|
||||||
background-color: $dark_mode_background;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="currentFile" class="file-preview-wrapper">
|
<div v-if="currentFile" class="file-preview-wrapper">
|
||||||
|
|
||||||
<!--Arrow navigation-->
|
<!--Arrow navigation-->
|
||||||
<div v-if="files.length > 1" class="navigation-arrows">
|
<div v-if="files.length > 1" class="navigation-arrows">
|
||||||
<div @click.prevent="prev" class="prev">
|
<div @click.prevent="prev" class="prev">
|
||||||
@@ -13,31 +12,30 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!--File preview-->
|
<!--File preview-->
|
||||||
<div class="file-wrapper-preview">
|
<div class="file-wrapper-preview">
|
||||||
|
|
||||||
<!--Show PDF-->
|
<!--Show PDF-->
|
||||||
<PdfFile v-if="isPDF" :file="currentFile"/>
|
<PdfFile v-if="isPDF" :file="currentFile" />
|
||||||
|
|
||||||
<!--Show Audio, Video and Image-->
|
<!--Show Audio, Video and Image-->
|
||||||
<div v-if="isAudio || isImage || isVideo" class="file-wrapper">
|
<div v-if="isAudio || isImage || isVideo" class="file-wrapper">
|
||||||
<Audio v-if="isAudio" :file="currentFile"/>
|
<Audio v-if="isAudio" :file="currentFile" />
|
||||||
<Video v-if="isVideo" :file="currentFile"/>
|
<Video v-if="isVideo" :file="currentFile" />
|
||||||
<ImageFile v-if="isImage" :file="currentFile"/>
|
<ImageFile v-if="isImage" :file="currentFile" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {ChevronLeftIcon, ChevronRightIcon} from 'vue-feather-icons'
|
import { ChevronLeftIcon, ChevronRightIcon } from 'vue-feather-icons'
|
||||||
import ToolbarButton from "../FilesView/ToolbarButton";
|
import ToolbarButton from '../FilesView/ToolbarButton'
|
||||||
import ImageFile from "./Media/ImageFile";
|
import ImageFile from './Media/ImageFile'
|
||||||
import PdfFile from "./Media/PdfFile";
|
import PdfFile from './Media/PdfFile'
|
||||||
import Audio from "./Media/Audio";
|
import Audio from './Media/Audio'
|
||||||
import Video from "./Media/Video";
|
import Video from './Media/Video'
|
||||||
import Spinner from "../FilesView/Spinner";
|
import Spinner from '../FilesView/Spinner'
|
||||||
import {mapGetters} from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
import {events} from "../../bus";
|
import { events } from '../../bus'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'FilePreviewMedia',
|
name: 'FilePreviewMedia',
|
||||||
@@ -45,22 +43,16 @@ export default {
|
|||||||
ChevronRightIcon,
|
ChevronRightIcon,
|
||||||
ChevronLeftIcon,
|
ChevronLeftIcon,
|
||||||
ToolbarButton,
|
ToolbarButton,
|
||||||
ImageFile,
|
ImageFile,
|
||||||
PdfFile,
|
PdfFile,
|
||||||
Spinner,
|
Spinner,
|
||||||
Audio,
|
Audio,
|
||||||
Video,
|
Video,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters([
|
...mapGetters(['fastPreview', 'clipboard', 'entries']),
|
||||||
'fastPreview',
|
|
||||||
'clipboard',
|
|
||||||
'entries',
|
|
||||||
]),
|
|
||||||
currentFile() {
|
currentFile() {
|
||||||
return this.fastPreview
|
return this.fastPreview ? this.fastPreview : this.files[Math.abs(this.currentIndex) % this.files.length]
|
||||||
? this.fastPreview
|
|
||||||
: this.files[Math.abs(this.currentIndex) % this.files.length]
|
|
||||||
},
|
},
|
||||||
isPDF() {
|
isPDF() {
|
||||||
return this.currentFile.data.attributes.mimetype === 'pdf'
|
return this.currentFile.data.attributes.mimetype === 'pdf'
|
||||||
@@ -73,7 +65,7 @@ export default {
|
|||||||
},
|
},
|
||||||
isImage() {
|
isImage() {
|
||||||
return this.currentFile.data.type === 'image'
|
return this.currentFile.data.type === 'image'
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -83,8 +75,7 @@ export default {
|
|||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
files() {
|
files() {
|
||||||
if (this.files.length === 0)
|
if (this.files.length === 0) events.$emit('file-preview-wrapper:hide')
|
||||||
events.$emit('file-preview-wrapper:hide')
|
|
||||||
},
|
},
|
||||||
currentFile() {
|
currentFile() {
|
||||||
if (this.clipboard[0]) {
|
if (this.clipboard[0]) {
|
||||||
@@ -111,17 +102,11 @@ export default {
|
|||||||
getFilesForView() {
|
getFilesForView() {
|
||||||
let requestedFile = this.clipboard[0]
|
let requestedFile = this.clipboard[0]
|
||||||
|
|
||||||
this.entries.map(element => {
|
this.entries.map((element) => {
|
||||||
|
|
||||||
if (requestedFile.data.attributes.mimetype === 'pdf') {
|
if (requestedFile.data.attributes.mimetype === 'pdf') {
|
||||||
|
if (element.data.attributes.mimetype === 'pdf') this.files.push(element)
|
||||||
if (element.data.attributes.mimetype === 'pdf')
|
|
||||||
this.files.push(element)
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
if (element.data.type === requestedFile.data.type) this.files.push(element)
|
||||||
if (element.data.type === requestedFile.data.type)
|
|
||||||
this.files.push(element)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -131,31 +116,31 @@ export default {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
next() {
|
next() {
|
||||||
if (!this.files.length > 1) return
|
if (!this.files.length > 1) return
|
||||||
|
|
||||||
this.currentIndex += 1
|
this.currentIndex += 1
|
||||||
|
|
||||||
if (this.currentIndex > this.files.length - 1) {
|
if (this.currentIndex > this.files.length - 1) {
|
||||||
this.currentIndex = 0
|
this.currentIndex = 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
prev() {
|
prev() {
|
||||||
if (!this.files.length > 1) return
|
if (!this.files.length > 1) return
|
||||||
|
|
||||||
this.currentIndex -= 1
|
this.currentIndex -= 1
|
||||||
|
|
||||||
if (this.currentIndex < 0) {
|
if (this.currentIndex < 0) {
|
||||||
this.currentIndex = this.files.length - 1
|
this.currentIndex = this.files.length - 1
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
events.$on('file-preview:next', () => this.next())
|
events.$on('file-preview:next', () => this.next())
|
||||||
events.$on('file-preview:prev', () => this.prev())
|
events.$on('file-preview:prev', () => this.prev())
|
||||||
|
|
||||||
this.getFilesForView()
|
this.getFilesForView()
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -164,8 +149,8 @@ export default {
|
|||||||
@import '../../../sass/vuefilemanager/mixins';
|
@import '../../../sass/vuefilemanager/mixins';
|
||||||
|
|
||||||
.navigation-arrows {
|
.navigation-arrows {
|
||||||
|
.prev,
|
||||||
.prev, .next {
|
.next {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 45%;
|
top: 45%;
|
||||||
@@ -234,17 +219,15 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: 960px) {
|
@media only screen and (max-width: 960px) {
|
||||||
|
|
||||||
.file-preview-wrapper {
|
.file-preview-wrapper {
|
||||||
top: 53px;
|
top: 53px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.dark {
|
.dark {
|
||||||
|
|
||||||
.navigation-arrows {
|
.navigation-arrows {
|
||||||
.prev, .next {
|
.prev,
|
||||||
|
.next {
|
||||||
color: $light-text;
|
color: $light-text;
|
||||||
filter: drop-shadow(0px 1px 0 rgba(17, 19, 20, 1));
|
filter: drop-shadow(0px 1px 0 rgba(17, 19, 20, 1));
|
||||||
}
|
}
|
||||||
@@ -260,4 +243,4 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,173 +1,166 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="navigation-panel" v-if="currentFile">
|
<div class="navigation-panel" v-if="currentFile">
|
||||||
<div class="name-wrapper">
|
<div class="name-wrapper">
|
||||||
|
<!--Close icon-->
|
||||||
|
<span @click="closeFullPreview" class="-m-3 p-3">
|
||||||
|
<x-icon size="17" class="icon-close hover-text-theme" />
|
||||||
|
</span>
|
||||||
|
|
||||||
<!--Close icon-->
|
<!--Item name-->
|
||||||
<span @click="closeFullPreview" class="p-3 -m-3">
|
<div class="name-count-wrapper">
|
||||||
<x-icon size="17" class="icon-close hover-text-theme" />
|
<p class="title">{{ currentFile.data.attributes.name }}</p>
|
||||||
</span>
|
<span v-if="!fastPreview" class="file-count"> ({{ showingImageIndex + ' ' + $t('pronouns.of') + ' ' + files.length }}) </span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!--Item name-->
|
<!--Context menu handler-->
|
||||||
<div class="name-count-wrapper">
|
<PopoverWrapper>
|
||||||
<p class="title">{{ currentFile.data.attributes.name }}</p>
|
<!--Icon-->
|
||||||
<span v-if="! fastPreview" class="file-count"> ({{ showingImageIndex + ' ' + $t('pronouns.of') + ' ' + files.length }}) </span>
|
<span @click.stop="showItemContextMenu" class="-m-3 p-3">
|
||||||
</div>
|
<div class="inline-block rounded-md bg-light-background py-0.5 px-1.5 align-middle transition-all duration-200 dark:bg-dark-foreground lg:bg-transparent">
|
||||||
|
<more-horizontal-icon size="14" />
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
|
||||||
<!--Context menu handler-->
|
<!--Desktop context menu-->
|
||||||
<PopoverWrapper>
|
<PopoverItem name="file-preview-contextmenu" side="right">
|
||||||
|
<OptionGroup>
|
||||||
|
<Option @click.native="$renameFileOrFolder(currentFile)" :title="$t('context_menu.rename')" icon="rename" />
|
||||||
|
<Option @click.native="$moveFileOrFolder(currentFile)" :title="$t('context_menu.move')" icon="move-item" />
|
||||||
|
<Option @click.native="$shareFileOrFolder(currentFile)" :title="sharingTitle" icon="share" v-if="$checkPermission('master')" />
|
||||||
|
<Option @click.native="$deleteFileOrFolder(currentFile)" :title="$t('context_menu.delete')" icon="trash" class="menu-option" />
|
||||||
|
</OptionGroup>
|
||||||
|
<OptionGroup>
|
||||||
|
<Option @click.native="downloadItem" :title="$t('context_menu.download')" icon="download" />
|
||||||
|
</OptionGroup>
|
||||||
|
</PopoverItem>
|
||||||
|
</PopoverWrapper>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!--Icon-->
|
<!--Item metadata-->
|
||||||
<span @click.stop="showItemContextMenu" class="p-3 -m-3">
|
<div class="created-at-wrapper">
|
||||||
<div class="py-0.5 px-1.5 align-middle inline-block rounded-md lg:bg-transparent dark:bg-dark-foreground bg-light-background transition-all duration-200">
|
<p>
|
||||||
<more-horizontal-icon size="14" />
|
{{ currentFile.data.attributes.filesize }},
|
||||||
</div>
|
{{ currentFile.data.attributes.created_at }}
|
||||||
</span>
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!--Desktop context menu-->
|
<!--Icon actions-->
|
||||||
<PopoverItem name="file-preview-contextmenu" side="right">
|
<div class="navigation-icons">
|
||||||
<OptionGroup>
|
<div v-if="isPdf" class="navigation-tool-wrapper">
|
||||||
<Option @click.native="$renameFileOrFolder(currentFile)" :title="$t('context_menu.rename')" icon="rename" />
|
<ToolbarButton @click.native="decreaseSizeOfPDF" source="zoom-out" :action="$t('pdf_zoom_out')" />
|
||||||
<Option @click.native="$moveFileOrFolder(currentFile)" :title="$t('context_menu.move')" icon="move-item" />
|
<ToolbarButton @click.native="increaseSizeOfPDF" source="zoom-in" :action="$t('pdf_zoom_in')" />
|
||||||
<Option @click.native="$shareFileOrFolder(currentFile)" :title="sharingTitle" icon="share" v-if="$checkPermission('master')" />
|
</div>
|
||||||
<Option @click.native="$deleteFileOrFolder(currentFile)" :title="$t('context_menu.delete')" icon="trash" class="menu-option" />
|
<div class="navigation-tool-wrapper">
|
||||||
</OptionGroup>
|
<ToolbarButton @click.native="downloadItem" class="mobile-hide" source="download" :action="$t('actions.download')" />
|
||||||
<OptionGroup>
|
<ToolbarButton
|
||||||
<Option @click.native="downloadItem" :title="$t('context_menu.download')" icon="download" />
|
v-if="canShareItem"
|
||||||
</OptionGroup>
|
@click.native="$shareFileOrFolder(currentFile)"
|
||||||
</PopoverItem>
|
class="mobile-hide"
|
||||||
</PopoverWrapper>
|
:class="{ 'is-inactive': !canShareItem }"
|
||||||
</div>
|
source="share"
|
||||||
|
:action="$t('actions.share')"
|
||||||
<!--Item metadata-->
|
/>
|
||||||
<div class="created-at-wrapper">
|
<ToolbarButton v-if="isImage" @click.native="printMethod()" source="print" :action="$t('actions.print')" />
|
||||||
<p>{{ currentFile.data.attributes.filesize }}, {{ currentFile.data.attributes.created_at }}</p>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<!--Icon actions-->
|
|
||||||
<div class="navigation-icons">
|
|
||||||
<div v-if="isPdf" class="navigation-tool-wrapper">
|
|
||||||
<ToolbarButton @click.native="decreaseSizeOfPDF" source="zoom-out" :action="$t('pdf_zoom_out')" />
|
|
||||||
<ToolbarButton @click.native="increaseSizeOfPDF" source="zoom-in" :action="$t('pdf_zoom_in')" />
|
|
||||||
</div>
|
|
||||||
<div class="navigation-tool-wrapper">
|
|
||||||
<ToolbarButton @click.native="downloadItem" class="mobile-hide" source="download" :action="$t('actions.download')" />
|
|
||||||
<ToolbarButton v-if="canShareItem" @click.native="$shareFileOrFolder(currentFile)" class="mobile-hide" :class="{ 'is-inactive': !canShareItem }" source="share" :action="$t('actions.share')" />
|
|
||||||
<ToolbarButton v-if="isImage" @click.native="printMethod()" source="print" :action="$t('actions.print')" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import PopoverWrapper from "../Desktop/PopoverWrapper";
|
import PopoverWrapper from '../Desktop/PopoverWrapper'
|
||||||
import PopoverItem from "../Desktop/PopoverItem";
|
import PopoverItem from '../Desktop/PopoverItem'
|
||||||
import OptionGroup from "../FilesView/OptionGroup";
|
import OptionGroup from '../FilesView/OptionGroup'
|
||||||
import Option from "../FilesView/Option";
|
import Option from '../FilesView/Option'
|
||||||
|
|
||||||
import ToolbarButton from "../FilesView/ToolbarButton";
|
import ToolbarButton from '../FilesView/ToolbarButton'
|
||||||
import {XIcon, MoreHorizontalIcon} from 'vue-feather-icons'
|
import { XIcon, MoreHorizontalIcon } from 'vue-feather-icons'
|
||||||
import {mapGetters} from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
import {events} from "../../bus";
|
import { events } from '../../bus'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'FilePreviewToolbar',
|
name: 'FilePreviewToolbar',
|
||||||
components: {
|
components: {
|
||||||
MoreHorizontalIcon,
|
MoreHorizontalIcon,
|
||||||
PopoverWrapper,
|
PopoverWrapper,
|
||||||
ToolbarButton,
|
ToolbarButton,
|
||||||
PopoverItem,
|
PopoverItem,
|
||||||
OptionGroup,
|
OptionGroup,
|
||||||
Option,
|
Option,
|
||||||
XIcon,
|
XIcon,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters(['fastPreview', 'clipboard', 'entries']),
|
||||||
|
currentFile() {
|
||||||
|
return this.fastPreview ? this.fastPreview : this.clipboard[0]
|
||||||
},
|
},
|
||||||
computed: {
|
sharingTitle() {
|
||||||
...mapGetters([
|
return this.currentFile.data.relationships.shared ? this.$t('context_menu.share_edit') : this.$t('context_menu.share')
|
||||||
'fastPreview',
|
|
||||||
'clipboard',
|
|
||||||
'entries'
|
|
||||||
]),
|
|
||||||
currentFile() {
|
|
||||||
return this.fastPreview ? this.fastPreview : this.clipboard[0]
|
|
||||||
},
|
|
||||||
sharingTitle() {
|
|
||||||
return this.currentFile.data.relationships.shared
|
|
||||||
? this.$t('context_menu.share_edit')
|
|
||||||
: this.$t('context_menu.share')
|
|
||||||
},
|
|
||||||
isImage() {
|
|
||||||
return this.currentFile.data.type === 'image'
|
|
||||||
},
|
|
||||||
isPdf() {
|
|
||||||
return this.currentFile.data.attributes.mimetype === 'pdf'
|
|
||||||
},
|
|
||||||
files() {
|
|
||||||
let files = []
|
|
||||||
|
|
||||||
this.entries.map(element => {
|
|
||||||
|
|
||||||
if (this.currentFile.data.attributes.mimetype === 'pdf') {
|
|
||||||
|
|
||||||
if (element.data.attributes.mimetype === 'pdf')
|
|
||||||
files.push(element)
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
if (element.data.type === this.currentFile.data.type)
|
|
||||||
files.push(element)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return files
|
|
||||||
},
|
|
||||||
showingImageIndex() {
|
|
||||||
let activeIndex = undefined
|
|
||||||
|
|
||||||
this.files.forEach((element, index) => {
|
|
||||||
if (element.data.id === this.currentFile.data.id) {
|
|
||||||
activeIndex = index + 1
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return activeIndex
|
|
||||||
},
|
|
||||||
canShareItem() {
|
|
||||||
return this.$isThisRoute(this.$route, ['Files', 'RecentUploads', 'MySharedItems'])
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
methods: {
|
isImage() {
|
||||||
showItemContextMenu() {
|
return this.currentFile.data.type === 'image'
|
||||||
if (this.$isMobile()) {
|
},
|
||||||
events.$emit('mobile-context-menu:show', this.currentFile)
|
isPdf() {
|
||||||
this.$showMobileMenu('file-menu')
|
return this.currentFile.data.attributes.mimetype === 'pdf'
|
||||||
} else {
|
},
|
||||||
events.$emit('popover:open', 'file-preview-contextmenu')
|
files() {
|
||||||
}
|
let files = []
|
||||||
},
|
|
||||||
increaseSizeOfPDF() {
|
|
||||||
events.$emit('document-zoom:in')
|
|
||||||
},
|
|
||||||
decreaseSizeOfPDF() {
|
|
||||||
events.$emit('document-zoom:out')
|
|
||||||
},
|
|
||||||
printMethod() {
|
|
||||||
let tab = document.getElementById('printable-file')
|
|
||||||
let win = window.open('', '', 'height=700,width=700')
|
|
||||||
|
|
||||||
win.document.write(tab.outerHTML)
|
this.entries.map((element) => {
|
||||||
win.document.close()
|
if (this.currentFile.data.attributes.mimetype === 'pdf') {
|
||||||
win.print()
|
if (element.data.attributes.mimetype === 'pdf') files.push(element)
|
||||||
},
|
} else {
|
||||||
downloadItem() {
|
if (element.data.type === this.currentFile.data.type) files.push(element)
|
||||||
this.$downloadFile(
|
}
|
||||||
this.currentFile.data.attributes.file_url,
|
})
|
||||||
this.currentFile.data.attributes.name + '.' + this.currentFile.data.attributes.mimetype
|
|
||||||
)
|
return files
|
||||||
},
|
},
|
||||||
closeFullPreview() {
|
showingImageIndex() {
|
||||||
events.$emit('file-preview:hide')
|
let activeIndex = undefined
|
||||||
|
|
||||||
|
this.files.forEach((element, index) => {
|
||||||
|
if (element.data.id === this.currentFile.data.id) {
|
||||||
|
activeIndex = index + 1
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return activeIndex
|
||||||
|
},
|
||||||
|
canShareItem() {
|
||||||
|
return this.$isThisRoute(this.$route, ['Files', 'RecentUploads', 'MySharedItems'])
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
showItemContextMenu() {
|
||||||
|
if (this.$isMobile()) {
|
||||||
|
events.$emit('mobile-context-menu:show', this.currentFile)
|
||||||
|
this.$showMobileMenu('file-menu')
|
||||||
|
} else {
|
||||||
|
events.$emit('popover:open', 'file-preview-contextmenu')
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
increaseSizeOfPDF() {
|
||||||
|
events.$emit('document-zoom:in')
|
||||||
|
},
|
||||||
|
decreaseSizeOfPDF() {
|
||||||
|
events.$emit('document-zoom:out')
|
||||||
|
},
|
||||||
|
printMethod() {
|
||||||
|
let tab = document.getElementById('printable-file')
|
||||||
|
let win = window.open('', '', 'height=700,width=700')
|
||||||
|
|
||||||
|
win.document.write(tab.outerHTML)
|
||||||
|
win.document.close()
|
||||||
|
win.print()
|
||||||
|
},
|
||||||
|
downloadItem() {
|
||||||
|
this.$downloadFile(this.currentFile.data.attributes.file_url, this.currentFile.data.attributes.name + '.' + this.currentFile.data.attributes.mimetype)
|
||||||
|
},
|
||||||
|
closeFullPreview() {
|
||||||
|
events.$emit('file-preview:hide')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@@ -300,9 +293,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 960px) {
|
@media (max-width: 960px) {
|
||||||
|
|
||||||
.context-menu {
|
.context-menu {
|
||||||
|
|
||||||
.name-wrapper {
|
.name-wrapper {
|
||||||
width: 67%;
|
width: 67%;
|
||||||
}
|
}
|
||||||
@@ -355,4 +346,4 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,17 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<audio
|
<audio :class="{ 'file-shadow': !$isMobile() }" class="file audio" :src="file.data.attributes.file_url" controls></audio>
|
||||||
:class="{'file-shadow': ! $isMobile() }"
|
|
||||||
class="file audio"
|
|
||||||
:src="file.data.attributes.file_url"
|
|
||||||
controls>
|
|
||||||
</audio>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'Audio',
|
name: 'Audio',
|
||||||
props: [
|
props: ['file'],
|
||||||
'file'
|
}
|
||||||
],
|
</script>
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|||||||
@@ -1,27 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
<img
|
<img id="printable-file" class="file" :class="{ 'file-shadow': !$isMobile() }" :src="imageSource" />
|
||||||
id="printable-file"
|
|
||||||
class="file"
|
|
||||||
:class="{'file-shadow': ! $isMobile() }"
|
|
||||||
:src="imageSource"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'ImageFile',
|
name: 'ImageFile',
|
||||||
props: [
|
props: ['file'],
|
||||||
'file'
|
computed: {
|
||||||
],
|
imageSource() {
|
||||||
computed: {
|
let windowWidth = window.innerWidth
|
||||||
imageSource() {
|
|
||||||
let windowWidth = window.innerWidth
|
|
||||||
|
|
||||||
if (windowWidth > 1280)
|
if (windowWidth > 1280) return this.file.data.attributes.thumbnail.xl
|
||||||
return this.file.data.attributes.thumbnail.xl
|
else return this.file.data.attributes.thumbnail.lg
|
||||||
else
|
},
|
||||||
return this.file.data.attributes.thumbnail.lg
|
},
|
||||||
}
|
}
|
||||||
}
|
</script>
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|||||||
@@ -1,116 +1,112 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="pdf-wrapper" :style="{width: documentSize + '%'}">
|
<div id="pdf-wrapper" :style="{ width: documentSize + '%' }">
|
||||||
<!-- <pdf :src="pdfData" v-for="i in numPages" :key="i" :resize="true" :page="i" scale="page-width" style="width:100%; margin:0 auto 35px;" id="printable-file" class="pdf-file">
|
<!-- <pdf :src="pdfData" v-for="i in numPages" :key="i" :resize="true" :page="i" scale="page-width" style="width:100%; margin:0 auto 35px;" id="printable-file" class="pdf-file">
|
||||||
<template slot="loading">
|
<template slot="loading">
|
||||||
<h1>loading content...</h1>
|
<h1>loading content...</h1>
|
||||||
</template>
|
</template>
|
||||||
</pdf>-->
|
</pdf>-->
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
//todo: resolve pdf
|
//todo: resolve pdf
|
||||||
|
|
||||||
import {events} from "../../../bus";
|
import { events } from '../../../bus'
|
||||||
//import pdf from 'pdfvuer'
|
//import pdf from 'pdfvuer'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'PdfFile',
|
name: 'PdfFile',
|
||||||
components: {
|
components: {
|
||||||
//pdf,
|
//pdf,
|
||||||
},
|
},
|
||||||
props: [
|
props: ['file'],
|
||||||
'file'
|
watch: {
|
||||||
],
|
file() {
|
||||||
watch: {
|
this.getPdf()
|
||||||
file() {
|
},
|
||||||
this.getPdf()
|
},
|
||||||
}
|
data() {
|
||||||
},
|
return {
|
||||||
data() {
|
pdfData: undefined,
|
||||||
return {
|
numPages: 0,
|
||||||
pdfData: undefined,
|
documentSize: 50,
|
||||||
numPages: 0,
|
}
|
||||||
documentSize: 50,
|
},
|
||||||
}
|
methods: {
|
||||||
},
|
getPdf() {
|
||||||
methods: {
|
this.pdfData = undefined
|
||||||
getPdf() {
|
this.numPages = 0
|
||||||
this.pdfData = undefined
|
|
||||||
this.numPages = 0
|
|
||||||
|
|
||||||
let self = this;
|
let self = this
|
||||||
|
|
||||||
//self.pdfData = pdf.createLoadingTask(this.file.data.attributes.file_url);
|
//self.pdfData = pdf.createLoadingTask(this.file.data.attributes.file_url);
|
||||||
|
|
||||||
//self.pdfData.then(pdf => self.numPages = pdf.numPages);
|
//self.pdfData.then(pdf => self.numPages = pdf.numPages);
|
||||||
},
|
},
|
||||||
getDocumentSize() {
|
getDocumentSize() {
|
||||||
if (window.innerWidth < 960) {
|
if (window.innerWidth < 960) {
|
||||||
this.documentSize = 100
|
this.documentSize = 100
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window.innerWidth > 960){
|
if (window.innerWidth > 960) {
|
||||||
this.documentSize = localStorage.getItem('documentSize')
|
this.documentSize = localStorage.getItem('documentSize') ? parseInt(localStorage.getItem('documentSize')) : 50
|
||||||
? parseInt(localStorage.getItem('documentSize'))
|
}
|
||||||
: 50;
|
},
|
||||||
}
|
zoomIn() {
|
||||||
},
|
if (this.documentSize < 100) {
|
||||||
zoomIn() {
|
this.documentSize += 10
|
||||||
if (this.documentSize < 100) {
|
localStorage.setItem('documentSize', this.documentSize)
|
||||||
this.documentSize += 10
|
}
|
||||||
localStorage.setItem('documentSize', this.documentSize)
|
},
|
||||||
}
|
zoomOut() {
|
||||||
},
|
if (this.documentSize > 40) {
|
||||||
zoomOut() {
|
this.documentSize -= 10
|
||||||
if (this.documentSize > 40) {
|
localStorage.setItem('documentSize', this.documentSize)
|
||||||
this.documentSize -= 10
|
}
|
||||||
localStorage.setItem('documentSize', this.documentSize)
|
},
|
||||||
}
|
},
|
||||||
}
|
created() {
|
||||||
},
|
this.getDocumentSize()
|
||||||
created() {
|
this.getPdf()
|
||||||
this.getDocumentSize()
|
|
||||||
this.getPdf()
|
|
||||||
|
|
||||||
events.$on('document-zoom:in', () => this.zoomIn())
|
events.$on('document-zoom:in', () => this.zoomIn())
|
||||||
events.$on('document-zoom:out', () => this.zoomOut())
|
events.$on('document-zoom:out', () => this.zoomOut())
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!--<style src="pdfvuer/dist/pdfvuer.css" lang="css"></style>-->
|
<!--<style src="pdfvuer/dist/pdfvuer.css" lang="css"></style>-->
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import '../../../../sass/vuefilemanager/variables';
|
@import '../../../../sass/vuefilemanager/variables';
|
||||||
|
|
||||||
#pdf-wrapper {
|
#pdf-wrapper {
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
padding: 40px;
|
padding: 40px;
|
||||||
|
|
||||||
.pdf-file {
|
.pdf-file {
|
||||||
box-shadow: $light_mode_popup_shadow;
|
box-shadow: $light_mode_popup_shadow;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: 960px) {
|
@media only screen and (max-width: 960px) {
|
||||||
#pdf-wrapper {
|
#pdf-wrapper {
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|
||||||
.pdf-file {
|
.pdf-file {
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,60 +1,58 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="video-wrapper">
|
<div class="video-wrapper">
|
||||||
<video
|
<video
|
||||||
:src="file.data.attributes.file_url"
|
:src="file.data.attributes.file_url"
|
||||||
class="video"
|
class="video"
|
||||||
:class="{'file-shadow': !$isMobile() }"
|
:class="{ 'file-shadow': !$isMobile() }"
|
||||||
controlsList="nodownload"
|
controlsList="nodownload"
|
||||||
disablePictureInPicture
|
disablePictureInPicture
|
||||||
playsinline
|
playsinline
|
||||||
controls
|
controls
|
||||||
autoplay
|
autoplay
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'Video',
|
name: 'Video',
|
||||||
props: [
|
props: ['file'],
|
||||||
'file'
|
}
|
||||||
],
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import '../../../../sass/vuefilemanager/variables';
|
@import '../../../../sass/vuefilemanager/variables';
|
||||||
|
|
||||||
.video-wrapper {
|
.video-wrapper {
|
||||||
max-width: 1080px;
|
max-width: 1080px;
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
|
|
||||||
@media (min-width: 1200px) {
|
@media (min-width: 1200px) {
|
||||||
& {
|
& {
|
||||||
max-width: 800px;
|
max-width: 800px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 1920px) and (max-width: 2560px) {
|
@media (min-width: 1920px) and (max-width: 2560px) {
|
||||||
& {
|
& {
|
||||||
max-width: 1080px;
|
max-width: 1080px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@media (min-width: 2560px) and (max-width: 3840px) {
|
@media (min-width: 2560px) and (max-width: 3840px) {
|
||||||
& {
|
& {
|
||||||
max-width: 1440px;
|
max-width: 1440px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@media (min-width: 3840px) {
|
@media (min-width: 3840px) {
|
||||||
& {
|
& {
|
||||||
max-width: 2160px;
|
max-width: 2160px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.video {
|
.video {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
align-self: center;
|
align-self: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -10,12 +10,7 @@
|
|||||||
<p v-if="message" class="message">{{ message }}</p>
|
<p v-if="message" class="message">{{ message }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="popup-actions">
|
<div class="popup-actions">
|
||||||
<ButtonBase
|
<ButtonBase @click.native="closePopup" :button-style="buttonStyle" class="action-confirm">{{ button }} </ButtonBase>
|
||||||
@click.native="closePopup"
|
|
||||||
:button-style="buttonStyle"
|
|
||||||
class="action-confirm"
|
|
||||||
>{{ button }}
|
|
||||||
</ButtonBase>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -23,182 +18,181 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ButtonBase from "./ButtonBase";
|
import ButtonBase from './ButtonBase'
|
||||||
import {events} from "../../bus";
|
import { events } from '../../bus'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'AlertPopup',
|
name: 'AlertPopup',
|
||||||
components: {
|
components: {
|
||||||
ButtonBase
|
ButtonBase,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isVisibleWrapper: false,
|
isVisibleWrapper: false,
|
||||||
buttonStyle: undefined,
|
buttonStyle: undefined,
|
||||||
message: undefined,
|
message: undefined,
|
||||||
title: undefined,
|
title: undefined,
|
||||||
button: undefined,
|
button: undefined,
|
||||||
emoji: undefined,
|
emoji: undefined,
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
closePopup() {
|
|
||||||
events.$emit('popup:close')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
// Show alert
|
|
||||||
events.$on('alert:open', args => {
|
|
||||||
this.isVisibleWrapper = true
|
|
||||||
|
|
||||||
this.title = args.title
|
|
||||||
this.message = args.message
|
|
||||||
|
|
||||||
this.button = this.$t('alerts.error_confirm')
|
|
||||||
this.emoji = '😢😢😢'
|
|
||||||
this.buttonStyle = 'danger-solid'
|
|
||||||
|
|
||||||
if (args.emoji) {
|
|
||||||
this.emoji = args.emoji
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.buttonStyle) {
|
|
||||||
this.buttonStyle = args.buttonStyle
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.button) {
|
|
||||||
this.button = args.button
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// Show alert
|
|
||||||
events.$on('success:open', args => {
|
|
||||||
this.isVisibleWrapper = true
|
|
||||||
|
|
||||||
this.title = args.title
|
|
||||||
this.message = args.message
|
|
||||||
|
|
||||||
this.button = this.$t('alerts.success_confirm')
|
|
||||||
this.emoji = '🥳🥳🥳'
|
|
||||||
this.buttonStyle = 'theme'
|
|
||||||
|
|
||||||
if (args.emoji) {
|
|
||||||
this.emoji = args.emoji
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// Close popup
|
|
||||||
events.$on('popup:close', () => {
|
|
||||||
this.isVisibleWrapper = false
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
methods: {
|
||||||
|
closePopup() {
|
||||||
|
events.$emit('popup:close')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
// Show alert
|
||||||
|
events.$on('alert:open', (args) => {
|
||||||
|
this.isVisibleWrapper = true
|
||||||
|
|
||||||
|
this.title = args.title
|
||||||
|
this.message = args.message
|
||||||
|
|
||||||
|
this.button = this.$t('alerts.error_confirm')
|
||||||
|
this.emoji = '😢😢😢'
|
||||||
|
this.buttonStyle = 'danger-solid'
|
||||||
|
|
||||||
|
if (args.emoji) {
|
||||||
|
this.emoji = args.emoji
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.buttonStyle) {
|
||||||
|
this.buttonStyle = args.buttonStyle
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.button) {
|
||||||
|
this.button = args.button
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// Show alert
|
||||||
|
events.$on('success:open', (args) => {
|
||||||
|
this.isVisibleWrapper = true
|
||||||
|
|
||||||
|
this.title = args.title
|
||||||
|
this.message = args.message
|
||||||
|
|
||||||
|
this.button = this.$t('alerts.success_confirm')
|
||||||
|
this.emoji = '🥳🥳🥳'
|
||||||
|
this.buttonStyle = 'theme'
|
||||||
|
|
||||||
|
if (args.emoji) {
|
||||||
|
this.emoji = args.emoji
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// Close popup
|
||||||
|
events.$on('popup:close', () => {
|
||||||
|
this.isVisibleWrapper = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import '../../../sass/vuefilemanager/variables';
|
@import '../../../sass/vuefilemanager/variables';
|
||||||
@import '../../../sass/vuefilemanager/mixins';
|
@import '../../../sass/vuefilemanager/mixins';
|
||||||
|
|
||||||
.popup {
|
.popup {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
z-index: 45;
|
z-index: 45;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup-wrapper {
|
||||||
|
z-index: 12;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
max-width: 480px;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%) scale(1);
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 20px;
|
||||||
|
box-shadow: $light_mode_popup_shadow;
|
||||||
|
border-radius: 8px;
|
||||||
|
text-align: center;
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup-image {
|
||||||
|
margin-bottom: 30px;
|
||||||
|
|
||||||
|
.emoji {
|
||||||
|
@include font-size(56);
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup-content {
|
||||||
|
.title {
|
||||||
|
@include font-size(22);
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-weight: 800;
|
||||||
|
color: $text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.message {
|
||||||
|
@include font-size(16);
|
||||||
|
color: #333;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup-actions {
|
||||||
|
margin-top: 30px;
|
||||||
|
|
||||||
|
.action-confirm {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 690px) {
|
||||||
.popup-wrapper {
|
.popup-wrapper {
|
||||||
z-index: 12;
|
padding: 40px 20px 20px;
|
||||||
position: absolute;
|
left: 15px;
|
||||||
left: 0;
|
right: 15px;
|
||||||
right: 0;
|
|
||||||
max-width: 480px;
|
|
||||||
top: 50%;
|
|
||||||
transform: translateY(-50%) scale(1);
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 20px;
|
|
||||||
box-shadow: $light_mode_popup_shadow;
|
|
||||||
border-radius: 8px;
|
|
||||||
text-align: center;
|
|
||||||
background: white;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.popup-image {
|
.dark {
|
||||||
margin-bottom: 30px;
|
.popup-wrapper {
|
||||||
|
background: $dark_mode_foreground;
|
||||||
.emoji {
|
|
||||||
@include font-size(56);
|
|
||||||
line-height: 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.popup-content {
|
.popup-content {
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
@include font-size(22);
|
color: $dark_mode_text_primary;
|
||||||
text-transform: uppercase;
|
|
||||||
font-weight: 800;
|
|
||||||
color: $text;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.message {
|
.message {
|
||||||
@include font-size(16);
|
color: $dark_mode_text_secondary;
|
||||||
color: #333;
|
|
||||||
margin-top: 5px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.popup-actions {
|
// Animations
|
||||||
margin-top: 30px;
|
.popup-enter-active {
|
||||||
|
animation: popup-in 0.35s 0.15s ease both;
|
||||||
|
}
|
||||||
|
|
||||||
.action-confirm {
|
.popup-leave-active {
|
||||||
width: 100%;
|
animation: popup-in 0.15s ease reverse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes popup-in {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(0.7);
|
||||||
}
|
}
|
||||||
|
100% {
|
||||||
@media only screen and (max-width: 690px) {
|
opacity: 1;
|
||||||
.popup-wrapper {
|
transform: scale(1);
|
||||||
padding: 40px 20px 20px;
|
|
||||||
left: 15px;
|
|
||||||
right: 15px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark {
|
|
||||||
.popup-wrapper {
|
|
||||||
background: $dark_mode_foreground;
|
|
||||||
}
|
|
||||||
.popup-content {
|
|
||||||
.title {
|
|
||||||
color: $dark_mode_text_primary;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message {
|
|
||||||
color: $dark_mode_text_secondary;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Animations
|
|
||||||
.popup-enter-active {
|
|
||||||
animation: popup-in 0.35s 0.15s ease both;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popup-leave-active {
|
|
||||||
animation: popup-in 0.15s ease reverse;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes popup-in {
|
|
||||||
0% {
|
|
||||||
opacity: 0;
|
|
||||||
transform: scale(0.7);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
opacity: 1;
|
|
||||||
transform: scale(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -2,129 +2,130 @@
|
|||||||
<button class="button-base" :class="buttonStyle" type="button">
|
<button class="button-base" :class="buttonStyle" type="button">
|
||||||
<div v-if="loading" class="icon">
|
<div v-if="loading" class="icon">
|
||||||
<refresh-cw-icon size="16" class="sync-alt" />
|
<refresh-cw-icon size="16" class="sync-alt" />
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<slot v-if="! loading"></slot>
|
<slot v-if="!loading"></slot>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { RefreshCwIcon } from 'vue-feather-icons'
|
import { RefreshCwIcon } from 'vue-feather-icons'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ButtonBase',
|
name: 'ButtonBase',
|
||||||
props: ['buttonStyle', 'loading'],
|
props: ['buttonStyle', 'loading'],
|
||||||
components: {
|
components: {
|
||||||
RefreshCwIcon,
|
RefreshCwIcon,
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import '../../../sass/vuefilemanager/variables';
|
@import '../../../sass/vuefilemanager/variables';
|
||||||
@import '../../../sass/vuefilemanager/mixins';
|
@import '../../../sass/vuefilemanager/mixins';
|
||||||
|
|
||||||
|
.button-base {
|
||||||
|
@include font-size(15);
|
||||||
|
font-weight: 700;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: 0.15s all ease;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 0;
|
||||||
|
padding: 10px 28px;
|
||||||
|
white-space: nowrap;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
line-height: 1;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
transform: scale(0.95);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.theme-solid {
|
||||||
|
.content {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.danger {
|
||||||
|
background: rgba($danger, 0.1);
|
||||||
|
|
||||||
|
.content {
|
||||||
|
color: $danger;
|
||||||
|
}
|
||||||
|
|
||||||
|
polyline,
|
||||||
|
path {
|
||||||
|
stroke: $danger;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.danger-solid {
|
||||||
|
background: $danger;
|
||||||
|
|
||||||
|
.content {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
polyline,
|
||||||
|
path {
|
||||||
|
stroke: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.secondary {
|
||||||
|
background: $light_background;
|
||||||
|
|
||||||
|
.content {
|
||||||
|
color: $text;
|
||||||
|
}
|
||||||
|
|
||||||
|
polyline,
|
||||||
|
path {
|
||||||
|
stroke: $text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.sync-alt {
|
||||||
|
animation: spin 1s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
0% {
|
||||||
|
transform: rotate(0);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark {
|
||||||
.button-base {
|
.button-base {
|
||||||
@include font-size(15);
|
|
||||||
font-weight: 700;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: 0.15s all ease;
|
|
||||||
border-radius: 8px;
|
|
||||||
border: 0;
|
|
||||||
padding: 10px 28px;
|
|
||||||
white-space: nowrap;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
line-height: 1;
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
transform: scale(0.95);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.theme-solid {
|
|
||||||
|
|
||||||
.content {
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.danger {
|
|
||||||
background: rgba($danger, .1);
|
|
||||||
|
|
||||||
.content {
|
|
||||||
color: $danger;
|
|
||||||
}
|
|
||||||
|
|
||||||
polyline, path {
|
|
||||||
stroke: $danger;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.danger-solid {
|
|
||||||
background: $danger;
|
|
||||||
|
|
||||||
.content {
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
polyline, path {
|
|
||||||
stroke: white;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.secondary {
|
&.secondary {
|
||||||
background: $light_background;
|
background: $dark_mode_foreground;
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
color: $text;
|
color: $dark_mode_text_primary;
|
||||||
}
|
}
|
||||||
|
|
||||||
polyline, path {
|
polyline,
|
||||||
stroke: $text;
|
path {
|
||||||
|
color: inherit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.sync-alt {
|
.popup-wrapper {
|
||||||
animation: spin 1s linear infinite;
|
.button-base.secondary {
|
||||||
}
|
background: lighten($dark_mode_foreground, 3%);
|
||||||
|
|
||||||
@keyframes spin {
|
|
||||||
0% {
|
|
||||||
transform: rotate(0);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark {
|
|
||||||
|
|
||||||
.button-base {
|
|
||||||
|
|
||||||
&.secondary {
|
|
||||||
background: $dark_mode_foreground;
|
|
||||||
|
|
||||||
.content {
|
|
||||||
color: $dark_mode_text_primary;
|
|
||||||
}
|
|
||||||
|
|
||||||
polyline, path {
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.popup-wrapper {
|
|
||||||
.button-base.secondary {
|
|
||||||
background: lighten($dark_mode_foreground, 3%);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,56 +1,48 @@
|
|||||||
<template>
|
<template>
|
||||||
<label :class="buttonStyle" label="file" class="button file-input button-base">
|
<label :class="buttonStyle" label="file" class="button file-input button-base">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
<input
|
<input accept="*" v-show="false" @change="emmitFiles" id="file" type="file" name="files[]" multiple />
|
||||||
accept="*"
|
|
||||||
v-show="false"
|
|
||||||
@change="emmitFiles"
|
|
||||||
id="file"
|
|
||||||
type="file"
|
|
||||||
name="files[]"
|
|
||||||
multiple
|
|
||||||
/>
|
|
||||||
</label>
|
</label>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'ButtonBase',
|
name: 'ButtonBase',
|
||||||
props: ['buttonStyle'],
|
props: ['buttonStyle'],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
files: undefined
|
files: undefined,
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
emmitFiles(e) {
|
|
||||||
this.$uploadFiles(e.target.files)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
methods: {
|
||||||
|
emmitFiles(e) {
|
||||||
|
this.$uploadFiles(e.target.files)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import '../../../sass/vuefilemanager/variables';
|
@import '../../../sass/vuefilemanager/variables';
|
||||||
@import '../../../sass/vuefilemanager/mixins';
|
@import '../../../sass/vuefilemanager/mixins';
|
||||||
|
|
||||||
.button-base {
|
.button-base {
|
||||||
@include font-size(15);
|
@include font-size(15);
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: 0.15s all ease;
|
transition: 0.15s all ease;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
border: 0;
|
border: 0;
|
||||||
padding: 10px 28px;
|
padding: 10px 28px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
|
||||||
&:active {
|
&:active {
|
||||||
transform: scale(0.95);
|
transform: scale(0.95);
|
||||||
}
|
|
||||||
|
|
||||||
&.secondary {
|
|
||||||
color: $text;
|
|
||||||
background: $light_background;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.secondary {
|
||||||
|
color: $text;
|
||||||
|
background: $light_background;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,39 +1,40 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="w-5 h-5 flex items-center justify-center rounded-md"
|
class="flex h-5 w-5 items-center justify-center rounded-md"
|
||||||
:class="{'bg-theme': isClicked, 'dark:bg-dark-foreground bg-light-background': !isClicked}"
|
:class="{
|
||||||
@click="changeState"
|
'bg-theme': isClicked,
|
||||||
>
|
'bg-light-background dark:bg-dark-foreground': !isClicked,
|
||||||
<CheckIcon v-if="isClicked" class="vue-feather text-white" size="17" />
|
}"
|
||||||
</div>
|
@click="changeState"
|
||||||
</div>
|
>
|
||||||
|
<CheckIcon v-if="isClicked" class="vue-feather text-white" size="17" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {CheckIcon} from 'vue-feather-icons'
|
import { CheckIcon } from 'vue-feather-icons'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'CheckBox',
|
name: 'CheckBox',
|
||||||
props: [
|
props: ['isClicked'],
|
||||||
'isClicked'
|
components: {
|
||||||
],
|
CheckIcon,
|
||||||
components: {
|
},
|
||||||
CheckIcon
|
data() {
|
||||||
},
|
return {
|
||||||
data() {
|
isSwitched: undefined,
|
||||||
return {
|
}
|
||||||
isSwitched: undefined
|
},
|
||||||
}
|
methods: {
|
||||||
},
|
changeState() {
|
||||||
methods: {
|
this.isSwitched = !this.isSwitched
|
||||||
changeState() {
|
this.$emit('input', this.isSwitched)
|
||||||
this.isSwitched = ! this.isSwitched
|
},
|
||||||
this.$emit('input', this.isSwitched)
|
},
|
||||||
}
|
mounted() {
|
||||||
},
|
this.isSwitched = this.isClicked
|
||||||
mounted() {
|
},
|
||||||
this.isSwitched = this.isClicked
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,116 +1,110 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
v-show="isVisible"
|
v-show="isVisible"
|
||||||
:style="{top: positionY + 'px', left: positionX + 'px'}"
|
:style="{ top: positionY + 'px', left: positionX + 'px' }"
|
||||||
@click="closeAndResetContextMenu"
|
@click="closeAndResetContextMenu"
|
||||||
class="absolute w-60 shadow-lg rounded-xl z-20 dark:bg-2x-dark-foreground bg-white overflow-hidden"
|
class="absolute z-20 w-60 overflow-hidden rounded-xl bg-white shadow-lg dark:bg-2x-dark-foreground"
|
||||||
ref="contextmenu"
|
ref="contextmenu"
|
||||||
>
|
>
|
||||||
<div id="menu-list" class="w-full">
|
<div id="menu-list" class="w-full">
|
||||||
|
<!--Show empty select contextmenu-->
|
||||||
|
<slot name="empty-select" v-if="!item" />
|
||||||
|
|
||||||
<!--Show empty select contextmenu-->
|
<!--Show single select contextmenu-->
|
||||||
<slot name="empty-select" v-if="! item" />
|
<slot name="single-select" v-if="isMultiSelectContextMenu" />
|
||||||
|
|
||||||
<!--Show single select contextmenu-->
|
<!--Show multiple select contextmenu-->
|
||||||
<slot name="single-select" v-if="isMultiSelectContextMenu" />
|
<slot name="multiple-select" v-if="!isMultiSelectContextMenu" />
|
||||||
|
|
||||||
<!--Show multiple select contextmenu-->
|
|
||||||
<slot name="multiple-select" v-if="! isMultiSelectContextMenu" />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {events} from "../../bus";
|
import { events } from '../../bus'
|
||||||
import {mapGetters} from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ContextMenu',
|
name: 'ContextMenu',
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters([
|
...mapGetters(['clipboard', 'user']),
|
||||||
'clipboard',
|
isMultiSelectContextMenu() {
|
||||||
'user',
|
// If is context Menu open on multi selected items open just options for the multi selected items
|
||||||
]),
|
if (this.clipboard.length > 1 && this.clipboard.includes(this.item)) return false
|
||||||
isMultiSelectContextMenu() {
|
|
||||||
// If is context Menu open on multi selected items open just options for the multi selected items
|
|
||||||
if (this.clipboard.length > 1 && this.clipboard.includes(this.item))
|
|
||||||
return false
|
|
||||||
|
|
||||||
// If is context Menu open for the non selected item open options for the single item
|
// If is context Menu open for the non selected item open options for the single item
|
||||||
if (this.clipboard.length < 2 || !this.clipboard.includes(this.item))
|
if (this.clipboard.length < 2 || !this.clipboard.includes(this.item)) return true
|
||||||
return true
|
},
|
||||||
},
|
},
|
||||||
},
|
data() {
|
||||||
data() {
|
return {
|
||||||
return {
|
item: undefined,
|
||||||
item: undefined,
|
isVisible: false,
|
||||||
isVisible: false,
|
positionX: 0,
|
||||||
positionX: 0,
|
positionY: 0,
|
||||||
positionY: 0
|
}
|
||||||
}
|
},
|
||||||
},
|
methods: {
|
||||||
methods: {
|
closeAndResetContextMenu() {
|
||||||
closeAndResetContextMenu() {
|
// Close context menu
|
||||||
// Close context menu
|
this.isVisible = false
|
||||||
this.isVisible = false
|
|
||||||
|
|
||||||
// Reset item container
|
// Reset item container
|
||||||
this.item = undefined
|
this.item = undefined
|
||||||
},
|
},
|
||||||
showContextMenu(event) {
|
showContextMenu(event) {
|
||||||
let parent = document.getElementById('menu-list')
|
let parent = document.getElementById('menu-list')
|
||||||
let nodesSameClass = parent.getElementsByClassName('menu-option')
|
let nodesSameClass = parent.getElementsByClassName('menu-option')
|
||||||
|
|
||||||
let VerticalOffsetArea = nodesSameClass.length * 50
|
let VerticalOffsetArea = nodesSameClass.length * 50
|
||||||
let HorizontalOffsetArea = 190
|
let HorizontalOffsetArea = 190
|
||||||
|
|
||||||
let container = document.getElementById('file-view')
|
let container = document.getElementById('file-view')
|
||||||
|
|
||||||
let offset = container.getClientRects()[0]
|
let offset = container.getClientRects()[0]
|
||||||
|
|
||||||
let x = event.clientX - offset.left
|
let x = event.clientX - offset.left
|
||||||
let y = event.clientY - offset.top
|
let y = event.clientY - offset.top
|
||||||
|
|
||||||
// Set position Y
|
// Set position Y
|
||||||
if (container.offsetHeight - y < VerticalOffsetArea) {
|
if (container.offsetHeight - y < VerticalOffsetArea) {
|
||||||
this.positionY = y - VerticalOffsetArea
|
this.positionY = y - VerticalOffsetArea
|
||||||
} else {
|
} else {
|
||||||
this.positionY = y
|
this.positionY = y
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set position X
|
// Set position X
|
||||||
if (container.offsetWidth - x < HorizontalOffsetArea) {
|
if (container.offsetWidth - x < HorizontalOffsetArea) {
|
||||||
this.positionX = x - HorizontalOffsetArea
|
this.positionX = x - HorizontalOffsetArea
|
||||||
} else {
|
} else {
|
||||||
this.positionX = x
|
this.positionX = x
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show context menu
|
// Show context menu
|
||||||
this.isVisible = true
|
this.isVisible = true
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
events.$on('context-menu:hide', () => this.closeAndResetContextMenu())
|
events.$on('context-menu:hide', () => this.closeAndResetContextMenu())
|
||||||
|
|
||||||
events.$on('context-menu:show', (event, item) => {
|
events.$on('context-menu:show', (event, item) => {
|
||||||
// Store item
|
// Store item
|
||||||
this.item = item
|
this.item = item
|
||||||
|
|
||||||
// Show context menu
|
// Show context menu
|
||||||
setTimeout(() => this.showContextMenu(event, item), 10)
|
setTimeout(() => this.showContextMenu(event, item), 10)
|
||||||
})
|
})
|
||||||
|
|
||||||
events.$on('context-menu:current-folder', folder => {
|
events.$on('context-menu:current-folder', (folder) => {
|
||||||
this.item = folder
|
this.item = folder
|
||||||
|
|
||||||
this.isVisible = ! this.isVisible
|
this.isVisible = !this.isVisible
|
||||||
|
|
||||||
if (this.isVisible) {
|
if (this.isVisible) {
|
||||||
let container = document.getElementById('folder-actions')
|
let container = document.getElementById('folder-actions')
|
||||||
|
|
||||||
this.positionX = container.offsetLeft
|
this.positionX = container.offsetLeft
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,380 +1,399 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="desktop-toolbar" class="lg:block hidden">
|
<div id="desktop-toolbar" class="hidden lg:block">
|
||||||
<div class="toolbar-wrapper">
|
<div class="toolbar-wrapper">
|
||||||
<div @click="goBack" class="location">
|
<div @click="goBack" class="location">
|
||||||
<div v-if="! isVisibleNavigationBars" @click="toggleNavigationBars" class="mr-2">
|
<div v-if="!isVisibleNavigationBars" @click="toggleNavigationBars" class="mr-2">
|
||||||
<menu-icon size="17" />
|
<menu-icon size="17" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<chevron-left-icon :class="{'opacity-0 -translate-x-3': ! currentFolder, 'opacity-100 translate-x-0': currentFolder }" class="icon-back transform transition-all duration-200" size="17" />
|
<chevron-left-icon
|
||||||
|
:class="{
|
||||||
|
'-translate-x-3 opacity-0': !currentFolder,
|
||||||
|
'translate-x-0 opacity-100': currentFolder,
|
||||||
|
}"
|
||||||
|
class="icon-back transform transition-all duration-200"
|
||||||
|
size="17"
|
||||||
|
/>
|
||||||
|
|
||||||
<span :class="{'-translate-x-4': ! currentFolder}" class="location-title transform transition-all duration-200">
|
<span :class="{ '-translate-x-4': !currentFolder }" class="location-title transform transition-all duration-200">
|
||||||
{{ $getCurrentLocationName() }}
|
{{ $getCurrentLocationName() }}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span :class="{'-translate-x-4 opacity-0': ! currentFolder, 'translate-x-0 opacity-100': currentFolder}" @click.stop="folderActions" class="transform location-more group transition-all duration-200" id="folder-actions">
|
<span
|
||||||
<more-horizontal-icon size="14" class="icon-more group-hover-text-theme" />
|
:class="{
|
||||||
</span>
|
'-translate-x-4 opacity-0': !currentFolder,
|
||||||
</div>
|
'translate-x-0 opacity-100': currentFolder,
|
||||||
|
}"
|
||||||
|
@click.stop="folderActions"
|
||||||
|
class="location-more group transform transition-all duration-200"
|
||||||
|
id="folder-actions"
|
||||||
|
>
|
||||||
|
<more-horizontal-icon size="14" class="icon-more group-hover-text-theme" />
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<ToolbarWrapper>
|
<ToolbarWrapper>
|
||||||
|
<!--Search bar-->
|
||||||
|
<ToolbarGroup class="ml-0">
|
||||||
|
<SearchBar class="hidden lg:block" />
|
||||||
|
</ToolbarGroup>
|
||||||
|
|
||||||
<!--Search bar-->
|
<!--Create button for all pages except SharedWithMe-->
|
||||||
<ToolbarGroup class="ml-0">
|
<ToolbarGroup v-if="$checkPermission(['master', 'editor']) && !$isThisRoute($route, ['SharedWithMe'])">
|
||||||
<SearchBar class="lg:block hidden" />
|
<span class="block lg:hidden">
|
||||||
</ToolbarGroup>
|
<ToolbarButton @click.stop.native="$openSpotlight()" source="search" :action="$t('Search files or folders')" />
|
||||||
|
</span>
|
||||||
|
|
||||||
<!--Create button for all pages except SharedWithMe-->
|
<PopoverWrapper>
|
||||||
<ToolbarGroup v-if="$checkPermission(['master', 'editor']) && ! $isThisRoute($route, ['SharedWithMe'])">
|
<ToolbarButton @click.stop.native="showCreateMenu" source="cloud-plus" :action="$t('actions.create')" />
|
||||||
|
|
||||||
<span class="lg:hidden block">
|
<PopoverItem name="desktop-create" side="left">
|
||||||
<ToolbarButton @click.stop.native="$openSpotlight()" source="search" :action="$t('Search files or folders')" />
|
<OptionGroup :class="{ 'is-inactive': canUploadInView }">
|
||||||
</span>
|
<OptionUpload :title="$t('actions.upload')" type="file" />
|
||||||
|
<OptionUpload :title="$t('actions.upload_folder')" type="folder" />
|
||||||
|
</OptionGroup>
|
||||||
|
<OptionGroup>
|
||||||
|
<Option @click.stop.native="$createTeamFolder" :title="$t('Create Team Folder')" icon="users" />
|
||||||
|
<Option
|
||||||
|
@click.stop.native="$createFolder"
|
||||||
|
:class="{
|
||||||
|
'is-inactive': canCreateFolderInView || isTeamFolderHomepage,
|
||||||
|
}"
|
||||||
|
:title="$t('actions.create_folder')"
|
||||||
|
icon="folder-plus"
|
||||||
|
/>
|
||||||
|
</OptionGroup>
|
||||||
|
</PopoverItem>
|
||||||
|
</PopoverWrapper>
|
||||||
|
</ToolbarGroup>
|
||||||
|
|
||||||
<PopoverWrapper>
|
<!--Create button for shared with me page-->
|
||||||
<ToolbarButton @click.stop.native="showCreateMenu" source="cloud-plus" :action="$t('actions.create')" />
|
<ToolbarGroup v-if="$isThisRoute($route, ['SharedWithMe'])">
|
||||||
|
<span class="block lg:hidden">
|
||||||
|
<ToolbarButton @click.stop.native="$openSpotlight()" source="search" :action="$t('Search files or folders')" />
|
||||||
|
</span>
|
||||||
|
|
||||||
<PopoverItem name="desktop-create" side="left">
|
<PopoverWrapper>
|
||||||
<OptionGroup :class="{'is-inactive': canUploadInView }">
|
<ToolbarButton @click.stop.native="showCreateMenu" source="cloud-plus" :class="{ 'is-inactive': !canEdit }" :action="$t('actions.create')" />
|
||||||
<OptionUpload :title="$t('actions.upload')" type="file" />
|
|
||||||
<OptionUpload :title="$t('actions.upload_folder')" type="folder" />
|
|
||||||
</OptionGroup>
|
|
||||||
<OptionGroup>
|
|
||||||
<Option @click.stop.native="$createTeamFolder" :title="$t('Create Team Folder')" icon="users" />
|
|
||||||
<Option @click.stop.native="$createFolder" :class="{'is-inactive': canCreateFolderInView || isTeamFolderHomepage }" :title="$t('actions.create_folder')" icon="folder-plus" />
|
|
||||||
</OptionGroup>
|
|
||||||
</PopoverItem>
|
|
||||||
</PopoverWrapper>
|
|
||||||
</ToolbarGroup>
|
|
||||||
|
|
||||||
<!--Create button for shared with me page-->
|
<PopoverItem name="desktop-create" side="left">
|
||||||
<ToolbarGroup v-if="$isThisRoute($route, ['SharedWithMe'])">
|
<OptionGroup>
|
||||||
<span class="lg:hidden block">
|
<OptionUpload
|
||||||
<ToolbarButton @click.stop.native="$openSpotlight()" source="search" :action="$t('Search files or folders')" />
|
:class="{
|
||||||
</span>
|
'is-inactive': canUploadInView || isSharedWithMeHomepage,
|
||||||
|
}"
|
||||||
|
:title="$t('actions.upload')"
|
||||||
|
/>
|
||||||
|
</OptionGroup>
|
||||||
|
<OptionGroup>
|
||||||
|
<Option
|
||||||
|
@click.stop.native="$createFolder"
|
||||||
|
:class="{
|
||||||
|
'is-inactive': canCreateFolderInView || isSharedWithMeHomepage,
|
||||||
|
}"
|
||||||
|
:title="$t('actions.create_folder')"
|
||||||
|
icon="folder-plus"
|
||||||
|
/>
|
||||||
|
</OptionGroup>
|
||||||
|
</PopoverItem>
|
||||||
|
</PopoverWrapper>
|
||||||
|
</ToolbarGroup>
|
||||||
|
|
||||||
<PopoverWrapper>
|
<!--File Controls-->
|
||||||
<ToolbarButton @click.stop.native="showCreateMenu" source="cloud-plus" :class="{'is-inactive': ! canEdit}" :action="$t('actions.create')" />
|
<ToolbarGroup v-if="$checkPermission(['master', 'editor']) || ($isMobile() && $isThisRoute($route, ['SharedWithMe', 'TeamFolders']))">
|
||||||
|
<!--Team Heads-->
|
||||||
|
<PopoverWrapper v-if="$isThisRoute($route, ['TeamFolders', 'SharedWithMe'])">
|
||||||
|
<TeamMembersButton
|
||||||
|
@click.stop.native="showTeamFolderMenu"
|
||||||
|
size="32"
|
||||||
|
class="cursor-pointer rounded-lg py-0.5 pl-2 pr-0.5 hover:bg-light-background dark:hover:bg-dark-foreground"
|
||||||
|
/>
|
||||||
|
|
||||||
<PopoverItem name="desktop-create" side="left">
|
<PopoverItem name="team-folder" side="left">
|
||||||
<OptionGroup>
|
<TeamFolderPreview />
|
||||||
<OptionUpload :class="{'is-inactive': canUploadInView || isSharedWithMeHomepage }" :title="$t('actions.upload')" />
|
|
||||||
</OptionGroup>
|
|
||||||
<OptionGroup>
|
|
||||||
<Option @click.stop.native="$createFolder" :class="{'is-inactive': canCreateFolderInView || isSharedWithMeHomepage }" :title="$t('actions.create_folder')" icon="folder-plus" />
|
|
||||||
</OptionGroup>
|
|
||||||
</PopoverItem>
|
|
||||||
</PopoverWrapper>
|
|
||||||
</ToolbarGroup>
|
|
||||||
|
|
||||||
<!--File Controls-->
|
<OptionGroup v-if="$isThisRoute($route, ['TeamFolders'])">
|
||||||
<ToolbarGroup v-if="$checkPermission(['master', 'editor']) || ($isMobile() && $isThisRoute($route, ['SharedWithMe', 'TeamFolders']))">
|
<Option @click.native="$updateTeamFolder(teamFolder)" :title="$t('Edit Members')" icon="rename" />
|
||||||
|
<Option @click.native="$dissolveTeamFolder(teamFolder)" :title="$t('Dissolve Team')" icon="trash" />
|
||||||
|
</OptionGroup>
|
||||||
|
|
||||||
<!--Team Heads-->
|
<OptionGroup v-if="$isThisRoute($route, ['SharedWithMe'])">
|
||||||
<PopoverWrapper v-if="$isThisRoute($route, ['TeamFolders', 'SharedWithMe'])">
|
<Option @click.native="$detachMeFromTeamFolder(teamFolder)" :title="$t('Leave the Team Folder')" icon="user-minus" />
|
||||||
<TeamMembersButton @click.stop.native="showTeamFolderMenu" size="32" class="dark:hover:bg-dark-foreground hover:bg-light-background rounded-lg cursor-pointer py-0.5 pl-2 pr-0.5" />
|
</OptionGroup>
|
||||||
|
</PopoverItem>
|
||||||
|
</PopoverWrapper>
|
||||||
|
|
||||||
<PopoverItem name="team-folder" side="left">
|
<!--Item actions-->
|
||||||
<TeamFolderPreview />
|
<span v-if="!$isMobile()" class="whitespace-nowrap">
|
||||||
|
<ToolbarButton
|
||||||
|
v-if="canShowConvertToTeamFolder"
|
||||||
|
@click.native="$convertAsTeamFolder(clipboard[0])"
|
||||||
|
:class="{
|
||||||
|
'is-inactive': !canCreateTeamFolderInView,
|
||||||
|
}"
|
||||||
|
source="user-plus"
|
||||||
|
:action="$t('actions.convert_into_team_folder')"
|
||||||
|
/>
|
||||||
|
<ToolbarButton
|
||||||
|
v-if="!$isThisRoute($route, ['SharedWithMe', 'Public'])"
|
||||||
|
@click.native="$shareFileOrFolder(clipboard[0])"
|
||||||
|
:class="{ 'is-inactive': canShareInView }"
|
||||||
|
source="share"
|
||||||
|
:action="$t('actions.share')"
|
||||||
|
/>
|
||||||
|
|
||||||
<OptionGroup v-if="$isThisRoute($route, ['TeamFolders'])">
|
<ToolbarButton
|
||||||
<Option @click.native="$updateTeamFolder(teamFolder)" :title="$t('Edit Members')" icon="rename" />
|
@click.native="$moveFileOrFolder(clipboard[0])"
|
||||||
<Option @click.native="$dissolveTeamFolder(teamFolder)" :title="$t('Dissolve Team')" icon="trash" />
|
:class="{
|
||||||
</OptionGroup>
|
'is-inactive': canMoveInView && !canEdit,
|
||||||
|
}"
|
||||||
|
source="move"
|
||||||
|
:action="$t('actions.move')"
|
||||||
|
/>
|
||||||
|
<ToolbarButton
|
||||||
|
@click.native="$deleteFileOrFolder(clipboard[0])"
|
||||||
|
:class="{
|
||||||
|
'is-inactive': canDeleteInView && !canEdit,
|
||||||
|
}"
|
||||||
|
source="trash"
|
||||||
|
:action="$t('actions.delete')"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</ToolbarGroup>
|
||||||
|
|
||||||
<OptionGroup v-if="$isThisRoute($route, ['SharedWithMe'])">
|
<!--View Controls-->
|
||||||
<Option @click.native="$detachMeFromTeamFolder(teamFolder)" :title="$t('Leave the Team Folder')" icon="user-minus" />
|
<ToolbarGroup>
|
||||||
</OptionGroup>
|
<PopoverWrapper>
|
||||||
</PopoverItem>
|
<ToolbarButton @click.stop.native="showSortingMenu" source="preview-sorting" :action="$t('actions.sorting_view')" />
|
||||||
</PopoverWrapper>
|
<PopoverItem name="desktop-sorting" side="left">
|
||||||
|
<FileSortingOptions />
|
||||||
<!--Item actions-->
|
</PopoverItem>
|
||||||
<span v-if="! $isMobile()" class="whitespace-nowrap">
|
</PopoverWrapper>
|
||||||
<ToolbarButton v-if="canShowConvertToTeamFolder" @click.native="$convertAsTeamFolder(clipboard[0])" :class="{'is-inactive': ! canCreateTeamFolderInView }" source="user-plus" :action="$t('actions.convert_into_team_folder')" />
|
|
||||||
<ToolbarButton v-if="! $isThisRoute($route, ['SharedWithMe', 'Public'])" @click.native="$shareFileOrFolder(clipboard[0])" :class="{'is-inactive': canShareInView }" source="share" :action="$t('actions.share')" />
|
|
||||||
|
|
||||||
<ToolbarButton @click.native="$moveFileOrFolder(clipboard[0])" :class="{'is-inactive': canMoveInView && ! canEdit }" source="move" :action="$t('actions.move')" />
|
|
||||||
<ToolbarButton @click.native="$deleteFileOrFolder(clipboard[0])" :class="{'is-inactive': canDeleteInView && ! canEdit }" source="trash" :action="$t('actions.delete')" />
|
|
||||||
</span>
|
|
||||||
</ToolbarGroup>
|
|
||||||
|
|
||||||
<!--View Controls-->
|
|
||||||
<ToolbarGroup>
|
|
||||||
<PopoverWrapper>
|
|
||||||
<ToolbarButton @click.stop.native="showSortingMenu" source="preview-sorting" :action="$t('actions.sorting_view')" />
|
|
||||||
<PopoverItem name="desktop-sorting" side="left">
|
|
||||||
<FileSortingOptions />
|
|
||||||
</PopoverItem>
|
|
||||||
</PopoverWrapper>
|
|
||||||
<ToolbarButton @click.native="$store.dispatch('fileInfoToggle')" :action="$t('actions.info_panel')" source="info" />
|
<ToolbarButton @click.native="$store.dispatch('fileInfoToggle')" :action="$t('actions.info_panel')" source="info" />
|
||||||
</ToolbarGroup>
|
</ToolbarGroup>
|
||||||
</ToolbarWrapper>
|
</ToolbarWrapper>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<UploadProgress />
|
<UploadProgress />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import FileSortingOptions from "./FileSortingOptions";
|
import FileSortingOptions from './FileSortingOptions'
|
||||||
import UploadProgress from "./UploadProgress";
|
import UploadProgress from './UploadProgress'
|
||||||
import PopoverWrapper from "../Desktop/PopoverWrapper";
|
import PopoverWrapper from '../Desktop/PopoverWrapper'
|
||||||
import ToolbarWrapper from "../Desktop/ToolbarWrapper";
|
import ToolbarWrapper from '../Desktop/ToolbarWrapper'
|
||||||
import ToolbarButton from "./ToolbarButton";
|
import ToolbarButton from './ToolbarButton'
|
||||||
import OptionUpload from "./OptionUpload";
|
import OptionUpload from './OptionUpload'
|
||||||
import ToolbarGroup from "../Desktop/ToolbarGroup";
|
import ToolbarGroup from '../Desktop/ToolbarGroup'
|
||||||
import OptionGroup from "./OptionGroup";
|
import OptionGroup from './OptionGroup'
|
||||||
import TeamMembersButton from "../Teams/Components/TeamMembersButton"
|
import TeamMembersButton from '../Teams/Components/TeamMembersButton'
|
||||||
import PopoverItem from "../Desktop/PopoverItem";
|
import PopoverItem from '../Desktop/PopoverItem'
|
||||||
import TeamFolderPreview from "../Teams/Components/TeamFolderPreview"
|
import TeamFolderPreview from '../Teams/Components/TeamFolderPreview'
|
||||||
import {MenuIcon, ChevronLeftIcon, MoreHorizontalIcon} from 'vue-feather-icons'
|
import { MenuIcon, ChevronLeftIcon, MoreHorizontalIcon } from 'vue-feather-icons'
|
||||||
import SearchBar from "./SearchBar";
|
import SearchBar from './SearchBar'
|
||||||
import Option from "./Option";
|
import Option from './Option'
|
||||||
import {events} from "../../bus";
|
import { events } from '../../bus'
|
||||||
import {mapGetters} from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'DesktopToolbar',
|
name: 'DesktopToolbar',
|
||||||
components: {
|
components: {
|
||||||
TeamMembersButton,
|
TeamMembersButton,
|
||||||
FileSortingOptions,
|
FileSortingOptions,
|
||||||
MoreHorizontalIcon,
|
MoreHorizontalIcon,
|
||||||
TeamFolderPreview,
|
TeamFolderPreview,
|
||||||
ChevronLeftIcon,
|
ChevronLeftIcon,
|
||||||
ToolbarWrapper,
|
ToolbarWrapper,
|
||||||
UploadProgress,
|
UploadProgress,
|
||||||
PopoverWrapper,
|
PopoverWrapper,
|
||||||
ToolbarButton,
|
ToolbarButton,
|
||||||
OptionUpload,
|
OptionUpload,
|
||||||
ToolbarGroup,
|
ToolbarGroup,
|
||||||
OptionGroup,
|
OptionGroup,
|
||||||
PopoverItem,
|
PopoverItem,
|
||||||
SearchBar,
|
SearchBar,
|
||||||
MenuIcon,
|
MenuIcon,
|
||||||
Option,
|
Option,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters([
|
...mapGetters(['isVisibleNavigationBars', 'currentTeamFolder', 'currentFolder', 'sharedDetail', 'clipboard', 'user']),
|
||||||
'isVisibleNavigationBars',
|
canEdit() {
|
||||||
'currentTeamFolder',
|
if (this.currentTeamFolder && this.user && this.clipboard[0]) {
|
||||||
'currentFolder',
|
let member = this.currentTeamFolder.data.relationships.members.data.find((member) => member.data.id === this.user.data.id)
|
||||||
'sharedDetail',
|
|
||||||
'clipboard',
|
|
||||||
'user',
|
|
||||||
]),
|
|
||||||
canEdit() {
|
|
||||||
if (this.currentTeamFolder && this.user && this.clipboard[0]) {
|
|
||||||
let member = this.currentTeamFolder.data.relationships.members.data.find(member => member.data.id === this.user.data.id)
|
|
||||||
|
|
||||||
return member.data.attributes.permission === 'can-edit'
|
return member.data.attributes.permission === 'can-edit'
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
},
|
},
|
||||||
teamFolder() {
|
teamFolder() {
|
||||||
return this.currentTeamFolder
|
return this.currentTeamFolder ? this.currentTeamFolder : this.clipboard[0]
|
||||||
? this.currentTeamFolder
|
},
|
||||||
: this.clipboard[0]
|
isNotHomepage() {
|
||||||
},
|
if (this.$isThisRoute(this.$route, ['Public'])) {
|
||||||
isNotHomepage() {
|
return this.sharedDetail && this.sharedDetail.data.attributes.item_id === this.$route.params.id
|
||||||
if (this.$isThisRoute(this.$route, ['Public'])) {
|
}
|
||||||
return this.sharedDetail && this.sharedDetail.data.attributes.item_id === this.$route.params.id
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.$route.params.id
|
return this.$route.params.id
|
||||||
},
|
},
|
||||||
isTeamFolderHomepage() {
|
isTeamFolderHomepage() {
|
||||||
return this.$isThisRoute(this.$route, ['TeamFolders'])
|
return this.$isThisRoute(this.$route, ['TeamFolders']) && !this.$route.params.id
|
||||||
&& ! this.$route.params.id
|
},
|
||||||
},
|
isSharedWithMeHomepage() {
|
||||||
isSharedWithMeHomepage() {
|
return this.$isThisRoute(this.$route, ['SharedWithMe']) && !this.$route.params.id
|
||||||
return this.$isThisRoute(this.$route, ['SharedWithMe'])
|
},
|
||||||
&& ! this.$route.params.id
|
canCreateFolderInView() {
|
||||||
},
|
return !this.$isThisRoute(this.$route, ['Files', 'Public', 'TeamFolders', 'SharedWithMe'])
|
||||||
canCreateFolderInView() {
|
},
|
||||||
return ! this.$isThisRoute(this.$route, ['Files', 'Public', 'TeamFolders', 'SharedWithMe'])
|
canShowConvertToTeamFolder() {
|
||||||
},
|
return this.$isThisRoute(this.$route, ['Files', 'MySharedItems'])
|
||||||
canShowConvertToTeamFolder() {
|
},
|
||||||
return this.$isThisRoute(this.$route, ['Files', 'MySharedItems'])
|
canUploadInView() {
|
||||||
},
|
return !this.$isThisRoute(this.$route, ['Files', 'Public', 'TeamFolders', 'SharedWithMe'])
|
||||||
canUploadInView() {
|
},
|
||||||
return ! this.$isThisRoute(this.$route, ['Files', 'Public', 'TeamFolders', 'SharedWithMe'])
|
canDeleteInView() {
|
||||||
},
|
let routes = ['TeamFolders', 'SharedWithMe', 'RecentUploads', 'MySharedItems', 'Trash', 'Public', 'Files']
|
||||||
canDeleteInView() {
|
return !this.$isThisRoute(this.$route, routes) || this.clipboard.length === 0
|
||||||
let routes = [
|
},
|
||||||
'TeamFolders',
|
canMoveInView() {
|
||||||
'SharedWithMe',
|
let routes = ['SharedWithMe', 'RecentUploads', 'MySharedItems', 'Public', 'Files', 'TeamFolders']
|
||||||
'RecentUploads',
|
return !this.$isThisRoute(this.$route, routes) || this.clipboard.length === 0
|
||||||
'MySharedItems',
|
},
|
||||||
'Trash',
|
canShareInView() {
|
||||||
'Public',
|
let routes = ['TeamFolders', 'RecentUploads', 'MySharedItems', 'Public', 'Files']
|
||||||
'Files',
|
return !this.$isThisRoute(this.$route, routes) || this.clipboard.length > 1 || this.clipboard.length === 0
|
||||||
]
|
},
|
||||||
return !this.$isThisRoute(this.$route, routes)
|
canCreateTeamFolderInView() {
|
||||||
|| this.clipboard.length === 0
|
let routes = ['MySharedItems', 'Files']
|
||||||
},
|
|
||||||
canMoveInView() {
|
|
||||||
let routes = [
|
|
||||||
'SharedWithMe',
|
|
||||||
'RecentUploads',
|
|
||||||
'MySharedItems',
|
|
||||||
'Public',
|
|
||||||
'Files',
|
|
||||||
'TeamFolders',
|
|
||||||
]
|
|
||||||
return ! this.$isThisRoute(this.$route, routes)
|
|
||||||
|| this.clipboard.length === 0
|
|
||||||
},
|
|
||||||
canShareInView() {
|
|
||||||
let routes = [
|
|
||||||
'TeamFolders',
|
|
||||||
'RecentUploads',
|
|
||||||
'MySharedItems',
|
|
||||||
'Public',
|
|
||||||
'Files',
|
|
||||||
]
|
|
||||||
return ! this.$isThisRoute(this.$route, routes)
|
|
||||||
|| this.clipboard.length > 1
|
|
||||||
|| this.clipboard.length === 0
|
|
||||||
},
|
|
||||||
canCreateTeamFolderInView() {
|
|
||||||
let routes = [
|
|
||||||
'MySharedItems',
|
|
||||||
'Files',
|
|
||||||
]
|
|
||||||
|
|
||||||
return this.$isThisRoute(this.$route, routes)
|
return this.$isThisRoute(this.$route, routes) && this.clipboard.length === 1 && this.clipboard[0].data.type === 'folder'
|
||||||
&& this.clipboard.length === 1
|
},
|
||||||
&& this.clipboard[0].data.type === 'folder'
|
},
|
||||||
}
|
methods: {
|
||||||
},
|
toggleNavigationBars() {
|
||||||
methods: {
|
this.$store.dispatch('toggleNavigationBars')
|
||||||
toggleNavigationBars() {
|
},
|
||||||
this.$store.dispatch('toggleNavigationBars')
|
goBack() {
|
||||||
},
|
if (this.isNotHomepage) this.$router.back()
|
||||||
goBack() {
|
},
|
||||||
if (this.isNotHomepage) this.$router.back()
|
showTeamFolderMenu() {
|
||||||
},
|
if (this.teamFolder) events.$emit('popover:open', 'team-folder')
|
||||||
showTeamFolderMenu() {
|
},
|
||||||
if (this.teamFolder)
|
showCreateMenu() {
|
||||||
events.$emit('popover:open', 'team-folder')
|
events.$emit('popover:open', 'desktop-create')
|
||||||
},
|
},
|
||||||
showCreateMenu() {
|
showSortingMenu() {
|
||||||
events.$emit('popover:open', 'desktop-create')
|
events.$emit('popover:open', 'desktop-sorting')
|
||||||
},
|
},
|
||||||
showSortingMenu() {
|
folderActions() {
|
||||||
events.$emit('popover:open', 'desktop-sorting')
|
events.$emit('context-menu:current-folder', this.currentFolder)
|
||||||
},
|
},
|
||||||
folderActions() {
|
},
|
||||||
events.$emit('context-menu:current-folder', this.currentFolder)
|
}
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "resources/sass/vuefilemanager/_variables";
|
@import 'resources/sass/vuefilemanager/_variables';
|
||||||
@import "resources/sass/vuefilemanager/_mixins";
|
@import 'resources/sass/vuefilemanager/_mixins';
|
||||||
|
|
||||||
.is-inactive {
|
.is-inactive {
|
||||||
opacity: 0.25;
|
opacity: 0.25;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toolbar-wrapper {
|
.toolbar-wrapper {
|
||||||
padding-top: 10px;
|
padding-top: 10px;
|
||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.location {
|
.location {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
.icon-back {
|
.icon-back {
|
||||||
@include transition(150ms);
|
@include transition(150ms);
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
margin-right: 6px;
|
margin-right: 6px;
|
||||||
shrink: 0;
|
shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.location-title {
|
.location-title {
|
||||||
@include font-size(15);
|
@include font-size(15);
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
color: $text;
|
color: $text;
|
||||||
}
|
}
|
||||||
|
|
||||||
.location-more {
|
.location-more {
|
||||||
margin-left: 6px;
|
margin-left: 6px;
|
||||||
padding: 1px 4px;
|
padding: 1px 4px;
|
||||||
line-height: 0;
|
line-height: 0;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
|
|
||||||
svg circle {
|
svg circle {
|
||||||
@include transition(150ms);
|
@include transition(150ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: $light_background;
|
background: $light_background;
|
||||||
|
|
||||||
svg circle {
|
svg circle {
|
||||||
color: inherit;
|
color: inherit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.toolbar-position {
|
.toolbar-position {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
span {
|
span {
|
||||||
@include font-size(17);
|
@include font-size(17);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: 1024px) {
|
@media only screen and (max-width: 1024px) {
|
||||||
.location {
|
.location {
|
||||||
|
.location-title {
|
||||||
|
max-width: 120px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.location-title {
|
.toolbar-tools {
|
||||||
max-width: 120px;
|
.button {
|
||||||
}
|
margin-left: 0;
|
||||||
}
|
height: 40px;
|
||||||
|
width: 40px;
|
||||||
.toolbar-tools {
|
}
|
||||||
.button {
|
}
|
||||||
margin-left: 0;
|
|
||||||
height: 40px;
|
|
||||||
width: 40px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark {
|
.dark {
|
||||||
|
.toolbar .directory-name {
|
||||||
|
color: $dark_mode_text_primary;
|
||||||
|
}
|
||||||
|
|
||||||
.toolbar .directory-name {
|
.location {
|
||||||
color: $dark_mode_text_primary;
|
.location-title {
|
||||||
}
|
color: $dark_mode_text_primary;
|
||||||
|
}
|
||||||
|
|
||||||
.location {
|
.location-more {
|
||||||
.location-title {
|
&:hover {
|
||||||
color: $dark_mode_text_primary;
|
background: $dark_mode_foreground;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
.location-more {
|
}
|
||||||
&:hover {
|
|
||||||
background: $dark_mode_foreground;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,27 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<TitlePreview
|
<TitlePreview icon="check-square" :title="title" :subtitle="subtitle" id="drag-ui" v-show="isVisible" />
|
||||||
icon="check-square"
|
|
||||||
:title="title"
|
|
||||||
:subtitle="subtitle"
|
|
||||||
id="drag-ui"
|
|
||||||
v-show="isVisible"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import TitlePreview from "./TitlePreview";
|
import TitlePreview from './TitlePreview'
|
||||||
import { mapGetters } from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
import { events } from '../../bus'
|
import { events } from '../../bus'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'DragUI',
|
name: 'DragUI',
|
||||||
components: {
|
components: {
|
||||||
TitlePreview
|
TitlePreview,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters([
|
...mapGetters(['clipboard']),
|
||||||
'clipboard'
|
|
||||||
]),
|
|
||||||
title() {
|
title() {
|
||||||
let filesLength = this.clipboard.length,
|
let filesLength = this.clipboard.length,
|
||||||
hasDraggedItem = this.clipboard.includes(this.draggedItem)
|
hasDraggedItem = this.clipboard.includes(this.draggedItem)
|
||||||
@@ -46,7 +38,6 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((filesLength < 2 || !hasDraggedItem) && this.draggedItem) {
|
if ((filesLength < 2 || !hasDraggedItem) && this.draggedItem) {
|
||||||
|
|
||||||
// Subtitle for single folder
|
// Subtitle for single folder
|
||||||
if (this.draggedItem.data.type === 'folder') {
|
if (this.draggedItem.data.type === 'folder') {
|
||||||
return this.draggedItem.items == 0 ? this.$t('folder.empty') : this.$tc('folder.item_counts', this.draggedItem.items)
|
return this.draggedItem.items == 0 ? this.$t('folder.empty') : this.$tc('folder.item_counts', this.draggedItem.items)
|
||||||
@@ -57,16 +48,16 @@ export default {
|
|||||||
return '.' + this.draggedItem.data.attributes.mimetype
|
return '.' + this.draggedItem.data.attributes.mimetype
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isVisible: false,
|
isVisible: false,
|
||||||
draggedItem: undefined
|
draggedItem: undefined,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
events.$on('dragstart', data => {
|
events.$on('dragstart', (data) => {
|
||||||
this.draggedItem = data
|
this.draggedItem = data
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@@ -74,8 +65,8 @@ export default {
|
|||||||
}, 100)
|
}, 100)
|
||||||
})
|
})
|
||||||
|
|
||||||
events.$on('drop', () => this.isVisible = false)
|
events.$on('drop', () => (this.isVisible = false))
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -100,5 +91,4 @@ export default {
|
|||||||
background: $dark_mode_foreground;
|
background: $dark_mode_foreground;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,65 +1,60 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex items-center justify-center h-full" v-if="isLoading || isEmpty">
|
<div class="flex h-full items-center justify-center" v-if="isLoading || isEmpty">
|
||||||
|
<!--Show message for user-->
|
||||||
|
<div v-if="!isLoading" class="text-content text-center">
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!--Show message for user-->
|
<!--Show spinner when loading content-->
|
||||||
<div v-if="!isLoading" class="text-content text-center">
|
<div v-else class="fixed top-0 bottom-0 sm:relative">
|
||||||
<slot></slot>
|
<Spinner />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!--Show spinner when loading content-->
|
|
||||||
<div v-else class="sm:relative fixed top-0 bottom-0">
|
|
||||||
<Spinner />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Spinner from "./Spinner";
|
import Spinner from './Spinner'
|
||||||
import {mapGetters} from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'EmptyFilePage',
|
name: 'EmptyFilePage',
|
||||||
components: {
|
components: {
|
||||||
Spinner,
|
Spinner,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters([
|
...mapGetters(['isLoading', 'entries']),
|
||||||
'isLoading',
|
isEmpty() {
|
||||||
'entries',
|
return this.entries && this.entries.length === 0
|
||||||
]),
|
},
|
||||||
isEmpty() {
|
},
|
||||||
return this.entries && this.entries.length === 0
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import '../../../sass/vuefilemanager/variables';
|
@import '../../../sass/vuefilemanager/variables';
|
||||||
@import '../../../sass/vuefilemanager/mixins';
|
@import '../../../sass/vuefilemanager/mixins';
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
@include font-size(20);
|
@include font-size(20);
|
||||||
color: $text;
|
color: $text;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.description {
|
.description {
|
||||||
@include font-size(13);
|
@include font-size(13);
|
||||||
color: $text-muted;
|
color: $text-muted;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark {
|
.dark {
|
||||||
|
.title {
|
||||||
|
color: $dark_mode_text_primary;
|
||||||
|
}
|
||||||
|
|
||||||
.title {
|
.description {
|
||||||
color: $dark_mode_text_primary;
|
color: $dark_mode_text_secondary;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
.description {
|
|
||||||
color: $dark_mode_text_secondary;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="sticky dark:bg-dark-background bg-white top-14 pb-3 px-4 z-20 whitespace-nowrap overflow-x-auto lg:hidden block">
|
<div class="sticky top-14 z-20 block overflow-x-auto whitespace-nowrap bg-white px-4 pb-3 dark:bg-dark-background lg:hidden">
|
||||||
|
|
||||||
<!--Show Buttons-->
|
<!--Show Buttons-->
|
||||||
<div v-if="! isMultiSelectMode" class="mobile-actions">
|
<div v-if="!isMultiSelectMode" class="mobile-actions">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Multi select mode -->
|
<!-- Multi select mode -->
|
||||||
<div v-if="isMultiSelectMode" class="mobile-actions">
|
<div v-if="isMultiSelectMode" class="mobile-actions">
|
||||||
<MobileActionButton @click.native="selectAll" icon="check-square">
|
<MobileActionButton @click.native="selectAll" icon="check-square">
|
||||||
{{ $t('mobile_selecting.select_all') }}
|
{{ $t('mobile_selecting.select_all') }}
|
||||||
@@ -20,60 +19,58 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!--Upload Progressbar-->
|
<!--Upload Progressbar-->
|
||||||
<UploadProgress class="pt-3"/>
|
<UploadProgress class="pt-3" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import MobileActionButton from "./MobileActionButton";
|
import MobileActionButton from './MobileActionButton'
|
||||||
import UploadProgress from "./UploadProgress";
|
import UploadProgress from './UploadProgress'
|
||||||
import {mapGetters} from "vuex";
|
import { mapGetters } from 'vuex'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'FileActionsMobile',
|
name: 'FileActionsMobile',
|
||||||
components: {
|
components: {
|
||||||
MobileActionButton,
|
MobileActionButton,
|
||||||
UploadProgress,
|
UploadProgress,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters(['isMultiSelectMode']),
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
selectAll() {
|
||||||
|
this.$store.commit('ADD_ALL_ITEMS_TO_CLIPBOARD')
|
||||||
},
|
},
|
||||||
computed: {
|
deselectAll() {
|
||||||
...mapGetters([
|
this.$store.commit('CLIPBOARD_CLEAR')
|
||||||
'isMultiSelectMode'
|
},
|
||||||
])
|
disableMultiSelectMode() {
|
||||||
},
|
this.$store.commit('TOGGLE_MULTISELECT_MODE')
|
||||||
methods: {
|
},
|
||||||
selectAll() {
|
},
|
||||||
this.$store.commit('ADD_ALL_ITEMS_TO_CLIPBOARD')
|
}
|
||||||
},
|
|
||||||
deselectAll() {
|
|
||||||
this.$store.commit('CLIPBOARD_CLEAR')
|
|
||||||
},
|
|
||||||
disableMultiSelectMode() {
|
|
||||||
this.$store.commit('TOGGLE_MULTISELECT_MODE')
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import '../../../sass/vuefilemanager/variables';
|
@import '../../../sass/vuefilemanager/variables';
|
||||||
@import '../../../sass/vuefilemanager/mixins';
|
@import '../../../sass/vuefilemanager/mixins';
|
||||||
|
|
||||||
.button-enter-active,
|
.button-enter-active,
|
||||||
.button-leave-active {
|
.button-leave-active {
|
||||||
transition: all 250ms;
|
transition: all 250ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-enter {
|
.button-enter {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: translateY(-50%);
|
transform: translateY(-50%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-leave-to {
|
.button-leave-to {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: translateY(50%);
|
transform: translateY(50%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-leave-active {
|
.button-leave-active {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,158 +1,155 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
:class="{
|
:class="{
|
||||||
'user-dropping-file': isDragging,
|
'user-dropping-file': isDragging,
|
||||||
'grid-view': itemViewType === 'grid' && ! isVisibleSidebar,
|
'grid-view': itemViewType === 'grid' && !isVisibleSidebar,
|
||||||
'grid-view-sidebar': itemViewType === 'grid' && isVisibleSidebar
|
'grid-view-sidebar': itemViewType === 'grid' && isVisibleSidebar,
|
||||||
}"
|
}"
|
||||||
class="lg:w-full lg:overflow-y-auto lg:h-full lg:px-0 px-4"
|
class="px-4 lg:h-full lg:w-full lg:overflow-y-auto lg:px-0"
|
||||||
@drop.stop.prevent="uploadDroppedItems($event)"
|
@drop.stop.prevent="uploadDroppedItems($event)"
|
||||||
@keydown.delete="deleteItems"
|
@keydown.delete="deleteItems"
|
||||||
@dragover="dragEnter"
|
@dragover="dragEnter"
|
||||||
@dragleave="dragLeave"
|
@dragleave="dragLeave"
|
||||||
@dragover.prevent
|
@dragover.prevent
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
@click.self="deselect"
|
@click.self="deselect"
|
||||||
>
|
>
|
||||||
<ItemHandler
|
<ItemHandler
|
||||||
@click.native="hideContextMenu"
|
@click.native="hideContextMenu"
|
||||||
@dragstart="dragStart(item)"
|
@dragstart="dragStart(item)"
|
||||||
@drop.stop.native.prevent="dragFinish(item, $event)"
|
@drop.stop.native.prevent="dragFinish(item, $event)"
|
||||||
@contextmenu.native.prevent="contextMenu($event, item)"
|
@contextmenu.native.prevent="contextMenu($event, item)"
|
||||||
:class="draggedItems.includes(item) ? 'opacity-60' : ''"
|
:class="draggedItems.includes(item) ? 'opacity-60' : ''"
|
||||||
v-for="item in entries"
|
v-for="item in entries"
|
||||||
:key="item.data.id"
|
:key="item.data.id"
|
||||||
:item="item"
|
:item="item"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ItemHandler from "./ItemHandler";
|
import ItemHandler from './ItemHandler'
|
||||||
import {events} from "../../bus";
|
import { events } from '../../bus'
|
||||||
import {mapGetters} from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'FileBrowser',
|
name: 'FileBrowser',
|
||||||
components: {
|
components: {
|
||||||
ItemHandler,
|
ItemHandler,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters([
|
...mapGetters(['isVisibleSidebar', 'currentFolder', 'itemViewType', 'clipboard', 'entries']),
|
||||||
'isVisibleSidebar',
|
draggedItems() {
|
||||||
'currentFolder',
|
// Set opacity for dragged items
|
||||||
'itemViewType',
|
if (!this.clipboard.includes(this.draggingId)) {
|
||||||
'clipboard',
|
return [this.draggingId]
|
||||||
'entries'
|
}
|
||||||
]),
|
|
||||||
draggedItems() {
|
|
||||||
// Set opacity for dragged items
|
|
||||||
if (!this.clipboard.includes(this.draggingId)) {
|
|
||||||
return [this.draggingId]
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.clipboard.includes(this.draggingId)) {
|
if (this.clipboard.includes(this.draggingId)) {
|
||||||
return this.clipboard
|
return this.clipboard
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
draggingId: undefined,
|
draggingId: undefined,
|
||||||
isDragging: false,
|
isDragging: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
deleteItems() {
|
deleteItems() {
|
||||||
if (this.clipboard.length > 0 && this.$checkPermission('master') || this.$checkPermission('editor')) {
|
if ((this.clipboard.length > 0 && this.$checkPermission('master')) || this.$checkPermission('editor')) {
|
||||||
this.$store.dispatch('deleteItem')
|
this.$store.dispatch('deleteItem')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
uploadDroppedItems(event) {
|
uploadDroppedItems(event) {
|
||||||
this.$uploadDraggedFiles(event, this.currentFolder.data.id)
|
this.$uploadDraggedFiles(event, this.currentFolder.data.id)
|
||||||
|
|
||||||
this.isDragging = false
|
this.isDragging = false
|
||||||
},
|
},
|
||||||
dragEnter() {
|
dragEnter() {
|
||||||
this.isDragging = true
|
this.isDragging = true
|
||||||
},
|
},
|
||||||
dragLeave() {
|
dragLeave() {
|
||||||
this.isDragging = false
|
this.isDragging = false
|
||||||
},
|
},
|
||||||
dragStart(data) {
|
dragStart(data) {
|
||||||
let img = document.createElement('img')
|
let img = document.createElement('img')
|
||||||
img.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
|
img.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'
|
||||||
event.dataTransfer.setDragImage(img, 0, 0)
|
event.dataTransfer.setDragImage(img, 0, 0)
|
||||||
|
|
||||||
events.$emit('dragstart', data)
|
events.$emit('dragstart', data)
|
||||||
|
|
||||||
// Store dragged folder
|
// Store dragged folder
|
||||||
this.draggingId = data
|
this.draggingId = data
|
||||||
|
|
||||||
// TODO: founded issue on firefox
|
// TODO: founded issue on firefox
|
||||||
},
|
},
|
||||||
dragFinish(data, event) {
|
dragFinish(data, event) {
|
||||||
|
if (event.dataTransfer.items.length === 0) {
|
||||||
|
// Prevent to drop on file or image
|
||||||
|
if (data.data.type !== 'folder' || this.draggingId === data) return
|
||||||
|
|
||||||
if (event.dataTransfer.items.length === 0) {
|
// Prevent move selected folder to folder if in between selected folders
|
||||||
// Prevent to drop on file or image
|
if (this.clipboard.find((item) => item === data && this.clipboard.length > 1)) return
|
||||||
if (data.data.type !== 'folder' || this.draggingId === data) return
|
|
||||||
|
|
||||||
// Prevent move selected folder to folder if in between selected folders
|
// Move item if is not included in selected items
|
||||||
if (this.clipboard.find(item => item === data && this.clipboard.length > 1)) return
|
if (!this.clipboard.includes(this.draggingId)) {
|
||||||
|
this.$store.dispatch('moveItem', {
|
||||||
|
to_item: data,
|
||||||
|
noSelectedItem: this.draggingId,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// Move item if is not included in selected items
|
// Move selected items to folder
|
||||||
if (!this.clipboard.includes(this.draggingId)) {
|
if (this.clipboard.length > 0 && this.clipboard.includes(this.draggingId)) {
|
||||||
this.$store.dispatch('moveItem', {to_item: data, noSelectedItem: this.draggingId})
|
this.$store.dispatch('moveItem', {
|
||||||
}
|
to_item: data,
|
||||||
|
noSelectedItem: null,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Get id from current folder
|
||||||
|
const id = data.data.type !== 'folder' ? this.currentFolder.data.id : data.data.id
|
||||||
|
|
||||||
// Move selected items to folder
|
// Upload external file
|
||||||
if (this.clipboard.length > 0 && this.clipboard.includes(this.draggingId)) {
|
this.$uploadDraggedFiles(event, id)
|
||||||
this.$store.dispatch('moveItem', {to_item: data, noSelectedItem: null})
|
}
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
this.isDragging = false
|
||||||
|
},
|
||||||
|
contextMenu(event, item) {
|
||||||
|
events.$emit('context-menu:show', event, item)
|
||||||
|
},
|
||||||
|
hideContextMenu() {
|
||||||
|
events.$emit('context-menu:hide')
|
||||||
|
},
|
||||||
|
deselect() {
|
||||||
|
// Hide context menu
|
||||||
|
events.$emit('context-menu:hide')
|
||||||
|
|
||||||
// Get id from current folder
|
// Clear clipboard
|
||||||
const id = data.data.type !== 'folder' ? this.currentFolder.data.id : data.data.id
|
this.$store.commit('CLIPBOARD_CLEAR')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
events.$on('drop', () => {
|
||||||
|
this.isDragging = false
|
||||||
|
|
||||||
// Upload external file
|
setTimeout(() => {
|
||||||
this.$uploadDraggedFiles(event, id)
|
this.draggingId = undefined
|
||||||
}
|
}, 10)
|
||||||
|
})
|
||||||
this.isDragging = false
|
},
|
||||||
},
|
}
|
||||||
contextMenu(event, item) {
|
|
||||||
events.$emit('context-menu:show', event, item)
|
|
||||||
},
|
|
||||||
hideContextMenu() {
|
|
||||||
events.$emit('context-menu:hide')
|
|
||||||
},
|
|
||||||
deselect() {
|
|
||||||
// Hide context menu
|
|
||||||
events.$emit('context-menu:hide')
|
|
||||||
|
|
||||||
// Clear clipboard
|
|
||||||
this.$store.commit('CLIPBOARD_CLEAR')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
events.$on('drop', () => {
|
|
||||||
this.isDragging = false
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
this.draggingId = undefined
|
|
||||||
}, 10)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.grid-view {
|
.grid-view {
|
||||||
@apply grid content-start xl:grid-cols-6 sm:grid-cols-4 grid-cols-3 xl:gap-4 lg:gap-2
|
@apply grid grid-cols-3 content-start sm:grid-cols-4 lg:gap-2 xl:grid-cols-6 xl:gap-4;
|
||||||
}
|
}
|
||||||
|
|
||||||
.grid-view-sidebar {
|
.grid-view-sidebar {
|
||||||
@apply grid content-start 2xl:grid-cols-5 xl:grid-cols-4 lg:grid-cols-3 md:grid-cols-2 grid-cols-3 xl:gap-4 lg:gap-2
|
@apply grid grid-cols-3 content-start md:grid-cols-2 lg:grid-cols-3 lg:gap-2 xl:grid-cols-4 xl:gap-4 2xl:grid-cols-5;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -9,18 +9,24 @@
|
|||||||
</OptionGroup>
|
</OptionGroup>
|
||||||
<OptionGroup>
|
<OptionGroup>
|
||||||
<Option @click.native="goToTeamFolders" :title="$t('Team Folders')" icon="users" :is-active="$isThisRoute($route, 'TeamFolders')" :is-hover-disabled="true" />
|
<Option @click.native="goToTeamFolders" :title="$t('Team Folders')" icon="users" :is-active="$isThisRoute($route, 'TeamFolders')" :is-hover-disabled="true" />
|
||||||
<Option @click.native="goToSharedWithMe" :title="$t('Shared with Me')" icon="user-check" :is-active="$isThisRoute($route, 'SharedWithMe')" :is-hover-disabled="true" />
|
<Option
|
||||||
|
@click.native="goToSharedWithMe"
|
||||||
|
:title="$t('Shared with Me')"
|
||||||
|
icon="user-check"
|
||||||
|
:is-active="$isThisRoute($route, 'SharedWithMe')"
|
||||||
|
:is-hover-disabled="true"
|
||||||
|
/>
|
||||||
</OptionGroup>
|
</OptionGroup>
|
||||||
</MenuMobileGroup>
|
</MenuMobileGroup>
|
||||||
</MenuMobile>
|
</MenuMobile>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import MenuMobileGroup from "../Mobile/MenuMobileGroup";
|
import MenuMobileGroup from '../Mobile/MenuMobileGroup'
|
||||||
import OptionGroup from '../FilesView/OptionGroup'
|
import OptionGroup from '../FilesView/OptionGroup'
|
||||||
import MenuMobile from '../Mobile/MenuMobile'
|
import MenuMobile from '../Mobile/MenuMobile'
|
||||||
import Option from '../FilesView/Option'
|
import Option from '../FilesView/Option'
|
||||||
import {mapGetters} from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'MobileContextMenu',
|
name: 'MobileContextMenu',
|
||||||
@@ -32,23 +38,23 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
goToFiles() {
|
goToFiles() {
|
||||||
this.$router.push({name: 'Files'})
|
this.$router.push({ name: 'Files' })
|
||||||
},
|
},
|
||||||
goToLatest() {
|
goToLatest() {
|
||||||
this.$router.push({name: 'RecentUploads'})
|
this.$router.push({ name: 'RecentUploads' })
|
||||||
},
|
},
|
||||||
goToShared() {
|
goToShared() {
|
||||||
this.$router.push({name: 'MySharedItems'})
|
this.$router.push({ name: 'MySharedItems' })
|
||||||
},
|
},
|
||||||
goToTrash() {
|
goToTrash() {
|
||||||
this.$router.push({name: 'Trash'})
|
this.$router.push({ name: 'Trash' })
|
||||||
},
|
},
|
||||||
goToTeamFolders() {
|
goToTeamFolders() {
|
||||||
this.$router.push({name: 'TeamFolders'})
|
this.$router.push({ name: 'TeamFolders' })
|
||||||
},
|
},
|
||||||
goToSharedWithMe() {
|
goToSharedWithMe() {
|
||||||
this.$router.push({name: 'SharedWithMe'})
|
this.$router.push({ name: 'SharedWithMe' })
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,23 +1,22 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex items-center justify-center">
|
<div class="flex items-center justify-center">
|
||||||
<span class="text-theme dark-text-theme lg:text-xs text-tiny font-semibold absolute z-10 inline-block mx-auto mt-1 w-7 text-ellipsis overflow-hidden text-center">
|
<span class="text-theme dark-text-theme absolute z-10 mx-auto mt-1 inline-block w-7 overflow-hidden text-ellipsis text-center text-tiny font-semibold lg:text-xs">
|
||||||
{{ entry.data.attributes.mimetype }}
|
{{ entry.data.attributes.mimetype }}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<svg width="38px" height="51px" viewBox="0 0 38 51" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
<svg width="38px" height="51px" viewBox="0 0 38 51" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
<path
|
<path
|
||||||
stroke-width="0"
|
stroke-width="0"
|
||||||
fill="#f4f5f6"
|
fill="#f4f5f6"
|
||||||
d="M22.1666667,13.546875 L22.1666667,0 L2.375,0 C1.05885417,0 0,1.06582031 0,2.390625 L0,48.609375 C0,49.9341797 1.05885417,51 2.375,51 L35.625,51 C36.9411458,51 38,49.9341797 38,48.609375 L38,15.9375 L24.5416667,15.9375 C23.2354167,15.9375 22.1666667,14.8617187 22.1666667,13.546875 Z M38,12.1423828 L38,12.75 L25.3333333,12.75 L25.3333333,0 L25.9369792,0 C26.5703125,0 27.1739583,0.249023438 27.6192708,0.697265625 L37.3072917,10.4589844 C37.7526042,10.9072266 38,11.5148437 38,12.1423828 Z"></path>
|
d="M22.1666667,13.546875 L22.1666667,0 L2.375,0 C1.05885417,0 0,1.06582031 0,2.390625 L0,48.609375 C0,49.9341797 1.05885417,51 2.375,51 L35.625,51 C36.9411458,51 38,49.9341797 38,48.609375 L38,15.9375 L24.5416667,15.9375 C23.2354167,15.9375 22.1666667,14.8617187 22.1666667,13.546875 Z M38,12.1423828 L38,12.75 L25.3333333,12.75 L25.3333333,0 L25.9369792,0 C26.5703125,0 27.1739583,0.249023438 27.6192708,0.697265625 L37.3072917,10.4589844 C37.7526042,10.9072266 38,11.5148437 38,12.1423828 Z"
|
||||||
</svg>
|
></path>
|
||||||
</div>
|
</svg>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'FileIconThumbnail',
|
name: 'FileIconThumbnail',
|
||||||
props: [
|
props: ['entry'],
|
||||||
'entry'
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -7,8 +7,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import FileSortingOptions from "./FileSortingOptions";
|
import FileSortingOptions from './FileSortingOptions'
|
||||||
import MenuMobileGroup from "../Mobile/MenuMobileGroup";
|
import MenuMobileGroup from '../Mobile/MenuMobileGroup'
|
||||||
import MenuMobile from '../Mobile/MenuMobile'
|
import MenuMobile from '../Mobile/MenuMobile'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|||||||
@@ -12,8 +12,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import OptionGroup from './OptionGroup'
|
||||||
import OptionGroup from "./OptionGroup";
|
|
||||||
import Option from './Option'
|
import Option from './Option'
|
||||||
import { ArrowUpIcon } from 'vue-feather-icons'
|
import { ArrowUpIcon } from 'vue-feather-icons'
|
||||||
import { mapGetters } from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
@@ -26,34 +25,30 @@ export default {
|
|||||||
Option,
|
Option,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters([
|
...mapGetters(['itemViewType']),
|
||||||
'itemViewType'
|
|
||||||
]),
|
|
||||||
isGrid() {
|
isGrid() {
|
||||||
return this.itemViewType === 'grid'
|
return this.itemViewType === 'grid'
|
||||||
},
|
},
|
||||||
isList() {
|
isList() {
|
||||||
return this.itemViewType === 'list'
|
return this.itemViewType === 'list'
|
||||||
},
|
},
|
||||||
arrowForCreatedAtField() {
|
arrowForCreatedAtField() {
|
||||||
if (this.filter.field !== 'created_at')
|
if (this.filter.field !== 'created_at') return undefined
|
||||||
return undefined
|
|
||||||
|
|
||||||
return this.filter.sort === 'DESC' ? 'up' : 'down'
|
return this.filter.sort === 'DESC' ? 'up' : 'down'
|
||||||
},
|
},
|
||||||
arrowForNameField() {
|
arrowForNameField() {
|
||||||
if (this.filter.field !== 'name')
|
if (this.filter.field !== 'name') return undefined
|
||||||
return undefined
|
|
||||||
|
|
||||||
return this.filter.sort === 'DESC' ? 'up' : 'down'
|
return this.filter.sort === 'DESC' ? 'up' : 'down'
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
filter: {
|
filter: {
|
||||||
sort: 'DESC',
|
sort: 'DESC',
|
||||||
field: undefined
|
field: undefined,
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -61,28 +56,32 @@ export default {
|
|||||||
this.filter.field = field
|
this.filter.field = field
|
||||||
|
|
||||||
// Set sorting direction
|
// Set sorting direction
|
||||||
if (this.filter.sort === 'DESC')
|
if (this.filter.sort === 'DESC') this.filter.sort = 'ASC'
|
||||||
this.filter.sort = 'ASC'
|
else if (this.filter.sort === 'ASC') this.filter.sort = 'DESC'
|
||||||
else if (this.filter.sort === 'ASC')
|
|
||||||
this.filter.sort = 'DESC'
|
|
||||||
|
|
||||||
// Save to localStorage sorting options
|
// Save to localStorage sorting options
|
||||||
localStorage.setItem('sorting', JSON.stringify({ sort: this.filter.sort, field: this.filter.field }))
|
localStorage.setItem(
|
||||||
|
'sorting',
|
||||||
|
JSON.stringify({
|
||||||
|
sort: this.filter.sort,
|
||||||
|
field: this.filter.field,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
// Update sorting state in vuex
|
// Update sorting state in vuex
|
||||||
this.$store.commit('UPDATE_SORTING')
|
this.$store.commit('UPDATE_SORTING')
|
||||||
|
|
||||||
// Get data of user with favourites tree
|
// Get data of user with favourites tree
|
||||||
this.$store.dispatch('getAppData')
|
this.$store.dispatch('getAppData')
|
||||||
|
|
||||||
// Get data of Navigator tree
|
// Get data of Navigator tree
|
||||||
this.$store.dispatch('getFolderTree')
|
this.$store.dispatch('getFolderTree')
|
||||||
|
|
||||||
this.$getDataByLocation()
|
this.$getDataByLocation()
|
||||||
},
|
},
|
||||||
changePreview(previewType) {
|
changePreview(previewType) {
|
||||||
this.$store.dispatch('togglePreviewType', previewType)
|
this.$store.dispatch('togglePreviewType', previewType)
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
let sorting = JSON.parse(localStorage.getItem('sorting'))
|
let sorting = JSON.parse(localStorage.getItem('sorting'))
|
||||||
@@ -90,6 +89,6 @@ export default {
|
|||||||
// Set default sorting if in not setup in LocalStorage
|
// Set default sorting if in not setup in LocalStorage
|
||||||
this.filter.sort = sorting ? sorting.sort : 'DESC'
|
this.filter.sort = sorting ? sorting.sort : 'DESC'
|
||||||
this.filter.field = sorting ? sorting.field : 'created_at'
|
this.filter.field = sorting ? sorting.field : 'created_at'
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,27 +1,20 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<VueFolderIcon
|
<VueFolderIcon v-if="!item.data.attributes.isTeamFolder" />
|
||||||
v-if="!item.data.attributes.isTeamFolder"
|
<VueFolderTeamIcon v-if="item.data.attributes.isTeamFolder" style="width: 53px; height: 52px" />
|
||||||
/>
|
|
||||||
<VueFolderTeamIcon
|
|
||||||
v-if="item.data.attributes.isTeamFolder"
|
|
||||||
style="width: 53px; height: 52px"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import VueFolderTeamIcon from "./Icons/VueFolderTeamIcon"
|
import VueFolderTeamIcon from './Icons/VueFolderTeamIcon'
|
||||||
import VueFolderIcon from "./Icons/VueFolderIcon"
|
import VueFolderIcon from './Icons/VueFolderIcon'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'FolderIcon',
|
name: 'FolderIcon',
|
||||||
props: [
|
props: ['item'],
|
||||||
'item',
|
components: {
|
||||||
],
|
VueFolderTeamIcon,
|
||||||
components: {
|
VueFolderIcon,
|
||||||
VueFolderTeamIcon,
|
},
|
||||||
VueFolderIcon,
|
}
|
||||||
},
|
</script>
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|||||||
@@ -1,22 +1,36 @@
|
|||||||
<template>
|
<template>
|
||||||
<svg class="alphabet-icon" fill="none" stroke="currentColor" stroke-width="2" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round" :width="`${size}px`" :height="`${size}px`" viewBox="-2 0 15 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
<svg
|
||||||
|
class="alphabet-icon"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
fill-rule="evenodd"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
:width="`${size}px`"
|
||||||
|
:height="`${size}px`"
|
||||||
|
viewBox="-2 0 15 15"
|
||||||
|
version="1.1"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
>
|
||||||
<polyline id="Path" points="11.1999993 13.1999991 5.59999967 0.199999094 0 13.1999991 5.59999967 0.199999094"></polyline>
|
<polyline id="Path" points="11.1999993 13.1999991 5.59999967 0.199999094 0 13.1999991 5.59999967 0.199999094"></polyline>
|
||||||
<line x1="2.25" y1="8" x2="8.75" y2="8" id="Line-2"></line>
|
<line x1="2.25" y1="8" x2="8.75" y2="8" id="Line-2"></line>
|
||||||
</svg>
|
</svg>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
props: ['size']
|
props: ['size'],
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
.alphabet-icon {
|
||||||
.alphabet-icon {
|
polyline,
|
||||||
|
line,
|
||||||
polyline, line, g {
|
g {
|
||||||
color: inherit;
|
color: inherit;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,23 +1,39 @@
|
|||||||
<template>
|
<template>
|
||||||
<svg class="preview-list-icon" fill="none" stroke="currentColor" stroke-width="1.5" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round" width="15px" height="15px" viewBox="0 0 17 12" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
<svg
|
||||||
<path d="M14.2729998,10.7729998 C15.6774712,10.0073227 16.384111,8.38688297 15.9895447,6.83668332 C15.5949785,5.28648367 14.1996249,4.20105605 12.5999998,4.19999993 L11.7179998,4.19999993 C11.1377566,1.9556703 9.23470173,0.300843012 6.93154234,0.0378706728 C4.62838295,-0.225101666 2.40127934,0.958148431 1.33005562,3.01391529 C0.258831904,5.06968215 0.564955244,7.57295196 2.09999996,9.30999984" id="Path"></path>
|
class="preview-list-icon"
|
||||||
<line x1="8.5" y1="7" x2="8.5" y2="12" id="Path"></line>
|
fill="none"
|
||||||
<line x1="6" y1="9.5" x2="11" y2="9.5" id="Path"></line>
|
stroke="currentColor"
|
||||||
</svg>
|
stroke-width="1.5"
|
||||||
|
fill-rule="evenodd"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
width="15px"
|
||||||
|
height="15px"
|
||||||
|
viewBox="0 0 17 12"
|
||||||
|
version="1.1"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M14.2729998,10.7729998 C15.6774712,10.0073227 16.384111,8.38688297 15.9895447,6.83668332 C15.5949785,5.28648367 14.1996249,4.20105605 12.5999998,4.19999993 L11.7179998,4.19999993 C11.1377566,1.9556703 9.23470173,0.300843012 6.93154234,0.0378706728 C4.62838295,-0.225101666 2.40127934,0.958148431 1.33005562,3.01391529 C0.258831904,5.06968215 0.564955244,7.57295196 2.09999996,9.30999984"
|
||||||
|
id="Path"
|
||||||
|
></path>
|
||||||
|
<line x1="8.5" y1="7" x2="8.5" y2="12" id="Path"></line>
|
||||||
|
<line x1="6" y1="9.5" x2="11" y2="9.5" id="Path"></line>
|
||||||
|
</svg>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: "CloudPlusIcon",
|
name: 'CloudPlusIcon',
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
.preview-list-icon {
|
||||||
.preview-list-icon {
|
path,
|
||||||
|
line {
|
||||||
path, line {
|
color: inherit;
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,25 +1,40 @@
|
|||||||
<template>
|
<template>
|
||||||
<svg class="preview-list-icon" fill="none" stroke="currentColor" stroke-width="1.5" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round" :width="`${size}px`" :height="`${size}px`" viewBox="0 -2 14 17" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
<svg
|
||||||
<path d="M0,10.6420028 C0,8.60583431 0,5.5515816 0,1.47924466 C0,0.662280392 0.633305625,0 1.4145277,0 L4.95084696,0 L6.36537467,2.21886699 L12.7307493,2.21886699 C13.5119714,2.21886699 14.145277,2.88114738 14.145277,3.69811164 C14.145277,7.76603445 14.145277,7.76603445 14.145277,11.8339573 C14.145277,12.6509215 13.5119714,13.3132019 12.7307493,13.3132019 C11.9928651,13.3132019 12.1671651,13.3132019 11.798223,13.3132019" id="Path"></path>
|
class="preview-list-icon"
|
||||||
<polyline id="Path-Copy-8" points="9.49893123 9.53496452 6.74946561 6.60112928 4 9.53496452"></polyline>
|
fill="none"
|
||||||
<line x1="6.74946561" y1="6.60112928" x2="6.74946561" y2="13.2022586" id="Path-Copy-7"></line>
|
stroke="currentColor"
|
||||||
</svg>
|
stroke-width="1.5"
|
||||||
|
fill-rule="evenodd"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
:width="`${size}px`"
|
||||||
|
:height="`${size}px`"
|
||||||
|
viewBox="0 -2 14 17"
|
||||||
|
version="1.1"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M0,10.6420028 C0,8.60583431 0,5.5515816 0,1.47924466 C0,0.662280392 0.633305625,0 1.4145277,0 L4.95084696,0 L6.36537467,2.21886699 L12.7307493,2.21886699 C13.5119714,2.21886699 14.145277,2.88114738 14.145277,3.69811164 C14.145277,7.76603445 14.145277,7.76603445 14.145277,11.8339573 C14.145277,12.6509215 13.5119714,13.3132019 12.7307493,13.3132019 C11.9928651,13.3132019 12.1671651,13.3132019 11.798223,13.3132019"
|
||||||
|
id="Path"
|
||||||
|
></path>
|
||||||
|
<polyline id="Path-Copy-8" points="9.49893123 9.53496452 6.74946561 6.60112928 4 9.53496452"></polyline>
|
||||||
|
<line x1="6.74946561" y1="6.60112928" x2="6.74946561" y2="13.2022586" id="Path-Copy-7"></line>
|
||||||
|
</svg>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
props: ['size']
|
props: ['size'],
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
.preview-list-icon {
|
||||||
.preview-list-icon {
|
path,
|
||||||
|
line,
|
||||||
path,
|
polyline {
|
||||||
line,
|
color: inherit;
|
||||||
polyline {
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,25 +1,38 @@
|
|||||||
<template>
|
<template>
|
||||||
<svg class="preview-list-icon" fill="none" stroke="currentColor" stroke-width="1.5" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round" width="15px" height="15px" viewBox="0 0 20 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
<svg
|
||||||
<rect x="9.77777778" y="0" width="6.22222222" height="6.22222222"></rect>
|
class="preview-list-icon"
|
||||||
<rect x="9.77777778" y="9.77777778" width="6.22222222" height="6.22222222"></rect>
|
fill="none"
|
||||||
<line x1="0" y1="2" x2="6" y2="2"></line>
|
stroke="currentColor"
|
||||||
<line x1="0" y1="8" x2="6" y2="8"></line>
|
stroke-width="1.5"
|
||||||
<line x1="0" y1="14" x2="6" y2="14"></line>
|
fill-rule="evenodd"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
width="15px"
|
||||||
|
height="15px"
|
||||||
|
viewBox="0 0 20 16"
|
||||||
|
version="1.1"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
>
|
||||||
|
<rect x="9.77777778" y="0" width="6.22222222" height="6.22222222"></rect>
|
||||||
|
<rect x="9.77777778" y="9.77777778" width="6.22222222" height="6.22222222"></rect>
|
||||||
|
<line x1="0" y1="2" x2="6" y2="2"></line>
|
||||||
|
<line x1="0" y1="8" x2="6" y2="8"></line>
|
||||||
|
<line x1="0" y1="14" x2="6" y2="14"></line>
|
||||||
</svg>
|
</svg>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: "SortingIcon",
|
name: 'SortingIcon',
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
.preview-list-icon {
|
||||||
.preview-list-icon {
|
rect,
|
||||||
|
line {
|
||||||
rect, line {
|
color: inherit;
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,29 +1,29 @@
|
|||||||
<template>
|
<template>
|
||||||
<svg width="53px" height="52px" viewBox="0 0 53 39" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
<svg width="53px" height="52px" viewBox="0 0 53 39" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
<path d="M48.03125,6.5 L29.790833,6.5 C28.7431613,6.5 27.7373076,6.08896217 26.9894703,5.35523504 L22.6980297,1.14476496 C21.9501924,0.41103783 20.9443387,-6.36543387e-16 19.896667,0 L4.96875,0 L4.96875,0 C2.22455078,0 0,2.18257812 0,4.875 L0,34.125 C0,36.8174219 2.22455078,39 4.96875,39 L48.03125,39 C50.7754492,39 53,36.8174219 53,34.125 L53,11.375 C53,8.68257813 50.7754492,6.5 48.03125,6.5 Z"
|
<path
|
||||||
class="svg-color-theme"
|
d="M48.03125,6.5 L29.790833,6.5 C28.7431613,6.5 27.7373076,6.08896217 26.9894703,5.35523504 L22.6980297,1.14476496 C21.9501924,0.41103783 20.9443387,-6.36543387e-16 19.896667,0 L4.96875,0 L4.96875,0 C2.22455078,0 0,2.18257812 0,4.875 L0,34.125 C0,36.8174219 2.22455078,39 4.96875,39 L48.03125,39 C50.7754492,39 53,36.8174219 53,34.125 L53,11.375 C53,8.68257813 50.7754492,6.5 48.03125,6.5 Z"
|
||||||
stroke="none"
|
class="svg-color-theme"
|
||||||
stroke-width="0">
|
stroke="none"
|
||||||
|
stroke-width="0"
|
||||||
</path>
|
></path>
|
||||||
<path d="M48.03125,6.5 L29.790833,6.5 C28.7431613,6.5 27.7373076,6.08896217 26.9894703,5.35523504 L22.6980297,1.14476496 C21.9501924,0.41103783 20.9443387,-6.36543387e-16 19.896667,0 L4.96875,0 L4.96875,0 C2.22455078,0 0,2.18257812 0,4.875 L0,34.125 C0,36.8174219 2.22455078,39 4.96875,39 L48.03125,39 C50.7754492,39 53,36.8174219 53,34.125 L53,11.375 C53,8.68257813 50.7754492,6.5 48.03125,6.5 Z"
|
<path
|
||||||
fill="black"
|
d="M48.03125,6.5 L29.790833,6.5 C28.7431613,6.5 27.7373076,6.08896217 26.9894703,5.35523504 L22.6980297,1.14476496 C21.9501924,0.41103783 20.9443387,-6.36543387e-16 19.896667,0 L4.96875,0 L4.96875,0 C2.22455078,0 0,2.18257812 0,4.875 L0,34.125 C0,36.8174219 2.22455078,39 4.96875,39 L48.03125,39 C50.7754492,39 53,36.8174219 53,34.125 L53,11.375 C53,8.68257813 50.7754492,6.5 48.03125,6.5 Z"
|
||||||
fill-opacity="0.2"
|
fill="black"
|
||||||
stroke="none"
|
fill-opacity="0.2"
|
||||||
stroke-width="0">
|
stroke="none"
|
||||||
|
stroke-width="0"
|
||||||
</path>
|
></path>
|
||||||
<path d="M48.03125,12.75 C49.0609313,12.75 49.9941504,13.1577174 50.6692739,13.8201027 C51.3356976,14.4739525 51.75,15.3766531 51.75,16.375 L51.75,16.375 L51.75,34.125 C51.75,35.1233469 51.3356976,36.0260475 50.6692739,36.6798973 C49.9941504,37.3422826 49.0609313,37.75 48.03125,37.75 L48.03125,37.75 L4.96875,37.75 C3.93906868,37.75 3.00584961,37.3422826 2.33072613,36.6798973 C1.66430239,36.0260475 1.25,35.1233469 1.25,34.125 L1.25,34.125 L1.25,16.375 C1.25,15.3766531 1.66430239,14.4739525 2.33072613,13.8201027 C3.00584961,13.1577174 3.93906868,12.75 4.96875,12.75 L4.96875,12.75 Z"
|
<path
|
||||||
stroke-width="2"
|
d="M48.03125,12.75 C49.0609313,12.75 49.9941504,13.1577174 50.6692739,13.8201027 C51.3356976,14.4739525 51.75,15.3766531 51.75,16.375 L51.75,16.375 L51.75,34.125 C51.75,35.1233469 51.3356976,36.0260475 50.6692739,36.6798973 C49.9941504,37.3422826 49.0609313,37.75 48.03125,37.75 L48.03125,37.75 L4.96875,37.75 C3.93906868,37.75 3.00584961,37.3422826 2.33072613,36.6798973 C1.66430239,36.0260475 1.25,35.1233469 1.25,34.125 L1.25,34.125 L1.25,16.375 C1.25,15.3766531 1.66430239,14.4739525 2.33072613,13.8201027 C3.00584961,13.1577174 3.93906868,12.75 4.96875,12.75 L4.96875,12.75 Z"
|
||||||
class="svg-color-theme"
|
stroke-width="2"
|
||||||
fill="green">
|
class="svg-color-theme"
|
||||||
|
fill="green"
|
||||||
</path>
|
></path>
|
||||||
</svg>
|
</svg>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'VueFolderIcon',
|
name: 'VueFolderIcon',
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,40 +1,52 @@
|
|||||||
<template>
|
<template>
|
||||||
<svg viewBox="0 0 53 39" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
<svg viewBox="0 0 53 39" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<g id="V2" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
<g id="V2" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
<g id="team-folder">
|
||||||
<g id="team-folder">
|
<path
|
||||||
<path d="M48.03125,6.5 L29.790833,6.5 C28.7431613,6.5 27.7373076,6.08896217 26.9894703,5.35523504 L22.6980297,1.14476496 C21.9501924,0.41103783 20.9443387,-6.36543387e-16 19.896667,0 L4.96875,0 L4.96875,0 C2.22455078,0 0,2.18257812 0,4.875 L0,34.125 C0,36.8174219 2.22455078,39 4.96875,39 L48.03125,39 C50.7754492,39 53,36.8174219 53,34.125 L53,11.375 C53,8.68257813 50.7754492,6.5 48.03125,6.5 Z"
|
d="M48.03125,6.5 L29.790833,6.5 C28.7431613,6.5 27.7373076,6.08896217 26.9894703,5.35523504 L22.6980297,1.14476496 C21.9501924,0.41103783 20.9443387,-6.36543387e-16 19.896667,0 L4.96875,0 L4.96875,0 C2.22455078,0 0,2.18257812 0,4.875 L0,34.125 C0,36.8174219 2.22455078,39 4.96875,39 L48.03125,39 C50.7754492,39 53,36.8174219 53,34.125 L53,11.375 C53,8.68257813 50.7754492,6.5 48.03125,6.5 Z"
|
||||||
class="svg-color-theme"
|
class="svg-color-theme"
|
||||||
stroke="none"
|
stroke="none"
|
||||||
stroke-width="0">
|
stroke-width="0"
|
||||||
|
></path>
|
||||||
</path>
|
<path
|
||||||
<path d="M48.03125,6.5 L29.790833,6.5 C28.7431613,6.5 27.7373076,6.08896217 26.9894703,5.35523504 L22.6980297,1.14476496 C21.9501924,0.41103783 20.9443387,-6.36543387e-16 19.896667,0 L4.96875,0 L4.96875,0 C2.22455078,0 0,2.18257812 0,4.875 L0,34.125 C0,36.8174219 2.22455078,39 4.96875,39 L48.03125,39 C50.7754492,39 53,36.8174219 53,34.125 L53,11.375 C53,8.68257813 50.7754492,6.5 48.03125,6.5 Z"
|
d="M48.03125,6.5 L29.790833,6.5 C28.7431613,6.5 27.7373076,6.08896217 26.9894703,5.35523504 L22.6980297,1.14476496 C21.9501924,0.41103783 20.9443387,-6.36543387e-16 19.896667,0 L4.96875,0 L4.96875,0 C2.22455078,0 0,2.18257812 0,4.875 L0,34.125 C0,36.8174219 2.22455078,39 4.96875,39 L48.03125,39 C50.7754492,39 53,36.8174219 53,34.125 L53,11.375 C53,8.68257813 50.7754492,6.5 48.03125,6.5 Z"
|
||||||
fill="black"
|
fill="black"
|
||||||
fill-opacity="0.2"
|
fill-opacity="0.2"
|
||||||
stroke="none"
|
stroke="none"
|
||||||
stroke-width="0">
|
stroke-width="0"
|
||||||
|
></path>
|
||||||
</path>
|
<path
|
||||||
<path d="M48.03125,12.75 C49.0609313,12.75 49.9941504,13.1577174 50.6692739,13.8201027 C51.3356976,14.4739525 51.75,15.3766531 51.75,16.375 L51.75,16.375 L51.75,34.125 C51.75,35.1233469 51.3356976,36.0260475 50.6692739,36.6798973 C49.9941504,37.3422826 49.0609313,37.75 48.03125,37.75 L48.03125,37.75 L4.96875,37.75 C3.93906868,37.75 3.00584961,37.3422826 2.33072613,36.6798973 C1.66430239,36.0260475 1.25,35.1233469 1.25,34.125 L1.25,34.125 L1.25,16.375 C1.25,15.3766531 1.66430239,14.4739525 2.33072613,13.8201027 C3.00584961,13.1577174 3.93906868,12.75 4.96875,12.75 L4.96875,12.75 Z"
|
d="M48.03125,12.75 C49.0609313,12.75 49.9941504,13.1577174 50.6692739,13.8201027 C51.3356976,14.4739525 51.75,15.3766531 51.75,16.375 L51.75,16.375 L51.75,34.125 C51.75,35.1233469 51.3356976,36.0260475 50.6692739,36.6798973 C49.9941504,37.3422826 49.0609313,37.75 48.03125,37.75 L48.03125,37.75 L4.96875,37.75 C3.93906868,37.75 3.00584961,37.3422826 2.33072613,36.6798973 C1.66430239,36.0260475 1.25,35.1233469 1.25,34.125 L1.25,34.125 L1.25,16.375 C1.25,15.3766531 1.66430239,14.4739525 2.33072613,13.8201027 C3.00584961,13.1577174 3.93906868,12.75 4.96875,12.75 L4.96875,12.75 Z"
|
||||||
stroke-width="2"
|
stroke-width="2"
|
||||||
class="svg-color-theme"
|
class="svg-color-theme"
|
||||||
fill="green">
|
fill="green"
|
||||||
|
></path>
|
||||||
</path>
|
<g
|
||||||
<g id="Icon" transform="translate(8.000000, 20.000000)" class="svg-stroke-theme-darken" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.3" stroke="black" stroke-opacity="0.25">
|
id="Icon"
|
||||||
<path d="M9.59999943,10.7999994 L9.59999943,9.59999943 C9.59999943,8.27451611 8.52548289,7.19999957 7.19999957,7.19999957 L2.39999986,7.19999957 C1.07451654,7.19999957 0,8.27451611 0,9.59999943 L0,10.7999994"></path>
|
transform="translate(8.000000, 20.000000)"
|
||||||
<circle cx="4.79999971" cy="2.39999986" r="2.39999986"></circle>
|
class="svg-stroke-theme-darken"
|
||||||
<path d="M13.1999992,10.7999994 L13.1999992,9.59999943 C13.1991834,8.50627014 12.4589985,7.55143166 11.3999993,7.27799957"></path>
|
stroke-linecap="round"
|
||||||
<path d="M8.99999946,0.0779999954 C10.0619483,0.349901852 10.8047053,1.30679461 10.8047053,2.40299986 C10.8047053,3.4992051 10.0619483,4.45609786 8.99999946,4.72799972"></path>
|
stroke-linejoin="round"
|
||||||
</g>
|
stroke-width="1.3"
|
||||||
</g>
|
stroke="black"
|
||||||
</g>
|
stroke-opacity="0.25"
|
||||||
</svg>
|
>
|
||||||
|
<path
|
||||||
|
d="M9.59999943,10.7999994 L9.59999943,9.59999943 C9.59999943,8.27451611 8.52548289,7.19999957 7.19999957,7.19999957 L2.39999986,7.19999957 C1.07451654,7.19999957 0,8.27451611 0,9.59999943 L0,10.7999994"
|
||||||
|
></path>
|
||||||
|
<circle cx="4.79999971" cy="2.39999986" r="2.39999986"></circle>
|
||||||
|
<path d="M13.1999992,10.7999994 L13.1999992,9.59999943 C13.1991834,8.50627014 12.4589985,7.55143166 11.3999993,7.27799957"></path>
|
||||||
|
<path
|
||||||
|
d="M8.99999946,0.0779999954 C10.0619483,0.349901852 10.8047053,1.30679461 10.8047053,2.40299986 C10.8047053,3.4992051 10.0619483,4.45609786 8.99999946,4.72799972"
|
||||||
|
></path>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'VueFolderTeamIcon',
|
name: 'VueFolderTeamIcon',
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
<b>{{ clipboard.metadata.ColorSpace }}</b>
|
<b>{{ clipboard.metadata.ColorSpace }}</b>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<!--TODO: Colour profile:sRGB IEC61966-2.1-->
|
<!--TODO: Colour profile:sRGB IEC61966-2.1-->
|
||||||
|
|
||||||
<li v-if="clipboard.metadata.Make">
|
<li v-if="clipboard.metadata.Make">
|
||||||
<span>{{ $t('file_detail_meta.make') }}</span>
|
<span>{{ $t('file_detail_meta.make') }}</span>
|
||||||
@@ -68,42 +68,41 @@
|
|||||||
<b>{{ clipboard.metadata.COMPUTED.CCDWidth }}</b>
|
<b>{{ clipboard.metadata.COMPUTED.CCDWidth }}</b>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li v-if="clipboard.metadata.GPSLongitude">
|
<li v-if="clipboard.metadata.GPSLongitude">
|
||||||
<span>{{ $t('file_detail_meta.longitude') }}</span>
|
<span>{{ $t('file_detail_meta.longitude') }}</span>
|
||||||
<b>{{ formatGps(clipboard.metadata.GPSLongitude, clipboard.metadata.GPSLongitudeRef) }}</b>
|
<b>{{ formatGps(clipboard.metadata.GPSLongitude, clipboard.metadata.GPSLongitudeRef) }}</b>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li v-if="clipboard.metadata.GPSLatitude">
|
<li v-if="clipboard.metadata.GPSLatitude">
|
||||||
<span>{{ $t('file_detail_meta.latitude') }}</span>
|
<span>{{ $t('file_detail_meta.latitude') }}</span>
|
||||||
<b>{{ formatGps(clipboard.metadata.GPSLatitude, clipboard.metadata.GPSLatitudeRef) }}</b>
|
<b>{{ formatGps(clipboard.metadata.GPSLatitude, clipboard.metadata.GPSLatitudeRef) }}</b>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {mapGetters} from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
import {split} from 'lodash'
|
import { split } from 'lodash'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ImageMetaData',
|
name: 'ImageMetaData',
|
||||||
computed: {
|
computed: {
|
||||||
clipboard() {
|
clipboard() {
|
||||||
return this.$store.getters.clipboard[0].data.relationships
|
return this.$store.getters.clipboard[0].data.relationships
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
formatGps(location, ref) {
|
formatGps(location, ref) {
|
||||||
let data = []
|
let data = []
|
||||||
|
|
||||||
location.forEach(location => {
|
location.forEach((location) => {
|
||||||
data.push(split(location, '/', 2)[0])
|
data.push(split(location, '/', 2)[0])
|
||||||
})
|
})
|
||||||
|
|
||||||
return `${data[0]}° ${data[1]}' ${data[2].substr(0, 4) / 100}" ${ref} `
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
|
return `${data[0]}° ${data[1]}' ${data[2].substr(0, 4) / 100}" ${ref} `
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -112,33 +111,34 @@ export default {
|
|||||||
@import '../../../sass/vuefilemanager/mixins';
|
@import '../../../sass/vuefilemanager/mixins';
|
||||||
|
|
||||||
.meta-data-list {
|
.meta-data-list {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
|
|
||||||
li {
|
li {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding: 9px 0;
|
padding: 9px 0;
|
||||||
border-bottom: 1px solid $light_mode_border;
|
border-bottom: 1px solid $light_mode_border;
|
||||||
|
|
||||||
b, span {
|
b,
|
||||||
@include font-size(14);
|
span {
|
||||||
color: $text;
|
@include font-size(14);
|
||||||
}
|
color: $text;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark {
|
.dark {
|
||||||
|
.meta-data-list {
|
||||||
|
li {
|
||||||
|
border-color: $dark_mode_border_color;
|
||||||
|
|
||||||
.meta-data-list {
|
b,
|
||||||
li {
|
span {
|
||||||
border-color: $dark_mode_border_color;
|
color: $dark_mode_text_primary !important;
|
||||||
|
}
|
||||||
b, span {
|
}
|
||||||
color: $dark_mode_text_primary !important;
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,108 +1,81 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="2xl:w-104 w-96 px-2.5 overflow-y-auto overflow-x-hidden h-screen lg:block hidden">
|
<div class="hidden h-screen w-96 overflow-y-auto overflow-x-hidden px-2.5 lg:block 2xl:w-104">
|
||||||
<!--Is empty clipboard-->
|
<!--Is empty clipboard-->
|
||||||
<div v-if="isEmpty" class="flex items-center justify-center h-full">
|
<div v-if="isEmpty" class="flex h-full items-center justify-center">
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<eye-off-icon size="28" class="vue-feather text-gray-400 inline-block mb-3" />
|
<eye-off-icon size="28" class="vue-feather mb-3 inline-block text-gray-400" />
|
||||||
<small class="text-sm block text-gray-400">
|
<small class="block text-sm text-gray-400">
|
||||||
{{ $t('messages.nothing_to_preview') }}
|
{{ $t('messages.nothing_to_preview') }}
|
||||||
</small>
|
</small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!--Multiple item selection-->
|
<!--Multiple item selection-->
|
||||||
<TitlePreview
|
<TitlePreview
|
||||||
v-if="! isSingleFile && !isEmpty"
|
v-if="!isSingleFile && !isEmpty"
|
||||||
class="mb-6"
|
class="mb-6"
|
||||||
icon="check-square"
|
icon="check-square"
|
||||||
:title="$t('file_detail.selected_multiple')"
|
:title="$t('file_detail.selected_multiple')"
|
||||||
:subtitle="this.clipboard.length + ' ' + $tc('file_detail.items', this.clipboard.length)"
|
:subtitle="this.clipboard.length + ' ' + $tc('file_detail.items', this.clipboard.length)"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!--Single file preview-->
|
<!--Single file preview-->
|
||||||
<div v-if="isSingleFile && !isEmpty">
|
<div v-if="isSingleFile && !isEmpty">
|
||||||
<FilePreviewDetail />
|
<FilePreviewDetail />
|
||||||
|
|
||||||
<TitlePreview
|
<TitlePreview class="mb-6" :icon="clipboard[0].data.type" :title="clipboard[0].data.attributes.name" :subtitle="clipboard[0].data.attributes.mimetype" />
|
||||||
class="mb-6"
|
|
||||||
:icon="clipboard[0].data.type"
|
|
||||||
:title="clipboard[0].data.attributes.name"
|
|
||||||
:subtitle="clipboard[0].data.attributes.mimetype"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!--Filesize-->
|
<!--Filesize-->
|
||||||
<ListInfoItem
|
<ListInfoItem v-if="singleFile.data.attributes.filesize" :title="$t('file_detail.size')" :content="singleFile.data.attributes.filesize" />
|
||||||
v-if="singleFile.data.attributes.filesize"
|
|
||||||
:title="$t('file_detail.size')"
|
|
||||||
:content="singleFile.data.attributes.filesize"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!--Created At-->
|
<!--Created At-->
|
||||||
<ListInfoItem
|
<ListInfoItem :title="$t('file_detail.created_at')" :content="singleFile.data.attributes.created_at" />
|
||||||
:title="$t('file_detail.created_at')"
|
|
||||||
:content="singleFile.data.attributes.created_at"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!--Location-->
|
<!--Location-->
|
||||||
<ListInfoItem
|
<ListInfoItem v-if="$checkPermission(['master'])" :title="$t('file_detail.where')">
|
||||||
v-if="$checkPermission(['master'])"
|
<div @click="$moveFileOrFolder(singleFile)" class="flex cursor-pointer items-center">
|
||||||
:title="$t('file_detail.where')"
|
<span class="inline-block text-sm font-bold">
|
||||||
>
|
{{ singleFile.data.relationships.parent ? singleFile.data.relationships.parent.data.attributes.name : $t('locations.home') }}
|
||||||
<div @click="$moveFileOrFolder(singleFile)" class="flex items-center cursor-pointer">
|
</span>
|
||||||
<span class="inline-block font-bold text-sm">
|
|
||||||
{{ singleFile.data.relationships.parent ? singleFile.data.relationships.parent.data.attributes.name : $t('locations.home') }}
|
|
||||||
</span>
|
|
||||||
<Edit2Icon size="10" class="ml-2" />
|
<Edit2Icon size="10" class="ml-2" />
|
||||||
</div>
|
</div>
|
||||||
</ListInfoItem>
|
</ListInfoItem>
|
||||||
|
|
||||||
<!--Team-->
|
<!--Team-->
|
||||||
<ListInfoItem
|
<ListInfoItem v-if="singleFile.data.attributes.isTeamFolder" :title="$t('Shared with the Team')">
|
||||||
v-if="singleFile.data.attributes.isTeamFolder"
|
<div class="flex cursor-pointer items-center" @click="$updateTeamFolder(singleFile)">
|
||||||
:title="$t('Shared with the Team')"
|
|
||||||
>
|
|
||||||
<div class="flex items-center cursor-pointer" @click="$updateTeamFolder(singleFile)">
|
|
||||||
<TeamMembersPreview :folder="singleFile" :avatar-size="32" />
|
<TeamMembersPreview :folder="singleFile" :avatar-size="32" />
|
||||||
<Edit2Icon size="10" class="ml-2" />
|
<Edit2Icon size="10" class="ml-2" />
|
||||||
</div>
|
</div>
|
||||||
</ListInfoItem>
|
</ListInfoItem>
|
||||||
|
|
||||||
<!--Shared-->
|
<!--Shared-->
|
||||||
<ListInfoItem
|
<ListInfoItem v-if="$checkPermission('master') && singleFile.data.relationships.shared" :title="$t('file_detail.shared')">
|
||||||
v-if="$checkPermission('master') && singleFile.data.relationships.shared"
|
<div @click="$shareFileOrFolder(singleFile)" class="mb-2 flex cursor-pointer items-center">
|
||||||
:title="$t('file_detail.shared')"
|
<span class="inline-block text-sm font-bold">
|
||||||
>
|
{{ sharedInfo }}
|
||||||
<div @click="$shareFileOrFolder(singleFile)" class="flex items-center cursor-pointer mb-2">
|
</span>
|
||||||
<span class="inline-block font-bold text-sm">
|
|
||||||
{{ sharedInfo }}
|
|
||||||
</span>
|
|
||||||
<Edit2Icon size="10" class="ml-2" />
|
<Edit2Icon size="10" class="ml-2" />
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center w-full">
|
<div class="flex w-full items-center">
|
||||||
<lock-icon v-if="isLocked" @click="$shareFileOrFolder(singleFile)" size="17" class="hover-text-theme vue-feather cursor-pointer"/>
|
<lock-icon v-if="isLocked" @click="$shareFileOrFolder(singleFile)" size="17" class="hover-text-theme vue-feather cursor-pointer" />
|
||||||
<unlock-icon v-if="! isLocked" @click="$shareFileOrFolder(singleFile)" size="17" class="hover-text-theme vue-feather cursor-pointer"/>
|
<unlock-icon v-if="!isLocked" @click="$shareFileOrFolder(singleFile)" size="17" class="hover-text-theme vue-feather cursor-pointer" />
|
||||||
<CopyShareLink :item="singleFile" size="small" class="w-full pl-2.5"/>
|
<CopyShareLink :item="singleFile" size="small" class="w-full pl-2.5" />
|
||||||
</div>
|
</div>
|
||||||
</ListInfoItem>
|
</ListInfoItem>
|
||||||
|
|
||||||
<!--Author-->
|
<!--Author-->
|
||||||
<ListInfoItem
|
<ListInfoItem v-if="canShowAuthor" :title="$t('Author')">
|
||||||
v-if="canShowAuthor"
|
<div class="mt-1.5 flex items-center">
|
||||||
:title="$t('Author')"
|
<MemberAvatar :size="32" :member="singleFile.data.relationships.owner" />
|
||||||
>
|
<span class="font-sm ml-3 block font-bold">
|
||||||
<div class="flex items-center mt-1.5">
|
{{ singleFile.data.relationships.owner.data.attributes.name }}
|
||||||
<MemberAvatar :size="32" :member="singleFile.data.relationships.owner" />
|
</span>
|
||||||
<span class="ml-3 block font-bold font-sm">
|
|
||||||
{{ singleFile.data.relationships.owner.data.attributes.name }}
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</ListInfoItem>
|
</ListInfoItem>
|
||||||
|
|
||||||
<!--Metadata-->
|
<!--Metadata-->
|
||||||
<ListInfoItem
|
<ListInfoItem v-if="canShowMetaData" :title="$t('file_detail_meta.meta_data')">
|
||||||
v-if="canShowMetaData"
|
|
||||||
:title="$t('file_detail_meta.meta_data')"
|
|
||||||
>
|
|
||||||
<ImageMetaData />
|
<ImageMetaData />
|
||||||
</ListInfoItem>
|
</ListInfoItem>
|
||||||
</div>
|
</div>
|
||||||
@@ -110,64 +83,62 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import FilePreviewDetail from "../Others/FilePreviewDetail";
|
import FilePreviewDetail from '../Others/FilePreviewDetail'
|
||||||
import CopyShareLink from "../Others/Forms/CopyShareLink";
|
import CopyShareLink from '../Others/Forms/CopyShareLink'
|
||||||
import {Edit2Icon, LockIcon, UnlockIcon, EyeOffIcon} from 'vue-feather-icons'
|
import { Edit2Icon, LockIcon, UnlockIcon, EyeOffIcon } from 'vue-feather-icons'
|
||||||
import ImageMetaData from "./ImageMetaData";
|
import ImageMetaData from './ImageMetaData'
|
||||||
import TitlePreview from "./TitlePreview";
|
import TitlePreview from './TitlePreview'
|
||||||
import TeamMembersPreview from "../Teams/Components/TeamMembersPreview"
|
import TeamMembersPreview from '../Teams/Components/TeamMembersPreview'
|
||||||
import ListInfoItem from "../Others/ListInfoItem";
|
import ListInfoItem from '../Others/ListInfoItem'
|
||||||
import MemberAvatar from "./MemberAvatar"
|
import MemberAvatar from './MemberAvatar'
|
||||||
import {mapGetters} from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'InfoSidebar',
|
name: 'InfoSidebar',
|
||||||
components: {
|
components: {
|
||||||
TeamMembersPreview,
|
TeamMembersPreview,
|
||||||
FilePreviewDetail,
|
FilePreviewDetail,
|
||||||
ImageMetaData,
|
ImageMetaData,
|
||||||
CopyShareLink,
|
CopyShareLink,
|
||||||
MemberAvatar,
|
MemberAvatar,
|
||||||
TitlePreview,
|
TitlePreview,
|
||||||
ListInfoItem,
|
ListInfoItem,
|
||||||
UnlockIcon,
|
UnlockIcon,
|
||||||
EyeOffIcon,
|
EyeOffIcon,
|
||||||
Edit2Icon,
|
Edit2Icon,
|
||||||
LockIcon,
|
LockIcon,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters([
|
...mapGetters(['permissionOptions', 'clipboard', 'user']),
|
||||||
'permissionOptions',
|
isEmpty() {
|
||||||
'clipboard',
|
return this.clipboard.length === 0
|
||||||
'user',
|
},
|
||||||
]),
|
isSingleFile() {
|
||||||
isEmpty() {
|
return this.clipboard.length === 1
|
||||||
return this.clipboard.length === 0
|
},
|
||||||
},
|
singleFile() {
|
||||||
isSingleFile() {
|
return this.clipboard[0]
|
||||||
return this.clipboard.length === 1
|
},
|
||||||
},
|
canShowMetaData() {
|
||||||
singleFile() {
|
return this.clipboard[0].data.attributes.metadata && this.clipboard[0].data.attributes.metadata.ExifImageWidth
|
||||||
return this.clipboard[0]
|
},
|
||||||
},
|
isLocked() {
|
||||||
canShowMetaData() {
|
return this.clipboard[0].data.relationships.shared.protected
|
||||||
return this.clipboard[0].data.attributes.metadata && this.clipboard[0].data.attributes.metadata.ExifImageWidth
|
},
|
||||||
},
|
sharedInfo() {
|
||||||
isLocked() {
|
let title = this.permissionOptions.find((option) => {
|
||||||
return this.clipboard[0].data.relationships.shared.protected
|
return option.value === this.clipboard[0].data.relationships.shared.permission
|
||||||
},
|
})
|
||||||
sharedInfo() {
|
|
||||||
let title = this.permissionOptions.find(option => {
|
|
||||||
return option.value === this.clipboard[0].data.relationships.shared.permission
|
|
||||||
})
|
|
||||||
|
|
||||||
return title ? this.$t(title.label) : this.$t('shared.can_download')
|
return title ? this.$t(title.label) : this.$t('shared.can_download')
|
||||||
},
|
},
|
||||||
canShowAuthor() {
|
canShowAuthor() {
|
||||||
return this.$isThisRoute(this.$route, ['SharedWithMe', 'TeamFolders'])
|
return (
|
||||||
&& this.clipboard[0].data.type !== 'folder'
|
this.$isThisRoute(this.$route, ['SharedWithMe', 'TeamFolders']) &&
|
||||||
&& this.user.data.id !== this.clipboard[0].data.relationships.owner.data.id
|
this.clipboard[0].data.type !== 'folder' &&
|
||||||
},
|
this.user.data.id !== this.clipboard[0].data.relationships.owner.data.id
|
||||||
},
|
)
|
||||||
}
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,221 +1,209 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
:class="{'dark:bg-dark-foreground bg-light-background': isClicked}"
|
:class="{ 'bg-light-background dark:bg-dark-foreground': isClicked }"
|
||||||
class="flex flex-wrap items-center justify-center relative z-0 text-center lg:h-60 sm:h-56 h-48 px-1 pt-2 rounded-lg select-none border-2 border-transparent border-dashed dark:hover:bg-dark-foreground lg:hover:bg-light-background"
|
class="relative z-0 flex h-48 select-none flex-wrap items-center justify-center rounded-lg border-2 border-dashed border-transparent px-1 pt-2 text-center dark:hover:bg-dark-foreground sm:h-56 lg:h-60 lg:hover:bg-light-background"
|
||||||
:draggable="canDrag"
|
:draggable="canDrag"
|
||||||
spellcheck="false"
|
spellcheck="false"
|
||||||
>
|
>
|
||||||
|
<!--MultiSelecting for the mobile version-->
|
||||||
|
<CheckBox v-if="isMultiSelectMode" :is-clicked="isClicked" class="mr-5" />
|
||||||
|
|
||||||
<!--MultiSelecting for the mobile version-->
|
<div class="w-full">
|
||||||
<CheckBox v-if="isMultiSelectMode" :is-clicked="isClicked" class="mr-5"/>
|
<!--Item thumbnail-->
|
||||||
|
<div class="relative mx-auto">
|
||||||
|
<!--Emoji Icon-->
|
||||||
|
<Emoji v-if="entry.data.attributes.emoji" :emoji="entry.data.attributes.emoji" class="mb-10 inline-block scale-150 transform text-5xl" />
|
||||||
|
|
||||||
<div class="w-full">
|
<!--Folder Icon-->
|
||||||
<!--Item thumbnail-->
|
<FolderIcon v-if="isFolder && !entry.data.attributes.emoji" :item="entry" class="mt-3 mb-5 inline-block scale-150 transform lg:mt-2 lg:mb-8" />
|
||||||
<div class="relative mx-auto">
|
|
||||||
|
|
||||||
<!--Emoji Icon-->
|
<!--File Icon-->
|
||||||
<Emoji
|
<div v-if="isFile || isVideo || isAudio || (isImage && !entry.data.attributes.thumbnail)" class="relative mx-auto w-24">
|
||||||
v-if="entry.data.attributes.emoji"
|
<!--Member thumbnail for team folders-->
|
||||||
:emoji="entry.data.attributes.emoji"
|
<MemberAvatar
|
||||||
class="text-5xl transform scale-150 inline-block mb-10"
|
v-if="user && canShowAuthor"
|
||||||
/>
|
:size="38"
|
||||||
|
:is-border="true"
|
||||||
|
:member="entry.data.relationships.owner"
|
||||||
|
class="absolute right-2 -bottom-5 z-10 z-10 scale-75 transform lg:-bottom-7 lg:scale-100"
|
||||||
|
/>
|
||||||
|
|
||||||
<!--Folder Icon-->
|
<FileIconThumbnail :entry="entry" class="z-0 mt-5 mb-10 scale-125 transform lg:mb-12 lg:mt-6 lg:scale-150" />
|
||||||
<FolderIcon v-if="isFolder && !entry.data.attributes.emoji" :item="entry" class="inline-block transform scale-150 lg:mt-2 lg:mb-8 mt-3 mb-5" />
|
</div>
|
||||||
|
|
||||||
<!--File Icon-->
|
<!--Image thumbnail-->
|
||||||
<div v-if="isFile || isVideo || isAudio || (isImage && !entry.data.attributes.thumbnail)" class="relative w-24 mx-auto">
|
<div v-if="isImage && entry.data.attributes.thumbnail" class="relative mb-4 inline-block h-24 w-28 lg:h-28 lg:w-36">
|
||||||
|
<!--Member thumbnail for team folders-->
|
||||||
|
<MemberAvatar
|
||||||
|
v-if="user && canShowAuthor"
|
||||||
|
:size="38"
|
||||||
|
:is-border="true"
|
||||||
|
:member="entry.data.relationships.owner"
|
||||||
|
class="absolute -right-3 -bottom-2.5 z-10 scale-75 transform lg:scale-100"
|
||||||
|
/>
|
||||||
|
|
||||||
<!--Member thumbnail for team folders-->
|
<img class="h-full w-full rounded-lg object-cover shadow-lg" :src="entry.data.attributes.thumbnail.sm" :alt="entry.data.attributes.name" loading="lazy" />
|
||||||
<MemberAvatar
|
</div>
|
||||||
v-if="user && canShowAuthor"
|
</div>
|
||||||
:size="38"
|
|
||||||
:is-border="true"
|
|
||||||
:member="entry.data.relationships.owner"
|
|
||||||
class="absolute lg:-bottom-7 right-2 -bottom-5 z-10 transform lg:scale-100 scale-75 z-10"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FileIconThumbnail :entry="entry" class="transform lg:scale-150 scale-125 lg:mb-12 lg:mt-6 mt-5 mb-10 z-0" />
|
<!--Item Info-->
|
||||||
</div>
|
<div class="text-center">
|
||||||
|
<!--Item Title-->
|
||||||
|
<b
|
||||||
|
class="tracking-tigh inline-block w-full overflow-hidden text-ellipsis whitespace-nowrap text-sm leading-3 hover:underline md:px-6"
|
||||||
|
ref="name"
|
||||||
|
@input="renameItem"
|
||||||
|
@keydown.delete.stop
|
||||||
|
@click.stop
|
||||||
|
:contenteditable="canEditName"
|
||||||
|
>
|
||||||
|
{{ itemName }}
|
||||||
|
</b>
|
||||||
|
|
||||||
<!--Image thumbnail-->
|
<!--Item sub line-->
|
||||||
<div v-if="isImage && entry.data.attributes.thumbnail" class="relative inline-block lg:w-36 lg:h-28 w-28 h-24 mb-4">
|
<div class="flex items-center justify-center">
|
||||||
|
<!--Shared Icon-->
|
||||||
|
<div v-if="$checkPermission('master') && entry.data.relationships.shared">
|
||||||
|
<link-icon size="12" class="text-theme dark-text-theme vue-feather mr-1.5" />
|
||||||
|
</div>
|
||||||
|
|
||||||
<!--Member thumbnail for team folders-->
|
<!--File & Image sub line-->
|
||||||
<MemberAvatar
|
<small v-if="!isFolder" class="block text-xs text-gray-500">
|
||||||
v-if="user && canShowAuthor"
|
{{ entry.data.attributes.filesize }}<span class="hidden text-xs text-gray-500 lg:inline-block">, {{ timeStamp }}</span>
|
||||||
:size="38"
|
</small>
|
||||||
:is-border="true"
|
|
||||||
:member="entry.data.relationships.owner"
|
|
||||||
class="absolute -right-3 -bottom-2.5 transform lg:scale-100 scale-75 z-10"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<img class="object-cover w-full h-full rounded-lg shadow-lg" :src="entry.data.attributes.thumbnail.sm" :alt="entry.data.attributes.name" loading="lazy" />
|
<!--Folder sub line-->
|
||||||
</div>
|
<small v-if="isFolder" class="block text-xs text-gray-500">
|
||||||
</div>
|
{{ folderItems === 0 ? $t('folder.empty') : $tc('folder.item_counts', folderItems)
|
||||||
|
}}<span class="hidden text-xs text-gray-500 lg:inline-block">, {{ timeStamp }}</span>
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!--Item Info-->
|
<!-- Mobile item action button-->
|
||||||
<div class="text-center">
|
<div v-if="mobileHandler && !isMultiSelectMode && $isMobile()" class="relative flex items-center justify-center py-0.5 px-2">
|
||||||
|
<div @mouseup.stop="$openInDetailPanel(entry)" class="hidden p-2.5 sm:block">
|
||||||
|
<eye-icon size="18" class="vue-feather inline-block opacity-30" />
|
||||||
|
</div>
|
||||||
|
|
||||||
<!--Item Title-->
|
<div @mouseup.stop="showItemActions" class="p-2.5">
|
||||||
<b class="inline-block leading-3 text-sm hover:underline w-full text-ellipsis overflow-hidden whitespace-nowrap md:px-6 tracking-tigh" ref="name" @input="renameItem" @keydown.delete.stop @click.stop :contenteditable="canEditName">
|
<MoreHorizontalIcon size="18" class="vue-feather text-theme dark-text-theme inline-block" />
|
||||||
{{ itemName }}
|
</div>
|
||||||
</b>
|
</div>
|
||||||
|
</div>
|
||||||
<!--Item sub line-->
|
</div>
|
||||||
<div class="flex items-center justify-center">
|
|
||||||
|
|
||||||
<!--Shared Icon-->
|
|
||||||
<div v-if="$checkPermission('master') && entry.data.relationships.shared">
|
|
||||||
<link-icon size="12" class="mr-1.5 text-theme dark-text-theme vue-feather"/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!--File & Image sub line-->
|
|
||||||
<small v-if="! isFolder" class="block text-xs text-gray-500">
|
|
||||||
{{ entry.data.attributes.filesize }}<span class="lg:inline-block hidden text-xs text-gray-500">, {{ timeStamp }}</span>
|
|
||||||
</small>
|
|
||||||
|
|
||||||
<!--Folder sub line-->
|
|
||||||
<small v-if="isFolder" class="block text-xs text-gray-500">
|
|
||||||
{{ folderItems === 0 ? $t('folder.empty') : $tc('folder.item_counts', folderItems) }}<span class="lg:inline-block hidden text-xs text-gray-500">, {{ timeStamp }}</span>
|
|
||||||
</small>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Mobile item action button-->
|
|
||||||
<div v-if="mobileHandler && ! isMultiSelectMode && $isMobile()" class="flex items-center justify-center py-0.5 px-2 relative">
|
|
||||||
<div @mouseup.stop="$openInDetailPanel(entry)" class="p-2.5 sm:block hidden">
|
|
||||||
<eye-icon size="18" class="vue-feather opacity-30 inline-block" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div @mouseup.stop="showItemActions" class="p-2.5">
|
|
||||||
<MoreHorizontalIcon size="18" class="vue-feather text-theme dark-text-theme inline-block" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import FolderIcon from "./FolderIcon";
|
import FolderIcon from './FolderIcon'
|
||||||
import {LinkIcon, MoreHorizontalIcon, EyeIcon} from 'vue-feather-icons'
|
import { LinkIcon, MoreHorizontalIcon, EyeIcon } from 'vue-feather-icons'
|
||||||
import FileIconThumbnail from "./FileIconThumbnail"
|
import FileIconThumbnail from './FileIconThumbnail'
|
||||||
import MemberAvatar from "./MemberAvatar"
|
import MemberAvatar from './MemberAvatar'
|
||||||
import Emoji from "../Others/Emoji"
|
import Emoji from '../Others/Emoji'
|
||||||
import CheckBox from "./CheckBox"
|
import CheckBox from './CheckBox'
|
||||||
import {debounce} from "lodash"
|
import { debounce } from 'lodash'
|
||||||
import {mapGetters} from "vuex"
|
import { mapGetters } from 'vuex'
|
||||||
import {events} from "../../bus"
|
import { events } from '../../bus'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ItemList',
|
name: 'ItemList',
|
||||||
components: {
|
components: {
|
||||||
FileIconThumbnail,
|
FileIconThumbnail,
|
||||||
MoreHorizontalIcon,
|
MoreHorizontalIcon,
|
||||||
MemberAvatar,
|
MemberAvatar,
|
||||||
FolderIcon,
|
FolderIcon,
|
||||||
CheckBox,
|
CheckBox,
|
||||||
LinkIcon,
|
LinkIcon,
|
||||||
EyeIcon,
|
EyeIcon,
|
||||||
Emoji,
|
Emoji,
|
||||||
},
|
},
|
||||||
props: [
|
props: ['mobileHandler', 'entry'],
|
||||||
'mobileHandler',
|
data() {
|
||||||
'entry',
|
return {
|
||||||
],
|
mobileMultiSelect: false,
|
||||||
data() {
|
itemName: undefined,
|
||||||
return {
|
}
|
||||||
mobileMultiSelect: false,
|
},
|
||||||
itemName: undefined,
|
computed: {
|
||||||
}
|
...mapGetters(['isMultiSelectMode', 'clipboard', 'user']),
|
||||||
},
|
isClicked() {
|
||||||
computed: {
|
return this.clipboard.some((element) => element.data.id === this.entry.data.id)
|
||||||
...mapGetters([
|
},
|
||||||
'isMultiSelectMode',
|
isAudio() {
|
||||||
'clipboard',
|
return this.entry.data.type === 'audio'
|
||||||
'user',
|
},
|
||||||
]),
|
isVideo() {
|
||||||
isClicked() {
|
return this.entry.data.type === 'video'
|
||||||
return this.clipboard.some(element => element.data.id === this.entry.data.id)
|
},
|
||||||
},
|
isFile() {
|
||||||
isAudio() {
|
return this.entry.data.type === 'file'
|
||||||
return this.entry.data.type === 'audio'
|
},
|
||||||
},
|
isImage() {
|
||||||
isVideo() {
|
return this.entry.data.type === 'image'
|
||||||
return this.entry.data.type === 'video'
|
},
|
||||||
},
|
isFolder() {
|
||||||
isFile() {
|
return this.entry.data.type === 'folder'
|
||||||
return this.entry.data.type === 'file'
|
},
|
||||||
},
|
timeStamp() {
|
||||||
isImage() {
|
return this.entry.data.attributes.deleted_at
|
||||||
return this.entry.data.type === 'image'
|
? this.$t('entry_thumbnail.deleted_at', {
|
||||||
},
|
time: this.entry.data.attributes.deleted_at,
|
||||||
isFolder() {
|
})
|
||||||
return this.entry.data.type === 'folder'
|
: this.entry.data.attributes.created_at
|
||||||
},
|
},
|
||||||
timeStamp() {
|
canEditName() {
|
||||||
return this.entry.data.attributes.deleted_at
|
return (
|
||||||
? this.$t('entry_thumbnail.deleted_at', {time: this.entry.data.attributes.deleted_at})
|
!this.$isMobile() &&
|
||||||
: this.entry.data.attributes.created_at
|
!this.$isThisRoute(this.$route, ['Trash']) &&
|
||||||
},
|
!this.$checkPermission('visitor') &&
|
||||||
canEditName() {
|
!(this.sharedDetail && this.sharedDetail.attributes.type === 'file')
|
||||||
return !this.$isMobile()
|
)
|
||||||
&& !this.$isThisRoute(this.$route, ['Trash'])
|
},
|
||||||
&& !this.$checkPermission('visitor')
|
folderItems() {
|
||||||
&& !(this.sharedDetail && this.sharedDetail.attributes.type === 'file')
|
return this.entry.data.attributes.deleted_at ? this.entry.data.attributes.trashed_items : this.entry.data.attributes.items
|
||||||
},
|
},
|
||||||
folderItems() {
|
canShowAuthor() {
|
||||||
return this.entry.data.attributes.deleted_at
|
return this.$isThisRoute(this.$route, ['SharedWithMe', 'TeamFolders']) && !this.isFolder && this.user.data.id !== this.entry.data.relationships.owner.data.id
|
||||||
? this.entry.data.attributes.trashed_items
|
},
|
||||||
: this.entry.data.attributes.items
|
canDrag() {
|
||||||
},
|
return !this.isDeleted && this.$checkPermission(['master', 'editor'])
|
||||||
canShowAuthor() {
|
},
|
||||||
return this.$isThisRoute(this.$route, ['SharedWithMe', 'TeamFolders'])
|
},
|
||||||
&& !this.isFolder
|
methods: {
|
||||||
&& this.user.data.id !== this.entry.data.relationships.owner.data.id
|
showItemActions() {
|
||||||
},
|
this.$store.commit('CLIPBOARD_CLEAR')
|
||||||
canDrag() {
|
this.$store.commit('ADD_ITEM_TO_CLIPBOARD', this.entry)
|
||||||
return !this.isDeleted && this.$checkPermission(['master', 'editor'])
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
showItemActions() {
|
|
||||||
this.$store.commit('CLIPBOARD_CLEAR')
|
|
||||||
this.$store.commit('ADD_ITEM_TO_CLIPBOARD', this.entry)
|
|
||||||
|
|
||||||
this.$showMobileMenu('file-menu')
|
this.$showMobileMenu('file-menu')
|
||||||
events.$emit('mobile-context-menu:show', this.entry)
|
events.$emit('mobile-context-menu:show', this.entry)
|
||||||
},
|
},
|
||||||
renameItem: debounce(function (e) {
|
renameItem: debounce(function (e) {
|
||||||
|
// Prevent submit empty string
|
||||||
|
if (e.target.innerText.trim() === '') return
|
||||||
|
|
||||||
// Prevent submit empty string
|
this.$store.dispatch('renameItem', {
|
||||||
if (e.target.innerText.trim() === '') return
|
id: this.entry.data.id,
|
||||||
|
type: this.entry.data.type,
|
||||||
|
name: e.target.innerText,
|
||||||
|
})
|
||||||
|
}, 300),
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
// Set item name to own component variable
|
||||||
|
this.itemName = this.entry.data.attributes.name
|
||||||
|
|
||||||
this.$store.dispatch('renameItem', {
|
// Change item name
|
||||||
id: this.entry.data.id,
|
events.$on('change:name', (item) => {
|
||||||
type: this.entry.data.type,
|
if (this.entry.data.id === item.id) this.itemName = item.name
|
||||||
name: e.target.innerText
|
})
|
||||||
})
|
|
||||||
}, 300)
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
|
|
||||||
// Set item name to own component variable
|
// Autofocus after newly created folder
|
||||||
this.itemName = this.entry.data.attributes.name
|
events.$on('newFolder:focus', (id) => {
|
||||||
|
if (!this.$isMobile() && this.entry.data.id === id) {
|
||||||
// Change item name
|
this.$refs.name.focus()
|
||||||
events.$on('change:name', item => {
|
document.execCommand('selectAll')
|
||||||
if (this.entry.data.id === item.id) this.itemName = item.name
|
}
|
||||||
})
|
})
|
||||||
|
},
|
||||||
// Autofocus after newly created folder
|
}
|
||||||
events.$on('newFolder:focus', id => {
|
|
||||||
|
|
||||||
if ( !this.$isMobile() && this.entry.data.id === id) {
|
|
||||||
this.$refs.name.focus()
|
|
||||||
document.execCommand('selectAll')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,57 +1,48 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<ItemList
|
<ItemList
|
||||||
v-if="itemViewType === 'list'"
|
v-if="itemViewType === 'list'"
|
||||||
:entry="item"
|
:entry="item"
|
||||||
:highlight="true"
|
:highlight="true"
|
||||||
:mobile-handler="true"
|
:mobile-handler="true"
|
||||||
@mouseup.stop.native="clickFilter"
|
@mouseup.stop.native="clickFilter"
|
||||||
@dragstart.native="$emit('dragstart')"
|
@dragstart.native="$emit('dragstart')"
|
||||||
@drop.native="drop()"
|
@drop.native="drop()"
|
||||||
@dragleave.native="dragLeave"
|
@dragleave.native="dragLeave"
|
||||||
@dragover.prevent.native="dragEnter"
|
@dragover.prevent.native="dragEnter"
|
||||||
:class="{'border-theme': area }"
|
:class="{ 'border-theme': area }"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<ItemGrid
|
<ItemGrid
|
||||||
v-if="itemViewType === 'grid'"
|
v-if="itemViewType === 'grid'"
|
||||||
:entry="item"
|
:entry="item"
|
||||||
:highlight="true"
|
:highlight="true"
|
||||||
:mobile-handler="true"
|
:mobile-handler="true"
|
||||||
@mouseup.stop.native="clickFilter"
|
@mouseup.stop.native="clickFilter"
|
||||||
@dragstart.native="$emit('dragstart')"
|
@dragstart.native="$emit('dragstart')"
|
||||||
@drop.native="drop()"
|
@drop.native="drop()"
|
||||||
@dragleave.native="dragLeave"
|
@dragleave.native="dragLeave"
|
||||||
@dragover.prevent.native="dragEnter"
|
@dragover.prevent.native="dragEnter"
|
||||||
:class="{'border-theme': area }"
|
:class="{ 'border-theme': area }"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {events} from "../../bus";
|
import { events } from '../../bus'
|
||||||
import ItemList from './ItemList'
|
import ItemList from './ItemList'
|
||||||
import ItemGrid from './ItemGrid'
|
import ItemGrid from './ItemGrid'
|
||||||
import {mapGetters} from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ItemHandler',
|
name: 'ItemHandler',
|
||||||
props: [
|
props: ['disableHighlight', 'item'],
|
||||||
'disableHighlight',
|
|
||||||
'item',
|
|
||||||
],
|
|
||||||
components: {
|
components: {
|
||||||
ItemList,
|
ItemList,
|
||||||
ItemGrid,
|
ItemGrid,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters([
|
...mapGetters(['isMultiSelectMode', 'itemViewType', 'clipboard', 'entries', 'user']),
|
||||||
'isMultiSelectMode',
|
|
||||||
'itemViewType',
|
|
||||||
'clipboard',
|
|
||||||
'entries',
|
|
||||||
'user',
|
|
||||||
]),
|
|
||||||
isFolder() {
|
isFolder() {
|
||||||
return this.item.data.type === 'folder'
|
return this.item.data.type === 'folder'
|
||||||
},
|
},
|
||||||
@@ -76,40 +67,38 @@ export default {
|
|||||||
return {
|
return {
|
||||||
area: false,
|
area: false,
|
||||||
|
|
||||||
delay: 220,
|
delay: 220,
|
||||||
clicks: 0,
|
clicks: 0,
|
||||||
timer: null
|
timer: null,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
clickFilter(e) {
|
clickFilter(e) {
|
||||||
|
// Handle click for mobile device
|
||||||
|
if (this.$isMobile()) {
|
||||||
|
this.clickedItem(e)
|
||||||
|
}
|
||||||
|
|
||||||
// Handle click for mobile device
|
// Handle click & double click for desktop
|
||||||
if (this.$isMobile()) {
|
if (!this.$isMobile()) {
|
||||||
this.clickedItem(e)
|
this.clicks++
|
||||||
}
|
|
||||||
|
|
||||||
// Handle click & double click for desktop
|
if (this.clicks === 1) {
|
||||||
if (! this.$isMobile()) {
|
let self = this
|
||||||
this.clicks++
|
|
||||||
|
|
||||||
if (this.clicks === 1) {
|
this.timer = setTimeout(() => {
|
||||||
let self = this
|
this.clickedItem(e)
|
||||||
|
self.clicks = 0
|
||||||
|
}, this.delay)
|
||||||
|
} else {
|
||||||
|
clearTimeout(this.timer)
|
||||||
|
|
||||||
this.timer = setTimeout(() => {
|
this.goToItem(e)
|
||||||
this.clickedItem(e)
|
this.clicks = 0
|
||||||
self.clicks = 0
|
}
|
||||||
}, this.delay);
|
}
|
||||||
|
},
|
||||||
} else {
|
drop() {
|
||||||
clearTimeout(this.timer);
|
|
||||||
|
|
||||||
this.goToItem(e)
|
|
||||||
this.clicks = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
drop() {
|
|
||||||
this.area = false
|
this.area = false
|
||||||
events.$emit('drop')
|
events.$emit('drop')
|
||||||
},
|
},
|
||||||
@@ -122,27 +111,24 @@ export default {
|
|||||||
this.area = false
|
this.area = false
|
||||||
},
|
},
|
||||||
clickedItem(e) {
|
clickedItem(e) {
|
||||||
// Disabled right click
|
// Disabled right click
|
||||||
if (e.button === 2) return
|
if (e.button === 2) return
|
||||||
|
|
||||||
if (!this.$isMobile()) {
|
if (!this.$isMobile()) {
|
||||||
|
|
||||||
// After click deselect new folder rename input
|
// After click deselect new folder rename input
|
||||||
if (document.getSelection().toString().length) {
|
if (document.getSelection().toString().length) {
|
||||||
document.getSelection().removeAllRanges();
|
document.getSelection().removeAllRanges()
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((e.ctrlKey || e.metaKey) && !e.shiftKey) {
|
if ((e.ctrlKey || e.metaKey) && !e.shiftKey) {
|
||||||
|
// Click + Ctrl
|
||||||
// Click + Ctrl
|
if (this.clipboard.some((item) => item.data.id === this.item.data.id)) {
|
||||||
if (this.clipboard.some(item => item.data.id === this.item.data.id)) {
|
|
||||||
this.$store.commit('REMOVE_ITEM_FROM_CLIPBOARD', this.item)
|
this.$store.commit('REMOVE_ITEM_FROM_CLIPBOARD', this.item)
|
||||||
} else {
|
} else {
|
||||||
this.$store.commit('ADD_ITEM_TO_CLIPBOARD', this.item)
|
this.$store.commit('ADD_ITEM_TO_CLIPBOARD', this.item)
|
||||||
}
|
}
|
||||||
} else if (e.shiftKey) {
|
} else if (e.shiftKey) {
|
||||||
|
// Click + Shift
|
||||||
// Click + Shift
|
|
||||||
let lastItem = this.entries.indexOf(this.clipboard[this.clipboard.length - 1])
|
let lastItem = this.entries.indexOf(this.clipboard[this.clipboard.length - 1])
|
||||||
let clickedItem = this.entries.indexOf(this.item)
|
let clickedItem = this.entries.indexOf(this.item)
|
||||||
|
|
||||||
@@ -163,21 +149,17 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// Click
|
||||||
// Click
|
|
||||||
this.$store.commit('CLIPBOARD_CLEAR')
|
this.$store.commit('CLIPBOARD_CLEAR')
|
||||||
this.$store.commit('ADD_ITEM_TO_CLIPBOARD', this.item)
|
this.$store.commit('ADD_ITEM_TO_CLIPBOARD', this.item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.isMultiSelectMode && this.$isMobile()) {
|
if (!this.isMultiSelectMode && this.$isMobile()) {
|
||||||
|
|
||||||
if (this.isFolder) {
|
if (this.isFolder) {
|
||||||
this.$goToFileView(this.item.data.id)
|
this.$goToFileView(this.item.data.id)
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (this.isImage || this.isVideo || this.isAudio || this.isPdf) {
|
if (this.isImage || this.isVideo || this.isAudio || this.isPdf) {
|
||||||
|
|
||||||
this.$store.commit('CLIPBOARD_CLEAR')
|
this.$store.commit('CLIPBOARD_CLEAR')
|
||||||
this.$store.commit('ADD_ITEM_TO_CLIPBOARD', this.item)
|
this.$store.commit('ADD_ITEM_TO_CLIPBOARD', this.item)
|
||||||
|
|
||||||
@@ -187,7 +169,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.isMultiSelectMode && this.$isMobile()) {
|
if (this.isMultiSelectMode && this.$isMobile()) {
|
||||||
if (this.clipboard.some(item => item.data.id === this.item.data.id)) {
|
if (this.clipboard.some((item) => item.data.id === this.item.data.id)) {
|
||||||
this.$store.commit('REMOVE_ITEM_FROM_CLIPBOARD', this.item)
|
this.$store.commit('REMOVE_ITEM_FROM_CLIPBOARD', this.item)
|
||||||
} else {
|
} else {
|
||||||
this.$store.commit('ADD_ITEM_TO_CLIPBOARD', this.item)
|
this.$store.commit('ADD_ITEM_TO_CLIPBOARD', this.item)
|
||||||
@@ -196,20 +178,17 @@ export default {
|
|||||||
},
|
},
|
||||||
goToItem() {
|
goToItem() {
|
||||||
if (this.isImage || this.isVideo || this.isAudio || this.isPdf) {
|
if (this.isImage || this.isVideo || this.isAudio || this.isPdf) {
|
||||||
this.$store.commit('CLIPBOARD_CLEAR')
|
this.$store.commit('CLIPBOARD_CLEAR')
|
||||||
this.$store.commit('ADD_ITEM_TO_CLIPBOARD', this.item)
|
this.$store.commit('ADD_ITEM_TO_CLIPBOARD', this.item)
|
||||||
|
|
||||||
events.$emit('file-preview:show')
|
events.$emit('file-preview:show')
|
||||||
|
} else if (this.isFile || (!this.isFolder && !this.isVideo && !this.isAudio && !this.isImage)) {
|
||||||
} else if (this.isFile || !this.isFolder && !this.isVideo && !this.isAudio && !this.isImage) {
|
|
||||||
this.$downloadFile(this.item.data.attributes.file_url, this.item.data.attributes.name + '.' + this.item.data.attributes.mimetype)
|
this.$downloadFile(this.item.data.attributes.file_url, this.item.data.attributes.name + '.' + this.item.data.attributes.mimetype)
|
||||||
|
|
||||||
} else if (this.isFolder) {
|
} else if (this.isFolder) {
|
||||||
|
this.$goToFileView(this.item.data.id)
|
||||||
this.$goToFileView(this.item.data.id)
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -217,7 +196,6 @@ export default {
|
|||||||
@import '../../../sass/vuefilemanager/variables';
|
@import '../../../sass/vuefilemanager/variables';
|
||||||
@import '../../../sass/vuefilemanager/mixins';
|
@import '../../../sass/vuefilemanager/mixins';
|
||||||
|
|
||||||
|
|
||||||
.slide-from-left-move {
|
.slide-from-left-move {
|
||||||
transition: transform 300s ease;
|
transition: transform 300s ease;
|
||||||
}
|
}
|
||||||
@@ -357,7 +335,7 @@ export default {
|
|||||||
height: 52px;
|
height: 52px;
|
||||||
|
|
||||||
/deep/ .folder-icon {
|
/deep/ .folder-icon {
|
||||||
@include font-size(52)
|
@include font-size(52);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -430,7 +408,6 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.dark {
|
.dark {
|
||||||
|
|
||||||
.file-wrapper {
|
.file-wrapper {
|
||||||
.icon-item {
|
.icon-item {
|
||||||
.file-icon {
|
.file-icon {
|
||||||
@@ -446,15 +423,13 @@ export default {
|
|||||||
background: $dark_mode_background !important;
|
background: $dark_mode_background !important;
|
||||||
|
|
||||||
.file-icon {
|
.file-icon {
|
||||||
|
|
||||||
path {
|
path {
|
||||||
fill: $dark_mode_foreground !important;
|
fill: $dark_mode_foreground !important;
|
||||||
stroke: #2F3C54;
|
stroke: #2f3c54;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.item-name {
|
.item-name {
|
||||||
|
|
||||||
.name {
|
.name {
|
||||||
color: $dark_mode_text_primary !important;
|
color: $dark_mode_text_primary !important;
|
||||||
}
|
}
|
||||||
@@ -485,4 +460,4 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,199 +1,195 @@
|
|||||||
<template>
|
<template>
|
||||||
<div :class="{'dark:bg-dark-foreground bg-light-background': isClicked && highlight, 'dark:hover:bg-dark-foreground hover:bg-light-background': highlight}" class="flex items-center px-2.5 py-2 rounded-xl select-none border-2 border-transparent border-dashed" :draggable="canDrag" spellcheck="false">
|
<div
|
||||||
|
:class="{
|
||||||
|
'bg-light-background dark:bg-dark-foreground': isClicked && highlight,
|
||||||
|
'hover:bg-light-background dark:hover:bg-dark-foreground': highlight,
|
||||||
|
}"
|
||||||
|
class="flex select-none items-center rounded-xl border-2 border-dashed border-transparent px-2.5 py-2"
|
||||||
|
:draggable="canDrag"
|
||||||
|
spellcheck="false"
|
||||||
|
>
|
||||||
|
<!--MultiSelecting for the mobile version-->
|
||||||
|
<CheckBox v-if="isMultiSelectMode" v-model="isClicked" :is-clicked="isClicked" class="mr-5" />
|
||||||
|
|
||||||
<!--MultiSelecting for the mobile version-->
|
<!--Item thumbnail-->
|
||||||
<CheckBox v-if="isMultiSelectMode" v-model="isClicked" :is-clicked="isClicked" class="mr-5"/>
|
<div class="relative w-16">
|
||||||
|
<!--Member thumbnail for team folders-->
|
||||||
|
<MemberAvatar v-if="user && canShowAuthor" :size="28" :is-border="true" :member="entry.data.relationships.owner" class="absolute right-1.5 -bottom-2 z-10" />
|
||||||
|
|
||||||
<!--Item thumbnail-->
|
<!--Emoji Icon-->
|
||||||
<div class="w-16 relative">
|
<Emoji v-if="entry.data.attributes.emoji" :emoji="entry.data.attributes.emoji" class="ml-1 scale-110 transform text-5xl" />
|
||||||
|
|
||||||
<!--Member thumbnail for team folders-->
|
<!--Folder Icon-->
|
||||||
<MemberAvatar
|
<FolderIcon v-if="isFolder && !entry.data.attributes.emoji" :item="entry" />
|
||||||
v-if="user && canShowAuthor"
|
|
||||||
:size="28"
|
|
||||||
:is-border="true"
|
|
||||||
:member="entry.data.relationships.owner"
|
|
||||||
class="absolute right-1.5 -bottom-2 z-10"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!--Emoji Icon-->
|
<!--File Icon-->
|
||||||
<Emoji
|
<FileIconThumbnail v-if="isFile || isVideo || isAudio || (isImage && !entry.data.attributes.thumbnail)" :entry="entry" class="pr-2" />
|
||||||
v-if="entry.data.attributes.emoji"
|
|
||||||
:emoji="entry.data.attributes.emoji"
|
|
||||||
class="text-5xl ml-1 transform scale-110"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!--Folder Icon-->
|
<!--Image thumbnail-->
|
||||||
<FolderIcon v-if="isFolder && !entry.data.attributes.emoji" :item="entry" />
|
<img
|
||||||
|
v-if="isImage && entry.data.attributes.thumbnail"
|
||||||
|
class="ml-0.5 h-12 w-12 rounded object-cover"
|
||||||
|
:src="entry.data.attributes.thumbnail.xs"
|
||||||
|
:alt="entry.data.attributes.name"
|
||||||
|
loading="lazy"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!--File Icon-->
|
<!--Item Info-->
|
||||||
<FileIconThumbnail v-if="isFile || isVideo || isAudio || (isImage && !entry.data.attributes.thumbnail)" :entry="entry" class="pr-2" />
|
<div class="pl-2">
|
||||||
|
<!--Item Title-->
|
||||||
|
<b
|
||||||
|
class="mb-0.5 block overflow-hidden text-ellipsis whitespace-nowrap text-sm hover:underline"
|
||||||
|
style="max-width: 240px"
|
||||||
|
ref="name"
|
||||||
|
@input="renameItem"
|
||||||
|
@keydown.delete.stop
|
||||||
|
@click.stop
|
||||||
|
:contenteditable="canEditName"
|
||||||
|
>
|
||||||
|
{{ itemName }}
|
||||||
|
</b>
|
||||||
|
|
||||||
<!--Image thumbnail-->
|
<!--Item sub line-->
|
||||||
<img v-if="isImage && entry.data.attributes.thumbnail" class="w-12 h-12 rounded ml-0.5 object-cover" :src="entry.data.attributes.thumbnail.xs" :alt="entry.data.attributes.name" loading="lazy" />
|
<div class="flex items-center">
|
||||||
</div>
|
<!--Shared Icon-->
|
||||||
|
<div v-if="$checkPermission('master') && entry.data.relationships.shared">
|
||||||
|
<link-icon size="12" class="text-theme dark-text-theme vue-feather mr-1.5" />
|
||||||
|
</div>
|
||||||
|
|
||||||
<!--Item Info-->
|
<!--File & Image sub line-->
|
||||||
<div class="pl-2">
|
<small v-if="!isFolder" class="block text-xs text-gray-500"> {{ entry.data.attributes.filesize }}, {{ timeStamp }} </small>
|
||||||
|
|
||||||
<!--Item Title-->
|
<!--Folder sub line-->
|
||||||
<b class="block text-sm mb-0.5 text-ellipsis overflow-hidden hover:underline whitespace-nowrap" style="max-width: 240px" ref="name" @input="renameItem" @keydown.delete.stop @click.stop :contenteditable="canEditName">
|
<small v-if="isFolder" class="block text-xs text-gray-500">
|
||||||
{{ itemName }}
|
{{ folderItems === 0 ? $t('folder.empty') : $tc('folder.item_counts', folderItems) }}, {{ timeStamp }}
|
||||||
</b>
|
</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!--Item sub line-->
|
<!-- Mobile item action button-->
|
||||||
<div class="flex items-center">
|
<div v-if="mobileHandler && !isMultiSelectMode && $isMobile()" class="relative flex-grow pr-1 text-right">
|
||||||
|
<div @mouseup.stop="$openInDetailPanel(entry)" class="absolute right-10 -mr-4 hidden -translate-y-2/4 transform p-2.5 lg:block">
|
||||||
<!--Shared Icon-->
|
<eye-icon size="18" class="vue-feather inline-block opacity-30" />
|
||||||
<div v-if="$checkPermission('master') && entry.data.relationships.shared">
|
</div>
|
||||||
<link-icon size="12" class="mr-1.5 text-theme dark-text-theme vue-feather"/>
|
<div @mouseup.stop="showItemActions" class="absolute right-0 -mr-4 -translate-y-2/4 transform p-2.5">
|
||||||
</div>
|
<MoreVerticalIcon size="18" class="vue-feather text-theme dark-text-theme inline-block" />
|
||||||
|
</div>
|
||||||
<!--File & Image sub line-->
|
</div>
|
||||||
<small v-if="! isFolder" class="block text-xs text-gray-500">
|
</div>
|
||||||
{{ entry.data.attributes.filesize }}, {{ timeStamp }}
|
|
||||||
</small>
|
|
||||||
|
|
||||||
<!--Folder sub line-->
|
|
||||||
<small v-if="isFolder" class="block text-xs text-gray-500">
|
|
||||||
{{ folderItems === 0 ? $t('folder.empty') : $tc('folder.item_counts', folderItems) }}, {{ timeStamp }}
|
|
||||||
</small>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Mobile item action button-->
|
|
||||||
<div v-if="mobileHandler && ! isMultiSelectMode && $isMobile()" class="pr-1 flex-grow text-right relative">
|
|
||||||
<div @mouseup.stop="$openInDetailPanel(entry)" class="absolute right-10 p-2.5 -mr-4 transform -translate-y-2/4 lg:block hidden">
|
|
||||||
<eye-icon size="18" class="vue-feather opacity-30 inline-block" />
|
|
||||||
</div>
|
|
||||||
<div @mouseup.stop="showItemActions" class="absolute right-0 p-2.5 -mr-4 transform -translate-y-2/4">
|
|
||||||
<MoreVerticalIcon size="18" class="vue-feather text-theme dark-text-theme inline-block" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Emoji from "../Others/Emoji";
|
import Emoji from '../Others/Emoji'
|
||||||
import FolderIcon from "./FolderIcon";
|
import FolderIcon from './FolderIcon'
|
||||||
import {LinkIcon, MoreVerticalIcon, EyeIcon} from 'vue-feather-icons'
|
import { LinkIcon, MoreVerticalIcon, EyeIcon } from 'vue-feather-icons'
|
||||||
import FileIconThumbnail from "./FileIconThumbnail";
|
import FileIconThumbnail from './FileIconThumbnail'
|
||||||
import MemberAvatar from "./MemberAvatar";
|
import MemberAvatar from './MemberAvatar'
|
||||||
import CheckBox from "./CheckBox";
|
import CheckBox from './CheckBox'
|
||||||
import {debounce} from "lodash";
|
import { debounce } from 'lodash'
|
||||||
import {mapGetters} from "vuex";
|
import { mapGetters } from 'vuex'
|
||||||
import {events} from "../../bus";
|
import { events } from '../../bus'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ItemList',
|
name: 'ItemList',
|
||||||
components: {
|
components: {
|
||||||
FileIconThumbnail,
|
FileIconThumbnail,
|
||||||
MoreVerticalIcon,
|
MoreVerticalIcon,
|
||||||
MemberAvatar,
|
MemberAvatar,
|
||||||
FolderIcon,
|
FolderIcon,
|
||||||
CheckBox,
|
CheckBox,
|
||||||
LinkIcon,
|
LinkIcon,
|
||||||
EyeIcon,
|
EyeIcon,
|
||||||
Emoji,
|
Emoji,
|
||||||
},
|
},
|
||||||
props: [
|
props: ['mobileHandler', 'highlight', 'entry'],
|
||||||
'mobileHandler',
|
data() {
|
||||||
'highlight',
|
return {
|
||||||
'entry',
|
mobileMultiSelect: false,
|
||||||
],
|
itemName: undefined,
|
||||||
data() {
|
isSelected: false,
|
||||||
return {
|
}
|
||||||
mobileMultiSelect: false,
|
},
|
||||||
itemName: undefined,
|
computed: {
|
||||||
isSelected: false,
|
...mapGetters(['isMultiSelectMode', 'clipboard', 'user']),
|
||||||
}
|
isClicked() {
|
||||||
},
|
return this.clipboard.some((element) => element.data.id === this.entry.data.id)
|
||||||
computed: {
|
},
|
||||||
...mapGetters([
|
isVideo() {
|
||||||
'isMultiSelectMode',
|
return this.entry.data.type === 'video'
|
||||||
'clipboard',
|
},
|
||||||
'user',
|
isAudio() {
|
||||||
]),
|
return this.entry.data.type === 'audio'
|
||||||
isClicked() {
|
},
|
||||||
return this.clipboard.some(element => element.data.id === this.entry.data.id)
|
isFile() {
|
||||||
},
|
return this.entry.data.type === 'file'
|
||||||
isVideo() {
|
},
|
||||||
return this.entry.data.type === 'video'
|
isImage() {
|
||||||
},
|
return this.entry.data.type === 'image'
|
||||||
isAudio() {
|
},
|
||||||
return this.entry.data.type === 'audio'
|
isFolder() {
|
||||||
},
|
return this.entry.data.type === 'folder'
|
||||||
isFile() {
|
},
|
||||||
return this.entry.data.type === 'file'
|
timeStamp() {
|
||||||
},
|
return this.entry.data.attributes.deleted_at
|
||||||
isImage() {
|
? this.$t('item_thumbnail.deleted_at', {
|
||||||
return this.entry.data.type === 'image'
|
time: this.entry.data.attributes.deleted_at,
|
||||||
},
|
})
|
||||||
isFolder() {
|
: this.entry.data.attributes.created_at
|
||||||
return this.entry.data.type === 'folder'
|
},
|
||||||
},
|
canEditName() {
|
||||||
timeStamp() {
|
return (
|
||||||
return this.entry.data.attributes.deleted_at
|
!this.$isMobile() &&
|
||||||
? this.$t('item_thumbnail.deleted_at', {time: this.entry.data.attributes.deleted_at})
|
!this.$isThisRoute(this.$route, ['Trash']) &&
|
||||||
: this.entry.data.attributes.created_at
|
!this.$checkPermission('visitor') &&
|
||||||
},
|
!(this.sharedDetail && this.sharedDetail.attributes.type === 'file')
|
||||||
canEditName() {
|
)
|
||||||
return !this.$isMobile()
|
},
|
||||||
&& !this.$isThisRoute(this.$route, ['Trash'])
|
folderItems() {
|
||||||
&& !this.$checkPermission('visitor')
|
return this.entry.data.attributes.deleted_at ? this.entry.data.attributes.trashed_items : this.entry.data.attributes.items
|
||||||
&& !(this.sharedDetail && this.sharedDetail.attributes.type === 'file')
|
},
|
||||||
},
|
canShowAuthor() {
|
||||||
folderItems() {
|
return !this.isFolder && this.user.data.id !== this.entry.data.relationships.owner.data.id
|
||||||
return this.entry.data.attributes.deleted_at
|
},
|
||||||
? this.entry.data.attributes.trashed_items
|
canDrag() {
|
||||||
: this.entry.data.attributes.items
|
return !this.isDeleted && this.$checkPermission(['master', 'editor'])
|
||||||
},
|
},
|
||||||
canShowAuthor() {
|
},
|
||||||
return !this.isFolder
|
methods: {
|
||||||
&& this.user.data.id !== this.entry.data.relationships.owner.data.id
|
showItemActions() {
|
||||||
},
|
this.$store.commit('CLIPBOARD_CLEAR')
|
||||||
canDrag() {
|
this.$store.commit('ADD_ITEM_TO_CLIPBOARD', this.entry)
|
||||||
return !this.isDeleted && this.$checkPermission(['master', 'editor'])
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
showItemActions() {
|
|
||||||
this.$store.commit('CLIPBOARD_CLEAR')
|
|
||||||
this.$store.commit('ADD_ITEM_TO_CLIPBOARD', this.entry)
|
|
||||||
|
|
||||||
this.$showMobileMenu('file-menu')
|
this.$showMobileMenu('file-menu')
|
||||||
events.$emit('mobile-context-menu:show', this.entry)
|
events.$emit('mobile-context-menu:show', this.entry)
|
||||||
},
|
},
|
||||||
renameItem: debounce(function (e) {
|
renameItem: debounce(function (e) {
|
||||||
|
// Prevent submit empty string
|
||||||
|
if (e.target.innerText.trim() === '') return
|
||||||
|
|
||||||
// Prevent submit empty string
|
this.$store.dispatch('renameItem', {
|
||||||
if (e.target.innerText.trim() === '') return
|
id: this.entry.data.id,
|
||||||
|
type: this.entry.data.type,
|
||||||
|
name: e.target.innerText,
|
||||||
|
})
|
||||||
|
}, 300),
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
// Set item name to own component variable
|
||||||
|
this.itemName = this.entry.data.attributes.name
|
||||||
|
|
||||||
this.$store.dispatch('renameItem', {
|
// Change item name
|
||||||
id: this.entry.data.id,
|
events.$on('change:name', (item) => {
|
||||||
type: this.entry.data.type,
|
if (this.entry.data.id === item.id) this.itemName = item.name
|
||||||
name: e.target.innerText
|
})
|
||||||
})
|
|
||||||
}, 300)
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
|
|
||||||
// Set item name to own component variable
|
// Autofocus after newly created folder
|
||||||
this.itemName = this.entry.data.attributes.name
|
events.$on('newFolder:focus', (id) => {
|
||||||
|
if (!this.$isMobile() && this.entry.data.id === id) {
|
||||||
// Change item name
|
this.$refs.name.focus()
|
||||||
events.$on('change:name', item => {
|
document.execCommand('selectAll')
|
||||||
if (this.entry.data.id === item.id) this.itemName = item.name
|
}
|
||||||
})
|
})
|
||||||
|
},
|
||||||
// Autofocus after newly created folder
|
}
|
||||||
events.$on('newFolder:focus', id => {
|
|
||||||
|
|
||||||
if ( !this.$isMobile() && this.entry.data.id === id) {
|
|
||||||
this.$refs.name.focus()
|
|
||||||
document.execCommand('selectAll')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,62 +1,69 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="shrink-0 grow-0">
|
<div class="shrink-0 grow-0">
|
||||||
<img
|
<img
|
||||||
:style="{width: size + 'px', height: size + 'px'}"
|
:style="{ width: size + 'px', height: size + 'px' }"
|
||||||
v-if="member.data.attributes.avatar"
|
v-if="member.data.attributes.avatar"
|
||||||
:src="avatar"
|
:src="avatar"
|
||||||
:class="[borderRadius, {'border-3 border-white dark:border-dark-background': isBorder}]"
|
:class="[
|
||||||
class=""
|
borderRadius,
|
||||||
/>
|
{
|
||||||
<div
|
'border-3 border-white dark:border-dark-background': isBorder,
|
||||||
v-else
|
},
|
||||||
class="flex items-center justify-center"
|
]"
|
||||||
:class="[borderRadius, {'border-3 border-white dark:border-dark-background': isBorder}]"
|
class=""
|
||||||
:style="{width: size + 'px', height: size + 'px', background: member.data.attributes.color ? member.data.attributes.color : '#f4f5f6'}"
|
/>
|
||||||
>
|
<div
|
||||||
<span :class="fontSize" class="uppercase font-extrabold text-gray-900">
|
v-else
|
||||||
{{ letter }}
|
class="flex items-center justify-center"
|
||||||
</span>
|
:class="[
|
||||||
</div>
|
borderRadius,
|
||||||
</div>
|
{
|
||||||
|
'border-3 border-white dark:border-dark-background': isBorder,
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
:style="{
|
||||||
|
width: size + 'px',
|
||||||
|
height: size + 'px',
|
||||||
|
background: member.data.attributes.color ? member.data.attributes.color : '#f4f5f6',
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<span :class="fontSize" class="font-extrabold uppercase text-gray-900">
|
||||||
|
{{ letter }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'MemberAvatar',
|
||||||
|
props: ['isBorder', 'member', 'size'],
|
||||||
|
computed: {
|
||||||
|
letter() {
|
||||||
|
let string = this.member.data.attributes.name ? this.member.data.attributes.name : this.member.data.attributes.email
|
||||||
|
|
||||||
export default {
|
return string.substr(0, 1)
|
||||||
name: 'MemberAvatar',
|
},
|
||||||
props: [
|
borderRadius() {
|
||||||
'isBorder',
|
return this.size > 32 ? 'rounded-xl' : 'rounded-lg'
|
||||||
'member',
|
},
|
||||||
'size',
|
fontSize() {
|
||||||
],
|
if (this.size > 42) {
|
||||||
computed: {
|
return 'text-lg'
|
||||||
letter() {
|
} else if (this.size > 32) {
|
||||||
let string = this.member.data.attributes.name
|
return 'text-base'
|
||||||
? this.member.data.attributes.name
|
} else {
|
||||||
: this.member.data.attributes.email
|
return 'text-sm'
|
||||||
|
}
|
||||||
return string.substr(0, 1)
|
},
|
||||||
},
|
avatar() {
|
||||||
borderRadius() {
|
if (this.size >= 52) {
|
||||||
return this.size > 32 ? 'rounded-xl' : 'rounded-lg'
|
return this.member.data.attributes.avatar.md
|
||||||
},
|
} else if (this.size > 32) {
|
||||||
fontSize() {
|
return this.member.data.attributes.avatar.sm
|
||||||
if (this.size > 42) {
|
} else {
|
||||||
return 'text-lg'
|
return this.member.data.attributes.avatar.xs
|
||||||
} else if (this.size > 32) {
|
}
|
||||||
return 'text-base'
|
},
|
||||||
} else {
|
},
|
||||||
return 'text-sm'
|
}
|
||||||
}
|
|
||||||
},
|
|
||||||
avatar() {
|
|
||||||
if (this.size >= 52) {
|
|
||||||
return this.member.data.attributes.avatar.md
|
|
||||||
} else if (this.size > 32) {
|
|
||||||
return this.member.data.attributes.avatar.sm
|
|
||||||
} else {
|
|
||||||
return this.member.data.attributes.avatar.xs
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<button class="inline-block dark:bg-2x-dark-foreground bg-light-background rounded-xl py-2 px-3.5 mr-2">
|
<button class="mr-2 inline-block rounded-xl bg-light-background py-2 px-3.5 dark:bg-2x-dark-foreground">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<hard-drive-icon v-if="icon === 'hard-drive'" size="15" class="vue-feather dark-text-theme" />
|
<hard-drive-icon v-if="icon === 'hard-drive'" size="15" class="vue-feather dark-text-theme" />
|
||||||
<upload-cloud-icon v-if="icon === 'upload-cloud'" size="15" class="vue-feather dark-text-theme" />
|
<upload-cloud-icon v-if="icon === 'upload-cloud'" size="15" class="vue-feather dark-text-theme" />
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
<trash2-icon v-if="icon === 'trash2'" size="15" class="vue-feather dark-text-theme" />
|
<trash2-icon v-if="icon === 'trash2'" size="15" class="vue-feather dark-text-theme" />
|
||||||
<users-icon v-if="icon === 'users'" size="15" class="vue-feather dark-text-theme" />
|
<users-icon v-if="icon === 'users'" size="15" class="vue-feather dark-text-theme" />
|
||||||
<user-check-icon v-if="icon === 'user-check'" size="15" class="vue-feather dark-text-theme" />
|
<user-check-icon v-if="icon === 'user-check'" size="15" class="vue-feather dark-text-theme" />
|
||||||
<search-icon v-if="icon === 'search'" size="15" class="vue-feather dark-text-theme" />
|
<search-icon v-if="icon === 'search'" size="15" class="vue-feather dark-text-theme" />
|
||||||
<refresh-cw-icon v-if="icon === 'refresh'" size="15" class="vue-feather dark-text-theme" />
|
<refresh-cw-icon v-if="icon === 'refresh'" size="15" class="vue-feather dark-text-theme" />
|
||||||
<download-icon v-if="icon === 'download'" size="15" class="vue-feather dark-text-theme" />
|
<download-icon v-if="icon === 'download'" size="15" class="vue-feather dark-text-theme" />
|
||||||
<copy-icon v-if="icon === 'copy'" size="15" class="vue-feather dark-text-theme" />
|
<copy-icon v-if="icon === 'copy'" size="15" class="vue-feather dark-text-theme" />
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
<sorting-icon v-if="icon === 'preview-sorting'" class="vue-feather dark-text-theme preview-sorting" />
|
<sorting-icon v-if="icon === 'preview-sorting'" class="vue-feather dark-text-theme preview-sorting" />
|
||||||
<cloud-plus-icon v-if="icon === 'cloud-plus'" class="vue-feather dark-text-theme preview-sorting" />
|
<cloud-plus-icon v-if="icon === 'cloud-plus'" class="vue-feather dark-text-theme preview-sorting" />
|
||||||
|
|
||||||
<span v-if="$slots.default" class="font-bold text-sm ml-2">
|
<span v-if="$slots.default" class="ml-2 text-sm font-bold">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -34,40 +34,61 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { UserCheckIcon, HardDriveIcon, UploadCloudIcon, LinkIcon, Trash2Icon, UsersIcon, SearchIcon, RefreshCwIcon, DownloadIcon, CopyIcon, FilterIcon, DollarSignIcon, CheckIcon, XSquareIcon, CheckSquareIcon, FolderPlusIcon, ListIcon, GridIcon, TrashIcon, UserPlusIcon, PlusIcon, CreditCardIcon } from 'vue-feather-icons'
|
import {
|
||||||
import CloudPlusIcon from "./Icons/CloudPlusIcon";
|
UserCheckIcon,
|
||||||
import SortingIcon from "./Icons/SortingIcon";
|
HardDriveIcon,
|
||||||
|
UploadCloudIcon,
|
||||||
|
LinkIcon,
|
||||||
|
Trash2Icon,
|
||||||
|
UsersIcon,
|
||||||
|
SearchIcon,
|
||||||
|
RefreshCwIcon,
|
||||||
|
DownloadIcon,
|
||||||
|
CopyIcon,
|
||||||
|
FilterIcon,
|
||||||
|
DollarSignIcon,
|
||||||
|
CheckIcon,
|
||||||
|
XSquareIcon,
|
||||||
|
CheckSquareIcon,
|
||||||
|
FolderPlusIcon,
|
||||||
|
ListIcon,
|
||||||
|
GridIcon,
|
||||||
|
TrashIcon,
|
||||||
|
UserPlusIcon,
|
||||||
|
PlusIcon,
|
||||||
|
CreditCardIcon,
|
||||||
|
} from 'vue-feather-icons'
|
||||||
|
import CloudPlusIcon from './Icons/CloudPlusIcon'
|
||||||
|
import SortingIcon from './Icons/SortingIcon'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'MobileActionButton',
|
name: 'MobileActionButton',
|
||||||
props: [
|
props: ['icon'],
|
||||||
'icon'
|
components: {
|
||||||
],
|
UserCheckIcon,
|
||||||
components: {
|
HardDriveIcon,
|
||||||
UserCheckIcon,
|
UploadCloudIcon,
|
||||||
HardDriveIcon,
|
LinkIcon,
|
||||||
UploadCloudIcon,
|
Trash2Icon,
|
||||||
LinkIcon,
|
UsersIcon,
|
||||||
Trash2Icon,
|
CheckSquareIcon,
|
||||||
UsersIcon,
|
DollarSignIcon,
|
||||||
CheckSquareIcon,
|
CreditCardIcon,
|
||||||
DollarSignIcon,
|
FolderPlusIcon,
|
||||||
CreditCardIcon,
|
RefreshCwIcon,
|
||||||
FolderPlusIcon,
|
CloudPlusIcon,
|
||||||
RefreshCwIcon,
|
UserPlusIcon,
|
||||||
CloudPlusIcon,
|
DownloadIcon,
|
||||||
UserPlusIcon,
|
SortingIcon,
|
||||||
DownloadIcon,
|
XSquareIcon,
|
||||||
SortingIcon,
|
FilterIcon,
|
||||||
XSquareIcon,
|
SearchIcon,
|
||||||
FilterIcon,
|
CheckIcon,
|
||||||
SearchIcon,
|
TrashIcon,
|
||||||
CheckIcon,
|
PlusIcon,
|
||||||
TrashIcon,
|
CopyIcon,
|
||||||
PlusIcon,
|
ListIcon,
|
||||||
CopyIcon,
|
GridIcon,
|
||||||
ListIcon,
|
},
|
||||||
GridIcon,
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -4,79 +4,76 @@
|
|||||||
<cloud-plus-icon class="icon dark-text-theme" size="15" />
|
<cloud-plus-icon class="icon dark-text-theme" size="15" />
|
||||||
<label label="file" class="label button file-input button-base">
|
<label label="file" class="label button file-input button-base">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
<input
|
<input @change="emmitFiles" v-show="false" id="file" type="file" name="files[]" multiple />
|
||||||
@change="emmitFiles"
|
|
||||||
v-show="false"
|
|
||||||
id="file"
|
|
||||||
type="file"
|
|
||||||
name="files[]"
|
|
||||||
multiple
|
|
||||||
/>
|
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { UploadCloudIcon } from 'vue-feather-icons'
|
import { UploadCloudIcon } from 'vue-feather-icons'
|
||||||
import CloudPlusIcon from "./Icons/CloudPlusIcon";
|
import CloudPlusIcon from './Icons/CloudPlusIcon'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'MobileActionButtonUpload',
|
name: 'MobileActionButtonUpload',
|
||||||
components: {
|
components: {
|
||||||
CloudPlusIcon,
|
CloudPlusIcon,
|
||||||
UploadCloudIcon,
|
UploadCloudIcon,
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
emmitFiles(e) {
|
||||||
|
this.$uploadFiles(e.target.files)
|
||||||
},
|
},
|
||||||
methods: {
|
},
|
||||||
emmitFiles(e) {
|
}
|
||||||
this.$uploadFiles(e.target.files)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import '../../../sass/vuefilemanager/variables';
|
@import '../../../sass/vuefilemanager/variables';
|
||||||
@import '../../../sass/vuefilemanager/mixins';
|
@import '../../../sass/vuefilemanager/mixins';
|
||||||
|
|
||||||
|
.mobile-action-button {
|
||||||
|
background: $light_background;
|
||||||
|
margin-right: 8px;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 7px 14px;
|
||||||
|
cursor: pointer;
|
||||||
|
border: none;
|
||||||
|
|
||||||
|
.flex {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
vertical-align: middle;
|
||||||
|
margin-right: 10px;
|
||||||
|
@include font-size(14);
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
vertical-align: middle;
|
||||||
|
@include font-size(14);
|
||||||
|
font-weight: 700;
|
||||||
|
color: $text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark {
|
||||||
.mobile-action-button {
|
.mobile-action-button {
|
||||||
background: $light_background;
|
background: $dark_mode_foreground;
|
||||||
margin-right: 8px;
|
|
||||||
border-radius: 8px;
|
|
||||||
padding: 7px 14px;
|
|
||||||
cursor: pointer;
|
|
||||||
border: none;
|
|
||||||
|
|
||||||
.flex {
|
path,
|
||||||
display: flex;
|
line,
|
||||||
align-items: center;
|
polyline,
|
||||||
}
|
rect,
|
||||||
|
circle {
|
||||||
.icon {
|
color: inherit;
|
||||||
vertical-align: middle;
|
|
||||||
margin-right: 10px;
|
|
||||||
@include font-size(14);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.label {
|
.label {
|
||||||
vertical-align: middle;
|
color: $dark_mode_text_primary;
|
||||||
@include font-size(14);
|
|
||||||
font-weight: 700;
|
|
||||||
color: $text;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark {
|
|
||||||
.mobile-action-button {
|
|
||||||
background: $dark_mode_foreground;
|
|
||||||
|
|
||||||
path, line, polyline, rect, circle {
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
.label {
|
|
||||||
color: $dark_mode_text_primary;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -2,37 +2,35 @@
|
|||||||
<MenuMobile name="file-menu">
|
<MenuMobile name="file-menu">
|
||||||
<ThumbnailItem class="m-5" :item="clipboard[0]" />
|
<ThumbnailItem class="m-5" :item="clipboard[0]" />
|
||||||
|
|
||||||
<MenuMobileGroup v-if="$slots.default">
|
<MenuMobileGroup v-if="$slots.default">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</MenuMobileGroup>
|
</MenuMobileGroup>
|
||||||
|
|
||||||
<MenuMobileGroup v-if="$slots.editor && $checkPermission('editor')">
|
<MenuMobileGroup v-if="$slots.editor && $checkPermission('editor')">
|
||||||
<slot name="editor"></slot>
|
<slot name="editor"></slot>
|
||||||
</MenuMobileGroup>
|
</MenuMobileGroup>
|
||||||
|
|
||||||
<MenuMobileGroup v-if="$slots.visitor && $checkPermission('visitor')">
|
<MenuMobileGroup v-if="$slots.visitor && $checkPermission('visitor')">
|
||||||
<slot name="visitor"></slot>
|
<slot name="visitor"></slot>
|
||||||
</MenuMobileGroup>
|
</MenuMobileGroup>
|
||||||
</MenuMobile>
|
</MenuMobile>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import MenuMobileGroup from "../Mobile/MenuMobileGroup";
|
import MenuMobileGroup from '../Mobile/MenuMobileGroup'
|
||||||
import ThumbnailItem from "../Others/ThumbnailItem";
|
import ThumbnailItem from '../Others/ThumbnailItem'
|
||||||
import MenuMobile from "../Mobile/MenuMobile";
|
import MenuMobile from '../Mobile/MenuMobile'
|
||||||
import {mapGetters} from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'MobileContextMenu',
|
name: 'MobileContextMenu',
|
||||||
components: {
|
components: {
|
||||||
MenuMobileGroup,
|
MenuMobileGroup,
|
||||||
ThumbnailItem,
|
ThumbnailItem,
|
||||||
MenuMobile,
|
MenuMobile,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters([
|
...mapGetters(['clipboard']),
|
||||||
'clipboard',
|
|
||||||
]),
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<MenuMobile @click.native.capture="closeMenu" name="create-list">
|
<MenuMobile @click.native.capture="closeMenu" name="create-list">
|
||||||
<MenuMobileGroup>
|
<MenuMobileGroup>
|
||||||
<slot />
|
<slot />
|
||||||
</MenuMobileGroup>
|
</MenuMobileGroup>
|
||||||
</MenuMobile>
|
</MenuMobile>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import MenuMobileGroup from "../Mobile/MenuMobileGroup";
|
import MenuMobileGroup from '../Mobile/MenuMobileGroup'
|
||||||
import MenuMobile from "../Mobile/MenuMobile";
|
import MenuMobile from '../Mobile/MenuMobile'
|
||||||
import {events} from "../../bus";
|
import { events } from '../../bus'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'MobileContextMenu',
|
name: 'MobileContextMenu',
|
||||||
@@ -18,9 +18,9 @@ export default {
|
|||||||
MenuMobile,
|
MenuMobile,
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
closeMenu() {
|
closeMenu() {
|
||||||
events.$emit('mobile-menu:hide')
|
events.$emit('mobile-menu:hide')
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<transition name="context-menu">
|
<transition name="context-menu">
|
||||||
<div v-if="isMultiSelectMode" class="multiselect-actions">
|
<div v-if="isMultiSelectMode" class="multiselect-actions">
|
||||||
<slot v-if="$slots.default" />
|
<slot v-if="$slots.default" />
|
||||||
<slot v-if="$slots.editor && $checkPermission('editor')" name="editor" />
|
<slot v-if="$slots.editor && $checkPermission('editor')" name="editor" />
|
||||||
<slot v-if="$slots.visitor && $checkPermission('visitor')" name="visitor" />
|
<slot v-if="$slots.visitor && $checkPermission('visitor')" name="visitor" />
|
||||||
|
|
||||||
<ToolbarButton @click.native="closeSelecting" class="action-btn close-icon" source="close" :action="$t('actions.close')" />
|
<ToolbarButton @click.native="closeSelecting" class="action-btn close-icon" source="close" :action="$t('actions.close')" />
|
||||||
</div>
|
</div>
|
||||||
@@ -11,31 +11,28 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ToolbarButton from "./ToolbarButton";
|
import ToolbarButton from './ToolbarButton'
|
||||||
import {mapGetters} from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'MobileMultiSelectToolbar',
|
name: 'MobileMultiSelectToolbar',
|
||||||
components: {
|
components: {
|
||||||
ToolbarButton,
|
ToolbarButton,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters([
|
...mapGetters(['isMultiSelectMode', 'clipboard']),
|
||||||
'isMultiSelectMode',
|
|
||||||
'clipboard',
|
|
||||||
]),
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
closeSelecting() {
|
closeSelecting() {
|
||||||
this.$store.commit('TOGGLE_MULTISELECT_MODE')
|
this.$store.commit('TOGGLE_MULTISELECT_MODE')
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "resources/sass/vuefilemanager/_variables";
|
@import 'resources/sass/vuefilemanager/_variables';
|
||||||
@import "resources/sass/vuefilemanager/_mixins";
|
@import 'resources/sass/vuefilemanager/_mixins';
|
||||||
|
|
||||||
.multiselect-actions {
|
.multiselect-actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -71,7 +68,6 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.options {
|
.options {
|
||||||
|
|
||||||
&.is-active {
|
&.is-active {
|
||||||
opacity: 1 !important;
|
opacity: 1 !important;
|
||||||
pointer-events: initial !important;
|
pointer-events: initial !important;
|
||||||
@@ -80,7 +76,6 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.dark {
|
.dark {
|
||||||
|
|
||||||
.multiselect-actions {
|
.multiselect-actions {
|
||||||
background: $dark_mode_foreground;
|
background: $dark_mode_foreground;
|
||||||
}
|
}
|
||||||
@@ -111,5 +106,4 @@ export default {
|
|||||||
.context-menu-leave-active {
|
.context-menu-leave-active {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,24 +1,24 @@
|
|||||||
<template>
|
<template>
|
||||||
<MenuMobile name="team-menu">
|
<MenuMobile name="team-menu">
|
||||||
<TeamFolderPreview />
|
<TeamFolderPreview />
|
||||||
|
|
||||||
<MenuMobileGroup v-if="$slots.default">
|
<MenuMobileGroup v-if="$slots.default">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</MenuMobileGroup>
|
</MenuMobileGroup>
|
||||||
</MenuMobile>
|
</MenuMobile>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import MenuMobileGroup from "../Mobile/MenuMobileGroup";
|
import MenuMobileGroup from '../Mobile/MenuMobileGroup'
|
||||||
import TeamFolderPreview from '../Teams/Components/TeamFolderPreview'
|
import TeamFolderPreview from '../Teams/Components/TeamFolderPreview'
|
||||||
import MenuMobile from "../Mobile/MenuMobile";
|
import MenuMobile from '../Mobile/MenuMobile'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'MobileTeamContextMenu',
|
name: 'MobileTeamContextMenu',
|
||||||
components: {
|
components: {
|
||||||
TeamFolderPreview,
|
TeamFolderPreview,
|
||||||
MenuMobileGroup,
|
MenuMobileGroup,
|
||||||
MenuMobile,
|
MenuMobile,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,90 +1,96 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="sticky top-0 dark:bg-dark-background bg-white flex text-center py-5 px-4 w-full justify-between items-center z-20 lg:hidden block">
|
<div class="sticky top-0 z-20 block flex w-full items-center justify-between bg-white py-5 px-4 text-center dark:bg-dark-background lg:hidden">
|
||||||
|
|
||||||
<!-- Go back-->
|
<!-- Go back-->
|
||||||
<div @click="goBack" class="go-back-button flex text-left items-center">
|
<div @click="goBack" class="go-back-button flex items-center text-left">
|
||||||
<chevron-left-icon size="17" :class="{'opacity-0 -translate-x-3': ! isLoadedFolder, 'opacity-100 translate-x-0': isLoadedFolder }" class="transform align-middle cursor-pointer mr-2 -ml-1 transition-all duration-200" />
|
<chevron-left-icon
|
||||||
|
size="17"
|
||||||
|
:class="{
|
||||||
|
'-translate-x-3 opacity-0': !isLoadedFolder,
|
||||||
|
'translate-x-0 opacity-100': isLoadedFolder,
|
||||||
|
}"
|
||||||
|
class="mr-2 -ml-1 transform cursor-pointer align-middle transition-all duration-200"
|
||||||
|
/>
|
||||||
|
|
||||||
<!--Folder Title-->
|
<!--Folder Title-->
|
||||||
<div :class="{'-translate-x-4': ! isLoadedFolder}" class="transform lg:text-base text-sm align-middle font-bold overflow-hidden text-ellipsis inline-block whitespace-nowrap transition-all duration-200" style="max-width: 200px;">
|
<div
|
||||||
{{ $getCurrentLocationName() }}
|
:class="{ '-translate-x-4': !isLoadedFolder }"
|
||||||
</div>
|
class="inline-block transform overflow-hidden text-ellipsis whitespace-nowrap align-middle text-sm font-bold transition-all duration-200 lg:text-base"
|
||||||
|
style="max-width: 200px"
|
||||||
|
>
|
||||||
|
{{ $getCurrentLocationName() }}
|
||||||
|
</div>
|
||||||
|
|
||||||
<span @click.stop="showItemActions" :class="{'-translate-x-4 opacity-0': ! currentFolder, 'translate-x-0 opacity-100': currentFolder}" class="transform py-0.5 px-1.5 ml-3 rounded-md dark:bg-dark-foreground bg-light-background transition-all duration-200">
|
<span
|
||||||
<more-horizontal-icon size="14" />
|
@click.stop="showItemActions"
|
||||||
</span>
|
:class="{
|
||||||
|
'-translate-x-4 opacity-0': !currentFolder,
|
||||||
|
'translate-x-0 opacity-100': currentFolder,
|
||||||
|
}"
|
||||||
|
class="ml-3 transform rounded-md bg-light-background py-0.5 px-1.5 transition-all duration-200 dark:bg-dark-foreground"
|
||||||
|
>
|
||||||
|
<more-horizontal-icon size="14" />
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex items-center relative">
|
<div class="relative flex items-center">
|
||||||
<TeamMembersButton
|
<TeamMembersButton v-if="$isThisRoute($route, ['TeamFolders', 'SharedWithMe'])" size="28" @click.stop.native="$showMobileMenu('team-menu')" class="absolute right-9" />
|
||||||
v-if="$isThisRoute($route, ['TeamFolders', 'SharedWithMe'])"
|
|
||||||
size="28"
|
|
||||||
@click.stop.native="$showMobileMenu('team-menu')"
|
|
||||||
class="absolute right-9"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!--More Actions-->
|
<!--More Actions-->
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<div v-if="$checkPermission('master')" @click="showMobileNavigation" class="absolute right-0 p-4 -mr-2 transform -translate-y-2/4">
|
<div v-if="$checkPermission('master')" @click="showMobileNavigation" class="absolute right-0 -mr-2 -translate-y-2/4 transform p-4">
|
||||||
<menu-icon size="17" />
|
<menu-icon size="17" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import TeamMembersPreview from "../Teams/Components/TeamMembersPreview";
|
import TeamMembersPreview from '../Teams/Components/TeamMembersPreview'
|
||||||
import TeamMembersButton from "../Teams/Components/TeamMembersButton";
|
import TeamMembersButton from '../Teams/Components/TeamMembersButton'
|
||||||
import ToolbarButton from "./ToolbarButton";
|
import ToolbarButton from './ToolbarButton'
|
||||||
import SearchBar from "./SearchBar";
|
import SearchBar from './SearchBar'
|
||||||
import {MenuIcon, ChevronLeftIcon, MoreHorizontalIcon } from 'vue-feather-icons'
|
import { MenuIcon, ChevronLeftIcon, MoreHorizontalIcon } from 'vue-feather-icons'
|
||||||
import {mapGetters} from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
import {events} from "../../bus";
|
import { events } from '../../bus'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'MobileToolBar',
|
name: 'MobileToolBar',
|
||||||
components: {
|
components: {
|
||||||
TeamMembersPreview,
|
TeamMembersPreview,
|
||||||
MoreHorizontalIcon,
|
MoreHorizontalIcon,
|
||||||
TeamMembersButton,
|
TeamMembersButton,
|
||||||
ChevronLeftIcon,
|
ChevronLeftIcon,
|
||||||
ToolbarButton,
|
ToolbarButton,
|
||||||
SearchBar,
|
SearchBar,
|
||||||
MenuIcon,
|
MenuIcon,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters(['currentTeamFolder', 'isVisibleSidebar', 'currentFolder', 'itemViewType', 'clipboard']),
|
||||||
|
isLoadedFolder() {
|
||||||
|
return this.$route.params.id
|
||||||
},
|
},
|
||||||
computed: {
|
},
|
||||||
...mapGetters([
|
methods: {
|
||||||
'currentTeamFolder',
|
showItemActions() {
|
||||||
'isVisibleSidebar',
|
this.$store.commit('CLIPBOARD_CLEAR')
|
||||||
'currentFolder',
|
this.$store.commit('ADD_ITEM_TO_CLIPBOARD', this.currentFolder)
|
||||||
'itemViewType',
|
|
||||||
'clipboard',
|
|
||||||
]),
|
|
||||||
isLoadedFolder() {
|
|
||||||
return this.$route.params.id
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
showItemActions() {
|
|
||||||
this.$store.commit('CLIPBOARD_CLEAR')
|
|
||||||
this.$store.commit('ADD_ITEM_TO_CLIPBOARD', this.currentFolder)
|
|
||||||
|
|
||||||
this.$showMobileMenu('file-menu')
|
this.$showMobileMenu('file-menu')
|
||||||
events.$emit('mobile-context-menu:show', this.currentFolder)
|
events.$emit('mobile-context-menu:show', this.currentFolder)
|
||||||
},
|
|
||||||
showMobileNavigation() {
|
|
||||||
this.$showMobileMenu('user-navigation')
|
|
||||||
this.$store.commit('DISABLE_MULTISELECT_MODE')
|
|
||||||
},
|
|
||||||
goBack() {
|
|
||||||
if (this.isLoadedFolder) this.$router.back()
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
created() {
|
showMobileNavigation() {
|
||||||
events.$on('show:content', () => {
|
this.$showMobileMenu('user-navigation')
|
||||||
if (this.isSidebarMenu) this.isSidebarMenu = false
|
this.$store.commit('DISABLE_MULTISELECT_MODE')
|
||||||
})
|
},
|
||||||
}
|
goBack() {
|
||||||
}
|
if (this.isLoadedFolder) this.$router.back()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
events.$on('show:content', () => {
|
||||||
|
if (this.isSidebarMenu) this.isSidebarMenu = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,63 +1,68 @@
|
|||||||
<template>
|
<template>
|
||||||
<li class="2xl:py-4 xl:py-3 lg:py-2.5 py-4 px-5 flex items-center justify-between" :class="{'dark:hover:bg-4x-dark-foreground hover:bg-light-background cursor-pointer group': ! isHoverDisabled}">
|
<li
|
||||||
|
class="flex items-center justify-between py-4 px-5 lg:py-2.5 xl:py-3 2xl:py-4"
|
||||||
|
:class="{
|
||||||
|
'group cursor-pointer hover:bg-light-background dark:hover:bg-4x-dark-foreground': !isHoverDisabled,
|
||||||
|
}"
|
||||||
|
>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="mr-4">
|
<div class="mr-4">
|
||||||
<calendar-icon v-if="icon === 'calendar'" size="17" class="vue-feather group-hover-text-theme" :class="{'text-theme': isActive}"/>
|
<calendar-icon v-if="icon === 'calendar'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||||
<grid-icon v-if="icon === 'grid'" size="17" class="vue-feather group-hover-text-theme" :class="{'text-theme': isActive}"/>
|
<grid-icon v-if="icon === 'grid'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||||
<list-icon v-if="icon === 'list'" size="17" class="vue-feather group-hover-text-theme" :class="{'text-theme': isActive}"/>
|
<list-icon v-if="icon === 'list'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||||
<trash-2-icon v-if="icon === 'trash'" size="17" class="vue-feather group-hover-text-theme" :class="{'text-theme': isActive}"/>
|
<trash-2-icon v-if="icon === 'trash'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||||
<life-buoy-icon v-if="icon === 'restore'" size="17" class="vue-feather group-hover-text-theme" :class="{'text-theme': isActive}"/>
|
<life-buoy-icon v-if="icon === 'restore'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||||
<trash-icon v-if="icon === 'empty-trash'" size="17" class="vue-feather group-hover-text-theme" :class="{'text-theme': isActive}"/>
|
<trash-icon v-if="icon === 'empty-trash'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||||
<eye-icon v-if="icon ==='detail'" size="17" class="vue-feather group-hover-text-theme" :class="{'text-theme': isActive}"/>
|
<eye-icon v-if="icon === 'detail'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||||
<download-cloud-icon v-if="icon === 'download'" size="17" class="vue-feather group-hover-text-theme" :class="{'text-theme': isActive}"/>
|
<download-cloud-icon v-if="icon === 'download'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||||
<edit2-icon v-if="icon === 'rename'" size="17" class="vue-feather group-hover-text-theme" :class="{'text-theme': isActive}"/>
|
<edit2-icon v-if="icon === 'rename'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||||
<corner-down-right-icon v-if="icon === 'move-item'" size="17" class="vue-feather group-hover-text-theme" :class="{'text-theme': isActive}"/>
|
<corner-down-right-icon v-if="icon === 'move-item'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||||
<link-icon v-if="icon === 'share'" size="17" class="vue-feather group-hover-text-theme" :class="{'text-theme': isActive}"/>
|
<link-icon v-if="icon === 'share'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||||
<star-icon v-if="icon === 'favourites'" size="17" class="vue-feather group-hover-text-theme" :class="{'text-theme': isActive}"/>
|
<star-icon v-if="icon === 'favourites'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||||
<folder-plus-icon v-if="icon === 'create-folder'" size="17" class="vue-feather group-hover-text-theme" :class="{'text-theme': isActive}"/>
|
<folder-plus-icon v-if="icon === 'create-folder'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||||
<smile-icon v-if="icon === 'no-options'" size="17" class="vue-feather group-hover-text-theme" :class="{'text-theme': isActive}"/>
|
<smile-icon v-if="icon === 'no-options'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||||
<paperclip-icon v-if="icon === 'zip-folder'" size="17" class="vue-feather group-hover-text-theme" :class="{'text-theme': isActive}"/>
|
<paperclip-icon v-if="icon === 'zip-folder'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||||
<alphabet-icon v-if="icon === 'alphabet'" size="17" class="vue-feather group-hover-text-theme" :class="{'text-theme': isActive}"/>
|
<alphabet-icon v-if="icon === 'alphabet'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||||
<star-icon v-if="icon === 'star'" size="17" class="vue-feather group-hover-text-theme" :class="{'text-theme': isActive}"/>
|
<star-icon v-if="icon === 'star'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||||
<hard-drive-icon v-if="icon === 'hard-drive'" size="17" class="vue-feather group-hover-text-theme" :class="{'text-theme': isActive}"/>
|
<hard-drive-icon v-if="icon === 'hard-drive'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||||
<upload-cloud-icon v-if="icon === 'upload-cloud'" size="17" class="vue-feather group-hover-text-theme" :class="{'text-theme': isActive}"/>
|
<upload-cloud-icon v-if="icon === 'upload-cloud'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||||
<users-icon v-if="icon === 'users'" size="17" class="vue-feather group-hover-text-theme" :class="{'text-theme': isActive}"/>
|
<users-icon v-if="icon === 'users'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||||
<user-icon v-if="icon === 'user'" size="17" class="vue-feather group-hover-text-theme" :class="{'text-theme': isActive}"/>
|
<user-icon v-if="icon === 'user'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||||
<user-plus-icon v-if="icon === 'user-plus'" size="17" class="vue-feather group-hover-text-theme" :class="{'text-theme': isActive}"/>
|
<user-plus-icon v-if="icon === 'user-plus'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||||
<user-minus-icon v-if="icon === 'user-minus'" size="17" class="vue-feather group-hover-text-theme" :class="{'text-theme': isActive}"/>
|
<user-minus-icon v-if="icon === 'user-minus'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||||
<user-check-icon v-if="icon === 'user-check'" size="17" class="vue-feather group-hover-text-theme" :class="{'text-theme': isActive}"/>
|
<user-check-icon v-if="icon === 'user-check'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||||
<settings-icon v-if="icon === 'settings'" size="17" class="vue-feather group-hover-text-theme" :class="{'text-theme': isActive}"/>
|
<settings-icon v-if="icon === 'settings'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||||
<power-icon v-if="icon === 'power'" size="17" class="vue-feather group-hover-text-theme" :class="{'text-theme': isActive}"/>
|
<power-icon v-if="icon === 'power'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||||
<lock-icon v-if="icon === 'lock'" size="17" class="vue-feather group-hover-text-theme" :class="{'text-theme': isActive}"/>
|
<lock-icon v-if="icon === 'lock'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||||
<cloud-icon v-if="icon === 'cloud'" size="17" class="vue-feather group-hover-text-theme" :class="{'text-theme': isActive}"/>
|
<cloud-icon v-if="icon === 'cloud'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||||
<credit-card-icon v-if="icon === 'credit-card'" size="17" class="vue-feather group-hover-text-theme" :class="{'text-theme': isActive}"/>
|
<credit-card-icon v-if="icon === 'credit-card'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||||
<file-text-icon v-if="icon === 'file-text'" size="17" class="vue-feather group-hover-text-theme" :class="{'text-theme': isActive}"/>
|
<file-text-icon v-if="icon === 'file-text'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||||
<database-icon v-if="icon === 'database'" size="17" class="vue-feather group-hover-text-theme" :class="{'text-theme': isActive}"/>
|
<database-icon v-if="icon === 'database'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||||
<globe-icon v-if="icon === 'globe'" size="17" class="vue-feather group-hover-text-theme" :class="{'text-theme': isActive}"/>
|
<globe-icon v-if="icon === 'globe'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||||
<monitor-icon v-if="icon === 'monitor'" size="17" class="vue-feather group-hover-text-theme" :class="{'text-theme': isActive}"/>
|
<monitor-icon v-if="icon === 'monitor'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||||
<box-icon v-if="icon === 'box'" size="17" class="vue-feather group-hover-text-theme" :class="{'text-theme': isActive}"/>
|
<box-icon v-if="icon === 'box'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||||
<folder-plus-icon v-if="icon === 'folder-plus'" size="17" class="vue-feather group-hover-text-theme" :class="{'text-theme': isActive}"/>
|
<folder-plus-icon v-if="icon === 'folder-plus'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||||
</div>
|
</div>
|
||||||
<b class="font-bold text-sm group-hover-text-theme" :class="{'text-theme': isActive}">
|
<b class="group-hover-text-theme text-sm font-bold" :class="{ 'text-theme': isActive }">
|
||||||
{{ title }}
|
{{ title }}
|
||||||
</b>
|
</b>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="arrow" class="ml-2">
|
<div v-if="arrow" class="ml-2">
|
||||||
<chevron-right-icon v-if="arrow === 'right'" size="14" class="vue-feather group-hover-text-theme opacity-50" :class="{'text-theme': isActive}"/>
|
<chevron-right-icon v-if="arrow === 'right'" size="14" class="vue-feather group-hover-text-theme opacity-50" :class="{ 'text-theme': isActive }" />
|
||||||
<arrow-up-icon v-if="arrow === 'up'" size="14" class="vue-feather group-hover-text-theme opacity-50" :class="{'text-theme': isActive}"/>
|
<arrow-up-icon v-if="arrow === 'up'" size="14" class="vue-feather group-hover-text-theme opacity-50" :class="{ 'text-theme': isActive }" />
|
||||||
<arrow-down-icon v-if="arrow === 'down'" size="14" class="vue-feather group-hover-text-theme opacity-50" :class="{'text-theme': isActive}"/>
|
<arrow-down-icon v-if="arrow === 'down'" size="14" class="vue-feather group-hover-text-theme opacity-50" :class="{ 'text-theme': isActive }" />
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import AlphabetIcon from "./Icons/AlphabetIcon";
|
import AlphabetIcon from './Icons/AlphabetIcon'
|
||||||
import {
|
import {
|
||||||
UserMinusIcon,
|
UserMinusIcon,
|
||||||
UserCheckIcon,
|
UserCheckIcon,
|
||||||
UserPlusIcon,
|
UserPlusIcon,
|
||||||
ArrowUpIcon,
|
ArrowUpIcon,
|
||||||
ArrowDownIcon,
|
ArrowDownIcon,
|
||||||
ChevronRightIcon,
|
ChevronRightIcon,
|
||||||
BoxIcon,
|
BoxIcon,
|
||||||
MonitorIcon,
|
MonitorIcon,
|
||||||
@@ -90,52 +95,46 @@ import {
|
|||||||
DatabaseIcon,
|
DatabaseIcon,
|
||||||
} from 'vue-feather-icons'
|
} from 'vue-feather-icons'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Option',
|
name: 'Option',
|
||||||
props:[
|
props: ['isHoverDisabled', 'isActive', 'title', 'arrow', 'icon'],
|
||||||
'isHoverDisabled',
|
components: {
|
||||||
'isActive',
|
UserMinusIcon,
|
||||||
'title',
|
UserCheckIcon,
|
||||||
'arrow',
|
UserPlusIcon,
|
||||||
'icon'
|
ArrowUpIcon,
|
||||||
],
|
ArrowDownIcon,
|
||||||
components: {
|
BoxIcon,
|
||||||
UserMinusIcon,
|
MonitorIcon,
|
||||||
UserCheckIcon,
|
GlobeIcon,
|
||||||
UserPlusIcon,
|
DatabaseIcon,
|
||||||
ArrowUpIcon,
|
ChevronRightIcon,
|
||||||
ArrowDownIcon,
|
FileTextIcon,
|
||||||
BoxIcon,
|
CreditCardIcon,
|
||||||
MonitorIcon,
|
CloudIcon,
|
||||||
GlobeIcon,
|
LockIcon,
|
||||||
DatabaseIcon,
|
CornerDownRightIcon,
|
||||||
ChevronRightIcon,
|
DownloadCloudIcon,
|
||||||
FileTextIcon,
|
UploadCloudIcon,
|
||||||
CreditCardIcon,
|
FolderPlusIcon,
|
||||||
CloudIcon,
|
HardDriveIcon,
|
||||||
LockIcon,
|
PaperclipIcon,
|
||||||
CornerDownRightIcon,
|
SettingsIcon,
|
||||||
DownloadCloudIcon,
|
LifeBuoyIcon,
|
||||||
UploadCloudIcon,
|
CalendarIcon,
|
||||||
FolderPlusIcon,
|
AlphabetIcon,
|
||||||
HardDriveIcon,
|
Trash2Icon,
|
||||||
PaperclipIcon,
|
SmileIcon,
|
||||||
SettingsIcon,
|
PowerIcon,
|
||||||
LifeBuoyIcon,
|
UsersIcon,
|
||||||
CalendarIcon,
|
Edit2Icon,
|
||||||
AlphabetIcon,
|
TrashIcon,
|
||||||
Trash2Icon,
|
LinkIcon,
|
||||||
SmileIcon,
|
StarIcon,
|
||||||
PowerIcon,
|
GridIcon,
|
||||||
UsersIcon,
|
ListIcon,
|
||||||
Edit2Icon,
|
UserIcon,
|
||||||
TrashIcon,
|
EyeIcon,
|
||||||
LinkIcon,
|
},
|
||||||
StarIcon,
|
}
|
||||||
GridIcon,
|
|
||||||
ListIcon,
|
|
||||||
UserIcon,
|
|
||||||
EyeIcon,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -5,20 +5,19 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'OptionGroup'
|
name: 'OptionGroup',
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.option-group {
|
.option-group {
|
||||||
|
&:first-child {
|
||||||
|
padding-top: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
&:first-child {
|
&:last-child {
|
||||||
padding-top: 0 !important;
|
padding-bottom: 0 !important;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
&:last-child {
|
|
||||||
padding-bottom: 0 !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,63 +1,41 @@
|
|||||||
<template>
|
<template>
|
||||||
<label class="menu-option group">
|
<label class="menu-option group">
|
||||||
<div class="icon-left group-hover-text-theme">
|
<div class="icon-left group-hover-text-theme">
|
||||||
<upload-cloud-icon v-if="type === 'file'" size="17" class="group-hover-text-theme"/>
|
<upload-cloud-icon v-if="type === 'file'" size="17" class="group-hover-text-theme" />
|
||||||
<folder-upload-icon v-if="type === 'folder'" size="17" class="group-hover-text-theme"/>
|
<folder-upload-icon v-if="type === 'folder'" size="17" class="group-hover-text-theme" />
|
||||||
</div>
|
</div>
|
||||||
<div class="text-label group-hover-text-theme">
|
<div class="text-label group-hover-text-theme">
|
||||||
{{ title }}
|
{{ title }}
|
||||||
|
|
||||||
<input
|
<input v-if="type === 'file'" @change="emmitFiles" v-show="false" id="file" type="file" name="files[]" multiple />
|
||||||
v-if="type === 'file'"
|
|
||||||
@change="emmitFiles"
|
|
||||||
v-show="false"
|
|
||||||
id="file"
|
|
||||||
type="file"
|
|
||||||
name="files[]"
|
|
||||||
multiple
|
|
||||||
/>
|
|
||||||
|
|
||||||
<input
|
<input v-if="type === 'folder'" @change="emmitFiles" v-show="false" id="folder" type="file" name="folders[]" webkitdirectory mozdirectory />
|
||||||
v-if="type === 'folder'"
|
|
||||||
@change="emmitFiles"
|
|
||||||
v-show="false"
|
|
||||||
id="folder"
|
|
||||||
type="file"
|
|
||||||
name="folders[]"
|
|
||||||
webkitdirectory
|
|
||||||
mozdirectory
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import FolderUploadIcon from "./Icons/FolderUploadIcon";
|
import FolderUploadIcon from './Icons/FolderUploadIcon'
|
||||||
import {
|
import { UploadCloudIcon } from 'vue-feather-icons'
|
||||||
UploadCloudIcon,
|
|
||||||
} from 'vue-feather-icons'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Option',
|
name: 'Option',
|
||||||
props:[
|
props: ['title', 'type'],
|
||||||
'title',
|
components: {
|
||||||
'type',
|
FolderUploadIcon,
|
||||||
],
|
UploadCloudIcon,
|
||||||
components: {
|
},
|
||||||
FolderUploadIcon,
|
methods: {
|
||||||
UploadCloudIcon,
|
emmitFiles(e) {
|
||||||
|
this.$uploadFiles(e.target.files)
|
||||||
},
|
},
|
||||||
methods: {
|
},
|
||||||
emmitFiles(e) {
|
}
|
||||||
this.$uploadFiles(e.target.files)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "resources/sass/vuefilemanager/_variables";
|
@import 'resources/sass/vuefilemanager/_variables';
|
||||||
@import "resources/sass/vuefilemanager/_mixins";
|
@import 'resources/sass/vuefilemanager/_mixins';
|
||||||
|
|
||||||
.menu-option {
|
.menu-option {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
@@ -94,14 +72,12 @@ import {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.dark {
|
.dark {
|
||||||
|
|
||||||
.menu-option {
|
.menu-option {
|
||||||
color: $dark_mode_text_primary;
|
color: $dark_mode_text_primary;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: lighten($dark_mode_foreground, 2%);
|
background: lighten($dark_mode_foreground, 2%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<div class="popup-wrapper">
|
<div class="popup-wrapper">
|
||||||
<div class="popup-content">
|
<div class="popup-content">
|
||||||
<div class="spinner-wrapper">
|
<div class="spinner-wrapper">
|
||||||
<Spinner/>
|
<Spinner />
|
||||||
</div>
|
</div>
|
||||||
<h1 class="title">{{ processingPopup.title }}</h1>
|
<h1 class="title">{{ processingPopup.title }}</h1>
|
||||||
<p class="message">{{ processingPopup.message }}</p>
|
<p class="message">{{ processingPopup.message }}</p>
|
||||||
@@ -15,19 +15,17 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Spinner from "./Spinner";
|
import Spinner from './Spinner'
|
||||||
import { mapGetters } from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ProcessingPopup',
|
name: 'ProcessingPopup',
|
||||||
components: {
|
components: {
|
||||||
Spinner
|
Spinner,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters([
|
...mapGetters(['processingPopup']),
|
||||||
'processingPopup'
|
},
|
||||||
])
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -68,7 +66,6 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.popup-content {
|
.popup-content {
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
@include font-size(22);
|
@include font-size(22);
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
@@ -90,7 +87,6 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.popup-content {
|
.popup-content {
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
@include font-size(19);
|
@include font-size(19);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,46 +1,44 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="progress-bar">
|
<div class="progress-bar">
|
||||||
<span class="bg-theme" :style="{ width: progress + '%' }"></span>
|
<span class="bg-theme" :style="{ width: progress + '%' }"></span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'ProgressBar',
|
name: 'ProgressBar',
|
||||||
props: ['progress']
|
props: ['progress'],
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import '../../../sass/vuefilemanager/variables';
|
@import '../../../sass/vuefilemanager/variables';
|
||||||
@import '../../../sass/vuefilemanager/mixins';
|
@import '../../../sass/vuefilemanager/mixins';
|
||||||
|
|
||||||
.progress-bar {
|
.progress-bar {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 5px;
|
height: 5px;
|
||||||
background: $light_background;
|
background: $light_background;
|
||||||
margin-top: 6px;
|
margin-top: 6px;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
|
|
||||||
span {
|
span {
|
||||||
display: block;
|
display: block;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark {
|
.dark {
|
||||||
|
.progress-bar {
|
||||||
|
background: $dark_mode_foreground;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.progress-bar {
|
@media only screen and (min-width: 680px) {
|
||||||
background: $dark_mode_foreground;
|
.dark .progress-bar {
|
||||||
}
|
background: $dark_mode_foreground;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
@media only screen and (min-width: 680px) {
|
|
||||||
|
|
||||||
.dark .progress-bar {
|
|
||||||
background: $dark_mode_foreground;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,31 +1,31 @@
|
|||||||
<template>
|
<template>
|
||||||
<div @click="$openSpotlight()" class="relative dark:bg-dark-foreground bg-light-background rounded-lg cursor-pointer">
|
<div @click="$openSpotlight()" class="relative cursor-pointer rounded-lg bg-light-background dark:bg-dark-foreground">
|
||||||
<div class="flex justify-between items-center px-5 py-2.5 xl:w-72 w-56 text-left">
|
<div class="flex w-56 items-center justify-between px-5 py-2.5 text-left xl:w-72">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<search-icon size="18" class="vue-feather dark:text-gray-600 text-gray-400" />
|
<search-icon size="18" class="vue-feather text-gray-400 dark:text-gray-600" />
|
||||||
<span class="font-bold xl:text-sm text-xs dark:text-gray-600 text-gray-400 pl-2.5">
|
<span class="pl-2.5 text-xs font-bold text-gray-400 dark:text-gray-600 xl:text-sm">
|
||||||
{{ $t('inputs.placeholder_search_files') }}
|
{{ $t('inputs.placeholder_search_files') }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<span class="font-bold xl:text-sm text-xs dark:text-gray-600 text-gray-400 dark:border-opacity-5 border rounded px-1 py-0.5 tracking-normal">
|
<span class="rounded border px-1 py-0.5 text-xs font-bold tracking-normal text-gray-400 dark:border-opacity-5 dark:text-gray-600 xl:text-sm">
|
||||||
{{ metaKeyIcon }}+K
|
{{ metaKeyIcon }}+K
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {SearchIcon} from 'vue-feather-icons'
|
import { SearchIcon } from 'vue-feather-icons'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'SearchBar',
|
name: 'SearchBar',
|
||||||
components: {
|
components: {
|
||||||
SearchIcon,
|
SearchIcon,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
metaKeyIcon() {
|
||||||
|
return this.$isApple() ? '⌘' : '⊞'
|
||||||
},
|
},
|
||||||
computed: {
|
},
|
||||||
metaKeyIcon() {
|
}
|
||||||
return this.$isApple() ? '⌘' : '⊞'
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -5,40 +5,40 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'Spinner'
|
name: 'Spinner',
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import '../../../sass/vuefilemanager/variables';
|
@import '../../../sass/vuefilemanager/variables';
|
||||||
@import '../../../sass/vuefilemanager/mixins';
|
@import '../../../sass/vuefilemanager/mixins';
|
||||||
|
|
||||||
#loading-bar-spinner.spinner {
|
#loading-bar-spinner.spinner {
|
||||||
left: 50%;
|
left: 50%;
|
||||||
margin-left: -20px;
|
margin-left: -20px;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
margin-top: -20px;
|
margin-top: -20px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 19 !important;
|
z-index: 19 !important;
|
||||||
animation: loading-bar-spinner 400ms linear infinite;
|
animation: loading-bar-spinner 400ms linear infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
#loading-bar-spinner.spinner .spinner-icon {
|
#loading-bar-spinner.spinner .spinner-icon {
|
||||||
width: 40px;
|
width: 40px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
border: solid 4px transparent;
|
border: solid 4px transparent;
|
||||||
//border-top-color: $theme !important;
|
//border-top-color: $theme !important;
|
||||||
//border-left-color: $theme !important;
|
//border-left-color: $theme !important;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes loading-bar-spinner {
|
@keyframes loading-bar-spinner {
|
||||||
0% {
|
0% {
|
||||||
transform: rotate(0deg);
|
transform: rotate(0deg);
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -2,44 +2,34 @@
|
|||||||
<div class="flex items-start">
|
<div class="flex items-start">
|
||||||
<div class="mr-2">
|
<div class="mr-2">
|
||||||
<CheckSquareIcon v-if="icon === 'check-square'" class="text-theme vue-feather" size="19" />
|
<CheckSquareIcon v-if="icon === 'check-square'" class="text-theme vue-feather" size="19" />
|
||||||
<image-icon v-if="icon === 'image'" class="text-theme vue-feather" size="19" />
|
<image-icon v-if="icon === 'image'" class="text-theme vue-feather" size="19" />
|
||||||
<video-icon v-if="icon === 'video'" class="text-theme vue-feather" size="19" />
|
<video-icon v-if="icon === 'video'" class="text-theme vue-feather" size="19" />
|
||||||
<folder-icon v-if="icon === 'folder'" class="text-theme vue-feather" size="19" />
|
<folder-icon v-if="icon === 'folder'" class="text-theme vue-feather" size="19" />
|
||||||
<file-icon v-if="icon === 'file'" class="text-theme vue-feather" size="19" />
|
<file-icon v-if="icon === 'file'" class="text-theme vue-feather" size="19" />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<b class="font-bold text-base inline-block whitespace-nowrap 2xl:w-72 w-52 text-ellipsis overflow-hidden leading-3">
|
<b class="inline-block w-52 overflow-hidden text-ellipsis whitespace-nowrap text-base font-bold leading-3 2xl:w-72">
|
||||||
{{ title }}
|
{{ title }}
|
||||||
</b>
|
</b>
|
||||||
<small class="font-bold text-xs text-gray-400 block">
|
<small class="block text-xs font-bold text-gray-400">
|
||||||
{{ subtitle }}
|
{{ subtitle }}
|
||||||
</small>
|
</small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {
|
import { CheckSquareIcon, FolderIcon, ImageIcon, VideoIcon, FileIcon } from 'vue-feather-icons'
|
||||||
CheckSquareIcon,
|
|
||||||
FolderIcon,
|
|
||||||
ImageIcon,
|
|
||||||
VideoIcon,
|
|
||||||
FileIcon,
|
|
||||||
} from "vue-feather-icons"
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'TitlePreview',
|
name: 'TitlePreview',
|
||||||
props: [
|
props: ['subtitle', 'title', 'icon'],
|
||||||
'subtitle',
|
components: {
|
||||||
'title',
|
CheckSquareIcon,
|
||||||
'icon',
|
FolderIcon,
|
||||||
],
|
ImageIcon,
|
||||||
components: {
|
VideoIcon,
|
||||||
CheckSquareIcon,
|
FileIcon,
|
||||||
FolderIcon,
|
},
|
||||||
ImageIcon,
|
}
|
||||||
VideoIcon,
|
|
||||||
FileIcon,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,32 +1,56 @@
|
|||||||
<template>
|
<template>
|
||||||
<button class="button hover-text-theme hover-svg-stroke-theme" :title="action">
|
<button class="button hover-text-theme hover-svg-stroke-theme" :title="action">
|
||||||
<corner-down-right-icon v-if="source === 'move'" size="19" class="hover-text-theme" />
|
<corner-down-right-icon v-if="source === 'move'" size="19" class="hover-text-theme" />
|
||||||
<download-cloud-icon v-if="source === 'download'" size="19" class="hover-text-theme" />
|
<download-cloud-icon v-if="source === 'download'" size="19" class="hover-text-theme" />
|
||||||
<folder-plus-icon v-if="source === 'folder-plus'" size="19" class="hover-text-theme" />
|
<folder-plus-icon v-if="source === 'folder-plus'" size="19" class="hover-text-theme" />
|
||||||
<user-plus-icon v-if="source === 'user-plus'" size="19" class="hover-text-theme" />
|
<user-plus-icon v-if="source === 'user-plus'" size="19" class="hover-text-theme" />
|
||||||
<zoom-in-icon v-if="source === 'zoom-in'" size="19" />
|
<zoom-in-icon v-if="source === 'zoom-in'" size="19" />
|
||||||
<zoom-out-icon v-if="source === 'zoom-out'" size="19" />
|
<zoom-out-icon v-if="source === 'zoom-out'" size="19" />
|
||||||
<edit-2-icon v-if="source === 'rename'" size="19" />
|
<edit-2-icon v-if="source === 'rename'" size="19" />
|
||||||
<printer-icon v-if="source === 'print'" size="19" />
|
<printer-icon v-if="source === 'print'" size="19" />
|
||||||
<trash-2-icon v-if="source === 'trash'" size="19" />
|
<trash-2-icon v-if="source === 'trash'" size="19" />
|
||||||
<list-icon v-if="source === 'th-list'" size="19" />
|
<list-icon v-if="source === 'th-list'" size="19" />
|
||||||
<info-icon v-if="source === 'info'" size="19" />
|
<info-icon v-if="source === 'info'" size="19" />
|
||||||
<grid-icon v-if="source === 'th'" size="19" />
|
<grid-icon v-if="source === 'th'" size="19" />
|
||||||
<link-icon v-if="source === 'share'" size="19" />
|
<link-icon v-if="source === 'share'" size="19" />
|
||||||
<x-icon v-if="source === 'close'" size="19" />
|
<x-icon v-if="source === 'close'" size="19" />
|
||||||
<search-icon v-if="source === 'search'" size="19" />
|
<search-icon v-if="source === 'search'" size="19" />
|
||||||
<cloud-off-icon v-if="source === 'shared-off'" size="19" />
|
<cloud-off-icon v-if="source === 'shared-off'" size="19" />
|
||||||
<sorting-icon v-if="source === 'preview-sorting'" class="preview-sorting"/>
|
<sorting-icon v-if="source === 'preview-sorting'" class="preview-sorting" />
|
||||||
<CloudPlusIcon v-if="source === 'cloud-plus'" class="preview-sorting"/>
|
<CloudPlusIcon v-if="source === 'cloud-plus'" class="preview-sorting" />
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import SortingIcon from "./Icons/SortingIcon";
|
import SortingIcon from './Icons/SortingIcon'
|
||||||
import CloudPlusIcon from "./Icons/CloudPlusIcon";
|
import CloudPlusIcon from './Icons/CloudPlusIcon'
|
||||||
import {
|
import {
|
||||||
SearchIcon,
|
SearchIcon,
|
||||||
UserPlusIcon,
|
UserPlusIcon,
|
||||||
|
CornerDownRightIcon,
|
||||||
|
DownloadCloudIcon,
|
||||||
|
FolderPlusIcon,
|
||||||
|
CloudOffIcon,
|
||||||
|
PrinterIcon,
|
||||||
|
ZoomOutIcon,
|
||||||
|
ZoomInIcon,
|
||||||
|
Trash2Icon,
|
||||||
|
Edit2Icon,
|
||||||
|
GridIcon,
|
||||||
|
ListIcon,
|
||||||
|
InfoIcon,
|
||||||
|
LinkIcon,
|
||||||
|
XIcon,
|
||||||
|
} from 'vue-feather-icons'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'ToolbarButton',
|
||||||
|
props: ['source', 'action'],
|
||||||
|
components: {
|
||||||
|
SearchIcon,
|
||||||
|
CloudPlusIcon,
|
||||||
|
UserPlusIcon,
|
||||||
|
SortingIcon,
|
||||||
CornerDownRightIcon,
|
CornerDownRightIcon,
|
||||||
DownloadCloudIcon,
|
DownloadCloudIcon,
|
||||||
FolderPlusIcon,
|
FolderPlusIcon,
|
||||||
@@ -36,48 +60,21 @@
|
|||||||
ZoomInIcon,
|
ZoomInIcon,
|
||||||
Trash2Icon,
|
Trash2Icon,
|
||||||
Edit2Icon,
|
Edit2Icon,
|
||||||
GridIcon,
|
|
||||||
ListIcon,
|
ListIcon,
|
||||||
|
GridIcon,
|
||||||
InfoIcon,
|
InfoIcon,
|
||||||
LinkIcon,
|
LinkIcon,
|
||||||
XIcon,
|
XIcon,
|
||||||
} from "vue-feather-icons";
|
},
|
||||||
|
}
|
||||||
export default {
|
|
||||||
name: "ToolbarButton",
|
|
||||||
props: [
|
|
||||||
'source',
|
|
||||||
'action'
|
|
||||||
],
|
|
||||||
components: {
|
|
||||||
SearchIcon,
|
|
||||||
CloudPlusIcon,
|
|
||||||
UserPlusIcon,
|
|
||||||
SortingIcon,
|
|
||||||
CornerDownRightIcon,
|
|
||||||
DownloadCloudIcon,
|
|
||||||
FolderPlusIcon,
|
|
||||||
CloudOffIcon,
|
|
||||||
PrinterIcon,
|
|
||||||
ZoomOutIcon,
|
|
||||||
ZoomInIcon,
|
|
||||||
Trash2Icon,
|
|
||||||
Edit2Icon,
|
|
||||||
ListIcon,
|
|
||||||
GridIcon,
|
|
||||||
InfoIcon,
|
|
||||||
LinkIcon,
|
|
||||||
XIcon,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "resources/sass/vuefilemanager/_variables";
|
@import 'resources/sass/vuefilemanager/_variables';
|
||||||
@import "resources/sass/vuefilemanager/_mixins";
|
@import 'resources/sass/vuefilemanager/_mixins';
|
||||||
|
|
||||||
.preview-sorting {
|
.preview-sorting {
|
||||||
transform: scale(1.3);
|
transform: scale(1.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
.button {
|
.button {
|
||||||
@@ -99,7 +96,11 @@
|
|||||||
svg {
|
svg {
|
||||||
color: inherit;
|
color: inherit;
|
||||||
|
|
||||||
path, line, polyline, rect, circle {
|
path,
|
||||||
|
line,
|
||||||
|
polyline,
|
||||||
|
rect,
|
||||||
|
circle {
|
||||||
color: inherit;
|
color: inherit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,16 +2,21 @@
|
|||||||
<transition name="info-panel">
|
<transition name="info-panel">
|
||||||
<div v-if="fileQueue.length > 0" class="upload-progress">
|
<div v-if="fileQueue.length > 0" class="upload-progress">
|
||||||
<div class="progress-title">
|
<div class="progress-title">
|
||||||
|
|
||||||
<!--Is processing-->
|
<!--Is processing-->
|
||||||
<span v-if="isProcessingFile" class="flex items-center justify-center">
|
<span v-if="isProcessingFile" class="flex items-center justify-center">
|
||||||
<refresh-cw-icon size="12" class="sync-alt text-theme" />
|
<refresh-cw-icon size="12" class="sync-alt text-theme" />
|
||||||
{{ $t('uploading.processing_file') }}
|
{{ $t('uploading.processing_file') }}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<!--Multi file upload-->
|
<!--Multi file upload-->
|
||||||
<span v-if="!isProcessingFile && fileQueue.length > 0">
|
<span v-if="!isProcessingFile && fileQueue.length > 0">
|
||||||
{{ $t('uploading.progress', {current:filesInQueueUploaded, total: filesInQueueTotal, progress: uploadingProgress}) }}
|
{{
|
||||||
|
$t('uploading.progress', {
|
||||||
|
current: filesInQueueUploaded,
|
||||||
|
total: filesInQueueTotal,
|
||||||
|
progress: uploadingProgress,
|
||||||
|
})
|
||||||
|
}}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="progress-wrapper">
|
<div class="progress-wrapper">
|
||||||
@@ -25,102 +30,96 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ProgressBar from "./ProgressBar";
|
import ProgressBar from './ProgressBar'
|
||||||
import { RefreshCwIcon, XIcon } from 'vue-feather-icons'
|
import { RefreshCwIcon, XIcon } from 'vue-feather-icons'
|
||||||
import {mapGetters} from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
import {events} from "../../bus";
|
import { events } from '../../bus'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'UploadProgress',
|
name: 'UploadProgress',
|
||||||
components: {
|
components: {
|
||||||
RefreshCwIcon,
|
RefreshCwIcon,
|
||||||
ProgressBar,
|
ProgressBar,
|
||||||
XIcon,
|
XIcon,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters(['filesInQueueUploaded', 'filesInQueueTotal', 'uploadingProgress', 'isProcessingFile', 'fileQueue']),
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
cancelUpload() {
|
||||||
|
events.$emit('cancel-upload')
|
||||||
},
|
},
|
||||||
computed: {
|
},
|
||||||
...mapGetters([
|
}
|
||||||
'filesInQueueUploaded',
|
|
||||||
'filesInQueueTotal',
|
|
||||||
'uploadingProgress',
|
|
||||||
'isProcessingFile',
|
|
||||||
'fileQueue',
|
|
||||||
])
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
cancelUpload() {
|
|
||||||
events.$emit('cancel-upload')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import '../../../sass/vuefilemanager/variables';
|
@import '../../../sass/vuefilemanager/variables';
|
||||||
@import '../../../sass/vuefilemanager/mixins';
|
@import '../../../sass/vuefilemanager/mixins';
|
||||||
|
|
||||||
.sync-alt {
|
.sync-alt {
|
||||||
animation: spin 1s linear infinite;
|
animation: spin 1s linear infinite;
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
|
|
||||||
polyline, path {
|
polyline,
|
||||||
color: inherit;
|
path {
|
||||||
}
|
color: inherit;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes spin {
|
@keyframes spin {
|
||||||
0% {
|
0% {
|
||||||
transform: rotate(0);
|
transform: rotate(0);
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
100% {
|
||||||
.info-panel-enter-active,
|
transform: rotate(360deg);
|
||||||
.info-panel-leave-active {
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.info-panel-enter,
|
.info-panel-enter-active,
|
||||||
.info-panel-leave-to {
|
.info-panel-leave-active {
|
||||||
opacity: 0;
|
transition: all 0.3s ease;
|
||||||
transform: translateY(-100%);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.upload-progress {
|
.info-panel-enter,
|
||||||
width: 100%;
|
.info-panel-leave-to {
|
||||||
position: relative;
|
opacity: 0;
|
||||||
z-index: 1;
|
transform: translateY(-100%);
|
||||||
|
}
|
||||||
|
|
||||||
.progress-wrapper {
|
.upload-progress {
|
||||||
display: flex;
|
width: 100%;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
|
||||||
.cancel-icon {
|
.progress-wrapper {
|
||||||
cursor: pointer;
|
display: flex;
|
||||||
padding: 0 7px 0 13px;
|
|
||||||
|
|
||||||
&:hover {
|
.cancel-icon {
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 0 7px 0 13px;
|
||||||
|
|
||||||
line {
|
&:hover {
|
||||||
color: inherit;
|
line {
|
||||||
}
|
color: inherit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.progress-title {
|
|
||||||
font-weight: 700;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
span {
|
|
||||||
@include font-size(14);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark {
|
.progress-title {
|
||||||
.progress-bar {
|
font-weight: 700;
|
||||||
background: $dark_mode_foreground;
|
text-align: center;
|
||||||
|
|
||||||
|
span {
|
||||||
|
@include font-size(14);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark {
|
||||||
|
.progress-bar {
|
||||||
|
background: $dark_mode_foreground;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -8,77 +8,76 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'IndexPageTile',
|
name: 'IndexPageTile',
|
||||||
props: ['title', 'description', 'type']
|
props: ['title', 'description', 'type'],
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import '../../../../sass/vuefilemanager/landing-page';
|
@import '../../../../sass/vuefilemanager/landing-page';
|
||||||
@import '../../../../sass/vuefilemanager/variables';
|
@import '../../../../sass/vuefilemanager/variables';
|
||||||
@import '../../../../sass/vuefilemanager/mixins';
|
@import '../../../../sass/vuefilemanager/mixins';
|
||||||
|
|
||||||
.page-title {
|
.page-title {
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
|
||||||
&.center {
|
&.center {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
.title {
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
max-width: 780px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.description {
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
max-width: 580px;
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
max-width: 780px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
max-width: 580px;
|
||||||
|
font-size: 48px;
|
||||||
|
font-weight: 800;
|
||||||
|
line-height: 1.3;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
|
||||||
|
/deep/ span {
|
||||||
font-size: 48px;
|
font-size: 48px;
|
||||||
font-weight: 800;
|
}
|
||||||
line-height: 1.3;
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
max-width: 580px;
|
||||||
|
@include font-size(20);
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 1.65;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 960px) {
|
||||||
|
.page-title {
|
||||||
|
.title {
|
||||||
|
max-width: 100%;
|
||||||
|
font-size: 32px;
|
||||||
|
line-height: 1.25;
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
|
|
||||||
/deep/ span {
|
/deep/ span {
|
||||||
font-size: 48px;
|
font-size: 32px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.description {
|
.description {
|
||||||
max-width: 580px;
|
max-width: 100%;
|
||||||
@include font-size(20);
|
@include font-size(16);
|
||||||
font-weight: 500;
|
line-height: 1.6;
|
||||||
line-height: 1.65;
|
|
||||||
margin-bottom: 30px;
|
margin-bottom: 30px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
@media only screen and (max-width: 960px) {
|
|
||||||
.page-title {
|
|
||||||
|
|
||||||
.title {
|
|
||||||
max-width: 100%;
|
|
||||||
font-size: 32px;
|
|
||||||
line-height: 1.25;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
|
|
||||||
/deep/ span {
|
|
||||||
font-size: 32px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.description {
|
|
||||||
max-width: 100%;
|
|
||||||
@include font-size(16);
|
|
||||||
line-height: 1.6;
|
|
||||||
margin-bottom: 30px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -7,7 +7,9 @@
|
|||||||
<hard-drive-icon class="text-theme" size="26" />
|
<hard-drive-icon class="text-theme" size="26" />
|
||||||
</div>
|
</div>
|
||||||
<h1 class="title">{{ plan.data.attributes.name }}</h1>
|
<h1 class="title">{{ plan.data.attributes.name }}</h1>
|
||||||
<h2 class="description">{{ plan.data.attributes.description }}</h2>
|
<h2 class="description">
|
||||||
|
{{ plan.data.attributes.description }}
|
||||||
|
</h2>
|
||||||
</header>
|
</header>
|
||||||
<section class="plan-features">
|
<section class="plan-features">
|
||||||
<b class="storage-size">{{ plan.data.attributes.capacity_formatted }}</b>
|
<b class="storage-size">{{ plan.data.attributes.capacity_formatted }}</b>
|
||||||
@@ -25,182 +27,176 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {HardDriveIcon} from "vue-feather-icons"
|
import { HardDriveIcon } from 'vue-feather-icons'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'PricingTables',
|
name: 'PricingTables',
|
||||||
components: {
|
components: {
|
||||||
HardDriveIcon,
|
HardDriveIcon,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
plans: undefined,
|
plans: undefined,
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
axios.get('/api/pricing')
|
|
||||||
.then(response => {
|
|
||||||
this.plans = response.data
|
|
||||||
this.$emit('load', response.data)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
created() {
|
||||||
|
axios.get('/api/pricing').then((response) => {
|
||||||
|
this.plans = response.data
|
||||||
|
this.$emit('load', response.data)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import '../../../../sass/vuefilemanager/variables';
|
@import '../../../../sass/vuefilemanager/variables';
|
||||||
@import '../../../../sass/vuefilemanager/mixins';
|
@import '../../../../sass/vuefilemanager/mixins';
|
||||||
|
|
||||||
|
.plans-wrapper {
|
||||||
|
box-shadow: 0 7px 20px 5px hsla(220, 36%, 16%, 0.05);
|
||||||
|
border-radius: 8px;
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.plan {
|
||||||
|
text-align: center;
|
||||||
|
flex: 0 0 33%;
|
||||||
|
padding: 55px 25px 75px;
|
||||||
|
//border-right: 1px solid #F7F7F7;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.plan-header {
|
||||||
|
.icon {
|
||||||
|
path,
|
||||||
|
line,
|
||||||
|
polyline,
|
||||||
|
rect,
|
||||||
|
circle {
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
@include font-size(22);
|
||||||
|
font-weight: 800;
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
@include font-size(14);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.plan-features {
|
||||||
|
margin: 55px 0;
|
||||||
|
|
||||||
|
.storage-size {
|
||||||
|
@include font-size(48);
|
||||||
|
font-weight: 900;
|
||||||
|
line-height: 1.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.storage-description {
|
||||||
|
display: block;
|
||||||
|
@include font-size(15);
|
||||||
|
font-weight: 800;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.plan-footer {
|
||||||
|
.sign-in-button {
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.price {
|
||||||
|
@include font-size(18);
|
||||||
|
display: block;
|
||||||
|
padding-top: 5px;
|
||||||
|
|
||||||
|
.vat-disclaimer {
|
||||||
|
@include font-size(11);
|
||||||
|
color: $text;
|
||||||
|
display: block;
|
||||||
|
font-weight: 300;
|
||||||
|
opacity: 0.45;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.plans-wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: space-around;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 960px) {
|
||||||
.plans-wrapper {
|
.plans-wrapper {
|
||||||
box-shadow: 0 7px 20px 5px hsla(220, 36%, 16%, 0.05);
|
display: block;
|
||||||
border-radius: 8px;
|
margin: 0;
|
||||||
background: white;
|
|
||||||
|
.plan {
|
||||||
|
padding: 30px 25px;
|
||||||
|
border-bottom: 1px solid #f7f7f7;
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark {
|
||||||
|
.plans-wrapper {
|
||||||
|
background: $dark_mode_foreground;
|
||||||
}
|
}
|
||||||
|
|
||||||
.plan {
|
.plan {
|
||||||
text-align: center;
|
border-color: $dark_mode_border_color !important;
|
||||||
flex: 0 0 33%;
|
|
||||||
padding: 55px 25px 75px;
|
|
||||||
//border-right: 1px solid #F7F7F7;
|
|
||||||
|
|
||||||
&:last-child {
|
.plan-wrapper {
|
||||||
border-right: none;
|
background: $dark_mode_foreground;
|
||||||
}
|
}
|
||||||
|
|
||||||
.plan-header {
|
.plan-header {
|
||||||
|
|
||||||
.icon {
|
|
||||||
|
|
||||||
path, line, polyline, rect, circle {
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
@include font-size(22);
|
color: $dark_mode_text_primary;
|
||||||
font-weight: 800;
|
|
||||||
padding-top: 10px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.description {
|
.description {
|
||||||
@include font-size(14);
|
color: $dark_mode_text_secondary;
|
||||||
font-weight: 600;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.plan-features {
|
.plan-features {
|
||||||
margin: 55px 0;
|
|
||||||
|
|
||||||
.storage-size {
|
.storage-size {
|
||||||
@include font-size(48);
|
color: $dark_mode_text_primary;
|
||||||
font-weight: 900;
|
|
||||||
line-height: 1.1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.storage-description {
|
.storage-description {
|
||||||
display: block;
|
color: $dark_mode_text_primary;
|
||||||
@include font-size(15);
|
|
||||||
font-weight: 800;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.plan-footer {
|
.plan-footer {
|
||||||
|
|
||||||
.sign-in-button {
|
.sign-in-button {
|
||||||
width: 100%;
|
background: rgba($theme, 0.1);
|
||||||
text-align: center;
|
|
||||||
|
/deep/ .content {
|
||||||
|
color: $theme;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.price {
|
.price {
|
||||||
@include font-size(18);
|
|
||||||
display: block;
|
|
||||||
padding-top: 5px;
|
|
||||||
|
|
||||||
.vat-disclaimer {
|
.vat-disclaimer {
|
||||||
@include font-size(11);
|
|
||||||
color: $text;
|
|
||||||
display: block;
|
|
||||||
font-weight: 300;
|
|
||||||
opacity: 0.45;
|
|
||||||
margin-top: 5px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.plans-wrapper {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
justify-content: space-around;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (max-width: 960px) {
|
|
||||||
|
|
||||||
.plans-wrapper {
|
|
||||||
display: block;
|
|
||||||
margin: 0;
|
|
||||||
|
|
||||||
.plan {
|
|
||||||
padding: 30px 25px;
|
|
||||||
border-bottom: 1px solid #F7F7F7;
|
|
||||||
border-right: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark {
|
|
||||||
|
|
||||||
.plans-wrapper {
|
|
||||||
background: $dark_mode_foreground;
|
|
||||||
}
|
|
||||||
|
|
||||||
.plan {
|
|
||||||
border-color: $dark_mode_border_color !important;
|
|
||||||
|
|
||||||
.plan-wrapper {
|
|
||||||
background: $dark_mode_foreground;
|
|
||||||
}
|
|
||||||
|
|
||||||
.plan-header {
|
|
||||||
|
|
||||||
.title {
|
|
||||||
color: $dark_mode_text_primary;
|
|
||||||
}
|
|
||||||
|
|
||||||
.description {
|
|
||||||
color: $dark_mode_text_secondary;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.plan-features {
|
|
||||||
|
|
||||||
.storage-size {
|
|
||||||
color: $dark_mode_text_primary;
|
|
||||||
}
|
|
||||||
|
|
||||||
.storage-description {
|
|
||||||
color: $dark_mode_text_primary;
|
color: $dark_mode_text_primary;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.plan-footer {
|
|
||||||
|
|
||||||
.sign-in-button {
|
|
||||||
background: rgba($theme, 0.1);
|
|
||||||
|
|
||||||
/deep/ .content {
|
|
||||||
color: $theme;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.price {
|
|
||||||
|
|
||||||
.vat-disclaimer {
|
|
||||||
color: $dark_mode_text_primary;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,14 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="page-wrapper large get-started" v-if="index.section_get_started === '1'">
|
<div class="page-wrapper large get-started" v-if="index.section_get_started === '1'">
|
||||||
|
<PageTitle class="page-title" type="center" :title="index.get_started_title" :description="index.get_started_description"></PageTitle>
|
||||||
|
|
||||||
<PageTitle
|
<router-link tag="button" class="get-started-button bg-theme-800 hover-bg-theme shadow-theme" :to="{ name: 'SignUp' }">
|
||||||
class="page-title"
|
|
||||||
type="center"
|
|
||||||
:title="index.get_started_title"
|
|
||||||
:description="index.get_started_description"
|
|
||||||
></PageTitle>
|
|
||||||
|
|
||||||
<router-link tag="button" class="get-started-button bg-theme-800 hover-bg-theme shadow-theme" :to="{name: 'SignUp'}">
|
|
||||||
<span class="content">{{ $t('page_index.get_started_button') }}</span>
|
<span class="content">{{ $t('page_index.get_started_button') }}</span>
|
||||||
<chevron-right-icon size="22"></chevron-right-icon>
|
<chevron-right-icon size="22"></chevron-right-icon>
|
||||||
</router-link>
|
</router-link>
|
||||||
@@ -41,296 +35,305 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import PageTitle from "./Components/PageTitle";
|
import PageTitle from './Components/PageTitle'
|
||||||
import {
|
import {
|
||||||
ChevronRightIcon,
|
ChevronRightIcon,
|
||||||
|
UploadCloudIcon,
|
||||||
|
FolderPlusIcon,
|
||||||
|
HardDriveIcon,
|
||||||
|
SettingsIcon,
|
||||||
|
Trash2Icon,
|
||||||
|
SearchIcon,
|
||||||
|
ShareIcon,
|
||||||
|
CloudIcon,
|
||||||
|
ImageIcon,
|
||||||
|
InfoIcon,
|
||||||
|
GridIcon,
|
||||||
|
LinkIcon,
|
||||||
|
StarIcon,
|
||||||
|
EyeIcon,
|
||||||
|
} from 'vue-feather-icons'
|
||||||
|
import { mapGetters } from 'vuex'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'IndexGetStarted',
|
||||||
|
components: {
|
||||||
|
InfoIcon,
|
||||||
UploadCloudIcon,
|
UploadCloudIcon,
|
||||||
|
ShareIcon,
|
||||||
|
ChevronRightIcon,
|
||||||
FolderPlusIcon,
|
FolderPlusIcon,
|
||||||
HardDriveIcon,
|
HardDriveIcon,
|
||||||
SettingsIcon,
|
SettingsIcon,
|
||||||
Trash2Icon,
|
Trash2Icon,
|
||||||
SearchIcon,
|
SearchIcon,
|
||||||
ShareIcon,
|
|
||||||
CloudIcon,
|
CloudIcon,
|
||||||
|
PageTitle,
|
||||||
ImageIcon,
|
ImageIcon,
|
||||||
InfoIcon,
|
|
||||||
GridIcon,
|
GridIcon,
|
||||||
LinkIcon,
|
LinkIcon,
|
||||||
StarIcon,
|
StarIcon,
|
||||||
EyeIcon,
|
EyeIcon,
|
||||||
} from 'vue-feather-icons'
|
},
|
||||||
import { mapGetters } from 'vuex'
|
computed: {
|
||||||
|
...mapGetters(['index']),
|
||||||
export default {
|
},
|
||||||
name: 'IndexGetStarted',
|
}
|
||||||
components: {
|
|
||||||
InfoIcon,
|
|
||||||
UploadCloudIcon,
|
|
||||||
ShareIcon,
|
|
||||||
ChevronRightIcon,
|
|
||||||
FolderPlusIcon,
|
|
||||||
HardDriveIcon,
|
|
||||||
SettingsIcon,
|
|
||||||
Trash2Icon,
|
|
||||||
SearchIcon,
|
|
||||||
CloudIcon,
|
|
||||||
PageTitle,
|
|
||||||
ImageIcon,
|
|
||||||
GridIcon,
|
|
||||||
LinkIcon,
|
|
||||||
StarIcon,
|
|
||||||
EyeIcon,
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters(['index']),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import '../../../sass/vuefilemanager/landing-page';
|
@import '../../../sass/vuefilemanager/landing-page';
|
||||||
@import '../../../sass/vuefilemanager/variables';
|
@import '../../../sass/vuefilemanager/variables';
|
||||||
@import '../../../sass/vuefilemanager/mixins';
|
@import '../../../sass/vuefilemanager/mixins';
|
||||||
|
|
||||||
.icons {
|
.icons {
|
||||||
|
.icon {
|
||||||
.icon {
|
|
||||||
position: absolute;
|
|
||||||
|
|
||||||
&:nth-child(20) {
|
|
||||||
bottom: -37%;
|
|
||||||
left: 37%;
|
|
||||||
transform: rotate(0deg);
|
|
||||||
|
|
||||||
circle, line {
|
|
||||||
stroke: $yellow;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(19) {
|
|
||||||
bottom: -21%;
|
|
||||||
left: 23.5%;
|
|
||||||
transform: rotate(-20deg);
|
|
||||||
|
|
||||||
path, line {
|
|
||||||
stroke: $purple;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(18) {
|
|
||||||
bottom: -4%;
|
|
||||||
left: 26.5%;
|
|
||||||
transform: rotate(0deg);
|
|
||||||
|
|
||||||
path {
|
|
||||||
stroke: $theme;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(17) {
|
|
||||||
bottom: -5%;
|
|
||||||
left: 8.5%;
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(16) {
|
|
||||||
top: 86%;
|
|
||||||
left: 17%;
|
|
||||||
transform: rotate(18deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(15) {
|
|
||||||
top: 64%;
|
|
||||||
left: 17%;
|
|
||||||
transform: rotate(0deg);
|
|
||||||
|
|
||||||
polyline, line, path {
|
|
||||||
stroke: $red;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(14) {
|
|
||||||
top: 44%;
|
|
||||||
left: 28%;
|
|
||||||
transform: rotate(0deg);
|
|
||||||
|
|
||||||
polygon {
|
|
||||||
stroke: $purple;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(13) {
|
|
||||||
top: 33%;
|
|
||||||
left: 16%;
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(12) {
|
|
||||||
top: 23%;
|
|
||||||
left: 32%;
|
|
||||||
transform: rotate(13deg);
|
|
||||||
|
|
||||||
line, path {
|
|
||||||
stroke: $yellow;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(1) {
|
|
||||||
top: 35%;
|
|
||||||
right: 49%;
|
|
||||||
transform: rotate(-11deg);
|
|
||||||
|
|
||||||
line, path {
|
|
||||||
stroke: $theme;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(2) {
|
|
||||||
top: 12%;
|
|
||||||
right: 45%;
|
|
||||||
transform: rotate(0);
|
|
||||||
|
|
||||||
circle, path {
|
|
||||||
stroke: $red;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(3) {
|
|
||||||
top: 30%;
|
|
||||||
right: 30%;
|
|
||||||
transform: rotate(20deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(4) {
|
|
||||||
top: 14%;
|
|
||||||
right: 14.5%;
|
|
||||||
transform: rotate(-1deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(5) {
|
|
||||||
top: 62%;
|
|
||||||
right: 15.5%;
|
|
||||||
transform: rotate(21deg);
|
|
||||||
|
|
||||||
polyline, path, line {
|
|
||||||
stroke: $red;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(6) {
|
|
||||||
top: 66%;
|
|
||||||
right: 26.5%;
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(7) {
|
|
||||||
bottom: 3%;
|
|
||||||
right: 21.5%;
|
|
||||||
transform: rotate(16deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(8) {
|
|
||||||
bottom: -13%;
|
|
||||||
right: 16.5%;
|
|
||||||
transform: rotate(0deg);
|
|
||||||
|
|
||||||
polygon {
|
|
||||||
stroke: $yellow;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(9) {
|
|
||||||
bottom: -32%;
|
|
||||||
right: 27%;
|
|
||||||
transform: rotate(-20deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(10) {
|
|
||||||
bottom: -5%;
|
|
||||||
right: 34%;
|
|
||||||
transform: rotate(16deg);
|
|
||||||
|
|
||||||
rect {
|
|
||||||
stroke: $purple;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(11) {
|
|
||||||
bottom: -28%;
|
|
||||||
right: 44%;
|
|
||||||
transform: rotate(-12deg);
|
|
||||||
|
|
||||||
polyline, line, path {
|
|
||||||
stroke: $red;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.cloud-bg {
|
|
||||||
z-index: 0;
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 70px;
|
|
||||||
right: 60px;
|
|
||||||
transform: scale(-1, 1) rotate(13deg);
|
|
||||||
opacity: 0.1;
|
|
||||||
|
|
||||||
path {
|
&:nth-child(20) {
|
||||||
stroke: none;
|
bottom: -37%;
|
||||||
|
left: 37%;
|
||||||
|
transform: rotate(0deg);
|
||||||
|
|
||||||
|
circle,
|
||||||
|
line {
|
||||||
|
stroke: $yellow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(19) {
|
||||||
|
bottom: -21%;
|
||||||
|
left: 23.5%;
|
||||||
|
transform: rotate(-20deg);
|
||||||
|
|
||||||
|
path,
|
||||||
|
line {
|
||||||
|
stroke: $purple;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(18) {
|
||||||
|
bottom: -4%;
|
||||||
|
left: 26.5%;
|
||||||
|
transform: rotate(0deg);
|
||||||
|
|
||||||
|
path {
|
||||||
|
stroke: $theme;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(17) {
|
||||||
|
bottom: -5%;
|
||||||
|
left: 8.5%;
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(16) {
|
||||||
|
top: 86%;
|
||||||
|
left: 17%;
|
||||||
|
transform: rotate(18deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(15) {
|
||||||
|
top: 64%;
|
||||||
|
left: 17%;
|
||||||
|
transform: rotate(0deg);
|
||||||
|
|
||||||
|
polyline,
|
||||||
|
line,
|
||||||
|
path {
|
||||||
|
stroke: $red;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(14) {
|
||||||
|
top: 44%;
|
||||||
|
left: 28%;
|
||||||
|
transform: rotate(0deg);
|
||||||
|
|
||||||
|
polygon {
|
||||||
|
stroke: $purple;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(13) {
|
||||||
|
top: 33%;
|
||||||
|
left: 16%;
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(12) {
|
||||||
|
top: 23%;
|
||||||
|
left: 32%;
|
||||||
|
transform: rotate(13deg);
|
||||||
|
|
||||||
|
line,
|
||||||
|
path {
|
||||||
|
stroke: $yellow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(1) {
|
||||||
|
top: 35%;
|
||||||
|
right: 49%;
|
||||||
|
transform: rotate(-11deg);
|
||||||
|
|
||||||
|
line,
|
||||||
|
path {
|
||||||
|
stroke: $theme;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(2) {
|
||||||
|
top: 12%;
|
||||||
|
right: 45%;
|
||||||
|
transform: rotate(0);
|
||||||
|
|
||||||
|
circle,
|
||||||
|
path {
|
||||||
|
stroke: $red;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(3) {
|
||||||
|
top: 30%;
|
||||||
|
right: 30%;
|
||||||
|
transform: rotate(20deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(4) {
|
||||||
|
top: 14%;
|
||||||
|
right: 14.5%;
|
||||||
|
transform: rotate(-1deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(5) {
|
||||||
|
top: 62%;
|
||||||
|
right: 15.5%;
|
||||||
|
transform: rotate(21deg);
|
||||||
|
|
||||||
|
polyline,
|
||||||
|
path,
|
||||||
|
line {
|
||||||
|
stroke: $red;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(6) {
|
||||||
|
top: 66%;
|
||||||
|
right: 26.5%;
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(7) {
|
||||||
|
bottom: 3%;
|
||||||
|
right: 21.5%;
|
||||||
|
transform: rotate(16deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(8) {
|
||||||
|
bottom: -13%;
|
||||||
|
right: 16.5%;
|
||||||
|
transform: rotate(0deg);
|
||||||
|
|
||||||
|
polygon {
|
||||||
|
stroke: $yellow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(9) {
|
||||||
|
bottom: -32%;
|
||||||
|
right: 27%;
|
||||||
|
transform: rotate(-20deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(10) {
|
||||||
|
bottom: -5%;
|
||||||
|
right: 34%;
|
||||||
|
transform: rotate(16deg);
|
||||||
|
|
||||||
|
rect {
|
||||||
|
stroke: $purple;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(11) {
|
||||||
|
bottom: -28%;
|
||||||
|
right: 44%;
|
||||||
|
transform: rotate(-12deg);
|
||||||
|
|
||||||
|
polyline,
|
||||||
|
line,
|
||||||
|
path {
|
||||||
|
stroke: $red;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.cloud-bg {
|
||||||
|
z-index: 0;
|
||||||
|
position: absolute;
|
||||||
|
top: 70px;
|
||||||
|
right: 60px;
|
||||||
|
transform: scale(-1, 1) rotate(13deg);
|
||||||
|
opacity: 0.1;
|
||||||
|
|
||||||
|
path {
|
||||||
|
stroke: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-title {
|
||||||
|
padding-top: 340px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.get-started-button {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
outline: none;
|
||||||
|
border: none;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 20px 36px;
|
||||||
|
border-radius: 6px;
|
||||||
|
//box-shadow: 0 5px 10px 2px rgba($theme, 0.34);
|
||||||
|
margin-bottom: 395px;
|
||||||
|
@include transition(150ms);
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
|
||||||
|
.content {
|
||||||
|
@include font-size(19);
|
||||||
|
font-weight: 700;
|
||||||
|
margin-right: 8px;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
polyline {
|
||||||
|
stroke: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 1190px) {
|
||||||
|
.get-started-button {
|
||||||
|
margin-bottom: 280px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 960px) {
|
||||||
.page-title {
|
.page-title {
|
||||||
padding-top: 340px;
|
padding-top: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.get-started-button {
|
.get-started-button {
|
||||||
display: flex;
|
margin-bottom: 30px;
|
||||||
align-items: center;
|
|
||||||
outline: none;
|
|
||||||
border: none;
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
cursor: pointer;
|
|
||||||
padding: 20px 36px;
|
|
||||||
border-radius: 6px;
|
|
||||||
//box-shadow: 0 5px 10px 2px rgba($theme, 0.34);
|
|
||||||
margin-bottom: 395px;
|
|
||||||
@include transition(150ms);
|
|
||||||
position: relative;
|
|
||||||
z-index: 1;
|
|
||||||
|
|
||||||
.content {
|
|
||||||
@include font-size(19);
|
|
||||||
font-weight: 700;
|
|
||||||
margin-right: 8px;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
polyline {
|
|
||||||
stroke: white;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: 1190px) {
|
.cloud-bg,
|
||||||
.get-started-button {
|
.icons {
|
||||||
margin-bottom: 280px;
|
display: none;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (max-width: 960px) {
|
|
||||||
.page-title {
|
|
||||||
padding-top: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.get-started-button {
|
|
||||||
margin-bottom: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cloud-bg,
|
|
||||||
.icons {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="page-wrapper large hero-screenshot">
|
<div class="page-wrapper large hero-screenshot">
|
||||||
<img class="hero-light" src="/assets/images/vuefilemanager-screenshot-light.png" :alt="config.app_name">
|
<img class="hero-light" src="/assets/images/vuefilemanager-screenshot-light.png" :alt="config.app_name" />
|
||||||
<img class="hero-dark" src="/assets/images/vuefilemanager-screenshot-dark.png" :alt="config.app_name">
|
<img class="hero-dark" src="/assets/images/vuefilemanager-screenshot-dark.png" :alt="config.app_name" />
|
||||||
|
|
||||||
<div class="icons">
|
<div class="icons">
|
||||||
<link-icon size="20" class="icon"></link-icon>
|
<link-icon size="20" class="icon"></link-icon>
|
||||||
@@ -22,8 +22,12 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapGetters } from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
import {
|
import { FolderPlusIcon, HardDriveIcon, SettingsIcon, Trash2Icon, SearchIcon, ImageIcon, GridIcon, LinkIcon, StarIcon, EyeIcon } from 'vue-feather-icons'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'IndexHeroScreenshot',
|
||||||
|
components: {
|
||||||
FolderPlusIcon,
|
FolderPlusIcon,
|
||||||
HardDriveIcon,
|
HardDriveIcon,
|
||||||
SettingsIcon,
|
SettingsIcon,
|
||||||
@@ -34,193 +38,179 @@
|
|||||||
LinkIcon,
|
LinkIcon,
|
||||||
StarIcon,
|
StarIcon,
|
||||||
EyeIcon,
|
EyeIcon,
|
||||||
} from 'vue-feather-icons'
|
},
|
||||||
|
computed: {
|
||||||
export default {
|
...mapGetters(['config']),
|
||||||
name: 'IndexHeroScreenshot',
|
},
|
||||||
components: {
|
}
|
||||||
FolderPlusIcon,
|
|
||||||
HardDriveIcon,
|
|
||||||
SettingsIcon,
|
|
||||||
Trash2Icon,
|
|
||||||
SearchIcon,
|
|
||||||
ImageIcon,
|
|
||||||
GridIcon,
|
|
||||||
LinkIcon,
|
|
||||||
StarIcon,
|
|
||||||
EyeIcon,
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters(['config']),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import '../../../sass/vuefilemanager/landing-page';
|
@import '../../../sass/vuefilemanager/landing-page';
|
||||||
@import '../../../sass/vuefilemanager/variables';
|
@import '../../../sass/vuefilemanager/variables';
|
||||||
@import '../../../sass/vuefilemanager/mixins';
|
@import '../../../sass/vuefilemanager/mixins';
|
||||||
|
|
||||||
.icons {
|
.icons {
|
||||||
|
.icon {
|
||||||
|
z-index: 0;
|
||||||
|
position: absolute;
|
||||||
|
|
||||||
.icon {
|
&:nth-child(1) {
|
||||||
z-index: 0;
|
top: -14%;
|
||||||
position: absolute;
|
right: 2%;
|
||||||
|
}
|
||||||
|
|
||||||
&:nth-child(1) {
|
&:nth-child(2) {
|
||||||
top: -14%;
|
top: -5%;
|
||||||
right: 2%;
|
right: 14%;
|
||||||
}
|
transform: rotate(19deg);
|
||||||
|
}
|
||||||
|
|
||||||
&:nth-child(2) {
|
&:nth-child(3) {
|
||||||
top: -5%;
|
top: -6.5%;
|
||||||
right: 14%;
|
right: 28.5%;
|
||||||
transform: rotate(19deg);
|
transform: rotate(-12deg);
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(3) {
|
line,
|
||||||
top: -6.5%;
|
path {
|
||||||
right: 28.5%;
|
stroke: $theme;
|
||||||
transform: rotate(-12deg);
|
|
||||||
|
|
||||||
line, path {
|
|
||||||
stroke: $theme;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(4) {
|
|
||||||
top: -9.5%;
|
|
||||||
right: 41.5%;
|
|
||||||
transform: rotate(13deg);
|
|
||||||
|
|
||||||
path, line {
|
|
||||||
stroke: $yellow;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(5) {
|
|
||||||
top: -16%;
|
|
||||||
right: 26%;
|
|
||||||
|
|
||||||
circle, path {
|
|
||||||
stroke: $red;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(6) {
|
|
||||||
top: -13%;
|
|
||||||
right: 49%;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(7) {
|
|
||||||
top: 2.5%;
|
|
||||||
right: 46%;
|
|
||||||
|
|
||||||
polygon {
|
|
||||||
stroke: $purple;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(8) {
|
|
||||||
top: 13%;
|
|
||||||
right: 2.5%;
|
|
||||||
transform: rotate(22deg);
|
|
||||||
|
|
||||||
polyline, path, line {
|
|
||||||
stroke: $red;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(9) {
|
|
||||||
top: 14%;
|
|
||||||
right: 11%;
|
|
||||||
|
|
||||||
circle, line {
|
|
||||||
stroke: $purple;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(10) {
|
|
||||||
top: 29%;
|
|
||||||
right: 7%;
|
|
||||||
transform: rotate(19deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(11) {
|
|
||||||
top: 38%;
|
|
||||||
right: 3%;
|
|
||||||
|
|
||||||
polygon {
|
|
||||||
stroke: $yellow;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(12) {
|
|
||||||
top: 50%;
|
|
||||||
right: 11.5%;
|
|
||||||
transform: rotate(-22deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(13) {
|
|
||||||
top: 34%;
|
|
||||||
right: 16%;
|
|
||||||
transform: rotate(13deg);
|
|
||||||
|
|
||||||
rect {
|
|
||||||
stroke: $theme;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:nth-child(4) {
|
||||||
|
top: -9.5%;
|
||||||
|
right: 41.5%;
|
||||||
|
transform: rotate(13deg);
|
||||||
|
|
||||||
|
path,
|
||||||
|
line {
|
||||||
|
stroke: $yellow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(5) {
|
||||||
|
top: -16%;
|
||||||
|
right: 26%;
|
||||||
|
|
||||||
|
circle,
|
||||||
|
path {
|
||||||
|
stroke: $red;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(6) {
|
||||||
|
top: -13%;
|
||||||
|
right: 49%;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(7) {
|
||||||
|
top: 2.5%;
|
||||||
|
right: 46%;
|
||||||
|
|
||||||
|
polygon {
|
||||||
|
stroke: $purple;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(8) {
|
||||||
|
top: 13%;
|
||||||
|
right: 2.5%;
|
||||||
|
transform: rotate(22deg);
|
||||||
|
|
||||||
|
polyline,
|
||||||
|
path,
|
||||||
|
line {
|
||||||
|
stroke: $red;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(9) {
|
||||||
|
top: 14%;
|
||||||
|
right: 11%;
|
||||||
|
|
||||||
|
circle,
|
||||||
|
line {
|
||||||
|
stroke: $purple;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(10) {
|
||||||
|
top: 29%;
|
||||||
|
right: 7%;
|
||||||
|
transform: rotate(19deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(11) {
|
||||||
|
top: 38%;
|
||||||
|
right: 3%;
|
||||||
|
|
||||||
|
polygon {
|
||||||
|
stroke: $yellow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(12) {
|
||||||
|
top: 50%;
|
||||||
|
right: 11.5%;
|
||||||
|
transform: rotate(-22deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(13) {
|
||||||
|
top: 34%;
|
||||||
|
right: 16%;
|
||||||
|
transform: rotate(13deg);
|
||||||
|
|
||||||
|
rect {
|
||||||
|
stroke: $theme;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-screenshot {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
padding-top: 75px;
|
||||||
|
padding-bottom: 130px;
|
||||||
|
|
||||||
|
img {
|
||||||
|
border-radius: 8px;
|
||||||
|
width: 80%;
|
||||||
|
box-shadow: 0 7px 255px rgba(#19363c, 0.1);
|
||||||
|
|
||||||
|
&.hero-dark {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 890px) {
|
||||||
|
.icons {
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hero-screenshot {
|
.hero-screenshot {
|
||||||
position: relative;
|
padding-top: 40px;
|
||||||
z-index: 1;
|
padding-bottom: 90px;
|
||||||
padding-top: 75px;
|
|
||||||
padding-bottom: 130px;
|
|
||||||
|
|
||||||
img {
|
img {
|
||||||
border-radius: 8px;
|
width: 100%;
|
||||||
width: 80%;
|
}
|
||||||
box-shadow: 0 7px 255px rgba(#19363C, 0.1);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&.hero-dark {
|
.dark {
|
||||||
|
.hero-screenshot {
|
||||||
|
img {
|
||||||
|
&.hero-light {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (max-width: 890px) {
|
&.hero-dark {
|
||||||
|
display: block;
|
||||||
.icons {
|
box-shadow: 0 7px 185px rgba(0, 0, 0, 0.8);
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero-screenshot {
|
|
||||||
padding-top: 40px;
|
|
||||||
padding-bottom: 90px;
|
|
||||||
|
|
||||||
img {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark {
|
|
||||||
|
|
||||||
.hero-screenshot {
|
|
||||||
|
|
||||||
img {
|
|
||||||
|
|
||||||
&.hero-light {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.hero-dark {
|
|
||||||
display: block;
|
|
||||||
box-shadow: 0 7px 185px rgba(0, 0, 0, 0.8);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,14 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<section class="main-features page-wrapper medium">
|
<section class="main-features page-wrapper medium">
|
||||||
<PageTitle
|
<PageTitle v-if="index.section_features === '1'" type="center" :title="index.features_title" :description="index.features_description"></PageTitle>
|
||||||
v-if="index.section_features === '1'"
|
|
||||||
type="center"
|
|
||||||
:title="index.features_title"
|
|
||||||
:description="index.features_description"
|
|
||||||
></PageTitle>
|
|
||||||
<div v-if="index.section_feature_boxes === '1'" class="content">
|
<div v-if="index.section_feature_boxes === '1'" class="content">
|
||||||
<div class="hero">
|
<div class="hero">
|
||||||
<img src="/assets/images/hero-Illustration.svg" alt="Hero">
|
<img src="/assets/images/hero-Illustration.svg" alt="Hero" />
|
||||||
</div>
|
</div>
|
||||||
<div class="features">
|
<div class="features">
|
||||||
<div class="feature">
|
<div class="feature">
|
||||||
@@ -50,143 +45,149 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { UserIcon, CloudIcon, HardDriveIcon } from 'vue-feather-icons'
|
import { UserIcon, CloudIcon, HardDriveIcon } from 'vue-feather-icons'
|
||||||
import PageTitle from "./Components/PageTitle";
|
import PageTitle from './Components/PageTitle'
|
||||||
import { mapGetters } from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'IndexMainFeatures',
|
name: 'IndexMainFeatures',
|
||||||
components: {
|
components: {
|
||||||
PageTitle,
|
PageTitle,
|
||||||
HardDriveIcon,
|
HardDriveIcon,
|
||||||
CloudIcon,
|
CloudIcon,
|
||||||
UserIcon,
|
UserIcon,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(['index']),
|
...mapGetters(['index']),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import '../../../sass/vuefilemanager/landing-page';
|
@import '../../../sass/vuefilemanager/landing-page';
|
||||||
@import '../../../sass/vuefilemanager/variables';
|
@import '../../../sass/vuefilemanager/variables';
|
||||||
@import '../../../sass/vuefilemanager/mixins';
|
@import '../../../sass/vuefilemanager/mixins';
|
||||||
|
|
||||||
|
.features {
|
||||||
|
padding-left: 75px;
|
||||||
|
|
||||||
|
.feature {
|
||||||
|
margin-bottom: 25px;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
@include font-size(26);
|
||||||
|
font-weight: 800;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
line-height: 1.5;
|
||||||
|
color: $text-muted;
|
||||||
|
@include font-size(18);
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
border-radius: 12px;
|
||||||
|
width: 44px;
|
||||||
|
height: 44px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 18px;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(1) .icon {
|
||||||
|
background: rgba($yellow, 0.1);
|
||||||
|
|
||||||
|
path,
|
||||||
|
line,
|
||||||
|
polyline,
|
||||||
|
rect,
|
||||||
|
circle {
|
||||||
|
stroke: $yellow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(2) .icon {
|
||||||
|
background: rgba($theme, 0.1);
|
||||||
|
|
||||||
|
path,
|
||||||
|
line,
|
||||||
|
polyline,
|
||||||
|
rect,
|
||||||
|
circle {
|
||||||
|
stroke: $theme;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(3) .icon {
|
||||||
|
background: rgba($purple, 0.1);
|
||||||
|
|
||||||
|
path,
|
||||||
|
line,
|
||||||
|
polyline,
|
||||||
|
rect,
|
||||||
|
circle {
|
||||||
|
stroke: $purple;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
margin-top: 107px;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 1190px) {
|
||||||
|
.hero {
|
||||||
|
flex: 0 0 60%;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.features {
|
.features {
|
||||||
padding-left: 75px;
|
padding-left: 25px;
|
||||||
|
margin-top: 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 960px) {
|
||||||
|
.content {
|
||||||
|
display: block;
|
||||||
|
margin-top: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.features {
|
||||||
|
margin-top: 50px;
|
||||||
|
padding-left: 0;
|
||||||
|
|
||||||
.feature {
|
.feature {
|
||||||
margin-bottom: 25px;
|
margin-bottom: 35px;
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
@include font-size(26);
|
@include font-size(22);
|
||||||
font-weight: 800;
|
|
||||||
margin-bottom: 4px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.description {
|
.description {
|
||||||
line-height: 1.5;
|
@include font-size(16);
|
||||||
color: $text-muted;
|
|
||||||
@include font-size(18);
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
border-radius: 12px;
|
|
||||||
width: 44px;
|
|
||||||
height: 44px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
margin-bottom: 18px;
|
|
||||||
|
|
||||||
svg {
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(1) .icon {
|
|
||||||
background: rgba($yellow, 0.1);
|
|
||||||
|
|
||||||
path, line, polyline, rect, circle {
|
|
||||||
stroke: $yellow;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(2) .icon {
|
|
||||||
background: rgba($theme, 0.1);
|
|
||||||
|
|
||||||
path, line, polyline, rect, circle {
|
|
||||||
stroke: $theme;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(3) .icon {
|
|
||||||
background: rgba($purple, 0.1);
|
|
||||||
|
|
||||||
path, line, polyline, rect, circle {
|
|
||||||
stroke: $purple;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.content {
|
.dark {
|
||||||
margin-top: 107px;
|
.features {
|
||||||
display: flex;
|
.feature {
|
||||||
}
|
.description {
|
||||||
|
color: $dark_mode_text_secondary;
|
||||||
@media only screen and (max-width: 1190px) {
|
|
||||||
|
|
||||||
.hero {
|
|
||||||
flex: 0 0 60%;
|
|
||||||
|
|
||||||
img {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.features {
|
|
||||||
padding-left: 25px;
|
|
||||||
margin-top: 0px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (max-width: 960px) {
|
|
||||||
|
|
||||||
.content {
|
|
||||||
display: block;
|
|
||||||
margin-top: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.features {
|
|
||||||
margin-top: 50px;
|
|
||||||
padding-left: 0;
|
|
||||||
|
|
||||||
.feature {
|
|
||||||
margin-bottom: 35px;
|
|
||||||
|
|
||||||
.title {
|
|
||||||
@include font-size(22);
|
|
||||||
}
|
|
||||||
|
|
||||||
.description {
|
|
||||||
@include font-size(16);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
.dark {
|
|
||||||
|
|
||||||
.features {
|
|
||||||
|
|
||||||
.feature {
|
|
||||||
|
|
||||||
.description {
|
|
||||||
color: $dark_mode_text_secondary;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<nav class="main-navigation">
|
<nav class="main-navigation">
|
||||||
<router-link :to="{name: 'Homepage'}" tag="div" class="logo">
|
<router-link :to="{ name: 'Homepage' }" tag="div" class="logo">
|
||||||
<img v-if="config.app_logo_horizontal" :src="$getImage(config.app_logo_horizontal)" :alt="config.app_name">
|
<img v-if="config.app_logo_horizontal" :src="$getImage(config.app_logo_horizontal)" :alt="config.app_name" />
|
||||||
<b v-if="! config.app_logo_horizontal" class="logo-text">{{ config.app_name }}</b>
|
<b v-if="!config.app_logo_horizontal" class="logo-text">{{ config.app_name }}</b>
|
||||||
</router-link>
|
</router-link>
|
||||||
<div class="navigation">
|
<div class="navigation">
|
||||||
<ul class="navigation-links">
|
<ul class="navigation-links">
|
||||||
@@ -12,123 +12,121 @@
|
|||||||
</a>
|
</a>
|
||||||
</li>-->
|
</li>-->
|
||||||
<li>
|
<li>
|
||||||
<router-link :to="{name: 'ContactUs'}" class="hover-text-theme">
|
<router-link :to="{ name: 'ContactUs' }" class="hover-text-theme">
|
||||||
{{ $t('page_index.menu.contact_us') }}
|
{{ $t('page_index.menu.contact_us') }}
|
||||||
</router-link>
|
</router-link>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul v-if="! config.isAuthenticated" class="navigation-links">
|
<ul v-if="!config.isAuthenticated" class="navigation-links">
|
||||||
<li>
|
<li>
|
||||||
<router-link :to="{name: 'SignIn'}" class="hover-text-theme">
|
<router-link :to="{ name: 'SignIn' }" class="hover-text-theme">
|
||||||
{{ $t('page_index.menu.log_in') }}
|
{{ $t('page_index.menu.log_in') }}
|
||||||
</router-link>
|
</router-link>
|
||||||
</li>
|
</li>
|
||||||
<li v-if="config.userRegistration">
|
<li v-if="config.userRegistration">
|
||||||
<router-link class="cta-button text-theme bg-theme-100" :to="{name: 'SignUp'}">
|
<router-link class="cta-button text-theme bg-theme-100" :to="{ name: 'SignUp' }">
|
||||||
{{ $t('page_index.menu.sign_in') }}
|
{{ $t('page_index.menu.sign_in') }}
|
||||||
</router-link>
|
</router-link>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul v-if="config.isAuthenticated" class="navigation-links">
|
<ul v-if="config.isAuthenticated" class="navigation-links">
|
||||||
<li v-if="config.userRegistration">
|
<li v-if="config.userRegistration">
|
||||||
<router-link class="cta-button text-theme bg-theme-100" :to="{name: 'Files'}">
|
<router-link class="cta-button text-theme bg-theme-100" :to="{ name: 'Files' }">
|
||||||
{{ $t('go_to_files') }}
|
{{ $t('go_to_files') }}
|
||||||
</router-link>
|
</router-link>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<router-link class="cta-button log-in text-theme bg-theme-100" :to="{name: 'SignIn'}">
|
<router-link class="cta-button log-in text-theme bg-theme-100" :to="{ name: 'SignIn' }">
|
||||||
{{ $t('page_index.menu.log_in') }}
|
{{ $t('page_index.menu.log_in') }}
|
||||||
</router-link>
|
</router-link>
|
||||||
</nav>
|
</nav>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapGetters } from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'IndexNavigation',
|
name: 'IndexNavigation',
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(['config', 'index']),
|
...mapGetters(['config', 'index']),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import '../../../sass/vuefilemanager/landing-page';
|
@import '../../../sass/vuefilemanager/landing-page';
|
||||||
@import '../../../sass/vuefilemanager/variables';
|
@import '../../../sass/vuefilemanager/variables';
|
||||||
@import '../../../sass/vuefilemanager/mixins';
|
@import '../../../sass/vuefilemanager/mixins';
|
||||||
|
|
||||||
.main-navigation {
|
.main-navigation {
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding-bottom: 25px;
|
padding-bottom: 25px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding-top: 25px;
|
padding-top: 25px;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
img {
|
||||||
|
cursor: pointer;
|
||||||
|
height: 38px;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-text {
|
||||||
|
font-weight: 800;
|
||||||
|
@include font-size(25);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.navigation-links {
|
||||||
|
display: inline-block;
|
||||||
|
margin-left: 25px;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
display: inline-block;
|
||||||
|
|
||||||
|
a {
|
||||||
|
padding: 14px;
|
||||||
|
font-weight: 700;
|
||||||
|
@include font-size(17);
|
||||||
|
@include transition(150ms);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-button {
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 8px 23px;
|
||||||
|
@include font-size(17);
|
||||||
|
font-weight: 700;
|
||||||
|
|
||||||
|
&.log-in {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 690px) {
|
||||||
|
.navigation {
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.logo {
|
.logo {
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
img {
|
img {
|
||||||
cursor: pointer;
|
height: auto;
|
||||||
height: 38px;
|
width: 190px;
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo-text {
|
|
||||||
font-weight: 800;
|
|
||||||
@include font-size(25);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.navigation-links {
|
.cta-button.log-in {
|
||||||
display: inline-block;
|
display: block;
|
||||||
margin-left: 25px;
|
|
||||||
|
|
||||||
&:first-child {
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
li {
|
|
||||||
display: inline-block;
|
|
||||||
|
|
||||||
a {
|
|
||||||
padding: 14px;
|
|
||||||
font-weight: 700;
|
|
||||||
@include font-size(17);
|
|
||||||
@include transition(150ms);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.cta-button {
|
|
||||||
border-radius: 6px;
|
|
||||||
padding: 8px 23px;
|
|
||||||
@include font-size(17);
|
|
||||||
font-weight: 700;
|
|
||||||
|
|
||||||
&.log-in {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (max-width: 690px) {
|
|
||||||
|
|
||||||
.navigation {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo {
|
|
||||||
|
|
||||||
img {
|
|
||||||
height: auto;
|
|
||||||
width: 190px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.cta-button.log-in {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,24 +1,24 @@
|
|||||||
<template>
|
<template>
|
||||||
<footer class="page-wrapper medium">
|
<footer class="page-wrapper medium">
|
||||||
<router-link :to="{name: 'Homepage'}" tag="div" class="logo">
|
<router-link :to="{ name: 'Homepage' }" tag="div" class="logo">
|
||||||
<img v-if="config.app_logo_horizontal" :src="$getImage(config.app_logo_horizontal)" :alt="config.app_name">
|
<img v-if="config.app_logo_horizontal" :src="$getImage(config.app_logo_horizontal)" :alt="config.app_name" />
|
||||||
<b v-if="! config.app_logo_horizontal" class="logo-text">{{ config.app_name }}</b>
|
<b v-if="!config.app_logo_horizontal" class="logo-text">{{ config.app_name }}</b>
|
||||||
</router-link>
|
</router-link>
|
||||||
<ul class="navigation-links">
|
<ul class="navigation-links">
|
||||||
<!-- <li>
|
<!-- <li>
|
||||||
<a href="/#pricing">
|
<a href="/#pricing">
|
||||||
{{ $t('page_index.menu.pricing') }}
|
{{ $t('page_index.menu.pricing') }}
|
||||||
</a>
|
</a>
|
||||||
</li>-->
|
</li>-->
|
||||||
<li>
|
<li>
|
||||||
<router-link :to="{name: 'ContactUs'}" class="hover-text-theme">
|
<router-link :to="{ name: 'ContactUs' }" class="hover-text-theme">
|
||||||
{{ $t('page_index.menu.contact_us') }}
|
{{ $t('page_index.menu.contact_us') }}
|
||||||
</router-link>
|
</router-link>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul class="navigation-links">
|
<ul class="navigation-links">
|
||||||
<li v-if="legal.visibility" v-for="(legal, index) in config.legal" :key="index">
|
<li v-if="legal.visibility" v-for="(legal, index) in config.legal" :key="index">
|
||||||
<router-link :to="{name: 'DynamicPage', params: {slug: legal.slug }}" class="hover-text-theme">
|
<router-link :to="{ name: 'DynamicPage', params: { slug: legal.slug } }" class="hover-text-theme">
|
||||||
{{ legal.title }}
|
{{ legal.title }}
|
||||||
</router-link>
|
</router-link>
|
||||||
</li>
|
</li>
|
||||||
@@ -28,86 +28,85 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapGetters } from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'IndexPageFooter',
|
name: 'IndexPageFooter',
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(['config']),
|
...mapGetters(['config']),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import '../../../sass/vuefilemanager/landing-page';
|
@import '../../../sass/vuefilemanager/landing-page';
|
||||||
@import '../../../sass/vuefilemanager/variables';
|
@import '../../../sass/vuefilemanager/variables';
|
||||||
@import '../../../sass/vuefilemanager/mixins';
|
@import '../../../sass/vuefilemanager/mixins';
|
||||||
|
|
||||||
footer {
|
footer {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding-top: 80px;
|
padding-top: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
img {
|
||||||
|
height: 38px;
|
||||||
|
width: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.logo {
|
.logo-text {
|
||||||
margin-bottom: 15px;
|
font-weight: 800;
|
||||||
cursor: pointer;
|
@include font-size(25);
|
||||||
|
|
||||||
img {
|
|
||||||
height: 38px;
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo-text {
|
|
||||||
font-weight: 800;
|
|
||||||
@include font-size(25);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.navigation-links {
|
.navigation-links {
|
||||||
|
display: inline-block;
|
||||||
|
|
||||||
|
li {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
|
||||||
|
a {
|
||||||
|
display: block;
|
||||||
|
padding: 19px;
|
||||||
|
font-weight: 700;
|
||||||
|
@include font-size(17);
|
||||||
|
@include transition(150ms);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.copyright {
|
||||||
|
@include font-size(17);
|
||||||
|
color: $text-muted;
|
||||||
|
padding-top: 50px;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
|
||||||
|
/deep/ a {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 960px) {
|
||||||
|
.navigation-links {
|
||||||
|
display: block;
|
||||||
|
|
||||||
li {
|
li {
|
||||||
display: inline-block;
|
display: block;
|
||||||
|
|
||||||
a {
|
a {
|
||||||
display: block;
|
padding: 10px 0;
|
||||||
padding: 19px;
|
|
||||||
font-weight: 700;
|
|
||||||
@include font-size(17);
|
|
||||||
@include transition(150ms);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark {
|
||||||
.copyright {
|
.copyright {
|
||||||
@include font-size(17);
|
color: $dark_mode_text_secondary;
|
||||||
color: $text-muted;
|
|
||||||
padding-top: 50px;
|
|
||||||
padding-bottom: 20px;
|
|
||||||
|
|
||||||
/deep/ a {
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (max-width: 960px) {
|
|
||||||
.navigation-links {
|
|
||||||
display: block;
|
|
||||||
|
|
||||||
li {
|
|
||||||
display: block;
|
|
||||||
|
|
||||||
a {
|
|
||||||
padding: 10px 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark {
|
|
||||||
|
|
||||||
.copyright {
|
|
||||||
color: $dark_mode_text_secondary;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,19 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<header class="main-header page-wrapper medium">
|
<header class="main-header page-wrapper medium">
|
||||||
<PageTitle
|
<PageTitle :title="index.header_title" :description="index.header_description" />
|
||||||
:title="index.header_title"
|
|
||||||
:description="index.header_description"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div v-if="! config.isAuthenticated">
|
|
||||||
|
|
||||||
|
<div v-if="!config.isAuthenticated">
|
||||||
<!--User registration button-->
|
<!--User registration button-->
|
||||||
<router-link v-if="config.userRegistration" class="sign-up-button" :to="{name: 'SignUp'}">
|
<router-link v-if="config.userRegistration" class="sign-up-button" :to="{ name: 'SignUp' }">
|
||||||
<AuthButton class="button" icon="chevron-right" :text="$t('page_index.sign_up_button')" />
|
<AuthButton class="button" icon="chevron-right" :text="$t('page_index.sign_up_button')" />
|
||||||
</router-link>
|
</router-link>
|
||||||
|
|
||||||
<!--User login button-->
|
<!--User login button-->
|
||||||
<router-link v-if="! config.userRegistration" class="sign-up-button" :to="{name: 'SignIn'}">
|
<router-link v-if="!config.userRegistration" class="sign-up-button" :to="{ name: 'SignIn' }">
|
||||||
<AuthButton class="button" icon="chevron-right" :text="$t('page_index.menu.log_in')" />
|
<AuthButton class="button" icon="chevron-right" :text="$t('page_index.menu.log_in')" />
|
||||||
</router-link>
|
</router-link>
|
||||||
|
|
||||||
@@ -24,7 +20,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="feature">
|
<div class="feature">
|
||||||
<hard-drive-icon size="19" class="feature-icon"></hard-drive-icon>
|
<hard-drive-icon size="19" class="feature-icon"></hard-drive-icon>
|
||||||
<b class="feature-title">{{ $t('page_index.sign_feature_2', {defaultSpace: config.storageDefaultSpaceFormatted}) }}</b>
|
<b class="feature-title">{{
|
||||||
|
$t('page_index.sign_feature_2', {
|
||||||
|
defaultSpace: config.storageDefaultSpaceFormatted,
|
||||||
|
})
|
||||||
|
}}</b>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -32,101 +32,108 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import HardDriveIcon from "vue-feather-icons/icons/HardDriveIcon";
|
import HardDriveIcon from 'vue-feather-icons/icons/HardDriveIcon'
|
||||||
import PageTitle from "./Components/PageTitle";
|
import PageTitle from './Components/PageTitle'
|
||||||
import AuthButton from "../Auth/AuthButton";
|
import AuthButton from '../Auth/AuthButton'
|
||||||
import { CreditCardIcon } from 'vue-feather-icons'
|
import { CreditCardIcon } from 'vue-feather-icons'
|
||||||
import { mapGetters } from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'IndexPageHeader',
|
name: 'IndexPageHeader',
|
||||||
components: {
|
components: {
|
||||||
PageTitle,
|
PageTitle,
|
||||||
CreditCardIcon,
|
CreditCardIcon,
|
||||||
HardDriveIcon,
|
HardDriveIcon,
|
||||||
AuthButton,
|
AuthButton,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(['index', 'config']),
|
...mapGetters(['index', 'config']),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import '../../../sass/vuefilemanager/landing-page';
|
@import '../../../sass/vuefilemanager/landing-page';
|
||||||
@import '../../../sass/vuefilemanager/variables';
|
@import '../../../sass/vuefilemanager/variables';
|
||||||
@import '../../../sass/vuefilemanager/mixins';
|
@import '../../../sass/vuefilemanager/mixins';
|
||||||
|
|
||||||
.features {
|
.features {
|
||||||
|
display: flex;
|
||||||
|
margin-top: 35px;
|
||||||
|
|
||||||
|
.feature {
|
||||||
display: flex;
|
display: flex;
|
||||||
margin-top: 35px;
|
margin-right: 35px;
|
||||||
|
|
||||||
.feature {
|
&:nth-child(1) {
|
||||||
display: flex;
|
path,
|
||||||
margin-right: 35px;
|
line,
|
||||||
|
polyline,
|
||||||
&:nth-child(1) {
|
rect,
|
||||||
path, line, polyline, rect, circle {
|
circle {
|
||||||
stroke: $yellow;
|
stroke: $yellow;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(2) {
|
|
||||||
path, line, polyline, rect, circle {
|
|
||||||
stroke: $purple;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
margin-right: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.feature-title {
|
|
||||||
@include font-size(14);
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
.feature-icon {
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:nth-child(2) {
|
||||||
|
path,
|
||||||
|
line,
|
||||||
|
polyline,
|
||||||
|
rect,
|
||||||
|
circle {
|
||||||
|
stroke: $purple;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.feature-title {
|
||||||
|
@include font-size(14);
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.feature-icon {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-header {
|
||||||
|
padding-top: 70px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sign-up-button {
|
||||||
|
margin-top: 65px;
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
.button {
|
||||||
|
margin-left: 0;
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 690px) {
|
||||||
|
.main-header {
|
||||||
|
padding-top: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.main-header {
|
.features {
|
||||||
padding-top: 70px;
|
display: block;
|
||||||
|
|
||||||
|
.feature {
|
||||||
|
margin-right: 0;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.sign-up-button {
|
.sign-up-button {
|
||||||
margin-top: 65px;
|
margin-top: 30px;
|
||||||
display: block;
|
|
||||||
|
|
||||||
.button {
|
|
||||||
margin-left: 0;
|
|
||||||
margin-right: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (max-width: 690px) {
|
|
||||||
|
|
||||||
.main-header {
|
|
||||||
padding-top: 50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.features {
|
|
||||||
display: block;
|
|
||||||
|
|
||||||
.feature {
|
|
||||||
margin-right: 0;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.sign-up-button {
|
|
||||||
margin-top: 30px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="page-wrapper medium pricing" v-if="! isEmpty && index.section_pricing_content === '1' && config.stripe_public_key">
|
<div class="page-wrapper medium pricing" v-if="!isEmpty && index.section_pricing_content === '1' && config.stripe_public_key">
|
||||||
<div id="pricing" class="page-title center">
|
<div id="pricing" class="page-title center">
|
||||||
<h1 class="title" v-html="index.pricing_title"></h1>
|
<h1 class="title" v-html="index.pricing_title"></h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<PricingTables class="pricing-tables" @load="pricingLoaded"/>
|
<PricingTables class="pricing-tables" @load="pricingLoaded" />
|
||||||
|
|
||||||
<div class="page-title center">
|
<div class="page-title center">
|
||||||
<h2 class="description">
|
<h2 class="description">
|
||||||
{{ index.pricing_description }}
|
{{ index.pricing_description }}
|
||||||
</h2>
|
</h2>
|
||||||
<router-link class="sign-up-button" :to="{name: 'SignUp'}">
|
<router-link class="sign-up-button" :to="{ name: 'SignUp' }">
|
||||||
<AuthButton class="button" icon="chevron-right" :text="$t('page_index.sign_up_button')" />
|
<AuthButton class="button" icon="chevron-right" :text="$t('page_index.sign_up_button')" />
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
@@ -21,157 +21,153 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import PricingTables from "./Components/PricingTables";
|
import PricingTables from './Components/PricingTables'
|
||||||
import AuthButton from "../Auth/AuthButton";
|
import AuthButton from '../Auth/AuthButton'
|
||||||
import { CloudIcon } from 'vue-feather-icons'
|
import { CloudIcon } from 'vue-feather-icons'
|
||||||
import { mapGetters } from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'IndexPricingTables',
|
name: 'IndexPricingTables',
|
||||||
components: {
|
components: {
|
||||||
PricingTables,
|
PricingTables,
|
||||||
AuthButton,
|
AuthButton,
|
||||||
CloudIcon,
|
CloudIcon,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(['index', 'config']),
|
...mapGetters(['index', 'config']),
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isEmpty: false,
|
isEmpty: false,
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
pricingLoaded(pricing) {
|
|
||||||
if (pricing.length === 0)
|
|
||||||
this.isEmpty = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
methods: {
|
||||||
|
pricingLoaded(pricing) {
|
||||||
|
if (pricing.length === 0) this.isEmpty = true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import '../../../sass/vuefilemanager/landing-page';
|
@import '../../../sass/vuefilemanager/landing-page';
|
||||||
@import '../../../sass/vuefilemanager/variables';
|
@import '../../../sass/vuefilemanager/variables';
|
||||||
@import '../../../sass/vuefilemanager/mixins';
|
@import '../../../sass/vuefilemanager/mixins';
|
||||||
|
|
||||||
.pricing {
|
.pricing {
|
||||||
.cloud-bg {
|
.cloud-bg {
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
|
|
||||||
path {
|
path {
|
||||||
stroke: none;
|
stroke: none;
|
||||||
fill: rgba($theme, 0.05);
|
fill: rgba($theme, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
&:first-of-type {
|
&:first-of-type {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 30px;
|
top: 30px;
|
||||||
right: -130px;
|
right: -130px;
|
||||||
transform: scale(-1, 1) rotate(-17deg);
|
transform: scale(-1, 1) rotate(-17deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
&:last-of-type {
|
&:last-of-type {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 160px;
|
bottom: 160px;
|
||||||
left: -230px;
|
left: -230px;
|
||||||
transform: rotate(13deg);
|
transform: rotate(13deg);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-title {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
|
||||||
|
&.center {
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-title {
|
.title {
|
||||||
position: relative;
|
max-width: 580px;
|
||||||
z-index: 1;
|
font-size: 48px;
|
||||||
|
font-weight: 800;
|
||||||
|
line-height: 1.25;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
|
||||||
&.center {
|
/deep/ span {
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
.title {
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.description {
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
max-width: 580px;
|
|
||||||
font-size: 48px;
|
font-size: 48px;
|
||||||
font-weight: 800;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
max-width: 580px;
|
||||||
|
@include font-size(20);
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 1.6;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.pricing {
|
||||||
|
padding-top: 250px;
|
||||||
|
padding-bottom: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pricing-tables {
|
||||||
|
margin-top: 50px;
|
||||||
|
margin-bottom: 60px;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sign-up-button {
|
||||||
|
padding-top: 10px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 1190px) {
|
||||||
|
.cloud-bg {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pricing {
|
||||||
|
padding-top: 150px;
|
||||||
|
padding-bottom: 60px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 960px) {
|
||||||
|
.page-title {
|
||||||
|
.title {
|
||||||
|
font-size: 28px;
|
||||||
line-height: 1.25;
|
line-height: 1.25;
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
|
|
||||||
/deep/ span {
|
/deep/ span {
|
||||||
font-size: 48px;
|
font-size: 28px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.description {
|
.description {
|
||||||
max-width: 580px;
|
@include font-size(16);
|
||||||
@include font-size(20);
|
|
||||||
font-weight: 500;
|
|
||||||
line-height: 1.6;
|
line-height: 1.6;
|
||||||
margin-bottom: 30px;
|
margin-bottom: 30px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.pricing {
|
.pricing {
|
||||||
padding-top: 250px;
|
padding-top: 50px;
|
||||||
padding-bottom: 120px;
|
padding-bottom: 120px;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
.pricing-tables {
|
|
||||||
margin-top: 50px;
|
|
||||||
margin-bottom: 60px;
|
|
||||||
position: relative;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sign-up-button {
|
|
||||||
padding-top: 10px;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (max-width: 1190px) {
|
|
||||||
|
|
||||||
.cloud-bg {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pricing {
|
|
||||||
padding-top: 150px;
|
|
||||||
padding-bottom: 60px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (max-width: 960px) {
|
|
||||||
|
|
||||||
.page-title {
|
|
||||||
|
|
||||||
.title {
|
|
||||||
font-size: 28px;
|
|
||||||
line-height: 1.25;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
|
|
||||||
/deep/ span {
|
|
||||||
font-size: 28px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.description {
|
|
||||||
@include font-size(16);
|
|
||||||
line-height: 1.6;
|
|
||||||
margin-bottom: 30px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.pricing {
|
|
||||||
padding-top: 50px;
|
|
||||||
padding-bottom: 120px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,71 +1,63 @@
|
|||||||
<template>
|
<template>
|
||||||
<transition name="context-menu">
|
<transition name="context-menu">
|
||||||
<div
|
<div v-if="isVisible" @click="closeMenu" class="fixed bottom-0 left-0 right-0 z-50 overflow-hidden rounded-tl-xl rounded-tr-xl bg-white pb-4 dark:bg-2x-dark-foreground">
|
||||||
v-if="isVisible"
|
|
||||||
@click="closeMenu"
|
|
||||||
class="fixed pb-4 bottom-0 left-0 right-0 z-50 overflow-hidden dark:bg-2x-dark-foreground bg-white rounded-tl-xl rounded-tr-xl"
|
|
||||||
>
|
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {events} from "../../bus";
|
import { events } from '../../bus'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'MenuMobile',
|
name: 'MenuMobile',
|
||||||
props: [
|
props: ['name'],
|
||||||
'name'
|
data() {
|
||||||
],
|
return {
|
||||||
data() {
|
isVisible: false,
|
||||||
return {
|
|
||||||
isVisible: false,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
closeMenu() {
|
|
||||||
this.isVisible = false
|
|
||||||
|
|
||||||
events.$emit('mobile-menu:hide')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
events.$on('mobile-menu:show', name => {
|
|
||||||
if (name === this.name)
|
|
||||||
this.isVisible = !this.isVisible
|
|
||||||
})
|
|
||||||
|
|
||||||
events.$on('mobile-menu:hide', () => this.isVisible = false)
|
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
methods: {
|
||||||
|
closeMenu() {
|
||||||
|
this.isVisible = false
|
||||||
|
|
||||||
|
events.$emit('mobile-menu:hide')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
events.$on('mobile-menu:show', (name) => {
|
||||||
|
if (name === this.name) this.isVisible = !this.isVisible
|
||||||
|
})
|
||||||
|
|
||||||
|
events.$on('mobile-menu:hide', () => (this.isVisible = false))
|
||||||
|
},
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
// Transition
|
||||||
|
.context-menu-enter-active,
|
||||||
|
.fade-enter-active {
|
||||||
|
transition: all 300ms;
|
||||||
|
}
|
||||||
|
|
||||||
// Transition
|
.context-menu-leave-active,
|
||||||
.context-menu-enter-active,
|
.fade-leave-active {
|
||||||
.fade-enter-active {
|
transition: all 300ms;
|
||||||
transition: all 300ms;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.context-menu-leave-active,
|
.fade-enter,
|
||||||
.fade-leave-active {
|
.fade-leave-to {
|
||||||
transition: all 300ms;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fade-enter,
|
.context-menu-enter,
|
||||||
.fade-leave-to {
|
.context-menu-leave-to {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
transform: translateY(100%);
|
||||||
|
}
|
||||||
|
|
||||||
.context-menu-enter,
|
.context-menu-leave-active {
|
||||||
.context-menu-leave-to {
|
position: fixed;
|
||||||
opacity: 0;
|
}
|
||||||
transform: translateY(100%);
|
|
||||||
}
|
|
||||||
|
|
||||||
.context-menu-leave-active {
|
|
||||||
position: fixed;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -5,18 +5,18 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'MenuMobileGroup',
|
name: 'MenuMobileGroup',
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "resources/sass/vuefilemanager/_variables";
|
@import 'resources/sass/vuefilemanager/_variables';
|
||||||
@import "resources/sass/vuefilemanager/_mixins";
|
@import 'resources/sass/vuefilemanager/_mixins';
|
||||||
|
|
||||||
.menu-options {
|
.menu-options {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<header class="mobile-header">
|
<header class="mobile-header">
|
||||||
|
|
||||||
<!-- Go back-->
|
<!-- Go back-->
|
||||||
<div @click="goBack" class="go-back">
|
<div @click="goBack" class="go-back">
|
||||||
<chevron-left-icon size="17" class="icon" />
|
<chevron-left-icon size="17" class="icon" />
|
||||||
@@ -17,92 +16,86 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {events} from '../../bus'
|
import { events } from '../../bus'
|
||||||
|
|
||||||
import {
|
import { ChevronLeftIcon, MenuIcon } from 'vue-feather-icons'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'MobileHeader',
|
||||||
|
props: ['title'],
|
||||||
|
components: {
|
||||||
ChevronLeftIcon,
|
ChevronLeftIcon,
|
||||||
MenuIcon,
|
MenuIcon,
|
||||||
} from 'vue-feather-icons'
|
},
|
||||||
|
methods: {
|
||||||
export default {
|
goBack() {
|
||||||
name: 'MobileHeader',
|
this.$router.back()
|
||||||
props: [
|
|
||||||
'title'
|
|
||||||
],
|
|
||||||
components: {
|
|
||||||
ChevronLeftIcon,
|
|
||||||
MenuIcon,
|
|
||||||
},
|
},
|
||||||
methods: {
|
},
|
||||||
goBack() {
|
}
|
||||||
this.$router.back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import '../../../sass/vuefilemanager/variables';
|
@import '../../../sass/vuefilemanager/variables';
|
||||||
@import '../../../sass/vuefilemanager/mixins';
|
@import '../../../sass/vuefilemanager/mixins';
|
||||||
|
|
||||||
.mobile-header {
|
.mobile-header {
|
||||||
padding: 10px 0;
|
padding: 10px 0;
|
||||||
|
text-align: center;
|
||||||
|
background: white;
|
||||||
|
position: sticky;
|
||||||
|
display: none;
|
||||||
|
z-index: 6;
|
||||||
|
top: 0;
|
||||||
|
|
||||||
|
> div {
|
||||||
|
flex-grow: 1;
|
||||||
|
align-self: center;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.go-back {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.location-name {
|
||||||
|
line-height: 1;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background: white;
|
width: 100%;
|
||||||
position: sticky;
|
vertical-align: middle;
|
||||||
display: none;
|
@include font-size(15);
|
||||||
z-index: 6;
|
color: $text;
|
||||||
top: 0;
|
font-weight: 700;
|
||||||
|
max-width: 220px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
> div {
|
.mobile-menu {
|
||||||
flex-grow: 1;
|
text-align: right;
|
||||||
align-self: center;
|
}
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.go-back {
|
.icon {
|
||||||
text-align: left;
|
vertical-align: middle;
|
||||||
}
|
margin-top: -4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 690px) {
|
||||||
|
.mobile-header {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark {
|
||||||
|
.mobile-header {
|
||||||
|
background: $dark_mode_background;
|
||||||
|
|
||||||
.location-name {
|
.location-name {
|
||||||
line-height: 1;
|
color: $dark_mode_text_primary;
|
||||||
text-align: center;
|
|
||||||
width: 100%;
|
|
||||||
vertical-align: middle;
|
|
||||||
@include font-size(15);
|
|
||||||
color: $text;
|
|
||||||
font-weight: 700;
|
|
||||||
max-width: 220px;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mobile-menu {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
vertical-align: middle;
|
|
||||||
margin-top: -4px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
@media only screen and (max-width: 690px) {
|
|
||||||
.mobile-header {
|
|
||||||
display: flex;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark {
|
|
||||||
.mobile-header {
|
|
||||||
background: $dark_mode_background;
|
|
||||||
|
|
||||||
.location-name {
|
|
||||||
color: $dark_mode_text_primary;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -9,43 +9,44 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { Edit2Icon, XIcon } from 'vue-feather-icons'
|
import { Edit2Icon, XIcon } from 'vue-feather-icons'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ActionButton',
|
name: 'ActionButton',
|
||||||
props: ['icon'],
|
props: ['icon'],
|
||||||
components: {
|
components: {
|
||||||
Edit2Icon,
|
Edit2Icon,
|
||||||
XIcon,
|
XIcon,
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import '../../../sass/vuefilemanager/variables';
|
@import '../../../sass/vuefilemanager/variables';
|
||||||
@import '../../../sass/vuefilemanager/mixins';
|
@import '../../../sass/vuefilemanager/mixins';
|
||||||
|
|
||||||
.action-button {
|
.action-button {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
.label {
|
.label {
|
||||||
@include font-size(12);
|
@include font-size(12);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
@include font-size(10);
|
|
||||||
vertical-align: middle;
|
|
||||||
display: inline-block;
|
|
||||||
margin-right: 2px;
|
|
||||||
|
|
||||||
path, circle, line {
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark {
|
.icon {
|
||||||
|
@include font-size(10);
|
||||||
|
vertical-align: middle;
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 2px;
|
||||||
|
|
||||||
|
path,
|
||||||
|
circle,
|
||||||
|
line {
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark {
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,41 +1,38 @@
|
|||||||
<template>
|
<template>
|
||||||
<b class="color-label capitalize inline-block text-xs font-bold rounded-lg py-1 px-2" :class="color">
|
<b class="color-label inline-block rounded-lg py-1 px-2 text-xs font-bold capitalize" :class="color">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</b>
|
</b>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'ColorLabel',
|
name: 'ColorLabel',
|
||||||
props: [
|
props: ['color'],
|
||||||
'color'
|
}
|
||||||
],
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import '../../../sass/vuefilemanager/variables';
|
@import '../../../sass/vuefilemanager/variables';
|
||||||
|
|
||||||
.color-label {
|
.color-label {
|
||||||
|
&.purple {
|
||||||
&.purple {
|
color: $purple;
|
||||||
color: $purple;
|
background: rgba($purple, 0.1);
|
||||||
background: rgba($purple, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.yellow {
|
|
||||||
color: $yellow;
|
|
||||||
background: rgba($yellow, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.green {
|
|
||||||
color: $theme;
|
|
||||||
background: rgba($theme, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.red {
|
|
||||||
color: $danger;
|
|
||||||
background: rgba($danger, 0.1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.yellow {
|
||||||
|
color: $yellow;
|
||||||
|
background: rgba($yellow, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.green {
|
||||||
|
color: $theme;
|
||||||
|
background: rgba($theme, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.red {
|
||||||
|
color: $danger;
|
||||||
|
background: rgba($danger, 0.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="color-pick-wrapper">
|
<div class="color-pick-wrapper">
|
||||||
<label class="main-label">{{ $t('popup_rename.color_pick_label') }}:</label>
|
<label class="main-label">{{ $t('popup_rename.color_pick_label') }}:</label>
|
||||||
<ul class="color-wrapper">
|
<ul class="color-wrapper">
|
||||||
<li v-for="(color, i) in colors" :key="i" @click="setColor( color )" class="single-color">
|
<li v-for="(color, i) in colors" :key="i" @click="setColor(color)" class="single-color">
|
||||||
<check-icon v-if="color === selectedColor" class="color-icon" size="22"/>
|
<check-icon v-if="color === selectedColor" class="color-icon" size="22" />
|
||||||
<span :style="{background:color}" class="color-box"></span>
|
<span :style="{ background: color }" class="color-box"></span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@@ -16,14 +16,12 @@ import { mapGetters } from 'vuex'
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ColorPicker',
|
name: 'ColorPicker',
|
||||||
props: [ 'pickedColor' ],
|
props: ['pickedColor'],
|
||||||
components: { CheckIcon },
|
components: { CheckIcon },
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters([
|
...mapGetters(['config']),
|
||||||
'config'
|
|
||||||
])
|
|
||||||
},
|
},
|
||||||
data () {
|
data() {
|
||||||
return {
|
return {
|
||||||
selectedColor: this.pickedColor,
|
selectedColor: this.pickedColor,
|
||||||
colors: [
|
colors: [
|
||||||
@@ -48,20 +46,19 @@ export default {
|
|||||||
'#FE7D6F',
|
'#FE7D6F',
|
||||||
'#4c4c4c',
|
'#4c4c4c',
|
||||||
'#06070B',
|
'#06070B',
|
||||||
]
|
],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
setColor (value) {
|
setColor(value) {
|
||||||
|
|
||||||
this.selectedColor = value
|
this.selectedColor = value
|
||||||
|
|
||||||
this.$emit('input', value)
|
this.$emit('input', value)
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.colors.push(this.config.app_color)
|
this.colors.push(this.config.app_color)
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -132,5 +129,4 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,109 +1,102 @@
|
|||||||
<template>
|
<template>
|
||||||
<PopupWrapper name="confirm-password">
|
<PopupWrapper name="confirm-password">
|
||||||
|
|
||||||
<PopupHeader :title="$t('Confirm Password')" icon="edit" />
|
<PopupHeader :title="$t('Confirm Password')" icon="edit" />
|
||||||
|
|
||||||
<PopupContent>
|
<PopupContent>
|
||||||
<ValidationObserver @submit.prevent="confirmPassword" ref="passwordForm" v-slot="{ invalid }" tag="form">
|
<ValidationObserver @submit.prevent="confirmPassword" ref="passwordForm" v-slot="{ invalid }" tag="form">
|
||||||
<ValidationProvider tag="div" mode="passive" name="Password" rules="required" v-slot="{ errors }">
|
<ValidationProvider tag="div" mode="passive" name="Password" rules="required" v-slot="{ errors }">
|
||||||
<AppInputText :title="$t('popup_2fa.input_label')" :error="errors[0]" :is-last="true">
|
<AppInputText :title="$t('popup_2fa.input_label')" :error="errors[0]" :is-last="true">
|
||||||
<input v-model="password" :class="{'border-red': errors[0]}" type="password" ref="input" class="focus-border-theme input-dark" :placeholder="$t('page_sign_in.placeholder_password')">
|
<input
|
||||||
</AppInputText>
|
v-model="password"
|
||||||
|
:class="{ 'border-red': errors[0] }"
|
||||||
|
type="password"
|
||||||
|
ref="input"
|
||||||
|
class="focus-border-theme input-dark"
|
||||||
|
:placeholder="$t('page_sign_in.placeholder_password')"
|
||||||
|
/>
|
||||||
|
</AppInputText>
|
||||||
</ValidationProvider>
|
</ValidationProvider>
|
||||||
</ValidationObserver>
|
</ValidationObserver>
|
||||||
</PopupContent>
|
</PopupContent>
|
||||||
|
|
||||||
<PopupActions>
|
<PopupActions>
|
||||||
<ButtonBase
|
<ButtonBase class="w-full" @click.native="$closePopup()" button-style="secondary">
|
||||||
class="w-full"
|
|
||||||
@click.native="$closePopup()"
|
|
||||||
button-style="secondary"
|
|
||||||
>
|
|
||||||
{{ $t('global.cancel') }}
|
{{ $t('global.cancel') }}
|
||||||
</ButtonBase>
|
</ButtonBase>
|
||||||
<ButtonBase
|
<ButtonBase class="w-full" @click.native="confirmPassword" button-style="theme" :loading="isLoading" :disabled="isLoading">
|
||||||
class="w-full"
|
{{ $t('popup_2fa.confirm_button') }}
|
||||||
@click.native="confirmPassword"
|
|
||||||
button-style="theme"
|
|
||||||
:loading="isLoading"
|
|
||||||
:disabled="isLoading"
|
|
||||||
>
|
|
||||||
{{ $t('popup_2fa.confirm_button') }}
|
|
||||||
</ButtonBase>
|
</ButtonBase>
|
||||||
</PopupActions>
|
</PopupActions>
|
||||||
</PopupWrapper>
|
</PopupWrapper>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {ValidationProvider, ValidationObserver} from 'vee-validate/dist/vee-validate.full'
|
import { ValidationProvider, ValidationObserver } from 'vee-validate/dist/vee-validate.full'
|
||||||
import PopupWrapper from "./Popup/PopupWrapper";
|
import PopupWrapper from './Popup/PopupWrapper'
|
||||||
import PopupActions from './Popup/PopupActions'
|
import PopupActions from './Popup/PopupActions'
|
||||||
import PopupContent from './Popup/PopupContent'
|
import PopupContent from './Popup/PopupContent'
|
||||||
import PopupHeader from './Popup/PopupHeader'
|
import PopupHeader from './Popup/PopupHeader'
|
||||||
import ButtonBase from "../FilesView/ButtonBase";
|
import ButtonBase from '../FilesView/ButtonBase'
|
||||||
import AppInputText from "../Admin/AppInputText"
|
import AppInputText from '../Admin/AppInputText'
|
||||||
import {required} from 'vee-validate/dist/rules'
|
import { required } from 'vee-validate/dist/rules'
|
||||||
import {events} from '../../bus'
|
import { events } from '../../bus'
|
||||||
import {mapGetters} from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "ConfirmPassword",
|
name: 'ConfirmPassword',
|
||||||
components: {
|
components: {
|
||||||
ValidationProvider,
|
ValidationProvider,
|
||||||
ValidationObserver,
|
ValidationObserver,
|
||||||
AppInputText,
|
AppInputText,
|
||||||
PopupWrapper,
|
PopupWrapper,
|
||||||
PopupActions,
|
PopupActions,
|
||||||
PopupContent,
|
PopupContent,
|
||||||
PopupHeader,
|
PopupHeader,
|
||||||
ButtonBase,
|
ButtonBase,
|
||||||
required,
|
required,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters([
|
...mapGetters(['user']),
|
||||||
'user'
|
},
|
||||||
]),
|
data() {
|
||||||
},
|
return {
|
||||||
data() {
|
isLoading: false,
|
||||||
return {
|
password: '',
|
||||||
isLoading: false,
|
args: undefined,
|
||||||
password: '',
|
}
|
||||||
args: undefined,
|
},
|
||||||
}
|
methods: {
|
||||||
},
|
confirmPassword() {
|
||||||
methods: {
|
this.isLoading = true
|
||||||
confirmPassword() {
|
|
||||||
this.isLoading = true
|
|
||||||
|
|
||||||
axios
|
axios
|
||||||
.post('/user/confirm-password', {
|
.post('/user/confirm-password', {
|
||||||
password: this.password
|
password: this.password,
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
events.$emit('password:confirmed', this.args)
|
events.$emit('password:confirmed', this.args)
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch((error) => {
|
||||||
if (error.response.status === 422) {
|
if (error.response.status === 422) {
|
||||||
this.$refs.passwordForm.setErrors({
|
this.$refs.passwordForm.setErrors({
|
||||||
'Password': this.$t('validation_errors.incorrect_password')
|
Password: this.$t('validation_errors.incorrect_password'),
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
this.isLoading = false
|
this.isLoading = false
|
||||||
this.password = undefined
|
this.password = undefined
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
// Show popup
|
// Show popup
|
||||||
events.$on('popup:open', args => {
|
events.$on('popup:open', (args) => {
|
||||||
|
if (args.name !== 'confirm-password') return
|
||||||
|
|
||||||
if (args.name !== 'confirm-password') return
|
this.args = args
|
||||||
|
})
|
||||||
this.args = args
|
},
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,44 +1,45 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="isVisibleDisclaimer" class="fixed bottom-0 sm:left-16 left-0 sm:right-auto right-0 sm:p-3 sm:w-56 w-full p-4 shadow-xl rounded-tl-xl rounded-tr-lg dark:bg-dark-foreground bg-white z-20">
|
<div
|
||||||
<span @click="closeDisclaimer" class="absolute -right-1 -top-1 p-3 cursor-pointer">
|
v-if="isVisibleDisclaimer"
|
||||||
|
class="fixed bottom-0 left-0 right-0 z-20 w-full rounded-tl-xl rounded-tr-lg bg-white p-4 shadow-xl dark:bg-dark-foreground sm:left-16 sm:right-auto sm:w-56 sm:p-3"
|
||||||
|
>
|
||||||
|
<span @click="closeDisclaimer" class="absolute -right-1 -top-1 cursor-pointer p-3">
|
||||||
<x-icon size="10" />
|
<x-icon size="10" />
|
||||||
</span>
|
</span>
|
||||||
<i18n path="cookie_disclaimer.description" tag="p" class="text-xs">
|
<i18n path="cookie_disclaimer.description" tag="p" class="text-xs">
|
||||||
<router-link :to="{name: 'DynamicPage', params: {slug: 'cookie-policy'}}" class="text-theme text-xs">
|
<router-link :to="{ name: 'DynamicPage', params: { slug: 'cookie-policy' } }" class="text-theme text-xs">
|
||||||
{{ $t('cookie_disclaimer.button') }}
|
{{ $t('cookie_disclaimer.button') }}
|
||||||
</router-link>
|
</router-link>
|
||||||
</i18n>
|
</i18n>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {XIcon} from 'vue-feather-icons'
|
import { XIcon } from 'vue-feather-icons'
|
||||||
import { mapGetters } from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'CookieDisclaimer',
|
name: 'CookieDisclaimer',
|
||||||
components: {
|
components: {
|
||||||
XIcon,
|
XIcon,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters([
|
...mapGetters(['config']),
|
||||||
'config'
|
},
|
||||||
]),
|
data() {
|
||||||
},
|
return {
|
||||||
data() {
|
isVisibleDisclaimer: false,
|
||||||
return {
|
|
||||||
isVisibleDisclaimer: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
closeDisclaimer() {
|
|
||||||
localStorage.setItem('isHiddenDisclaimer', 'true')
|
|
||||||
|
|
||||||
this.isVisibleDisclaimer = false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.isVisibleDisclaimer = !localStorage.getItem('isHiddenDisclaimer');
|
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
methods: {
|
||||||
|
closeDisclaimer() {
|
||||||
|
localStorage.setItem('isHiddenDisclaimer', 'true')
|
||||||
|
|
||||||
|
this.isVisibleDisclaimer = false
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.isVisibleDisclaimer = !localStorage.getItem('isHiddenDisclaimer')
|
||||||
|
},
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,114 +1,105 @@
|
|||||||
<template>
|
<template>
|
||||||
<PopupWrapper name="create-folder">
|
<PopupWrapper name="create-folder">
|
||||||
|
|
||||||
<!--Title-->
|
<!--Title-->
|
||||||
<PopupHeader :title="$t('popup_create_folder.title')" icon="edit" />
|
<PopupHeader :title="$t('popup_create_folder.title')" icon="edit" />
|
||||||
|
|
||||||
<!--Content-->
|
<!--Content-->
|
||||||
<PopupContent>
|
<PopupContent>
|
||||||
|
|
||||||
<!--Form to set sharing-->
|
<!--Form to set sharing-->
|
||||||
<ValidationObserver @submit.prevent="createFolder" ref="createForm" v-slot="{ invalid }" tag="form">
|
<ValidationObserver @submit.prevent="createFolder" ref="createForm" v-slot="{ invalid }" tag="form">
|
||||||
|
|
||||||
<!--Set folder name-->
|
<!--Set folder name-->
|
||||||
<ValidationProvider tag="div" mode="passive" name="Title" rules="required" v-slot="{ errors }">
|
<ValidationProvider tag="div" mode="passive" name="Title" rules="required" v-slot="{ errors }">
|
||||||
<AppInputText :title="$t('popup_create_folder.label')" :error="errors[0]">
|
<AppInputText :title="$t('popup_create_folder.label')" :error="errors[0]">
|
||||||
<input v-model="name" :class="{'border-red': errors[0]}" type="text" ref="input" class="focus-border-theme input-dark" :placeholder="$t('popup_create_folder.placeholder')">
|
<input
|
||||||
</AppInputText>
|
v-model="name"
|
||||||
|
:class="{ 'border-red': errors[0] }"
|
||||||
|
type="text"
|
||||||
|
ref="input"
|
||||||
|
class="focus-border-theme input-dark"
|
||||||
|
:placeholder="$t('popup_create_folder.placeholder')"
|
||||||
|
/>
|
||||||
|
</AppInputText>
|
||||||
</ValidationProvider>
|
</ValidationProvider>
|
||||||
|
|
||||||
<AppInputSwitch :title="$t('Emoji as an Icon')" :description="$t('Replace folder icon with an Emoji')" :is-last="! isEmoji">
|
<AppInputSwitch :title="$t('Emoji as an Icon')" :description="$t('Replace folder icon with an Emoji')" :is-last="!isEmoji">
|
||||||
<SwitchInput v-model="isEmoji" :state="isEmoji" />
|
<SwitchInput v-model="isEmoji" :state="isEmoji" />
|
||||||
</AppInputSwitch>
|
</AppInputSwitch>
|
||||||
|
|
||||||
<!--Set emoji-->
|
<!--Set emoji-->
|
||||||
<EmojiPicker v-if="isEmoji" v-model="emoji" :default-emoji="emoji"/>
|
<EmojiPicker v-if="isEmoji" v-model="emoji" :default-emoji="emoji" />
|
||||||
</ValidationObserver>
|
</ValidationObserver>
|
||||||
</PopupContent>
|
</PopupContent>
|
||||||
|
|
||||||
<!--Actions-->
|
<!--Actions-->
|
||||||
<PopupActions>
|
<PopupActions>
|
||||||
<ButtonBase
|
<ButtonBase class="w-full" @click.native="$closePopup()" button-style="secondary">{{ $t('popup_move_item.cancel') }} </ButtonBase>
|
||||||
class="w-full"
|
<ButtonBase class="w-full" @click.native="createFolder" button-style="theme">{{ $t('popup_create_folder.title') }} </ButtonBase>
|
||||||
@click.native="$closePopup()"
|
|
||||||
button-style="secondary"
|
|
||||||
>{{ $t('popup_move_item.cancel') }}
|
|
||||||
</ButtonBase>
|
|
||||||
<ButtonBase
|
|
||||||
class="w-full"
|
|
||||||
@click.native="createFolder"
|
|
||||||
button-style="theme"
|
|
||||||
>{{ $t('popup_create_folder.title') }}
|
|
||||||
</ButtonBase>
|
|
||||||
</PopupActions>
|
</PopupActions>
|
||||||
</PopupWrapper>
|
</PopupWrapper>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {ValidationProvider, ValidationObserver} from 'vee-validate/dist/vee-validate.full'
|
import { ValidationProvider, ValidationObserver } from 'vee-validate/dist/vee-validate.full'
|
||||||
import PopupWrapper from "./Popup/PopupWrapper";
|
import PopupWrapper from './Popup/PopupWrapper'
|
||||||
import PopupActions from "./Popup/PopupActions";
|
import PopupActions from './Popup/PopupActions'
|
||||||
import PopupContent from "./Popup/PopupContent";
|
import PopupContent from './Popup/PopupContent'
|
||||||
import PopupHeader from "./Popup/PopupHeader";
|
import PopupHeader from './Popup/PopupHeader'
|
||||||
import ThumbnailItem from "./ThumbnailItem";
|
import ThumbnailItem from './ThumbnailItem'
|
||||||
import ButtonBase from "../FilesView/ButtonBase";
|
import ButtonBase from '../FilesView/ButtonBase'
|
||||||
import {required} from 'vee-validate/dist/rules'
|
import { required } from 'vee-validate/dist/rules'
|
||||||
import AppInputSwitch from "../Admin/AppInputSwitch"
|
import AppInputSwitch from '../Admin/AppInputSwitch'
|
||||||
import AppInputText from "../Admin/AppInputText"
|
import AppInputText from '../Admin/AppInputText'
|
||||||
import SwitchInput from "./Forms/SwitchInput"
|
import SwitchInput from './Forms/SwitchInput'
|
||||||
import {events} from '../../bus'
|
import { events } from '../../bus'
|
||||||
import EmojiPicker from "./EmojiPicker"
|
import EmojiPicker from './EmojiPicker'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'CreateFolderPopup',
|
name: 'CreateFolderPopup',
|
||||||
components: {
|
components: {
|
||||||
AppInputSwitch,
|
AppInputSwitch,
|
||||||
SwitchInput,
|
SwitchInput,
|
||||||
EmojiPicker,
|
EmojiPicker,
|
||||||
AppInputText,
|
AppInputText,
|
||||||
ValidationProvider,
|
ValidationProvider,
|
||||||
ValidationObserver,
|
ValidationObserver,
|
||||||
ThumbnailItem,
|
ThumbnailItem,
|
||||||
PopupWrapper,
|
PopupWrapper,
|
||||||
PopupActions,
|
PopupActions,
|
||||||
PopupContent,
|
PopupContent,
|
||||||
PopupHeader,
|
PopupHeader,
|
||||||
ButtonBase,
|
ButtonBase,
|
||||||
required,
|
required,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
name: undefined,
|
name: undefined,
|
||||||
isEmoji: false,
|
isEmoji: false,
|
||||||
emoji: undefined,
|
emoji: undefined,
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
async createFolder() {
|
|
||||||
|
|
||||||
// Validate fields
|
|
||||||
const isValid = await this.$refs.createForm.validate();
|
|
||||||
|
|
||||||
if (!isValid) return;
|
|
||||||
|
|
||||||
await this.$store.dispatch('createFolder', {
|
|
||||||
name: this.name,
|
|
||||||
emoji: this.emoji
|
|
||||||
})
|
|
||||||
|
|
||||||
this.$closePopup()
|
|
||||||
|
|
||||||
this.name = undefined
|
|
||||||
this.isEmoji = false
|
|
||||||
this.emoji = undefined
|
|
||||||
},
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
events.$on('popup:open', ({name}) => {
|
|
||||||
|
|
||||||
if (name === 'create-folder' && ! this.$isMobile())
|
|
||||||
this.$nextTick(() => this.$refs.input.focus())
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
methods: {
|
||||||
|
async createFolder() {
|
||||||
|
// Validate fields
|
||||||
|
const isValid = await this.$refs.createForm.validate()
|
||||||
|
|
||||||
|
if (!isValid) return
|
||||||
|
|
||||||
|
await this.$store.dispatch('createFolder', {
|
||||||
|
name: this.name,
|
||||||
|
emoji: this.emoji,
|
||||||
|
})
|
||||||
|
|
||||||
|
this.$closePopup()
|
||||||
|
|
||||||
|
this.name = undefined
|
||||||
|
this.isEmoji = false
|
||||||
|
this.emoji = undefined
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
events.$on('popup:open', ({ name }) => {
|
||||||
|
if (name === 'create-folder' && !this.$isMobile()) this.$nextTick(() => this.$refs.input.focus())
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,54 +1,43 @@
|
|||||||
<template>
|
<template>
|
||||||
<PopupWrapper name="create-personal-token">
|
<PopupWrapper name="create-personal-token">
|
||||||
|
|
||||||
<PopupHeader :title="$t('popup_personal_token.title')" icon="key" />
|
<PopupHeader :title="$t('popup_personal_token.title')" icon="key" />
|
||||||
|
|
||||||
<PopupContent>
|
<PopupContent>
|
||||||
<ValidationObserver v-if="! token" @submit.prevent="createTokenForm" ref="createToken" v-slot="{ invalid }" tag="form">
|
<ValidationObserver v-if="!token" @submit.prevent="createTokenForm" ref="createToken" v-slot="{ invalid }" tag="form">
|
||||||
|
|
||||||
<ValidationProvider tag="div" mode="passive" name="Token Name" rules="required" v-slot="{ errors }">
|
<ValidationProvider tag="div" mode="passive" name="Token Name" rules="required" v-slot="{ errors }">
|
||||||
<AppInputText :title="$t('popup_personal_token.label')" :error="errors[0]" :is-last="true">
|
<AppInputText :title="$t('popup_personal_token.label')" :error="errors[0]" :is-last="true">
|
||||||
<input v-model="name" :class="{'border-red': errors[0]}" type="text" ref="input" class="focus-border-theme input-dark" :placeholder="$t('popup_personal_token.plc')">
|
<input
|
||||||
</AppInputText>
|
v-model="name"
|
||||||
|
:class="{ 'border-red': errors[0] }"
|
||||||
|
type="text"
|
||||||
|
ref="input"
|
||||||
|
class="focus-border-theme input-dark"
|
||||||
|
:placeholder="$t('popup_personal_token.plc')"
|
||||||
|
/>
|
||||||
|
</AppInputText>
|
||||||
</ValidationProvider>
|
</ValidationProvider>
|
||||||
|
|
||||||
</ValidationObserver>
|
</ValidationObserver>
|
||||||
|
|
||||||
<AppInputText v-if="token" :title="$t('popup_personal_token.your_token')" :is-last="true">
|
<AppInputText v-if="token" :title="$t('popup_personal_token.your_token')" :is-last="true">
|
||||||
<CopyInput size="small" :str="token['plainTextToken']" />
|
<CopyInput size="small" :str="token['plainTextToken']" />
|
||||||
|
|
||||||
<InfoBox style="margin-bottom: 0; margin-top: 20px">
|
|
||||||
<p v-html="$t('popup_personal_token.copy_token')"></p>
|
|
||||||
</InfoBox>
|
|
||||||
</AppInputText>
|
|
||||||
|
|
||||||
|
<InfoBox style="margin-bottom: 0; margin-top: 20px">
|
||||||
|
<p v-html="$t('popup_personal_token.copy_token')"></p>
|
||||||
|
</InfoBox>
|
||||||
|
</AppInputText>
|
||||||
</PopupContent>
|
</PopupContent>
|
||||||
|
|
||||||
<PopupActions v-if="! token">
|
<PopupActions v-if="!token">
|
||||||
<ButtonBase
|
<ButtonBase class="w-full" @click.native="$closePopup()" button-style="secondary">
|
||||||
class="w-full"
|
|
||||||
@click.native="$closePopup()"
|
|
||||||
button-style="secondary"
|
|
||||||
>
|
|
||||||
{{ $t('global.cancel') }}
|
{{ $t('global.cancel') }}
|
||||||
</ButtonBase>
|
</ButtonBase>
|
||||||
<ButtonBase
|
<ButtonBase class="w-full" @click.native="createTokenForm" button-style="theme" :loading="isLoading" :disabled="isLoading">
|
||||||
class="w-full"
|
{{ $t('personal_token.create_token') }}
|
||||||
@click.native="createTokenForm"
|
|
||||||
button-style="theme"
|
|
||||||
:loading="isLoading"
|
|
||||||
:disabled="isLoading"
|
|
||||||
>
|
|
||||||
{{ $t('personal_token.create_token') }}
|
|
||||||
</ButtonBase>
|
</ButtonBase>
|
||||||
</PopupActions>
|
</PopupActions>
|
||||||
|
|
||||||
<PopupActions v-if="token">
|
<PopupActions v-if="token">
|
||||||
<ButtonBase
|
<ButtonBase class="w-full" @click.native="closePopup" button-style="theme">
|
||||||
class="w-full"
|
|
||||||
@click.native="closePopup"
|
|
||||||
button-style="theme"
|
|
||||||
>
|
|
||||||
{{ $t('shared_form.button_done') }}
|
{{ $t('shared_form.button_done') }}
|
||||||
</ButtonBase>
|
</ButtonBase>
|
||||||
</PopupActions>
|
</PopupActions>
|
||||||
@@ -56,82 +45,79 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import AppInputText from "../Admin/AppInputText";
|
import AppInputText from '../Admin/AppInputText'
|
||||||
import {ValidationProvider, ValidationObserver} from 'vee-validate/dist/vee-validate.full'
|
import { ValidationProvider, ValidationObserver } from 'vee-validate/dist/vee-validate.full'
|
||||||
import PopupWrapper from "./Popup/PopupWrapper";
|
import PopupWrapper from './Popup/PopupWrapper'
|
||||||
import PopupActions from "./Popup/PopupActions";
|
import PopupActions from './Popup/PopupActions'
|
||||||
import PopupContent from "./Popup/PopupContent";
|
import PopupContent from './Popup/PopupContent'
|
||||||
import PopupHeader from "./Popup/PopupHeader";
|
import PopupHeader from './Popup/PopupHeader'
|
||||||
import CopyInput from "./Forms/CopyInput";
|
import CopyInput from './Forms/CopyInput'
|
||||||
import ButtonBase from "../FilesView/ButtonBase";
|
import ButtonBase from '../FilesView/ButtonBase'
|
||||||
import InfoBox from "./Forms/InfoBox";
|
import InfoBox from './Forms/InfoBox'
|
||||||
import {required} from 'vee-validate/dist/rules'
|
import { required } from 'vee-validate/dist/rules'
|
||||||
import {events} from '../../bus'
|
import { events } from '../../bus'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "CreatePersonalTokenPopup",
|
name: 'CreatePersonalTokenPopup',
|
||||||
components: {
|
components: {
|
||||||
ValidationProvider,
|
ValidationProvider,
|
||||||
ValidationObserver,
|
ValidationObserver,
|
||||||
AppInputText,
|
AppInputText,
|
||||||
PopupWrapper,
|
PopupWrapper,
|
||||||
PopupActions,
|
PopupActions,
|
||||||
PopupContent,
|
PopupContent,
|
||||||
PopupHeader,
|
PopupHeader,
|
||||||
ButtonBase,
|
ButtonBase,
|
||||||
CopyInput,
|
CopyInput,
|
||||||
required,
|
required,
|
||||||
InfoBox,
|
InfoBox,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
name: undefined,
|
name: undefined,
|
||||||
token: undefined
|
token: undefined,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async createTokenForm() {
|
async createTokenForm() {
|
||||||
|
const isValid = await this.$refs.createToken.validate()
|
||||||
|
|
||||||
const isValid = await this.$refs.createToken.validate()
|
if (!isValid) return
|
||||||
|
|
||||||
if (!isValid) return
|
this.isLoading = true
|
||||||
|
|
||||||
this.isLoading = true
|
axios
|
||||||
|
.post('/api/user/tokens', {
|
||||||
|
name: this.name,
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
this.token = response.data
|
||||||
|
|
||||||
axios
|
events.$emit('reload-personal-access-tokens')
|
||||||
.post('/api/user/tokens', {
|
})
|
||||||
name: this.name
|
.catch(() => this.$isSomethingWrong())
|
||||||
})
|
.finally(() => {
|
||||||
.then(response => {
|
this.isLoading = false
|
||||||
this.token = response.data
|
this.name = undefined
|
||||||
|
})
|
||||||
events.$emit('reload-personal-access-tokens')
|
},
|
||||||
})
|
closePopup() {
|
||||||
.catch(() => this.$isSomethingWrong())
|
this.$closePopup()
|
||||||
.finally(() => {
|
this.token = undefined
|
||||||
this.isLoading = false
|
},
|
||||||
this.name = undefined
|
},
|
||||||
})
|
|
||||||
},
|
|
||||||
closePopup() {
|
|
||||||
this.$closePopup()
|
|
||||||
this.token = undefined
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import '../../../sass/vuefilemanager/inapp-forms';
|
@import '../../../sass/vuefilemanager/inapp-forms';
|
||||||
@import '../../../sass/vuefilemanager/forms';
|
@import '../../../sass/vuefilemanager/forms';
|
||||||
|
|
||||||
.dark {
|
|
||||||
|
|
||||||
.info-box {
|
|
||||||
background: lighten($dark_mode_foreground, 3%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
.dark {
|
||||||
|
.info-box {
|
||||||
|
background: lighten($dark_mode_foreground, 3%);
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,55 +1,44 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="emoji">
|
<div v-if="emoji">
|
||||||
<div
|
<div v-if="config.defaultEmoji === 'twemoji'" v-html="transferEmoji" style="font-size: inherit; transform: scale(0.95)"></div>
|
||||||
v-if="config.defaultEmoji === 'twemoji'"
|
<div v-if="config.defaultEmoji === 'applemoji'" style="font-size: inherit">
|
||||||
v-html="transferEmoji"
|
{{ emoji.char }}
|
||||||
style="font-size: inherit; transform: scale(0.95)"
|
</div>
|
||||||
></div>
|
|
||||||
<div
|
|
||||||
v-if="config.defaultEmoji === 'applemoji'"
|
|
||||||
style="font-size: inherit"
|
|
||||||
>
|
|
||||||
{{ emoji.char }}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import twemoji from 'twemoji'
|
import twemoji from 'twemoji'
|
||||||
import {mapGetters} from "vuex";
|
import { mapGetters } from 'vuex'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Emoji',
|
name: 'Emoji',
|
||||||
props: [
|
props: ['emoji'],
|
||||||
'emoji',
|
data() {
|
||||||
],
|
return {
|
||||||
data() {
|
isApple: false,
|
||||||
return {
|
sizeClass: undefined,
|
||||||
isApple: false,
|
}
|
||||||
sizeClass: undefined,
|
},
|
||||||
}
|
computed: {
|
||||||
},
|
...mapGetters(['config']),
|
||||||
computed: {
|
transferEmoji() {
|
||||||
...mapGetters([
|
return twemoji.parse(this.emoji.char, {
|
||||||
'config',
|
folder: 'svg',
|
||||||
]),
|
ext: '.svg',
|
||||||
transferEmoji() {
|
attributes: () => ({
|
||||||
return twemoji.parse(this.emoji.char, {
|
loading: 'lazy',
|
||||||
folder: 'svg',
|
}),
|
||||||
ext: '.svg',
|
})
|
||||||
attributes: () => ({
|
},
|
||||||
loading: 'lazy'
|
},
|
||||||
})
|
}
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="css">
|
<style lang="css">
|
||||||
.emoji {
|
.emoji {
|
||||||
height: 1em;
|
height: 1em;
|
||||||
width: 1em;
|
width: 1em;
|
||||||
font-size: inherit;
|
font-size: inherit;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,112 +1,114 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<!-- Search field -->
|
<!-- Search field -->
|
||||||
<div class="mb-3 relative flex items-center">
|
<div class="relative mb-3 flex items-center">
|
||||||
|
<!-- Selected emoji preview -->
|
||||||
|
<div v-if="defaultEmoji" class="mr-3 select-none">
|
||||||
|
<Emoji :emoji="defaultEmoji" class="text-5xl" />
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Selected emoji preview -->
|
<!-- Search input -->
|
||||||
<div v-if="defaultEmoji" class="select-none mr-3">
|
<input @click="openList" v-model="query" class="focus-border-theme input-dark" type="text" :placeholder="$t('Select or search emoji icon...')" />
|
||||||
<Emoji :emoji="defaultEmoji" class="text-5xl" />
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Search input -->
|
<!-- Spinner -->
|
||||||
<input @click="openList" v-model="query" class="focus-border-theme input-dark" type="text" :placeholder="$t('Select or search emoji icon...')">
|
<div v-if="isOpen && !isLoaded" class="relative h-20 select-none">
|
||||||
</div>
|
<Spinner />
|
||||||
|
</div>
|
||||||
<!-- Spinner -->
|
|
||||||
<div v-if="isOpen && !isLoaded" class="relative h-20 select-none">
|
|
||||||
<Spinner />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Emojis List -->
|
<!-- Emojis List -->
|
||||||
<div v-if="isOpen && isLoaded && emojis" @scroll="checkGroupInView" id="group-box" class="2xl:h-96 lg:h-60 h-96 overflow-y-auto select-none relative">
|
<div v-if="isOpen && isLoaded && emojis" @scroll="checkGroupInView" id="group-box" class="relative h-96 select-none overflow-y-auto lg:h-60 2xl:h-96">
|
||||||
|
<!-- Navigation of Emojis Groups -->
|
||||||
|
<ul v-if="!query" class="sticky top-0 z-10 flex items-center justify-between space-x-1 bg-white dark:bg-dark-background sm:dark:bg-4x-dark-foreground" id="group-bar">
|
||||||
|
<li
|
||||||
|
@click.stop="scrollToGroup(group.name)"
|
||||||
|
v-for="(group, i) in emojis.groups"
|
||||||
|
:key="i"
|
||||||
|
class="flex h-14 w-14 cursor-pointer items-center justify-center rounded-xl hover:bg-light-background dark:hover:bg-2x-dark-foreground"
|
||||||
|
:class="{
|
||||||
|
'bg-light-background dark:bg-2x-dark-foreground': group.name === groupInView,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<Emoji :emoji="group.emoji" class="text-3xl" />
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<!-- Navigation of Emojis Groups -->
|
<!-- All Emojis -->
|
||||||
<ul v-if="! query" class="flex items-center justify-between space-x-1 sticky top-0 sm:dark:bg-4x-dark-foreground dark:bg-dark-background bg-white z-10" id="group-bar">
|
<div v-if="!query" v-for="(group, name) in allEmoji" :key="name" :id="`group-${name}`">
|
||||||
<li @click.stop="scrollToGroup(group.name)" v-for="(group,i) in emojis.groups" :key="i" class="w-14 h-14 flex items-center justify-center rounded-xl cursor-pointer dark:hover:bg-2x-dark-foreground hover:bg-light-background" :class="{'dark:bg-2x-dark-foreground bg-light-background': group.name === groupInView}">
|
<label class="mt-4 mb-2 block text-sm font-bold">
|
||||||
<Emoji :emoji="group.emoji" class="text-3xl" />
|
{{ name }}
|
||||||
</li>
|
</label>
|
||||||
</ul>
|
<ul class="space-between grid grid-cols-7 gap-4 md:grid-cols-9">
|
||||||
|
<li @click="setEmoji(emoji)" v-for="(emoji, i) in group" :key="i" class="flex cursor-pointer items-center justify-center">
|
||||||
|
<Emoji :emoji="emoji" class="text-4xl" />
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- All Emojis -->
|
<!-- Searched emojis -->
|
||||||
<div v-if="! query" v-for="(group, name) in allEmoji" :key="name" :id="`group-${name}`">
|
<ul v-if="query" class="space-between grid grid-cols-7 gap-4 md:grid-cols-9">
|
||||||
<label class="font-bold text-sm mt-4 mb-2 block">
|
<li @click="setEmoji(emoji)" v-for="(emoji, i) in filteredEmojis" :key="i" class="flex cursor-pointer items-center justify-center">
|
||||||
{{ name }}
|
<Emoji :emoji="emoji" class="text-4xl" />
|
||||||
</label>
|
</li>
|
||||||
<ul class="grid md:grid-cols-9 grid-cols-7 gap-4 space-between">
|
</ul>
|
||||||
<li @click="setEmoji( emoji )" v-for="(emoji,i) in group" :key="i" class="flex items-center justify-center cursor-pointer">
|
|
||||||
<Emoji :emoji="emoji" class="text-4xl" />
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Searched emojis -->
|
<!-- Not found -->
|
||||||
<ul v-if="query" class="grid md:grid-cols-9 grid-cols-7 gap-4 space-between">
|
<span class="ml-2 text-sm font-bold" v-if="filteredEmojis.length === 0 && query !== undefined">
|
||||||
<li @click="setEmoji( emoji )" v-for="(emoji,i) in filteredEmojis" :key="i" class="flex items-center justify-center cursor-pointer">
|
{{ $t('There is nothing :(') }}
|
||||||
<Emoji :emoji="emoji" class="text-4xl" />
|
</span>
|
||||||
</li>
|
</div>
|
||||||
</ul>
|
|
||||||
|
|
||||||
<!-- Not found -->
|
|
||||||
<span class="font-bold text-sm ml-2" v-if="filteredEmojis.length === 0 && query !== undefined">
|
|
||||||
{{ $t('There is nothing :(') }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Spinner from "../FilesView/Spinner";
|
import Spinner from '../FilesView/Spinner'
|
||||||
import Emoji from "./Emoji";
|
import Emoji from './Emoji'
|
||||||
import {debounce, groupBy} from 'lodash'
|
import { debounce, groupBy } from 'lodash'
|
||||||
import {XIcon} from 'vue-feather-icons'
|
import { XIcon } from 'vue-feather-icons'
|
||||||
import {mapGetters} from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'EmojiPicker',
|
name: 'EmojiPicker',
|
||||||
props: [
|
props: ['defaultEmoji'],
|
||||||
'defaultEmoji',
|
|
||||||
],
|
|
||||||
components: {
|
components: {
|
||||||
Spinner,
|
Spinner,
|
||||||
Emoji,
|
Emoji,
|
||||||
XIcon,
|
XIcon,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters([
|
...mapGetters(['emojis']),
|
||||||
'emojis',
|
allEmoji() {
|
||||||
]),
|
return groupBy(this.emojis.list, 'group')
|
||||||
allEmoji() {
|
},
|
||||||
return groupBy(this.emojis.list, 'group')
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
query: undefined,
|
query: undefined,
|
||||||
filteredEmojis: [],
|
filteredEmojis: [],
|
||||||
isOpen: false,
|
isOpen: false,
|
||||||
isLoaded: false,
|
isLoaded: false,
|
||||||
groupInView: 'Smileys & Emotion',
|
groupInView: 'Smileys & Emotion',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
query: debounce(function (val) {
|
query: debounce(function (val) {
|
||||||
// Clear search results
|
// Clear search results
|
||||||
this.filteredEmojis = []
|
this.filteredEmojis = []
|
||||||
|
|
||||||
// Reset query
|
// Reset query
|
||||||
if (val === '' || val === undefined) return
|
if (val === '' || val === undefined) return
|
||||||
|
|
||||||
// Filter emojis by query
|
// Filter emojis by query
|
||||||
this.filteredEmojis = this.emojis.list.filter(emoji => emoji.name.includes(val.toLowerCase()))
|
this.filteredEmojis = this.emojis.list.filter((emoji) => emoji.name.includes(val.toLowerCase()))
|
||||||
|
|
||||||
if (this.filteredEmojis.length === 0) {
|
if (this.filteredEmojis.length === 0) {
|
||||||
console.log('empty');
|
console.log('empty')
|
||||||
}
|
}
|
||||||
}, 200),
|
}, 200),
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
checkGroupInView: _.debounce(function () {
|
checkGroupInView: _.debounce(function () {
|
||||||
this.emojis.groups.forEach(group => {
|
this.emojis.groups.forEach((group) => {
|
||||||
let element = document.getElementById(`group-${group.name}`).getBoundingClientRect()
|
let element = document.getElementById(`group-${group.name}`).getBoundingClientRect()
|
||||||
let groupBox = document.getElementById('group-box').getBoundingClientRect()
|
let groupBox = document.getElementById('group-box').getBoundingClientRect()
|
||||||
|
|
||||||
@@ -117,50 +119,51 @@ export default {
|
|||||||
})
|
})
|
||||||
}, 300),
|
}, 300),
|
||||||
scrollToGroup(name) {
|
scrollToGroup(name) {
|
||||||
let groupBar = document.getElementById('group-bar')
|
let groupBar = document.getElementById('group-bar')
|
||||||
let groupBox = document.getElementById('group-box')
|
let groupBox = document.getElementById('group-box')
|
||||||
let group = document.getElementById(`group-${name}`)
|
let group = document.getElementById(`group-${name}`)
|
||||||
|
|
||||||
groupBox.scrollTo({
|
groupBox.scrollTo({
|
||||||
top: group.offsetTop - groupBar.clientHeight - 5,
|
top: group.offsetTop - groupBar.clientHeight - 5,
|
||||||
left: 0,
|
left: 0,
|
||||||
behavior: 'smooth'
|
behavior: 'smooth',
|
||||||
});
|
})
|
||||||
|
|
||||||
this.groupInView = name
|
this.groupInView = name
|
||||||
},
|
},
|
||||||
openList() {
|
openList() {
|
||||||
// Open list if it's not opened
|
// Open list if it's not opened
|
||||||
if (! this.isOpen) this.isOpen = true
|
if (!this.isOpen) this.isOpen = true
|
||||||
|
|
||||||
// Load emojis from server just if not loaded already
|
// Load emojis from server just if not loaded already
|
||||||
if (this.isOpen && !this.emojis) {
|
if (this.isOpen && !this.emojis) {
|
||||||
axios.get('/assets/emojis.json')
|
axios
|
||||||
.then(response => {
|
.get('/assets/emojis.json')
|
||||||
|
.then((response) => {
|
||||||
this.$store.commit('LOAD_EMOJIS_LIST', response.data)
|
this.$store.commit('LOAD_EMOJIS_LIST', response.data)
|
||||||
})
|
})
|
||||||
.finally(() => this.isLoaded = true)
|
.finally(() => (this.isLoaded = true))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Simulate loading for the list processing
|
// Simulate loading for the list processing
|
||||||
if (this.emojis) {
|
if (this.emojis) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.isLoaded = true
|
this.isLoaded = true
|
||||||
}, 20);
|
}, 20)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.groupInView = 'Smileys & Emotion'
|
this.groupInView = 'Smileys & Emotion'
|
||||||
},
|
},
|
||||||
setEmoji(value) {
|
setEmoji(value) {
|
||||||
this.query = undefined
|
this.query = undefined
|
||||||
this.isOpen = false
|
this.isOpen = false
|
||||||
|
|
||||||
this.$emit('input', value)
|
this.$emit('input', value)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
// Open list of there isn't set any emoji
|
// Open list of there isn't set any emoji
|
||||||
if (! this.defaultEmoji) this.openList()
|
if (!this.defaultEmoji) this.openList()
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -16,59 +16,62 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { FileIcon, FileTextIcon, SettingsIcon } from 'vue-feather-icons'
|
import { FileIcon, FileTextIcon, SettingsIcon } from 'vue-feather-icons'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'EmptyPageContent',
|
name: 'EmptyPageContent',
|
||||||
props: ['icon','title','description'],
|
props: ['icon', 'title', 'description'],
|
||||||
components: {
|
components: {
|
||||||
SettingsIcon,
|
SettingsIcon,
|
||||||
FileTextIcon,
|
FileTextIcon,
|
||||||
FileIcon,
|
FileIcon,
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import '../../../sass/vuefilemanager/variables';
|
@import '../../../sass/vuefilemanager/variables';
|
||||||
@import '../../../sass/vuefilemanager/mixins';
|
@import '../../../sass/vuefilemanager/mixins';
|
||||||
|
|
||||||
.empty-page-content {
|
.empty-page-content {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
|
margin: 0 auto;
|
||||||
|
max-width: 360px;
|
||||||
|
|
||||||
|
/deep/ .button-base {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
max-width: 360px;
|
|
||||||
|
|
||||||
/deep/ .button-base {
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
path, polyline, line, circle {
|
|
||||||
stroke: $theme;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.header {
|
|
||||||
margin-top: 15px;
|
|
||||||
margin-bottom: 25px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
@include font-size(23);
|
|
||||||
font-weight: 700;
|
|
||||||
padding-bottom: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.description {
|
|
||||||
@include font-size(16);
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
path,
|
||||||
|
polyline,
|
||||||
|
line,
|
||||||
|
circle {
|
||||||
|
stroke: $theme;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
margin-top: 15px;
|
||||||
|
margin-bottom: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
@include font-size(23);
|
||||||
|
font-weight: 700;
|
||||||
|
padding-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
@include font-size(16);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,56 +1,37 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="canBePreview" class="w-full block mb-4">
|
<div v-if="canBePreview" class="mb-4 block w-full">
|
||||||
|
<!--Image-->
|
||||||
|
<img
|
||||||
|
v-if="singleFile.data.type === 'image' && singleFile.data.attributes.thumbnail"
|
||||||
|
:src="singleFile.data.attributes.thumbnail.md"
|
||||||
|
:alt="singleFile.data.attributes.name"
|
||||||
|
class="w-full overflow-hidden rounded-lg object-cover shadow-lg"
|
||||||
|
/>
|
||||||
|
|
||||||
<!--Image-->
|
<!--Audio-->
|
||||||
<img
|
<audio v-else-if="singleFile.data.type === 'audio'" :src="singleFile.data.attributes.file_url" controlsList="nodownload" controls class="w-full"></audio>
|
||||||
v-if="singleFile.data.type === 'image' && singleFile.data.attributes.thumbnail"
|
|
||||||
:src="singleFile.data.attributes.thumbnail.md"
|
|
||||||
:alt="singleFile.data.attributes.name"
|
|
||||||
class="rounded-lg overflow-hidden w-full object-cover shadow-lg"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!--Audio-->
|
<!--Video-->
|
||||||
<audio
|
<video class="h-auto w-full overflow-hidden rounded-sm" v-else-if="singleFile.data.type === 'video'" controlsList="nodownload" disablePictureInPicture playsinline controls>
|
||||||
v-else-if="singleFile.data.type === 'audio'"
|
<source :src="singleFile.data.attributes.file_url" type="video/mp4" />
|
||||||
:src="singleFile.data.attributes.file_url"
|
|
||||||
controlsList="nodownload"
|
|
||||||
controls
|
|
||||||
class="w-full"
|
|
||||||
>
|
|
||||||
</audio>
|
|
||||||
|
|
||||||
<!--Video-->
|
|
||||||
<video
|
|
||||||
class="w-full h-auto rounded-sm overflow-hidden"
|
|
||||||
v-else-if="singleFile.data.type === 'video'"
|
|
||||||
controlsList="nodownload"
|
|
||||||
disablePictureInPicture
|
|
||||||
playsinline
|
|
||||||
controls
|
|
||||||
>
|
|
||||||
<source :src="singleFile.data.attributes.file_url" type="video/mp4">
|
|
||||||
</video>
|
</video>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {mapGetters} from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
import {includes} from 'lodash'
|
import { includes } from 'lodash'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'FilePreview',
|
name: 'FilePreview',
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters([
|
...mapGetters(['clipboard']),
|
||||||
'clipboard',
|
singleFile() {
|
||||||
]),
|
return this.clipboard[0]
|
||||||
singleFile() {
|
},
|
||||||
return this.clipboard[0]
|
canBePreview() {
|
||||||
},
|
return this.singleFile && !includes(['folder', 'file'], this.singleFile.data.type)
|
||||||
canBePreview() {
|
},
|
||||||
return this.singleFile && !includes([
|
},
|
||||||
'folder', 'file'
|
}
|
||||||
], this.singleFile.data.type)
|
</script>
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|||||||
@@ -1,62 +1,47 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="relative cursor-pointer">
|
<div class="relative cursor-pointer">
|
||||||
<input
|
<input ref="file" type="file" @change="showImagePreview($event)" class="absolute top-0 bottom-0 left-0 right-0 z-10 w-full cursor-pointer opacity-0" />
|
||||||
ref="file"
|
<img v-if="imagePreview" ref="image" :src="imagePreview" class="relative z-0 h-14 w-14 cursor-pointer rounded-xl object-cover shadow-lg md:h-16 md:w-16" alt="avatar" />
|
||||||
type="file"
|
|
||||||
@change="showImagePreview($event)"
|
|
||||||
class="absolute opacity-0 top-0 bottom-0 left-0 right-0 w-full z-10 cursor-pointer"
|
|
||||||
/>
|
|
||||||
<img
|
|
||||||
v-if="imagePreview"
|
|
||||||
ref="image"
|
|
||||||
:src="imagePreview"
|
|
||||||
class="md:w-16 w-14 md:h-16 h-14 object-cover rounded-xl relative z-0 shadow-lg cursor-pointer"
|
|
||||||
alt="avatar"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'AvatarInput',
|
name: 'AvatarInput',
|
||||||
props: [
|
props: ['avatar'],
|
||||||
'avatar',
|
data() {
|
||||||
],
|
return {
|
||||||
data() {
|
imagePreview: undefined,
|
||||||
return {
|
}
|
||||||
imagePreview: undefined
|
},
|
||||||
}
|
watch: {
|
||||||
},
|
imagePreview(val) {
|
||||||
watch: {
|
this.$store.commit('UPDATE_AVATAR', val)
|
||||||
imagePreview(val) {
|
},
|
||||||
this.$store.commit('UPDATE_AVATAR', val)
|
},
|
||||||
}
|
methods: {
|
||||||
},
|
showImagePreview(event) {
|
||||||
methods: {
|
let imgPath = event.target.files[0].name,
|
||||||
showImagePreview(event) {
|
extension = imgPath.substring(imgPath.lastIndexOf('.') + 1).toLowerCase()
|
||||||
let imgPath = event.target.files[0].name,
|
|
||||||
extension = imgPath
|
|
||||||
.substring(imgPath.lastIndexOf('.') + 1)
|
|
||||||
.toLowerCase()
|
|
||||||
|
|
||||||
if (['png', 'jpg', 'jpeg'].includes(extension)) {
|
if (['png', 'jpg', 'jpeg'].includes(extension)) {
|
||||||
let file = event.target.files[0],
|
let file = event.target.files[0],
|
||||||
reader = new FileReader()
|
reader = new FileReader()
|
||||||
|
|
||||||
reader.onload = () => (this.imagePreview = reader.result)
|
reader.onload = () => (this.imagePreview = reader.result)
|
||||||
|
|
||||||
reader.readAsDataURL(file)
|
reader.readAsDataURL(file)
|
||||||
|
|
||||||
// Update user avatar
|
// Update user avatar
|
||||||
this.$updateImage('/user/settings', 'avatar', event.target.files[0])
|
this.$updateImage('/user/settings', 'avatar', event.target.files[0])
|
||||||
} else {
|
} else {
|
||||||
alert(this.$t('validation_errors.wrong_image'))
|
alert(this.$t('validation_errors.wrong_image'))
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
// If there is default image then load
|
// If there is default image then load
|
||||||
if (this.avatar) this.imagePreview = this.avatar
|
if (this.avatar) this.imagePreview = this.avatar
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,28 +1,21 @@
|
|||||||
<template>
|
<template>
|
||||||
<div @click="copyUrl" class="flex items-center relative">
|
<div @click="copyUrl" class="relative flex items-center">
|
||||||
<input ref="sel" :value="str" :id="id" type="text" class="pr-10 focus-border-theme input-dark" readonly>
|
<input ref="sel" :value="str" :id="id" type="text" class="focus-border-theme input-dark pr-10" readonly />
|
||||||
|
|
||||||
<!--Copy icon-->
|
<!--Copy icon-->
|
||||||
<div class="absolute right-0 px-4">
|
<div class="absolute right-0 px-4">
|
||||||
<copy-icon v-if="! isCopiedLink" size="16" class="cursor-pointer hover-text-theme vue-feather"/>
|
<copy-icon v-if="!isCopiedLink" size="16" class="hover-text-theme vue-feather cursor-pointer" />
|
||||||
<check-icon v-if="isCopiedLink" size="16" class="cursor-pointer text-theme vue-feather"/>
|
<check-icon v-if="isCopiedLink" size="16" class="text-theme vue-feather cursor-pointer" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {
|
import { CopyIcon, CheckIcon, SendIcon } from 'vue-feather-icons'
|
||||||
CopyIcon,
|
|
||||||
CheckIcon,
|
|
||||||
SendIcon
|
|
||||||
} from 'vue-feather-icons'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'CopyInput',
|
name: 'CopyInput',
|
||||||
props: [
|
props: ['size', 'str'],
|
||||||
'size',
|
|
||||||
'str',
|
|
||||||
],
|
|
||||||
components: {
|
components: {
|
||||||
CheckIcon,
|
CheckIcon,
|
||||||
CopyIcon,
|
CopyIcon,
|
||||||
@@ -31,12 +24,11 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isCopiedLink: false,
|
isCopiedLink: false,
|
||||||
id: 'link-input-' + Math.floor(Math.random() * 10000000),
|
id: 'link-input-' + Math.floor(Math.random() * 10000000),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
copyUrl() {
|
copyUrl() {
|
||||||
|
|
||||||
// Get input value
|
// Get input value
|
||||||
let copyText = document.getElementById(this.id)
|
let copyText = document.getElementById(this.id)
|
||||||
|
|
||||||
@@ -54,7 +46,7 @@ export default {
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.isCopiedLink = false
|
this.isCopiedLink = false
|
||||||
}, 1000)
|
}, 1000)
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user