Commit 735d39eb authored by wanli's avatar wanli

update tools/frontend

parent 90d35e4c
......@@ -11,16 +11,18 @@
"@antv/g2": "^3.2.7",
"ant-design-vue": "^1.7.5",
"axios": "^0.18.0",
"bootstrap": "4.6.0",
"codemirror": "^5.59.2",
"core-js": "^3.9.0",
"cropperjs": "^1.5.11",
"plyr": "^3.6.4",
"npm-check-updates": "^11.7.1",
"numeral": "^2.0.6",
"plyr": "^3.6.4",
"vue": "^2.5.17",
"vue-codemirror": "^4.0.6",
"vue-i18n": "^8.1.0",
"vue-router": "^3.0.1",
"vuex": "^3.0.1",
"vue-codemirror": "^4.0.6",
"vuex-router-sync": "^5.0.0"
},
"devDependencies": {
......
......@@ -6,6 +6,7 @@
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>EVM 应用商店</title>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.2/css/all.css">
<style>
html,
body {
......
......@@ -46,6 +46,7 @@ export default {
'menu.system.setting.config': '配置管理',
'menu.system.setting.dict': '字典管理',
'menu.system.setting.area': '行政区划',
'menu.system.setting.file-manager': '文件管理',
'menu.system.role': '权限管理',
'menu.system.admin': '系统管理员',
//---
......
/* eslint-disable max-len,prefer-destructuring,object-curly-newline */
import GET from '../../utils/get';
import POST from '../../utils/post';
import GET from '@/utils/get';
import POST from '@/utils/post';
export default {
/**
......
/* eslint-disable object-curly-newline */
import GET from '../../../utils/get';
import GET from '@/utils/get';
export default {
/**
......
......@@ -2,23 +2,23 @@ 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';
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';
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_CN from '@/locales/lang/zh_CN';
import zh_TW from '@/locales/lang/zh_TW';
import pl from '@/locales/lang/pl';
export default {
namespaced: true,
......@@ -57,12 +57,12 @@ export default {
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-CN': Object.freeze(zh_CN),
'zh-TW': Object.freeze(zh_TW),
pl: Object.freeze(pl),
},
......
import GET from '../../../utils/get';
import GET from '@/utils/get';
export default {
/**
......
......@@ -10,13 +10,13 @@ Vue.use(Vuex)
export default new Vuex.Store({
modules: {
fm,
frontend: {
namespaced: true,
modules: {
openapi: frontendOpenapi
}
},
fm: fm,
global: {
namespaced: true,
...global,
......
.breadcrumb {
display: flex;
flex-wrap: wrap;
padding: $breadcrumb-padding-y $breadcrumb-padding-x;
margin-bottom: $breadcrumb-margin-bottom;
@include font-size($breadcrumb-font-size);
list-style: none;
background-color: $breadcrumb-bg;
@include border-radius($breadcrumb-border-radius);
}
.breadcrumb-item {
// The separator between breadcrumbs (by default, a forward-slash: "/")
+ .breadcrumb-item {
padding-left: $breadcrumb-item-padding;
&::before {
float: left; // Suppress inline spacings and underlining of the separator
padding-right: $breadcrumb-item-padding;
color: $breadcrumb-divider-color;
content: escape-svg($breadcrumb-divider);
}
}
// IE9-11 hack to properly handle hyperlink underlines for breadcrumbs built
// without `<ul>`s. The `::before` pseudo-element generates an element
// *within* the .breadcrumb-item and thereby inherits the `text-decoration`.
//
// To trick IE into suppressing the underline, we give the pseudo-element an
// underline and then immediately remove it.
+ .breadcrumb-item:hover::before {
text-decoration: underline;
}
// stylelint-disable-next-line no-duplicate-selectors
+ .breadcrumb-item:hover::before {
text-decoration: none;
}
&.active {
color: $breadcrumb-active-color;
}
}
import axios from 'axios';
export default axios.create();
\ No newline at end of file
import axios from 'axios';
const HTTP = axios.create();
import request from './axios';
export default {
/**
......@@ -7,7 +6,7 @@ export default {
* @returns {*}
*/
initialize() {
return HTTP.get('initialize');
return request.get('initialize');
},
/**
......@@ -17,7 +16,7 @@ export default {
* @returns {*}
*/
tree(disk, path) {
return HTTP.get('tree', { params: { disk, path } });
return request.get('tree', { params: { disk, path } });
},
/**
......@@ -26,7 +25,7 @@ export default {
* @returns {*}
*/
selectDisk(disk) {
return HTTP.get('select-disk', { params: { disk } });
return request.get('select-disk', { params: { disk } });
},
/**
......@@ -36,14 +35,14 @@ export default {
* @returns {*}
*/
content(disk, path) {
return HTTP.get('content', { params: { disk, path } });
return request.get('content', { params: { disk, path } });
},
/**
* Item properties
*/
/* properties(disk, path) {
return HTTP.get('properties', { params: { disk, path } });
return request.get('properties', { params: { disk, path } });
}, */
/**
......@@ -53,7 +52,7 @@ export default {
* @returns {*}
*/
url(disk, path) {
return HTTP.get('url', { params: { disk, path } });
return request.get('url', { params: { disk, path } });
},
/**
......@@ -63,7 +62,7 @@ export default {
* @returns {*}
*/
getFile(disk, path) {
return HTTP.get('download', { params: { disk, path } });
return request.get('download', { params: { disk, path } });
},
/**
......@@ -73,7 +72,7 @@ export default {
* @returns {*}
*/
getFileArrayBuffer(disk, path) {
return HTTP.get('download', {
return request.get('download', {
responseType: 'arraybuffer',
params: { disk, path },
});
......@@ -86,7 +85,7 @@ export default {
* @returns {*}
*/
thumbnail(disk, path) {
return HTTP.get('thumbnails', {
return request.get('thumbnails', {
responseType: 'arraybuffer',
params: { disk, path },
});
......@@ -99,7 +98,8 @@ export default {
* @return {*}
*/
preview(disk, path) {
return HTTP.get('preview', {
window.console.log("###############===========>", disk)
return request.get('preview', {
responseType: 'arraybuffer',
params: { disk, path },
});
......@@ -112,7 +112,7 @@ export default {
* @return {*}
*/
download(disk, path) {
return HTTP.get('download', {
return request.get('download', {
responseType: 'arraybuffer',
params: { disk, path },
});
......
......@@ -28,7 +28,7 @@ export default {
const date = new Date(timestamp * 1000);
return date.toLocaleString(this.$store.state.fm.settings.lang);
return date.toLocaleString();
},
/**
......
import axios from 'axios';
const HTTP = axios.create();
import request from './axios';
export default {
/**
......@@ -10,7 +9,7 @@ export default {
* @returns {AxiosPromise<any>}
*/
createFile(disk, path, name) {
return HTTP.post('create-file', { disk, path, name });
return request.post('create-file', { disk, path, name });
},
/**
......@@ -19,7 +18,7 @@ export default {
* @returns {*}
*/
updateFile(formData) {
return HTTP.post('update-file', formData);
return request.post('update-file', formData);
},
/**
......@@ -28,7 +27,7 @@ export default {
* @returns {*}
*/
createDirectory(data) {
return HTTP.post('create-directory', data);
return request.post('create-directory', data);
},
/**
......@@ -38,7 +37,7 @@ export default {
* @returns {AxiosPromise<any>}
*/
upload(data, config) {
return HTTP.post('upload', data, config);
return request.post('upload', data, config);
},
/**
......@@ -47,7 +46,7 @@ export default {
* @returns {*}
*/
delete(data) {
return HTTP.post('delete', data);
return request.post('delete', data);
},
/**
......@@ -56,7 +55,7 @@ export default {
* @returns {*}
*/
rename(data) {
return HTTP.post('rename', data);
return request.post('rename', data);
},
/**
......@@ -65,7 +64,7 @@ export default {
* @returns {*}
*/
paste(data) {
return HTTP.post('paste', data);
return request.post('paste', data);
},
/**
......@@ -74,7 +73,7 @@ export default {
* @returns {*}
*/
zip(data) {
return HTTP.post('zip', data);
return request.post('zip', data);
},
/**
......@@ -83,6 +82,6 @@ export default {
* @param data
*/
unzip(data) {
return HTTP.post('unzip', data);
return request.post('unzip', data);
},
};
/*
* @Author: your name
* @Date: 2021-06-18 10:43:12
* @LastEditTime: 2021-06-19 17:00:27
* @LastEditors: your name
* @Description: In User Settings Edit
* @FilePath: \evm-store\tools\frontend\src\utils\translate.js
*/
export default {
computed: {
/**
......
@import 'ant-design-vue/lib/style/themes/default.less';
@import 'assets/utils.less';
@import 'styles/utils.less';
.iconGroup {
i {
......
@import 'ant-design-vue/lib/style/themes/default.less';
@import 'assets/utils.less';
@import 'styles/utils.less';
.activitiesList {
padding: 0 24px 8px 24px;
......
......@@ -40,8 +40,7 @@
/* eslint-disable import/no-duplicates, no-param-reassign */
import { mapState } from "vuex";
// Axios
import axios from "axios";
const HTTP = axios.create();
import request from "@/utils/axios";
import EventBus from "@/utils/eventBus";
// Components
import Navbar from "./components/blocks/Navbar.vue";
......@@ -77,19 +76,11 @@ export default {
settings: {
headers: { // axios headers
"X-Requested-With": "XMLHttpRequest",
Authorization: `Bearer ${window.localStorage.getItem("user-token")}`,
// Authorization: `Bearer ${window.localStorage.getItem("user-token")}`,
},
baseUrl: "http://test.loc/file-manager/", // overwrite base url Axios
baseUrl: "/file-manager/", // overwrite base url Axios
windowsConfig: 2, // overwrite config
lang: "zh_CN", // set language
// translation: {
// // add new translation
// name: "zh_CN",
// content: {
// about: "Über",
// back: "Zurück",
// },
// },
},
};
},
......@@ -125,8 +116,8 @@ export default {
EventBus.$off(["contextMenu", "addNotification"]);
// eject interceptors
HTTP.interceptors.request.eject(this.interceptorIndex.request);
HTTP.interceptors.response.eject(this.interceptorIndex.response);
request.interceptors.request.eject(this.interceptorIndex.request);
request.interceptors.response.eject(this.interceptorIndex.response);
},
computed: {
...mapState("fm", {
......@@ -141,7 +132,7 @@ export default {
* Add axios request interceptor
*/
requestInterceptor() {
this.interceptorIndex.request = HTTP.interceptors.request.use(
this.interceptorIndex.request = request.interceptors.request.use(
(config) => {
// overwrite base url and headers
config.baseURL = this.$store.getters["fm/settings/baseUrl"];
......@@ -164,7 +155,7 @@ export default {
* Add axios response interceptor
*/
responseInterceptor() {
this.interceptorIndex.response = HTTP.interceptors.response.use(
this.interceptorIndex.response = request.interceptors.response.use(
(response) => {
// loading spinner -
this.$store.commit("fm/messages/subtractLoading");
......@@ -258,7 +249,21 @@ export default {
};
</script>
<style lang="scss">
<style scope lang="scss">
// https://stackpath.bootstrapcdn.com/bootstrap/scss/mixins/_text-truncate.scss
@import "~bootstrap/scss/mixins";
@import "~bootstrap/scss/functions";
@import "~bootstrap/scss/variables";
@import "~bootstrap/scss/utilities/sizing.scss";
@import "~bootstrap/scss/utilities/text.scss";
@import "~bootstrap/scss/bootstrap-grid";
@import "~bootstrap/scss/close";
@import "~bootstrap/scss/buttons";
@import "~bootstrap/scss/button-group";
@import "~bootstrap/scss/badge";
@import "~bootstrap/scss/modal";
@import "~bootstrap/scss/tables";
@import "~bootstrap/scss/type";
@import "~plyr/src/sass/plyr.scss";
.fm {
position: relative;
......
......@@ -306,7 +306,6 @@ export default {
<style lang="scss">
.fm-navbar {
.btn-group {
margin-right: 0.4rem;
}
......
<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>
<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',
name: "Breadcrumb",
props: {
manager: { type: String, required: true },
},
......@@ -65,12 +71,15 @@ export default {
* @param index
*/
selectDirectory(index) {
const path = this.breadcrumb.slice(0, index + 1).join('/');
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 });
this.$store.dispatch(`fm/${this.manager}/selectDirectory`, {
path,
history: true,
});
}
},
......@@ -79,30 +88,72 @@ export default {
*/
selectMainDirectory() {
if (this.selectedDirectory) {
this.$store.dispatch(`fm/${this.manager}/selectDirectory`, { path: null, history: true });
this.$store.dispatch(`fm/${this.manager}/selectDirectory`, {
path: null,
history: true,
});
}
},
},
};
</script>
<style lang="scss">
.fm-breadcrumb {
<style scoped lang="scss">
@import "~bootstrap/scss/mixins";
@import "~bootstrap/scss/functions";
@import "~bootstrap/scss/variables";
.fm-breadcrumb {
.breadcrumb {
display: flex;
flex-wrap: nowrap;
padding: 0.2rem 0.3rem;
margin-bottom: 0.5rem;
@include font-size($breadcrumb-font-size);
list-style: none;
background-color: $breadcrumb-bg;
@include border-radius($breadcrumb-border-radius);
.breadcrumb {
flex-wrap: nowrap;
padding: 0.2rem 0.3rem;
margin-bottom: 0.5rem;
.breadcrumb-item {
// The separator between breadcrumbs (by default, a forward-slash: "/")
+ .breadcrumb-item {
padding-left: $breadcrumb-item-padding;
&.active-manager {
background-color: #c2e5eb;
}
.breadcrumb-item:not(.active):hover {
cursor: pointer;
font-weight: normal;
color: #6d757d;
}
&::before {
float: left; // Suppress inline spacings and underlining of the separator
padding-right: $breadcrumb-item-padding;
color: $breadcrumb-divider-color;
content: escape-svg($breadcrumb-divider);
}
}
// IE9-11 hack to properly handle hyperlink underlines for breadcrumbs built
// without `<ul>`s. The `::before` pseudo-element generates an element
// *within* the .breadcrumb-item and thereby inherits the `text-decoration`.
//
// To trick IE into suppressing the underline, we give the pseudo-element an
// underline and then immediately remove it.
+ .breadcrumb-item:hover::before {
text-decoration: underline;
}
// stylelint-disable-next-line no-duplicate-selectors
+ .breadcrumb-item:hover::before {
text-decoration: none;
}
&.active {
color: $breadcrumb-active-color;
}
}
&.active-manager {
background-color: #c2e5eb;
}
.breadcrumb-item:not(.active):hover {
cursor: pointer;
font-weight: normal;
color: #6d757d;
}
}
}
</style>
<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>
<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';
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',
name: "Modal",
components: {
NewFile,
NewFolder,
......@@ -49,7 +51,10 @@ export default {
},
mounted() {
// set height
this.$store.commit('fm/modal/setModalBlockHeight', this.$refs.fmModal.offsetHeight);
this.$store.commit(
"fm/modal/setModalBlockHeight",
this.$refs.fmModal.offsetHeight
);
},
computed: {
/**
......@@ -66,9 +71,10 @@ export default {
*/
modalSize() {
return {
'modal-xl': this.modalName === 'Preview' || this.modalName === 'TextEdit',
'modal-lg': this.modalName === 'VideoPlayer',
'modal-sm': false,
"modal-xl":
this.modalName === "Preview" || this.modalName === "TextEdit",
"modal-lg": this.modalName === "VideoPlayer",
"modal-sm": false,
};
},
},
......@@ -77,37 +83,42 @@ export default {
* Hide modal window
*/
hideModal() {
this.$store.commit('fm/modal/clearModal');
this.$store.commit("fm/modal/clearModal");
},
},
};
</script>
<style lang="scss">
<style scoped lang="scss">
// @import "~bootstrap/scss/mixins";
// @import "~bootstrap/scss/functions";
// @import "~bootstrap/scss/variables";
// @import "~bootstrap/scss/modal";
.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, 0.35);
display: block;
transition: opacity 0.4s ease;
overflow: auto;
.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%;
}
}
.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;
}
.fm-modal-enter-active,
.fm-modal-leave-active {
transition: opacity 0.5s;
}
.fm-modal-enter,
.fm-modal-leave-to {
opacity: 0;
}
</style>
<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">&times;</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 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">&times;</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';
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',
name: "Preview",
mixins: [modal, translate, helper],
components: { CropperModule },
data() {
return {
showCropperModule: false,
imgSrc: '',
imgSrc: "",
};
},
created() {
......@@ -63,7 +81,7 @@ export default {
* @return {*}
*/
auth() {
return this.$store.getters['fm/settings/authHeader'];
return this.$store.getters["fm/settings/authHeader"];
},
/**
......@@ -71,7 +89,7 @@ export default {
* @returns {*}
*/
selectedDisk() {
return this.$store.getters['fm/selectedDisk'];
return this.$store.getters["fm/selectedDisk"];
},
/**
......@@ -79,7 +97,7 @@ export default {
* @returns {*}
*/
selectedItem() {
return this.$store.getters['fm/selectedItems'][0];
return this.$store.getters["fm/selectedItems"][0];
},
/**
......@@ -87,7 +105,9 @@ export default {
* @return boolean
*/
showFooter() {
return this.canCrop(this.selectedItem.extension) && !this.showCropperModule;
return (
this.canCrop(this.selectedItem.extension) && !this.showCropperModule
);
},
/**
......@@ -109,7 +129,9 @@ export default {
* @returns {boolean}
*/
canCrop(extension) {
return this.$store.state.fm.settings.cropExtensions.includes(extension.toLowerCase());
return this.$store.state.fm.settings.cropExtensions.includes(
extension.toLowerCase()
);
},
/**
......@@ -126,17 +148,22 @@ export default {
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');
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}`;
});
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}`;
this.imgSrc = `${
this.$store.getters["fm/settings/baseUrl"]
}preview?disk=${this.selectedDisk}&path=${encodeURIComponent(
this.selectedItem.path
)}&v=${this.selectedItem.timestamp}`;
}
},
},
......@@ -144,19 +171,18 @@ export default {
</script>
<style lang="scss">
.fm-modal-preview {
.modal-body {
padding: 0;
.fm-modal-preview {
.modal-body {
padding: 0;
img {
max-width: 100%;
}
}
& > .d-flex {
padding: 1rem;
border-top: 1px solid #e9ecef;
}
img {
max-width: 100%;
}
}
& > .d-flex {
padding: 1rem;
border-top: 1px solid #e9ecef;
}
}
</style>
<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>
<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>
<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',
name: "Branch",
props: {
parentId: { type: Number, required: true },
},
......@@ -40,7 +47,9 @@ export default {
* @returns {*}
*/
subDirectories() {
return this.$store.getters['fm/tree/directories'].filter((item) => item.parentId === this.parentId);
return this.$store.getters["fm/tree/directories"].filter(
(item) => item.parentId === this.parentId
);
},
},
methods: {
......@@ -70,10 +79,10 @@ export default {
showSubdirectories(path, showState) {
if (showState) {
// hide
this.$store.dispatch('fm/tree/hideSubdirectories', path);
this.$store.dispatch("fm/tree/hideSubdirectories", path);
} else {
// show
this.$store.dispatch('fm/tree/showSubdirectories', path);
this.$store.dispatch("fm/tree/showSubdirectories", path);
}
},
......@@ -84,7 +93,10 @@ export default {
selectDirectory(path) {
// only if this path not selected
if (!this.isDirectorySelected(path)) {
this.$store.dispatch('fm/left/selectDirectory', { path, history: true });
this.$store.dispatch("fm/left/selectDirectory", {
path,
history: true,
});
}
},
},
......@@ -92,38 +104,40 @@ export default {
</script>
<style lang="scss">
.fm-tree-branch {
display: table;
width: 100%;
padding-left: 1.4rem;
.fm-tree-branch {
display: table;
width: 100%;
padding-left: 1.4rem!important;
li > p{
margin-bottom: 0.1rem;
padding: 0.4rem 0.4rem;
white-space: nowrap;
cursor: pointer;
li > p {
margin-bottom: 0.1rem;
padding: 0.4rem 0.4rem;
white-space: nowrap;
cursor: pointer;
&:hover,
&.selected {
background-color: #f8f9fa;
}
}
&:hover,
&.selected {
background-color: #f8f9fa;
}
}
.fas.fa-minus{
padding-left: 0.1rem;
padding-right: 0.6rem;
}
.fas.fa-minus {
padding-left: 0.1rem;
padding-right: 0.6rem;
}
.far{
padding-right: 0.5rem;
}
}
.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;
}
.fade-tree-enter-active,
.fade-tree-leave-active {
transition: all 0.3s ease;
}
.fade-tree-enter,
.fade-tree-leave-to {
transform: translateX(20px);
opacity: 0;
}
</style>
<!--
* @Author: your name
* @Date: 2021-06-18 10:39:31
* @LastEditTime: 2021-06-19 16:35:22
* @LastEditors: your name
* @Description: In User Settings Edit
* @FilePath: \evm-store\tools\frontend\src\views\FileManager\components\tree\FolderTree.vue
-->
<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 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';
import Branch from "./Branch.vue";
export default {
name: 'FolderTree',
name: "FolderTree",
components: {
branch: Branch,
},
......@@ -21,30 +29,30 @@ export default {
* @returns {*}
*/
selectedDisk() {
return this.$store.getters['fm/selectedDisk'];
return this.$store.getters["fm/selectedDisk"];
},
},
};
</script>
<style lang="scss">
.fm-tree {
overflow: auto;
border-right: 1px solid #6d757d;
.fm-tree {
overflow: auto;
border-right: 1px solid #6d757d;
& > .fm-folders-tree {
padding-left: 0.2rem;
}
& > .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 {
padding: 0.2rem 0.3rem;
margin-bottom: 0.3rem;
background-color: white;
}
.fm-tree-disk > i {
padding-left: 0.2rem;
padding-right: 0.5rem;
}
}
.fm-tree-disk > i {
padding-left: 0.2rem;
padding-right: 0.5rem;
}
}
</style>
......@@ -365,5 +365,5 @@ export default {
};
</script>
<style lang="less">
@import url("assets/tableList.less");
@import url("styles/tableList.less");
</style>
\ No newline at end of file
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment