Stackedit/src/components/modals/WorkspaceManagementModal.vue
2022-09-23 19:33:25 +08:00

284 lines
8.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<modal-inner class="modal__inner-1--workspace-management" aria-label="管理文档空间">
<div class="modal__content">
<div class="modal__image">
<icon-database></icon-database>
</div>
<p><br>可以访问以下文档空间</p>
<div class="workspace-entry flex flex--column" v-for="(workspace, id) in workspacesById" :key="id">
<div class="flex flex--column">
<div class="workspace-entry__header flex flex--row flex--align-center">
<div class="workspace-entry__icon">
<icon-provider :provider-id="workspace.providerId"></icon-provider>
</div>
<input class="text-input" type="text" v-if="editedId === id" v-focus @blur="submitEdit()" @keydown.enter="submitEdit()" @keydown.esc.stop="submitEdit(true)" v-model="editingName">
<div class="workspace-entry__name" v-else>{{workspace.name}}</div>
<div class="workspace-entry__buttons flex flex--row">
<button class="workspace-entry__button button" @click="edit(id)" v-title="'编辑名称'">
<icon-pen></icon-pen>
</button>
<template v-if="workspace.providerId === 'giteeAppData' || workspace.providerId === 'githubWorkspace'
|| workspace.providerId === 'giteeWorkspace' || workspace.providerId === 'gitlabWorkspace' || workspace.providerId === 'giteaWorkspace'">
<button class="workspace-entry__button button" @click="stopAutoSync(id)" v-if="workspace.autoSync == undefined || workspace.autoSync" v-title="'关闭自动同步'">
<icon-sync-auto></icon-sync-auto>
</button>
<button class="workspace-entry__button button" @click="startAutoSync(id)" v-if="workspace.autoSync != undefined && !workspace.autoSync" v-title="'启动自动同步'">
<icon-sync-stop></icon-sync-stop>
</button>
</template>
<button class="workspace-entry__button button" @click="remove(id)" v-title="'删除'">
<icon-delete></icon-delete>
</button>
</div>
</div>
<div class="workspace-entry__row flex flex--row flex--align-center">
<div class="workspace-entry__url">
{{workspace.url}}
</div>
<div class="workspace-entry__buttons flex flex--row">
<button class="workspace-entry__button button" v-clipboard="workspace.url" @click="info('文档空间URL已复制到剪贴板!')" v-title="'复制URL'">
<icon-content-copy></icon-content-copy>
</button>
<a class="workspace-entry__button button" :href="workspace.url" target="_blank" v-title="'打开文档空间'">
<icon-open-in-new></icon-open-in-new>
</a>
</div>
</div>
<div class="workspace-entry__row flex flex--row flex--align-center" v-if="workspace.locationUrl">
<div class="workspace-entry__url">
{{workspace.locationUrl}}
</div>
<div class="workspace-entry__buttons flex flex--row">
<button class="workspace-entry__button button" v-clipboard="workspace.locationUrl" @click="info('文档空间URL已复制到剪贴板!')" v-title="'复制URL'">
<icon-content-copy></icon-content-copy>
</button>
<a class="workspace-entry__button button" :href="workspace.locationUrl" target="_blank" v-title="'打开文档空间位置'">
<icon-open-in-new></icon-open-in-new>
</a>
</div>
</div>
<div>
<span class="workspace-entry__offline" v-if="availableOffline[id]">
离线可用
</span>
</div>
</div>
</div>
</div>
<div class="modal__button-bar">
<button class="button button--resolve" @click="config.resolve()">关闭</button>
</div>
</modal-inner>
</template>
<script>
import Vue from 'vue';
import { mapGetters, mapActions } from 'vuex';
import ModalInner from './common/ModalInner';
import workspaceSvc from '../../services/workspaceSvc';
import store from '../../store';
import badgeSvc from '../../services/badgeSvc';
import localDbSvc from '../../services/localDbSvc';
export default {
components: {
ModalInner,
},
data: () => ({
editedId: null,
editingName: '',
availableOffline: {},
}),
computed: {
...mapGetters('modal', [
'config',
]),
...mapGetters('workspace', [
'workspacesById',
'mainWorkspace',
'currentWorkspace',
]),
},
methods: {
...mapActions('notification', [
'info',
]),
edit(id) {
this.editedId = id;
this.editingName = this.workspacesById[id].name;
},
submitEdit(cancel) {
const workspace = this.workspacesById[this.editedId];
if (workspace) {
if (!cancel && this.editingName && this.editingName !== workspace.name) {
store.dispatch('workspace/patchWorkspacesById', {
[this.editedId]: {
...workspace,
name: this.editingName,
},
});
badgeSvc.addBadge('renameWorkspace');
} else {
this.editingName = workspace.name;
}
}
this.editedId = null;
},
async remove(id) {
if (id === this.mainWorkspace.id) {
this.info('您的主文档空间无法删除。');
} else if (id === this.currentWorkspace.id) {
this.info('请先关闭文档空间,然后再将其删除。');
} else {
try {
const workspace = this.workspacesById[id];
if (!workspace) {
return;
}
await store.dispatch('modal/open', {
type: 'removeWorkspace',
name: workspace.name,
});
workspaceSvc.removeWorkspace(id);
badgeSvc.addBadge('removeWorkspace');
} catch (e) { /* Cancel */ }
}
},
async stopAutoSync(id) {
const workspace = this.workspacesById[id];
if (!workspace) {
return;
}
await store.dispatch('modal/open', {
type: 'stopAutoSyncWorkspace',
name: workspace.name,
});
store.dispatch('workspace/patchWorkspacesById', {
[id]: {
...workspace,
autoSync: false,
},
});
badgeSvc.addBadge('stopAutoSyncWorkspace');
},
async startAutoSync(id) {
const workspace = this.workspacesById[id];
if (!workspace) {
return;
}
await store.dispatch('modal/open', {
type: 'autoSyncWorkspace',
name: workspace.name,
});
store.dispatch('workspace/patchWorkspacesById', {
[id]: {
...workspace,
autoSync: true,
},
});
badgeSvc.addBadge('autoSyncWorkspace');
},
},
created() {
Object.keys(this.workspacesById).forEach(async (workspaceId) => {
const cancel = localDbSvc.getWorkspaceItems(workspaceId, () => {
Vue.set(this.availableOffline, workspaceId, true);
cancel();
});
});
},
};
</script>
<style lang="scss">
@import '../../styles/variables.scss';
.workspace-entry {
margin: 1.75em 0;
height: auto;
font-size: 17px;
line-height: 1.5;
}
$button-size: 30px;
$small-button-size: 22px;
.workspace-entry__header {
line-height: $button-size;
.text-input {
border: 1px solid $link-color;
padding: 0 5px;
line-height: $button-size;
height: $button-size;
}
}
.workspace-entry__row {
border-top: 1px solid $hr-color;
line-height: $small-button-size;
}
.workspace-entry__icon {
height: 22px;
width: 22px;
margin-right: 0.75rem;
flex: none;
}
.workspace-entry__name {
width: 100%;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
font-weight: bold;
}
.workspace-entry__url {
width: 100%;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
opacity: 0.5;
font-size: 0.67em;
}
.workspace-entry__buttons {
margin-left: 0.75rem;
.workspace-entry__row & {
margin-left: 0.5rem;
}
}
.workspace-entry__button {
width: $button-size;
height: $button-size;
padding: 4px;
background-color: transparent;
opacity: 0.75;
.workspace-entry__row & {
width: $small-button-size;
height: $small-button-size;
padding: 4px;
}
&:active,
&:focus,
&:hover {
opacity: 1;
background-color: rgba(0, 0, 0, 0.1);
}
}
.workspace-entry__offline {
font-size: 0.8rem;
line-height: 1;
padding: 0.15em 0.35em;
border-radius: 3px;
color: #fff;
background-color: darken($error-color, 10);
}
</style>