Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
E
evm-store
Project overview
Project overview
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wanli
evm-store
Commits
bae8cfdf
Commit
bae8cfdf
authored
Jun 18, 2021
by
wanli
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update
parent
32f1fd2c
Changes
102
Hide whitespace changes
Inline
Side-by-side
Showing
102 changed files
with
13291 additions
and
2569 deletions
+13291
-2569
tools/frontend/package-lock.json
tools/frontend/package-lock.json
+2484
-2379
tools/frontend/package.json
tools/frontend/package.json
+7
-2
tools/frontend/public/favicon.ico
tools/frontend/public/favicon.ico
+0
-0
tools/frontend/src/assets/app-store.svg
tools/frontend/src/assets/app-store.svg
+16
-0
tools/frontend/src/assets/evue-logo.png
tools/frontend/src/assets/evue-logo.png
+0
-0
tools/frontend/src/assets/laravel-file-manager.gif
tools/frontend/src/assets/laravel-file-manager.gif
+0
-0
tools/frontend/src/assets/logo.png
tools/frontend/src/assets/logo.png
+0
-0
tools/frontend/src/components/GlobalHeader/RightContent.vue
tools/frontend/src/components/GlobalHeader/RightContent.vue
+13
-23
tools/frontend/src/components/GlobalHeader/index.js
tools/frontend/src/components/GlobalHeader/index.js
+1
-0
tools/frontend/src/components/NumberInfo/NumberInfo.vue
tools/frontend/src/components/NumberInfo/NumberInfo.vue
+22
-22
tools/frontend/src/components/SiderMenu/BaseMenu.vue
tools/frontend/src/components/SiderMenu/BaseMenu.vue
+23
-28
tools/frontend/src/components/SiderMenu/index.less
tools/frontend/src/components/SiderMenu/index.less
+50
-47
tools/frontend/src/components/TopNavHeader/index.js
tools/frontend/src/components/TopNavHeader/index.js
+2
-2
tools/frontend/src/defaultSettings.js
tools/frontend/src/defaultSettings.js
+2
-1
tools/frontend/src/layouts/BasicLayout.js
tools/frontend/src/layouts/BasicLayout.js
+1
-1
tools/frontend/src/layouts/Footer.js
tools/frontend/src/layouts/Footer.js
+9
-9
tools/frontend/src/layouts/UserLayout.js
tools/frontend/src/layouts/UserLayout.js
+11
-3
tools/frontend/src/locales/lang/ar.js
tools/frontend/src/locales/lang/ar.js
+190
-0
tools/frontend/src/locales/lang/cs.js
tools/frontend/src/locales/lang/cs.js
+191
-0
tools/frontend/src/locales/lang/de.js
tools/frontend/src/locales/lang/de.js
+190
-0
tools/frontend/src/locales/lang/en.js
tools/frontend/src/locales/lang/en.js
+190
-0
tools/frontend/src/locales/lang/es.js
tools/frontend/src/locales/lang/es.js
+192
-0
tools/frontend/src/locales/lang/fa.js
tools/frontend/src/locales/lang/fa.js
+191
-0
tools/frontend/src/locales/lang/fr.js
tools/frontend/src/locales/lang/fr.js
+190
-0
tools/frontend/src/locales/lang/it.js
tools/frontend/src/locales/lang/it.js
+191
-0
tools/frontend/src/locales/lang/nl.js
tools/frontend/src/locales/lang/nl.js
+193
-0
tools/frontend/src/locales/lang/pl.js
tools/frontend/src/locales/lang/pl.js
+190
-0
tools/frontend/src/locales/lang/pt_BR.js
tools/frontend/src/locales/lang/pt_BR.js
+191
-0
tools/frontend/src/locales/lang/ru.js
tools/frontend/src/locales/lang/ru.js
+190
-0
tools/frontend/src/locales/lang/sr.js
tools/frontend/src/locales/lang/sr.js
+191
-0
tools/frontend/src/locales/lang/tr.js
tools/frontend/src/locales/lang/tr.js
+190
-0
tools/frontend/src/locales/lang/zh_CN.js
tools/frontend/src/locales/lang/zh_CN.js
+193
-0
tools/frontend/src/locales/lang/zh_TW.js
tools/frontend/src/locales/lang/zh_TW.js
+191
-0
tools/frontend/src/store/file-manager.js
tools/frontend/src/store/file-manager.js
+27
-0
tools/frontend/src/store/file-manager/actions.js
tools/frontend/src/store/file-manager/actions.js
+600
-0
tools/frontend/src/store/file-manager/getters.js
tools/frontend/src/store/file-manager/getters.js
+47
-0
tools/frontend/src/store/file-manager/manager/actions.js
tools/frontend/src/store/file-manager/manager/actions.js
+128
-0
tools/frontend/src/store/file-manager/manager/getters.js
tools/frontend/src/store/file-manager/manager/getters.js
+126
-0
tools/frontend/src/store/file-manager/manager/mutations.js
tools/frontend/src/store/file-manager/manager/mutations.js
+232
-0
tools/frontend/src/store/file-manager/manager/store.js
tools/frontend/src/store/file-manager/manager/store.js
+46
-0
tools/frontend/src/store/file-manager/messages/mutations.js
tools/frontend/src/store/file-manager/messages/mutations.js
+80
-0
tools/frontend/src/store/file-manager/messages/store.js
tools/frontend/src/store/file-manager/messages/store.js
+24
-0
tools/frontend/src/store/file-manager/modal/mutations.js
tools/frontend/src/store/file-manager/modal/mutations.js
+30
-0
tools/frontend/src/store/file-manager/modal/store.js
tools/frontend/src/store/file-manager/modal/store.js
+18
-0
tools/frontend/src/store/file-manager/mutations.js
tools/frontend/src/store/file-manager/mutations.js
+95
-0
tools/frontend/src/store/file-manager/settings/getters.js
tools/frontend/src/store/file-manager/settings/getters.js
+28
-0
tools/frontend/src/store/file-manager/settings/mutations.js
tools/frontend/src/store/file-manager/settings/mutations.js
+104
-0
tools/frontend/src/store/file-manager/settings/store.js
tools/frontend/src/store/file-manager/settings/store.js
+198
-0
tools/frontend/src/store/file-manager/state.js
tools/frontend/src/store/file-manager/state.js
+28
-0
tools/frontend/src/store/file-manager/tree/actions.js
tools/frontend/src/store/file-manager/tree/actions.js
+260
-0
tools/frontend/src/store/file-manager/tree/getters.js
tools/frontend/src/store/file-manager/tree/getters.js
+23
-0
tools/frontend/src/store/file-manager/tree/mutations.js
tools/frontend/src/store/file-manager/tree/mutations.js
+71
-0
tools/frontend/src/store/file-manager/tree/store.js
tools/frontend/src/store/file-manager/tree/store.js
+32
-0
tools/frontend/src/store/index.js
tools/frontend/src/store/index.js
+3
-1
tools/frontend/src/store/modules/frontend-openapi.js
tools/frontend/src/store/modules/frontend-openapi.js
+0
-1
tools/frontend/src/utils/get.js
tools/frontend/src/utils/get.js
+120
-0
tools/frontend/src/utils/helper.js
tools/frontend/src/utils/helper.js
+219
-0
tools/frontend/src/utils/post.js
tools/frontend/src/utils/post.js
+88
-0
tools/frontend/src/utils/translate.js
tools/frontend/src/utils/translate.js
+21
-0
tools/frontend/src/views/FileManager/FileManager.vue
tools/frontend/src/views/FileManager/FileManager.vue
+331
-0
tools/frontend/src/views/FileManager/components/blocks/ContextMenu.vue
...d/src/views/FileManager/components/blocks/ContextMenu.vue
+185
-0
tools/frontend/src/views/FileManager/components/blocks/InfoBlock.vue
...end/src/views/FileManager/components/blocks/InfoBlock.vue
+165
-0
tools/frontend/src/views/FileManager/components/blocks/Navbar.vue
...ontend/src/views/FileManager/components/blocks/Navbar.vue
+314
-0
tools/frontend/src/views/FileManager/components/blocks/Notification.vue
.../src/views/FileManager/components/blocks/Notification.vue
+77
-0
tools/frontend/src/views/FileManager/components/blocks/mixins/contextMenu.js
...views/FileManager/components/blocks/mixins/contextMenu.js
+105
-0
tools/frontend/src/views/FileManager/components/blocks/mixins/contextMenuActions.js
...ileManager/components/blocks/mixins/contextMenuActions.js
+182
-0
tools/frontend/src/views/FileManager/components/blocks/mixins/contextMenuRules.js
.../FileManager/components/blocks/mixins/contextMenuRules.js
+136
-0
tools/frontend/src/views/FileManager/components/manager/Breadcrumb.vue
...d/src/views/FileManager/components/manager/Breadcrumb.vue
+108
-0
tools/frontend/src/views/FileManager/components/manager/DiskList.vue
...end/src/views/FileManager/components/manager/DiskList.vue
+67
-0
tools/frontend/src/views/FileManager/components/manager/GridView.vue
...end/src/views/FileManager/components/manager/GridView.vue
+143
-0
tools/frontend/src/views/FileManager/components/manager/Manager.vue
...tend/src/views/FileManager/components/manager/Manager.vue
+51
-0
tools/frontend/src/views/FileManager/components/manager/TableView.vue
...nd/src/views/FileManager/components/manager/TableView.vue
+169
-0
tools/frontend/src/views/FileManager/components/manager/Thumbnail.vue
...nd/src/views/FileManager/components/manager/Thumbnail.vue
+110
-0
tools/frontend/src/views/FileManager/components/manager/mixins/manager.js
...rc/views/FileManager/components/manager/mixins/manager.js
+207
-0
tools/frontend/src/views/FileManager/components/modals/Modal.vue
...rontend/src/views/FileManager/components/modals/Modal.vue
+113
-0
tools/frontend/src/views/FileManager/components/modals/additions/Cropper.vue
...views/FileManager/components/modals/additions/Cropper.vue
+385
-0
tools/frontend/src/views/FileManager/components/modals/additions/SelectedFileList.vue
...eManager/components/modals/additions/SelectedFileList.vue
+48
-0
tools/frontend/src/views/FileManager/components/modals/mixins/modal.js
...d/src/views/FileManager/components/modals/mixins/modal.js
+33
-0
tools/frontend/src/views/FileManager/components/modals/views/About.vue
...d/src/views/FileManager/components/modals/views/About.vue
+51
-0
tools/frontend/src/views/FileManager/components/modals/views/AudioPlayer.vue
...views/FileManager/components/modals/views/AudioPlayer.vue
+170
-0
tools/frontend/src/views/FileManager/components/modals/views/Clipboard.vue
...c/views/FileManager/components/modals/views/Clipboard.vue
+142
-0
tools/frontend/src/views/FileManager/components/modals/views/Delete.vue
.../src/views/FileManager/components/modals/views/Delete.vue
+61
-0
tools/frontend/src/views/FileManager/components/modals/views/NewFile.vue
...src/views/FileManager/components/modals/views/NewFile.vue
+83
-0
tools/frontend/src/views/FileManager/components/modals/views/NewFolder.vue
...c/views/FileManager/components/modals/views/NewFolder.vue
+83
-0
tools/frontend/src/views/FileManager/components/modals/views/Preview.vue
...src/views/FileManager/components/modals/views/Preview.vue
+162
-0
tools/frontend/src/views/FileManager/components/modals/views/Properties.vue
.../views/FileManager/components/modals/views/Properties.vue
+189
-0
tools/frontend/src/views/FileManager/components/modals/views/Rename.vue
.../src/views/FileManager/components/modals/views/Rename.vue
+114
-0
tools/frontend/src/views/FileManager/components/modals/views/Status.vue
.../src/views/FileManager/components/modals/views/Status.vue
+55
-0
tools/frontend/src/views/FileManager/components/modals/views/TextEdit.vue
...rc/views/FileManager/components/modals/views/TextEdit.vue
+147
-0
tools/frontend/src/views/FileManager/components/modals/views/Unzip.vue
...d/src/views/FileManager/components/modals/views/Unzip.vue
+117
-0
tools/frontend/src/views/FileManager/components/modals/views/Upload.vue
.../src/views/FileManager/components/modals/views/Upload.vue
+216
-0
tools/frontend/src/views/FileManager/components/modals/views/VideoPlayer.vue
...views/FileManager/components/modals/views/VideoPlayer.vue
+72
-0
tools/frontend/src/views/FileManager/components/modals/views/Zip.vue
...end/src/views/FileManager/components/modals/views/Zip.vue
+87
-0
tools/frontend/src/views/FileManager/components/tree/Branch.vue
...frontend/src/views/FileManager/components/tree/Branch.vue
+129
-0
tools/frontend/src/views/FileManager/components/tree/FolderTree.vue
...tend/src/views/FileManager/components/tree/FolderTree.vue
+50
-0
tools/frontend/src/views/FileManager/init.js
tools/frontend/src/views/FileManager/init.js
+16
-0
tools/frontend/src/views/System/Role.vue
tools/frontend/src/views/System/Role.vue
+1
-1
tools/frontend/src/views/User/Login.vue
tools/frontend/src/views/User/Login.vue
+3
-6
tools/frontend/src/views/User/Register.vue
tools/frontend/src/views/User/Register.vue
+0
-5
tools/frontend/src/views/User/login.less
tools/frontend/src/views/User/login.less
+8
-0
tools/frontend/src/views/User/register.less
tools/frontend/src/views/User/register.less
+4
-1
tools/frontend/vue.config.js
tools/frontend/vue.config.js
+59
-37
No files found.
tools/frontend/package-lock.json
View file @
bae8cfdf
This source diff could not be displayed because it is too large. You can
view the blob
instead.
tools/frontend/package.json
View file @
bae8cfdf
...
@@ -9,13 +9,18 @@
...
@@ -9,13 +9,18 @@
},
},
"dependencies"
:
{
"dependencies"
:
{
"@antv/g2"
:
"^3.2.7"
,
"@antv/g2"
:
"^3.2.7"
,
"ant-design-vue"
:
"^1.
1.2
"
,
"ant-design-vue"
:
"^1.
7.5
"
,
"axios"
:
"^0.18.0"
,
"axios"
:
"^0.18.0"
,
"codemirror"
:
"^5.59.2"
,
"core-js"
:
"^3.9.0"
,
"cropperjs"
:
"^1.5.11"
,
"plyr"
:
"^3.6.4"
,
"numeral"
:
"^2.0.6"
,
"numeral"
:
"^2.0.6"
,
"vue"
:
"^2.5.17"
,
"vue"
:
"^2.5.17"
,
"vue-i18n"
:
"^8.1.0"
,
"vue-i18n"
:
"^8.1.0"
,
"vue-router"
:
"^3.0.1"
,
"vue-router"
:
"^3.0.1"
,
"vuex"
:
"^3.0.1"
,
"vuex"
:
"^3.0.1"
,
"vue-codemirror"
:
"^4.0.6"
,
"vuex-router-sync"
:
"^5.0.0"
"vuex-router-sync"
:
"^5.0.0"
},
},
"devDependencies"
:
{
"devDependencies"
:
{
...
@@ -26,7 +31,7 @@
...
@@ -26,7 +31,7 @@
"less"
:
"^3.8.1"
,
"less"
:
"^3.8.1"
,
"less-loader"
:
"^4.1.0"
,
"less-loader"
:
"^4.1.0"
,
"svg-sprite-loader"
:
"^3.9.2"
,
"svg-sprite-loader"
:
"^3.9.2"
,
"vue-template-compiler"
:
"^2.
5.17
"
"vue-template-compiler"
:
"^2.
6.12
"
},
},
"eslintConfig"
:
{
"eslintConfig"
:
{
"root"
:
true
,
"root"
:
true
,
...
...
tools/frontend/public/favicon.ico
View replaced file @
32f1fd2c
View file @
bae8cfdf
1.12 KB
|
W:
|
H:
16.6 KB
|
W:
|
H:
2-up
Swipe
Onion skin
tools/frontend/src/assets/app-store.svg
0 → 100644
View file @
bae8cfdf
<svg
width=
"642"
height=
"642"
xmlns=
"http://www.w3.org/2000/svg"
class=
"icon"
>
<defs>
<style
type=
"text/css"
/>
</defs>
<g>
<title>
background
</title>
<rect
x=
"-1"
y=
"-1"
width=
"644"
height=
"644"
id=
"canvas_background"
fill=
"none"
/>
</g>
<g>
<title>
Layer 1
</title>
<path
d=
"m546.6176,641.32967l-451.23517,0c-52.32527,0 -95.08571,-42.76044 -95.08571,-95.08571l0,-451.23517c0,-52.32527 42.76044,-95.08571 95.08571,-95.08571l451.23517,0c52.32527,0 95.08571,42.76044 95.08571,95.08571l0,451.23517c0,52.32527 -42.76044,95.08571 -95.08571,95.08571z"
fill=
"#2ecccd"
id=
"svg_1"
/>
<path
d=
"m321.46431,263.67473c-131.65714,0 -238.55824,-87.2088 -243.05934,-195.79781c0,-3.93846 -3.37582,-7.31428 -7.31429,-7.31428c-3.93846,0 -7.87692,3.37582 -7.31428,7.87692c5.06373,115.34066 118.71648,208.17582 258.25055,208.17583s253.18681,-92.27253 258.25055,-208.17583c0,-3.93846 -3.37583,-7.87692 -7.31429,-7.87692c-3.93846,0 -7.31428,3.37582 -7.31428,7.31428c-5.62638,108.58901 -112.52748,195.79781 -244.18462,195.79781z"
fill=
"#FCFCFC"
id=
"svg_2"
/>
<path
d=
"m322,324.43956m-14.06593,0a14.06593,14.06593 0 1 0 28.13186,0a14.06593,14.06593 0 1 0 -28.13186,0z"
fill=
"#FCFCFC"
id=
"svg_3"
/>
<text
fill=
"#ffffff"
stroke-width=
"0"
x=
"183.3125"
y=
"488.8"
id=
"svg_4"
font-size=
"128"
font-family=
"Helvetica, Arial, sans-serif"
text-anchor=
"start"
xml:space=
"preserve"
>
EVM
</text>
</g>
</svg>
\ No newline at end of file
tools/frontend/src/assets/evue-logo.png
0 → 100644
View file @
bae8cfdf
4.56 KB
tools/frontend/src/assets/laravel-file-manager.gif
0 → 100644
View file @
bae8cfdf
841 KB
tools/frontend/src/assets/logo.png
View replaced file @
32f1fd2c
View file @
bae8cfdf
6.69 KB
|
W:
|
H:
5.2 KB
|
W:
|
H:
2-up
Swipe
Onion skin
tools/frontend/src/components/GlobalHeader/RightContent.vue
View file @
bae8cfdf
...
@@ -5,18 +5,6 @@
...
@@ -5,18 +5,6 @@
<a-icon
type=
"question-circle-o"
/>
<a-icon
type=
"question-circle-o"
/>
</a>
</a>
</a-tooltip>
</a-tooltip>
<a-tooltip
title=
"Code"
placement=
"bottom"
>
-->
<a
target=
"_blank"
href=
"https://github.com/ruyangit/seed-workbench-ui.git"
class=
"action"
>
<span
class=
"action"
>
<a-icon
type=
"codepen"
theme=
"outlined"
/>
</span>
</a>
</a-tooltip>
<a-dropdown
placement=
"bottomRight"
>
<a-dropdown
placement=
"bottomRight"
>
<span
class=
"action"
>
<span
class=
"action"
>
<a-icon
type=
"codepen"
theme=
"outlined"
/>
<a-icon
type=
"codepen"
theme=
"outlined"
/>
...
@@ -24,16 +12,16 @@
...
@@ -24,16 +12,16 @@
<a-menu
slot=
"overlay"
@
click=
"handleMenuClick"
>
<a-menu
slot=
"overlay"
@
click=
"handleMenuClick"
>
<a-menu-item
key=
"gitee"
>
<a-menu-item
key=
"gitee"
>
<
!--
<a
target=
"_blank"
href=
"https://github.com/ruyangit/seed-workbench-ui.git"
>
--
>
<
a
target=
"_blank"
href=
"https://gitee.com/scriptiot/evm"
>
<a-icon
type=
"slack-square"
theme=
"outlined"
/>
<a-icon
type=
"slack-square"
theme=
"outlined"
/>
Gitee
(开源中国)
Gitee
<
!--
</a>
--
>
<
/a
>
</a-menu-item>
</a-menu-item>
<a-menu-item
key=
"github"
>
<a-menu-item
key=
"github"
>
<
!--
<a
target=
"_blank"
href=
"https://github.com/ruyangit/seed-workbench-ui.git"
>
--
>
<
a
target=
"_blank"
href=
"https://github.com/scriptiot/evm"
>
<a-icon
type=
"github"
/>
<a-icon
type=
"github"
/>
Github
(同性交友)
Github
<
!--
</a>
--
>
<
/a
>
</a-menu-item>
</a-menu-item>
</a-menu>
</a-menu>
</a-dropdown>
</a-dropdown>
...
@@ -124,7 +112,7 @@
...
@@ -124,7 +112,7 @@
src=
"https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png"
src=
"https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png"
alt=
"avatar"
alt=
"avatar"
/>
/>
<span
class=
"name"
>
Ryan Ru
</span>
<span
class=
"name"
>
EVM
</span>
</span>
</span>
<a-menu
slot=
"overlay"
class=
"menu"
>
<a-menu
slot=
"overlay"
class=
"menu"
>
...
@@ -142,7 +130,7 @@
...
@@ -142,7 +130,7 @@
</a-menu-item>
</a-menu-item>
<a-menu-divider
/>
<a-menu-divider
/>
<a-menu-item
key=
"logout"
>
<a-menu-item
key=
"logout"
@
click=
"logout"
>
<a-icon
type=
"logout"
/>
<a-icon
type=
"logout"
/>
退出登录
退出登录
</a-menu-item>
</a-menu-item>
...
@@ -192,7 +180,6 @@ export default {
...
@@ -192,7 +180,6 @@ export default {
AAvatar
:
Avatar
,
AAvatar
:
Avatar
,
ANoticeIcon
:
NoticeIcon
,
ANoticeIcon
:
NoticeIcon
,
ANoticeIconTab
:
NoticeIcon
.
Tab
,
ANoticeIconTab
:
NoticeIcon
.
Tab
,
ADivider
:
Divider
,
ADivider
:
Divider
,
ASettingDrawer
:
SettingDrawer
,
ASettingDrawer
:
SettingDrawer
,
},
},
...
@@ -204,16 +191,19 @@ export default {
...
@@ -204,16 +191,19 @@ export default {
handleMenuClick
(
e
)
{
handleMenuClick
(
e
)
{
if
(
e
.
key
===
"
gitee
"
)
{
if
(
e
.
key
===
"
gitee
"
)
{
window
.
open
(
window
.
open
(
"
https://gitee.com/
ruyangit/seed-workbench-ui.git
"
,
"
https://gitee.com/
scriptiot/evm
"
,
"
_blank
"
"
_blank
"
);
);
}
else
{
}
else
{
window
.
open
(
window
.
open
(
"
https://git
hub.com/ruyangit/seed-workbench-ui.git
"
,
"
https://git
ee.com/scriptiot/evm
"
,
"
_blank
"
"
_blank
"
);
);
}
}
},
},
logout
()
{
this
.
$router
.
push
({
path
:
"
/user/login
"
});
},
success
()
{
success
()
{
Modal
.
success
({
Modal
.
success
({
title
:
"
友好的一个提示
"
,
title
:
"
友好的一个提示
"
,
...
...
tools/frontend/src/components/GlobalHeader/index.js
View file @
bae8cfdf
...
@@ -17,6 +17,7 @@ const GlobalHeader = {
...
@@ -17,6 +17,7 @@ const GlobalHeader = {
},
},
render
()
{
render
()
{
const
{
spinning
,
collapsed
,
onCollapsed
,
theme
,
layout
}
=
this
const
{
spinning
,
collapsed
,
onCollapsed
,
theme
,
layout
}
=
this
return
(
return
(
<
div
class
=
"
header-index
"
>
<
div
class
=
"
header-index
"
>
<
Icon
<
Icon
...
...
tools/frontend/src/components/NumberInfo/NumberInfo.vue
View file @
bae8cfdf
<
template
>
<
template
>
<div
:class=
"cls"
>
<div
:class=
"cls"
>
<div
v-if=
"title"
class=
"numberInfoTitle"
>
<div
v-if=
"title"
class=
"numberInfoTitle"
>
{{
title
}}
{{
title
}}
</div>
</div>
<div
v-if=
"subTitle"
class=
"numberInfoSubTitle"
>
<div
v-if=
"subTitle"
class=
"numberInfoSubTitle"
>
{{
subTitle
}}
{{
subTitle
}}
</div>
</div>
<div
class=
"numberInfoValue"
:style=
"
{'margin-top:gap':gap
}">
<div
class=
"numberInfoValue"
:style=
"
{ 'margin-top:gap': gap
}">
<span>
<span>
{{
total
}}
{{
total
}}
<em
v-if=
"suffix"
class=
"suffix"
>
{{
suffix
}}
</em>
<em
v-if=
"suffix"
class=
"suffix"
>
{{
suffix
}}
</em>
</span>
</span>
<span
v-if=
"status || subTotal"
class=
"subTotal"
>
<span
v-if=
"status || subTotal"
class=
"subTotal"
>
{{
subTotal
}}
{{
subTotal
}}
<a-icon
v-if=
"status"
:type=
"`caret-$
{status}`" />}
<a-icon
v-if=
"status"
:type=
"`caret-$
{status}`" />}
</span>
</span>
</div>
</div>
</div>
</div>
</
template
>
</
template
>
<
script
>
<
script
>
...
@@ -32,18 +32,18 @@ export default {
...
@@ -32,18 +32,18 @@ export default {
"
subTotal
"
,
"
subTotal
"
,
"
status
"
,
"
status
"
,
"
suffix
"
,
"
suffix
"
,
"
gap
"
"
gap
"
,
],
],
components
:
{
components
:
{
AIcon
:
Icon
AIcon
:
Icon
,
},
},
computed
:
{
computed
:
{
cls
()
{
cls
()
{
const
{
theme
}
=
this
;
const
{
theme
}
=
this
;
return
classNames
(
"
numberInfo
"
,
{
return
classNames
(
"
numberInfo
"
,
{
[
"
numberInfo
"
+
theme
]:
theme
[
"
numberInfo
"
+
theme
]:
theme
,
});
});
}
}
,
}
}
,
};
};
</
script
>
</
script
>
\ No newline at end of file
tools/frontend/src/components/SiderMenu/BaseMenu.vue
View file @
bae8cfdf
...
@@ -8,21 +8,21 @@ export default {
...
@@ -8,21 +8,21 @@ export default {
theme
:
{
default
:
"
dark
"
,
type
:
String
},
theme
:
{
default
:
"
dark
"
,
type
:
String
},
layout
:
{
type
:
String
},
layout
:
{
type
:
String
},
mode
:
{
default
:
"
inline
"
,
type
:
String
},
mode
:
{
default
:
"
inline
"
,
type
:
String
},
menuData
:
{
default
:
[],
type
:
Array
},
menuData
:
{
default
:
()
=>
[],
type
:
Array
},
styles
:
{
type
:
String
}
styles
:
{
type
:
String
}
,
},
},
computed
:
{
computed
:
{
...
mapGetters
({
...
mapGetters
({
loading
:
"
global/nav/loading
"
loading
:
"
global/nav/loading
"
,
}),
}),
},
},
components
:
{
components
:
{
AMenu
:
Menu
,
AMenu
:
Menu
,
AMenuItem
:
Menu
.
Item
,
AMenuItem
:
Menu
.
Item
,
ASubMenu
:
Menu
.
SubMenu
,
ASubMenu
:
Menu
.
SubMenu
,
AMenuDivider
:
Menu
.
Divider
,
AMenuDivider
:
Menu
.
Divider
,
AMenuItemGroup
:
Menu
.
ItemGroup
,
AMenuItemGroup
:
Menu
.
ItemGroup
,
AIcon
:
Icon
AIcon
:
Icon
,
},
},
methods
:
{
methods
:
{
getIcon
(
icon
)
{
getIcon
(
icon
)
{
...
@@ -38,12 +38,11 @@ export default {
...
@@ -38,12 +38,11 @@ export default {
return
icon
;
return
icon
;
},
},
getNavMenuItems
(
menusData
,
parent
)
{
getNavMenuItems
(
menusData
,
parent
)
{
// console.log(menusData)
// console.log(menusData)
if
(
!
menusData
)
{
if
(
!
menusData
)
{
return
[];
return
[];
}
}
return
menusData
.
map
(
item
=>
{
return
menusData
.
map
(
(
item
)
=>
{
if
(
item
.
name
)
{
if
(
item
.
name
)
{
return
this
.
getSubMenuOrItem
(
item
,
parent
);
return
this
.
getSubMenuOrItem
(
item
,
parent
);
}
}
...
@@ -54,10 +53,7 @@ export default {
...
@@ -54,10 +53,7 @@ export default {
},
},
getSubMenuOrItem
(
item
)
{
getSubMenuOrItem
(
item
)
{
// doc: add hideChildrenInMenu 隐藏菜单
// doc: add hideChildrenInMenu 隐藏菜单
if
(
if
(
item
.
menus
&&
item
.
menus
.
some
((
menu
)
=>
menu
.
name
))
{
item
.
menus
&&
item
.
menus
.
some
(
menu
=>
menu
.
name
)
)
{
const
name
=
this
.
$t
(
item
.
locale
);
const
name
=
this
.
$t
(
item
.
locale
);
return
(
return
(
<
a
-
sub
-
menu
<
a
-
sub
-
menu
...
@@ -108,7 +104,7 @@ export default {
...
@@ -108,7 +104,7 @@ export default {
return
`/
${
path
||
""
}
`
.
replace
(
/
\/
+/g
,
"
/
"
);
return
`/
${
path
||
""
}
`
.
replace
(
/
\/
+/g
,
"
/
"
);
},
},
urlToList
(
url
)
{
urlToList
(
url
)
{
const
urllist
=
url
.
split
(
"
/
"
).
filter
(
i
=>
i
);
const
urllist
=
url
.
split
(
"
/
"
).
filter
(
(
i
)
=>
i
);
return
urllist
.
map
(
return
urllist
.
map
(
(
urlItem
,
index
)
=>
`/
${
urllist
.
slice
(
0
,
index
+
1
).
join
(
"
/
"
)}
`
(
urlItem
,
index
)
=>
`/
${
urllist
.
slice
(
0
,
index
+
1
).
join
(
"
/
"
)}
`
);
);
...
@@ -116,30 +112,29 @@ export default {
...
@@ -116,30 +112,29 @@ export default {
getOpenKeys
(
path
)
{
getOpenKeys
(
path
)
{
const
openKeys
=
this
.
urlToList
(
path
);
const
openKeys
=
this
.
urlToList
(
path
);
if
(
this
.
layout
===
"
topmenu
"
)
{
if
(
this
.
layout
===
"
topmenu
"
)
{
return
null
return
null
;
}
}
return
openKeys
.
filter
(
item
=>
item
!==
path
);
return
openKeys
.
filter
(
(
item
)
=>
item
!==
path
);
}
}
,
},
},
render
()
{
render
()
{
const
{
path
}
=
this
.
$route
;
const
{
path
}
=
this
.
$route
;
const
openKeys
=
this
.
getOpenKeys
(
path
);
const
openKeys
=
this
.
getOpenKeys
(
path
);
return
(
return
(
<
Spin
spinning
=
{
this
.
loading
}
class
=
"
baseMenuLoadding
"
>
<
Spin
spinning
=
{
this
.
loading
}
class
=
"
baseMenuLoadding
"
>
<
a
-
menu
<
a
-
menu
defaultOpenKeys
=
{
openKeys
}
defaultOpenKeys
=
{
openKeys
}
selectedKeys
=
{[
path
]}
selectedKeys
=
{[
path
]}
key
=
"
Menu
"
key
=
"
Menu
"
mode
=
{
this
.
mode
}
mode
=
{
this
.
mode
}
theme
=
{
this
.
theme
}
theme
=
{
this
.
theme
}
collapsed
=
{
this
.
collapsed
}
collapsed
=
{
this
.
collapsed
}
style
=
{
this
.
styles
}
style
=
{
this
.
styles
}
>
>
{
this
.
getNavMenuItems
(
this
.
menuData
)}
{
this
.
getNavMenuItems
(
this
.
menuData
)}
<
/a-menu
>
<
/a-menu
>
<
/Spin
>
<
/Spin
>
);
);
}
}
,
};
};
</
script
>
</
script
>
\ No newline at end of file
tools/frontend/src/components/SiderMenu/index.less
View file @
bae8cfdf
@import
'ant-design-vue/lib/style/themes/default.less'
;
@import
"ant-design-vue/lib/style/themes/default.less"
;
@ai-sider-menu-prefix: ~"@{ai-prefix}-sider-menu";
@ai-sider-menu-prefix: ~"@{ai-prefix}-sider-menu";
.@{ai-sider-menu-prefix}{
.@{ai-sider-menu-prefix} {
.logo{
.logo {
width: 100%;
width: 100%;
height: 64px;
height: 64px;
position: relative;
position: relative;
line-height: 64px;
line-height: 64px;
padding-left: (@menu-collapsed-width - 32px) / 2;
padding-left: (@menu-collapsed-width - 32px) / 2;
transition: all 0.3s;
transition: all 0.3s;
background: #002140;
background: #002140;
overflow: hidden;
overflow: hidden;
img {
img {
display: inline-block;
display: inline-block;
vertical-align: middle;
vertical-align: middle;
height: 32px;
height: 32px;
}
}
h1 {
h1 {
color: white;
color: white;
display: inline-block;
display: inline-block;
vertical-align: middle;
vertical-align: middle;
font-size: 20px;
font-size: 20px;
margin: 0 0 0 12px;
margin: 0 0 0 12px;
font-family: 'Myriad Pro', 'Helvetica Neue', Arial, Helvetica, sans-serif;
font-family: "Myriad Pro", "Helvetica Neue", Arial, Helvetica, sans-serif;
font-weight: 600;
font-weight: 600;
}
}
}
}
}
}
.sider {
.sider {
min-height: 100vh;
min-height: 100vh;
box-shadow: 2px 0 6px rgba(0, 21, 41, 0.35);
box-shadow: 2px 0 6px rgba(0, 21, 41, 0.35);
position: relative;
position: relative;
z-index: 10;
z-index: 10;
&.fixSiderbar {
&.fixSiderbar {
position: fixed;
position: fixed;
top: 0;
top: 0;
left: 0;
left: 0;
}
}
&.light {
&.light {
box-shadow: 2px 0 8px 0 rgba(29, 35, 41, 0.05);
box-shadow: 2px 0 8px 0 rgba(29, 35, 41, 0.05);
background-color: white;
background-color: white;
.logo {
.logo {
background: white;
background: white;
border-bottom: 1px solid @border-color-split;
border-bottom: 1px solid @border-color-split;
border-right: 1px solid @border-color-split;
border-right: 1px solid @border-color-split;
h1 {
h1 {
color: @primary-color;
color: @primary-color;
}
}
}
}
}
}
}
}
.baseMenuLoadding{
.active-menu-item {
background-color: #2ecccd;
}
}
.baseMenuLoadding {
}
tools/frontend/src/components/TopNavHeader/index.js
View file @
bae8cfdf
...
@@ -22,7 +22,7 @@ const TopNavHeader = {
...
@@ -22,7 +22,7 @@ const TopNavHeader = {
theme
=
"
dark
"
,
theme
=
"
dark
"
,
contentWidth
=
"
Fixed
"
,
contentWidth
=
"
Fixed
"
,
layout
,
layout
,
//
title = "admin",
title
=
"
admin
"
,
}
=
this
;
}
=
this
;
return
(
return
(
<
div
class
=
"
top-nav-header
"
>
<
div
class
=
"
top-nav-header
"
>
...
@@ -32,7 +32,7 @@ const TopNavHeader = {
...
@@ -32,7 +32,7 @@ const TopNavHeader = {
<
div
class
=
"
logo
"
>
<
div
class
=
"
logo
"
>
<
router
-
link
to
=
"
/
"
>
<
router
-
link
to
=
"
/
"
>
<
img
src
=
{
logo
}
alt
=
"
logo
"
/>
<
img
src
=
{
logo
}
alt
=
"
logo
"
/>
<
h1
>
Ant
Design
Pro
<
/h1
>
<
h1
>
{
title
}
<
/h1
>
<
/router-link
>
<
/router-link
>
<
/div
>
<
/div
>
<
div
<
div
...
...
tools/frontend/src/defaultSettings.js
View file @
bae8cfdf
...
@@ -7,5 +7,6 @@ export default {
...
@@ -7,5 +7,6 @@ export default {
autoHideHeader
:
false
,
// auto hide header
autoHideHeader
:
false
,
// auto hide header
fixSiderbar
:
false
,
// sticky siderbar
fixSiderbar
:
false
,
// sticky siderbar
leftMenuTitle
:
"
EVM 应用商店
"
,
// 左侧边栏顶部名称
leftMenuTitle
:
"
EVM 应用商店
"
,
// 左侧边栏顶部名称
leftMenuIcon
:
""
// 左侧边栏顶部Logo
leftMenuIcon
:
""
,
// 左侧边栏顶部Logo
appSlogan
:
"
EVM,致力于为互联网行业提供物联网解决方案
"
,
// 应用宣传文案
}
}
tools/frontend/src/layouts/BasicLayout.js
View file @
bae8cfdf
...
@@ -5,7 +5,7 @@ import SiderMenu from "@/components/SiderMenu";
...
@@ -5,7 +5,7 @@ import SiderMenu from "@/components/SiderMenu";
import
Header
from
'
./Header
'
;
import
Header
from
'
./Header
'
;
import
Footer
from
'
./Footer
'
;
import
Footer
from
'
./Footer
'
;
import
eventBus
from
'
@/utils/eventBus.js
'
import
eventBus
from
'
@/utils/eventBus.js
'
import
logo
from
"
@/assets/
logo.pn
g
"
;
import
logo
from
"
@/assets/
app-store.sv
g
"
;
import
{
mapGetters
}
from
"
vuex
"
;
import
{
mapGetters
}
from
"
vuex
"
;
const
BasicLayout
=
{
const
BasicLayout
=
{
data
:
()
=>
({
data
:
()
=>
({
...
...
tools/frontend/src/layouts/Footer.js
View file @
bae8cfdf
...
@@ -8,27 +8,27 @@ const FooterView = {
...
@@ -8,27 +8,27 @@ const FooterView = {
<
GlobalFooter
<
GlobalFooter
links
=
{[
links
=
{[
{
{
key
:
'
Pro 首页
'
,
key
:
'
EVM
'
,
title
:
'
Pro
首页
'
,
title
:
'
EVM
首页
'
,
href
:
'
https://git
hub.com/ruyangit/seed-workbench-ui.git
'
,
href
:
'
https://git
ee.com/scriptiot/evm
'
,
blankTarget
:
true
,
blankTarget
:
true
,
},
},
{
{
key
:
'
git
hub
'
,
key
:
'
git
ee
'
,
title
:
<
Icon
type
=
"
github
"
/>
,
title
:
<
Icon
type
=
"
github
"
/>
,
href
:
'
https://git
hub.com/ruyangit/seed-workbench-ui.git
'
,
href
:
'
https://git
ee.com/scriptiot/evm
'
,
blankTarget
:
true
,
blankTarget
:
true
,
},
},
{
{
key
:
'
Ant Design
'
,
key
:
'
ByteCode
'
,
title
:
'
Ant Design
'
,
title
:
'
ByteCode
'
,
href
:
'
http
s://ant.design
'
,
href
:
'
http
://evmiot.com
'
,
blankTarget
:
true
,
blankTarget
:
true
,
},
},
]}
]}
copyright
=
{
copyright
=
{
<
div
>
<
div
>
Copyright
<
Icon
type
=
"
copyright
"
/>
20
18
Ryan
Ru
金服体验技术部出品
Copyright
<
Icon
type
=
"
copyright
"
/>
20
21
武汉市字节码科技有限公司
<
/div
>
<
/div
>
}
}
/
>
/
>
...
...
tools/frontend/src/layouts/UserLayout.js
View file @
bae8cfdf
import
'
./UserLayout.less
'
import
'
./UserLayout.less
'
import
logo
from
'
@/assets/logo.png
'
;
import
logo
from
'
@/assets/app-store.svg
'
;
import
{
mapGetters
}
from
"
vuex
"
;
const
UserLayout
=
{
const
UserLayout
=
{
props
:
{
props
:
{
logo
:
{
default
:
logo
,
types
:
String
}
logo
:
{
default
:
logo
,
types
:
String
}
},
},
computed
:
{
...
mapGetters
({
settings
:
"
global/settings
"
})
},
render
()
{
render
()
{
const
{
leftMenuTitle
,
appSlogan
}
=
this
.
settings
;
return
(
return
(
<
div
class
=
"
ai-user-layout-container
"
>
<
div
class
=
"
ai-user-layout-container
"
>
<
div
class
=
"
content
"
>
<
div
class
=
"
content
"
>
...
@@ -12,11 +20,11 @@ const UserLayout = {
...
@@ -12,11 +20,11 @@ const UserLayout = {
<
div
class
=
"
header
"
>
<
div
class
=
"
header
"
>
<
img
alt
=
"
logo
"
class
=
"
logo
"
src
=
{
this
.
logo
}
/
>
<
img
alt
=
"
logo
"
class
=
"
logo
"
src
=
{
this
.
logo
}
/
>
<
span
class
=
"
title
"
>
<
span
class
=
"
title
"
>
Ant
Design
{
leftMenuTitle
}
<
/span
>
<
/span
>
<
/div
>
<
/div
>
<
div
class
=
"
desc
"
>
<
div
class
=
"
desc
"
>
Ant
Design
是西湖区最具影响力的
Web
设计规范
{
appSlogan
}
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
router
-
view
/>
<
router
-
view
/>
...
...
tools/frontend/src/locales/lang/ar.js
0 → 100644
View file @
bae8cfdf
/**
* Arabic translate - D34DlyM4N(https://github.com/D34DlyM4N)
* @type Object
*/
const
ar
=
{
btn
:
{
about
:
'
حول
'
,
back
:
'
رجوع
'
,
cancel
:
'
الغاء
'
,
clear
:
'
مسح
'
,
copy
:
'
نسخ
'
,
cut
:
'
قص
'
,
delete
:
'
حذف
'
,
edit
:
'
تعديل
'
,
forward
:
'
الى الامام
'
,
folder
:
'
مجلد جديد
'
,
file
:
'
ملف جديد
'
,
fullScreen
:
'
ملء الشاشة
'
,
grid
:
'
شبكة
'
,
paste
:
'
لصق
'
,
refresh
:
'
تحديث
'
,
submit
:
'
ارسال
'
,
table
:
'
جدول
'
,
upload
:
'
رفع
'
,
uploadSelect
:
'
اختر الملفات
'
,
hidden
:
'
الملفات المخفية
'
,
},
clipboard
:
{
actionType
:
'
نوع
'
,
copy
:
'
نسخ
'
,
cut
:
'
قص
'
,
none
:
'
لا شيء محدد
'
,
title
:
'
ذاكرة النصوص
'
,
},
contextMenu
:
{
copy
:
'
نسخ
'
,
cut
:
'
قص
'
,
delete
:
'
حذف
'
,
download
:
'
تحميل
'
,
info
:
'
اختير:
'
,
open
:
'
فتح
'
,
paste
:
'
لصق
'
,
properties
:
'
الخصائص
'
,
rename
:
'
اعادة تسمية
'
,
select
:
'
اختيار
'
,
view
:
'
عرض
'
,
zip
:
'
ضغط
'
,
unzip
:
'
أستخراج
'
,
edit
:
'
تعديل
'
,
audioPlay
:
'
تشغيل
'
,
videoPlay
:
'
تشغيل
'
,
},
info
:
{
directories
:
'
المجلدات:
'
,
files
:
'
الملفات:
'
,
selected
:
'
أختيرت:
'
,
selectedSize
:
'
حجم الملفات:
'
,
size
:
'
حجم الملفات:
'
,
},
manager
:
{
table
:
{
date
:
'
تأريخ
'
,
folder
:
'
مجلد
'
,
name
:
'
أسم
'
,
size
:
'
حجم
'
,
type
:
'
نوع
'
,
},
},
modal
:
{
about
:
{
developer
:
'
مطور
'
,
name
:
'
Laravel File Manager
'
,
title
:
'
حول
'
,
version
:
'
الإصدار
'
,
},
delete
:
{
noSelected
:
'
لا شيء محدد!
'
,
title
:
'
حذف
'
,
},
newFile
:
{
fieldName
:
'
أسم الملف
'
,
fieldFeedback
:
'
الملف موجود!
'
,
title
:
'
أنشاء ملف جديد
'
,
},
newFolder
:
{
fieldName
:
'
أسم المجلد
'
,
fieldFeedback
:
'
المجلد موجود!
'
,
title
:
'
انشاء مجلد جديد
'
,
},
preview
:
{
title
:
'
عرض
'
,
},
properties
:
{
disk
:
'
قرص
'
,
modified
:
'
تم التعديل
'
,
name
:
'
أسم
'
,
path
:
'
مسار
'
,
size
:
'
حجم
'
,
title
:
'
خصائص
'
,
type
:
'
نوع
'
,
url
:
'
رابط
'
,
access
:
'
التمكن من
'
,
access_0
:
'
تم الرفض
'
,
access_1
:
'
قراءة فقط
'
,
access_2
:
'
اقرا و اكتب
'
,
},
rename
:
{
directoryExist
:
'
المجلد موجود
'
,
fieldName
:
'
ادخال اسم جديد
'
,
fieldFeedback
:
'
اسم خاطئ
'
,
fileExist
:
'
الملف موجود
'
,
title
:
'
اعادة تسمية
'
,
},
status
:
{
noErrors
:
'
لايوجد خطأ!
'
,
title
:
'
الحالة
'
,
},
upload
:
{
ifExist
:
'
اذا الملف موجود:
'
,
noSelected
:
'
لا توجد ملفات مختارة!
'
,
overwrite
:
'
اعادة الكتابة!
'
,
selected
:
'
المختارة:
'
,
size
:
'
الحجم:
'
,
skip
:
'
تخطي
'
,
title
:
'
رفع الملفات
'
,
},
editor
:
{
title
:
'
محرر
'
,
},
audioPlayer
:
{
title
:
'
مشغل الاصوات
'
,
},
videoPlayer
:
{
title
:
'
مشغل الفيديو
'
,
},
zip
:
{
title
:
'
أنشاء أرشيف
'
,
fieldName
:
'
أسم الارشيف
'
,
fieldFeedback
:
'
الارشيف موجود!
'
,
},
unzip
:
{
title
:
'
فك الارشيف
'
,
fieldName
:
'
أسم المجلد
'
,
fieldRadioName
:
'
أستخراج الى:
'
,
fieldRadio1
:
'
الى المجلد الحالي
'
,
fieldRadio2
:
'
في مجلد جديد
'
,
fieldFeedback
:
'
المجلد موجود!
'
,
warning
:
'
تحذير! اذا تشابهت الاسماء, سيتم استبدال الملفات!
'
,
},
cropper
:
{
title
:
'
قص
'
,
apply
:
'
تطبيق
'
,
reset
:
'
اعادة تعين
'
,
save
:
'
حفظ
'
,
},
},
notifications
:
{
cutToClipboard
:
'
قص إلى الحافظة!
'
,
copyToClipboard
:
'
نسخ إلى الحافظة!
'
,
},
response
:
{
noConfig
:
'
الاعدادت غير متوفرة!
'
,
notFound
:
'
غير متوفر!
'
,
diskNotFound
:
'
القرص غير موجود!
'
,
pathNotFound
:
'
مسار غير موجود!
'
,
diskSelected
:
'
تم اختيار القرص!
'
,
// files
fileExist
:
'
الملف موجود بالفعل!
'
,
fileCreated
:
'
تم إنشاء الملف!
'
,
fileUpdated
:
'
تم تحديث الملف!
'
,
fileNotFound
:
'
الملف غير موجود!
'
,
// directories
dirExist
:
'
المجلد موجود بالفعل!
'
,
dirCreated
:
'
تم أنشاء المجلد!
'
,
dirNotFound
:
'
المجلد غير موجود
'
,
// actions
uploaded
:
'
تم تحديث كل الملفات!
'
,
notAllUploaded
:
'
بعض الملفات غير المحملة!
'
,
delNotFound
:
'
بعض الملفات غير موجودة! تحديث!
'
,
deleted
:
'
تم الحذف!
'
,
renamed
:
'
أعيدت تسميتها!
'
,
copied
:
'
تم النسخ بنجاح!
'
,
// zip
zipError
:
'
خطأ في إنشاء الأرشيف!
'
,
// acl
aclError
:
'
تم الرفض!
'
,
},
};
export
default
ar
;
tools/frontend/src/locales/lang/cs.js
0 → 100644
View file @
bae8cfdf
/**
* Czech translate
* Aleš Nejdr - mige
* @type Object
*/
const
cs
=
{
btn
:
{
about
:
'
O aplikaci
'
,
back
:
'
Zpět
'
,
cancel
:
'
Zrušit
'
,
clear
:
'
Vymazat
'
,
copy
:
'
Kopírovat
'
,
cut
:
'
Vyjmout
'
,
delete
:
'
Smazat
'
,
edit
:
'
Upravit
'
,
forward
:
'
Vpřed
'
,
folder
:
'
Nová složka
'
,
file
:
'
Nový soubor
'
,
fullScreen
:
'
Celá obrazovka
'
,
grid
:
'
Mřížka
'
,
paste
:
'
Vložit
'
,
refresh
:
'
Obnovit
'
,
submit
:
'
Odeslat
'
,
table
:
'
Tabulka
'
,
upload
:
'
Nahrát
'
,
uploadSelect
:
'
Vybrat soubory
'
,
hidden
:
'
Skryté soubory
'
,
},
clipboard
:
{
actionType
:
'
Typ
'
,
copy
:
'
Kopírovat
'
,
cut
:
'
Vyjmout
'
,
none
:
'
Nic nevybráno
'
,
title
:
'
Schránka
'
,
},
contextMenu
:
{
copy
:
'
Kopírovat
'
,
cut
:
'
Vyjmout
'
,
delete
:
'
Smazat
'
,
download
:
'
Stáhnout
'
,
info
:
'
Vybráno:
'
,
open
:
'
Otevřit
'
,
paste
:
'
Vložit
'
,
properties
:
'
Vlastnosti
'
,
rename
:
'
Přejmenovat
'
,
select
:
'
Vybrat
'
,
view
:
'
Zobrazit
'
,
zip
:
'
Zabalit (Zip)
'
,
unzip
:
'
Rozbalit (Zip)
'
,
edit
:
'
Upravit
'
,
audioPlay
:
'
Přehrát
'
,
videoPlay
:
'
Přehrát
'
,
},
info
:
{
directories
:
'
Složky:
'
,
files
:
'
Soubory:
'
,
selected
:
'
Vybráno:
'
,
selectedSize
:
'
Velikost souborů:
'
,
size
:
'
Velikost souborů:
'
,
},
manager
:
{
table
:
{
date
:
'
Změněno
'
,
folder
:
'
Složka
'
,
name
:
'
Název
'
,
size
:
'
Velikost
'
,
type
:
'
Typ
'
,
},
},
modal
:
{
about
:
{
developer
:
'
Vývojář
'
,
name
:
'
Laravel File Manager
'
,
title
:
'
O aplikaci
'
,
version
:
'
Verze
'
,
},
delete
:
{
noSelected
:
'
Nic nevybráno!
'
,
title
:
'
Smazat
'
,
},
newFile
:
{
fieldName
:
'
Název souboru
'
,
fieldFeedback
:
'
Soubor již existuje!
'
,
title
:
'
Vytvořit nový soubor
'
,
},
newFolder
:
{
fieldName
:
'
Název složky
'
,
fieldFeedback
:
'
Složka již existuje!
'
,
title
:
'
Vytvořit novou složku
'
,
},
preview
:
{
title
:
'
Náhled
'
,
},
properties
:
{
disk
:
'
Disk
'
,
modified
:
'
Změněno
'
,
name
:
'
Název
'
,
path
:
'
Cesta
'
,
size
:
'
Velikost
'
,
title
:
'
Vlastnosti
'
,
type
:
'
Typ
'
,
url
:
'
URL
'
,
access
:
'
Přístup
'
,
access_0
:
'
Přístup odepřen
'
,
access_1
:
'
Pouze ke čtení
'
,
access_2
:
'
Čtení a zápis
'
,
},
rename
:
{
directoryExist
:
'
Složka již existuje
'
,
fieldName
:
'
Vložte nové jméno
'
,
fieldFeedback
:
'
Neplatné jméno
'
,
fileExist
:
'
Soubor již existuje
'
,
title
:
'
Přejmenovat
'
,
},
status
:
{
noErrors
:
'
Žádná chyba!
'
,
title
:
'
Stav
'
,
},
upload
:
{
ifExist
:
'
Pokud soubor již existuje:
'
,
noSelected
:
'
Nevybrány žádné soubory!
'
,
overwrite
:
'
Přepsat!
'
,
selected
:
'
Vybráno:
'
,
size
:
'
Velikost:
'
,
skip
:
'
Přeskočit
'
,
title
:
'
Nahrát soubory
'
,
},
editor
:
{
title
:
'
Editor
'
,
},
audioPlayer
:
{
title
:
'
Audio přehrávač
'
,
},
videoPlayer
:
{
title
:
'
Video přehrávač
'
,
},
zip
:
{
title
:
'
Vytvořit archiv
'
,
fieldName
:
'
Název archivu
'
,
fieldFeedback
:
'
Archiv již existuje!
'
,
},
unzip
:
{
title
:
'
Rozbalit archiv
'
,
fieldName
:
'
Název složky
'
,
fieldRadioName
:
'
Rozbalit do:
'
,
fieldRadio1
:
'
Do aktuální složky
'
,
fieldRadio2
:
'
Do nové složky
'
,
fieldFeedback
:
'
Složka již existuje!
'
,
warning
:
'
Pozor! Pokud se jména shodují, budou soubory přepsány!
'
,
},
cropper
:
{
title
:
'
Oříznutí
'
,
apply
:
'
Aplikovat
'
,
reset
:
'
Obnovit
'
,
save
:
'
Uložit
'
,
},
},
notifications
:
{
cutToClipboard
:
'
Vyjmuto do schránky!
'
,
copyToClipboard
:
'
Zkopírováno do schránky!
'
,
},
response
:
{
noConfig
:
'
Konfigurace nebyla nalezena!
'
,
notFound
:
'
Nenalezeno!
'
,
diskNotFound
:
'
Disk nebyla nalezen!
'
,
pathNotFound
:
'
Cesta nebyla nalezena!
'
,
diskSelected
:
'
Disk byl vybrán!
'
,
// files
fileExist
:
'
Soubor již existuje!
'
,
fileCreated
:
'
Soubor byl vytvořen!
'
,
fileUpdated
:
'
Soubor byl aktualizován!
'
,
fileNotFound
:
'
Soubor nebyl nalezen!
'
,
// directories
dirExist
:
'
Složka již existuje!
'
,
dirCreated
:
'
Složka byla vytvořena!
'
,
dirNotFound
:
'
Složka nebyla nalezena
'
,
// actions
uploaded
:
'
Všechny soubory byly nahrány!
'
,
notAllUploaded
:
'
Některé soubory nebyly nahrány!
'
,
delNotFound
:
'
Některé položky nebyly nalezeny!
'
,
deleted
:
'
Smazáno!
'
,
renamed
:
'
Přejmenováno!
'
,
copied
:
'
Úspěšně zkopírováno!
'
,
// zip
zipError
:
'
Chyba při vytváření archivu!
'
,
// acl
aclError
:
'
Přístup odepřen!
'
,
},
};
export
default
cs
;
tools/frontend/src/locales/lang/de.js
0 → 100644
View file @
bae8cfdf
/**
* German translate
* @type Object
*/
const
de
=
{
btn
:
{
about
:
'
Über
'
,
back
:
'
Zurück
'
,
cancel
:
'
Abbrechen
'
,
clear
:
'
Leeren
'
,
copy
:
'
Kopieren
'
,
cut
:
'
Ausschneiden
'
,
delete
:
'
Löschen
'
,
edit
:
'
Bearbeiten
'
,
forward
:
'
Weiter
'
,
folder
:
'
Neuer Order
'
,
file
:
'
Neue Datei
'
,
fullScreen
:
'
Vollbildschirm
'
,
grid
:
'
Raster
'
,
paste
:
'
Einfügen
'
,
refresh
:
'
Neu laden
'
,
submit
:
'
Bestätigen
'
,
table
:
'
Detailansicht
'
,
upload
:
'
Hochladen
'
,
uploadSelect
:
'
Auswählen
'
,
hidden
:
'
Versteckte Dateien
'
,
},
clipboard
:
{
actionType
:
'
Type
'
,
copy
:
'
Kopieren
'
,
cut
:
'
Ausschneiden
'
,
none
:
'
Nichts ausgewählt
'
,
title
:
'
Zwischenablage
'
,
},
contextMenu
:
{
copy
:
'
Kopieren
'
,
cut
:
'
Ausschneiden
'
,
delete
:
'
Löschen
'
,
download
:
'
Herunterladen
'
,
info
:
'
Ausgewählt:
'
,
open
:
'
Öffnen
'
,
paste
:
'
Einfügen
'
,
properties
:
'
Einstellungen
'
,
rename
:
'
Umbenennen
'
,
select
:
'
Wählen
'
,
view
:
'
Vorschau
'
,
zip
:
'
Zip
'
,
unzip
:
'
Unzip
'
,
edit
:
'
Bearbeiten
'
,
audioPlay
:
'
Abspielen
'
,
videoPlay
:
'
Abspielen
'
,
},
info
:
{
directories
:
'
Ordner:
'
,
files
:
'
Dateien:
'
,
selected
:
'
Ausgewählt:
'
,
selectedSize
:
'
Dateigröße:
'
,
size
:
'
Dateigröße:
'
,
},
manager
:
{
table
:
{
date
:
'
Datum
'
,
folder
:
'
Ordner
'
,
name
:
'
Name
'
,
size
:
'
Größe
'
,
type
:
'
Type
'
,
},
},
modal
:
{
about
:
{
developer
:
'
Entwickler
'
,
name
:
'
Laravel File Manager
'
,
title
:
'
Über
'
,
version
:
'
Version
'
,
},
delete
:
{
noSelected
:
'
Nichts ausgewählt!
'
,
title
:
'
Löschen
'
,
},
newFile
:
{
fieldName
:
'
Dateiname
'
,
fieldFeedback
:
'
Datei existiert!
'
,
title
:
'
Neue Datei erstellen
'
,
},
newFolder
:
{
fieldName
:
'
Ordnername
'
,
fieldFeedback
:
'
Ordner existiert!
'
,
title
:
'
Neuen Ordner erstellen
'
,
},
preview
:
{
title
:
'
Vorschau
'
,
},
properties
:
{
disk
:
'
Festplatte
'
,
modified
:
'
Geändert
'
,
name
:
'
Name
'
,
path
:
'
Pfad
'
,
size
:
'
Größe
'
,
title
:
'
Eigenschaften
'
,
type
:
'
Type
'
,
url
:
'
URL
'
,
access
:
'
Zugang
'
,
access_0
:
'
Zugriff verweigert
'
,
access_1
:
'
Nur Lesezugriff
'
,
access_2
:
'
Lesen- und Schreibenzugriff
'
,
},
rename
:
{
directoryExist
:
'
Verzeichnis ist vorhanden
'
,
fieldName
:
'
Neuen Namen eingeben
'
,
fieldFeedback
:
'
Ungültiger Name
'
,
fileExist
:
'
Datei ist vorhanden
'
,
title
:
'
Umbenennen
'
,
},
status
:
{
noErrors
:
'
Keine Fehler!
'
,
title
:
'
Status
'
,
},
upload
:
{
ifExist
:
'
Datei existiert:
'
,
noSelected
:
'
Keine Dateien selektiert!
'
,
overwrite
:
'
Überschreiben!
'
,
selected
:
'
Ausgewählt:
'
,
size
:
'
Größe:
'
,
skip
:
'
Überspringen
'
,
title
:
'
Hochladen von Dateien
'
,
},
editor
:
{
title
:
'
Editor
'
,
},
audioPlayer
:
{
title
:
'
Audio-Player
'
,
},
videoPlayer
:
{
title
:
'
Video-Player
'
,
},
zip
:
{
title
:
'
Archiv erzeugen
'
,
fieldName
:
'
Archiv Name
'
,
fieldFeedback
:
'
Archiv existiert!
'
,
},
unzip
:
{
title
:
'
Archiv entpacken
'
,
fieldName
:
'
Ordnername
'
,
fieldRadioName
:
'
Extrahieren in:
'
,
fieldRadio1
:
'
Zum aktuellen Verzeichnis
'
,
fieldRadio2
:
'
In einem neuen Ordner
'
,
fieldFeedback
:
'
Ordner ist vorhanden!
'
,
warning
:
'
Achtung! Wenn die Namen übereinstimmen, werden die Dateien überschrieben!
'
,
},
cropper
:
{
title
:
'
Beschneiden
'
,
apply
:
'
Übernehmen
'
,
reset
:
'
Zurücksetzen
'
,
save
:
'
Speichern
'
,
},
},
notifications
:
{
cutToClipboard
:
'
Ausgeschnitten in die Zwischenablage!
'
,
copyToClipboard
:
'
Kopiert in die Zwischenablage!
'
,
},
response
:
{
noConfig
:
'
Konfiguration nicht gefunden!
'
,
notFound
:
'
Nicht gefunden!
'
,
diskNotFound
:
'
Festplatte nicht gefunden!
'
,
pathNotFound
:
'
Pfad nicht gefunden!
'
,
diskSelected
:
'
Festplatte ausgewählt!
'
,
// files
fileExist
:
'
Datei existiert bereits!
'
,
fileCreated
:
'
Datei erstellt!
'
,
fileUpdated
:
'
Datei wurde aktualisiert!
'
,
fileNotFound
:
'
Datei nicht gefunden!
'
,
// directories
dirExist
:
'
Ordner existiert bereits!
'
,
dirCreated
:
'
Ordner angelegt!
'
,
dirNotFound
:
'
Ordner nicht gefunden
'
,
// actions
uploaded
:
'
Alle Dateien wurden hochgeladen!
'
,
notAllUploaded
:
'
Einige Dateien wurden nicht hochgeladen!
'
,
delNotFound
:
'
Einige Dateien wurden nicht gefunden!
'
,
deleted
:
'
Gelöscht!
'
,
renamed
:
'
Umbenannt!
'
,
copied
:
'
Erfolgreich kopiert!
'
,
// zip
zipError
:
'
Fehler bei der Erstellung des Archivs!
'
,
// acl
aclError
:
'
Zugriff verweigert!
'
,
},
};
export
default
de
;
tools/frontend/src/locales/lang/en.js
0 → 100644
View file @
bae8cfdf
/**
* English translate
* @type Object
*/
const
en
=
{
btn
:
{
about
:
'
About
'
,
back
:
'
Back
'
,
cancel
:
'
Cancel
'
,
clear
:
'
Clear
'
,
copy
:
'
Copy
'
,
cut
:
'
Cut
'
,
delete
:
'
Delete
'
,
edit
:
'
Edit
'
,
forward
:
'
Forward
'
,
folder
:
'
New folder
'
,
file
:
'
New file
'
,
fullScreen
:
'
Full screen
'
,
grid
:
'
Grid
'
,
paste
:
'
Paste
'
,
refresh
:
'
Refresh
'
,
submit
:
'
Submit
'
,
table
:
'
Table
'
,
upload
:
'
Upload
'
,
uploadSelect
:
'
Select files
'
,
hidden
:
'
Hidden files
'
,
},
clipboard
:
{
actionType
:
'
Type
'
,
copy
:
'
Copy
'
,
cut
:
'
Cut
'
,
none
:
'
Nothing selected
'
,
title
:
'
Clipboard
'
,
},
contextMenu
:
{
copy
:
'
Copy
'
,
cut
:
'
Cut
'
,
delete
:
'
Delete
'
,
download
:
'
Download
'
,
info
:
'
Selected:
'
,
open
:
'
Open
'
,
paste
:
'
Paste
'
,
properties
:
'
Properties
'
,
rename
:
'
Rename
'
,
select
:
'
Select
'
,
view
:
'
View
'
,
zip
:
'
Zip
'
,
unzip
:
'
Unzip
'
,
edit
:
'
Edit
'
,
audioPlay
:
'
Play
'
,
videoPlay
:
'
Play
'
,
},
info
:
{
directories
:
'
Folders:
'
,
files
:
'
Files:
'
,
selected
:
'
Selected:
'
,
selectedSize
:
'
Files size:
'
,
size
:
'
Files size:
'
,
},
manager
:
{
table
:
{
date
:
'
Date
'
,
folder
:
'
Folder
'
,
name
:
'
Name
'
,
size
:
'
Size
'
,
type
:
'
Type
'
,
},
},
modal
:
{
about
:
{
developer
:
'
Developer
'
,
name
:
'
Laravel File Manager
'
,
title
:
'
About
'
,
version
:
'
Version
'
,
},
delete
:
{
noSelected
:
'
Nothing selected!
'
,
title
:
'
Delete
'
,
},
newFile
:
{
fieldName
:
'
File name
'
,
fieldFeedback
:
'
File exists!
'
,
title
:
'
Create new file
'
,
},
newFolder
:
{
fieldName
:
'
Folder name
'
,
fieldFeedback
:
'
Folder exists!
'
,
title
:
'
Create new folder
'
,
},
preview
:
{
title
:
'
Preview
'
,
},
properties
:
{
disk
:
'
Disk
'
,
modified
:
'
Modified
'
,
name
:
'
Name
'
,
path
:
'
Path
'
,
size
:
'
Size
'
,
title
:
'
Properties
'
,
type
:
'
Type
'
,
url
:
'
URL
'
,
access
:
'
Access
'
,
access_0
:
'
Access denied
'
,
access_1
:
'
Only Read
'
,
access_2
:
'
Read and Write
'
,
},
rename
:
{
directoryExist
:
'
Directory exists
'
,
fieldName
:
'
Enter new name
'
,
fieldFeedback
:
'
Invalid name
'
,
fileExist
:
'
File exists
'
,
title
:
'
Rename
'
,
},
status
:
{
noErrors
:
'
No errors!
'
,
title
:
'
Status
'
,
},
upload
:
{
ifExist
:
'
If file exist:
'
,
noSelected
:
'
No files selected!
'
,
overwrite
:
'
Overwrite!
'
,
selected
:
'
Selected:
'
,
size
:
'
Size:
'
,
skip
:
'
Skip
'
,
title
:
'
Upload files
'
,
},
editor
:
{
title
:
'
Editor
'
,
},
audioPlayer
:
{
title
:
'
Audio player
'
,
},
videoPlayer
:
{
title
:
'
Video player
'
,
},
zip
:
{
title
:
'
Create archive
'
,
fieldName
:
'
Archive name
'
,
fieldFeedback
:
'
Archive exists!
'
,
},
unzip
:
{
title
:
'
Unpack archive
'
,
fieldName
:
'
Folder name
'
,
fieldRadioName
:
'
Extract to:
'
,
fieldRadio1
:
'
To current folder
'
,
fieldRadio2
:
'
In a new folder
'
,
fieldFeedback
:
'
Folder exists!
'
,
warning
:
'
Attention! If the names match, the files will be overwritten!
'
,
},
cropper
:
{
title
:
'
Cropping
'
,
apply
:
'
Apply
'
,
reset
:
'
Reset
'
,
save
:
'
Save
'
,
},
},
notifications
:
{
cutToClipboard
:
'
Cut to clipboard!
'
,
copyToClipboard
:
'
Copied to clipboard!
'
,
},
response
:
{
noConfig
:
'
Config not found!
'
,
notFound
:
'
Not found!
'
,
diskNotFound
:
'
Disk not found!
'
,
pathNotFound
:
'
Path not found!
'
,
diskSelected
:
'
Disk selected!
'
,
// files
fileExist
:
'
File already exists!
'
,
fileCreated
:
'
File created!
'
,
fileUpdated
:
'
File updated!
'
,
fileNotFound
:
'
File not found!
'
,
// directories
dirExist
:
'
Directory already exists!
'
,
dirCreated
:
'
Directory created!
'
,
dirNotFound
:
'
Directory not found
'
,
// actions
uploaded
:
'
All files uploaded!
'
,
notAllUploaded
:
'
Some files weren
\'
t uploaded!
'
,
delNotFound
:
'
Some items weren
\'
t founded!
'
,
deleted
:
'
Deleted!
'
,
renamed
:
'
Renamed!
'
,
copied
:
'
Copied successfully!
'
,
// zip
zipError
:
'
Error creating archive!
'
,
// acl
aclError
:
'
Access denied!
'
,
},
};
export
default
en
;
tools/frontend/src/locales/lang/es.js
0 → 100644
View file @
bae8cfdf
/**
* Spanish translate
* Marc Garcia Torrent - https://github.com/mgarcia96
* @type Object
*/
const
es
=
{
btn
:
{
about
:
'
Acerca de
'
,
back
:
'
Atras
'
,
cancel
:
'
Cancelar
'
,
clear
:
'
Limpiar
'
,
copy
:
'
Copiar
'
,
cut
:
'
Cortar
'
,
delete
:
'
Eliminar
'
,
edit
:
'
Editar
'
,
forward
:
'
Siguiente
'
,
folder
:
'
Nueva carpeta
'
,
file
:
'
Crear archivo
'
,
fullScreen
:
'
Pantalla completa
'
,
grid
:
'
Cuadrícula
'
,
paste
:
'
Pegar
'
,
refresh
:
'
Actualizar
'
,
submit
:
'
Guardar
'
,
table
:
'
Tabla
'
,
upload
:
'
Subir
'
,
uploadSelect
:
'
Seleccionar archivos
'
,
hidden
:
'
Archivos ocultos
'
,
},
clipboard
:
{
actionType
:
'
Tipo
'
,
copy
:
'
Copiar
'
,
cut
:
'
Cortar
'
,
none
:
'
Nada seleccionado
'
,
title
:
'
Portapapeles
'
,
},
contextMenu
:
{
copy
:
'
Copiar
'
,
cut
:
'
Cortar
'
,
delete
:
'
Eliminar
'
,
download
:
'
Descargar
'
,
info
:
'
Seleccionar:
'
,
open
:
'
Abrir
'
,
paste
:
'
Pegar
'
,
properties
:
'
Propiedades
'
,
rename
:
'
Renombrar
'
,
select
:
'
Seleccionar
'
,
view
:
'
Vista
'
,
zip
:
'
Zip
'
,
unzip
:
'
Unzip
'
,
edit
:
'
Editar
'
,
audioPlay
:
'
Play
'
,
videoPlay
:
'
Play
'
,
},
info
:
{
directories
:
'
Carpetas:
'
,
files
:
'
Archivos:
'
,
selected
:
'
Seleccionar:
'
,
selectedSize
:
'
Tamaño archivos:
'
,
size
:
'
Tamaño archivos:
'
,
},
manager
:
{
table
:
{
date
:
'
Fecha
'
,
folder
:
'
Carpeta
'
,
name
:
'
Nombre
'
,
size
:
'
Tamaño
'
,
type
:
'
Tipo
'
,
},
},
modal
:
{
about
:
{
developer
:
'
Developer
'
,
name
:
'
Laravel File Manager
'
,
title
:
'
About
'
,
version
:
'
Version
'
,
},
delete
:
{
noSelected
:
'
Nada seleccionado
'
,
title
:
'
Eliminar
'
,
},
newFile
:
{
fieldName
:
'
Nombre del archivo
'
,
fieldFeedback
:
'
El archivo ya existe
'
,
title
:
'
Crear nuevo archivo
'
,
},
newFolder
:
{
fieldName
:
'
Nombre de la carpeta
'
,
fieldFeedback
:
'
La carpeta ya existe
'
,
title
:
'
Crear nueva carpeta
'
,
},
preview
:
{
title
:
'
Preview
'
,
},
properties
:
{
disk
:
'
Disk
'
,
modified
:
'
Modificado
'
,
name
:
'
Nombre
'
,
path
:
'
Path
'
,
size
:
'
Tamaño
'
,
title
:
'
Propiedades
'
,
type
:
'
Tipo
'
,
url
:
'
URL
'
,
access
:
'
Acceso
'
,
access_0
:
'
Access denied
'
,
access_1
:
'
Only Read
'
,
access_2
:
'
Read and Write
'
,
},
rename
:
{
directoryExist
:
'
Ya existe el directorio
'
,
fieldName
:
'
Nuevo nombre
'
,
fieldFeedback
:
'
Nombre invalido
'
,
fileExist
:
'
Ya existe el archivo
'
,
title
:
'
Renombrar
'
,
},
status
:
{
noErrors
:
'
No errors!
'
,
title
:
'
Status
'
,
},
upload
:
{
ifExist
:
'
Si el archivo ya existe:
'
,
noSelected
:
'
No has seleccionado nada!
'
,
overwrite
:
'
Sobreescribir
'
,
selected
:
'
Seleccionar:
'
,
size
:
'
Size:
'
,
skip
:
'
Omitir
'
,
title
:
'
Subir archivos
'
,
},
editor
:
{
title
:
'
Editor
'
,
},
audioPlayer
:
{
title
:
'
Audio player
'
,
},
videoPlayer
:
{
title
:
'
Video player
'
,
},
zip
:
{
title
:
'
Crear archivo
'
,
fieldName
:
'
Nombre del archivo
'
,
fieldFeedback
:
'
Ya existe!
'
,
},
unzip
:
{
title
:
'
Descomprimir
'
,
fieldName
:
'
Nombre del directorio
'
,
fieldRadioName
:
'
Extraer en:
'
,
fieldRadio1
:
'
Carpeta actual
'
,
fieldRadio2
:
'
Nueva carpeta
'
,
fieldFeedback
:
'
Carpeta existente!
'
,
warning
:
'
Attention! If the names match, the files will be overwritten!
'
,
},
cropper
:
{
title
:
'
Cropping
'
,
apply
:
'
Aceptar
'
,
reset
:
'
Reset
'
,
save
:
'
Guardar
'
,
},
},
notifications
:
{
cutToClipboard
:
'
Copiado!
'
,
copyToClipboard
:
'
Copiado!
'
,
},
// todo - need to translate
response
:
{
noConfig
:
'
Configuración no encontrada!
'
,
notFound
:
'
Extraviado!
'
,
diskNotFound
:
'
Disco no encontrado!
'
,
pathNotFound
:
'
Camino no encontrado!
'
,
diskSelected
:
'
Disco seleccionado!
'
,
// files
fileExist
:
'
El archivo ya existe!
'
,
fileCreated
:
'
Archivo creado!
'
,
fileUpdated
:
'
Archivo actualizado!
'
,
fileNotFound
:
'
Archivo no encontrado!
'
,
// directories
dirExist
:
'
El directorio ya existe!
'
,
dirCreated
:
'
Directorio creado!
'
,
dirNotFound
:
'
Directorio no encontrado
'
,
// actions
uploaded
:
'
Todos los archivos cargados!
'
,
notAllUploaded
:
'
Algunos archivos no fueron subidos!
'
,
delNotFound
:
'
Algunos artículos no fueron encontrados!
'
,
deleted
:
'
Eliminado!
'
,
renamed
:
'
Renombrado!
'
,
copied
:
'
Copiado exitosamente!
'
,
// zip
zipError
:
'
Error al crear archivo!
'
,
// acl
aclError
:
'
Acceso denegado!
'
,
},
};
export
default
es
;
tools/frontend/src/locales/lang/fa.js
0 → 100644
View file @
bae8cfdf
/**
* Farsi translate
* vahidalvandi
* @type Object
*/
const
fa
=
{
btn
:
{
about
:
'
درباره
'
,
back
:
'
عقب
'
,
cancel
:
'
لغو
'
,
clear
:
'
پاک کردن
'
,
copy
:
'
رونوشت
'
,
cut
:
'
برش
'
,
delete
:
'
حذف
'
,
edit
:
'
ویرایش
'
,
forward
:
'
ارسال به دیگری
'
,
folder
:
'
پوشه جدید
'
,
file
:
'
فایل جدید
'
,
fullScreen
:
'
تمام صفحه
'
,
grid
:
'
شبکه
'
,
paste
:
'
جانمایی/چسباندن/جاگذاری
'
,
refresh
:
'
تازه کردن صفحه
'
,
submit
:
'
تایید و ارسال
'
,
table
:
'
جدول
'
,
upload
:
'
بارگذاری
'
,
uploadSelect
:
'
انتخاب فایل
'
,
hidden
:
'
فایل های مخفی
'
,
},
clipboard
:
{
actionType
:
'
نوع
'
,
copy
:
'
رونوشت
'
,
cut
:
'
برش
'
,
none
:
'
چیزی انتخاب نشده است
'
,
title
:
'
کلیپ بورد
'
,
},
contextMenu
:
{
copy
:
'
رونوشت
'
,
cut
:
'
برش
'
,
delete
:
'
حذف
'
,
download
:
'
دانلود
'
,
info
:
'
انتخاب شده:
'
,
open
:
'
باز کردن
'
,
paste
:
'
جاگذاری
'
,
properties
:
'
ویژگی ها
'
,
rename
:
'
تغییر نام
'
,
select
:
'
انتخاب
'
,
view
:
'
مشاهده
'
,
zip
:
'
فشرده کردن
'
,
unzip
:
'
از حالت فشرده خارج کردن
'
,
edit
:
'
ویرایش
'
,
audioPlay
:
'
پخش
'
,
videoPlay
:
'
نمایش
'
,
},
info
:
{
directories
:
'
پوشه ها:
'
,
files
:
'
فایل ها:
'
,
selected
:
'
انتخاب شده ها:
'
,
selectedSize
:
'
اندازه فایل ها:
'
,
size
:
'
اندازه فایل ها:
'
,
},
manager
:
{
table
:
{
date
:
'
تاریخ
'
,
folder
:
'
پوشه
'
,
name
:
'
نام
'
,
size
:
'
اندازه
'
,
type
:
'
نوع
'
,
},
},
modal
:
{
about
:
{
developer
:
'
توسعه دهنده
'
,
name
:
'
مدیریت فایل
'
,
title
:
'
درباره
'
,
version
:
'
نسخه
'
,
},
delete
:
{
noSelected
:
'
چیزی انتخاب نشده است
'
,
title
:
'
حذف
'
,
},
newFile
:
{
fieldName
:
'
نام فایل
'
,
fieldFeedback
:
'
فایل وجود دارد!
'
,
title
:
'
فایل جدید ایجاد کنید
'
,
},
newFolder
:
{
fieldName
:
'
نام پوشه
'
,
fieldFeedback
:
'
پوشه وجود دارد!
'
,
title
:
'
پوشه جدید ایجاد کنید
'
,
},
preview
:
{
title
:
'
پیش نمایش
'
,
},
properties
:
{
disk
:
'
Disk
'
,
modified
:
'
اصلاح شده
'
,
name
:
'
نام
'
,
path
:
'
مسیر
'
,
size
:
'
اندازه
'
,
title
:
'
ویژگی ها
'
,
type
:
'
نوع
'
,
url
:
'
آدرس اینترنتی
'
,
access
:
'
دسترسی
'
,
access_0
:
'
دسترسی امکان پذیر نیست
'
,
access_1
:
'
فقط خواندن
'
,
access_2
:
'
خواندن و نوشتن
'
,
},
rename
:
{
directoryExist
:
'
فهرست وجود دارد
'
,
fieldName
:
'
نام جدید را وارد نمایید
'
,
fieldFeedback
:
'
نام نامعتبر است
'
,
fileExist
:
'
فایل وجود دارد
'
,
title
:
'
تغییر نام
'
,
},
status
:
{
noErrors
:
'
خطایی وجود ندارد!
'
,
title
:
'
وضعیت
'
,
},
upload
:
{
ifExist
:
'
اگر فایل وجود دارد:
'
,
noSelected
:
'
هیچ فایلی انتخاب نشده است!
'
,
overwrite
:
'
بازنویسی!
'
,
selected
:
'
انتخاب شده ها/انتخاب شده است:
'
,
size
:
'
اندازه:
'
,
skip
:
'
رد شدن
'
,
title
:
'
بارگزاری فایل ها
'
,
},
editor
:
{
title
:
'
ویرایشگر
'
,
},
audioPlayer
:
{
title
:
'
پخش کننده فایل صوتی
'
,
},
videoPlayer
:
{
title
:
'
نمایش دهنده ویدیو
'
,
},
zip
:
{
title
:
'
ایجاد بایگانی
'
,
fieldName
:
'
نام بایگانی
'
,
fieldFeedback
:
'
بایگانی وجود دارد
'
,
},
unzip
:
{
title
:
'
باز کردن بایگانی
'
,
fieldName
:
'
نام پوشه
'
,
fieldRadioName
:
'
استخراج شود به:
'
,
fieldRadio1
:
'
به پوشه فعلی
'
,
fieldRadio2
:
'
در یک پوشه جدید
'
,
fieldFeedback
:
'
پوشه وجود دارد!
'
,
warning
:
'
توجه! اگر نام ها تکراری باشند، فایل های قدیمی با فایل های جدید جایگزین خواهند شد
'
,
},
cropper
:
{
title
:
'
کوچک کردن
'
,
apply
:
'
اجرا
'
,
reset
:
'
تنظیم مجدد
'
,
save
:
'
ذخیره
'
,
},
},
notifications
:
{
cutToClipboard
:
'
برش یه کلیپ بورد!
'
,
copyToClipboard
:
'
رونوشت به کلیپ بورد!
'
,
},
response
:
{
noConfig
:
'
پیکربندی یافت نشد
'
,
notFound
:
'
یافت نشد
'
,
diskNotFound
:
'
دیسک یافت نشد !
'
,
pathNotFound
:
'
مسیر یافت نشد!
'
,
diskSelected
:
'
دیسک انتخاب شد !
'
,
// files
fileExist
:
'
در حال حاضر فایل مورد نظر وجود دارد!
'
,
fileCreated
:
'
فایل ایجاد شد!
'
,
fileUpdated
:
'
فایل بروزرسانی شد!
'
,
fileNotFound
:
'
فایل یافت نشد!
'
,
// directories
dirExist
:
'
در حال حاضر پیکربندی مورد نظر وجود دارد!
'
,
dirCreated
:
'
پیکربندی ایجاد شد!
'
,
dirNotFound
:
'
پیکربندی یافت نشد
'
,
// actions
uploaded
:
'
همه فایل ها بارگذاری شده اند!
'
,
notAllUploaded
:
'
برخی از فایل ها بارگذاری نشده اند!
'
,
delNotFound
:
'
برخی از بخش ها یافت نشد!
'
,
deleted
:
'
حذف شد!
'
,
renamed
:
'
تغییر نام یافت!
'
,
copied
:
'
رونوشت با موفقیت انجام شد!
'
,
// zip
zipError
:
'
خطای ایجاد بایگانی! zip
'
,
// acl
aclError
:
'
دسترسی امکان پذیر نیست!
'
,
},
};
export
default
fa
;
tools/frontend/src/locales/lang/fr.js
0 → 100644
View file @
bae8cfdf
/**
* French translate
* @type Object
*/
const
fr
=
{
btn
:
{
about
:
'
À propos
'
,
back
:
'
Retour
'
,
cancel
:
'
Annuler
'
,
clear
:
'
Effacer
'
,
copy
:
'
Copier
'
,
cut
:
'
Couper
'
,
delete
:
'
Supprimer
'
,
edit
:
'
Modifier
'
,
forward
:
'
Suivant
'
,
folder
:
'
Nouveau dossier
'
,
file
:
'
Nouveau fichier
'
,
fullScreen
:
'
Plein écran
'
,
grid
:
'
Grille
'
,
paste
:
'
Coller
'
,
refresh
:
'
Rafraîchir
'
,
submit
:
'
Envoyer
'
,
table
:
'
Tableau
'
,
upload
:
'
Télécharger
'
,
uploadSelect
:
'
Sélectionner fichiers
'
,
hidden
:
'
Masquer fichiers
'
,
},
clipboard
:
{
actionType
:
'
Type
'
,
copy
:
'
Copier
'
,
cut
:
'
Coller
'
,
none
:
'
Aucune sélection
'
,
title
:
'
Clipboard
'
,
},
contextMenu
:
{
copy
:
'
Copier
'
,
cut
:
'
Coller
'
,
delete
:
'
Supprimer
'
,
download
:
'
Télécharger
'
,
info
:
'
Sélectionné:
'
,
open
:
'
Ouvrir
'
,
paste
:
'
Coller
'
,
properties
:
'
Propriétés
'
,
rename
:
'
Renommer
'
,
select
:
'
Sélectionner
'
,
view
:
'
Voir
'
,
zip
:
'
Zipper
'
,
unzip
:
'
Dézipper
'
,
edit
:
'
Modifier
'
,
audioPlay
:
'
Lire
'
,
videoPlay
:
'
Lire
'
,
},
info
:
{
directories
:
'
Dossiers:
'
,
files
:
'
Fichiers:
'
,
selected
:
'
Sélectionné:
'
,
selectedSize
:
'
Taille fichiers:
'
,
size
:
'
Taille fichiers:
'
,
},
manager
:
{
table
:
{
date
:
'
Date
'
,
folder
:
'
Dossier
'
,
name
:
'
Nom
'
,
size
:
'
Taille
'
,
type
:
'
Type
'
,
},
},
modal
:
{
about
:
{
developer
:
'
Développeur
'
,
name
:
'
Laravel File Manager
'
,
title
:
'
À propos
'
,
version
:
'
Version
'
,
},
delete
:
{
noSelected
:
'
Aucune sélection!
'
,
title
:
'
Supprimer
'
,
},
newFile
:
{
fieldName
:
'
Nom du fichier
'
,
fieldFeedback
:
'
Ce fichier existe!
'
,
title
:
'
Créer un fichier
'
,
},
newFolder
:
{
fieldName
:
'
Nom du dossier
'
,
fieldFeedback
:
'
Ce dossier existe!
'
,
title
:
'
Créer un dossier
'
,
},
preview
:
{
title
:
'
Prévisualisation
'
,
},
properties
:
{
disk
:
'
Disque
'
,
modified
:
'
Modifié
'
,
name
:
'
Nom
'
,
path
:
'
Chemin
'
,
size
:
'
Taille
'
,
title
:
'
Propriétés
'
,
type
:
'
Type
'
,
url
:
'
URL
'
,
access
:
'
Accès
'
,
access_0
:
'
Accès refusé
'
,
access_1
:
'
Lecture seul
'
,
access_2
:
'
Lecture/écriture
'
,
},
rename
:
{
directoryExist
:
'
Dossier existant
'
,
fieldName
:
'
Entrer un nom
'
,
fieldFeedback
:
'
Nom invalide
'
,
fileExist
:
'
Fichier existant
'
,
title
:
'
Renommer
'
,
},
status
:
{
noErrors
:
'
Aucune erreurs!
'
,
title
:
'
Statut
'
,
},
upload
:
{
ifExist
:
'
Si le fichier existe:
'
,
noSelected
:
'
Aucun fichier sélectionné!
'
,
overwrite
:
'
Écraser!
'
,
selected
:
'
Sélectionné:
'
,
size
:
'
Taille:
'
,
skip
:
'
Passer
'
,
title
:
'
Télécharger fichiers
'
,
},
editor
:
{
title
:
'
Editeur
'
,
},
audioPlayer
:
{
title
:
'
Lecteur audio
'
,
},
videoPlayer
:
{
title
:
'
Lecteur video
'
,
},
zip
:
{
title
:
'
Créer une archive
'
,
fieldName
:
'
Nom archive
'
,
fieldFeedback
:
'
Archive existante!
'
,
},
unzip
:
{
title
:
'
Extraite l
\'
archive
'
,
fieldName
:
'
Nom du dossier
'
,
fieldRadioName
:
'
Extraire vers:
'
,
fieldRadio1
:
'
Dossier actuel
'
,
fieldRadio2
:
'
Dans un nouveau dossier
'
,
fieldFeedback
:
'
Dossier existant!
'
,
warning
:
'
Attention! Si le nom correspond, les fichiers seront écrasés!
'
,
},
cropper
:
{
title
:
'
Recadrer
'
,
apply
:
'
Appliquer
'
,
reset
:
'
Réinitialisé
'
,
save
:
'
Sauvegarder
'
,
},
},
notifications
:
{
cutToClipboard
:
'
Coller dans le presse-papier!
'
,
copyToClipboard
:
'
Copied dans le presse-papier!
'
,
},
response
:
{
noConfig
:
'
Configuration introuvable!
'
,
notFound
:
'
Introuvable!
'
,
diskNotFound
:
'
Disque introuvable!
'
,
pathNotFound
:
'
Chemin introuvable!
'
,
diskSelected
:
'
Disque sélectionné!
'
,
// files
fileExist
:
'
Fichier existant!
'
,
fileCreated
:
'
Fichier créé!
'
,
fileUpdated
:
'
Fichier téléchargé!
'
,
fileNotFound
:
'
Fichier introuvable!
'
,
// directories
dirExist
:
'
Dossier existant!
'
,
dirCreated
:
'
Dossier créé!
'
,
dirNotFound
:
'
Dossier introuvable
'
,
// actions
uploaded
:
'
Tous les fichiers ont été téléchargés!
'
,
notAllUploaded
:
'
Certains fichiers n
\'
ont pas été téléchargés!
'
,
delNotFound
:
'
Certains éléments n
\'
ont pas été trouvés!
'
,
deleted
:
'
Supprimé!
'
,
renamed
:
'
Renommé!
'
,
copied
:
'
Copié!
'
,
// zip
zipError
:
'
Erreur dans la création de l
\'
archive!
'
,
// acl
aclError
:
'
Accès refusé!
'
,
},
};
export
default
fr
;
tools/frontend/src/locales/lang/it.js
0 → 100644
View file @
bae8cfdf
/**
* Italian translate
* Ezio
* @type Object
*/
const
it
=
{
btn
:
{
about
:
'
Informazioni
'
,
back
:
'
Indietro
'
,
cancel
:
'
Annulla
'
,
clear
:
'
Pulisci
'
,
copy
:
'
Copia
'
,
cut
:
'
Taglia
'
,
delete
:
'
Elimina
'
,
edit
:
'
Modifica
'
,
forward
:
'
Inoltra
'
,
folder
:
'
Nuova Cartella
'
,
file
:
'
Nuovo File
'
,
fullScreen
:
'
Visualizzazione a schermo intero
'
,
grid
:
'
Griglia
'
,
paste
:
'
Incolla
'
,
refresh
:
'
Ricarica
'
,
submit
:
'
Conferma
'
,
table
:
'
Tabella
'
,
upload
:
'
Upload
'
,
uploadSelect
:
'
Seleziona files
'
,
hidden
:
'
Files Nascosti
'
,
},
clipboard
:
{
actionType
:
'
Tipo
'
,
copy
:
'
Copia
'
,
cut
:
'
Taglia
'
,
none
:
'
Nessun elemento selezionato
'
,
title
:
'
Appunti
'
,
},
contextMenu
:
{
copy
:
'
Copia
'
,
cut
:
'
Taglia
'
,
delete
:
'
Elimina
'
,
download
:
'
Scarica
'
,
info
:
'
Selezionati:
'
,
open
:
'
Apri
'
,
paste
:
'
Incolla
'
,
properties
:
'
Proprietà
'
,
rename
:
'
Rinomina
'
,
select
:
'
Seleziona
'
,
view
:
'
Anteprima
'
,
zip
:
'
Zip
'
,
unzip
:
'
Estrai zip
'
,
edit
:
'
Modifica
'
,
audioPlay
:
'
Play
'
,
videoPlay
:
'
Play
'
,
},
info
:
{
directories
:
'
Cartelle:
'
,
files
:
'
Files:
'
,
selected
:
'
Selezionati:
'
,
selectedSize
:
'
Dimensione files:
'
,
size
:
'
Dimensione files:
'
,
},
manager
:
{
table
:
{
date
:
'
Data
'
,
folder
:
'
Cartella
'
,
name
:
'
Nome
'
,
size
:
'
Dim.
'
,
type
:
'
Tipo
'
,
},
},
modal
:
{
about
:
{
developer
:
'
Developer
'
,
name
:
'
Laravel File Manager
'
,
title
:
'
Informazioni
'
,
version
:
'
Versione
'
,
},
delete
:
{
noSelected
:
'
Nessuna selezione!
'
,
title
:
'
Elimina
'
,
},
newFile
:
{
fieldName
:
'
Nome del file
'
,
fieldFeedback
:
'
Il file esiste!
'
,
title
:
'
Crea nuovo file
'
,
},
newFolder
:
{
fieldName
:
'
Nome cartella
'
,
fieldFeedback
:
'
La cartella esiste!
'
,
title
:
'
Crea nuova cartella
'
,
},
preview
:
{
title
:
'
Anteprima
'
,
},
properties
:
{
disk
:
'
Disco
'
,
modified
:
'
Mod.
'
,
name
:
'
Nome
'
,
path
:
'
Percorso
'
,
size
:
'
Dim.
'
,
title
:
'
Proprietà
'
,
type
:
'
Tipo
'
,
url
:
'
URL
'
,
access
:
'
Accesso
'
,
access_0
:
'
Accesso negato
'
,
access_1
:
'
Sola lettura
'
,
access_2
:
'
Lettura e Scrittura
'
,
},
rename
:
{
directoryExist
:
'
La cartella esiste
'
,
fieldName
:
'
Inserisci il nome
'
,
fieldFeedback
:
'
Nome non valido
'
,
fileExist
:
'
Il file esiste
'
,
title
:
'
Rinomina
'
,
},
status
:
{
noErrors
:
'
Nessun errore!
'
,
title
:
'
Stato
'
,
},
upload
:
{
ifExist
:
'
Il file esiste:
'
,
noSelected
:
'
Nessun files selezionato!
'
,
overwrite
:
'
Sovrascrivi!
'
,
selected
:
'
Selezionato:
'
,
size
:
'
Dim.:
'
,
skip
:
'
Salta
'
,
title
:
'
Carica files
'
,
},
editor
:
{
title
:
'
Editor
'
,
},
audioPlayer
:
{
title
:
'
Player Audio
'
,
},
videoPlayer
:
{
title
:
'
Player Video
'
,
},
zip
:
{
title
:
'
Crea Archivio
'
,
fieldName
:
'
Nome Archivio
'
,
fieldFeedback
:
'
Archivio esistente!
'
,
},
unzip
:
{
title
:
'
Estrai archivio
'
,
fieldName
:
'
Nom cartella
'
,
fieldRadioName
:
'
Estrai in:
'
,
fieldRadio1
:
'
Nella cartella corrente
'
,
fieldRadio2
:
'
In una nuova cartella
'
,
fieldFeedback
:
'
Cartella esistente!
'
,
warning
:
'
Attenzione! se i nomi dei file coincidono i file presenti verranno sovrascritti!
'
,
},
cropper
:
{
title
:
'
Ritaglia
'
,
apply
:
'
Applica
'
,
reset
:
'
Reset
'
,
save
:
'
Salva
'
,
},
},
notifications
:
{
cutToClipboard
:
'
Tagliato e salvato negli appunti!
'
,
copyToClipboard
:
'
Copiato negli appunti!
'
,
},
response
:
{
noConfig
:
'
File di configuraizone non trovato!
'
,
notFound
:
'
Non trovato!
'
,
diskNotFound
:
'
Disco non trovato!
'
,
pathNotFound
:
'
Cartella non trovata!
'
,
diskSelected
:
'
Disco selezionato!
'
,
// files
fileExist
:
'
File già esistente!
'
,
fileCreated
:
'
File creato!
'
,
fileUpdated
:
'
File caricato!
'
,
fileNotFound
:
'
File non trovato!
'
,
// directories
dirExist
:
'
La cartella è già presente!
'
,
dirCreated
:
'
Cartella creata!
'
,
dirNotFound
:
'
Cartella non trovata
'
,
// actions
uploaded
:
'
Tutti i file sono stati caricati!
'
,
notAllUploaded
:
'
Alcuni file NON sono stati caricati!
'
,
delNotFound
:
'
Alcuni elementi NON sono stati trovati!
'
,
deleted
:
'
Eliminato!
'
,
renamed
:
'
Rinominato!
'
,
copied
:
'
Copiato con successo!
'
,
// zip
zipError
:
"
Errore dirante la creazione dell'archivio!
"
,
// acl
aclError
:
'
Accesso negato!
'
,
},
};
export
default
it
;
tools/frontend/src/locales/lang/nl.js
0 → 100644
View file @
bae8cfdf
/**
* Dutch (Netherlands) translate
* Laurens - https://github.com/Laussii078
* @type Object
*/
const
nl
=
{
// todo - need to translate
btn
:
{
about
:
'
About
'
,
back
:
'
Back
'
,
cancel
:
'
Cancel
'
,
clear
:
'
Clear
'
,
copy
:
'
Copy
'
,
cut
:
'
Cut
'
,
delete
:
'
Delete
'
,
edit
:
'
Edit
'
,
forward
:
'
Forward
'
,
folder
:
'
New folder
'
,
file
:
'
New file
'
,
fullScreen
:
'
Full screen
'
,
grid
:
'
Grid
'
,
paste
:
'
Paste
'
,
refresh
:
'
Refresh
'
,
submit
:
'
Submit
'
,
table
:
'
Table
'
,
upload
:
'
Upload
'
,
uploadSelect
:
'
Select files
'
,
hidden
:
'
Verborgen bestanden
'
,
},
clipboard
:
{
actionType
:
'
Type
'
,
copy
:
'
Copy
'
,
cut
:
'
Cut
'
,
none
:
'
Nothing selected
'
,
title
:
'
Clipboard
'
,
},
contextMenu
:
{
copy
:
'
Copy
'
,
cut
:
'
Cut
'
,
delete
:
'
Delete
'
,
download
:
'
Download
'
,
info
:
'
Selected:
'
,
open
:
'
Open
'
,
paste
:
'
Paste
'
,
properties
:
'
Properties
'
,
rename
:
'
Rename
'
,
select
:
'
Select
'
,
view
:
'
View
'
,
zip
:
'
Zip
'
,
unzip
:
'
Unzip
'
,
edit
:
'
Edit
'
,
audioPlay
:
'
Play
'
,
videoPlay
:
'
Play
'
,
},
info
:
{
directories
:
'
Folders:
'
,
files
:
'
Files:
'
,
selected
:
'
Selected:
'
,
selectedSize
:
'
Files size:
'
,
size
:
'
Files size:
'
,
},
manager
:
{
table
:
{
date
:
'
Date
'
,
folder
:
'
Folder
'
,
name
:
'
Name
'
,
size
:
'
Size
'
,
type
:
'
Type
'
,
},
},
modal
:
{
about
:
{
developer
:
'
Developer
'
,
name
:
'
Laravel File Manager
'
,
title
:
'
About
'
,
version
:
'
Version
'
,
},
delete
:
{
noSelected
:
'
Nothing selected!
'
,
title
:
'
Delete
'
,
},
newFile
:
{
fieldName
:
'
File name
'
,
fieldFeedback
:
'
File exists!
'
,
title
:
'
Create new file
'
,
},
newFolder
:
{
fieldName
:
'
Folder name
'
,
fieldFeedback
:
'
Folder exists!
'
,
title
:
'
Create new folder
'
,
},
preview
:
{
title
:
'
Preview
'
,
},
properties
:
{
disk
:
'
Disk
'
,
modified
:
'
Modified
'
,
name
:
'
Name
'
,
path
:
'
Path
'
,
size
:
'
Size
'
,
title
:
'
Properties
'
,
type
:
'
Type
'
,
url
:
'
URL
'
,
access
:
'
Access
'
,
access_0
:
'
Access denied
'
,
access_1
:
'
Only Read
'
,
access_2
:
'
Read and Write
'
,
},
rename
:
{
directoryExist
:
'
Directory exists
'
,
fieldName
:
'
Enter new name
'
,
fieldFeedback
:
'
Invalid name
'
,
fileExist
:
'
File exists
'
,
title
:
'
Rename
'
,
},
status
:
{
noErrors
:
'
No errors!
'
,
title
:
'
Status
'
,
},
upload
:
{
ifExist
:
'
If file exist:
'
,
noSelected
:
'
No files selected!
'
,
overwrite
:
'
Overwrite!
'
,
selected
:
'
Selected:
'
,
size
:
'
Size:
'
,
skip
:
'
Skip
'
,
title
:
'
Upload files
'
,
},
editor
:
{
title
:
'
Editor
'
,
},
audioPlayer
:
{
title
:
'
Audio player
'
,
},
videoPlayer
:
{
title
:
'
Video player
'
,
},
zip
:
{
title
:
'
Create archive
'
,
fieldName
:
'
Archive name
'
,
fieldFeedback
:
'
Archive exists!
'
,
},
unzip
:
{
title
:
'
Unpack archive
'
,
fieldName
:
'
Folder name
'
,
fieldRadioName
:
'
Extract to:
'
,
fieldRadio1
:
'
To current folder
'
,
fieldRadio2
:
'
In a new folder
'
,
fieldFeedback
:
'
Folder exists!
'
,
warning
:
'
Attention! If the names match, the files will be overwritten!
'
,
},
cropper
:
{
title
:
'
Cropping
'
,
apply
:
'
Apply
'
,
reset
:
'
Reset
'
,
save
:
'
Save
'
,
},
},
notifications
:
{
cutToClipboard
:
'
Cut to clipboard!
'
,
copyToClipboard
:
'
Copied to clipboard!
'
,
},
// todo - need to translate - end
response
:
{
noConfig
:
'
Config niet gevonden!
'
,
notFound
:
'
Niet gevonden!
'
,
diskNotFound
:
'
Schijf niet gevonden!
'
,
pathNotFound
:
'
Pad niet gevonden!
'
,
diskSelected
:
'
Schijf geselecteerd!
'
,
// files
fileExist
:
'
Bestand bestaat al!
'
,
fileCreated
:
'
Bestand aangemaakt!
'
,
fileUpdated
:
'
Bestand bijgewerkt!
'
,
fileNotFound
:
'
Bestand niet gevonden!
'
,
// directories
dirExist
:
'
Folder bestaat al!
'
,
dirCreated
:
'
Folder aangemaakt!
'
,
dirNotFound
:
'
Folder niet gevonden
'
,
// actions
uploaded
:
'
Alle bestanden geüpload!
'
,
notAllUploaded
:
'
Sommige bestanden zijn niet geüpload!
'
,
delNotFound
:
'
Sommige bestanden konden niet worden gevonden!
'
,
deleted
:
'
Verwijderd!
'
,
renamed
:
'
Hernoemd!
'
,
copied
:
'
Succesvol gekopieerd!
'
,
// zip
zipError
:
'
Fout bij het maken van archief!
'
,
// acl
aclError
:
'
Toegang geweigerd!
'
,
},
};
export
default
nl
;
tools/frontend/src/locales/lang/pl.js
0 → 100644
View file @
bae8cfdf
/**
* Polish
* @type Object
*/
const
pl
=
{
btn
:
{
about
:
'
O Programie
'
,
back
:
'
Wstecz
'
,
cancel
:
'
Anuluj
'
,
clear
:
'
Wyczyść
'
,
copy
:
'
Kopiuj
'
,
cut
:
'
Wytnij
'
,
delete
:
'
Usuń
'
,
edit
:
'
Edycja
'
,
forward
:
'
Do przodu
'
,
folder
:
'
Nowy folder
'
,
file
:
'
Nowy plik
'
,
fullScreen
:
'
Pełny ekran
'
,
grid
:
'
Siatka
'
,
paste
:
'
Wklej
'
,
refresh
:
'
Odśwież
'
,
submit
:
'
Zatwierdź
'
,
table
:
'
Tabela
'
,
upload
:
'
Wyślij plik
'
,
uploadSelect
:
'
Wybierz pliki
'
,
hidden
:
'
Ukryte pliki
'
,
},
clipboard
:
{
actionType
:
'
Rodzaj
'
,
copy
:
'
Kopiuj
'
,
cut
:
'
Przytnij
'
,
none
:
'
Nic nie zostało zaznaczone
'
,
title
:
'
Schowek
'
,
},
contextMenu
:
{
copy
:
'
Kopiuj
'
,
cut
:
'
Przytnij
'
,
delete
:
'
Usuń
'
,
download
:
'
Pobierz
'
,
info
:
'
Wybrano:
'
,
open
:
'
Otwórz
'
,
paste
:
'
Wklej
'
,
properties
:
'
Właściwości
'
,
rename
:
'
Zmień nazwę
'
,
select
:
'
Wybierz
'
,
view
:
'
Widok
'
,
zip
:
'
Spakuj
'
,
unzip
:
'
Rozpakuj
'
,
edit
:
'
Edycja
'
,
audioPlay
:
'
Odtwórz
'
,
videoPlay
:
'
Odtwórz
'
,
},
info
:
{
directories
:
'
Katalogi
'
,
files
:
'
Pliki:
'
,
selected
:
'
Wybrany:
'
,
selectedSize
:
'
Rozmiar plików:
'
,
size
:
'
Rozmiar plików:
'
,
},
manager
:
{
table
:
{
date
:
'
Data
'
,
folder
:
'
Folder
'
,
name
:
'
Nazwa
'
,
size
:
'
Rozmiar
'
,
type
:
'
Rodzaj
'
,
},
},
modal
:
{
about
:
{
developer
:
'
Deweloper
'
,
name
:
'
Menedżer plików
'
,
title
:
'
O
'
,
version
:
'
Wersja
'
,
},
delete
:
{
noSelected
:
'
Nic nie zostało zaznaczone!
'
,
title
:
'
Usuń
'
,
},
newFile
:
{
fieldName
:
'
Nazwa pliku
'
,
fieldFeedback
:
'
Plik istnieje!
'
,
title
:
'
Utwórz nowy plik
'
,
},
newFolder
:
{
fieldName
:
'
Nazwa folderu
'
,
fieldFeedback
:
'
Katalog istnieje!
'
,
title
:
'
Stwórz nowy folder
'
,
},
preview
:
{
title
:
'
Podgląd
'
,
},
properties
:
{
disk
:
'
Dysk
'
,
modified
:
'
Zmodyfikowano
'
,
name
:
'
Nazwa
'
,
path
:
'
Ścieżka
'
,
size
:
'
Rozmiar
'
,
title
:
'
Właściwości
'
,
type
:
'
Rodzaj
'
,
url
:
'
URL
'
,
access
:
'
Dostęp
'
,
access_0
:
'
Brak dostępu
'
,
access_1
:
'
Tylko do odczytu
'
,
access_2
:
'
Odczyt i zapis
'
,
},
rename
:
{
directoryExist
:
'
Katalog istnieje
'
,
fieldName
:
'
Wpisz nową nazwę
'
,
fieldFeedback
:
'
Błędna nazwa
'
,
fileExist
:
'
Plik istnieje
'
,
title
:
'
Zmień nazwę
'
,
},
status
:
{
noErrors
:
'
Bez błędów!
'
,
title
:
'
Status
'
,
},
upload
:
{
ifExist
:
'
Jeśli plik istnieje:
'
,
noSelected
:
'
Nie wybrano plików!
'
,
overwrite
:
'
Nadpisz
'
,
selected
:
'
Wybrano:
'
,
size
:
'
Rozmiar:
'
,
skip
:
'
Pomiń
'
,
title
:
'
Prześlij pliki
'
,
},
editor
:
{
title
:
'
Edytor
'
,
},
audioPlayer
:
{
title
:
'
Odtwarzacz muzyki
'
,
},
videoPlayer
:
{
title
:
'
Odtwarzacz wideo
'
,
},
zip
:
{
title
:
'
Utwórz archiwum
'
,
fieldName
:
'
Nazwa archiwum
'
,
fieldFeedback
:
'
Archiwum istnieje!
'
,
},
unzip
:
{
title
:
'
Rozpakuj archiwum
'
,
fieldName
:
'
Nazwa folderu
'
,
fieldRadioName
:
'
Wypakować do:
'
,
fieldRadio1
:
'
Do bieżącego folderu
'
,
fieldRadio2
:
'
W nowym folderze
'
,
fieldFeedback
:
'
Katalog istnieje!
'
,
warning
:
'
Uwaga! Przy identycznej nazwie, pliki zostaną nadpisane!
'
,
},
cropper
:
{
title
:
'
Przycinanie
'
,
apply
:
'
Zastosuj
'
,
reset
:
'
Reset
'
,
save
:
'
Zapisz
'
,
},
},
notifications
:
{
cutToClipboard
:
'
Wytnij do schowka!
'
,
copyToClipboard
:
'
Skopiowane do schowka!
'
,
},
response
:
{
noConfig
:
'
Nie znaleziono konfiguracji!
'
,
notFound
:
'
Nie znaleziono!
'
,
diskNotFound
:
'
Nie znaleziono dysku!
'
,
pathNotFound
:
'
Ścieżka nie znaleziona!
'
,
diskSelected
:
'
Dysk wybrany!
'
,
// files
fileExist
:
'
Plik już istnieje!
'
,
fileCreated
:
'
Plik utworzony!
'
,
fileUpdated
:
'
Plik zaktualizowany!
'
,
fileNotFound
:
'
Nie znaleziono pliku!
'
,
// directories
dirExist
:
'
Katalog już istnieje!
'
,
dirCreated
:
'
Katalog utworzony!
'
,
dirNotFound
:
'
Nie znaleziono katalogu
'
,
// actions
uploaded
:
'
Przesłano wszystkie pliki!
'
,
notAllUploaded
:
'
Niektóre pliki nie zostały przesłane!
'
,
delNotFound
:
'
Niektóre pozycje nie zostały znalezione!
'
,
deleted
:
'
Usunięto!
'
,
renamed
:
'
Zmieniono nazwę!
'
,
copied
:
'
Skopiowano pomyślnie!
'
,
// zip
zipError
:
'
Błąd podczas tworzenia archiwum!
'
,
// acl
aclError
:
'
Brak dostępu!
'
,
},
};
export
default
pl
;
tools/frontend/src/locales/lang/pt_BR.js
0 → 100644
View file @
bae8cfdf
/**
* Portuguese Brazilian translate
* @type Object
*/
/* eslint camelcase: 0 */
const
pt_BR
=
{
btn
:
{
about
:
'
Sobre
'
,
back
:
'
Voltar
'
,
cancel
:
'
Cancelar
'
,
clear
:
'
Limpar
'
,
copy
:
'
Copiar
'
,
cut
:
'
Recortar
'
,
delete
:
'
Apagar
'
,
edit
:
'
Editar
'
,
forward
:
'
Avançar
'
,
folder
:
'
Nova pasta
'
,
file
:
'
Novo arquivo
'
,
fullScreen
:
'
Tela cheia
'
,
grid
:
'
Grade
'
,
paste
:
'
Colar
'
,
refresh
:
'
Atualizar
'
,
submit
:
'
Criar
'
,
table
:
'
Tabela
'
,
upload
:
'
Upload
'
,
uploadSelect
:
'
Selecionar arquivos
'
,
hidden
:
'
Arquivos ocultos
'
,
},
clipboard
:
{
actionType
:
'
Formato
'
,
copy
:
'
Copiar
'
,
cut
:
'
Recortar
'
,
none
:
'
Nada selecionado
'
,
title
:
'
Área de transferência
'
,
},
contextMenu
:
{
copy
:
'
Copiar
'
,
cut
:
'
Colar
'
,
delete
:
'
Apagar
'
,
download
:
'
Download
'
,
info
:
'
Selecionado:
'
,
open
:
'
Abrir
'
,
paste
:
'
Colar
'
,
properties
:
'
Propriedades
'
,
rename
:
'
Renomear
'
,
select
:
'
Selecionar
'
,
view
:
'
Visualizar
'
,
zip
:
'
Compactar
'
,
unzip
:
'
Descompactar
'
,
edit
:
'
Editar
'
,
audioPlay
:
'
Play
'
,
videoPlay
:
'
Play
'
,
},
info
:
{
directories
:
'
Pastas:
'
,
files
:
'
Arquivos:
'
,
selected
:
'
Selecionado:
'
,
selectedSize
:
'
Tamanho dos arquivos:
'
,
size
:
'
Tamanho dos arquivos:
'
,
},
manager
:
{
table
:
{
date
:
'
Data
'
,
folder
:
'
Pasta
'
,
name
:
'
Nome
'
,
size
:
'
Tamanho
'
,
type
:
'
Tipo
'
,
},
},
modal
:
{
about
:
{
developer
:
'
Desenvolvedor
'
,
name
:
'
Laravel File Manager
'
,
title
:
'
Sobre
'
,
version
:
'
Versão
'
,
},
delete
:
{
noSelected
:
'
Nada selecionado!
'
,
title
:
'
Apagar
'
,
},
newFile
:
{
fieldName
:
'
Nome do arquivo
'
,
fieldFeedback
:
'
Arquivo existente!
'
,
title
:
'
Criar novo arquivo
'
,
},
newFolder
:
{
fieldName
:
'
Nome da pasta
'
,
fieldFeedback
:
'
Pasta existente!
'
,
title
:
'
Criar nova pasta
'
,
},
preview
:
{
title
:
'
Visualizar
'
,
},
properties
:
{
disk
:
'
Disco
'
,
modified
:
'
Modificado
'
,
name
:
'
Nome
'
,
path
:
'
Caminho
'
,
size
:
'
Tamanho
'
,
title
:
'
Propriedades
'
,
type
:
'
Tipo
'
,
url
:
'
URL
'
,
access
:
'
Acesso
'
,
access_0
:
'
Acesso negado
'
,
access_1
:
'
Apenas leitura
'
,
access_2
:
'
Leitura e escrita
'
,
},
rename
:
{
directoryExist
:
'
Pasta existente
'
,
fieldName
:
'
Digite o novo nome
'
,
fieldFeedback
:
'
Nome inválido
'
,
fileExist
:
'
Arquivo existente
'
,
title
:
'
Renomear
'
,
},
status
:
{
noErrors
:
'
Nenhum erro!
'
,
title
:
'
Status
'
,
},
upload
:
{
ifExist
:
'
Se arquivo não existir:
'
,
noSelected
:
'
Nenhum arquivo selecionado!
'
,
overwrite
:
'
Substituir!
'
,
selected
:
'
Selecionado:
'
,
size
:
'
Tamanho:
'
,
skip
:
'
Pular
'
,
title
:
'
Upload de arquivos
'
,
},
editor
:
{
title
:
'
Editor
'
,
},
audioPlayer
:
{
title
:
'
Áudio player
'
,
},
videoPlayer
:
{
title
:
'
Video player
'
,
},
zip
:
{
title
:
'
Compactar arquivo
'
,
fieldName
:
'
Nome do arquivo
'
,
fieldFeedback
:
'
Arquivo existente!
'
,
},
unzip
:
{
title
:
'
Descompactar arquivo
'
,
fieldName
:
'
Nome da pasta
'
,
fieldRadioName
:
'
Extrair para:
'
,
fieldRadio1
:
'
Pasta atual
'
,
fieldRadio2
:
'
Nova pasta
'
,
fieldFeedback
:
'
Pasta existente!
'
,
warning
:
'
Atenção! Se os nomes forem idênticos, os arquivos serão substituídos!
'
,
},
cropper
:
{
title
:
'
Cortar
'
,
apply
:
'
Aplicar
'
,
reset
:
'
Resetar
'
,
save
:
'
Salvar
'
,
},
},
notifications
:
{
cutToClipboard
:
'
Recortado para área de transferência!
'
,
copyToClipboard
:
'
Copiado para área de transferência!
'
,
},
response
:
{
noConfig
:
'
Configuração não encontrada!
'
,
notFound
:
'
Não encontrado!
'
,
diskNotFound
:
'
Disco não encontrado!
'
,
pathNotFound
:
'
Caminho não encontrado!
'
,
diskSelected
:
'
Disco selecionado!
'
,
// files
fileExist
:
'
Arquivo já existe!
'
,
fileCreated
:
'
Arquivo criado!
'
,
fileUpdated
:
'
Arquivo atualizado!
'
,
fileNotFound
:
'
Arquivo não encontrado!
'
,
// directories
dirExist
:
'
Pasta já existe!
'
,
dirCreated
:
'
Pasta criada!
'
,
dirNotFound
:
'
Pasta não encontrada
'
,
// actions
uploaded
:
'
Todos os arquivo realizarm o upload!
'
,
notAllUploaded
:
'
Alguns arquivos não realizaram o upload!
'
,
delNotFound
:
'
Alguns itens não foram encontrados!
'
,
deleted
:
'
Deletado!
'
,
renamed
:
'
Renomeado!
'
,
copied
:
'
Copiado com sucesso!
'
,
// zip
zipError
:
'
Erro ao compactar!
'
,
// acl
aclError
:
'
Acesso negado!
'
,
},
};
export
default
pt_BR
;
tools/frontend/src/locales/lang/ru.js
0 → 100644
View file @
bae8cfdf
/**
* Russian translate
* @type Object
*/
const
ru
=
{
btn
:
{
about
:
'
О программе
'
,
back
:
'
Назад
'
,
cancel
:
'
Отменить
'
,
clear
:
'
Очистить
'
,
copy
:
'
Копировать
'
,
cut
:
'
Вырезать
'
,
delete
:
'
Удалить
'
,
edit
:
'
Редактировать
'
,
forward
:
'
Вперед
'
,
folder
:
'
Новая папка
'
,
file
:
'
Новый файл
'
,
fullScreen
:
'
На весь экран
'
,
grid
:
'
Сетка
'
,
paste
:
'
Вставить
'
,
refresh
:
'
Обновить
'
,
submit
:
'
Отправить
'
,
table
:
'
Таблица
'
,
upload
:
'
Загрузить
'
,
uploadSelect
:
'
Выбрать файлы
'
,
hidden
:
'
Скрытые файлы
'
,
},
clipboard
:
{
actionType
:
'
Тип операции
'
,
copy
:
'
Копировать
'
,
cut
:
'
Вырезать
'
,
none
:
'
Ничего не выбрано
'
,
title
:
'
Буфер обмена
'
,
},
contextMenu
:
{
copy
:
'
Копировать
'
,
cut
:
'
Вырезать
'
,
delete
:
'
Удалить
'
,
download
:
'
Скачать
'
,
info
:
'
Выбрано:
'
,
open
:
'
Открыть
'
,
paste
:
'
Вставить
'
,
properties
:
'
Свойства
'
,
rename
:
'
Переименовать
'
,
select
:
'
Выбрать
'
,
view
:
'
Просмотр
'
,
zip
:
'
Архивировать
'
,
unzip
:
'
Разархивировать
'
,
edit
:
'
Редактировать
'
,
audioPlay
:
'
Воспроизвести
'
,
videoPlay
:
'
Воспроизвести
'
,
},
info
:
{
directories
:
'
Папок:
'
,
files
:
'
Файлов:
'
,
selected
:
'
Выбрано:
'
,
selectedSize
:
'
Размер:
'
,
size
:
'
Размер файлов:
'
,
},
manager
:
{
table
:
{
date
:
'
Дата
'
,
folder
:
'
Папка
'
,
name
:
'
Имя
'
,
size
:
'
Размер
'
,
type
:
'
Тип
'
,
},
},
modal
:
{
about
:
{
developer
:
'
Разработчик
'
,
name
:
'
Laravel File Manager
'
,
title
:
'
О программе
'
,
version
:
'
Версия
'
,
},
delete
:
{
noSelected
:
'
Ничего не выбрано!
'
,
title
:
'
Удалить
'
,
},
newFile
:
{
fieldName
:
'
Имя файла
'
,
fieldFeedback
:
'
Такой файл уже существует!
'
,
title
:
'
Создать новый файл
'
,
},
newFolder
:
{
fieldName
:
'
Имя папки
'
,
fieldFeedback
:
'
Такакя папка уже существует!
'
,
title
:
'
Создать новую папку
'
,
},
preview
:
{
title
:
'
Предпросмотр
'
,
},
properties
:
{
disk
:
'
Диск
'
,
modified
:
'
Изменен
'
,
name
:
'
Имя
'
,
path
:
'
Путь
'
,
size
:
'
Размер
'
,
title
:
'
Свойства
'
,
type
:
'
Тип
'
,
url
:
'
URL
'
,
access
:
'
Доступ
'
,
access_0
:
'
Нет доступа
'
,
access_1
:
'
Только чтение
'
,
access_2
:
'
Чтение и Запись
'
,
},
rename
:
{
directoryExist
:
'
Папка существует
'
,
fieldName
:
'
Введите новое имя
'
,
fieldFeedback
:
'
Некорректное имя
'
,
fileExist
:
'
Файл существует
'
,
title
:
'
Переименовать
'
,
},
status
:
{
noErrors
:
'
Ошибок нет!
'
,
title
:
'
Состояние
'
,
},
upload
:
{
ifExist
:
'
Если файл существует:
'
,
noSelected
:
'
Ни одного файла не выбрано!
'
,
overwrite
:
'
Перезаписать!
'
,
selected
:
'
Выбрано:
'
,
size
:
'
Размер:
'
,
skip
:
'
Пропустить
'
,
title
:
'
Загрузить файлы
'
,
},
editor
:
{
title
:
'
Редактор
'
,
},
audioPlayer
:
{
title
:
'
Аудиоплеер
'
,
},
videoPlayer
:
{
title
:
'
Видеоплеер
'
,
},
zip
:
{
title
:
'
Создать архив
'
,
fieldName
:
'
Имя архива
'
,
fieldFeedback
:
'
Такой файл уже существует!
'
,
},
unzip
:
{
title
:
'
Распаковать архив
'
,
fieldName
:
'
Имя папки
'
,
fieldRadioName
:
'
Извлечь в:
'
,
fieldRadio1
:
'
В текущую папку
'
,
fieldRadio2
:
'
В новую папку
'
,
fieldFeedback
:
'
Папка существует!
'
,
warning
:
'
Внимание! При совпадении имен файлы будут перезаписаны!
'
,
},
cropper
:
{
title
:
'
Обрезка
'
,
apply
:
'
Применить
'
,
reset
:
'
Сбросить
'
,
save
:
'
Сохранить
'
,
},
},
notifications
:
{
cutToClipboard
:
'
Вырезано!
'
,
copyToClipboard
:
'
Скопировано!
'
,
},
response
:
{
noConfig
:
'
Конфигурация не найдена!
'
,
notFound
:
'
Не найдено!
'
,
diskNotFound
:
'
Диск не найден!
'
,
pathNotFound
:
'
Путь не существует!
'
,
diskSelected
:
'
Диск выбран!
'
,
// files
fileExist
:
'
Файл существует!
'
,
fileCreated
:
'
Файл создан!
'
,
fileUpdated
:
'
Файл обновлен!
'
,
fileNotFound
:
'
Файл не найден!
'
,
// directories
dirExist
:
'
Директория существует!
'
,
dirCreated
:
'
Директория создана!
'
,
dirNotFound
:
'
Директория не найдена
'
,
// actions
uploaded
:
'
Все файлы загружены!
'
,
notAllUploaded
:
'
Не все файлы загружены!
'
,
delNotFound
:
'
Не все элементы найдены!
'
,
deleted
:
'
Удалено!
'
,
renamed
:
'
Переименовано!
'
,
copied
:
'
Скопировано!
'
,
// zip
zipError
:
'
Ошибка создания архива!
'
,
// acl
aclError
:
'
В доступе отказано!
'
,
},
};
export
default
ru
;
tools/frontend/src/locales/lang/sr.js
0 → 100644
View file @
bae8cfdf
/**
* Serbian translate
* Aleksandar Stevanović - aleks989
* @type Object
*/
const
sr
=
{
btn
:
{
about
:
'
O Nama
'
,
back
:
'
Nazad
'
,
cancel
:
'
Otkaži
'
,
clear
:
'
Očisti
'
,
copy
:
'
Kopiraj
'
,
cut
:
'
Iseci
'
,
delete
:
'
Obriši
'
,
edit
:
'
Izmeni
'
,
forward
:
'
Napred
'
,
folder
:
'
Novi direktorijum
'
,
file
:
'
Nova datoteka
'
,
fullScreen
:
'
Ceo ekran
'
,
grid
:
'
Mrežasti prikaz
'
,
paste
:
'
Nalepi
'
,
refresh
:
'
Osveži
'
,
submit
:
'
Potvrdi
'
,
table
:
'
Tabela
'
,
upload
:
'
Upload
'
,
uploadSelect
:
'
Izaberi datoteke
'
,
hidden
:
'
Skrivene datoteke
'
,
},
clipboard
:
{
actionType
:
'
Tip operacije
'
,
copy
:
'
Kopiraj
'
,
cut
:
'
Iseci
'
,
none
:
'
Ništa niste izabrali!
'
,
title
:
'
Clipboard
'
,
},
contextMenu
:
{
copy
:
'
Kopiraj
'
,
cut
:
'
Iseci
'
,
delete
:
'
Obriši
'
,
download
:
'
Preuzimanje
'
,
info
:
'
Izabrano:
'
,
open
:
'
Otvori
'
,
paste
:
'
Nalepi
'
,
properties
:
'
Svojstva
'
,
rename
:
'
Preimenuj
'
,
select
:
'
Izaberi
'
,
view
:
'
Pregledaj
'
,
zip
:
'
Arhiviraj
'
,
unzip
:
'
Izbaci iz arhive
'
,
edit
:
'
Izmeni
'
,
audioPlay
:
'
Reprodukuj
'
,
videoPlay
:
'
Reprodukuj
'
,
},
info
:
{
directories
:
'
Direktorijumi:
'
,
files
:
'
Datoteke:
'
,
selected
:
'
Izabrano:
'
,
selectedSize
:
'
Veličina fajla:
'
,
size
:
'
Veličina fajla:
'
,
},
manager
:
{
table
:
{
date
:
'
Datum
'
,
folder
:
'
Datoteka
'
,
name
:
'
Naziv
'
,
size
:
'
Veličina
'
,
type
:
'
Vrsta
'
,
},
},
modal
:
{
about
:
{
developer
:
'
Razvio
'
,
name
:
'
Laravel File Manager
'
,
title
:
'
O Nama
'
,
version
:
'
Verzija
'
,
},
delete
:
{
noSelected
:
'
Ništa niste izabrali!
'
,
title
:
'
Obriši
'
,
},
newFile
:
{
fieldName
:
'
Naziv datoteke
'
,
fieldFeedback
:
'
Datoteka već postoji!
'
,
title
:
'
Kreiraj novu datoteku
'
,
},
newFolder
:
{
fieldName
:
'
Naziv direktorijuma
'
,
fieldFeedback
:
'
Direktorijum već postoji!
'
,
title
:
'
Kreiraj novi direktorijum
'
,
},
preview
:
{
title
:
'
Pregled
'
,
},
properties
:
{
disk
:
'
Disk
'
,
modified
:
'
Izmenjen
'
,
name
:
'
Naziv
'
,
path
:
'
Lokacija
'
,
size
:
'
Veličina
'
,
title
:
'
Svojstva
'
,
type
:
'
Tip datoteke
'
,
url
:
'
URL
'
,
access
:
'
Pristup
'
,
access_0
:
'
Pristup odbijen
'
,
access_1
:
'
Samo za čitanje
'
,
access_2
:
'
Pristup za čitanje i pisanje
'
,
},
rename
:
{
directoryExist
:
'
Direktorijum postoji
'
,
fieldName
:
'
Unesite novi naziv
'
,
fieldFeedback
:
'
Neispravan naziv
'
,
fileExist
:
'
Datoteka već postoji
'
,
title
:
'
Preimenuj
'
,
},
status
:
{
noErrors
:
'
Nema Grešaka!
'
,
title
:
'
Status
'
,
},
upload
:
{
ifExist
:
'
Ako datoteka postoji:
'
,
noSelected
:
'
Nema izabranih fajlova!
'
,
overwrite
:
'
Zameni!
'
,
selected
:
'
Izabrano:
'
,
size
:
'
Veličina:
'
,
skip
:
'
Preskoči
'
,
title
:
'
DOdaj fajlove
'
,
},
editor
:
{
title
:
'
Editor
'
,
},
audioPlayer
:
{
title
:
'
Audio plejer
'
,
},
videoPlayer
:
{
title
:
'
Video plejer
'
,
},
zip
:
{
title
:
'
Napravi arhivu
'
,
fieldName
:
'
Naziv Arhive
'
,
fieldFeedback
:
'
Arhiva Postoji!
'
,
},
unzip
:
{
title
:
'
Otpakuj arhivu
'
,
fieldName
:
'
Naziv direktorijuma
'
,
fieldRadioName
:
'
Otpakuj u:
'
,
fieldRadio1
:
'
U aktivni direktorijum
'
,
fieldRadio2
:
'
U novi direktorijum
'
,
fieldFeedback
:
'
Direktorijum Postoji!
'
,
warning
:
'
Pažnja! Ako se nazivi poklapaju, datoteke će biti prepisane!
'
,
},
cropper
:
{
title
:
'
Orezivanje
'
,
apply
:
'
Primeni
'
,
reset
:
'
Resetuj
'
,
save
:
'
Sačuvaj
'
,
},
},
notifications
:
{
cutToClipboard
:
'
Isečeno u klipbord!
'
,
copyToClipboard
:
'
Kopirano u klipbord!
'
,
},
response
:
{
noConfig
:
'
Nema konfiguracije!
'
,
notFound
:
'
Nije pronađeno!
'
,
diskNotFound
:
'
Disk nije pronađen!
'
,
pathNotFound
:
'
Putanja nije pronađena!
'
,
diskSelected
:
'
Disk izabran!
'
,
// files
fileExist
:
'
Datoteka već postoji!
'
,
fileCreated
:
'
Nova datoteka napravljena!
'
,
fileUpdated
:
'
Datoteka izmenjena!
'
,
fileNotFound
:
'
Datoteka nije pronadjena!
'
,
// directories
dirExist
:
'
Direktorijum već postoji!
'
,
dirCreated
:
'
Novi direktorijum napravljen!
'
,
dirNotFound
:
'
Direktorijum nije pronađen
'
,
// actions
uploaded
:
'
Sve datoteke poslate!
'
,
notAllUploaded
:
'
Some files weren
\'
t uploaded!
'
,
delNotFound
:
'
Nekoliko stavki nije pronađeno! Osvežite!
'
,
deleted
:
'
Obrisano!
'
,
renamed
:
'
Preimenovano!
'
,
copied
:
'
Uspešno kopirano!
'
,
// zip
zipError
:
'
Greška u pravljenju arhive!
'
,
// acl
aclError
:
'
Pristup odbijen!
'
,
},
};
export
default
sr
;
tools/frontend/src/locales/lang/tr.js
0 → 100644
View file @
bae8cfdf
/**
* Turkish translate
* @type Object
*/
const
tr
=
{
btn
:
{
about
:
'
Hakkında
'
,
back
:
'
Geri
'
,
cancel
:
'
İptal
'
,
clear
:
'
Temizle
'
,
copy
:
'
Kopyala
'
,
cut
:
'
Kes
'
,
delete
:
'
Sil
'
,
edit
:
'
Düzenle
'
,
forward
:
'
İleri
'
,
folder
:
'
Yeni klasör
'
,
file
:
'
Yeni dosya
'
,
fullScreen
:
'
Tam ekran
'
,
grid
:
'
Izgara
'
,
paste
:
'
Yapıştır
'
,
refresh
:
'
Yenile
'
,
submit
:
'
Gönder
'
,
table
:
'
Tablo
'
,
upload
:
'
Yükle
'
,
uploadSelect
:
'
Dosyaları seç
'
,
hidden
:
'
Gizli dosyalar
'
,
},
clipboard
:
{
actionType
:
'
İşlem türü
'
,
copy
:
'
Kopyala
'
,
cut
:
'
Yapıştır
'
,
none
:
'
Hiç bir şey seçilmedi
'
,
title
:
'
Pano
'
,
},
contextMenu
:
{
copy
:
'
Kopyala
'
,
cut
:
'
Yapıştır
'
,
delete
:
'
Sil
'
,
download
:
'
İndir
'
,
info
:
'
Seçilenler:
'
,
open
:
'
Aç
'
,
paste
:
'
Yapıştır
'
,
properties
:
'
Özellikler
'
,
rename
:
'
Yeniden adlandır
'
,
select
:
'
Seç
'
,
view
:
'
Gör
'
,
zip
:
'
Zip
'
,
unzip
:
'
Zip aç
'
,
edit
:
'
Düzenle
'
,
audioPlay
:
'
Oynat
'
,
videoPlay
:
'
Oynat
'
,
},
info
:
{
directories
:
'
Klasörler:
'
,
files
:
'
Dosyalar:
'
,
selected
:
'
Seçilenler:
'
,
selectedSize
:
'
Dosyaların boyutu:
'
,
size
:
'
Dosyaların boyutu:
'
,
},
manager
:
{
table
:
{
date
:
'
Tarih
'
,
folder
:
'
Klasör
'
,
name
:
'
İsim
'
,
size
:
'
Boyut
'
,
type
:
'
Tür
'
,
},
},
modal
:
{
about
:
{
developer
:
'
Geliştirici
'
,
name
:
'
Laravel File Manager
'
,
title
:
'
Hakkında
'
,
version
:
'
Sürüm
'
,
},
delete
:
{
noSelected
:
'
Hiç bir şey seçilmedi!
'
,
title
:
'
Sil
'
,
},
newFile
:
{
fieldName
:
'
Dosya adı
'
,
fieldFeedback
:
'
Aynı isimli dosya var!
'
,
title
:
'
Yeni dosya yarat
'
,
},
newFolder
:
{
fieldName
:
'
Klasör adı
'
,
fieldFeedback
:
'
Aynı isimli klasör var!
'
,
title
:
'
Yeni klasör yarat
'
,
},
preview
:
{
title
:
'
Önizleme
'
,
},
properties
:
{
disk
:
'
Disk
'
,
modified
:
'
Değiştirilme
'
,
name
:
'
İsim
'
,
path
:
'
Yol
'
,
size
:
'
Boyut
'
,
title
:
'
Özellikler
'
,
type
:
'
Tür
'
,
url
:
'
URL
'
,
access
:
'
Erişim
'
,
access_0
:
'
Erişim engellendi
'
,
access_1
:
'
Salt okunur
'
,
access_2
:
'
Okuma ve yazma
'
,
},
rename
:
{
directoryExist
:
'
Klasör mevcut
'
,
fieldName
:
'
Yeni isim girin
'
,
fieldFeedback
:
'
Geçersiz isim
'
,
fileExist
:
'
Dosya mevcut
'
,
title
:
'
Yeniden adlandır
'
,
},
status
:
{
noErrors
:
'
Hata yok!
'
,
title
:
'
Durum
'
,
},
upload
:
{
ifExist
:
'
Eğer dosya mevcutsa:
'
,
noSelected
:
'
Hiç bir dosya seçilmedi!
'
,
overwrite
:
'
Üzerine yaz!
'
,
selected
:
'
Seçilen:
'
,
size
:
'
Boyut:
'
,
skip
:
'
Atla
'
,
title
:
'
Dosyaları yükle
'
,
},
editor
:
{
title
:
'
Editör
'
,
},
audioPlayer
:
{
title
:
'
Ses oynatıcı
'
,
},
videoPlayer
:
{
title
:
'
Video oynatıcı
'
,
},
zip
:
{
title
:
'
Arşiv yarat
'
,
fieldName
:
'
Arşiv adı
'
,
fieldFeedback
:
'
Arşiv mevcut!
'
,
},
unzip
:
{
title
:
'
Arşivi aç
'
,
fieldName
:
'
Klasör adı
'
,
fieldRadioName
:
'
Hedef:
'
,
fieldRadio1
:
'
Şu anki klasör
'
,
fieldRadio2
:
'
Yeni klasör
'
,
fieldFeedback
:
'
Klasör mevcut!
'
,
warning
:
'
Dikkat! Eğer dosya isimleri aynı olursa, üzerine yazılacak!
'
,
},
cropper
:
{
title
:
'
Kırpma
'
,
apply
:
'
Uygula
'
,
reset
:
'
Sıfırla
'
,
save
:
'
Kaydet
'
,
},
},
notifications
:
{
cutToClipboard
:
'
Panoya kesildi!
'
,
copyToClipboard
:
'
Panoya kopyalandı!
'
,
},
response
:
{
noConfig
:
'
Ayarlar bulunamadı!
'
,
notFound
:
'
Bulunamadı!
'
,
diskNotFound
:
'
Disk bulunamadı!
'
,
pathNotFound
:
'
Yol bulunamadı!
'
,
diskSelected
:
'
Disk seçildi!
'
,
// files
fileExist
:
'
Dosya zaten var!
'
,
fileCreated
:
'
Dosya yaratıldı!
'
,
fileUpdated
:
'
Dosya güncellendi!
'
,
fileNotFound
:
'
Dosya bulunamadı!
'
,
// directories
dirExist
:
'
Klasör zaten var!
'
,
dirCreated
:
'
Klasör yaratıldı!
'
,
dirNotFound
:
'
Klasör bulunamadı
'
,
// actions
uploaded
:
'
Tüm dosyalar yüklendi!
'
,
notAllUploaded
:
'
Bazı dosyalar yüklenemedi!
'
,
delNotFound
:
'
Bazı öğeler bulunamadı!
'
,
deleted
:
'
Silindi!
'
,
renamed
:
'
Yeniden adlandırıldı!
'
,
copied
:
'
Başarıyla kopyalandı!
'
,
// zip
zipError
:
'
Arşiv yaratılırken hata oluştu!
'
,
// acl
aclError
:
'
Erişim engellendi!
'
,
},
};
export
default
tr
;
tools/frontend/src/locales/lang/zh_CN.js
0 → 100644
View file @
bae8cfdf
/**
* zh_CN translate
* osindex - https://github.com/osindex
* @type Object
*/
/* eslint camelcase: 0 */
const
zh_CN
=
{
btn
:
{
about
:
'
关于
'
,
back
:
'
返回
'
,
cancel
:
'
取消
'
,
clear
:
'
清除
'
,
copy
:
'
复制
'
,
cut
:
'
剪切
'
,
delete
:
'
删除
'
,
edit
:
'
编辑
'
,
forward
:
'
前进
'
,
folder
:
'
创建目录
'
,
file
:
'
创建文件
'
,
fullScreen
:
'
全屏
'
,
grid
:
'
网格
'
,
paste
:
'
粘贴
'
,
refresh
:
'
刷新
'
,
submit
:
'
提交
'
,
table
:
'
表格
'
,
upload
:
'
上传
'
,
uploadSelect
:
'
选择文件
'
,
hidden
:
'
隐藏文件
'
,
},
clipboard
:
{
actionType
:
'
类型
'
,
copy
:
'
复制
'
,
cut
:
'
剪切
'
,
none
:
'
未选中文件
'
,
title
:
'
剪切板
'
,
},
contextMenu
:
{
copy
:
'
复制
'
,
cut
:
'
剪切
'
,
delete
:
'
删除
'
,
download
:
'
下载
'
,
info
:
'
选择:
'
,
open
:
'
打开
'
,
paste
:
'
粘贴
'
,
properties
:
'
属性
'
,
rename
:
'
重命名
'
,
select
:
'
选择
'
,
view
:
'
查看
'
,
zip
:
'
压缩
'
,
unzip
:
'
解压
'
,
edit
:
'
编辑
'
,
audioPlay
:
'
播放
'
,
videoPlay
:
'
播放
'
,
},
info
:
{
directories
:
'
目录:
'
,
files
:
'
文件:
'
,
selected
:
'
已选择:
'
,
selectedSize
:
'
已选择文件大小:
'
,
size
:
'
文件大小:
'
,
},
manager
:
{
table
:
{
date
:
'
日期
'
,
folder
:
'
目录
'
,
name
:
'
名称
'
,
size
:
'
大小
'
,
type
:
'
类型
'
,
},
},
modal
:
{
about
:
{
developer
:
'
开发者信息
'
,
name
:
'
文件管理页
'
,
title
:
'
关于
'
,
version
:
'
版本
'
,
},
delete
:
{
noSelected
:
'
暂无选中!
'
,
title
:
'
删除
'
,
},
newFile
:
{
fieldName
:
'
文件名
'
,
fieldFeedback
:
'
文件已存在!
'
,
title
:
'
创建文件
'
,
},
newFolder
:
{
fieldName
:
'
目录名
'
,
fieldFeedback
:
'
目录已存在!
'
,
title
:
'
创建目录
'
,
},
preview
:
{
title
:
'
预览
'
,
},
properties
:
{
disk
:
'
模块
'
,
modified
:
'
时间
'
,
name
:
'
名称
'
,
path
:
'
路径
'
,
size
:
'
大小
'
,
title
:
'
属性
'
,
type
:
'
类型
'
,
url
:
'
网址
'
,
access
:
'
授权
'
,
access_0
:
'
禁止访问
'
,
access_1
:
'
只读
'
,
access_2
:
'
读写
'
,
},
rename
:
{
directoryExist
:
'
目录存在
'
,
fieldName
:
'
输入名称
'
,
fieldFeedback
:
'
名称不可用
'
,
fileExist
:
'
文件存在
'
,
title
:
'
重命名
'
,
},
status
:
{
noErrors
:
'
暂无错误!
'
,
title
:
'
状态
'
,
},
upload
:
{
ifExist
:
'
如果文件存在:
'
,
noSelected
:
'
暂无选中!
'
,
overwrite
:
'
覆盖
'
,
selected
:
'
已选择:
'
,
size
:
'
大小:
'
,
skip
:
'
忽略
'
,
title
:
'
上传文件
'
,
},
editor
:
{
title
:
'
编辑
'
,
},
audioPlayer
:
{
title
:
'
播放音频
'
,
},
videoPlayer
:
{
title
:
'
播放视频
'
,
},
zip
:
{
title
:
'
归档文件
'
,
fieldName
:
'
归档名称
'
,
fieldFeedback
:
'
文件存在!
'
,
},
unzip
:
{
title
:
'
解压
'
,
fieldName
:
'
目录名称
'
,
fieldRadioName
:
'
解压到:
'
,
fieldRadio1
:
'
当前目录
'
,
fieldRadio2
:
'
输入目录
'
,
fieldFeedback
:
'
目录存在!
'
,
warning
:
'
注意!如果文件存在将会被覆盖!
'
,
},
cropper
:
{
title
:
'
裁剪
'
,
apply
:
'
应用
'
,
reset
:
'
重置
'
,
save
:
'
保存
'
,
},
},
notifications
:
{
cutToClipboard
:
'
剪切到粘贴板!
'
,
copyToClipboard
:
'
复制到粘贴板!
'
,
},
// todo - need to translate
response
:
{
noConfig
:
'
Config not found!
'
,
notFound
:
'
Not found!
'
,
diskNotFound
:
'
Disk not found!
'
,
pathNotFound
:
'
Path not found!
'
,
diskSelected
:
'
Disk selected!
'
,
// files
fileExist
:
'
File already exists!
'
,
fileCreated
:
'
File created!
'
,
fileUpdated
:
'
File updated!
'
,
fileNotFound
:
'
File not found!
'
,
// directories
dirExist
:
'
Directory already exists!
'
,
dirCreated
:
'
Directory created!
'
,
dirNotFound
:
'
Directory not found
'
,
// actions
uploaded
:
'
All files uploaded!
'
,
notAllUploaded
:
'
Some files weren
\'
t uploaded!
'
,
delNotFound
:
'
Some items weren
\'
t founded!
'
,
deleted
:
'
Deleted!
'
,
renamed
:
'
Renamed!
'
,
copied
:
'
Copied successfully!
'
,
// zip
zipError
:
'
Error creating archive!
'
,
// acl
aclError
:
'
Access denied!
'
,
},
};
export
default
zh_CN
;
tools/frontend/src/locales/lang/zh_TW.js
0 → 100644
View file @
bae8cfdf
/**
* zh_TW translate
* @type Object
*/
/* eslint camelcase: 0 */
const
zh_TW
=
{
btn
:
{
about
:
'
關於
'
,
back
:
'
返回
'
,
cancel
:
'
取消
'
,
clear
:
'
清除
'
,
copy
:
'
複製
'
,
cut
:
'
剪下
'
,
delete
:
'
刪除
'
,
edit
:
'
編輯
'
,
forward
:
'
前進
'
,
folder
:
'
新增目錄
'
,
file
:
'
新增文件
'
,
fullScreen
:
'
全螢幕
'
,
grid
:
'
網格
'
,
paste
:
'
貼上
'
,
refresh
:
'
重新整理
'
,
submit
:
'
送出
'
,
table
:
'
表格
'
,
upload
:
'
上傳
'
,
uploadSelect
:
'
選擇文件
'
,
hidden
:
'
隱藏文件
'
,
},
clipboard
:
{
actionType
:
'
類型
'
,
copy
:
'
複製
'
,
cut
:
'
剪下
'
,
none
:
'
未選取
'
,
title
:
'
剪貼簿
'
,
},
contextMenu
:
{
copy
:
'
複製
'
,
cut
:
'
剪下
'
,
delete
:
'
刪除
'
,
download
:
'
下載
'
,
info
:
'
選擇:
'
,
open
:
'
打開
'
,
paste
:
'
貼上
'
,
properties
:
'
屬性
'
,
rename
:
'
重新命名
'
,
select
:
'
選擇
'
,
view
:
'
查看
'
,
zip
:
'
壓縮
'
,
unzip
:
'
解壓縮
'
,
edit
:
'
編輯
'
,
audioPlay
:
'
播放
'
,
videoPlay
:
'
播放
'
,
},
info
:
{
directories
:
'
目錄:
'
,
files
:
'
文件:
'
,
selected
:
'
已選擇:
'
,
selectedSize
:
'
已選擇文件大小:
'
,
size
:
'
文件大小:
'
,
},
manager
:
{
table
:
{
date
:
'
日期
'
,
folder
:
'
目錄
'
,
name
:
'
名稱
'
,
size
:
'
大小
'
,
type
:
'
類型
'
,
},
},
modal
:
{
about
:
{
developer
:
'
開發者資訊
'
,
name
:
'
文件管理頁
'
,
title
:
'
關於
'
,
version
:
'
版本
'
,
},
delete
:
{
noSelected
:
'
暫無選中!
'
,
title
:
'
刪除
'
,
},
newFile
:
{
fieldName
:
'
文件名
'
,
fieldFeedback
:
'
文件已存在!
'
,
title
:
'
新增文件
'
,
},
newFolder
:
{
fieldName
:
'
目錄名
'
,
fieldFeedback
:
'
目錄已存在!
'
,
title
:
'
新增目錄
'
,
},
preview
:
{
title
:
'
預覽
'
,
},
properties
:
{
disk
:
'
磁碟
'
,
modified
:
'
時間
'
,
name
:
'
名稱
'
,
path
:
'
路徑
'
,
size
:
'
大小
'
,
title
:
'
屬性
'
,
type
:
'
類型
'
,
url
:
'
網址
'
,
access
:
'
授權
'
,
access_0
:
'
禁止訪問
'
,
access_1
:
'
唯獨
'
,
access_2
:
'
讀寫
'
,
},
rename
:
{
directoryExist
:
'
目錄存在
'
,
fieldName
:
'
輸入名稱
'
,
fieldFeedback
:
'
名稱不可用
'
,
fileExist
:
'
文件存在
'
,
title
:
'
重命名
'
,
},
status
:
{
noErrors
:
'
暫無錯誤!
'
,
title
:
'
狀態
'
,
},
upload
:
{
ifExist
:
'
如果文件存在:
'
,
noSelected
:
'
暫無選中!
'
,
overwrite
:
'
覆蓋
'
,
selected
:
'
已選擇:
'
,
size
:
'
大小:
'
,
skip
:
'
忽略
'
,
title
:
'
上傳文件
'
,
},
editor
:
{
title
:
'
編輯
'
,
},
audioPlayer
:
{
title
:
'
播放音樂
'
,
},
videoPlayer
:
{
title
:
'
播放影片
'
,
},
zip
:
{
title
:
'
壓縮文件
'
,
fieldName
:
'
壓縮名稱
'
,
fieldFeedback
:
'
文件存在!
'
,
},
unzip
:
{
title
:
'
解壓縮
'
,
fieldName
:
'
目錄名稱
'
,
fieldRadioName
:
'
解壓到:
'
,
fieldRadio1
:
'
當前目錄
'
,
fieldRadio2
:
'
輸入目錄
'
,
fieldFeedback
:
'
目錄存在!
'
,
warning
:
'
注意!如果文件存在將會被覆蓋!
'
,
},
cropper
:
{
title
:
'
裁剪
'
,
apply
:
'
套用
'
,
reset
:
'
重設
'
,
save
:
'
儲存
'
,
},
},
notifications
:
{
cutToClipboard
:
'
剪下到剪貼簿!
'
,
copyToClipboard
:
'
複製到剪貼簿!
'
,
},
response
:
{
noConfig
:
'
找不到設定檔!
'
,
notFound
:
'
找不到項目!
'
,
diskNotFound
:
'
找不到磁碟!
'
,
pathNotFound
:
'
找不到路徑!
'
,
diskSelected
:
'
磁碟已選取!
'
,
// files
fileExist
:
'
文件已存在!
'
,
fileCreated
:
'
文件已建立!
'
,
fileUpdated
:
'
文件已更新!
'
,
fileNotFound
:
'
找不到文件!
'
,
// directories
dirExist
:
'
目錄已存在!
'
,
dirCreated
:
'
目錄已存在!
'
,
dirNotFound
:
'
找不到目錄
'
,
// actions
uploaded
:
'
全部文件已上傳完畢!
'
,
notAllUploaded
:
'
部分文件未上傳!
'
,
delNotFound
:
'
部分項目未被找到!
'
,
deleted
:
'
已刪除!
'
,
renamed
:
'
已重新命名!
'
,
copied
:
'
已複製完成!
'
,
// zip
zipError
:
'
壓縮檔建立失敗!
'
,
// acl
aclError
:
'
存取拒絕!
'
,
},
};
export
default
zh_TW
;
tools/frontend/src/store/file-manager.js
0 → 100644
View file @
bae8cfdf
// store modules
import
tree
from
'
./file-manager/tree/store
'
;
import
modal
from
'
./file-manager/modal/store
'
;
import
settings
from
'
./file-manager/settings/store
'
;
import
manager
from
'
./file-manager/manager/store
'
;
import
messages
from
'
./file-manager/messages/store
'
;
// main store
import
state
from
'
./file-manager/state
'
;
import
mutations
from
'
./file-manager/mutations
'
;
import
getters
from
'
./file-manager/getters
'
;
import
actions
from
'
./file-manager/actions
'
;
export
default
{
namespaced
:
true
,
modules
:
{
settings
,
left
:
manager
,
right
:
manager
,
tree
,
modal
,
messages
,
},
state
,
mutations
,
actions
,
getters
,
};
tools/frontend/src/store/file-manager/actions.js
0 → 100644
View file @
bae8cfdf
/* eslint-disable max-len,prefer-destructuring,object-curly-newline */
import
GET
from
'
../../utils/get
'
;
import
POST
from
'
../../utils/post
'
;
export
default
{
/**
* Get initiation data from server
* @param state
* @param commit
* @param getters
* @param dispatch
*/
initializeApp
({
state
,
commit
,
getters
,
dispatch
})
{
GET
.
initialize
().
then
((
response
)
=>
{
if
(
response
.
data
.
result
.
status
===
'
success
'
)
{
commit
(
'
settings/initSettings
'
,
response
.
data
.
config
);
commit
(
'
setDisks
'
,
response
.
data
.
config
.
disks
);
let
leftDisk
=
response
.
data
.
config
.
leftDisk
?
response
.
data
.
config
.
leftDisk
:
getters
.
diskList
[
0
];
let
rightDisk
=
response
.
data
.
config
.
rightDisk
?
response
.
data
.
config
.
rightDisk
:
getters
.
diskList
[
0
];
// paths
let
leftPath
=
response
.
data
.
config
.
leftPath
;
let
rightPath
=
response
.
data
.
config
.
rightPath
;
// find disk and path settings in the URL
if
(
window
.
location
.
search
)
{
const
params
=
new
URLSearchParams
(
window
.
location
.
search
);
if
(
params
.
get
(
'
leftDisk
'
))
{
leftDisk
=
params
.
get
(
'
leftDisk
'
);
}
if
(
params
.
get
(
'
rightDisk
'
))
{
rightDisk
=
params
.
get
(
'
rightDisk
'
);
}
if
(
params
.
get
(
'
leftPath
'
))
{
leftPath
=
params
.
get
(
'
leftPath
'
);
}
if
(
params
.
get
(
'
rightPath
'
))
{
rightPath
=
params
.
get
(
'
rightPath
'
);
}
}
commit
(
'
left/setDisk
'
,
leftDisk
);
// if leftPath not null
if
(
leftPath
)
{
commit
(
'
left/setSelectedDirectory
'
,
leftPath
);
commit
(
'
left/addToHistory
'
,
leftPath
);
}
dispatch
(
'
getLoadContent
'
,
{
manager
:
'
left
'
,
disk
:
leftDisk
,
path
:
leftPath
,
});
// if selected left and right managers
if
(
state
.
settings
.
windowsConfig
===
3
)
{
commit
(
'
right/setDisk
'
,
rightDisk
);
// if rightPath not null
if
(
rightPath
)
{
commit
(
'
right/setSelectedDirectory
'
,
rightPath
);
commit
(
'
right/addToHistory
'
,
rightPath
);
}
dispatch
(
'
getLoadContent
'
,
{
manager
:
'
right
'
,
disk
:
rightDisk
,
path
:
rightPath
,
});
}
else
if
(
state
.
settings
.
windowsConfig
===
2
)
{
// if selected left manager and directories tree
// init directories tree
dispatch
(
'
tree/initTree
'
,
leftDisk
).
then
(()
=>
{
if
(
leftPath
)
{
// reopen folders if path not null
dispatch
(
'
tree/reopenPath
'
,
leftPath
);
}
});
}
}
});
},
/**
* Download files and folders to the selected file manager
* @param context
* @param manager
* @param disk
* @param path
*/
getLoadContent
(
context
,
{
manager
,
disk
,
path
})
{
GET
.
content
(
disk
,
path
).
then
((
response
)
=>
{
if
(
response
.
data
.
result
.
status
===
'
success
'
)
{
context
.
commit
(
`
${
manager
}
/setDirectoryContent`
,
response
.
data
);
}
});
},
/**
* Select disk
* @param state
* @param commit
* @param dispatch
* @param disk
* @param manager
*/
selectDisk
({
state
,
commit
,
dispatch
},
{
disk
,
manager
})
{
GET
.
selectDisk
(
disk
).
then
((
response
)
=>
{
// if disk exist => change disk
if
(
response
.
data
.
result
.
status
===
'
success
'
)
{
// set disk name
commit
(
`
${
manager
}
/setDisk`
,
disk
);
// reset history
commit
(
`
${
manager
}
/resetHistory`
);
// reinitialize tree if directories tree is shown
if
(
state
.
settings
.
windowsConfig
===
2
)
{
dispatch
(
'
tree/initTree
'
,
disk
);
}
// download content for root path
dispatch
(
`
${
manager
}
/selectDirectory`
,
{
path
:
null
,
history
:
false
});
}
});
},
/**
* Create new file
* @param getters
* @param dispatch
* @param fileName
* @returns {Promise}
*/
createFile
({
getters
,
dispatch
},
fileName
)
{
// directory for new file
const
selectedDirectory
=
getters
.
selectedDirectory
;
// create new file, server side
return
POST
.
createFile
(
getters
.
selectedDisk
,
selectedDirectory
,
fileName
)
.
then
((
response
)
=>
{
// update file list
dispatch
(
'
updateContent
'
,
{
response
,
oldDir
:
selectedDirectory
,
commitName
:
'
addNewFile
'
,
type
:
'
file
'
,
});
return
response
;
});
},
/**
* Get file content
* @param context
* @param disk
* @param path
* @returns {*}
*/
getFile
(
context
,
{
disk
,
path
})
{
return
GET
.
getFile
(
disk
,
path
);
},
/**
* Update file
* @param getters
* @param dispatch
* @param formData
* @returns {PromiseLike | Promise}
*/
updateFile
({
getters
,
dispatch
},
formData
)
{
return
POST
.
updateFile
(
formData
).
then
((
response
)
=>
{
// update file list
dispatch
(
'
updateContent
'
,
{
response
,
oldDir
:
getters
.
selectedDirectory
,
commitName
:
'
updateFile
'
,
type
:
'
file
'
,
});
return
response
;
});
},
/**
* Create new directory
* @param getters
* @param dispatch
* @param name
* @returns {*|PromiseLike<T | never>|Promise<T | never>}
*/
createDirectory
({
getters
,
dispatch
},
name
)
{
// directory for new folder
const
selectedDirectory
=
getters
.
selectedDirectory
;
// create new directory, server side
return
POST
.
createDirectory
({
disk
:
getters
.
selectedDisk
,
path
:
selectedDirectory
,
name
,
}).
then
((
response
)
=>
{
// update file list
dispatch
(
'
updateContent
'
,
{
response
,
oldDir
:
selectedDirectory
,
commitName
:
'
addNewDirectory
'
,
type
:
'
directory
'
,
});
return
response
;
});
},
/**
* Upload file or files
* @param getters
* @param commit
* @param dispatch
* @param files
* @param overwrite
* @returns {Promise}
*/
upload
({
getters
,
commit
,
dispatch
},
{
files
,
overwrite
})
{
// directory where files will be uploaded
const
selectedDirectory
=
getters
.
selectedDirectory
;
// create new form data
const
data
=
new
FormData
();
data
.
append
(
'
disk
'
,
getters
.
selectedDisk
);
data
.
append
(
'
path
'
,
selectedDirectory
||
''
);
data
.
append
(
'
overwrite
'
,
overwrite
);
// add file or files
for
(
let
i
=
0
;
i
<
files
.
length
;
i
+=
1
)
{
data
.
append
(
'
files[]
'
,
files
[
i
]);
}
// axios config - progress bar
const
config
=
{
onUploadProgress
(
progressEvent
)
{
const
progress
=
Math
.
round
((
progressEvent
.
loaded
*
100
)
/
progressEvent
.
total
);
commit
(
'
messages/setProgress
'
,
progress
);
},
};
// upload files
return
POST
.
upload
(
data
,
config
).
then
((
response
)
=>
{
// clear progress
commit
(
'
messages/clearProgress
'
);
// if files uploaded successfully
if
(
response
.
data
.
result
.
status
===
'
success
'
&&
selectedDirectory
===
getters
.
selectedDirectory
)
{
// refresh content
dispatch
(
'
refreshManagers
'
);
}
return
response
;
}).
catch
(()
=>
{
// clear progress
commit
(
'
messages/clearProgress
'
);
});
},
/**
* Delete selected files and folders
* @param state
* @param getters
* @param dispatch
* @param items
* @returns {*|PromiseLike<T | never>|Promise<T | never>}
*/
delete
({
state
,
getters
,
dispatch
},
items
)
{
return
POST
.
delete
({
disk
:
getters
.
selectedDisk
,
items
,
}).
then
((
response
)
=>
{
// if all items deleted successfully
if
(
response
.
data
.
result
.
status
===
'
success
'
)
{
// refresh content
dispatch
(
'
refreshManagers
'
);
// delete directories from tree
if
(
state
.
settings
.
windowsConfig
===
2
)
{
const
onlyDir
=
items
.
filter
((
item
)
=>
item
.
type
===
'
dir
'
);
dispatch
(
'
tree/deleteFromTree
'
,
onlyDir
);
}
}
return
response
;
});
},
/**
* Paste files and folders
* @param state
* @param commit
* @param getters
* @param dispatch
*/
paste
({
state
,
commit
,
getters
,
dispatch
})
{
POST
.
paste
({
disk
:
getters
.
selectedDisk
,
path
:
getters
.
selectedDirectory
,
clipboard
:
state
.
clipboard
,
}).
then
((
response
)
=>
{
// if the action was successful
if
(
response
.
data
.
result
.
status
===
'
success
'
)
{
// refresh content
dispatch
(
'
refreshAll
'
);
// if action - cut - clear clipboard
if
(
state
.
clipboard
.
type
===
'
cut
'
)
{
commit
(
'
resetClipboard
'
);
}
}
});
},
/**
* Rename file or folder
* @param getters
* @param dispatch
* @param type
* @param newName
* @param oldName
* @returns {Promise}
*/
rename
({
getters
,
dispatch
},
{
type
,
newName
,
oldName
})
{
return
POST
.
rename
({
disk
:
getters
.
selectedDisk
,
newName
,
oldName
,
type
,
}).
then
((
response
)
=>
{
// refresh content
if
(
type
===
'
dir
'
)
{
dispatch
(
'
refreshAll
'
);
}
else
{
dispatch
(
'
refreshManagers
'
);
}
return
response
;
});
},
/**
* Get file url
* @param store
* @param disk
* @param path
* @returns {Promise}
*/
url
(
store
,
{
disk
,
path
})
{
return
GET
.
url
(
disk
,
path
);
},
/**
* Zip files and folders
* @param state
* @param getters
* @param dispatch
* @param name
* @returns {*|PromiseLike<T | never>|Promise<T | never>}
*/
zip
({
state
,
getters
,
dispatch
},
name
)
{
const
selectedDirectory
=
getters
.
selectedDirectory
;
return
POST
.
zip
({
disk
:
getters
.
selectedDisk
,
path
:
selectedDirectory
,
name
,
elements
:
state
[
state
.
activeManager
].
selected
,
}).
then
((
response
)
=>
{
// if zipped successfully
if
(
response
.
data
.
result
.
status
===
'
success
'
&&
selectedDirectory
===
getters
.
selectedDirectory
)
{
// refresh content
dispatch
(
'
refreshManagers
'
);
}
return
response
;
});
},
/**
* Unzip selected archive
* @param getters
* @param dispatch
* @param folder
* @returns {*|PromiseLike<T | never>|Promise<T | never>}
*/
unzip
({
getters
,
dispatch
},
folder
)
{
const
selectedDirectory
=
getters
.
selectedDirectory
;
return
POST
.
unzip
({
disk
:
getters
.
selectedDisk
,
path
:
getters
.
selectedItems
[
0
].
path
,
folder
,
}).
then
((
response
)
=>
{
// if unzipped successfully
if
(
response
.
data
.
result
.
status
===
'
success
'
&&
selectedDirectory
===
getters
.
selectedDirectory
)
{
// refresh
dispatch
(
'
refreshAll
'
);
}
return
response
;
});
},
/**
* Add selected items to clipboard
* @param state
* @param commit
* @param getters
* @param type
*/
toClipboard
({
state
,
commit
,
getters
},
type
)
{
// if files are selected
if
(
getters
[
`
${
state
.
activeManager
}
/selectedCount`
])
{
commit
(
'
setClipboard
'
,
{
type
,
disk
:
state
[
state
.
activeManager
].
selectedDisk
,
directories
:
state
[
state
.
activeManager
].
selected
.
directories
.
slice
(
0
),
files
:
state
[
state
.
activeManager
].
selected
.
files
.
slice
(
0
),
});
}
},
/**
* Refresh content in the manager/s
* @param dispatch
* @param state
* @returns {*}
*/
refreshManagers
({
dispatch
,
state
})
{
// select what needs to be an updated
if
(
state
.
settings
.
windowsConfig
===
3
)
{
return
Promise
.
all
([
// left manager
dispatch
(
'
left/refreshDirectory
'
),
// right manager
dispatch
(
'
right/refreshDirectory
'
),
]);
}
// only left manager
return
dispatch
(
'
left/refreshDirectory
'
);
},
/**
* Refresh All
* @param state
* @param getters
* @param dispatch
* @returns {*}
*/
refreshAll
({
state
,
getters
,
dispatch
})
{
if
(
state
.
settings
.
windowsConfig
===
2
)
{
// refresh tree
return
dispatch
(
'
tree/initTree
'
,
state
.
left
.
selectedDisk
).
then
(()
=>
Promise
.
all
([
// reopen folders if need
dispatch
(
'
tree/reopenPath
'
,
getters
.
selectedDirectory
),
// refresh manager/s
dispatch
(
'
refreshManagers
'
),
]));
}
// refresh manager/s
return
dispatch
(
'
refreshManagers
'
);
},
/**
* Repeat sorting
* @param state
* @param dispatch
* @param manager
*/
repeatSort
({
state
,
dispatch
},
manager
)
{
dispatch
(
`
${
manager
}
/sortBy`
,
{
field
:
state
[
manager
].
sort
.
field
,
direction
:
state
[
manager
].
sort
.
direction
,
});
},
/**
* Update content - files, folders after create or update
* @param state
* @param commit
* @param getters
* @param dispatch
* @param response
* @param oldDir
* @param commitName
* @param type
*/
updateContent
({
state
,
commit
,
getters
,
dispatch
},
{
response
,
oldDir
,
commitName
,
type
})
{
// if operation success
if
(
response
.
data
.
result
.
status
===
'
success
'
&&
oldDir
===
getters
.
selectedDirectory
)
{
// add/update file/folder in to the files/folders list
commit
(
`
${
state
.
activeManager
}
/
${
commitName
}
`
,
response
.
data
[
type
]);
// repeat sort
dispatch
(
'
repeatSort
'
,
state
.
activeManager
);
// if tree module is showing
if
(
type
===
'
directory
'
&&
state
.
settings
.
windowsConfig
===
2
)
{
// update tree module
dispatch
(
'
tree/addToTree
'
,
{
parentPath
:
oldDir
,
newDirectory
:
response
.
data
.
tree
,
});
// if both managers show the same folder
}
else
if
(
state
.
settings
.
windowsConfig
===
3
&&
state
.
left
.
selectedDirectory
===
state
.
right
.
selectedDirectory
&&
state
.
left
.
selectedDisk
===
state
.
right
.
selectedDisk
)
{
// add/update file/folder in to the files/folders list (inactive manager)
commit
(
`
${
getters
.
inactiveManager
}
/
${
commitName
}
`
,
response
.
data
[
type
]);
// repeat sort
dispatch
(
'
repeatSort
'
,
getters
.
inactiveManager
);
}
}
},
/**
* Reset application state
* @param state
* @param commit
*/
resetState
({
state
,
commit
})
{
// left manager
commit
(
'
left/setDisk
'
,
null
);
commit
(
'
left/setSelectedDirectory
'
,
null
);
commit
(
'
left/setDirectoryContent
'
,
{
directories
:
[],
files
:
[]
});
commit
(
'
left/resetSelected
'
);
commit
(
'
left/resetSortSettings
'
);
commit
(
'
left/resetHistory
'
);
commit
(
'
left/setView
'
,
'
table
'
);
// modals
commit
(
'
modal/clearModal
'
);
// messages
commit
(
'
messages/clearActionResult
'
);
commit
(
'
messages/clearProgress
'
);
commit
(
'
messages/clearLoading
'
);
commit
(
'
messages/clearErrors
'
);
if
(
state
.
settings
.
windowsConfig
===
3
)
{
// right manager
commit
(
'
right/setDisk
'
,
null
);
commit
(
'
right/setSelectedDirectory
'
,
null
);
commit
(
'
right/setDirectoryContent
'
,
{
directories
:
[],
files
:
[]
});
commit
(
'
right/resetSelected
'
);
commit
(
'
right/resetSortSettings
'
);
commit
(
'
right/resetHistory
'
);
commit
(
'
right/setView
'
,
'
table
'
);
}
else
if
(
state
.
settings
.
windowsConfig
===
2
)
{
// tree
commit
(
'
tree/cleanTree
'
);
commit
(
'
tree/clearTempArray
'
);
}
commit
(
'
resetState
'
);
},
/**
* Open PDF
* @param context
* @param disk
* @param path
*/
openPDF
(
context
,
{
disk
,
path
})
{
const
win
=
window
.
open
();
GET
.
getFileArrayBuffer
(
disk
,
path
).
then
((
response
)
=>
{
const
blob
=
new
Blob
([
response
.
data
],
{
type
:
'
application/pdf
'
});
win
.
document
.
write
(
`<iframe src="
${
URL
.
createObjectURL
(
blob
)}
" allowfullscreen height="100%" width="100%"></iframe>`
);
});
},
};
tools/frontend/src/store/file-manager/getters.js
0 → 100644
View file @
bae8cfdf
export
default
{
/**
* Get a list of disks
* @param state
* @returns {string[]}
*/
diskList
(
state
)
{
return
Object
.
keys
(
state
.
disks
);
},
/**
* Selected disk for active manager
* @param state
* @returns {selectedDisk|null|*|computed.selectedDisk}
*/
selectedDisk
(
state
)
{
return
state
[
state
.
activeManager
].
selectedDisk
;
},
/**
* Selected directory for active manager
* @param state
* @returns {selectedDirectory|computed.selectedDirectory|string|*}
*/
selectedDirectory
(
state
)
{
return
state
[
state
.
activeManager
].
selectedDirectory
;
},
/**
* List of selected files and folders for the active manager
* @param state
* @param getters
* @returns {*}
*/
selectedItems
(
state
,
getters
)
{
return
getters
[
`
${
state
.
activeManager
}
/selectedList`
];
},
/**
* Inactive manager name
* @param state
* @returns {string}
*/
inactiveManager
(
state
)
{
return
state
.
activeManager
===
'
left
'
?
'
right
'
:
'
left
'
;
},
};
tools/frontend/src/store/file-manager/manager/actions.js
0 → 100644
View file @
bae8cfdf
/* eslint-disable object-curly-newline */
import
GET
from
'
../../../utils/get
'
;
export
default
{
/**
* Load files and folders for the selected directory
* @param state
* @param commit
* @param dispatch
* @param rootState
* @param path
* @param history
* @returns {Promise}
*/
selectDirectory
({
state
,
commit
,
dispatch
,
rootState
},
{
path
,
history
})
{
// reset content
commit
(
'
setDirectoryContent
'
,
{
directories
:
[],
files
:
[]
});
// get content for the selected directory
return
GET
.
content
(
state
.
selectedDisk
,
path
).
then
((
response
)
=>
{
if
(
response
.
data
.
result
.
status
===
'
success
'
)
{
commit
(
'
resetSelected
'
);
commit
(
'
resetSortSettings
'
);
commit
(
'
setDirectoryContent
'
,
response
.
data
);
commit
(
'
setSelectedDirectory
'
,
path
);
if
(
history
)
commit
(
'
addToHistory
'
,
path
);
// if directories tree is shown, not main directory and directory have subdirectories
if
(
rootState
.
fm
.
settings
.
windowsConfig
===
2
&&
path
&&
response
.
data
.
directories
.
length
)
{
dispatch
(
'
fm/tree/showSubdirectories
'
,
path
,
{
root
:
true
});
}
}
});
},
/**
* Refresh content in the selected directory
* @param state
* @param commit
* @param dispatch
*/
refreshDirectory
({
state
,
commit
,
dispatch
})
{
GET
.
content
(
state
.
selectedDisk
,
state
.
selectedDirectory
).
then
((
response
)
=>
{
commit
(
'
resetSelected
'
);
commit
(
'
resetSortSettings
'
);
commit
(
'
resetHistory
'
);
// add to history selected directory
if
(
state
.
selectedDirectory
)
commit
(
'
addToHistory
'
,
state
.
selectedDirectory
);
if
(
response
.
data
.
result
.
status
===
'
success
'
)
{
commit
(
'
setDirectoryContent
'
,
response
.
data
);
}
else
if
(
response
.
data
.
result
.
status
===
'
danger
'
)
{
// If directory not found try to load main directory
commit
(
'
setSelectedDirectory
'
,
null
);
dispatch
(
'
refreshDirectory
'
);
}
});
},
/**
* History Back
* @param state
* @param commit
* @param dispatch
*/
historyBack
({
state
,
commit
,
dispatch
})
{
dispatch
(
'
selectDirectory
'
,
{
path
:
state
.
history
[
state
.
historyPointer
-
1
],
history
:
false
,
});
commit
(
'
pointerBack
'
);
},
/**
* History Forward
* @param state
* @param commit
* @param dispatch
*/
historyForward
({
state
,
commit
,
dispatch
})
{
dispatch
(
'
selectDirectory
'
,
{
path
:
state
.
history
[
state
.
historyPointer
+
1
],
history
:
false
,
});
commit
(
'
pointerForward
'
);
},
/**
* Sort data by field
* @param context
* @param field
* @param direction
*/
sortBy
({
state
,
commit
},
{
field
,
direction
})
{
if
(
state
.
sort
.
field
===
field
&&
!
direction
)
{
commit
(
'
setSortDirection
'
,
state
.
sort
.
direction
===
'
up
'
?
'
down
'
:
'
up
'
);
}
else
if
(
direction
)
{
commit
(
'
setSortDirection
'
,
direction
);
commit
(
'
setSortField
'
,
field
);
}
else
{
commit
(
'
setSortDirection
'
,
'
up
'
);
commit
(
'
setSortField
'
,
field
);
}
// sort by field type
switch
(
field
)
{
case
'
name
'
:
commit
(
'
sortByName
'
);
break
;
case
'
size
'
:
commit
(
'
sortBySize
'
);
break
;
case
'
type
'
:
commit
(
'
sortByType
'
);
break
;
case
'
date
'
:
commit
(
'
sortByDate
'
);
break
;
default
:
break
;
}
},
};
tools/frontend/src/store/file-manager/manager/getters.js
0 → 100644
View file @
bae8cfdf
export
default
{
/**
* Files list(filtered)
* @param state
* @param getters
* @param rootState
*/
files
(
state
,
getters
,
rootState
)
{
if
(
rootState
.
fm
.
settings
.
hiddenFiles
)
{
return
state
.
files
;
}
return
state
.
files
.
filter
((
item
)
=>
item
.
basename
.
match
(
new
RegExp
(
'
^([^.]).*
'
,
'
i
'
)));
},
/**
* Directories list(filtered)
* @param state
* @param getters
* @param rootState
* @returns {*}
*/
directories
(
state
,
getters
,
rootState
)
{
if
(
rootState
.
fm
.
settings
.
hiddenFiles
)
{
return
state
.
directories
;
}
return
state
.
directories
.
filter
((
item
)
=>
item
.
basename
.
match
(
new
RegExp
(
'
^([^.]).*
'
,
'
i
'
)));
},
/**
* Files counter
* @param state
* @param getters
* @returns {*}
*/
filesCount
(
state
,
getters
)
{
return
getters
.
files
.
length
;
},
/**
* Directories counter
* @param state
* @param getters
* @returns {*}
*/
directoriesCount
(
state
,
getters
)
{
return
getters
.
directories
.
length
;
},
/**
* Files size - bytes
* @param state
* @param getters
* @returns {*}
*/
filesSize
(
state
,
getters
)
{
if
(
getters
.
files
.
length
)
{
return
getters
.
files
.
reduce
((
previous
,
current
)
=>
previous
+
Number
(
current
.
size
),
0
);
}
return
0
;
},
/**
* Count selected files and folders
* @param state
* @param getters
* @returns {number}
*/
selectedCount
(
state
,
getters
)
{
return
getters
.
selectedList
.
length
;
},
/**
* Selected files size
* @param state
* @returns {number}
*/
selectedFilesSize
(
state
)
{
const
selectedFiles
=
state
.
files
.
filter
((
file
)
=>
state
.
selected
.
files
.
includes
(
file
.
path
));
if
(
selectedFiles
.
length
)
{
return
selectedFiles
.
reduce
((
previous
,
current
)
=>
previous
+
Number
(
current
.
size
),
0
);
}
return
0
;
},
/**
* Selected files and folders
* @param state
*/
selectedList
(
state
)
{
const
selectedDirectories
=
state
.
directories
.
filter
((
directory
)
=>
state
.
selected
.
directories
.
includes
(
directory
.
path
));
const
selectedFiles
=
state
.
files
.
filter
((
file
)
=>
state
.
selected
.
files
.
includes
(
file
.
path
));
return
selectedDirectories
.
concat
(
selectedFiles
);
},
/**
* Breadcrumb
* @param state
* @returns {*}
*/
breadcrumb
(
state
)
{
if
(
state
.
selectedDirectory
)
{
return
state
.
selectedDirectory
.
split
(
'
/
'
);
}
return
null
;
},
/**
* Compare directories name
* @param state
*/
directoryExist
:
(
state
)
=>
(
basename
)
=>
state
.
directories
.
some
((
el
)
=>
el
.
basename
===
basename
),
/**
* Compare files name
* @param state
*/
fileExist
:
(
state
)
=>
(
basename
)
=>
state
.
files
.
some
((
el
)
=>
el
.
basename
===
basename
),
};
tools/frontend/src/store/file-manager/manager/mutations.js
0 → 100644
View file @
bae8cfdf
export
default
{
/**
* Set selected disk
* @param state
* @param disk
*/
setDisk
(
state
,
disk
)
{
state
.
selectedDisk
=
disk
;
},
/**
* Set directories and files in selected directory
* @param state
* @param data
*/
setDirectoryContent
(
state
,
data
)
{
state
.
directories
=
data
.
directories
;
state
.
files
=
data
.
files
;
},
/**
* Set selected directory
* @param state
* @param directory
*/
setSelectedDirectory
(
state
,
directory
)
{
state
.
selectedDirectory
=
directory
;
},
/**
* Set selected items
* @param state
* @param type (directories, files)
* @param path
*/
setSelected
(
state
,
{
type
,
path
})
{
state
.
selected
[
type
].
push
(
path
);
},
/**
* Remove item from array
* @param state
* @param arrayIndex
*/
removeSelected
(
state
,
{
type
,
path
})
{
const
itemIndex
=
state
.
selected
[
type
].
indexOf
(
path
);
if
(
itemIndex
!==
-
1
)
state
.
selected
[
type
].
splice
(
itemIndex
,
1
);
},
/**
* Change selected item
* @param state
* @param type
* @param path
*/
changeSelected
(
state
,
{
type
,
path
})
{
state
.
selected
.
directories
=
[];
state
.
selected
.
files
=
[];
state
.
selected
[
type
].
push
(
path
);
},
/**
* Reset selected items array
* @param state
*/
resetSelected
(
state
)
{
state
.
selected
.
directories
=
[];
state
.
selected
.
files
=
[];
},
/**
* Add new file
* @param state
* @param newFile
*/
addNewFile
(
state
,
newFile
)
{
state
.
files
.
push
(
newFile
);
},
/**
* Update file
* @param state
* @param file
*/
updateFile
(
state
,
file
)
{
const
itemIndex
=
state
.
files
.
findIndex
((
el
)
=>
el
.
basename
===
file
.
basename
);
if
(
itemIndex
!==
-
1
)
state
.
files
[
itemIndex
]
=
file
;
},
/**
* Add new directory
* @param state
* @param newDirectory
*/
addNewDirectory
(
state
,
newDirectory
)
{
state
.
directories
.
push
(
newDirectory
);
},
/**
* Change history pointer (back)
* @param state
*/
pointerBack
(
state
)
{
state
.
historyPointer
-=
1
;
},
/**
* Change history pointer (forward)
* @param state
*/
pointerForward
(
state
)
{
state
.
historyPointer
+=
1
;
},
/**
* Add to history
* @param state
* @param path
*/
addToHistory
(
state
,
path
)
{
if
(
state
.
historyPointer
<
state
.
history
.
length
-
1
)
{
// erase next elements in the history
state
.
history
.
splice
(
state
.
historyPointer
+
1
,
Number
.
MAX_VALUE
);
}
// add new path
state
.
history
.
push
(
path
);
// change history pointer
state
.
historyPointer
+=
1
;
},
/**
* Reset history
* @param state
*/
resetHistory
(
state
)
{
state
.
history
=
[
null
];
state
.
historyPointer
=
0
;
},
/**
* Set view type
* Grid or Table
* @param state
* @param type
*/
setView
(
state
,
type
)
{
state
.
viewType
=
type
;
},
/**
* Set sort settings - field name
* @param state
* @param field
*/
setSortField
(
state
,
field
)
{
state
.
sort
.
field
=
field
;
},
/**
* Set sort settings - direction
* @param state
* @param direction
*/
setSortDirection
(
state
,
direction
)
{
state
.
sort
.
direction
=
direction
;
},
/**
* Reset sort settings
* @param state
*/
resetSortSettings
(
state
)
{
state
.
sort
.
field
=
'
name
'
;
state
.
sort
.
direction
=
'
up
'
;
},
/**
* Sort table by name field
* @param state
*/
sortByName
(
state
)
{
if
(
state
.
sort
.
direction
===
'
up
'
)
{
state
.
directories
.
sort
((
a
,
b
)
=>
a
.
basename
.
localeCompare
(
b
.
basename
));
state
.
files
.
sort
((
a
,
b
)
=>
a
.
basename
.
localeCompare
(
b
.
basename
));
}
else
{
state
.
directories
.
sort
((
a
,
b
)
=>
b
.
basename
.
localeCompare
(
a
.
basename
));
state
.
files
.
sort
((
a
,
b
)
=>
b
.
basename
.
localeCompare
(
a
.
basename
));
}
},
/**
* Sort by file size
* @param state
*/
sortBySize
(
state
)
{
state
.
directories
.
sort
((
a
,
b
)
=>
a
.
basename
.
localeCompare
(
b
.
basename
));
if
(
state
.
sort
.
direction
===
'
up
'
)
{
state
.
files
.
sort
((
a
,
b
)
=>
a
.
size
-
b
.
size
);
}
else
{
state
.
files
.
sort
((
a
,
b
)
=>
b
.
size
-
a
.
size
);
}
},
/**
* Sort by file extension
* @param state
*/
sortByType
(
state
)
{
state
.
directories
.
sort
((
a
,
b
)
=>
a
.
basename
.
localeCompare
(
b
.
basename
));
if
(
state
.
sort
.
direction
===
'
up
'
)
{
state
.
files
.
sort
((
a
,
b
)
=>
a
.
extension
.
localeCompare
(
b
.
extension
));
}
else
{
state
.
files
.
sort
((
a
,
b
)
=>
b
.
extension
.
localeCompare
(
a
.
extension
));
}
},
/**
* Sort by date
* @param state
*/
sortByDate
(
state
)
{
if
(
state
.
sort
.
direction
===
'
up
'
)
{
state
.
directories
.
sort
((
a
,
b
)
=>
a
.
timestamp
-
b
.
timestamp
);
state
.
files
.
sort
((
a
,
b
)
=>
a
.
timestamp
-
b
.
timestamp
);
}
else
{
state
.
directories
.
sort
((
a
,
b
)
=>
b
.
timestamp
-
a
.
timestamp
);
state
.
files
.
sort
((
a
,
b
)
=>
b
.
timestamp
-
a
.
timestamp
);
}
},
};
tools/frontend/src/store/file-manager/manager/store.js
0 → 100644
View file @
bae8cfdf
import
mutations
from
'
./mutations
'
;
import
getters
from
'
./getters
'
;
import
actions
from
'
./actions
'
;
export
default
{
namespaced
:
true
,
state
()
{
return
{
// selected disk
selectedDisk
:
null
,
// selected directory
selectedDirectory
:
null
,
// Directories in the selected directory
directories
:
[],
// files in the selected directory
files
:
[],
// selected files and folders
selected
:
{
directories
:
[],
files
:
[],
},
// sorting settings
sort
:
{
field
:
'
name
'
,
direction
:
'
up
'
,
},
// history
history
:
[
null
],
// history pointer
historyPointer
:
0
,
// view type - table or grid - (default - table)
viewType
:
'
table
'
,
};
},
mutations
,
getters
,
actions
,
};
tools/frontend/src/store/file-manager/messages/mutations.js
0 → 100644
View file @
bae8cfdf
export
default
{
/**
* Set the result of the action
* when the message exists
* @param state
* @param status
* @param message
*/
setActionResult
(
state
,
{
status
,
message
})
{
state
.
actionResult
.
status
=
status
;
state
.
actionResult
.
message
=
message
;
},
/**
* Clear action result
* @param state
*/
clearActionResult
(
state
)
{
state
.
actionResult
.
status
=
null
;
state
.
actionResult
.
message
=
null
;
},
/**
* Progress Bar (%) - upload..
* @param state
* @param progress
*/
setProgress
(
state
,
progress
)
{
state
.
actionProgress
=
progress
;
},
/**
* Clear progress
* @param state
*/
clearProgress
(
state
)
{
state
.
actionProgress
=
0
;
},
/**
* Add new action
* @param state
*/
addLoading
(
state
)
{
state
.
loading
+=
1
;
},
/**
* Action finish
* @param state
*/
subtractLoading
(
state
)
{
state
.
loading
-=
1
;
},
/**
* Clear
* @param state
*/
clearLoading
(
state
)
{
state
.
loading
=
0
;
},
/**
* Set error message
* @param state
* @param error
*/
setError
(
state
,
error
)
{
state
.
errors
.
push
(
error
);
},
/**
* Clear errors
* @param state
*/
clearErrors
(
state
)
{
state
.
errors
=
[];
},
};
tools/frontend/src/store/file-manager/messages/store.js
0 → 100644
View file @
bae8cfdf
import
mutations
from
'
./mutations
'
;
export
default
{
namespaced
:
true
,
state
()
{
return
{
// last action result
actionResult
:
{
status
:
null
,
message
:
null
,
},
// completing state
actionProgress
:
0
,
// loading spinner
loading
:
0
,
// application error messages
errors
:
[],
};
},
mutations
,
};
tools/frontend/src/store/file-manager/modal/mutations.js
0 → 100644
View file @
bae8cfdf
export
default
{
/**
* Modal window state
* @param state
* @param show
* @param modalName
*/
setModalState
(
state
,
{
show
,
modalName
})
{
state
.
showModal
=
show
;
state
.
modalName
=
modalName
;
},
/**
* Clear modal
* @param state
*/
clearModal
(
state
)
{
state
.
showModal
=
false
;
state
.
modalName
=
null
;
},
/**
* Main modal block - set height
* @param state
* @param height
*/
setModalBlockHeight
(
state
,
height
)
{
state
.
modalBlockHeight
=
height
;
},
};
tools/frontend/src/store/file-manager/modal/store.js
0 → 100644
View file @
bae8cfdf
import
mutations
from
'
./mutations
'
;
export
default
{
namespaced
:
true
,
state
()
{
return
{
// modal window
showModal
:
false
,
// modal name
modalName
:
null
,
// main modal block height
modalBlockHeight
:
0
,
};
},
mutations
,
};
tools/frontend/src/store/file-manager/mutations.js
0 → 100644
View file @
bae8cfdf
/* eslint-disable object-curly-newline */
export
default
{
/**
* Set disks
* @param state
* @param disks
*/
setDisks
(
state
,
disks
)
{
state
.
disks
=
disks
;
},
/**
* Set clipboard
* @param state
* @param type
* @param disk
* @param directories
* @param files
*/
setClipboard
(
state
,
{
type
,
disk
,
directories
,
files
})
{
state
.
clipboard
.
type
=
type
;
state
.
clipboard
.
disk
=
disk
;
state
.
clipboard
.
directories
=
directories
;
state
.
clipboard
.
files
=
files
;
},
/**
* Truncate clipboard
* @param state
* @param type
* @param path
*/
truncateClipboard
(
state
,
{
type
,
path
})
{
const
itemIndex
=
state
.
clipboard
[
type
].
indexOf
(
path
);
if
(
itemIndex
!==
-
1
)
state
.
clipboard
[
type
].
splice
(
itemIndex
,
1
);
if
(
!
state
.
clipboard
.
directories
.
length
&&
!
state
.
clipboard
.
files
.
length
)
{
state
.
clipboard
.
type
=
null
;
}
},
/**
* Reset clipboard
* @param state
*/
resetClipboard
(
state
)
{
state
.
clipboard
.
type
=
null
;
state
.
clipboard
.
disk
=
null
;
state
.
clipboard
.
directories
=
[];
state
.
clipboard
.
files
=
[];
},
/**
* Select manager (when shown 2 file manager windows)
* @param state
* @param managerName
*/
setActiveManager
(
state
,
managerName
)
{
state
.
activeManager
=
managerName
;
},
/**
* Set file callback
* @param state
* @param callback
*/
setFileCallBack
(
state
,
callback
)
{
state
.
fileCallback
=
callback
;
},
/**
* Screen mode toggle - ON/OFF full screen
* @param state
*/
screenToggle
(
state
)
{
state
.
fullScreen
=
!
state
.
fullScreen
;
},
/**
* Reset state
* @param state
*/
resetState
(
state
)
{
state
.
activeManager
=
'
left
'
;
state
.
clipboard
=
{
type
:
null
,
disk
:
null
,
directories
:
[],
files
:
[],
};
state
.
disks
=
[];
state
.
fileCallback
=
null
;
state
.
fullScreen
=
false
;
},
};
tools/frontend/src/store/file-manager/settings/getters.js
0 → 100644
View file @
bae8cfdf
export
default
{
/**
* Base URL
* @param state
* @returns {default.baseUrl|(function(*))|string|*|string|null}
*/
baseUrl
(
state
)
{
return
state
.
baseUrl
;
},
/**
* Headers
* @param state
* @return {*}
*/
headers
(
state
)
{
return
state
.
headers
;
},
/**
* Headers has Authorization
* @param state
* @return {boolean}
*/
authHeader
(
state
)
{
return
Object
.
prototype
.
hasOwnProperty
.
call
(
state
.
headers
,
'
Authorization
'
);
},
};
tools/frontend/src/store/file-manager/settings/mutations.js
0 → 100644
View file @
bae8cfdf
import
Vue
from
'
vue
'
;
export
default
{
/**
* Set config
* @param state
* @param data
*/
manualSettings
(
state
,
data
)
{
// overwrite headers - Axios
if
(
Object
.
prototype
.
hasOwnProperty
.
call
(
data
,
'
headers
'
))
{
state
.
headers
=
data
.
headers
;
}
// base url - axios
if
(
Object
.
prototype
.
hasOwnProperty
.
call
(
data
,
'
baseUrl
'
))
{
state
.
baseUrl
=
data
.
baseUrl
;
}
// windows config
if
(
Object
.
prototype
.
hasOwnProperty
.
call
(
data
,
'
windowsConfig
'
))
{
state
.
windowsConfig
=
data
.
windowsConfig
;
}
// language
if
(
Object
.
prototype
.
hasOwnProperty
.
call
(
data
,
'
lang
'
))
{
state
.
lang
=
data
.
lang
;
}
// add new translation
if
(
Object
.
prototype
.
hasOwnProperty
.
call
(
data
,
'
translation
'
))
{
Vue
.
set
(
state
.
translations
,
data
.
translation
.
name
,
Object
.
freeze
(
data
.
translation
.
content
));
}
},
/**
* Initiate Axios baseUrl and headers
* @param state
*/
initAxiosSettings
(
state
)
{
// initiate base url, if not set manually
if
(
!
state
.
baseUrl
)
{
if
(
process
.
env
.
VUE_APP_LFM_AXIOS_BASE_URL
)
{
// vue .env
state
.
baseUrl
=
process
.
env
.
VUE_APP_LFM_AXIOS_BASE_URL
;
}
else
if
(
process
.
env
.
MIX_LFM_BASE_URL
)
{
// laravel .env
state
.
baseUrl
=
process
.
env
.
MIX_LFM_BASE_URL
;
}
else
{
let
baseUrl
=
`
${
window
.
location
.
protocol
}
//
${
window
.
location
.
hostname
}
`
;
if
(
window
.
location
.
port
.
length
)
{
baseUrl
+=
`:
${
window
.
location
.
port
}
/file-manager/`
;
}
else
{
baseUrl
+=
'
/file-manager/
'
;
}
state
.
baseUrl
=
baseUrl
;
}
}
// initiate headers, if not set manually
if
(
Object
.
keys
(
state
.
headers
).
length
===
0
)
{
// off laravel csrf-token if need
if
(
process
.
env
.
VUE_APP_LFM_CSRF_TOKEN
===
'
OFF
'
||
process
.
env
.
MIX_LFM_CSRF_TOKEN
===
'
OFF
'
)
{
state
.
headers
=
{
'
X-Requested-With
'
:
'
XMLHttpRequest
'
};
}
else
{
// Laravel CSRF token
const
token
=
document
.
head
.
querySelector
(
'
meta[name="csrf-token"]
'
);
if
(
!
token
)
{
state
.
headers
=
{
'
X-Requested-With
'
:
'
XMLHttpRequest
'
,
};
// eslint-disable-next-line
console
.
error
(
'
CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token
'
);
}
else
{
state
.
headers
=
{
'
X-Requested-With
'
:
'
XMLHttpRequest
'
,
'
X-CSRF-TOKEN
'
:
token
.
content
,
};
}
}
}
},
/**
* Initialize App settings from server
* @param state
* @param data
*/
initSettings
(
state
,
data
)
{
if
(
!
state
.
lang
)
state
.
lang
=
data
.
lang
;
if
(
!
state
.
windowsConfig
)
state
.
windowsConfig
=
data
.
windowsConfig
;
state
.
acl
=
data
.
acl
;
state
.
hiddenFiles
=
data
.
hiddenFiles
;
},
/**
* Set Hide or Show hidden files
* @param state
*/
toggleHiddenFiles
(
state
)
{
state
.
hiddenFiles
=
!
state
.
hiddenFiles
;
},
};
tools/frontend/src/store/file-manager/settings/store.js
0 → 100644
View file @
bae8cfdf
import
mutations
from
'
./mutations
'
;
import
getters
from
'
./getters
'
;
// languages
import
ru
from
'
../../../locales/lang/ru
'
;
import
en
from
'
../../../locales/lang/en
'
;
import
ar
from
'
../../../locales/lang/ar
'
;
import
sr
from
'
../../../locales/lang/sr
'
;
import
cs
from
'
../../../locales/lang/cs
'
;
import
de
from
'
../../../locales/lang/de
'
;
import
es
from
'
../../../locales/lang/es
'
;
import
nl
from
'
../../../locales/lang/nl
'
;
/* eslint camelcase: 0 */
import
zh_CN
from
'
../../../locales/lang/zh_CN
'
;
import
fa
from
'
../../../locales/lang/fa
'
;
import
it
from
'
../../../locales/lang/it
'
;
import
tr
from
'
../../../locales/lang/tr
'
;
import
fr
from
'
../../../locales/lang/fr
'
;
import
pt_BR
from
'
../../../locales/lang/pt_BR
'
;
import
zh_TW
from
'
../../../locales/lang/zh_TW
'
;
import
pl
from
'
../../../locales/lang/pl
'
;
export
default
{
namespaced
:
true
,
state
()
{
return
{
// ACL
acl
:
null
,
// App version
version
:
'
2.5.4
'
,
// axios headers
headers
:
{},
// axios default URL
baseUrl
:
null
,
/**
* File manager windows configuration
* 1 - only one file manager window
* 2 - one file manager window with directories tree module
* 3 - two file manager windows
*/
windowsConfig
:
null
,
// App language
lang
:
null
,
// Translations (/src/lang)
translations
:
{
ru
:
Object
.
freeze
(
ru
),
en
:
Object
.
freeze
(
en
),
ar
:
Object
.
freeze
(
ar
),
sr
:
Object
.
freeze
(
sr
),
cs
:
Object
.
freeze
(
cs
),
de
:
Object
.
freeze
(
de
),
es
:
Object
.
freeze
(
es
),
nl
:
Object
.
freeze
(
nl
),
'
zh-CN
'
:
Object
.
freeze
(
zh_CN
),
fa
:
Object
.
freeze
(
fa
),
it
:
Object
.
freeze
(
it
),
tr
:
Object
.
freeze
(
tr
),
fr
:
Object
.
freeze
(
fr
),
'
pt-BR
'
:
Object
.
freeze
(
pt_BR
),
'
zh-TW
'
:
Object
.
freeze
(
zh_TW
),
pl
:
Object
.
freeze
(
pl
),
},
// show or hide hidden files
hiddenFiles
:
false
,
// Context menu items
contextMenu
:
[
[
{
name
:
'
open
'
,
icon
:
'
far fa-folder-open
'
,
},
{
name
:
'
audioPlay
'
,
icon
:
'
fas fa-play
'
,
},
{
name
:
'
videoPlay
'
,
icon
:
'
fas fa-play
'
,
},
{
name
:
'
view
'
,
icon
:
'
fas fa-eye
'
,
},
{
name
:
'
edit
'
,
icon
:
'
fas fa-file-signature
'
,
},
{
name
:
'
select
'
,
icon
:
'
fas fa-check
'
,
},
{
name
:
'
download
'
,
icon
:
'
fas fa-download
'
,
},
],
[
{
name
:
'
copy
'
,
icon
:
'
far fa-copy
'
,
},
{
name
:
'
cut
'
,
icon
:
'
fas fa-cut
'
,
},
{
name
:
'
rename
'
,
icon
:
'
far fa-edit
'
,
},
{
name
:
'
paste
'
,
icon
:
'
far fa-clipboard
'
,
},
{
name
:
'
zip
'
,
icon
:
'
far fa-file-archive
'
,
},
{
name
:
'
unzip
'
,
icon
:
'
far fa-file-archive
'
,
},
],
[
{
name
:
'
delete
'
,
icon
:
'
far fa-trash-alt text-danger
'
,
},
],
[
{
name
:
'
properties
'
,
icon
:
'
far fa-list-alt
'
,
},
],
],
// Image extensions for view and preview
imageExtensions
:
[
'
png
'
,
'
jpg
'
,
'
jpeg
'
,
'
gif
'
],
// Image extensions for cropping
cropExtensions
:
[
'
png
'
,
'
jpg
'
,
'
jpeg
'
],
// audio extensions for play
audioExtensions
:
[
'
ogg
'
,
'
mp3
'
,
'
aac
'
,
'
wav
'
],
// video extensions for play
videoExtensions
:
[
'
webm
'
,
'
mp4
'
],
// File extensions for code editor
textExtensions
:
{
sh
:
'
text/x-sh
'
,
// styles
css
:
'
text/css
'
,
less
:
'
text/x-less
'
,
sass
:
'
text/x-sass
'
,
scss
:
'
text/x-scss
'
,
html
:
'
text/html
'
,
// js
js
:
'
text/javascript
'
,
ts
:
'
text/typescript
'
,
vue
:
'
text/x-vue
'
,
// text
htaccess
:
'
text/plain
'
,
env
:
'
text/plain
'
,
txt
:
'
text/plain
'
,
log
:
'
text/plain
'
,
ini
:
'
text/x-ini
'
,
xml
:
'
application/xml
'
,
md
:
'
text/x-markdown
'
,
// c-like
java
:
'
text/x-java
'
,
c
:
'
text/x-csrc
'
,
cpp
:
'
text/x-c++src
'
,
cs
:
'
text/x-csharp
'
,
scl
:
'
text/x-scala
'
,
php
:
'
application/x-httpd-php
'
,
// DB
sql
:
'
text/x-sql
'
,
// other
pl
:
'
text/x-perl
'
,
py
:
'
text/x-python
'
,
lua
:
'
text/x-lua
'
,
swift
:
'
text/x-swift
'
,
rb
:
'
text/x-ruby
'
,
go
:
'
text/x-go
'
,
yaml
:
'
text/x-yaml
'
,
json
:
'
application/json
'
,
},
};
},
mutations
,
getters
,
};
tools/frontend/src/store/file-manager/state.js
0 → 100644
View file @
bae8cfdf
export
default
{
/**
* Active manager
* left or right
* default: left
*/
activeManager
:
'
left
'
,
/**
* Clipboard
* Operation type - copy || cut
*/
clipboard
:
{
type
:
null
,
disk
:
null
,
directories
:
[],
files
:
[],
},
// available disks
disks
:
[],
// file callback for ckeditor, ...
fileCallback
:
null
,
// full screen mode
fullScreen
:
false
,
};
tools/frontend/src/store/file-manager/tree/actions.js
0 → 100644
View file @
bae8cfdf
import
GET
from
'
../../../utils/get
'
;
export
default
{
/**
* Initialize directories tree
* @param state
* @param commit
* @param disk
* @returns {Promise}
*/
initTree
({
state
,
commit
},
disk
)
{
return
GET
.
tree
(
disk
,
null
).
then
((
response
)
=>
{
// if the action was successful
if
(
response
.
data
.
result
.
status
===
'
success
'
)
{
// clean the tree, if need
if
(
state
.
directories
)
commit
(
'
cleanTree
'
);
// initialize directories tree
commit
(
'
addDirectories
'
,
{
parentId
:
0
,
directories
:
response
.
data
.
directories
,
});
}
});
},
/**
* Add new directory to the tree
* @param state
* @param commit
* @param getters
* @param parentPath
* @param newDirectory
*/
addToTree
({
state
,
commit
,
getters
},
{
parentPath
,
newDirectory
})
{
// If this directory is not the root directory
if
(
parentPath
)
{
// find parent directory index
const
parentDirectoryIndex
=
getters
.
findDirectoryIndex
(
parentPath
);
if
(
parentDirectoryIndex
!==
-
1
)
{
// add a new directory
commit
(
'
addDirectories
'
,
{
directories
:
newDirectory
,
parentId
:
state
.
directories
[
parentDirectoryIndex
].
id
,
});
// update parent directory property
commit
(
'
updateDirectoryProps
'
,
{
index
:
parentDirectoryIndex
,
props
:
{
hasSubdirectories
:
true
,
showSubdirectories
:
true
,
subdirectoriesLoaded
:
true
,
},
});
}
else
{
commit
(
'
fm/messages/setError
'
,
{
message
:
'
Directory not found
'
},
{
root
:
true
});
}
}
else
{
// add a new directory to the root of the disk
commit
(
'
addDirectories
'
,
{
directories
:
newDirectory
,
parentId
:
0
,
});
}
},
/**
* Delete directories and subdirectories from tree
* @param state
* @param commit
* @param getters
* @param dispatch
* @param directories
*/
deleteFromTree
({
state
,
commit
,
getters
,
dispatch
,
},
directories
)
{
directories
.
forEach
((
item
)
=>
{
// find this directory in the tree
const
directoryIndex
=
getters
.
findDirectoryIndex
(
item
.
path
);
if
(
directoryIndex
!==
-
1
)
{
// add directory index to array for deleting
commit
(
'
addToTempArray
'
,
directoryIndex
);
// if directory has subdirectories
if
(
state
.
directories
[
directoryIndex
].
props
.
hasSubdirectories
)
{
// find subDirectories
dispatch
(
'
subDirsFinder
'
,
state
.
directories
[
directoryIndex
].
id
);
}
}
});
// filter directories
const
temp
=
state
.
directories
.
filter
((
item
,
index
)
=>
{
if
(
state
.
tempIndexArray
.
indexOf
(
index
)
===
-
1
)
{
return
item
;
}
return
false
;
});
// replace directories
commit
(
'
replaceDirectories
'
,
temp
);
// clear temp array
commit
(
'
clearTempArray
'
);
},
/**
* Find subdirectories
* @param state
* @param commit
* @param dispatch
* @param parentId
*/
subDirsFinder
({
state
,
commit
,
dispatch
},
parentId
)
{
// find sub directories
state
.
directories
.
forEach
((
item
,
index
)
=>
{
if
(
item
.
parentId
===
parentId
)
{
// add directory index to array
commit
(
'
addToTempArray
'
,
index
);
// if directory has subdirectories
if
(
item
.
props
.
hasSubdirectories
)
{
// find subDirectories
dispatch
(
'
subDirsFinder
'
,
item
.
id
);
}
}
});
},
/**
* Get subDirectories from server
* @param commit
* @param rootGetters
* @param path
* @param parentId
* @param parentIndex
* @returns {Promise}
*/
getSubdirectories
({
commit
,
rootGetters
},
{
path
,
parentId
,
parentIndex
})
{
return
GET
.
tree
(
rootGetters
[
'
fm/selectedDisk
'
],
path
).
then
((
response
)
=>
{
// if the action was successful
if
(
response
.
data
.
result
.
status
===
'
success
'
)
{
// add directories
commit
(
'
addDirectories
'
,
{
parentId
,
directories
:
response
.
data
.
directories
,
});
// update properties at parent directory
commit
(
'
updateDirectoryProps
'
,
{
index
:
parentIndex
,
props
:
{
subdirectoriesLoaded
:
true
,
},
});
}
});
},
/**
* Show subdirectories
* @param state
* @param commit
* @param getters
* @param dispatch
* @param path
* @returns {*}
*/
showSubdirectories
({
state
,
commit
,
getters
,
dispatch
,
},
path
)
{
const
promise
=
Promise
.
resolve
();
// find parent directory index
const
parentDirectoryIndex
=
getters
.
findDirectoryIndex
(
path
);
if
(
parentDirectoryIndex
!==
-
1
)
{
// Are the subdirectories loaded?
if
(
state
.
directories
[
parentDirectoryIndex
].
props
.
subdirectoriesLoaded
)
{
// update directory properties
commit
(
'
updateDirectoryProps
'
,
{
index
:
parentDirectoryIndex
,
props
:
{
showSubdirectories
:
true
,
},
});
}
else
{
// load subdirectories
return
dispatch
(
'
getSubdirectories
'
,
{
path
:
state
.
directories
[
parentDirectoryIndex
].
path
,
parentId
:
state
.
directories
[
parentDirectoryIndex
].
id
,
parentIndex
:
parentDirectoryIndex
,
}).
then
(()
=>
{
// update properties in the parent directory
commit
(
'
updateDirectoryProps
'
,
{
index
:
parentDirectoryIndex
,
props
:
{
showSubdirectories
:
true
,
},
});
});
}
}
else
{
commit
(
'
fm/messages/setError
'
,
{
message
:
'
Directory not found
'
},
{
root
:
true
});
}
return
promise
;
},
/**
* Hide subdirectories
* @param commit
* @param getters
* @param path
*/
hideSubdirectories
({
commit
,
getters
},
path
)
{
// find parent directory index
const
parentDirectoryIndex
=
getters
.
findDirectoryIndex
(
path
);
if
(
parentDirectoryIndex
!==
-
1
)
{
// hide subdirectories
commit
(
'
updateDirectoryProps
'
,
{
index
:
parentDirectoryIndex
,
props
:
{
showSubdirectories
:
false
,
},
});
}
else
{
commit
(
'
fm/messages/setError
'
,
{
message
:
'
Directory not found
'
},
{
root
:
true
});
}
},
/**
* Reopen tree directories by selected path
* @param dispatch
* @param path
* @returns {Promise<void>}
*/
reopenPath
({
dispatch
},
path
)
{
let
promises
=
Promise
.
resolve
();
if
(
path
)
{
const
splitPath
=
path
.
split
(
'
/
'
);
for
(
let
i
=
0
;
splitPath
.
length
>
i
;
i
+=
1
)
{
promises
=
promises
.
then
(()
=>
dispatch
(
'
showSubdirectories
'
,
splitPath
.
slice
(
0
,
i
+
1
).
join
(
'
/
'
),
));
}
return
promises
;
}
return
promises
;
},
};
tools/frontend/src/store/file-manager/tree/getters.js
0 → 100644
View file @
bae8cfdf
export
default
{
/**
* Find directory index in the tree
* @param state
* @returns {function(*): (number | *)}
*/
findDirectoryIndex
:
(
state
)
=>
(
path
)
=>
state
.
directories
.
findIndex
((
el
)
=>
el
.
path
===
path
),
/**
* Filtered directories list
* @param state
* @param getters
* @param rootState
* @returns {*}
*/
directories
(
state
,
getters
,
rootState
)
{
if
(
rootState
.
fm
.
settings
.
hiddenFiles
)
{
return
state
.
directories
;
}
return
state
.
directories
.
filter
((
item
)
=>
item
.
basename
.
match
(
new
RegExp
(
'
^([^.]).*
'
,
'
i
'
)));
},
};
tools/frontend/src/store/file-manager/tree/mutations.js
0 → 100644
View file @
bae8cfdf
/* eslint-disable no-param-reassign,no-restricted-syntax */
export
default
{
/**
* Clean the directories tree
* @param state
*/
cleanTree
(
state
)
{
state
.
directories
=
[];
state
.
counter
=
1
;
},
/**
* Add directories to the tree
* @param state
* @param directories
* @param parentId
*/
addDirectories
(
state
,
{
directories
,
parentId
})
{
directories
.
forEach
((
directory
)
=>
{
// add properties to dir
directory
.
id
=
state
.
counter
;
directory
.
parentId
=
parentId
;
directory
.
props
.
subdirectoriesLoaded
=
false
;
directory
.
props
.
showSubdirectories
=
false
;
state
.
counter
+=
1
;
state
.
directories
.
push
(
directory
);
});
},
/**
* Replace directories
* @param state
* @param directories
*/
replaceDirectories
(
state
,
directories
)
{
state
.
directories
=
directories
;
},
/**
* Update directory properties
* @param state
* @param index
* @param props
*/
updateDirectoryProps
(
state
,
{
index
,
props
})
{
for
(
const
property
in
props
)
{
if
(
Object
.
prototype
.
hasOwnProperty
.
call
(
props
,
property
))
{
state
.
directories
[
index
].
props
[
property
]
=
props
[
property
];
}
}
},
/**
* Add to temp index array
* @param state
* @param index
*/
addToTempArray
(
state
,
index
)
{
state
.
tempIndexArray
.
push
(
index
);
},
/**
* Clear temp index array
* @param state
*/
clearTempArray
(
state
)
{
state
.
tempIndexArray
=
[];
},
};
tools/frontend/src/store/file-manager/tree/store.js
0 → 100644
View file @
bae8cfdf
import
mutations
from
'
./mutations
'
;
import
getters
from
'
./getters
'
;
import
actions
from
'
./actions
'
;
export
default
{
namespaced
:
true
,
state
()
{
return
{
/**
* directories.id (int), el id
* directories.basename (string), folder name
* directories.dirname (string) directory name
* directories.path (string), path to directory
* directories.props (object), directory properties
* directories.props.hasSubdirectories (boolean), has child directories,
* directories.props.subdirectoriesLoaded (boolean), child directories loaded
* directories.props.showSubdirectories (boolean), show or hide subdirectories branch
* directories.parentId (int), parent id
*/
directories
:
[],
// directories id counter
counter
:
1
,
// directories array for deleting(indexes)
tempIndexArray
:
[],
};
},
mutations
,
getters
,
actions
,
};
tools/frontend/src/store/index.js
View file @
bae8cfdf
import
Vue
from
'
vue
'
import
Vue
from
'
vue
'
import
Vuex
from
'
vuex
'
import
Vuex
from
'
vuex
'
import
fm
from
'
./file-manager
'
import
global
from
'
./modules/global
'
import
global
from
'
./modules/global
'
import
globalNav
from
'
./modules/global-nav
'
import
globalNav
from
'
./modules/global-nav
'
import
frontendOpenapi
from
'
./modules/frontend-openapi
'
import
frontendOpenapi
from
'
./modules/frontend-openapi
'
...
@@ -15,6 +16,7 @@ export default new Vuex.Store({
...
@@ -15,6 +16,7 @@ export default new Vuex.Store({
openapi
:
frontendOpenapi
openapi
:
frontendOpenapi
}
}
},
},
fm
:
fm
,
global
:
{
global
:
{
namespaced
:
true
,
namespaced
:
true
,
...
global
,
...
global
,
...
@@ -22,5 +24,5 @@ export default new Vuex.Store({
...
@@ -22,5 +24,5 @@ export default new Vuex.Store({
nav
:
globalNav
nav
:
globalNav
}
}
}
}
}
}
,
})
})
tools/frontend/src/store/modules/frontend-openapi.js
View file @
bae8cfdf
...
@@ -40,7 +40,6 @@ const mutations = {
...
@@ -40,7 +40,6 @@ const mutations = {
pageSize
:
config
.
results
pageSize
:
config
.
results
}
}
}
}
// console.log(state.users.pagination)
}
}
}
}
...
...
tools/frontend/src/utils/get.js
0 → 100644
View file @
bae8cfdf
import
axios
from
'
axios
'
;
const
HTTP
=
axios
.
create
();
export
default
{
/**
* Get configuration data from server
* @returns {*}
*/
initialize
()
{
return
HTTP
.
get
(
'
initialize
'
);
},
/**
* Get directories for the tree (upper level)
* @param disk
* @param path
* @returns {*}
*/
tree
(
disk
,
path
)
{
return
HTTP
.
get
(
'
tree
'
,
{
params
:
{
disk
,
path
}
});
},
/**
* Select disk
* @param disk
* @returns {*}
*/
selectDisk
(
disk
)
{
return
HTTP
.
get
(
'
select-disk
'
,
{
params
:
{
disk
}
});
},
/**
* Get content (files and folders)
* @param disk
* @param path
* @returns {*}
*/
content
(
disk
,
path
)
{
return
HTTP
.
get
(
'
content
'
,
{
params
:
{
disk
,
path
}
});
},
/**
* Item properties
*/
/* properties(disk, path) {
return HTTP.get('properties', { params: { disk, path } });
}, */
/**
* URL
* @param disk
* @param path
* @returns {*}
*/
url
(
disk
,
path
)
{
return
HTTP
.
get
(
'
url
'
,
{
params
:
{
disk
,
path
}
});
},
/**
* Get file to editing or showing
* @param disk
* @param path
* @returns {*}
*/
getFile
(
disk
,
path
)
{
return
HTTP
.
get
(
'
download
'
,
{
params
:
{
disk
,
path
}
});
},
/**
* Get file - ArrayBuffer
* @param disk
* @param path
* @returns {*}
*/
getFileArrayBuffer
(
disk
,
path
)
{
return
HTTP
.
get
(
'
download
'
,
{
responseType
:
'
arraybuffer
'
,
params
:
{
disk
,
path
},
});
},
/**
* Image thumbnail
* @param disk
* @param path
* @returns {*}
*/
thumbnail
(
disk
,
path
)
{
return
HTTP
.
get
(
'
thumbnails
'
,
{
responseType
:
'
arraybuffer
'
,
params
:
{
disk
,
path
},
});
},
/**
* Image preview
* @param disk
* @param path
* @return {*}
*/
preview
(
disk
,
path
)
{
return
HTTP
.
get
(
'
preview
'
,
{
responseType
:
'
arraybuffer
'
,
params
:
{
disk
,
path
},
});
},
/**
* Download file
* @param disk
* @param path
* @return {*}
*/
download
(
disk
,
path
)
{
return
HTTP
.
get
(
'
download
'
,
{
responseType
:
'
arraybuffer
'
,
params
:
{
disk
,
path
},
});
},
};
tools/frontend/src/utils/helper.js
0 → 100644
View file @
bae8cfdf
export
default
{
methods
:
{
/**
* Bytes to KB, MB, ..
* @param bytes
* @returns {string}
*/
bytesToHuman
(
bytes
)
{
const
sizes
=
[
'
Bytes
'
,
'
KB
'
,
'
MB
'
,
'
GB
'
,
'
TB
'
];
if
(
bytes
===
0
)
return
'
0 Bytes
'
;
const
i
=
parseInt
(
Math
.
floor
(
Math
.
log
(
bytes
)
/
Math
.
log
(
1024
)),
10
);
if
(
i
===
0
)
return
`
${
bytes
}
${
sizes
[
i
]}
`
;
return
`
${(
bytes
/
(
1024
**
i
)).
toFixed
(
1
)}
${
sizes
[
i
]}
`
;
},
/**
* Timestamp to date
* @param timestamp
* @returns {string}
*/
timestampToDate
(
timestamp
)
{
// if date not defined
if
(
timestamp
===
undefined
)
return
'
-
'
;
const
date
=
new
Date
(
timestamp
*
1000
);
return
date
.
toLocaleString
(
this
.
$store
.
state
.
fm
.
settings
.
lang
);
},
/**
* Mime type to icon
* @param mime
* @returns {*}
*/
mimeToIcon
(
mime
)
{
// mime types
const
mimeTypes
=
{
// image
'
image/gif
'
:
'
fa-file-image
'
,
'
image/png
'
:
'
fa-file-image
'
,
'
image/jpeg
'
:
'
fa-file-image
'
,
'
image/bmp
'
:
'
fa-file-image
'
,
'
image/webp
'
:
'
fa-file-image
'
,
'
image/tiff
'
:
'
fa-file-image
'
,
'
image/svg+xml
'
:
'
fa-file-image
'
,
// text
'
text/plain
'
:
'
fa-file-alt
'
,
// code
'
text/javascript
'
:
'
fa-file-code
'
,
'
application/json
'
:
'
fa-file-code
'
,
'
text/markdown
'
:
'
fa-file-code
'
,
'
text/html
'
:
'
fa-file-code
'
,
'
text/css
'
:
'
fa-file-code
'
,
// audio
'
audio/midi
'
:
'
fa-file-audio
'
,
'
audio/mpeg
'
:
'
fa-file-audio
'
,
'
audio/webm
'
:
'
fa-file-audio
'
,
'
audio/ogg
'
:
'
fa-file-audio
'
,
'
audio/wav
'
:
'
fa-file-audio
'
,
'
audio/aac
'
:
'
fa-file-audio
'
,
'
audio/x-wav
'
:
'
fa-file-audio
'
,
'
audio/mp4
'
:
'
fa-file-audio
'
,
// video
'
video/webm
'
:
'
fa-file-video
'
,
'
video/ogg
'
:
'
fa-file-video
'
,
'
video/mpeg
'
:
'
fa-file-video
'
,
'
video/3gpp
'
:
'
fa-file-video
'
,
'
video/x-flv
'
:
'
fa-file-video
'
,
'
video/mp4
'
:
'
fa-file-video
'
,
'
video/quicktime
'
:
'
fa-file-video
'
,
'
video/x-msvideo
'
:
'
fa-file-video
'
,
'
video/vnd.dlna.mpeg-tts
'
:
'
fa-file-video
'
,
// archive
'
application/x-bzip
'
:
'
fa-file-archive
'
,
'
application/x-bzip2
'
:
'
fa-file-archive
'
,
'
application/x-tar
'
:
'
fa-file-archive
'
,
'
application/gzip
'
:
'
fa-file-archive
'
,
'
application/zip
'
:
'
fa-file-archive
'
,
'
application/x-7z-compressed
'
:
'
fa-file-archive
'
,
'
application/x-rar-compressed
'
:
'
fa-file-archive
'
,
// application
'
application/pdf
'
:
'
fa-file-pdf
'
,
'
application/rtf
'
:
'
fa-file-word
'
,
'
application/msword
'
:
'
fa-file-word
'
,
'
application/vnd.ms-word
'
:
'
fa-file-word
'
,
'
application/vnd.ms-excel
'
:
'
fa-file-excel
'
,
'
application/vnd.ms-powerpoint
'
:
'
fa-file-powerpoint
'
,
'
application/vnd.oasis.opendocument.text
'
:
'
fa-file-word
'
,
'
application/vnd.oasis.opendocument.spreadsheet
'
:
'
fa-file-excel
'
,
'
application/vnd.oasis.opendocument.presentation
'
:
'
fa-file-powerpoint
'
,
'
application/vnd.openxmlformats-officedocument.wordprocessingml
'
:
'
fa-file-word
'
,
'
application/vnd.openxmlformats-officedocument.spreadsheetml
'
:
'
fa-file-excel
'
,
'
application/vnd.openxmlformats-officedocument.presentationml
'
:
'
fa-file-powerpoint
'
,
};
if
(
mimeTypes
[
mime
]
!==
undefined
)
{
return
mimeTypes
[
mime
];
}
// file blank
return
'
fa-file
'
;
},
/**
* File extension to icon (font awesome)
* @returns {*}
* @param extension
*/
extensionToIcon
(
extension
)
{
// files extensions
const
extensionTypes
=
{
// images
gif
:
'
fa-file-image
'
,
png
:
'
fa-file-image
'
,
jpeg
:
'
fa-file-image
'
,
jpg
:
'
fa-file-image
'
,
bmp
:
'
fa-file-image
'
,
psd
:
'
fa-file-image
'
,
svg
:
'
fa-file-image
'
,
ico
:
'
fa-file-image
'
,
ai
:
'
fa-file-image
'
,
tif
:
'
fa-file-image
'
,
tiff
:
'
fa-file-image
'
,
// text
txt
:
'
fa-file-alt
'
,
json
:
'
fa-file-alt
'
,
log
:
'
fa-file-alt
'
,
ini
:
'
fa-file-alt
'
,
xml
:
'
fa-file-alt
'
,
md
:
'
fa-file-alt
'
,
env
:
'
fa-file-alt
'
,
// code
js
:
'
fa-file-code
'
,
php
:
'
fa-file-code
'
,
css
:
'
fa-file-code
'
,
cpp
:
'
fa-file-code
'
,
class
:
'
fa-file-code
'
,
h
:
'
fa-file-code
'
,
java
:
'
fa-file-code
'
,
sh
:
'
fa-file-code
'
,
swift
:
'
fa-file-code
'
,
// audio
aif
:
'
fa-file-audio
'
,
cda
:
'
fa-file-audio
'
,
mid
:
'
fa-file-audio
'
,
mp3
:
'
fa-file-audio
'
,
mpa
:
'
fa-file-audio
'
,
ogg
:
'
fa-file-audio
'
,
wav
:
'
fa-file-audio
'
,
wma
:
'
fa-file-audio
'
,
// video
wmv
:
'
fa-file-video
'
,
avi
:
'
fa-file-video
'
,
mpeg
:
'
fa-file-video
'
,
mpg
:
'
fa-file-video
'
,
flv
:
'
fa-file-video
'
,
mp4
:
'
fa-file-video
'
,
mkv
:
'
fa-file-video
'
,
mov
:
'
fa-file-video
'
,
ts
:
'
fa-file-video
'
,
'
3gpp
'
:
'
fa-file-video
'
,
// archive
zip
:
'
fa-file-archive
'
,
arj
:
'
fa-file-archive
'
,
deb
:
'
fa-file-archive
'
,
pkg
:
'
fa-file-archive
'
,
rar
:
'
fa-file-archive
'
,
rpm
:
'
fa-file-archive
'
,
'
7z
'
:
'
fa-file-archive
'
,
'
tar.gz
'
:
'
fa-file-archive
'
,
// application
pdf
:
'
fa-file-pdf
'
,
rtf
:
'
fa-file-word
'
,
doc
:
'
fa-file-word
'
,
docx
:
'
fa-file-word
'
,
odt
:
'
fa-file-word
'
,
xlr
:
'
fa-file-excel
'
,
xls
:
'
fa-file-excel
'
,
xlsx
:
'
fa-file-excel
'
,
ppt
:
'
fa-file-powerpoint
'
,
pptx
:
'
fa-file-powerpoint
'
,
pptm
:
'
fa-file-powerpoint
'
,
xps
:
'
fa-file-powerpoint
'
,
potx
:
'
fa-file-powerpoint
'
,
};
if
(
extension
&&
extensionTypes
[
extension
.
toLowerCase
()]
!==
undefined
)
{
return
extensionTypes
[
extension
.
toLowerCase
()];
}
// blank file
return
'
fa-file
'
;
},
},
};
tools/frontend/src/utils/post.js
0 → 100644
View file @
bae8cfdf
import
axios
from
'
axios
'
;
const
HTTP
=
axios
.
create
();
export
default
{
/**
* Create new file
* @param disk
* @param path
* @param name
* @returns {AxiosPromise<any>}
*/
createFile
(
disk
,
path
,
name
)
{
return
HTTP
.
post
(
'
create-file
'
,
{
disk
,
path
,
name
});
},
/**
* Update file
* @param formData
* @returns {*}
*/
updateFile
(
formData
)
{
return
HTTP
.
post
(
'
update-file
'
,
formData
);
},
/**
* Create new directory
* @param data
* @returns {*}
*/
createDirectory
(
data
)
{
return
HTTP
.
post
(
'
create-directory
'
,
data
);
},
/**
* Upload file
* @param data
* @param config
* @returns {AxiosPromise<any>}
*/
upload
(
data
,
config
)
{
return
HTTP
.
post
(
'
upload
'
,
data
,
config
);
},
/**
* Delete selected items
* @param data
* @returns {*}
*/
delete
(
data
)
{
return
HTTP
.
post
(
'
delete
'
,
data
);
},
/**
* Rename file or folder
* @param data
* @returns {*}
*/
rename
(
data
)
{
return
HTTP
.
post
(
'
rename
'
,
data
);
},
/**
* Copy / Cut files and folders
* @param data
* @returns {*}
*/
paste
(
data
)
{
return
HTTP
.
post
(
'
paste
'
,
data
);
},
/**
* Zip
* @param data
* @returns {*}
*/
zip
(
data
)
{
return
HTTP
.
post
(
'
zip
'
,
data
);
},
/**
* Unzip
* @returns {*}
* @param data
*/
unzip
(
data
)
{
return
HTTP
.
post
(
'
unzip
'
,
data
);
},
};
tools/frontend/src/utils/translate.js
0 → 100644
View file @
bae8cfdf
export
default
{
computed
:
{
/**
* Selected translate
* @returns {*}
*/
lang
()
{
// If selected translations exists
if
(
Object
.
prototype
.
hasOwnProperty
.
call
(
this
.
$store
.
state
.
fm
.
settings
.
translations
,
this
.
$store
.
state
.
fm
.
settings
.
lang
,
))
{
return
this
.
$store
.
state
.
fm
.
settings
.
translations
[
this
.
$store
.
state
.
fm
.
settings
.
lang
];
}
// default translate - en
return
this
.
$store
.
state
.
fm
.
settings
.
translations
.
en
;
},
},
};
tools/frontend/src/views/FileManager/FileManager.vue
0 → 100644
View file @
bae8cfdf
<
template
>
<div
class=
"fm d-flex flex-column"
v-bind:class=
"
{ 'fm-full-screen': fullScreen }"
>
<navbar
/>
<div
class=
"fm-body"
>
<notification
/>
<context-menu
/>
<modal
v-if=
"showModal"
/>
<template
v-if=
"windowsConfig === 1"
>
<left-manager
class=
"col"
manager=
"left"
/>
</
template
>
<
template
v-else-if=
"windowsConfig === 2"
>
<folder-tree
class=
"col-4 col-md-3"
/>
<left-manager
class=
"col-8 col-md-9"
manager=
"left"
/>
</
template
>
<
template
v-else-if=
"windowsConfig === 3"
>
<left-manager
class=
"col-12 col-sm-6"
manager=
"left"
v-on:click.native=
"selectManager('left')"
v-on:contextmenu.native=
"selectManager('left')"
>
</left-manager>
<right-manager
class=
"col-12 col-sm-6"
manager=
"right"
v-on:click.native=
"selectManager('right')"
v-on:contextmenu.native=
"selectManager('right')"
>
</right-manager>
</
template
>
</div>
<info-block
/>
</div>
</template>
<
script
>
/* eslint-disable import/no-duplicates, no-param-reassign */
import
{
mapState
}
from
"
vuex
"
;
// Axios
import
axios
from
'
axios
'
;
const
HTTP
=
axios
.
create
();
import
EventBus
from
"
@/utils/eventBus
"
;
// Components
import
Navbar
from
"
./components/blocks/Navbar.vue
"
;
import
FolderTree
from
"
./components/tree/FolderTree.vue
"
;
import
LeftManager
from
"
./components/manager/Manager.vue
"
;
import
RightManager
from
"
./components/manager/Manager.vue
"
;
import
Modal
from
"
./components/modals/Modal.vue
"
;
import
InfoBlock
from
"
./components/blocks/InfoBlock.vue
"
;
import
ContextMenu
from
"
./components/blocks/ContextMenu.vue
"
;
import
Notification
from
"
./components/blocks/Notification.vue
"
;
// Mixins
import
translate
from
"
@/utils/translate
"
;
export
default
{
name
:
"
FileManager
"
,
mixins
:
[
translate
],
components
:
{
Navbar
,
FolderTree
,
LeftManager
,
RightManager
,
Modal
,
InfoBlock
,
ContextMenu
,
Notification
,
},
props
:
{
/**
* LFM manual settings
*/
settings
:
{
type
:
Object
,
default
()
{
return
{};
},
},
},
data
()
{
return
{
interceptorIndex
:
{
request
:
null
,
response
:
null
,
},
};
},
created
()
{
// manual settings
this
.
$store
.
commit
(
"
fm/settings/manualSettings
"
,
this
.
settings
);
// initiate Axios
this
.
$store
.
commit
(
"
fm/settings/initAxiosSettings
"
);
this
.
requestInterceptor
();
this
.
responseInterceptor
();
// initialize app settings
this
.
$store
.
dispatch
(
"
fm/initializeApp
"
);
/**
* todo Keyboard event
*/
/*
window.addEventListener('keyup', (event) => {
event.preventDefault();
event.stopPropagation();
EventBus.$emit('keyMonitor', event);
});
*/
},
destroyed
()
{
// reset state
this
.
$store
.
dispatch
(
"
fm/resetState
"
);
// delete events
EventBus
.
$off
([
"
contextMenu
"
,
"
addNotification
"
]);
// eject interceptors
HTTP
.
interceptors
.
request
.
eject
(
this
.
interceptorIndex
.
request
);
HTTP
.
interceptors
.
response
.
eject
(
this
.
interceptorIndex
.
response
);
},
computed
:
{
...
mapState
(
"
fm
"
,
{
windowsConfig
:
(
state
)
=>
state
.
settings
.
windowsConfig
,
activeManager
:
(
state
)
=>
state
.
settings
.
activeManager
,
showModal
:
(
state
)
=>
state
.
modal
.
showModal
,
fullScreen
:
(
state
)
=>
state
.
settings
.
fullScreen
,
}),
},
methods
:
{
/**
* Add axios request interceptor
*/
requestInterceptor
()
{
this
.
interceptorIndex
.
request
=
HTTP
.
interceptors
.
request
.
use
(
(
config
)
=>
{
// overwrite base url and headers
config
.
baseURL
=
this
.
$store
.
getters
[
"
fm/settings/baseUrl
"
];
config
.
headers
=
this
.
$store
.
getters
[
"
fm/settings/headers
"
];
// loading spinner +
this
.
$store
.
commit
(
"
fm/messages/addLoading
"
);
return
config
;
},
(
error
)
=>
{
// loading spinner -
this
.
$store
.
commit
(
"
fm/messages/subtractLoading
"
);
return
Promise
.
reject
(
error
);
}
);
},
/**
* Add axios response interceptor
*/
responseInterceptor
()
{
this
.
interceptorIndex
.
response
=
HTTP
.
interceptors
.
response
.
use
(
(
response
)
=>
{
// loading spinner -
this
.
$store
.
commit
(
"
fm/messages/subtractLoading
"
);
// create notification, if find message text
if
(
Object
.
prototype
.
hasOwnProperty
.
call
(
response
.
data
,
"
result
"
))
{
if
(
response
.
data
.
result
.
message
)
{
const
message
=
{
status
:
response
.
data
.
result
.
status
,
message
:
Object
.
prototype
.
hasOwnProperty
.
call
(
this
.
lang
.
response
,
response
.
data
.
result
.
message
)
?
this
.
lang
.
response
[
response
.
data
.
result
.
message
]
:
response
.
data
.
result
.
message
,
};
// show notification
EventBus
.
$emit
(
"
addNotification
"
,
message
);
// set action result
this
.
$store
.
commit
(
"
fm/messages/setActionResult
"
,
message
);
}
}
return
response
;
},
(
error
)
=>
{
// loading spinner -
this
.
$store
.
commit
(
"
fm/messages/subtractLoading
"
);
const
errorMessage
=
{
status
:
0
,
message
:
""
,
};
const
errorNotificationMessage
=
{
status
:
"
error
"
,
message
:
""
,
};
// add message
if
(
error
.
response
)
{
errorMessage
.
status
=
error
.
response
.
status
;
if
(
error
.
response
.
data
.
message
)
{
const
trMessage
=
Object
.
prototype
.
hasOwnProperty
.
call
(
this
.
lang
.
response
,
error
.
response
.
data
.
message
)
?
this
.
lang
.
response
[
error
.
response
.
data
.
message
]
:
error
.
response
.
data
.
message
;
errorMessage
.
message
=
trMessage
;
errorNotificationMessage
.
message
=
trMessage
;
}
else
{
errorMessage
.
message
=
error
.
response
.
statusText
;
errorNotificationMessage
.
message
=
error
.
response
.
statusText
;
}
}
else
if
(
error
.
request
)
{
errorMessage
.
status
=
error
.
request
.
status
;
errorMessage
.
message
=
error
.
request
.
statusText
||
"
Network error
"
;
errorNotificationMessage
.
message
=
error
.
request
.
statusText
||
"
Network error
"
;
}
else
{
errorMessage
.
message
=
error
.
message
;
errorNotificationMessage
.
message
=
error
.
message
;
}
// set error message
this
.
$store
.
commit
(
"
fm/messages/setError
"
,
errorMessage
);
// show notification
EventBus
.
$emit
(
"
addNotification
"
,
errorNotificationMessage
);
return
Promise
.
reject
(
error
);
}
);
},
/**
* Select manager (when shown 2 file manager windows)
* @param managerName
*/
selectManager
(
managerName
)
{
if
(
this
.
activeManager
!==
managerName
)
{
this
.
$store
.
commit
(
"
fm/setActiveManager
"
,
managerName
);
}
},
},
};
</
script
>
<
style
lang=
"scss"
>
@import
"~plyr/src/sass/plyr.scss"
;
.fm
{
position
:
relative
;
height
:
100%
;
padding
:
1rem
1rem
0
;
background-color
:
white
;
&
:
-
moz-full-screen
{
background-color
:
white
;
}
&
:
-
webkit-full-screen
{
background-color
:
white
;
}
&
:fullscreen
{
background-color
:
white
;
}
.fm-body
{
display
:
flex
;
height
:
100%
;
margin-right
:
-15px
;
margin-left
:
-15px
;
position
:
relative
;
padding-top
:
1rem
;
padding-bottom
:
1rem
;
border-top
:
1px
solid
#6d757d
;
border-bottom
:
1px
solid
#6d757d
;
}
.unselectable
{
-webkit-touch-callout
:
none
;
-webkit-user-select
:
none
;
-moz-user-select
:
none
;
-ms-user-select
:
none
;
user-select
:
none
;
}
}
.fm-error
{
color
:
white
;
background-color
:
#dc3545
;
border-color
:
#dc3545
;
}
.fm-danger
{
color
:
#dc3545
;
background-color
:
white
;
border-color
:
#dc3545
;
}
.fm-warning
{
color
:
#ffc107
;
background-color
:
white
;
border-color
:
#ffc107
;
}
.fm-success
{
color
:
#28a745
;
background-color
:
white
;
border-color
:
#28a745
;
}
.fm-info
{
color
:
#17a2b8
;
background-color
:
white
;
border-color
:
#17a2b8
;
}
.fm.fm-full-screen
{
width
:
100%
;
height
:
100%
;
padding-bottom
:
0
;
}
</
style
>
tools/frontend/src/views/FileManager/components/blocks/ContextMenu.vue
0 → 100644
View file @
bae8cfdf
<
template
>
<div
ref=
"contextMenu"
v-if=
"menuVisible"
v-bind:style=
"menuStyle"
v-on:blur=
"closeMenu"
class=
"fm-context-menu"
tabindex=
"-1"
>
<ul
v-for=
"(group, index) in menu"
v-bind:key=
"`g-$
{index}`"
class="list-unstyled"
>
<li
v-for=
"(item, index) in group"
v-bind:key=
"`i-$
{index}`"
v-on:click="menuAction(item.name)"
>
<template
v-if=
"showMenuItem(item.name)"
>
<i
class=
"fa-fw"
v-bind:class=
"item.icon"
/>
{{
lang
.
contextMenu
[
item
.
name
]
}}
</
template
>
</li>
</ul>
</div>
</template>
<
script
>
/* eslint-disable no-param-reassign */
import
EventBus
from
"
@/utils/eventBus
"
;
import
translate
from
"
@/utils/translate
"
;
import
contextMenu
from
"
./mixins/contextMenu
"
;
import
contextMenuRules
from
"
./mixins/contextMenuRules
"
;
import
contextMenuActions
from
"
./mixins/contextMenuActions
"
;
export
default
{
name
:
"
ContextMenu
"
,
mixins
:
[
translate
,
contextMenu
,
contextMenuRules
,
contextMenuActions
],
data
()
{
return
{
menuVisible
:
false
,
menuStyle
:
{
top
:
0
,
left
:
0
,
},
};
},
mounted
()
{
/**
* Listen events
* 'contextMenu'
*/
EventBus
.
$on
(
"
contextMenu
"
,
(
event
)
=>
this
.
showMenu
(
event
));
},
computed
:
{
/**
* Context menu items
* @returns {*}
*/
menu
()
{
return
this
.
$store
.
state
.
fm
.
settings
.
contextMenu
;
},
},
methods
:
{
/**
* Show context menu
* @param event
*/
showMenu
(
event
)
{
if
(
this
.
selectedItems
)
{
this
.
menuVisible
=
true
;
// focus on menu
this
.
$nextTick
(()
=>
{
this
.
$refs
.
contextMenu
.
focus
();
// set menu params
this
.
setMenu
(
event
.
pageY
,
event
.
pageX
);
});
}
},
/**
* Set context menu coordinates
* @param top
* @param left
*/
setMenu
(
top
,
left
)
{
// get parent el (.fm-body)
const
el
=
this
.
$refs
.
contextMenu
.
parentNode
;
// get parent el size
const
elSize
=
el
.
getBoundingClientRect
();
// actual coordinates of the block
const
elY
=
window
.
pageYOffset
+
elSize
.
top
;
const
elX
=
window
.
pageXOffset
+
elSize
.
left
;
// calculate the preliminary coordinates
let
menuY
=
top
-
elY
;
let
menuX
=
left
-
elX
;
// calculate max X and Y coordinates
const
maxY
=
elY
+
(
el
.
offsetHeight
-
this
.
$refs
.
contextMenu
.
offsetHeight
-
25
);
const
maxX
=
elX
+
(
el
.
offsetWidth
-
this
.
$refs
.
contextMenu
.
offsetWidth
-
25
);
if
(
top
>
maxY
)
menuY
=
maxY
-
elY
;
if
(
left
>
maxX
)
menuX
=
maxX
-
elX
;
// set coordinates
this
.
menuStyle
.
top
=
`
${
menuY
}
px`
;
this
.
menuStyle
.
left
=
`
${
menuX
}
px`
;
},
/**
* Close context menu
*/
closeMenu
()
{
this
.
menuVisible
=
false
;
},
/**
* Show context menu item
* @param name
* @returns {*}
*/
showMenuItem
(
name
)
{
if
(
Object
.
prototype
.
hasOwnProperty
.
call
(
this
,
`
${
name
}
Rule`
))
{
return
this
[
`
${
name
}
Rule`
]();
}
return
false
;
},
/**
* Call actions when clicking the context menu
* @param name
*/
menuAction
(
name
)
{
if
(
Object
.
prototype
.
hasOwnProperty
.
call
(
this
,
`
${
name
}
Action`
))
{
this
[
`
${
name
}
Action`
]();
}
// close context menu
this
.
closeMenu
();
},
},
};
</
script
>
<
style
lang=
"scss"
>
.fm-context-menu
{
position
:
absolute
;
z-index
:
9997
;
background-color
:
white
;
box-shadow
:
3px
2px
5px
gray
;
border-radius
:
5px
;
&
:focus
{
outline
:
none
;
}
.list-unstyled
{
margin-bottom
:
0
;
border-bottom
:
1px
solid
rgba
(
0
,
0
,
0
,
0
.125
);
}
ul
>
li
{
padding
:
0
.4rem
1rem
;
}
ul
>
li
:not
(
.disabled
)
{
cursor
:
pointer
;
&
:hover
{
background-color
:
#f8f9fa
;
}
i
{
padding-right
:
2rem
;
}
}
}
</
style
>
tools/frontend/src/views/FileManager/components/blocks/InfoBlock.vue
0 → 100644
View file @
bae8cfdf
<
template
>
<div
class=
"justify-content-between fm-info-block"
>
<div
class=
"col-auto"
>
<span
v-show=
"selectedCount"
>
{{
`${lang.info.selected
}
${selectedCount
}
`
}}
{{
`${lang.info.selectedSize
}
${selectedFilesSize
}
`
}}
<
/span
>
<
span
v
-
show
=
"
!selectedCount
"
>
{{
`${lang.info.directories
}
${directoriesCount
}
`
}}
{{
`${lang.info.files
}
${filesCount
}
`
}}
{{
`${lang.info.size
}
${filesSize
}
`
}}
<
/span
>
<
/div
>
<
div
class
=
"
col-4
"
>
<!--
Progress
Bar
-->
<
div
class
=
"
progress
"
v
-
show
=
"
progressBar
"
>
<
div
class
=
"
progress-bar progress-bar-striped bg-info
"
role
=
"
progressbar
"
v
-
bind
:
aria
-
valuenow
=
"
progressBar
"
aria
-
valuemin
=
"
0
"
aria
-
valuemax
=
"
100
"
v
-
bind
:
style
=
"
{width: progressBar + '%'
}
"
>
{{
progressBar
}}
%
<
/div
>
<
/div
>
<
/div
>
<
div
class
=
"
col-auto text-right
"
>
<
span
v
-
show
=
"
loadingSpinner
"
>
<
i
class
=
"
fas fa-spinner fa-pulse
"
/>
<
/span
>
<
span
v
-
show
=
"
clipboardType
"
v
-
on
:
click
=
"
showModal('Clipboard')
"
v
-
bind
:
title
=
"
[ lang.clipboard.title + ' - ' + lang.clipboard[clipboardType] ]
"
>
<
i
class
=
"
far fa-clipboard
"
/>
<
/span
>
<
span
v
-
on
:
click
=
"
showModal('Status')
"
v
-
bind
:
class
=
"
[hasErrors ? 'text-danger' : 'text-success']
"
v
-
bind
:
title
=
"
lang.modal.status.title
"
>
<
i
class
=
"
fas fa-info-circle
"
/>
<
/span
>
<
/div
>
<
/div
>
<
/template
>
<
script
>
import
translate
from
'
@/utils/translate
'
;
import
helper
from
'
@/utils/helper
'
;
export
default
{
name
:
'
InfoBlock
'
,
mixins
:
[
translate
,
helper
],
computed
:
{
/**
* Active manager
* @returns {default.computed.activeManager|(function())|string|activeManager
}
*/
activeManager
()
{
return
this
.
$store
.
state
.
fm
.
activeManager
;
}
,
/**
* Progress bar value - %
* @returns {number
}
*/
progressBar
()
{
return
this
.
$store
.
state
.
fm
.
messages
.
actionProgress
;
}
,
/**
* App has errors
* @returns {boolean
}
*/
hasErrors
()
{
return
!!
this
.
$store
.
state
.
fm
.
messages
.
errors
.
length
;
}
,
/**
* Files count in selected directory
* @returns {*
}
*/
filesCount
()
{
return
this
.
$store
.
getters
[
`fm/${this.activeManager
}
/filesCount`
];
}
,
/**
* Directories count in selected directory
* @returns {*
}
*/
directoriesCount
()
{
return
this
.
$store
.
getters
[
`fm/${this.activeManager
}
/directoriesCount`
];
}
,
/**
* Files size in selected directory
* @returns {*|string
}
*/
filesSize
()
{
return
this
.
bytesToHuman
(
this
.
$store
.
getters
[
`fm/${this.activeManager
}
/filesSize`
]);
}
,
/**
* Count files and folders
* @returns {*
}
*/
selectedCount
()
{
return
this
.
$store
.
getters
[
`fm/${this.activeManager
}
/selectedCount`
];
}
,
/**
* Calculate selected files size
* @returns {*|string
}
*/
selectedFilesSize
()
{
return
this
.
bytesToHuman
(
this
.
$store
.
getters
[
`fm/${this.activeManager
}
/selectedFilesSize`
]);
}
,
/**
* Clipboard - action type
* @returns {null
}
*/
clipboardType
()
{
return
this
.
$store
.
state
.
fm
.
clipboard
.
type
;
}
,
/**
* Spinner
* @returns {number
}
*/
loadingSpinner
()
{
return
this
.
$store
.
state
.
fm
.
messages
.
loading
;
}
,
}
,
methods
:
{
/**
* Show modal window
* @param modalName
*/
showModal
(
modalName
)
{
this
.
$store
.
commit
(
'
fm/modal/setModalState
'
,
{
modalName
,
show
:
true
,
}
);
}
,
}
,
}
;
<
/script
>
<
style
lang
=
"
scss
"
>
.
fm
-
info
-
block
{
display
:
flex
;
margin
-
right
:
-
15
px
;
margin
-
left
:
-
15
px
;
padding
-
top
:
0.2
rem
;
padding
-
bottom
:
0.4
rem
;
border
-
bottom
:
1
px
solid
#
6
d757d
;
.
progress
{
margin
-
top
:
0.3
rem
;
}
.
text
-
right
>
span
{
padding
-
left
:
0.5
rem
;
cursor
:
pointer
;
}
}
<
/style
>
tools/frontend/src/views/FileManager/components/blocks/Navbar.vue
0 → 100644
View file @
bae8cfdf
<
template
>
<div
class=
"fm-navbar mb-3"
>
<div
class=
"row justify-content-between"
>
<div
class=
"col-auto"
>
<div
class=
"btn-group"
role=
"group"
>
<button
type=
"button"
class=
"btn btn-secondary"
v-bind:disabled=
"backDisabled"
v-bind:title=
"lang.btn.back"
v-on:click=
"historyBack()"
>
<i
class=
"fas fa-step-backward"
/>
</button>
<button
type=
"button"
class=
"btn btn-secondary"
v-bind:disabled=
"forwardDisabled"
v-bind:title=
"lang.btn.forward"
v-on:click=
"historyForward()"
>
<i
class=
"fas fa-step-forward"
/>
</button>
<button
type=
"button"
class=
"btn btn-secondary"
v-on:click=
"refreshAll()"
v-bind:title=
"lang.btn.refresh"
>
<i
class=
"fas fa-sync-alt"
/>
</button>
</div>
<div
class=
"btn-group"
role=
"group"
>
<button
type=
"button"
class=
"btn btn-secondary"
v-on:click=
"showModal('NewFile')"
v-bind:title=
"lang.btn.file"
>
<i
class=
"far fa-file"
/>
</button>
<button
type=
"button"
class=
"btn btn-secondary"
v-on:click=
"showModal('NewFolder')"
v-bind:title=
"lang.btn.folder"
>
<i
class=
"far fa-folder"
/>
</button>
<button
type=
"button"
class=
"btn btn-secondary"
disabled
v-if=
"uploading"
v-bind:title=
"lang.btn.upload"
>
<i
class=
"fas fa-upload"
/>
</button>
<button
type=
"button"
class=
"btn btn-secondary"
v-else
v-on:click=
"showModal('Upload')"
v-bind:title=
"lang.btn.upload"
>
<i
class=
"fas fa-upload"
/>
</button>
<button
type=
"button"
class=
"btn btn-secondary"
v-bind:disabled=
"!isAnyItemSelected"
v-on:click=
"showModal('Delete')"
v-bind:title=
"lang.btn.delete"
>
<i
class=
"fas fa-trash-alt"
/>
</button>
</div>
<div
class=
"btn-group"
role=
"group"
>
<button
type=
"button"
class=
"btn btn-secondary"
v-bind:disabled=
"!isAnyItemSelected"
v-bind:title=
"lang.btn.copy"
v-on:click=
"toClipboard('copy')"
>
<i
class=
"fas fa-copy"
/>
</button>
<button
type=
"button"
class=
"btn btn-secondary"
v-bind:disabled=
"!isAnyItemSelected"
v-bind:title=
"lang.btn.cut"
v-on:click=
"toClipboard('cut')"
>
<i
class=
"fas fa-cut"
/>
</button>
<button
type=
"button"
class=
"btn btn-secondary"
v-bind:disabled=
"!clipboardType"
v-bind:title=
"lang.btn.paste"
v-on:click=
"paste"
>
<i
class=
"fas fa-paste"
/>
</button>
</div>
<div
class=
"btn-group"
role=
"group"
>
<button
type=
"button"
class=
"btn btn-secondary"
v-bind:title=
"lang.btn.hidden"
v-on:click=
"toggleHidden"
>
<i
class=
"fas"
v-bind:class=
"[hiddenFiles ? 'fa-eye': 'fa-eye-slash']"
/>
</button>
</div>
</div>
<div
class=
"col-auto text-right"
>
<div
class=
"btn-group"
role=
"group"
>
<button
type=
"button"
class=
"btn btn-secondary"
v-bind:class=
"[viewType === 'table' ? 'active' : '']"
v-on:click=
"selectView('table')"
v-bind:title=
"lang.btn.table"
>
<i
class=
"fas fa-th-list"
/>
</button>
<button
role=
"button"
class=
"btn btn-secondary"
v-bind:class=
"[viewType === 'grid' ? 'active' : '']"
v-on:click=
"selectView('grid')"
v-bind:title=
"lang.btn.grid"
>
<i
class=
"fas fa-th"
/>
</button>
</div>
<div
class=
"btn-group"
role=
"group"
>
<button
type=
"button"
class=
"btn btn-secondary"
v-bind:title=
"lang.btn.fullScreen"
v-bind:class=
"
{ active: fullScreen }"
v-on:click="screenToggle">
<i
class=
"fas fa-expand-arrows-alt"
/>
</button>
</div>
<div
class=
"btn-group"
role=
"group"
>
<button
type=
"button"
class=
"btn btn-secondary"
v-bind:title=
"lang.btn.about"
v-on:click=
"showModal('About')"
>
<i
class=
"fas fa-question"
/>
</button>
</div>
</div>
</div>
</div>
</
template
>
<
script
>
import
translate
from
'
@/utils/translate
'
;
import
EventBus
from
'
@/utils/eventBus
'
;
export
default
{
mixins
:
[
translate
],
computed
:
{
/**
* Active manager name
* @returns {default.computed.activeManager|(function())|string|activeManager}
*/
activeManager
()
{
return
this
.
$store
.
state
.
fm
.
activeManager
;
},
/**
* Back button state
* @returns {boolean}
*/
backDisabled
()
{
return
!
this
.
$store
.
state
.
fm
[
this
.
activeManager
].
historyPointer
;
},
/**
* Forward button state
* @returns {boolean}
*/
forwardDisabled
()
{
return
this
.
$store
.
state
.
fm
[
this
.
activeManager
].
historyPointer
===
this
.
$store
.
state
.
fm
[
this
.
activeManager
].
history
.
length
-
1
;
},
/**
* Is any files or directories selected?
* @returns {boolean}
*/
isAnyItemSelected
()
{
return
this
.
$store
.
state
.
fm
[
this
.
activeManager
].
selected
.
files
.
length
>
0
||
this
.
$store
.
state
.
fm
[
this
.
activeManager
].
selected
.
directories
.
length
>
0
;
},
/**
* Manager view type - grid or table
* @returns {default.computed.viewType|(function())|string}
*/
viewType
()
{
return
this
.
$store
.
state
.
fm
[
this
.
activeManager
].
viewType
;
},
/**
* Upload files
* @returns {boolean}
*/
uploading
()
{
return
this
.
$store
.
state
.
fm
.
messages
.
actionProgress
>
0
;
},
/**
* Clipboard - action type
* @returns {null}
*/
clipboardType
()
{
return
this
.
$store
.
state
.
fm
.
clipboard
.
type
;
},
/**
* Full screen status
* @returns {default.computed.fullScreen|(function())|boolean|fullScreen|*|string}
*/
fullScreen
()
{
return
this
.
$store
.
state
.
fm
.
fullScreen
;
},
/**
* Show or Hide hidden files
* @returns {boolean}
*/
hiddenFiles
()
{
return
this
.
$store
.
state
.
fm
.
settings
.
hiddenFiles
;
},
},
methods
:
{
/**
* Refresh file manager
*/
refreshAll
()
{
this
.
$store
.
dispatch
(
'
fm/refreshAll
'
);
},
/**
* History back
*/
historyBack
()
{
this
.
$store
.
dispatch
(
`fm/
${
this
.
activeManager
}
/historyBack`
);
},
/**
* History forward
*/
historyForward
()
{
this
.
$store
.
dispatch
(
`fm/
${
this
.
activeManager
}
/historyForward`
);
},
/**
* Copy
* @param type
*/
toClipboard
(
type
)
{
this
.
$store
.
dispatch
(
'
fm/toClipboard
'
,
type
);
// show notification
if
(
type
===
'
cut
'
)
{
EventBus
.
$emit
(
'
addNotification
'
,
{
status
:
'
success
'
,
message
:
this
.
lang
.
notifications
.
cutToClipboard
,
});
}
else
if
(
type
===
'
copy
'
)
{
EventBus
.
$emit
(
'
addNotification
'
,
{
status
:
'
success
'
,
message
:
this
.
lang
.
notifications
.
copyToClipboard
,
});
}
},
/**
* Paste
*/
paste
()
{
this
.
$store
.
dispatch
(
'
fm/paste
'
);
},
/**
* Set Hide or Show hidden files
*/
toggleHidden
()
{
this
.
$store
.
commit
(
'
fm/settings/toggleHiddenFiles
'
);
},
/**
* Show modal window
* @param modalName
*/
showModal
(
modalName
)
{
// show selected modal
this
.
$store
.
commit
(
'
fm/modal/setModalState
'
,
{
modalName
,
show
:
true
,
});
},
/**
* Select view type
* @param type
*/
selectView
(
type
)
{
if
(
this
.
viewType
!==
type
)
this
.
$store
.
commit
(
`fm/
${
this
.
activeManager
}
/setView`
,
type
);
},
/**
* Full screen toggle
*/
screenToggle
()
{
const
fm
=
document
.
getElementsByClassName
(
'
fm
'
)[
0
];
if
(
!
this
.
fullScreen
)
{
if
(
fm
.
requestFullscreen
)
{
fm
.
requestFullscreen
();
}
else
if
(
fm
.
mozRequestFullScreen
)
{
fm
.
mozRequestFullScreen
();
}
else
if
(
fm
.
webkitRequestFullscreen
)
{
fm
.
webkitRequestFullscreen
();
}
else
if
(
fm
.
msRequestFullscreen
)
{
fm
.
msRequestFullscreen
();
}
}
else
if
(
document
.
exitFullscreen
)
{
document
.
exitFullscreen
();
}
else
if
(
document
.
webkitExitFullscreen
)
{
document
.
webkitExitFullscreen
();
}
else
if
(
document
.
mozCancelFullScreen
)
{
document
.
mozCancelFullScreen
();
}
else
if
(
document
.
msExitFullscreen
)
{
document
.
msExitFullscreen
();
}
this
.
$store
.
commit
(
'
fm/screenToggle
'
);
},
},
};
</
script
>
<
style
lang=
"scss"
>
.fm-navbar
{
.btn-group
{
margin-right
:
0
.4rem
;
}
}
</
style
>
tools/frontend/src/views/FileManager/components/blocks/Notification.vue
0 → 100644
View file @
bae8cfdf
<
template
>
<div
class=
"fm-notification"
>
<transition-group
name=
"notify"
>
<div
class=
"fm-notification-item"
role=
"alert"
v-for=
"(notification, index) in notifications"
v-bind:class=
"`fm-$
{notification.status}`"
v-bind:key="`notify-${index}`">
{{
notification
.
message
}}
</div>
</transition-group>
</div>
</
template
>
<
script
>
import
EventBus
from
'
@/utils/eventBus
'
;
export
default
{
name
:
'
notification
'
,
data
()
{
return
{
notifications
:
[],
};
},
mounted
()
{
/**
* Listen 'addNotification' events
*/
EventBus
.
$on
(
'
addNotification
'
,
({
status
,
message
})
=>
this
.
addNotification
(
status
,
message
));
},
methods
:
{
/**
* Show new notification
* @param status
* @param message
*/
addNotification
(
status
,
message
)
{
this
.
notifications
.
push
({
status
,
message
,
});
// timeout for closing
setTimeout
(()
=>
{
this
.
notifications
.
shift
();
},
3000
);
},
},
};
</
script
>
<
style
lang=
"scss"
>
.fm-notification
{
position
:
absolute
;
right
:
1rem
;
bottom
:
0
;
z-index
:
9999
;
width
:
350px
;
display
:
block
;
transition
:
opacity
.4s
ease
;
overflow
:
auto
;
.fm-notification-item
{
padding
:
.75rem
1
.25rem
;
margin-bottom
:
1rem
;
border
:
1px
solid
;
border-radius
:
.25rem
;
}
.notify-enter-active
{
transition
:
all
.3s
ease
;
}
.notify-leave-active
{
transition
:
all
.8s
ease
;
}
.notify-enter
,
.notify-leave-to
{
opacity
:
0
;
}
}
</
style
>
tools/frontend/src/views/FileManager/components/blocks/mixins/contextMenu.js
0 → 100644
View file @
bae8cfdf
export
default
{
computed
:
{
/**
* Selected disk
* @returns {*}
*/
selectedDisk
()
{
return
this
.
$store
.
getters
[
'
fm/selectedDisk
'
];
},
/**
* Selected items
* @returns {*}
*/
selectedItems
()
{
return
this
.
$store
.
getters
[
'
fm/selectedItems
'
];
},
/**
* Driver for selected disk
* @returns {*}
*/
selectedDiskDriver
()
{
return
this
.
$store
.
state
.
fm
.
disks
[
this
.
selectedDisk
].
driver
;
},
/**
* Multi selection
* @returns {boolean}
*/
multiSelect
()
{
return
this
.
$store
.
getters
[
'
fm/selectedItems
'
].
length
>
1
;
},
/**
* First item type - dir or file
* @returns {*}
*/
firstItemType
()
{
return
this
.
$store
.
getters
[
'
fm/selectedItems
'
][
0
].
type
;
},
},
methods
:
{
/**
* Can we show this item?
* @param extension
* @returns {boolean}
*/
canView
(
extension
)
{
// extension not found
if
(
!
extension
)
return
false
;
return
this
.
$store
.
state
.
fm
.
settings
.
imageExtensions
.
includes
(
extension
.
toLowerCase
());
},
/**
* Can we edit this file in the code editor?
* @param extension
* @returns {boolean}
*/
canEdit
(
extension
)
{
// extension not found
if
(
!
extension
)
return
false
;
return
Object
.
keys
(
this
.
$store
.
state
.
fm
.
settings
.
textExtensions
)
.
includes
(
extension
.
toLowerCase
());
},
/**
* Can we play this audio file?
* @param extension
* @returns {boolean}
*/
canAudioPlay
(
extension
)
{
// extension not found
if
(
!
extension
)
return
false
;
return
this
.
$store
.
state
.
fm
.
settings
.
audioExtensions
.
includes
(
extension
.
toLowerCase
());
},
/**
* Can we play this video file?
* @param extension
* @returns {boolean}
*/
canVideoPlay
(
extension
)
{
// extension not found
if
(
!
extension
)
return
false
;
return
this
.
$store
.
state
.
fm
.
settings
.
videoExtensions
.
includes
(
extension
.
toLowerCase
());
},
/**
* Zip archive or not
* @param extension
* @returns {boolean}
*/
isZip
(
extension
)
{
// extension not found
if
(
!
extension
)
return
false
;
return
extension
.
toLowerCase
()
===
'
zip
'
;
},
},
};
tools/frontend/src/views/FileManager/components/blocks/mixins/contextMenuActions.js
0 → 100644
View file @
bae8cfdf
import
HTTP
from
'
@/utils/get
'
;
/**
* Context menu actions
* {name}Action
*/
export
default
{
methods
:
{
/**
* Open folder
*/
openAction
()
{
// select directory
this
.
$store
.
dispatch
(
`fm/
${
this
.
$store
.
state
.
fm
.
activeManager
}
/selectDirectory`
,
{
path
:
this
.
selectedItems
[
0
].
path
,
history
:
true
,
});
},
/**
* Play music or video
*/
audioPlayAction
()
{
// show player modal
this
.
$store
.
commit
(
'
fm/modal/setModalState
'
,
{
modalName
:
'
AudioPlayer
'
,
show
:
true
,
});
},
/**
* Play music or video
*/
videoPlayAction
()
{
// show player modal
this
.
$store
.
commit
(
'
fm/modal/setModalState
'
,
{
modalName
:
'
VideoPlayer
'
,
show
:
true
,
});
},
/**
* View file
*/
viewAction
()
{
// show image
this
.
$store
.
commit
(
'
fm/modal/setModalState
'
,
{
modalName
:
'
Preview
'
,
show
:
true
,
});
},
/**
* Edit file
*/
editAction
()
{
// show text file
this
.
$store
.
commit
(
'
fm/modal/setModalState
'
,
{
modalName
:
'
TextEdit
'
,
show
:
true
,
});
},
/**
* Select file
*/
selectAction
()
{
// file callback
this
.
$store
.
dispatch
(
'
fm/url
'
,
{
disk
:
this
.
selectedDisk
,
path
:
this
.
selectedItems
[
0
].
path
,
}).
then
((
response
)
=>
{
if
(
response
.
data
.
result
.
status
===
'
success
'
)
{
this
.
$store
.
state
.
fm
.
fileCallback
(
response
.
data
.
url
);
}
});
},
/**
* Download file
*/
downloadAction
()
{
const
tempLink
=
document
.
createElement
(
'
a
'
);
tempLink
.
style
.
display
=
'
none
'
;
tempLink
.
setAttribute
(
'
download
'
,
this
.
selectedItems
[
0
].
basename
);
// download file with authorization
if
(
this
.
$store
.
getters
[
'
fm/settings/authHeader
'
])
{
HTTP
.
download
(
this
.
selectedDisk
,
this
.
selectedItems
[
0
].
path
).
then
((
response
)
=>
{
tempLink
.
href
=
window
.
URL
.
createObjectURL
(
new
Blob
([
response
.
data
]));
document
.
body
.
appendChild
(
tempLink
);
tempLink
.
click
();
document
.
body
.
removeChild
(
tempLink
);
});
}
else
{
tempLink
.
href
=
`
${
this
.
$store
.
getters
[
'
fm/settings/baseUrl
'
]}
download?disk=
${
this
.
selectedDisk
}
&path=
${
encodeURIComponent
(
this
.
selectedItems
[
0
].
path
)}
`
;
document
.
body
.
appendChild
(
tempLink
);
tempLink
.
click
();
document
.
body
.
removeChild
(
tempLink
);
}
},
/**
* Copy selected items
*/
copyAction
()
{
// add selected items to the clipboard
this
.
$store
.
dispatch
(
'
fm/toClipboard
'
,
'
copy
'
);
},
/**
* Cut selected items
*/
cutAction
()
{
// add selected items to the clipboard
this
.
$store
.
dispatch
(
'
fm/toClipboard
'
,
'
cut
'
);
},
/**
* Rename selected item
*/
renameAction
()
{
// show modal - rename
this
.
$store
.
commit
(
'
fm/modal/setModalState
'
,
{
modalName
:
'
Rename
'
,
show
:
true
,
});
},
/**
* Paste copied or cut items
*/
pasteAction
()
{
// paste items in the selected folder
this
.
$store
.
dispatch
(
'
fm/paste
'
);
},
/**
* Zip selected files
*/
zipAction
()
{
// show modal - Zip
this
.
$store
.
commit
(
'
fm/modal/setModalState
'
,
{
modalName
:
'
Zip
'
,
show
:
true
,
});
},
/**
* Unzip selected archive
*/
unzipAction
()
{
// show modal - Unzip
this
.
$store
.
commit
(
'
fm/modal/setModalState
'
,
{
modalName
:
'
Unzip
'
,
show
:
true
,
});
},
/**
* Delete selected items
*/
deleteAction
()
{
// show modal - delete
this
.
$store
.
commit
(
'
fm/modal/setModalState
'
,
{
modalName
:
'
Delete
'
,
show
:
true
,
});
},
/**
* Show properties for selected items
*/
propertiesAction
()
{
// show modal - properties
this
.
$store
.
commit
(
'
fm/modal/setModalState
'
,
{
modalName
:
'
Properties
'
,
show
:
true
,
});
},
},
};
tools/frontend/src/views/FileManager/components/blocks/mixins/contextMenuRules.js
0 → 100644
View file @
bae8cfdf
/**
* Rules for context menu items (show/hide)
* {name}Rule
*/
export
default
{
methods
:
{
/**
* Open - menu item status - show or hide
* @returns {boolean}
*/
openRule
()
{
return
!
this
.
multiSelect
&&
this
.
firstItemType
===
'
dir
'
;
},
/**
* Play audio - menu item status - show or hide
* @returns {boolean}
*/
audioPlayRule
()
{
return
this
.
selectedItems
.
every
((
elem
)
=>
elem
.
type
===
'
file
'
)
&&
this
.
selectedItems
.
every
((
elem
)
=>
this
.
canAudioPlay
(
elem
.
extension
));
},
/**
* Play video - menu item status - show or hide
* @returns {boolean}
*/
videoPlayRule
()
{
return
!
this
.
multiSelect
&&
this
.
canVideoPlay
(
this
.
selectedItems
[
0
].
extension
);
},
/**
* View - menu item status - show or hide
* @returns {boolean|*}
*/
viewRule
()
{
return
!
this
.
multiSelect
&&
this
.
firstItemType
===
'
file
'
&&
this
.
canView
(
this
.
selectedItems
[
0
].
extension
);
},
/**
* Edit - menu item status - show or hide
* @returns {boolean|*}
*/
editRule
()
{
return
!
this
.
multiSelect
&&
this
.
firstItemType
===
'
file
'
&&
this
.
canEdit
(
this
.
selectedItems
[
0
].
extension
);
},
/**
* Select - menu item status - show or hide
* @returns {boolean|null}
*/
selectRule
()
{
return
!
this
.
multiSelect
&&
this
.
firstItemType
===
'
file
'
&&
this
.
$store
.
state
.
fm
.
fileCallback
;
},
/**
* Download - menu item status - show or hide
* @returns {boolean}
*/
downloadRule
()
{
return
!
this
.
multiSelect
&&
this
.
firstItemType
===
'
file
'
;
},
/**
* Copy - menu item status - show or hide
* @returns {boolean}
*/
copyRule
()
{
return
true
;
},
/**
* Cut - menu item status - show or hide
* @returns {boolean}
*/
cutRule
()
{
return
true
;
},
/**
* Rename - menu item status - show or hide
* @returns {boolean}
*/
renameRule
()
{
return
!
this
.
multiSelect
;
},
/**
* Paste - menu item status - show or hide
* @returns {boolean}
*/
pasteRule
()
{
return
!!
this
.
$store
.
state
.
fm
.
clipboard
.
type
;
},
/**
* Zip - menu item status - show or hide
* @returns {boolean}
*/
zipRule
()
{
return
this
.
selectedDiskDriver
===
'
local
'
;
},
/**
* Unzip - menu item status - show or hide
* @returns {boolean}
*/
unzipRule
()
{
return
this
.
selectedDiskDriver
===
'
local
'
&&
!
this
.
multiSelect
&&
this
.
firstItemType
===
'
file
'
&&
this
.
isZip
(
this
.
selectedItems
[
0
].
extension
);
},
/**
* Delete - menu item status - show or hide
* @returns {boolean}
*/
deleteRule
()
{
return
true
;
},
/**
* Properties - menu item status - show or hide
* @returns {boolean}
*/
propertiesRule
()
{
return
!
this
.
multiSelect
;
},
},
};
tools/frontend/src/views/FileManager/components/manager/Breadcrumb.vue
0 → 100644
View file @
bae8cfdf
<
template
>
<div
class=
"fm-breadcrumb"
>
<nav
aria-label=
"breadcrumb"
>
<ol
class=
"breadcrumb"
v-bind:class=
"[manager === activeManager ? 'active-manager' : 'bg-light']"
>
<li
class=
"breadcrumb-item"
v-on:click=
"selectMainDirectory"
>
<span
class=
"badge badge-secondary"
>
<i
class=
"far fa-hdd"
/>
</span>
</li>
<li
class=
"breadcrumb-item text-truncate"
v-for=
"(item, index) in breadcrumb"
v-bind:key=
"index"
v-bind:class=
"[breadcrumb.length === index + 1 ? 'active' : '']"
v-on:click=
"selectDirectory(index)"
>
<span>
{{
item
}}
</span>
</li>
</ol>
</nav>
</div>
</
template
>
<
script
>
export
default
{
name
:
'
Breadcrumb
'
,
props
:
{
manager
:
{
type
:
String
,
required
:
true
},
},
computed
:
{
/**
* Active manager name
* @returns {default.computed.activeManager|(function())|string|activeManager}
*/
activeManager
()
{
return
this
.
$store
.
state
.
fm
.
activeManager
;
},
/**
* Selected Disk for this manager
* @returns {default.computed.selectedDisk|(function())|default.selectedDisk|null}
*/
selectedDisk
()
{
return
this
.
$store
.
state
.
fm
[
this
.
manager
].
selectedDisk
;
},
/**
* Selected directory for this manager
* @returns {default.computed.selectedDirectory|(function())|default.selectedDirectory|null}
*/
selectedDirectory
()
{
return
this
.
$store
.
state
.
fm
[
this
.
manager
].
selectedDirectory
;
},
/**
* Breadcrumb
* @returns {*}
*/
breadcrumb
()
{
return
this
.
$store
.
getters
[
`fm/
${
this
.
manager
}
/breadcrumb`
];
},
},
methods
:
{
/**
* Load selected directory
* @param index
*/
selectDirectory
(
index
)
{
const
path
=
this
.
breadcrumb
.
slice
(
0
,
index
+
1
).
join
(
'
/
'
);
// only if this path not selected
if
(
path
!==
this
.
selectedDirectory
)
{
// load directory
this
.
$store
.
dispatch
(
`fm/
${
this
.
manager
}
/selectDirectory`
,
{
path
,
history
:
true
});
}
},
/**
* Select main directory
*/
selectMainDirectory
()
{
if
(
this
.
selectedDirectory
)
{
this
.
$store
.
dispatch
(
`fm/
${
this
.
manager
}
/selectDirectory`
,
{
path
:
null
,
history
:
true
});
}
},
},
};
</
script
>
<
style
lang=
"scss"
>
.fm-breadcrumb
{
.breadcrumb
{
flex-wrap
:
nowrap
;
padding
:
0
.2rem
0
.3rem
;
margin-bottom
:
0
.5rem
;
&
.active-manager
{
background-color
:
#c2e5eb
;
}
.breadcrumb-item
:not
(
.active
)
:hover
{
cursor
:
pointer
;
font-weight
:
normal
;
color
:
#6d757d
;
}
}
}
</
style
>
tools/frontend/src/views/FileManager/components/manager/DiskList.vue
0 → 100644
View file @
bae8cfdf
<
template
>
<div
class=
"fm-disk-list"
>
<ul
class=
"list-inline"
>
<li
class=
"list-inline-item"
v-for=
"(disk, index) in disks"
v-bind:key=
"index"
>
<span
class=
"badge"
v-on:click=
"selectDisk(disk)"
v-bind:class=
"[disk === selectedDisk ? 'badge-secondary' : 'badge-light']"
>
<i
class=
"fa-fw far fa-hdd"
/>
{{
disk
}}
</span>
</li>
</ul>
</div>
</
template
>
<
script
>
export
default
{
name
:
'
DiskList
'
,
props
:
{
// manager name - left or right
manager
:
{
type
:
String
,
required
:
true
},
},
computed
:
{
/**
* Disk list
* @returns {Array}
*/
disks
()
{
return
this
.
$store
.
getters
[
'
fm/diskList
'
];
},
/**
* Selected Disk for this manager
* @returns {default.computed.selectedDisk|(function())|default.selectedDisk|null}
*/
selectedDisk
()
{
return
this
.
$store
.
state
.
fm
[
this
.
manager
].
selectedDisk
;
},
},
methods
:
{
/**
* Select disk
* @param disk
*/
selectDisk
(
disk
)
{
if
(
this
.
selectedDisk
!==
disk
)
{
this
.
$store
.
dispatch
(
'
fm/selectDisk
'
,
{
disk
,
manager
:
this
.
manager
,
});
}
},
},
};
</
script
>
<
style
lang=
"scss"
>
.fm-disk-list
{
ul
.list-inline
{
margin-bottom
:
0
.5rem
;
}
.badge.badge-light
{
cursor
:
pointer
;
}
}
</
style
>
tools/frontend/src/views/FileManager/components/manager/GridView.vue
0 → 100644
View file @
bae8cfdf
<
template
>
<div
class=
"fm-grid"
>
<div
class=
"d-flex align-content-start flex-wrap"
>
<div
v-if=
"!isRootPath"
v-on:click=
"levelUp"
class=
"fm-grid-item text-center"
>
<div
class=
"fm-item-icon"
>
<i
class=
"fas fa-level-up-alt fa-5x pb-2"
/>
</div>
<div
class=
"fm-item-info"
><strong>
..
</strong></div>
</div>
<div
class=
"fm-grid-item text-center unselectable"
v-for=
"(directory, index) in directories"
v-bind:key=
"`d-$
{index}`"
v-bind:title="directory.basename"
v-bind:class="{'active': checkSelect('directories', directory.path)}"
v-on:click="selectItem('directories', directory.path, $event)"
v-on:dblclick.stop="selectDirectory(directory.path)"
v-on:contextmenu.prevent="contextMenu(directory, $event)">
<div
class=
"fm-item-icon"
>
<i
class=
"fa-5x pb-2"
v-bind:class=
"(acl && directory.acl === 0) ? 'fas fa-unlock-alt' : 'far fa-folder'"
/>
</div>
<div
class=
"fm-item-info"
>
{{
directory
.
basename
}}
</div>
</div>
<div
class=
"fm-grid-item text-center unselectable"
v-for=
"(file, index) in files"
v-bind:key=
"`f-$
{index}`"
v-bind:title="file.basename"
v-bind:class="{'active': checkSelect('files', file.path)}"
v-on:click="selectItem('files', file.path, $event)"
v-on:dblclick="selectAction(file.path, file.extension)"
v-on:contextmenu.prevent="contextMenu(file, $event)">
<div
class=
"fm-item-icon"
>
<i
v-if=
"acl && file.acl === 0"
class=
"fas fa-unlock-alt fa-5x pb-2"
/>
<thumbnail
v-else-if=
"thisImage(file.extension)"
v-bind:disk=
"disk"
v-bind:file=
"file"
>
</thumbnail>
<i
v-else
class=
"far fa-5x pb-2"
v-bind:class=
"extensionToIcon(file.extension)"
/>
</div>
<div
class=
"fm-item-info"
>
{{
`${file.filename
}
.${file.extension
}
`
}}
<
br
>
{{
bytesToHuman
(
file
.
size
)
}}
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
/template
>
<
script
>
import
translate
from
'
@/utils/translate
'
;
import
helper
from
'
@/utils/helper
'
;
import
managerHelper
from
'
./mixins/manager
'
;
import
Thumbnail
from
'
./Thumbnail.vue
'
;
export
default
{
name
:
'
grid-view
'
,
components
:
{
Thumbnail
}
,
mixins
:
[
translate
,
helper
,
managerHelper
],
data
()
{
return
{
disk
:
''
,
}
;
}
,
props
:
{
manager
:
{
type
:
String
,
required
:
true
}
,
}
,
mounted
()
{
this
.
disk
=
this
.
selectedDisk
;
}
,
beforeUpdate
()
{
// if disk changed
if
(
this
.
disk
!==
this
.
selectedDisk
)
{
this
.
disk
=
this
.
selectedDisk
;
}
}
,
computed
:
{
/**
* Image extensions list
* @returns {*
}
*/
imageExtensions
()
{
return
this
.
$store
.
state
.
fm
.
settings
.
imageExtensions
;
}
,
}
,
methods
:
{
/**
* Check file extension (image or no)
* @param extension
* @returns {boolean
}
*/
thisImage
(
extension
)
{
// extension not found
if
(
!
extension
)
return
false
;
return
this
.
imageExtensions
.
includes
(
extension
.
toLowerCase
());
}
,
}
,
}
;
<
/script
>
<
style
lang
=
"
scss
"
>
.
fm
-
grid
{
padding
-
top
:
1
rem
;
.
fm
-
grid
-
item
{
position
:
relative
;
width
:
125
px
;
padding
:
0.4
rem
;
margin
-
bottom
:
1
rem
;
margin
-
right
:
1
rem
;
border
-
radius
:
5
px
;
&
.
active
{
background
-
color
:
#
c2e5eb
;
box
-
shadow
:
3
px
2
px
5
px
gray
;
}
&
:
not
(.
active
):
hover
{
background
-
color
:
#
f8f9fa
;
box
-
shadow
:
3
px
2
px
5
px
gray
;
}
.
fm
-
item
-
icon
{
cursor
:
pointer
;
}
.
fm
-
item
-
icon
>
i
,
.
fm
-
item
-
icon
>
figure
>
i
{
color
:
#
6
d757d
;
}
.
fm
-
item
-
info
{
overflow
:
hidden
;
text
-
overflow
:
ellipsis
;
white
-
space
:
nowrap
;
}
}
}
<
/style
>
tools/frontend/src/views/FileManager/components/manager/Manager.vue
0 → 100644
View file @
bae8cfdf
<
template
>
<div
class=
"fm-content d-flex flex-column"
>
<disk-list
v-bind:manager=
"manager"
/>
<breadcrumb
v-bind:manager=
"manager"
/>
<div
class=
"fm-content-body"
>
<table-view
v-if=
"viewType === 'table'"
v-bind:manager=
"manager"
/>
<grid-view
v-else
v-bind:manager=
"manager"
/>
</div>
</div>
</
template
>
<
script
>
// Components
import
DiskList
from
'
./DiskList.vue
'
;
import
Breadcrumb
from
'
./Breadcrumb.vue
'
;
import
TableView
from
'
./TableView.vue
'
;
import
GridView
from
'
./GridView.vue
'
;
export
default
{
name
:
'
Manager
'
,
components
:
{
DiskList
,
Breadcrumb
,
TableView
,
GridView
,
},
props
:
{
manager
:
{
type
:
String
,
required
:
true
},
},
computed
:
{
/**
* view type - grid or table
* @returns {default.computed.viewType|(function())|string}
*/
viewType
()
{
return
this
.
$store
.
state
.
fm
[
this
.
manager
].
viewType
;
},
},
};
</
script
>
<
style
lang=
"scss"
>
.fm-content
{
height
:
100%
;
padding-left
:
1rem
;
.fm-content-body
{
overflow
:
auto
;
}
}
</
style
>
tools/frontend/src/views/FileManager/components/manager/TableView.vue
0 → 100644
View file @
bae8cfdf
<
template
>
<div
class=
"fm-table"
>
<table
class=
"table table-sm"
>
<thead>
<tr>
<th
class=
"w-65"
v-on:click=
"sortBy('name')"
>
{{
lang
.
manager
.
table
.
name
}}
<template
v-if=
"sortSettings.field === 'name'"
>
<i
class=
"fas fa-sort-amount-down"
v-show=
"sortSettings.direction === 'down'"
/>
<i
class=
"fas fa-sort-amount-up"
v-show=
"sortSettings.direction === 'up'"
/>
</
template
>
</th>
<th
class=
"w-10"
v-on:click=
"sortBy('size')"
>
{{ lang.manager.table.size }}
<
template
v-if=
"sortSettings.field === 'size'"
>
<i
class=
"fas fa-sort-amount-down"
v-show=
"sortSettings.direction === 'down'"
/>
<i
class=
"fas fa-sort-amount-up"
v-show=
"sortSettings.direction === 'up'"
/>
</
template
>
</th>
<th
class=
"w-10"
v-on:click=
"sortBy('type')"
>
{{ lang.manager.table.type }}
<
template
v-if=
"sortSettings.field === 'type'"
>
<i
class=
"fas fa-sort-amount-down"
v-show=
"sortSettings.direction === 'down'"
/>
<i
class=
"fas fa-sort-amount-up"
v-show=
"sortSettings.direction === 'up'"
/>
</
template
>
</th>
<th
class=
"w-auto"
v-on:click=
"sortBy('date')"
>
{{ lang.manager.table.date }}
<
template
v-if=
"sortSettings.field === 'date'"
>
<i
class=
"fas fa-sort-amount-down"
v-show=
"sortSettings.direction === 'down'"
/>
<i
class=
"fas fa-sort-amount-up"
v-show=
"sortSettings.direction === 'up'"
/>
</
template
>
</th>
</tr>
</thead>
<tbody>
<tr
v-if=
"!isRootPath"
>
<td
colspan=
"4"
class=
"fm-content-item"
v-on:click=
"levelUp"
>
<i
class=
"fas fa-level-up-alt"
/>
</td>
</tr>
<tr
v-for=
"(directory, index) in directories"
v-bind:key=
"`d-${index}`"
v-bind:class=
"{'table-info': checkSelect('directories', directory.path)}"
v-on:click=
"selectItem('directories', directory.path, $event)"
v-on:contextmenu.prevent=
"contextMenu(directory, $event)"
>
<td
class=
"fm-content-item unselectable"
v-bind:class=
"(acl && directory.acl === 0) ? 'text-hidden' : ''"
v-on:dblclick=
"selectDirectory(directory.path)"
>
<i
class=
"far fa-folder"
/>
{{ directory.basename }}
</td>
<td/>
<td>
{{ lang.manager.table.folder }}
</td>
<td>
{{ timestampToDate(directory.timestamp) }}
</td>
</tr>
<tr
v-for=
"(file, index) in files"
v-bind:key=
"`f-${index}`"
v-bind:class=
"{'table-info': checkSelect('files', file.path)}"
v-on:click=
"selectItem('files', file.path, $event)"
v-on:dblclick=
"selectAction(file.path, file.extension)"
v-on:contextmenu.prevent=
"contextMenu(file, $event)"
>
<td
class=
"fm-content-item unselectable"
v-bind:class=
"(acl && file.acl === 0) ? 'text-hidden' : ''"
>
<i
class=
"far"
v-bind:class=
"extensionToIcon(file.extension)"
/>
{{ file.filename ? file.filename : file.basename }}
</td>
<td>
{{ bytesToHuman(file.size) }}
</td>
<td>
{{ file.extension }}
</td>
<td>
{{ timestampToDate(file.timestamp) }}
</td>
</tr>
</tbody>
</table>
</div>
</template>
<
script
>
import
translate
from
'
@/utils/translate
'
;
import
helper
from
'
@/utils/helper
'
;
import
managerHelper
from
'
./mixins/manager
'
;
export
default
{
name
:
'
table-view
'
,
mixins
:
[
translate
,
helper
,
managerHelper
],
props
:
{
manager
:
{
type
:
String
,
required
:
true
},
},
computed
:
{
/**
* Sort settings
* @returns {*}
*/
sortSettings
()
{
return
this
.
$store
.
state
.
fm
[
this
.
manager
].
sort
;
},
},
methods
:
{
/**
* Sort by field
* @param field
*/
sortBy
(
field
)
{
this
.
$store
.
dispatch
(
`fm/
${
this
.
manager
}
/sortBy`
,
{
field
,
direction
:
null
});
},
},
};
</
script
>
<
style
lang=
"scss"
>
.fm-table
{
thead
th
{
background
:
white
;
position
:
sticky
;
top
:
0
;
z-index
:
10
;
cursor
:
pointer
;
border-top
:
none
;
&
:hover
{
background-color
:
#f8f9fa
;
}
&
>
i
{
padding-left
:
0
.5rem
;
}
}
td
{
white-space
:
nowrap
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
}
tr
:hover
{
background-color
:
#f8f9fa
;
}
.w-10
{
width
:
10%
;
}
.w-65
{
width
:
65%
;
}
.fm-content-item
{
cursor
:
pointer
;
max-width
:
1px
;
}
.text-hidden
{
color
:
#cdcdcd
;
}
}
</
style
>
tools/frontend/src/views/FileManager/components/manager/Thumbnail.vue
0 → 100644
View file @
bae8cfdf
<
template
>
<figure
class=
"fm-thumbnail"
>
<transition
name=
"fade"
mode=
"out-in"
>
<i
v-if=
"!src"
class=
"far fa-file-image fa-5x pb-2"
/>
<img
v-else
v-bind:src=
"src"
v-bind:alt=
"file.filename"
class=
"img-thumbnail"
>
</transition>
</figure>
</
template
>
<
script
>
import
GET
from
'
@/utils/get
'
;
export
default
{
name
:
'
Thumbnail
'
,
data
()
{
return
{
src
:
''
,
};
},
props
:
{
disk
:
{
type
:
String
,
required
:
true
,
},
file
:
{
type
:
Object
,
required
:
true
,
},
},
watch
:
{
'
file.timestamp
'
:
'
loadImage
'
,
},
mounted
()
{
if
(
window
.
IntersectionObserver
)
{
const
observer
=
new
IntersectionObserver
(
(
entries
,
obs
)
=>
{
entries
.
forEach
((
entry
)
=>
{
if
(
entry
.
isIntersecting
)
{
this
.
loadImage
();
obs
.
unobserve
(
this
.
$el
);
}
});
},
{
root
:
null
,
threshold
:
'
0.5
'
,
},
);
// add observer for template
observer
.
observe
(
this
.
$el
);
}
else
{
this
.
loadImage
();
}
},
computed
:
{
/**
* Authorization required
* @return {*}
*/
auth
()
{
return
this
.
$store
.
getters
[
'
fm/settings/authHeader
'
];
},
},
methods
:
{
/**
* Load image
*/
loadImage
()
{
// if authorization required
if
(
this
.
auth
)
{
GET
.
thumbnail
(
this
.
disk
,
this
.
file
.
path
,
).
then
((
response
)
=>
{
const
mimeType
=
response
.
headers
[
'
content-type
'
].
toLowerCase
();
const
imgBase64
=
Buffer
.
from
(
response
.
data
,
'
binary
'
).
toString
(
'
base64
'
);
this
.
src
=
`data:
${
mimeType
}
;base64,
${
imgBase64
}
`
;
});
}
else
{
this
.
src
=
`
${
this
.
$store
.
getters
[
'
fm/settings/baseUrl
'
]}
thumbnails?disk=
${
this
.
disk
}
&path=
${
encodeURIComponent
(
this
.
file
.
path
)}
&v=
${
this
.
file
.
timestamp
}
`
;
}
},
},
};
</
script
>
<
style
lang=
"scss"
>
.fm-thumbnail
{
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
.img-thumbnail
{
width
:
88px
;
height
:
88px
;
}
.fade-enter-active
,
.fade-leave-active
{
transition
:
opacity
.3s
;
}
.fade-enter
,
.fade-leave-to
{
opacity
:
0
;
}
}
</
style
>
tools/frontend/src/views/FileManager/components/manager/mixins/manager.js
0 → 100644
View file @
bae8cfdf
// Event bus
import
EventBus
from
'
@/utils/eventBus
'
;
export
default
{
computed
:
{
/**
* Selected disk for this manager
* @returns {default.computed.selectedDisk|(function())|default.selectedDisk|null}
*/
selectedDisk
()
{
return
this
.
$store
.
state
.
fm
[
this
.
manager
].
selectedDisk
;
},
/**
* Selected directory for this manager
* @returns {default.computed.selectedDirectory|(function())|default.selectedDirectory|null}
*/
selectedDirectory
()
{
return
this
.
$store
.
state
.
fm
[
this
.
manager
].
selectedDirectory
;
},
/**
* Files list for selected directory
* @returns {*}
*/
files
()
{
return
this
.
$store
.
getters
[
`fm/
${
this
.
manager
}
/files`
];
},
/**
* Directories list for selected directory
* @returns {*}
*/
directories
()
{
return
this
.
$store
.
getters
[
`fm/
${
this
.
manager
}
/directories`
];
},
/**
* Selected files and folders
* @returns {default.computed.selected|(function())|selected|{directories, files}|string|*|boolean}
*/
selected
()
{
return
this
.
$store
.
state
.
fm
[
this
.
manager
].
selected
;
},
/**
* ACL On/Off
*/
acl
()
{
return
this
.
$store
.
state
.
fm
.
settings
.
acl
;
},
/**
* Check if current path is at root level
* @return {boolean}
*/
isRootPath
()
{
return
this
.
$store
.
state
.
fm
[
this
.
manager
].
selectedDirectory
===
null
;
},
},
methods
:
{
/**
* Load selected directory and show files
* @param path
*/
selectDirectory
(
path
)
{
this
.
$store
.
dispatch
(
`fm/
${
this
.
manager
}
/selectDirectory`
,
{
path
,
history
:
true
});
},
/**
* Level up directory
*/
levelUp
()
{
// if this a not root directory
if
(
this
.
selectedDirectory
)
{
// calculate up directory path
const
pathUp
=
this
.
selectedDirectory
.
split
(
'
/
'
).
slice
(
0
,
-
1
).
join
(
'
/
'
);
// load directory
this
.
$store
.
dispatch
(
`fm/
${
this
.
manager
}
/selectDirectory`
,
{
path
:
pathUp
||
null
,
history
:
true
});
}
},
/**
* Check item - selected
* @param type
* @param path
*/
checkSelect
(
type
,
path
)
{
return
this
.
selected
[
type
].
includes
(
path
);
},
/**
* Select items in list (files + folders)
* @param type
* @param path
* @param event
*/
selectItem
(
type
,
path
,
event
)
{
// search in selected array
const
alreadySelected
=
this
.
selected
[
type
].
includes
(
path
);
// if pressed Ctrl -> multi select
if
(
event
.
ctrlKey
||
event
.
metaKey
)
{
if
(
!
alreadySelected
)
{
// add new selected item
this
.
$store
.
commit
(
`fm/
${
this
.
manager
}
/setSelected`
,
{
type
,
path
});
}
else
{
// remove selected item
this
.
$store
.
commit
(
`fm/
${
this
.
manager
}
/removeSelected`
,
{
type
,
path
});
}
}
// single select
if
(
!
event
.
ctrlKey
&&
!
alreadySelected
&&
!
event
.
metaKey
)
{
this
.
$store
.
commit
(
`fm/
${
this
.
manager
}
/changeSelected`
,
{
type
,
path
});
}
},
/**
* Show context menu
* @param item
* @param event
*/
contextMenu
(
item
,
event
)
{
// el type
const
type
=
item
.
type
===
'
dir
'
?
'
directories
'
:
'
files
'
;
// search in selected array
const
alreadySelected
=
this
.
selected
[
type
].
includes
(
item
.
path
);
// select this element
if
(
!
alreadySelected
)
{
// select item
this
.
$store
.
commit
(
`fm/
${
this
.
manager
}
/changeSelected`
,
{
type
,
path
:
item
.
path
,
});
}
// create event
EventBus
.
$emit
(
'
contextMenu
'
,
event
);
},
/**
* Select and Action
* @param path
* @param extension
*/
selectAction
(
path
,
extension
)
{
// if is set fileCallback
if
(
this
.
$store
.
state
.
fm
.
fileCallback
)
{
this
.
$store
.
dispatch
(
'
fm/url
'
,
{
disk
:
this
.
selectedDisk
,
path
,
}).
then
((
response
)
=>
{
if
(
response
.
data
.
result
.
status
===
'
success
'
)
{
this
.
$store
.
state
.
fm
.
fileCallback
(
response
.
data
.
url
);
}
});
return
;
}
// if extension not defined
if
(
!
extension
)
{
return
;
}
// show, play..
if
(
this
.
$store
.
state
.
fm
.
settings
.
imageExtensions
.
includes
(
extension
.
toLowerCase
()))
{
// show image
this
.
$store
.
commit
(
'
fm/modal/setModalState
'
,
{
modalName
:
'
Preview
'
,
show
:
true
,
});
}
else
if
(
Object
.
keys
(
this
.
$store
.
state
.
fm
.
settings
.
textExtensions
)
.
includes
(
extension
.
toLowerCase
()))
{
// show text file
this
.
$store
.
commit
(
'
fm/modal/setModalState
'
,
{
modalName
:
'
TextEdit
'
,
show
:
true
,
});
}
else
if
(
this
.
$store
.
state
.
fm
.
settings
.
audioExtensions
.
includes
(
extension
.
toLowerCase
()))
{
// show player modal
this
.
$store
.
commit
(
'
fm/modal/setModalState
'
,
{
modalName
:
'
AudioPlayer
'
,
show
:
true
,
});
}
else
if
(
this
.
$store
.
state
.
fm
.
settings
.
videoExtensions
.
includes
(
extension
.
toLowerCase
()))
{
// show player modal
this
.
$store
.
commit
(
'
fm/modal/setModalState
'
,
{
modalName
:
'
VideoPlayer
'
,
show
:
true
,
});
}
else
if
(
extension
.
toLowerCase
()
===
'
pdf
'
)
{
// show pdf document
this
.
$store
.
dispatch
(
'
fm/openPDF
'
,
{
disk
:
this
.
selectedDisk
,
path
,
});
}
},
},
};
tools/frontend/src/views/FileManager/components/modals/Modal.vue
0 → 100644
View file @
bae8cfdf
<
template
>
<transition
name=
"fm-modal"
>
<div
class=
"fm-modal"
ref=
"fmModal"
v-on:click=
"hideModal"
>
<div
class=
"modal-dialog"
role=
"document"
v-bind:class=
"modalSize"
v-on:click
.
stop
>
<component
v-bind:is=
"modalName"
/>
</div>
</div>
</transition>
</
template
>
<
script
>
import
NewFile
from
'
./views/NewFile.vue
'
;
import
NewFolder
from
'
./views/NewFolder.vue
'
;
import
Upload
from
'
./views/Upload.vue
'
;
import
Delete
from
'
./views/Delete.vue
'
;
import
Clipboard
from
'
./views/Clipboard.vue
'
;
import
Status
from
'
./views/Status.vue
'
;
import
Rename
from
'
./views/Rename.vue
'
;
import
Properties
from
'
./views/Properties.vue
'
;
import
Preview
from
'
./views/Preview.vue
'
;
import
TextEdit
from
'
./views/TextEdit.vue
'
;
import
AudioPlayer
from
'
./views/AudioPlayer.vue
'
;
import
VideoPlayer
from
'
./views/VideoPlayer.vue
'
;
import
Zip
from
'
./views/Zip.vue
'
;
import
Unzip
from
'
./views/Unzip.vue
'
;
import
About
from
'
./views/About.vue
'
;
export
default
{
name
:
'
Modal
'
,
components
:
{
NewFile
,
NewFolder
,
Upload
,
Delete
,
Clipboard
,
Status
,
Rename
,
Properties
,
Preview
,
TextEdit
,
AudioPlayer
,
VideoPlayer
,
Zip
,
Unzip
,
About
,
},
mounted
()
{
// set height
this
.
$store
.
commit
(
'
fm/modal/setModalBlockHeight
'
,
this
.
$refs
.
fmModal
.
offsetHeight
);
},
computed
:
{
/**
* Selected modal name
* @returns {null|*}
*/
modalName
()
{
return
this
.
$store
.
state
.
fm
.
modal
.
modalName
;
},
/**
* Modal size style
* @returns {{'modal-lg': boolean, 'modal-sm': boolean}}
*/
modalSize
()
{
return
{
'
modal-xl
'
:
this
.
modalName
===
'
Preview
'
||
this
.
modalName
===
'
TextEdit
'
,
'
modal-lg
'
:
this
.
modalName
===
'
VideoPlayer
'
,
'
modal-sm
'
:
false
,
};
},
},
methods
:
{
/**
* Hide modal window
*/
hideModal
()
{
this
.
$store
.
commit
(
'
fm/modal/clearModal
'
);
},
},
};
</
script
>
<
style
lang=
"scss"
>
.fm-modal
{
position
:
absolute
;
z-index
:
9998
;
top
:
0
;
bottom
:
0
;
left
:
0
;
right
:
0
;
width
:
100%
;
height
:
100%
;
background-color
:
rgba
(
0
,
0
,
0
,
.35
);
display
:
block
;
transition
:
opacity
.4s
ease
;
overflow
:
auto
;
.modal-xl
{
max-width
:
96%
;
}
}
.fm-modal-enter-active
,
.fm-modal-leave-active
{
transition
:
opacity
.5s
;
}
.fm-modal-enter
,
.fm-modal-leave-to
{
opacity
:
0
;
}
</
style
>
tools/frontend/src/views/FileManager/components/modals/additions/Cropper.vue
0 → 100644
View file @
bae8cfdf
<
template
>
<div
class=
"fm-additions-cropper"
>
<div
class=
"row"
v-bind:style=
"
{ 'max-height': maxHeight + 'px' }">
<div
class=
"col-sm-9 cropper-block"
>
<img
v-bind:src=
"imgSrc"
ref=
"fmCropper"
v-bind:alt=
"selectedItem.basename"
/>
</div>
<div
class=
"col-sm-3 pl-0"
>
<div
class=
"cropper-preview"
></div>
<div
class=
"cropper-data"
>
<div
class=
"input-group input-group-sm"
>
<span
class=
"input-group-prepend"
>
<label
class=
"input-group-text"
for=
"dataX"
>
X
</label>
</span>
<input
v-model.number=
"x"
type=
"text"
class=
"form-control"
id=
"dataX"
/>
<span
class=
"input-group-append"
>
<span
class=
"input-group-text"
>
px
</span>
</span>
</div>
<div
class=
"input-group input-group-sm"
>
<span
class=
"input-group-prepend"
>
<label
class=
"input-group-text"
for=
"dataY"
>
Y
</label>
</span>
<input
v-model.number=
"y"
type=
"text"
class=
"form-control"
id=
"dataY"
/>
<span
class=
"input-group-append"
>
<span
class=
"input-group-text"
>
px
</span>
</span>
</div>
<div
class=
"input-group input-group-sm"
>
<span
class=
"input-group-prepend"
>
<label
class=
"input-group-text"
for=
"dataWidth"
>
Width
</label>
</span>
<input
v-model.number=
"width"
type=
"text"
class=
"form-control"
id=
"dataWidth"
/>
<span
class=
"input-group-append"
>
<span
class=
"input-group-text"
>
px
</span>
</span>
</div>
<div
class=
"input-group input-group-sm"
>
<span
class=
"input-group-prepend"
>
<label
class=
"input-group-text"
for=
"dataHeight"
>
Height
</label>
</span>
<input
v-model.number=
"height"
type=
"text"
class=
"form-control"
id=
"dataHeight"
/>
<span
class=
"input-group-append"
>
<span
class=
"input-group-text"
>
px
</span>
</span>
</div>
<div
class=
"input-group input-group-sm"
>
<span
class=
"input-group-prepend"
>
<label
class=
"input-group-text"
for=
"dataRotate"
>
Rotate
</label>
</span>
<input
v-model.number=
"rotate"
type=
"text"
class=
"form-control"
id=
"dataRotate"
/>
<span
class=
"input-group-append"
>
<span
class=
"input-group-text"
>
deg
</span>
</span>
</div>
<div
class=
"input-group input-group-sm"
>
<span
class=
"input-group-prepend"
>
<label
class=
"input-group-text"
for=
"dataScaleX"
>
ScaleX
</label>
</span>
<input
v-model.number=
"scaleX"
type=
"text"
class=
"form-control"
id=
"dataScaleX"
/>
</div>
<div
class=
"input-group input-group-sm"
>
<span
class=
"input-group-prepend"
>
<label
class=
"input-group-text"
for=
"dataScaleY"
>
ScaleY
</label>
</span>
<input
v-model.number=
"scaleY"
type=
"text"
class=
"form-control"
id=
"dataScaleY"
/>
</div>
<button
v-on:click=
"setData()"
v-bind:title=
"lang.modal.cropper.apply"
type=
"button"
class=
"btn btn-block btn-sm btn-info mb-2"
>
<i
class=
"fas fa-check"
/>
</button>
</div>
</div>
</div>
<div
class=
"d-flex justify-content-between"
>
<div>
<div
class=
"btn-group mr-2"
role=
"group"
aria-label=
"Scale"
>
<button
v-on:click=
"cropMove(-10, 0)"
class=
"btn btn-info"
>
<i
class=
"fas fa-arrow-left"
/>
</button>
<button
v-on:click=
"cropMove(10, 0)"
class=
"btn btn-info"
>
<i
class=
"fas fa-arrow-right"
/>
</button>
<button
v-on:click=
"cropMove(0, -10)"
class=
"btn btn-info"
>
<i
class=
"fas fa-arrow-up"
/>
</button>
<button
v-on:click=
"cropMove(0, 10)"
class=
"btn btn-info"
>
<i
class=
"fas fa-arrow-down"
/>
</button>
</div>
<div
class=
"btn-group mr-2"
role=
"group"
aria-label=
"Scale"
>
<button
v-on:click=
"cropScaleX()"
class=
"btn btn-info"
>
<i
class=
"fas fa-arrows-alt-h"
/>
</button>
<button
v-on:click=
"cropScaleY()"
class=
"btn btn-info"
>
<i
class=
"fas fa-arrows-alt-v"
/>
</button>
</div>
<div
class=
"btn-group mr-2"
role=
"group"
aria-label=
"Rotate"
>
<button
v-on:click=
"cropRotate(-45)"
class=
"btn btn-info"
>
<i
class=
"fas fa-undo"
/>
</button>
<button
v-on:click=
"cropRotate(45)"
class=
"btn btn-info"
>
<i
class=
"fas fa-redo"
/>
</button>
</div>
<div
class=
"btn-group mr-2"
role=
"group"
aria-label=
"Rotate"
>
<button
v-on:click=
"cropZoom(0.1)"
class=
"btn btn-info"
>
<i
class=
"fas fa-search-plus"
/>
</button>
<button
v-on:click=
"cropZoom(-0.1)"
class=
"btn btn-info"
>
<i
class=
"fas fa-search-minus"
/>
</button>
</div>
<button
v-on:click=
"cropReset()"
v-bind:title=
"lang.modal.cropper.reset"
class=
"btn btn-info mr-2"
>
<i
class=
"fas fa-sync-alt"
/>
</button>
<button
v-on:click=
"cropSave()"
v-bind:title=
"lang.modal.cropper.save"
class=
"btn btn-danger mr-2"
>
<i
class=
"far fa-save"
/>
</button>
</div>
<span
class=
"d-block"
>
<button
v-on:click=
"$emit('closeCropper')"
class=
"btn btn-light"
>
{{
lang
.
btn
.
back
}}
</button>
</span>
</div>
</div>
</
template
>
<
script
>
import
Cropper
from
"
cropperjs
"
;
import
translate
from
"
@/utils/translate
"
;
export
default
{
name
:
"
Cropper
"
,
mixins
:
[
translate
],
props
:
{
imgSrc
:
{
required
:
true
},
maxHeight
:
{
type
:
Number
,
required
:
true
},
},
data
()
{
return
{
cropper
:
{},
height
:
0
,
width
:
0
,
x
:
0
,
y
:
0
,
rotate
:
0
,
scaleX
:
1
,
scaleY
:
1
,
};
},
mounted
()
{
// set cropper instance
this
.
cropper
=
new
Cropper
(
this
.
$refs
.
fmCropper
,
{
preview
:
"
.cropper-preview
"
,
crop
:
(
e
)
=>
{
this
.
x
=
Math
.
round
(
e
.
detail
.
x
);
this
.
y
=
Math
.
round
(
e
.
detail
.
y
);
this
.
height
=
Math
.
round
(
e
.
detail
.
height
);
this
.
width
=
Math
.
round
(
e
.
detail
.
width
);
this
.
rotate
=
typeof
e
.
detail
.
rotate
!==
"
undefined
"
?
e
.
detail
.
rotate
:
""
;
this
.
scaleX
=
typeof
e
.
detail
.
scaleX
!==
"
undefined
"
?
e
.
detail
.
scaleX
:
""
;
this
.
scaleY
=
typeof
e
.
detail
.
scaleY
!==
"
undefined
"
?
e
.
detail
.
scaleY
:
""
;
},
});
},
beforeDestroy
()
{
this
.
cropper
.
destroy
();
},
computed
:
{
/**
* Selected file
* @returns {*}
*/
selectedItem
()
{
return
this
.
$store
.
getters
[
"
fm/selectedItems
"
][
0
];
},
},
methods
:
{
/**
* Move
* @param x
* @param y
*/
cropMove
(
x
,
y
)
{
this
.
cropper
.
move
(
x
,
y
);
},
/**
* Scale - mirroring Y
*/
cropScaleY
()
{
this
.
cropper
.
scale
(
1
,
this
.
cropper
.
getData
().
scaleY
===
1
?
-
1
:
1
);
},
/**
* Scale - mirroring X
*/
cropScaleX
()
{
this
.
cropper
.
scale
(
this
.
cropper
.
getData
().
scaleX
===
1
?
-
1
:
1
,
1
);
},
/**
* Rotate
* @param grade
*/
cropRotate
(
grade
)
{
this
.
cropper
.
rotate
(
grade
);
},
/**
* Zoom
* @param ratio
*/
cropZoom
(
ratio
)
{
this
.
cropper
.
zoom
(
ratio
);
},
/**
* Reset
*/
cropReset
()
{
this
.
cropper
.
reset
();
},
/**
* Set data from form
*/
setData
()
{
this
.
cropper
.
setData
({
x
:
this
.
x
,
y
:
this
.
y
,
width
:
this
.
width
,
height
:
this
.
height
,
rotate
:
this
.
rotate
,
scaleX
:
this
.
scaleX
,
scaleY
:
this
.
scaleY
,
});
},
/**
* Save cropped image
*/
cropSave
()
{
this
.
cropper
.
getCroppedCanvas
().
toBlob
(
(
blob
)
=>
{
const
formData
=
new
FormData
();
// add disk name
formData
.
append
(
"
disk
"
,
this
.
$store
.
getters
[
"
fm/selectedDisk
"
]);
// add path
formData
.
append
(
"
path
"
,
this
.
selectedItem
.
dirname
);
// new image
formData
.
append
(
"
file
"
,
blob
,
this
.
selectedItem
.
basename
);
this
.
$store
.
dispatch
(
"
fm/updateFile
"
,
formData
).
then
((
response
)
=>
{
// if file updated successfully
if
(
response
.
data
.
result
.
status
===
"
success
"
)
{
// close cropper
this
.
$emit
(
"
closeCropper
"
);
}
});
},
this
.
selectedItem
.
extension
!==
"
jpg
"
?
`image/
${
this
.
selectedItem
.
extension
}
`
:
"
image/jpeg
"
);
},
},
};
</
script
>
<
style
lang=
"scss"
>
@import
"~cropperjs/dist/cropper.css"
;
.fm-additions-cropper
{
overflow
:
hidden
;
&
>
.row
{
flex-wrap
:
nowrap
;
}
.cropper-block
{
overflow
:
hidden
;
img
{
max-width
:
100%
;
}
}
.col-sm-3
{
overflow
:
auto
;
&
:
:-
webkit-scrollbar
{
display
:
none
;
}
}
.cropper-preview
{
margin-bottom
:
1rem
;
overflow
:
hidden
;
height
:
200px
;
img
{
max-width
:
100%
;
}
}
.cropper-data
{
padding-left
:
1rem
;
padding-right
:
1rem
;
&
>
.input-group
{
margin-bottom
:
0
.5rem
;
}
.input-group-prepend
.input-group-text
{
min-width
:
4rem
;
}
.input-group-append
.input-group-text
{
min-width
:
3rem
;
}
}
&
>
.d-flex
{
padding
:
1rem
;
border-top
:
1px
solid
#e9ecef
;
}
}
</
style
>
tools/frontend/src/views/FileManager/components/modals/additions/SelectedFileList.vue
0 → 100644
View file @
bae8cfdf
<
template
>
<div
class=
"fm-additions-file-list"
>
<div
class=
"d-flex justify-content-between"
v-for=
"(item, index) in selectedItems"
v-bind:key=
"index"
>
<div
class=
"w-75 text-truncate"
>
<span
v-if=
"item.type === 'dir'"
>
<i
class=
"far fa-folder"
/>
{{
item
.
basename
}}
</span>
<span
v-else
>
<i
class=
"far"
v-bind:class=
"extensionToIcon(item.extension)"
/>
{{
item
.
basename
}}
</span>
</div>
<div
class=
"text-right"
v-if=
"item.type === 'file'"
>
{{
bytesToHuman
(
item
.
size
)
}}
</div>
</div>
</div>
</
template
>
<
script
>
import
helper
from
"
@/utils/helper
"
;
export
default
{
name
:
"
SelectedFileList
"
,
mixins
:
[
helper
],
computed
:
{
/**
* Selected files and folders
* @returns {*}
*/
selectedItems
()
{
return
this
.
$store
.
getters
[
"
fm/selectedItems
"
];
},
},
};
</
script
>
<
style
lang=
"scss"
>
.fm-additions-file-list
{
.far
{
padding-right
:
0
.5rem
;
}
}
</
style
>
tools/frontend/src/views/FileManager/components/modals/mixins/modal.js
0 → 100644
View file @
bae8cfdf
export
default
{
directives
:
{
/**
* AutoFocus for inputs
*/
focus
:
{
inserted
(
el
)
{
el
.
focus
();
},
},
},
computed
:
{
/**
* Active manager
* @returns {default.computed.activeManager|(function())|string|activeManager}
*/
activeManager
()
{
return
this
.
$store
.
state
.
fm
.
activeManager
;
},
},
methods
:
{
/**
* Hide modal window
*/
hideModal
()
{
this
.
$store
.
commit
(
'
fm/modal/setModalState
'
,
{
modalName
:
null
,
show
:
false
,
});
},
},
};
tools/frontend/src/views/FileManager/components/modals/views/About.vue
0 → 100644
View file @
bae8cfdf
<
template
>
<div
class=
"modal-content fm-modal-about"
>
<div
class=
"modal-header"
>
<h5
class=
"modal-title"
>
{{
lang
.
modal
.
about
.
title
}}
</h5>
<button
type=
"button"
class=
"close"
aria-label=
"Close"
v-on:click=
"hideModal"
>
<span
aria-hidden=
"true"
>
×
</span>
</button>
</div>
<div
class=
"modal-body"
>
<strong>
{{
lang
.
modal
.
about
.
name
}}
</strong>
<hr>
<dl
class=
"row"
>
<dt
class=
"col-3"
>
{{
lang
.
modal
.
about
.
version
}}
:
</dt>
<dd
class=
"col-9"
>
{{
version
}}
</dd>
<dt
class=
"col-3"
>
{{
lang
.
modal
.
about
.
developer
}}
:
</dt>
<dd
class=
"col-9"
>
Aleksandr Manekin (alexusmai@gmail.com)
</dd>
<dt
class=
"col-3"
>
GitHub:
</dt>
<dd
class=
"col-9"
>
<a
href=
"https://github.com/alexusmai/laravel-file-manager"
target=
"_blank"
>
alexusmai/laravel-file-manager
</a>
<br>
<a
href=
"https://github.com/alexusmai/vue-laravel-file-manager"
target=
"_blank"
>
alexusmai/vue-laravel-file-manager
</a>
</dd>
</dl>
</div>
</div>
</
template
>
<
script
>
import
modal
from
'
../mixins/modal
'
;
import
translate
from
'
@/utils/translate
'
;
export
default
{
name
:
'
About
'
,
mixins
:
[
modal
,
translate
],
computed
:
{
/**
* App version
* @returns {*}
*/
version
()
{
return
this
.
$store
.
state
.
fm
.
settings
.
version
;
},
},
};
</
script
>
tools/frontend/src/views/FileManager/components/modals/views/AudioPlayer.vue
0 → 100644
View file @
bae8cfdf
<
template
>
<div
class=
"modal-content fm-modal-audio-player"
>
<div
class=
"modal-header"
>
<h5
class=
"modal-title"
>
{{
lang
.
modal
.
audioPlayer
.
title
}}
</h5>
<button
type=
"button"
class=
"close"
aria-label=
"Close"
v-on:click=
"hideModal"
>
<span
aria-hidden=
"true"
>
×
</span>
</button>
</div>
<div
class=
"modal-body"
>
<audio
ref=
"fmAudio"
controls
/>
<hr>
<div
class=
"d-flex justify-content-between py-2 px-2"
v-bind:class=
"playingIndex === index ? 'bg-light' : ''"
v-for=
"(item, index) in audioFiles"
v-bind:key=
"index"
>
<div
class=
"w-75 text-truncate"
>
<span
class=
"text-muted pr-2"
>
{{
index
}}
.
</span>
{{
item
.
basename
}}
</div>
<template
v-if=
"playingIndex === index"
>
<div
v-if=
"status === 'playing'"
>
<i
v-on:click=
"togglePlay()"
class=
"fas fa-play active"
/>
</div>
<div
v-else
>
<i
v-on:click=
"togglePlay()"
class=
"fas fa-pause"
/>
</div>
</
template
>
<
template
v-else
>
<div>
<i
v-on:click=
"selectTrack(index)"
class=
"fas fa-play"
/>
</div>
</
template
>
</div>
</div>
</div>
</template>
<
script
>
import
Plyr
from
'
plyr
'
;
import
modal
from
'
../mixins/modal
'
;
import
translate
from
'
@/utils/translate
'
;
export
default
{
name
:
'
Player
'
,
mixins
:
[
modal
,
translate
],
data
()
{
return
{
player
:
{},
playingIndex
:
0
,
status
:
'
paused
'
,
};
},
mounted
()
{
// initiate player
this
.
player
=
new
Plyr
(
this
.
$refs
.
fmAudio
,
{
speed
:
{
selected
:
1
,
options
:
[
0.5
,
1
,
1.5
],
},
});
// select first item in the list
this
.
setSource
(
this
.
playingIndex
);
// add event listeners
this
.
player
.
on
(
'
play
'
,
()
=>
{
this
.
status
=
'
playing
'
;
});
this
.
player
.
on
(
'
pause
'
,
()
=>
{
this
.
status
=
'
paused
'
;
});
this
.
player
.
on
(
'
ended
'
,
()
=>
{
if
(
this
.
audioFiles
.
length
>
this
.
playingIndex
+
1
)
{
// play next track
this
.
selectTrack
(
this
.
playingIndex
+
1
);
}
});
},
beforeDestroy
()
{
// destroy player
this
.
player
.
destroy
();
},
computed
:
{
/**
* Selected disk
* @returns {*}
*/
selectedDisk
()
{
return
this
.
$store
.
getters
[
'
fm/selectedDisk
'
];
},
/**
* Audio files list
* @returns {*}
*/
audioFiles
()
{
return
this
.
$store
.
getters
[
'
fm/selectedItems
'
];
},
},
methods
:
{
/**
* Select another audio track
* @param index
*/
selectTrack
(
index
)
{
if
(
this
.
player
.
playing
)
{
// stop playing
this
.
player
.
stop
();
}
// load new source
this
.
setSource
(
index
);
// start play
this
.
player
.
play
();
this
.
playingIndex
=
index
;
},
/**
* Set source to audio player
* @param index
*/
setSource
(
index
)
{
this
.
player
.
source
=
{
type
:
'
audio
'
,
title
:
this
.
audioFiles
[
index
].
filename
,
sources
:
[{
src
:
`
${
this
.
$store
.
getters
[
'
fm/settings/baseUrl
'
]}
stream-file?disk=
${
this
.
selectedDisk
}
&path=
${
encodeURIComponent
(
this
.
audioFiles
[
index
].
path
)}
`
,
type
:
`audio/
${
this
.
audioFiles
[
index
].
extension
}
`
,
}],
};
},
/**
* Play/Pause
*/
togglePlay
()
{
this
.
player
.
togglePlay
();
},
},
};
</
script
>
<
style
lang=
"scss"
>
.fm-modal-audio-player
{
.fas.fa-play
{
color
:
gray
;
opacity
:
0
.1
;
cursor
:
pointer
;
&
:hover
{
opacity
:
0
.5
;
}
&
.active
{
opacity
:
1
;
color
:
deepskyblue
;
}
}
.fas.fa-pause
{
color
:
gray
;
opacity
:
0
.5
;
cursor
:
pointer
;
}
}
</
style
>
tools/frontend/src/views/FileManager/components/modals/views/Clipboard.vue
0 → 100644
View file @
bae8cfdf
<
template
>
<div
class=
"modal-content fm-modal-clipboard"
>
<div
class=
"modal-header"
>
<h5
class=
"modal-title"
>
{{
lang
.
clipboard
.
title
}}
</h5>
<button
type=
"button"
class=
"close"
aria-label=
"Close"
v-on:click=
"hideModal"
>
<span
aria-hidden=
"true"
>
×
</span>
</button>
</div>
<div
class=
"modal-body"
>
<template
v-if=
"clipboard.type"
>
<div
class=
"d-flex justify-content-between"
>
<div
class=
"w-75 text-truncate"
>
<span>
<i
class=
"far fa-hdd"
/>
{{
clipboard
.
disk
}}
</span>
</div>
<div
class=
"text-right text-muted"
>
<span
v-bind:title=
"`$
{lang.clipboard.actionType} - ${lang.clipboard[clipboard.type]}`">
<i
v-if=
"clipboard.type === 'copy'"
class=
"fas fa-copy"
/>
<i
v-else
class=
"fas fa-cut"
/>
</span>
</div>
</div>
<hr>
<div
class=
"d-flex justify-content-between"
v-for=
"(dir, index) in directories"
v-bind:key=
"`d-$
{index}`">
<div
class=
"w-75 text-truncate"
>
<span>
<i
class=
"far fa-folder"
/>
{{
dir
.
name
}}
</span>
</div>
<div
class=
"text-right"
>
<button
type=
"button"
class=
"close"
v-bind:title=
"lang.btn.delete"
v-on:click=
"deleteItem('directories', dir.path)"
>
<span
aria-hidden=
"true"
>
×
</span>
</button>
</div>
</div>
<div
class=
"d-flex justify-content-between"
v-for=
"(file, index) in files"
v-bind:key=
"`f-$
{index}`">
<div
class=
"w-75 text-truncate"
>
<span>
<i
class=
"far"
v-bind:class=
"file.icon"
/>
{{
file
.
name
}}
</span>
</div>
<div
class=
"text-right"
>
<button
type=
"button"
class=
"close"
v-bind:title=
"lang.btn.delete"
v-on:click=
"deleteItem('files', file.path)"
>
<span
aria-hidden=
"true"
>
×
</span>
</button>
</div>
</div>
</
template
>
<
template
v-else
>
<span>
{{
lang
.
clipboard
.
none
}}
</span>
</
template
>
</div>
<div
class=
"modal-footer"
>
<button
class=
"btn btn-danger"
v-bind:disabled=
"!clipboard.type"
v-on:click=
"resetClipboard"
>
{{ lang.btn.clear }}
</button>
<button
class=
"btn btn-light"
v-on:click=
"hideModal"
>
{{ lang.btn.cancel }}
</button>
</div>
</div>
</template>
<
script
>
import
modal
from
'
../mixins/modal
'
;
import
translate
from
'
@/utils/translate
'
;
import
helper
from
'
@/utils/helper
'
;
export
default
{
name
:
'
Clipboard
'
,
mixins
:
[
modal
,
translate
,
helper
],
computed
:
{
/**
* Clipboard state
* @returns {*}
*/
clipboard
()
{
return
this
.
$store
.
state
.
fm
.
clipboard
;
},
/**
* Paths and names for directories
* @returns {{path: *, name: *}[]}
*/
directories
()
{
return
this
.
$store
.
state
.
fm
.
clipboard
.
directories
.
map
((
item
)
=>
({
path
:
item
,
name
:
item
.
split
(
'
/
'
).
slice
(
-
1
)[
0
],
}));
},
/**
* File names, paths and icons
* @returns {{path: *, name: *, icon: *}[]}
*/
files
()
{
return
this
.
$store
.
state
.
fm
.
clipboard
.
files
.
map
((
item
)
=>
{
const
name
=
item
.
split
(
'
/
'
).
slice
(
-
1
)[
0
];
return
{
path
:
item
,
name
,
icon
:
this
.
extensionToIcon
(
name
.
split
(
'
.
'
).
slice
(
-
1
)[
0
]),
};
});
},
},
methods
:
{
/**
* Delete item from clipboard
* @param type
* @param path
*/
deleteItem
(
type
,
path
)
{
this
.
$store
.
commit
(
'
fm/truncateClipboard
'
,
{
type
,
path
});
},
/**
* Reset clipboard
*/
resetClipboard
()
{
this
.
$store
.
commit
(
'
fm/resetClipboard
'
);
},
},
};
</
script
>
<
style
lang=
"scss"
>
.fm-modal-clipboard
{
.modal-body
.far
{
padding-right
:
0
.5rem
;
}
}
</
style
>
tools/frontend/src/views/FileManager/components/modals/views/Delete.vue
0 → 100644
View file @
bae8cfdf
<
template
>
<div
class=
"modal-content fm-modal-delete"
>
<div
class=
"modal-header"
>
<h5
class=
"modal-title"
>
{{
lang
.
modal
.
delete
.
title
}}
</h5>
<button
type=
"button"
class=
"close"
aria-label=
"Close"
v-on:click=
"hideModal"
>
<span
aria-hidden=
"true"
>
×
</span>
</button>
</div>
<div
class=
"modal-body"
>
<div
v-if=
"selectedItems.length"
>
<selected-file-list/>
</div>
<div
v-else
>
<span
class=
"text-danger"
>
{{
lang
.
modal
.
delete
.
noSelected
}}
</span>
</div>
</div>
<div
class=
"modal-footer"
>
<button
class=
"btn btn-danger"
v-on:click=
"deleteItems"
>
{{
lang
.
modal
.
delete
.
title
}}
</button>
<button
class=
"btn btn-light"
v-on:click=
"hideModal"
>
{{
lang
.
btn
.
cancel
}}
</button>
</div>
</div>
</
template
>
<
script
>
import
SelectedFileList
from
'
../additions/SelectedFileList.vue
'
;
import
modal
from
'
../mixins/modal
'
;
import
translate
from
'
@/utils/translate
'
;
export
default
{
name
:
'
Delete
'
,
mixins
:
[
modal
,
translate
],
components
:
{
SelectedFileList
},
computed
:
{
/**
* Files and folders for deleting
* @returns {*}
*/
selectedItems
()
{
return
this
.
$store
.
getters
[
'
fm/selectedItems
'
];
},
},
methods
:
{
/**
* Delete selected directories and files
*/
deleteItems
()
{
// create items list for delete
const
items
=
this
.
selectedItems
.
map
((
item
)
=>
({
path
:
item
.
path
,
type
:
item
.
type
,
}));
this
.
$store
.
dispatch
(
'
fm/delete
'
,
items
).
then
(()
=>
{
// close modal window
this
.
hideModal
();
});
},
},
};
</
script
>
tools/frontend/src/views/FileManager/components/modals/views/NewFile.vue
0 → 100644
View file @
bae8cfdf
<
template
>
<div
class=
"modal-content fm-modal-folder"
>
<div
class=
"modal-header"
>
<h5
class=
"modal-title"
>
{{
lang
.
modal
.
newFile
.
title
}}
</h5>
<button
type=
"button"
class=
"close"
aria-label=
"Close"
v-on:click=
"hideModal"
>
<span
aria-hidden=
"true"
>
×
</span>
</button>
</div>
<div
class=
"modal-body"
>
<div
class=
"form-group"
>
<label
for=
"fm-file-name"
>
{{
lang
.
modal
.
newFile
.
fieldName
}}
</label>
<input
type=
"text"
class=
"form-control"
id=
"fm-file-name"
v-focus
v-bind:class=
"
{'is-invalid': fileExist}"
v-model="fileName"
v-on:keyup="validateFileName">
<div
class=
"invalid-feedback"
v-show=
"fileExist"
>
{{
lang
.
modal
.
newFile
.
fieldFeedback
}}
</div>
</div>
</div>
<div
class=
"modal-footer"
>
<button
class=
"btn btn-info"
v-bind:disabled=
"!submitActive"
v-on:click=
"addFile"
>
{{
lang
.
btn
.
submit
}}
</button>
<button
class=
"btn btn-light"
v-on:click=
"hideModal"
>
{{
lang
.
btn
.
cancel
}}
</button>
</div>
</div>
</
template
>
<
script
>
import
modal
from
'
../mixins/modal
'
;
import
translate
from
'
@/utils/translate
'
;
export
default
{
name
:
'
NewFile
'
,
mixins
:
[
modal
,
translate
],
data
()
{
return
{
// name for new file
fileName
:
''
,
// file exist
fileExist
:
false
,
};
},
computed
:
{
/**
* Submit button - active or no
* @returns {string|boolean}
*/
submitActive
()
{
return
this
.
fileName
&&
!
this
.
fileExist
;
},
},
methods
:
{
/**
* Check the file name if it exists or not.
*/
validateFileName
()
{
if
(
this
.
fileName
)
{
this
.
fileExist
=
this
.
$store
.
getters
[
`fm/
${
this
.
activeManager
}
/fileExist`
](
this
.
fileName
);
}
else
{
this
.
fileExist
=
false
;
}
},
/**
* Create new file
*/
addFile
()
{
this
.
$store
.
dispatch
(
'
fm/createFile
'
,
this
.
fileName
).
then
((
response
)
=>
{
// if new directory created successfully
if
(
response
.
data
.
result
.
status
===
'
success
'
)
{
// close modal window
this
.
hideModal
();
}
});
},
},
};
</
script
>
tools/frontend/src/views/FileManager/components/modals/views/NewFolder.vue
0 → 100644
View file @
bae8cfdf
<
template
>
<div
class=
"modal-content fm-modal-folder"
>
<div
class=
"modal-header"
>
<h5
class=
"modal-title"
>
{{
lang
.
modal
.
newFolder
.
title
}}
</h5>
<button
type=
"button"
class=
"close"
aria-label=
"Close"
v-on:click=
"hideModal"
>
<span
aria-hidden=
"true"
>
×
</span>
</button>
</div>
<div
class=
"modal-body"
>
<div
class=
"form-group"
>
<label
for=
"fm-folder-name"
>
{{
lang
.
modal
.
newFolder
.
fieldName
}}
</label>
<input
type=
"text"
class=
"form-control"
id=
"fm-folder-name"
v-focus
v-bind:class=
"
{'is-invalid': directoryExist}"
v-model="directoryName"
v-on:keyup="validateDirName">
<div
class=
"invalid-feedback"
v-show=
"directoryExist"
>
{{
lang
.
modal
.
newFolder
.
fieldFeedback
}}
</div>
</div>
</div>
<div
class=
"modal-footer"
>
<button
class=
"btn btn-info"
v-bind:disabled=
"!submitActive"
v-on:click=
"addFolder"
>
{{
lang
.
btn
.
submit
}}
</button>
<button
class=
"btn btn-light"
v-on:click=
"hideModal"
>
{{
lang
.
btn
.
cancel
}}
</button>
</div>
</div>
</
template
>
<
script
>
import
modal
from
'
../mixins/modal
'
;
import
translate
from
'
@/utils/translate
'
;
export
default
{
name
:
'
NewFolder
'
,
mixins
:
[
modal
,
translate
],
data
()
{
return
{
// name for new directory
directoryName
:
''
,
// directory exist
directoryExist
:
false
,
};
},
computed
:
{
/**
* Submit button - active or no
* @returns {string|boolean}
*/
submitActive
()
{
return
this
.
directoryName
&&
!
this
.
directoryExist
;
},
},
methods
:
{
/**
* Check the folder name if it exists or not.
*/
validateDirName
()
{
if
(
this
.
directoryName
)
{
this
.
directoryExist
=
this
.
$store
.
getters
[
`fm/
${
this
.
activeManager
}
/directoryExist`
](
this
.
directoryName
);
}
else
{
this
.
directoryExist
=
false
;
}
},
/**
* Create new directory
*/
addFolder
()
{
this
.
$store
.
dispatch
(
'
fm/createDirectory
'
,
this
.
directoryName
).
then
((
response
)
=>
{
// if new directory created successfully
if
(
response
.
data
.
result
.
status
===
'
success
'
)
{
// close modal window
this
.
hideModal
();
}
});
},
},
};
</
script
>
tools/frontend/src/views/FileManager/components/modals/views/Preview.vue
0 → 100644
View file @
bae8cfdf
<
template
>
<div
class=
"modal-content fm-modal-preview"
>
<div
class=
"modal-header"
>
<h5
class=
"modal-title w-75 text-truncate"
>
{{
showCropperModule
?
lang
.
modal
.
cropper
.
title
:
lang
.
modal
.
preview
.
title
}}
<small
class=
"text-muted pl-3"
>
{{
selectedItem
.
basename
}}
</small>
</h5>
<button
type=
"button"
class=
"close"
aria-label=
"Close"
v-on:click=
"hideModal"
>
<span
aria-hidden=
"true"
>
×
</span>
</button>
</div>
<div
class=
"modal-body text-center"
>
<template
v-if=
"showCropperModule"
>
<cropper-module
v-bind:imgSrc=
"imgSrc"
v-bind:maxHeight=
"maxHeight"
v-on:closeCropper=
"closeCropper"
/>
</
template
>
<transition
v-else
name=
"fade"
mode=
"out-in"
>
<i
v-if=
"!imgSrc"
class=
"fas fa-spinner fa-spin fa-5x p-5 text-muted"
/>
<img
v-else
v-bind:src=
"imgSrc"
v-bind:alt=
"selectedItem.basename"
v-bind:style=
"{'max-height': maxHeight+'px'}"
>
</transition>
</div>
<div
v-if=
"showFooter"
class=
"d-flex justify-content-between"
>
<span
class=
"d-block"
>
<button
class=
"btn btn-info"
v-bind:title=
"lang.modal.cropper.title"
v-on:click=
"showCropperModule = true"
>
<i
class=
"fas fa-crop-alt"
/>
</button>
</span>
<span
class=
"d-block"
>
<button
class=
"btn btn-light"
v-on:click=
"hideModal"
>
{{ lang.btn.cancel }}
</button>
</span>
</div>
</div>
</template>
<
script
>
import
CropperModule
from
'
../additions/Cropper.vue
'
;
import
modal
from
'
../mixins/modal
'
;
import
translate
from
'
@/utils/translate
'
;
import
helper
from
'
@/utils/helper
'
;
import
GET
from
'
@/utils/get
'
;
export
default
{
name
:
'
Preview
'
,
mixins
:
[
modal
,
translate
,
helper
],
components
:
{
CropperModule
},
data
()
{
return
{
showCropperModule
:
false
,
imgSrc
:
''
,
};
},
created
()
{
this
.
loadImage
();
},
computed
:
{
/**
* Authorization required
* @return {*}
*/
auth
()
{
return
this
.
$store
.
getters
[
'
fm/settings/authHeader
'
];
},
/**
* Selected disk
* @returns {*}
*/
selectedDisk
()
{
return
this
.
$store
.
getters
[
'
fm/selectedDisk
'
];
},
/**
* Selected file
* @returns {*}
*/
selectedItem
()
{
return
this
.
$store
.
getters
[
'
fm/selectedItems
'
][
0
];
},
/**
* Show modal footer
* @return boolean
*/
showFooter
()
{
return
this
.
canCrop
(
this
.
selectedItem
.
extension
)
&&
!
this
.
showCropperModule
;
},
/**
* Calculate the max height for image
* @returns {number}
*/
maxHeight
()
{
if
(
this
.
$store
.
state
.
fm
.
modal
.
modalBlockHeight
)
{
return
this
.
$store
.
state
.
fm
.
modal
.
modalBlockHeight
-
170
;
}
return
300
;
},
},
methods
:
{
/**
* Can we crop this image?
* @param extension
* @returns {boolean}
*/
canCrop
(
extension
)
{
return
this
.
$store
.
state
.
fm
.
settings
.
cropExtensions
.
includes
(
extension
.
toLowerCase
());
},
/**
* Close cropper
*/
closeCropper
()
{
this
.
showCropperModule
=
false
;
this
.
loadImage
();
},
/**
* Load image
*/
loadImage
()
{
// if authorization required
if
(
this
.
auth
)
{
GET
.
preview
(
this
.
selectedDisk
,
this
.
selectedItem
.
path
,
).
then
((
response
)
=>
{
const
mimeType
=
response
.
headers
[
'
content-type
'
].
toLowerCase
();
const
imgBase64
=
Buffer
.
from
(
response
.
data
,
'
binary
'
).
toString
(
'
base64
'
);
this
.
imgSrc
=
`data:
${
mimeType
}
;base64,
${
imgBase64
}
`
;
});
}
else
{
this
.
imgSrc
=
`
${
this
.
$store
.
getters
[
'
fm/settings/baseUrl
'
]}
preview?disk=
${
this
.
selectedDisk
}
&path=
${
encodeURIComponent
(
this
.
selectedItem
.
path
)}
&v=
${
this
.
selectedItem
.
timestamp
}
`
;
}
},
},
};
</
script
>
<
style
lang=
"scss"
>
.fm-modal-preview
{
.modal-body
{
padding
:
0
;
img
{
max-width
:
100%
;
}
}
&
>
.d-flex
{
padding
:
1rem
;
border-top
:
1px
solid
#e9ecef
;
}
}
</
style
>
tools/frontend/src/views/FileManager/components/modals/views/Properties.vue
0 → 100644
View file @
bae8cfdf
<
template
>
<div
class=
"modal-content fm-modal-properties"
>
<div
class=
"modal-header"
>
<h5
class=
"modal-title"
>
{{
lang
.
modal
.
properties
.
title
}}
</h5>
<button
type=
"button"
class=
"close"
aria-label=
"Close"
v-on:click=
"hideModal"
>
<span
aria-hidden=
"true"
>
×
</span>
</button>
</div>
<div
class=
"modal-body"
>
<div
class=
"row"
>
<div
class=
"col-2"
>
{{
lang
.
modal
.
properties
.
disk
}}
:
</div>
<div
class=
"col-9"
>
{{
selectedDisk
}}
</div>
<div
class=
"col-1 text-right"
>
<i
v-on:click=
"copyToClipboard(selectedDisk)"
v-bind:title=
"lang.clipboard.copy"
class=
"far fa-copy"
/>
</div>
</div>
<div
class=
"row"
>
<div
class=
"col-2"
>
{{
lang
.
modal
.
properties
.
name
}}
:
</div>
<div
class=
"col-9"
>
{{
selectedItem
.
basename
}}
</div>
<div
class=
"col-1 text-right"
>
<i
v-on:click=
"copyToClipboard(selectedItem.basename)"
v-bind:title=
"lang.clipboard.copy"
class=
"far fa-copy"
/>
</div>
</div>
<div
class=
"row"
>
<div
class=
"col-2"
>
{{
lang
.
modal
.
properties
.
path
}}
:
</div>
<div
class=
"col-9"
>
{{
selectedItem
.
path
}}
</div>
<div
class=
"col-1 text-right"
>
<i
v-on:click=
"copyToClipboard(selectedItem.path)"
v-bind:title=
"lang.clipboard.copy"
class=
"far fa-copy"
/>
</div>
</div>
<template
v-if=
"selectedItem.type === 'file'"
>
<div
class=
"row"
>
<div
class=
"col-2"
>
{{
lang
.
modal
.
properties
.
size
}}
:
</div>
<div
class=
"col-9"
>
{{
bytesToHuman
(
selectedItem
.
size
)
}}
</div>
<div
class=
"col-1 text-right"
>
<i
v-on:click=
"copyToClipboard(bytesToHuman(selectedItem.size))"
v-bind:title=
"lang.clipboard.copy"
class=
"far fa-copy"
/>
</div>
</div>
<div
class=
"row"
>
<div
class=
"col-2"
>
{{
lang
.
modal
.
properties
.
url
}}
:
</div>
<div
class=
"col-9"
>
<span
v-if=
"url"
>
{{
url
}}
</span>
<span
v-else
>
<button
v-on:click=
"getUrl"
type=
"button"
class=
"btn btn-sm btn-light"
>
<i
class=
"fas fa-sm fa-link"
/>
Get URL
</button>
</span>
</div>
<div
v-if=
"url"
class=
"col-1 text-right"
>
<i
v-on:click=
"copyToClipboard(url)"
v-bind:title=
"lang.clipboard.copy"
class=
"far fa-copy"
/>
</div>
</div>
</
template
>
<
template
v-if=
"selectedItem.hasOwnProperty('timestamp')"
>
<div
class=
"row"
>
<div
class=
"col-2"
>
{{
lang
.
modal
.
properties
.
modified
}}
:
</div>
<div
class=
"col-9"
>
{{
timestampToDate
(
selectedItem
.
timestamp
)
}}
</div>
<div
class=
"col-1 text-right"
>
<i
v-on:click=
"copyToClipboard(timestampToDate(selectedItem.timestamp))"
v-bind:title=
"lang.clipboard.copy"
class=
"far fa-copy"
/>
</div>
</div>
</
template
>
<
template
v-if=
"selectedItem.hasOwnProperty('acl')"
>
<div
class=
"row"
>
<div
class=
"col-2"
>
{{
lang
.
modal
.
properties
.
access
}}
:
</div>
<div
class=
"col-9"
>
{{
lang
.
modal
.
properties
[
'
access_
'
+
selectedItem
.
acl
]
}}
</div>
</div>
</
template
>
</div>
</div>
</template>
<
script
>
import
modal
from
'
../mixins/modal
'
;
import
translate
from
'
@/utils/translate
'
;
import
helper
from
'
@/utils/helper
'
;
import
EventBus
from
'
@/utils/eventBus
'
;
export
default
{
name
:
'
Properties
'
,
mixins
:
[
modal
,
translate
,
helper
],
data
()
{
return
{
url
:
null
,
};
},
computed
:
{
/**
* Selected disk
* @returns {*}
*/
selectedDisk
()
{
return
this
.
$store
.
getters
[
'
fm/selectedDisk
'
];
},
/**
* Selected file
* @returns {*}
*/
selectedItem
()
{
return
this
.
$store
.
getters
[
'
fm/selectedItems
'
][
0
];
},
},
methods
:
{
/**
* Get URL
*/
getUrl
()
{
this
.
$store
.
dispatch
(
'
fm/url
'
,
{
disk
:
this
.
selectedDisk
,
path
:
this
.
selectedItem
.
path
,
}).
then
((
response
)
=>
{
if
(
response
.
data
.
result
.
status
===
'
success
'
)
{
this
.
url
=
response
.
data
.
url
;
}
});
},
/**
* Copy text to clipboard
* @param text
*/
copyToClipboard
(
text
)
{
// create input
const
copyInputHelper
=
document
.
createElement
(
'
input
'
);
copyInputHelper
.
className
=
'
copyInputHelper
'
;
document
.
body
.
appendChild
(
copyInputHelper
);
// add text
copyInputHelper
.
value
=
text
;
copyInputHelper
.
select
();
// copy text to clipboard
document
.
execCommand
(
'
copy
'
);
// clear
document
.
body
.
removeChild
(
copyInputHelper
);
// Notification
EventBus
.
$emit
(
'
addNotification
'
,
{
status
:
'
success
'
,
message
:
this
.
lang
.
notifications
.
copyToClipboard
,
});
},
},
};
</
script
>
<
style
lang=
"scss"
>
.fm-modal-properties
.modal-body
{
.row
{
margin-bottom
:
0
.3rem
;
padding-top
:
0
.3rem
;
padding-bottom
:
0
.3rem
;
.fa-copy
{
padding-top
:
0
.2rem
;
display
:
none
;
cursor
:
pointer
;
}
&
:hover
{
background-color
:
#f8f9fa
;
&
.fa-copy
{
display
:
block
;
}
}
}
.col-2
{
font-weight
:
bold
;
}
.col-9
{
word-wrap
:
break-word
;
}
}
</
style
>
tools/frontend/src/views/FileManager/components/modals/views/Rename.vue
0 → 100644
View file @
bae8cfdf
<
template
>
<div
class=
"modal-content fm-modal-rename"
>
<div
class=
"modal-header"
>
<h5
class=
"modal-title"
>
{{
lang
.
modal
.
rename
.
title
}}
</h5>
<button
type=
"button"
class=
"close"
aria-label=
"Close"
v-on:click=
"hideModal"
>
<span
aria-hidden=
"true"
>
×
</span>
</button>
</div>
<div
class=
"modal-body"
>
<div
class=
"form-group"
>
<label
for=
"fm-input-rename"
>
{{
lang
.
modal
.
rename
.
fieldName
}}
</label>
<input
type=
"text"
class=
"form-control"
id=
"fm-input-rename"
v-focus
v-bind:class=
"
{'is-invalid': checkName}"
v-model="name"
v-on:keyup="validateName">
<div
class=
"invalid-feedback"
v-show=
"checkName"
>
{{
lang
.
modal
.
rename
.
fieldFeedback
}}
{{
directoryExist
?
` - ${lang.modal.rename.directoryExist
}
`
:
''
}}
{{
fileExist
?
` - ${lang.modal.rename.fileExist
}
`
:
''
}}
<
/div
>
<
/div
>
<
/div
>
<
div
class
=
"
modal-footer
"
>
<
button
class
=
"
btn btn-info
"
v
-
bind
:
disabled
=
"
submitDisable
"
v
-
on
:
click
=
"
rename
"
>
{{
lang
.
btn
.
submit
}}
<
/button
>
<
button
class
=
"
btn btn-light
"
v
-
on
:
click
=
"
hideModal
"
>
{{
lang
.
btn
.
cancel
}}
<
/button
>
<
/div
>
<
/div
>
<
/template
>
<
script
>
import
modal
from
'
../mixins/modal
'
;
import
translate
from
'
@/utils/translate
'
;
export
default
{
name
:
'
Rename
'
,
mixins
:
[
modal
,
translate
],
data
()
{
return
{
name
:
''
,
directoryExist
:
false
,
fileExist
:
false
,
}
;
}
,
computed
:
{
/**
* Selected item
* @returns {*
}
*/
selectedItem
()
{
return
this
.
$store
.
getters
[
`fm/${this.activeManager
}
/selectedList`
][
0
];
}
,
/**
* Check new name
* @returns {boolean
}
*/
checkName
()
{
return
this
.
directoryExist
||
this
.
fileExist
||
!
this
.
name
;
}
,
/**
* Submit button disable
* @returns {*|boolean
}
*/
submitDisable
()
{
return
this
.
checkName
||
this
.
name
===
this
.
selectedItem
.
basename
;
}
,
}
,
mounted
()
{
// initiate item name
this
.
name
=
this
.
selectedItem
.
basename
;
}
,
methods
:
{
/**
* Validate item name
*/
validateName
()
{
if
(
this
.
name
!==
this
.
selectedItem
.
basename
)
{
// if item - folder
if
(
this
.
selectedItem
.
type
===
'
dir
'
)
{
// check folder name matches
this
.
directoryExist
=
this
.
$store
.
getters
[
`fm/${this.activeManager
}
/directoryExist`
](
this
.
name
);
}
else
{
// check file name matches
this
.
fileExist
=
this
.
$store
.
getters
[
`fm/${this.activeManager
}
/fileExist`
](
this
.
name
);
}
}
}
,
/**
* Rename item
*/
rename
()
{
// create new name with path
const
newName
=
this
.
selectedItem
.
dirname
?
`${this.selectedItem.dirname
}
/${this.name
}
`
:
this
.
name
;
this
.
$store
.
dispatch
(
'
fm/rename
'
,
{
type
:
this
.
selectedItem
.
type
,
newName
,
oldName
:
this
.
selectedItem
.
path
,
}
).
then
(()
=>
{
// close modal window
this
.
hideModal
();
}
);
}
,
}
,
}
;
<
/script
>
tools/frontend/src/views/FileManager/components/modals/views/Status.vue
0 → 100644
View file @
bae8cfdf
<
template
>
<div
class=
"modal-content fm-modal-errors"
>
<div
class=
"modal-header"
>
<h5
class=
"modal-title"
>
{{
lang
.
modal
.
status
.
title
}}
</h5>
<button
type=
"button"
class=
"close"
aria-label=
"Close"
v-on:click=
"hideModal"
>
<span
aria-hidden=
"true"
>
×
</span>
</button>
</div>
<div
class=
"modal-body"
>
<div
v-if=
"errors.length"
>
<ul
class=
"list-unstyled"
>
<li
v-for=
"(item, index) in errors"
v-bind:key=
"index"
>
{{
item
.
status
}}
-
{{
item
.
message
}}
</li>
</ul>
</div>
<div
v-else
>
<span>
{{
lang
.
modal
.
status
.
noErrors
}}
</span>
</div>
</div>
<div
class=
"modal-footer"
>
<button
class=
"btn btn-danger"
v-bind:disabled=
"!errors.length"
v-on:click=
"clearErrors"
>
{{
lang
.
btn
.
clear
}}
</button>
<button
class=
"btn btn-light"
v-on:click=
"hideModal"
>
{{
lang
.
btn
.
cancel
}}
</button>
</div>
</div>
</
template
>
<
script
>
import
modal
from
'
../mixins/modal
'
;
import
translate
from
'
@/utils/translate
'
;
export
default
{
name
:
'
Status
'
,
mixins
:
[
modal
,
translate
],
computed
:
{
/**
* Application errors
* @returns {default.computed.errors|(function())|Array|boolean}
*/
errors
()
{
return
this
.
$store
.
state
.
fm
.
messages
.
errors
;
},
},
methods
:
{
/**
* Clear all errors
*/
clearErrors
()
{
this
.
$store
.
commit
(
'
fm/messages/clearErrors
'
);
},
},
};
</
script
>
tools/frontend/src/views/FileManager/components/modals/views/TextEdit.vue
0 → 100644
View file @
bae8cfdf
<
template
>
<div
class=
"modal-content fm-modal-text-edit"
>
<div
class=
"modal-header"
>
<h5
class=
"modal-title w-75 text-truncate"
>
{{
lang
.
modal
.
editor
.
title
}}
<small
class=
"text-muted pl-3"
>
{{
selectedItem
.
basename
}}
</small>
</h5>
<button
type=
"button"
class=
"close"
aria-label=
"Close"
v-on:click=
"hideModal"
>
<span
aria-hidden=
"true"
>
×
</span>
</button>
</div>
<div
class=
"modal-body"
>
<codemirror
ref=
"fmCodeEditor"
v-model=
"code"
:options=
"cmOptions"
/>
</div>
<div
class=
"modal-footer"
>
<button
class=
"btn btn-info"
v-on:click=
"updateFile"
>
{{
lang
.
btn
.
submit
}}
</button>
<button
class=
"btn btn-light"
v-on:click=
"hideModal"
>
{{
lang
.
btn
.
cancel
}}
</button>
</div>
</div>
</
template
>
<
script
>
import
{
codemirror
}
from
'
vue-codemirror
'
;
import
'
codemirror/mode/shell/shell
'
;
import
'
codemirror/mode/css/css
'
;
import
'
codemirror/mode/sass/sass
'
;
import
'
codemirror/mode/htmlmixed/htmlmixed
'
;
import
'
codemirror/mode/javascript/javascript
'
;
import
'
codemirror/mode/vue/vue
'
;
import
'
codemirror/mode/markdown/markdown
'
;
import
'
codemirror/mode/xml/xml
'
;
import
'
codemirror/mode/clike/clike
'
;
import
'
codemirror/mode/php/php
'
;
import
'
codemirror/mode/sql/sql
'
;
import
'
codemirror/mode/lua/lua
'
;
import
'
codemirror/mode/perl/perl
'
;
import
'
codemirror/mode/python/python
'
;
import
'
codemirror/mode/swift/swift
'
;
import
'
codemirror/mode/ruby/ruby
'
;
import
'
codemirror/mode/go/go
'
;
import
'
codemirror/mode/yaml/yaml
'
;
import
'
codemirror/mode/properties/properties
'
;
import
modal
from
'
../mixins/modal
'
;
import
translate
from
'
@/utils/translate
'
;
export
default
{
name
:
'
TextEdit
'
,
mixins
:
[
modal
,
translate
],
components
:
{
codemirror
},
data
()
{
return
{
code
:
''
,
};
},
mounted
()
{
// get file for edit
this
.
$store
.
dispatch
(
'
fm/getFile
'
,
{
disk
:
this
.
selectedDisk
,
path
:
this
.
selectedItem
.
path
,
}).
then
((
response
)
=>
{
// add code
if
(
this
.
selectedItem
.
extension
===
'
json
'
)
{
this
.
code
=
JSON
.
stringify
(
response
.
data
,
null
,
4
);
}
else
{
this
.
code
=
response
.
data
;
}
// set size
this
.
$refs
.
fmCodeEditor
.
codemirror
.
setSize
(
null
,
this
.
editorHeight
);
});
},
computed
:
{
/**
* Selected disk
* @returns {*}
*/
selectedDisk
()
{
return
this
.
$store
.
getters
[
'
fm/selectedDisk
'
];
},
/**
* Selected file
* @returns {*}
*/
selectedItem
()
{
return
this
.
$store
.
getters
[
'
fm/selectedItems
'
][
0
];
},
/**
* CodeMirror options
* @returns {{tabSize: number, mode: *, theme: string, lineNumbers: boolean, line: boolean}}
*/
cmOptions
()
{
return
{
mode
:
this
.
$store
.
state
.
fm
.
settings
.
textExtensions
[
this
.
selectedItem
.
extension
],
theme
:
'
blackboard
'
,
lineNumbers
:
true
,
line
:
true
,
};
},
/**
* Calculate the height of the code editor
* @returns {number}
*/
editorHeight
()
{
if
(
this
.
$store
.
state
.
fm
.
modal
.
modalBlockHeight
)
{
return
this
.
$store
.
state
.
fm
.
modal
.
modalBlockHeight
-
200
;
}
return
300
;
},
},
methods
:
{
// Update file
updateFile
()
{
const
formData
=
new
FormData
();
// add disk name
formData
.
append
(
'
disk
'
,
this
.
selectedDisk
);
// add path
formData
.
append
(
'
path
'
,
this
.
selectedItem
.
dirname
);
// add updated file
formData
.
append
(
'
file
'
,
new
Blob
([
this
.
code
]),
this
.
selectedItem
.
basename
);
this
.
$store
.
dispatch
(
'
fm/updateFile
'
,
formData
).
then
((
response
)
=>
{
// if file updated successfully
if
(
response
.
data
.
result
.
status
===
'
success
'
)
{
// close modal window
this
.
hideModal
();
}
});
},
},
};
</
script
>
<
style
lang=
"scss"
>
@import
'~codemirror/lib/codemirror.css'
;
@import
'~codemirror/theme/blackboard.css'
;
.fm-modal-text-edit
{
.modal-body
{
padding
:
0
;
}
}
</
style
>
tools/frontend/src/views/FileManager/components/modals/views/Unzip.vue
0 → 100644
View file @
bae8cfdf
<
template
>
<div
class=
"modal-content fm-modal-unzip"
>
<div
class=
"modal-header"
>
<h5
class=
"modal-title"
>
{{
lang
.
modal
.
unzip
.
title
}}
</h5>
<button
type=
"button"
class=
"close"
aria-label=
"Close"
v-on:click=
"hideModal"
>
<span
aria-hidden=
"true"
>
×
</span>
</button>
</div>
<div
class=
"modal-body"
>
<div
class=
"d-flex justify-content-between"
>
<div>
<strong>
{{
lang
.
modal
.
unzip
.
fieldRadioName
}}
</strong>
</div>
<div
class=
"form-check form-check-inline"
>
<input
class=
"form-check-input"
id=
"unzipRadio1"
type=
"radio"
name=
"uploadOptions"
value=
"0"
checked
v-model.number=
"createFolder"
>
<label
class=
"form-check-label"
for=
"unzipRadio1"
>
{{
lang
.
modal
.
unzip
.
fieldRadio1
}}
</label>
</div>
<div
class=
"form-check form-check-inline"
>
<input
class=
"form-check-input"
id=
"unzipRadio2"
type=
"radio"
name=
"uploadOptions"
value=
"1"
checked
v-model.number=
"createFolder"
>
<label
class=
"form-check-label"
for=
"unzipRadio2"
>
{{
lang
.
modal
.
unzip
.
fieldRadio2
}}
</label>
</div>
</div>
<hr>
<div
v-if=
"createFolder"
class=
"form-group"
>
<label
for=
"fm-folder-name"
>
{{
lang
.
modal
.
unzip
.
fieldName
}}
</label>
<input
type=
"text"
class=
"form-control"
id=
"fm-folder-name"
v-focus
v-bind:class=
"
{'is-invalid': directoryExist}"
v-model="directoryName"
v-on:keyup="validateDirName">
<div
class=
"invalid-feedback"
v-show=
"directoryExist"
>
{{
lang
.
modal
.
unzip
.
fieldFeedback
}}
</div>
</div>
<span
v-else
class=
"text-danger"
>
{{
lang
.
modal
.
unzip
.
warning
}}
</span>
</div>
<div
class=
"modal-footer"
>
<button
class=
"btn btn-info"
v-bind:disabled=
"!submitActive"
v-on:click=
"unpackArchive"
>
{{
lang
.
btn
.
submit
}}
</button>
<button
class=
"btn btn-light"
v-on:click=
"hideModal"
>
{{
lang
.
btn
.
cancel
}}
</button>
</div>
</div>
</
template
>
<
script
>
import
modal
from
'
../mixins/modal
'
;
import
translate
from
'
@/utils/translate
'
;
export
default
{
name
:
'
Unzip
'
,
mixins
:
[
modal
,
translate
],
data
()
{
return
{
createFolder
:
0
,
// name for new directory
directoryName
:
''
,
// directory exist
directoryExist
:
false
,
};
},
computed
:
{
/**
* Submit button - active or no
* @returns {string|boolean}
*/
submitActive
()
{
if
(
this
.
createFolder
)
{
return
this
.
directoryName
&&
!
this
.
directoryExist
;
}
return
true
;
},
},
methods
:
{
/**
* Check the folder name if it exists or not.
*/
validateDirName
()
{
if
(
this
.
directoryName
)
{
this
.
directoryExist
=
this
.
$store
.
getters
[
`fm/
${
this
.
activeManager
}
/directoryExist`
](
this
.
directoryName
);
}
else
{
this
.
directoryExist
=
false
;
}
},
/**
* Unpack selected archive
*/
unpackArchive
()
{
this
.
$store
.
dispatch
(
'
fm/unzip
'
,
this
.
createFolder
?
this
.
directoryName
:
null
).
then
(()
=>
{
// close modal window
this
.
hideModal
();
});
},
},
};
</
script
>
tools/frontend/src/views/FileManager/components/modals/views/Upload.vue
0 → 100644
View file @
bae8cfdf
<
template
>
<div
class=
"modal-content fm-modal-upload"
>
<div
class=
"modal-header"
>
<h5
class=
"modal-title"
>
{{
lang
.
modal
.
upload
.
title
}}
</h5>
<button
type=
"button"
class=
"close"
aria-label=
"Close"
v-on:click=
"hideModal"
>
<span
aria-hidden=
"true"
>
×
</span>
</button>
</div>
<div
class=
"modal-body"
>
<div
class=
"fm-btn-wrapper"
v-show=
"!progressBar"
>
<button
type=
"button"
class=
"btn btn-secondary btn-block"
>
{{
lang
.
btn
.
uploadSelect
}}
</button>
<input
type=
"file"
multiple
name=
"myfile"
v-on:change=
"selectFiles($event)"
>
</div>
<div
class=
"fm-upload-list"
v-if=
"countFiles"
>
<div
class=
"d-flex justify-content-between"
v-for=
"(item, index) in newFiles"
v-bind:key=
"index"
>
<div
class=
"w-75 text-truncate"
>
<i
class=
"far"
v-bind:class=
"mimeToIcon(item.type)"
/>
{{
item
.
name
}}
</div>
<div
class=
"text-right"
>
{{
bytesToHuman
(
item
.
size
)
}}
</div>
</div>
<hr>
<div
class=
"d-flex justify-content-between"
>
<div>
<strong>
{{
lang
.
modal
.
upload
.
selected
}}
</strong>
{{
newFiles
.
length
}}
</div>
<div
class=
"text-right"
>
<strong>
{{
lang
.
modal
.
upload
.
size
}}
</strong>
{{
allFilesSize
}}
</div>
</div>
<hr>
<div
class=
"d-flex justify-content-between"
>
<div>
<strong>
{{
lang
.
modal
.
upload
.
ifExist
}}
</strong>
</div>
<div
class=
"form-check form-check-inline"
>
<input
class=
"form-check-input"
id=
"uploadRadio1"
type=
"radio"
name=
"uploadOptions"
value=
"0"
checked
v-model=
"overwrite"
>
<label
class=
"form-check-label"
for=
"uploadRadio1"
>
{{
lang
.
modal
.
upload
.
skip
}}
</label>
</div>
<div
class=
"form-check form-check-inline"
>
<input
class=
"form-check-input"
id=
"uploadRadio2"
type=
"radio"
name=
"uploadOptions"
value=
"1"
checked
v-model=
"overwrite"
>
<label
class=
"form-check-label"
for=
"uploadRadio2"
>
{{
lang
.
modal
.
upload
.
overwrite
}}
</label>
</div>
</div>
<hr>
</div>
<div
v-else
><p>
{{
lang
.
modal
.
upload
.
noSelected
}}
</p></div>
<div
class=
"fm-upload-info"
>
<!-- Progress Bar -->
<div
class=
"progress"
v-show=
"countFiles"
>
<div
class=
"progress-bar progress-bar-striped bg-info"
role=
"progressbar"
v-bind:aria-valuenow=
"progressBar"
aria-valuemin=
"0"
aria-valuemax=
"100"
v-bind:style=
"
{width: progressBar + '%' }">
{{
progressBar
}}
%
</div>
</div>
</div>
</div>
<div
class=
"modal-footer"
>
<button
class=
"btn"
v-bind:class=
"[countFiles ? 'btn-info' : 'btn-light']"
v-bind:disabled=
"!countFiles"
v-on:click=
"uploadFiles"
>
{{
lang
.
btn
.
submit
}}
</button>
<button
class=
"btn btn-light"
v-on:click=
"hideModal()"
>
{{
lang
.
btn
.
cancel
}}
</button>
</div>
</div>
</
template
>
<
script
>
import
modal
from
'
../mixins/modal
'
;
import
translate
from
'
@/utils/translate
'
;
import
helper
from
'
@/utils/helper
'
;
export
default
{
name
:
'
Upload
'
,
mixins
:
[
modal
,
translate
,
helper
],
data
()
{
return
{
// selected files
newFiles
:
[],
// overwrite if exists
overwrite
:
0
,
};
},
computed
:
{
/**
* Progress bar value - %
* @returns {number}
*/
progressBar
()
{
return
this
.
$store
.
state
.
fm
.
messages
.
actionProgress
;
},
/**
* Count of files selected for upload
* @returns {number}
*/
countFiles
()
{
return
this
.
newFiles
.
length
;
},
/**
* Calculate the size of all files
* @returns {*|string}
*/
allFilesSize
()
{
let
size
=
0
;
for
(
let
i
=
0
;
i
<
this
.
newFiles
.
length
;
i
+=
1
)
{
size
+=
this
.
newFiles
[
i
].
size
;
}
return
this
.
bytesToHuman
(
size
);
},
},
methods
:
{
/**
* Select file or files
* @param event
*/
selectFiles
(
event
)
{
// files selected?
if
(
event
.
target
.
files
.
length
===
0
)
{
// no file selected
this
.
newFiles
=
[];
}
else
{
// we have file or files
this
.
newFiles
=
event
.
target
.
files
;
}
},
/**
* Upload new files
*/
uploadFiles
()
{
// if files exists
if
(
this
.
countFiles
)
{
// upload files
this
.
$store
.
dispatch
(
'
fm/upload
'
,
{
files
:
this
.
newFiles
,
overwrite
:
this
.
overwrite
,
}).
then
((
response
)
=>
{
// if upload is successful
if
(
response
.
data
.
result
.
status
===
'
success
'
)
{
// close modal window
this
.
hideModal
();
}
});
}
},
},
};
</
script
>
<
style
lang=
"scss"
>
.fm-modal-upload
{
.fm-btn-wrapper
{
position
:
relative
;
overflow
:
hidden
;
padding-bottom
:
6px
;
margin-bottom
:
0
.6rem
;
}
.fm-btn-wrapper
input
[
type
=
file
]
{
font-size
:
100px
;
position
:
absolute
;
left
:
0
;
top
:
0
;
opacity
:
0
;
cursor
:
pointer
;
}
.fm-upload-list
.far
{
padding-right
:
0
.5rem
;
}
.fm-upload-list
.form-check-inline
{
margin-right
:
0
;
}
.fm-upload-info
>
.progress
{
margin-bottom
:
1rem
;
}
}
</
style
>
tools/frontend/src/views/FileManager/components/modals/views/VideoPlayer.vue
0 → 100644
View file @
bae8cfdf
<
template
>
<div
class=
"modal-content fm-modal-video-player"
>
<div
class=
"modal-header"
>
<h5
class=
"modal-title w-75 text-truncate"
>
{{
lang
.
modal
.
videoPlayer
.
title
}}
<small
class=
"text-muted pl-3"
>
{{
videoFile
.
basename
}}
</small>
</h5>
<button
type=
"button"
class=
"close"
aria-label=
"Close"
v-on:click=
"hideModal"
>
<span
aria-hidden=
"true"
>
×
</span>
</button>
</div>
<div
class=
"modal-body"
>
<video
ref=
"fmVideo"
controls
/>
</div>
</div>
</
template
>
<
script
>
import
Plyr
from
'
plyr
'
;
import
modal
from
'
../mixins/modal
'
;
import
translate
from
'
@/utils/translate
'
;
export
default
{
name
:
'
Player
'
,
mixins
:
[
modal
,
translate
],
data
()
{
return
{
player
:
{},
};
},
mounted
()
{
// initiate video player
this
.
player
=
new
Plyr
(
this
.
$refs
.
fmVideo
);
// load source
this
.
player
.
source
=
{
type
:
'
video
'
,
title
:
this
.
videoFile
.
filename
,
sources
:
[{
src
:
`
${
this
.
$store
.
getters
[
'
fm/settings/baseUrl
'
]}
stream-file?disk=
${
this
.
selectedDisk
}
&path=
${
encodeURIComponent
(
this
.
videoFile
.
path
)}
`
,
type
:
`audio/
${
this
.
videoFile
.
extension
}
`
,
}],
};
},
beforeDestroy
()
{
this
.
player
.
destroy
();
},
computed
:
{
/**
* Selected disk
* @returns {*}
*/
selectedDisk
()
{
return
this
.
$store
.
getters
[
'
fm/selectedDisk
'
];
},
/**
* Video file
* @returns {*}
*/
videoFile
()
{
return
this
.
$store
.
getters
[
'
fm/selectedItems
'
][
0
];
},
},
methods
:
{
},
};
</
script
>
<
style
lang=
"scss"
>
.fm-modal-video-player
{
}
</
style
>
tools/frontend/src/views/FileManager/components/modals/views/Zip.vue
0 → 100644
View file @
bae8cfdf
<
template
>
<div
class=
"modal-content fm-modal-zip"
>
<div
class=
"modal-header"
>
<h5
class=
"modal-title"
>
{{
lang
.
modal
.
zip
.
title
}}
</h5>
<button
type=
"button"
class=
"close"
aria-label=
"Close"
v-on:click=
"hideModal"
>
<span
aria-hidden=
"true"
>
×
</span>
</button>
</div>
<div
class=
"modal-body"
>
<label
for=
"fm-zip-name"
>
{{
lang
.
modal
.
zip
.
fieldName
}}
</label>
<div
class=
"input-group mb-3"
>
<input
type=
"text"
class=
"form-control"
id=
"fm-zip-name"
v-focus
v-bind:class=
"
{'is-invalid': archiveExist}"
v-model="archiveName"
v-on:keyup="validateArchiveName">
<div
class=
"input-group-append"
>
<span
class=
"input-group-text"
>
.zip
</span>
</div>
<div
class=
"invalid-feedback"
v-show=
"archiveExist"
>
{{
lang
.
modal
.
zip
.
fieldFeedback
}}
</div>
</div>
<hr>
<selected-file-list/>
</div>
<div
class=
"modal-footer"
>
<button
class=
"btn btn-info"
v-bind:disabled=
"!submitActive"
v-on:click=
"createArchive"
>
{{
lang
.
btn
.
submit
}}
</button>
<button
class=
"btn btn-light"
v-on:click=
"hideModal"
>
{{
lang
.
btn
.
cancel
}}
</button>
</div>
</div>
</
template
>
<
script
>
import
SelectedFileList
from
'
../additions/SelectedFileList.vue
'
;
import
modal
from
'
../mixins/modal
'
;
import
translate
from
'
@/utils/translate
'
;
export
default
{
name
:
'
Zip
'
,
mixins
:
[
modal
,
translate
],
components
:
{
SelectedFileList
},
data
()
{
return
{
// name for new archive
archiveName
:
''
,
// archive exist
archiveExist
:
false
,
};
},
computed
:
{
/**
* Submit button - active or no
* @returns {string|boolean}
*/
submitActive
()
{
return
this
.
archiveName
&&
!
this
.
archiveExist
;
},
},
methods
:
{
/**
* Check the archive name if it exists or not.
*/
validateArchiveName
()
{
if
(
this
.
archiveName
)
{
this
.
archiveExist
=
this
.
$store
.
getters
[
`fm/
${
this
.
activeManager
}
/fileExist`
](
`
${
this
.
archiveName
}
.zip`
);
}
else
{
this
.
archiveExist
=
false
;
}
},
/**
* Create new archive
*/
createArchive
()
{
this
.
$store
.
dispatch
(
'
fm/zip
'
,
`
${
this
.
archiveName
}
.zip`
).
then
(()
=>
{
// close modal window
this
.
hideModal
();
});
},
},
};
</
script
>
tools/frontend/src/views/FileManager/components/tree/Branch.vue
0 → 100644
View file @
bae8cfdf
<
template
>
<ul
class=
"list-unstyled fm-tree-branch"
>
<li
v-for=
"(directory, index) in subDirectories"
v-bind:key=
"index"
>
<p
class=
"unselectable"
v-bind:class=
"
{'selected': isDirectorySelected(directory.path)}"
v-on:click="selectDirectory(directory.path)">
<i
class=
"far"
v-if=
"directory.props.hasSubdirectories"
v-on:click.stop=
"showSubdirectories(
directory.path,
directory.props.showSubdirectories
)"
v-bind:class=
"[arrowState(index)
? 'fa-minus-square'
: 'fa-plus-square'
]"
/>
<i
class=
"fas fa-minus fa-xs"
v-else
/>
{{
directory
.
basename
}}
</p>
<transition
name=
"fade-tree"
>
<branch
v-show=
"arrowState(index)"
v-if=
"directory.props.hasSubdirectories"
v-bind:parent-id=
"directory.id"
>
</branch>
</transition>
</li>
</ul>
</
template
>
<
script
>
export
default
{
name
:
'
Branch
'
,
props
:
{
parentId
:
{
type
:
Number
,
required
:
true
},
},
computed
:
{
/**
* Subdirectories for selected parent
* @returns {*}
*/
subDirectories
()
{
return
this
.
$store
.
getters
[
'
fm/tree/directories
'
].
filter
((
item
)
=>
item
.
parentId
===
this
.
parentId
);
},
},
methods
:
{
/**
* Check, is this directory selected?
* @param path
* @returns {boolean}
*/
isDirectorySelected
(
path
)
{
return
this
.
$store
.
state
.
fm
.
left
.
selectedDirectory
===
path
;
},
/**
* Show subdirectories - arrow
* @returns {boolean}
* @param index
*/
arrowState
(
index
)
{
return
this
.
subDirectories
[
index
].
props
.
showSubdirectories
;
},
/**
* Show/Hide subdirectories
* @param path
* @param showState
*/
showSubdirectories
(
path
,
showState
)
{
if
(
showState
)
{
// hide
this
.
$store
.
dispatch
(
'
fm/tree/hideSubdirectories
'
,
path
);
}
else
{
// show
this
.
$store
.
dispatch
(
'
fm/tree/showSubdirectories
'
,
path
);
}
},
/**
* Load selected directory and show files
* @param path
*/
selectDirectory
(
path
)
{
// only if this path not selected
if
(
!
this
.
isDirectorySelected
(
path
))
{
this
.
$store
.
dispatch
(
'
fm/left/selectDirectory
'
,
{
path
,
history
:
true
});
}
},
},
};
</
script
>
<
style
lang=
"scss"
>
.fm-tree-branch
{
display
:
table
;
width
:
100%
;
padding-left
:
1
.4rem
;
li
>
p
{
margin-bottom
:
0
.1rem
;
padding
:
0
.4rem
0
.4rem
;
white-space
:
nowrap
;
cursor
:
pointer
;
&
:hover
,
&
.selected
{
background-color
:
#f8f9fa
;
}
}
.fas.fa-minus
{
padding-left
:
0
.1rem
;
padding-right
:
0
.6rem
;
}
.far
{
padding-right
:
0
.5rem
;
}
}
.fade-tree-enter-active
,
.fade-tree-leave-active
{
transition
:
all
.3s
ease
;
}
.fade-tree-enter
,
.fade-tree-leave-to
{
transform
:
translateX
(
20px
);
opacity
:
0
;
}
</
style
>
tools/frontend/src/views/FileManager/components/tree/FolderTree.vue
0 → 100644
View file @
bae8cfdf
<
template
>
<div
class=
"fm-tree"
>
<div
class=
"fm-tree-disk sticky-top"
>
<i
class=
"far fa-hdd"
/>
{{
selectedDisk
}}
</div>
<branch
v-bind:parent-id=
"0"
/>
</div>
</
template
>
<
script
>
import
Branch
from
'
./Branch.vue
'
;
export
default
{
name
:
'
FolderTree
'
,
components
:
{
branch
:
Branch
,
},
computed
:
{
/**
* Selected Disk
* @returns {*}
*/
selectedDisk
()
{
return
this
.
$store
.
getters
[
'
fm/selectedDisk
'
];
},
},
};
</
script
>
<
style
lang=
"scss"
>
.fm-tree
{
overflow
:
auto
;
border-right
:
1px
solid
#6d757d
;
&
>
.fm-folders-tree
{
padding-left
:
0
.2rem
;
}
.fm-tree-disk
{
padding
:
0
.2rem
0
.3rem
;
margin-bottom
:
0
.3rem
;
background-color
:
white
;
}
.fm-tree-disk
>
i
{
padding-left
:
0
.2rem
;
padding-right
:
0
.5rem
;
}
}
</
style
>
tools/frontend/src/views/FileManager/init.js
0 → 100644
View file @
bae8cfdf
import
store
from
'
@/store/file-manager
'
;
import
FileManager
from
'
./FileManager.vue
'
;
/**
* Install
*
* @param Vue
* @param options
*/
export
default
function
install
(
Vue
,
options
=
{})
{
if
(
!
options
.
store
)
window
.
console
.
error
(
'
Please provide a store!!
'
);
Vue
.
component
(
'
file-manager
'
,
FileManager
);
options
.
store
.
registerModule
(
'
fm
'
,
store
);
}
tools/frontend/src/views/System/Role.vue
View file @
bae8cfdf
...
@@ -337,7 +337,7 @@ export default {
...
@@ -337,7 +337,7 @@ export default {
this
.
expandForm
=
!
this
.
expandForm
;
this
.
expandForm
=
!
this
.
expandForm
;
},
},
onSelectChange
(
selectedRowKeys
)
{
onSelectChange
(
selectedRowKeys
)
{
console
.
log
(
"
selectedRowKeys changed:
"
,
selectedRowKeys
);
window
.
console
.
log
(
"
selectedRowKeys changed:
"
,
selectedRowKeys
);
this
.
selectedRowKeys
=
selectedRowKeys
;
this
.
selectedRowKeys
=
selectedRowKeys
;
},
},
handleTableChange
(
pagination
,
filters
,
sorter
)
{
handleTableChange
(
pagination
,
filters
,
sorter
)
{
...
...
tools/frontend/src/views/User/Login.vue
View file @
bae8cfdf
...
@@ -3,11 +3,6 @@
...
@@ -3,11 +3,6 @@
<div
class=
"ai-login"
>
<div
class=
"ai-login"
>
<a-form
<a-form
@
submit=
"handleSubmit"
@
submit=
"handleSubmit"
:autoFormCreate=
"
(form) =>
{
this.form = form;
}
"
>
>
<a-tabs
<a-tabs
:animated=
"false"
:animated=
"false"
...
@@ -88,7 +83,7 @@
...
@@ -88,7 +83,7 @@
<a-checkbox
:checked=
"autoLogin"
@
change=
"onSwithAutoLogin"
>
<a-checkbox
:checked=
"autoLogin"
@
change=
"onSwithAutoLogin"
>
自动登录
自动登录
</a-checkbox>
</a-checkbox>
<a
style=
"float: right"
href=
"#"
>
忘记密码
</a>
<a
style=
"float: right
;color: #2ECCCD;
"
href=
"#"
>
忘记密码
</a>
</div>
</div>
<a-form-item>
<a-form-item>
<a-button
<a-button
...
@@ -165,12 +160,14 @@ export default {
...
@@ -165,12 +160,14 @@ export default {
}
}
},
},
handleSubmit
(
e
)
{
handleSubmit
(
e
)
{
window
.
console
.
log
(
e
);
this
.
form
.
validateFields
(
this
.
form
.
validateFields
(
this
.
active
,
this
.
active
,
{
{
force
:
true
,
force
:
true
,
},
},
(
err
,
values
)
=>
{
(
err
,
values
)
=>
{
window
.
console
.
log
(
values
);
if
(
!
err
)
{
if
(
!
err
)
{
// console.log("Received values of form: ", values);
// console.log("Received values of form: ", values);
this
.
$router
.
push
({
path
:
"
/
"
});
this
.
$router
.
push
({
path
:
"
/
"
});
...
...
tools/frontend/src/views/User/Register.vue
View file @
bae8cfdf
...
@@ -3,11 +3,6 @@
...
@@ -3,11 +3,6 @@
<h3>
注册
</h3>
<h3>
注册
</h3>
<a-form
<a-form
@
submit=
"handleSubmit"
@
submit=
"handleSubmit"
:autoFormCreate=
"
(form) =>
{
this.form = form;
}
"
>
>
<a-form-item
<a-form-item
v-decorator=
"[
v-decorator=
"[
...
...
tools/frontend/src/views/User/login.less
View file @
bae8cfdf
...
@@ -72,8 +72,16 @@
...
@@ -72,8 +72,16 @@
width: 100%;
width: 100%;
}
}
.other {
a {
color: #2ECCCD;
}
}
.submit {
.submit {
width: 100%;
width: 100%;
margin-top: 24px;
margin-top: 24px;
border-color: #2ECCCD;
background-color: #2ECCCD;
}
}
}
}
tools/frontend/src/views/User/register.less
View file @
bae8cfdf
...
@@ -20,13 +20,16 @@
...
@@ -20,13 +20,16 @@
display: block;
display: block;
width: 100%;
width: 100%;
}
}
.submit {
.submit {
width: 50%;
width: 50%;
border-color: #2ECCCD;
background-color: #2ECCCD;
}
}
.login {
.login {
float: right;
float: right;
color: #2ECCCD;
line-height: @btn-height-lg;
line-height: @btn-height-lg;
}
}
...
...
tools/frontend/vue.config.js
View file @
bae8cfdf
'
use strict
'
"
use strict
"
;
// 基础配置文件
// 基础配置文件
const
path
=
require
(
'
path
'
)
const
path
=
require
(
"
path
"
);
const
webpack
=
require
(
'
webpack
'
)
const
webpack
=
require
(
"
webpack
"
);
// 拼接路径
// 拼接路径
function
resolve
(
dir
)
{
function
resolve
(
dir
)
{
return
path
.
join
(
__dirname
,
dir
)
return
path
.
join
(
__dirname
,
dir
)
;
}
}
// 基础路径 注意发布之前要先修改这里
// 基础路径 注意发布之前要先修改这里
const
BASE_URL
=
process
.
env
.
NODE_ENV
===
'
production
'
const
BASE_URL
=
process
.
env
.
NODE_ENV
===
"
production
"
?
"
/frontend/
"
:
"
/
"
;
?
'
/frontend/
'
:
'
/
'
module
.
exports
=
{
module
.
exports
=
{
baseUrl
:
BASE_URL
,
// 根据你的实际情况更改这里
baseUrl
:
BASE_URL
,
// 根据你的实际情况更改这里
productionSourceMap
:
false
,
productionSourceMap
:
false
,
devServer
:
{
devServer
:
{
publicPath
:
BASE_URL
// 和 baseUrl 保持一致
publicPath
:
BASE_URL
,
// 和 baseUrl 保持一致
// port: 8080,
// open: true,
// overlay: {
// warnings: false,
// errors: true,
// },
// proxy: {
// // change xxx-api/login => mock/login
// // detail: https://cli.vuejs.org/config/#devserver-proxy
// "/api/v1": {
// target: "http://127.0.0.1:5001/",
// changeOrigin: true,
// pathRewrite: {},
// },
// "/file-manager": {
// target: "https://file-manager.webmai.ru/",
// changeOrigin: true,
// pathRewrite: {},
// },
// "/uowap/": {
// target: "https://web-drcn.hispace.dbankcloud.cn/",
// changeOrigin: true,
// pathRewrite: {},
// },
// },
// after: require("./mock/mock-server.js"),
},
},
css
:
{
css
:
{
loaderOptions
:
{
loaderOptions
:
{
less
:
{
less
:
{
modifyVars
:
{
modifyVars
:
{
'
ai-prefix
'
:
'
ai
'
,
"
ai-prefix
"
:
"
ai
"
,
'
primary-color
'
:
'
#42b983
'
"
primary-color
"
:
"
#2ECCCD
"
,
},
},
paths
:
[
paths
:
[
resolve
(
"
node_modules
"
),
resolve
(
"
src
"
)],
resolve
(
'
node_modules
'
),
javascriptEnabled
:
true
,
resolve
(
'
src
'
)
},
],
},
javascriptEnabled
:
true
}
}
},
},
configureWebpack
:
{
configureWebpack
:
{
plugins
:
[
plugins
:
[
new
webpack
.
ContextReplacementPlugin
(
/moment
[\\/]
locale$/
,
/^
\.\/(
zh-cn|en-us
)
$/
),
new
webpack
.
ContextReplacementPlugin
(
]
/moment
[\\/]
locale$/
,
/^
\.\/(
zh-cn|en-us
)
$/
),
],
},
},
chainWebpack
:
config
=>
{
chainWebpack
:
(
config
)
=>
{
const
svgRule
=
config
.
module
.
rule
(
'
svg
'
)
const
svgRule
=
config
.
module
.
rule
(
"
svg
"
);
svgRule
.
uses
.
clear
()
svgRule
.
uses
.
clear
();
svgRule
svgRule
.
include
.
include
.
add
(
resolve
(
"
src/assets/svg-icons
"
))
.
add
(
resolve
(
'
src/assets/svg-icons
'
))
.
end
()
.
end
()
.
use
(
'
svg-sprite-loader
'
)
.
use
(
"
svg-sprite-loader
"
)
.
loader
(
'
svg-sprite-loader
'
)
.
loader
(
"
svg-sprite-loader
"
)
.
options
({
.
options
({
symbolId
:
'
ai-[name]
'
symbolId
:
"
ai-[name]
"
,
})
})
.
end
()
.
end
()
;
// image exclude
// image exclude
const
imagesRule
=
config
.
module
.
rule
(
'
images
'
)
const
imagesRule
=
config
.
module
.
rule
(
"
images
"
);
imagesRule
imagesRule
.
test
(
/
\.(
png|jpe
?
g|gif|webp|svg
)(\?
.*
)?
$/
)
.
test
(
/
\.(
png|jpe
?
g|gif|webp|svg
)(\?
.*
)?
$/
)
.
exclude
.
exclude
.
add
(
resolve
(
"
src/assets/svg-icons
"
))
.
add
(
resolve
(
'
src/assets/svg-icons
'
))
.
end
();
.
end
()
// 重新设置 alias
// 重新设置 alias
config
.
resolve
.
alias
config
.
resolve
.
alias
.
set
(
"
@
"
,
resolve
(
"
src
"
));
.
set
(
'
@
'
,
resolve
(
'
src
'
))
},
}
};
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment