Stackedit/src/components/menus/MainMenu.vue
2019-06-16 14:49:50 +01:00

263 lines
9.4 KiB
Vue

<template>
<div class="side-bar__panel side-bar__panel--menu">
<div class="side-bar__info">
<div class="menu-entry menu-entry--info flex flex--row flex--align-center" v-if="loginToken">
<div class="menu-entry__icon menu-entry__icon--image">
<user-image :user-id="userId"></user-image>
</div>
<span>Signed in as <b>{{loginToken.name}}</b>.</span>
</div>
<div class="menu-entry menu-entry--info flex flex--row flex--align-center" v-if="syncToken">
<div class="menu-entry__icon menu-entry__icon--image">
<icon-provider :provider-id="currentWorkspace.providerId"></icon-provider>
</div>
<span v-if="currentWorkspace.providerId === 'googleDriveAppData'">
<b>{{currentWorkspace.name}}</b> synced with your Google Drive app data folder.
</span>
<span v-else-if="currentWorkspace.providerId === 'googleDriveWorkspace'">
<b>{{currentWorkspace.name}}</b> synced with a <a :href="workspaceLocationUrl" target="_blank">Google Drive folder</a>.
</span>
<span v-else-if="currentWorkspace.providerId === 'couchdbWorkspace'">
<b>{{currentWorkspace.name}}</b> synced with a <a :href="workspaceLocationUrl" target="_blank">CouchDB database</a>.
</span>
<span v-else-if="currentWorkspace.providerId === 'githubWorkspace'">
<b>{{currentWorkspace.name}}</b> synced with a <a :href="workspaceLocationUrl" target="_blank">GitHub repo</a>.
</span>
<span v-else-if="currentWorkspace.providerId === 'gitlabWorkspace'">
<b>{{currentWorkspace.name}}</b> synced with a <a :href="workspaceLocationUrl" target="_blank">GitLab project</a>.
</span>
</div>
<div class="menu-entry menu-entry--info flex flex--row flex--align-center" v-else>
<div class="menu-entry__icon menu-entry__icon--disabled">
<icon-sync-off></icon-sync-off>
</div>
<span><b>{{currentWorkspace.name}}</b> not synced.</span>
</div>
</div>
<menu-entry v-if="!loginToken" @click.native="signin">
<icon-login slot="icon"></icon-login>
<div>Sign in with Google</div>
<span>Sync your main workspace and unlock functionalities.</span>
</menu-entry>
<menu-entry @click.native="setPanel('workspaces')">
<icon-database slot="icon"></icon-database>
<div><div class="menu-entry__label menu-entry__label--count" v-if="workspaceCount">{{workspaceCount}}</div> Workspaces</div>
<span>Switch to another workspace.</span>
</menu-entry>
<hr>
<menu-entry @click.native="setPanel('sync')">
<icon-sync slot="icon"></icon-sync>
<div><div class="menu-entry__label menu-entry__label--count" v-if="syncLocationCount">{{syncLocationCount}}</div> Synchronize</div>
<span>Sync your files in the Cloud.</span>
</menu-entry>
<menu-entry @click.native="setPanel('publish')">
<icon-upload slot="icon"></icon-upload>
<div><div class="menu-entry__label menu-entry__label--count" v-if="publishLocationCount">{{publishLocationCount}}</div>Publish</div>
<span>Export your files to the web.</span>
</menu-entry>
<menu-entry @click.native="setPanel('history')">
<icon-history slot="icon"></icon-history>
<div>History</div>
<span>Track and restore file revisions.</span>
</menu-entry>
<menu-entry @click.native="fileProperties">
<icon-view-list slot="icon"></icon-view-list>
<div>File properties</div>
<span>Add metadata and configure extensions.</span>
</menu-entry>
<hr>
<menu-entry @click.native="setPanel('toc')">
<icon-toc slot="icon"></icon-toc>
Table of contents
</menu-entry>
<menu-entry @click.native="setPanel('help')">
<icon-help-circle slot="icon"></icon-help-circle>
Markdown cheat sheet
</menu-entry>
<hr>
<menu-entry @click.native="setPanel('import')">
<icon-content-save slot="icon"></icon-content-save>
Import from disk
</menu-entry>
<menu-entry @click.native="setPanel('export')">
<icon-content-save slot="icon"></icon-content-save>
Export to disk
</menu-entry>
<menu-entry @click.native="print">
<icon-printer slot="icon"></icon-printer>
Print
</menu-entry>
<hr>
<menu-entry @click.native="settings">
<icon-settings slot="icon"></icon-settings>
<div>Settings</div>
<span>Tweak application and keyboard shortcuts.</span>
</menu-entry>
<menu-entry @click.native="templates">
<icon-code-braces slot="icon"></icon-code-braces>
<div><div class="menu-entry__label menu-entry__label--count">{{templateCount}}</div> Templates</div>
<span>Configure Handlebars templates for your exports.</span>
</menu-entry>
<menu-entry @click.native="accounts">
<icon-key slot="icon"></icon-key>
<div><div class="menu-entry__label menu-entry__label--count">{{accountCount}}</div> User accounts</div>
<span>Manage access to your external accounts.</span>
</menu-entry>
<hr>
<menu-entry @click.native="exportWorkspace">
<icon-content-save slot="icon"></icon-content-save>
Export workspace backup
</menu-entry>
<input class="hidden-file" id="import-backup-file-input" type="file" @change="onImportBackup">
<label class="menu-entry button flex flex--row flex--align-center" for="import-backup-file-input">
<div class="menu-entry__icon flex flex--column flex--center">
<icon-content-save></icon-content-save>
</div>
<div class="flex flex--column">
Import workspace backup
</div>
</label>
<menu-entry @click.native="reset">
<icon-logout slot="icon"></icon-logout>
<div>Reset application</div>
<span>Sign out and clean all workspaces.</span>
</menu-entry>
<hr>
<menu-entry @click.native="about">
<icon-help-circle slot="icon"></icon-help-circle>
About StackEdit
</menu-entry>
</div>
</template>
<script>
import { mapGetters, mapActions } from 'vuex';
import MenuEntry from './common/MenuEntry';
import providerRegistry from '../../services/providers/common/providerRegistry';
import UserImage from '../UserImage';
import googleHelper from '../../services/providers/helpers/googleHelper';
import syncSvc from '../../services/syncSvc';
import userSvc from '../../services/userSvc';
import backupSvc from '../../services/backupSvc';
import utils from '../../services/utils';
import store from '../../store';
export default {
components: {
MenuEntry,
UserImage,
},
computed: {
...mapGetters('workspace', [
'currentWorkspace',
'syncToken',
'loginToken',
]),
userId() {
return userSvc.getCurrentUserId();
},
workspaceLocationUrl() {
const provider = providerRegistry.providersById[this.currentWorkspace.providerId];
return provider.getWorkspaceLocationUrl(this.currentWorkspace);
},
workspaceCount() {
return Object.keys(store.getters['workspace/workspacesById']).length;
},
syncLocationCount() {
return Object.keys(store.getters['syncLocation/currentWithWorkspaceSyncLocation']).length;
},
publishLocationCount() {
return Object.keys(store.getters['publishLocation/current']).length;
},
templateCount() {
return Object.keys(store.getters['data/allTemplatesById']).length;
},
accountCount() {
return Object.values(store.getters['data/tokensByType'])
.reduce((count, tokensBySub) => count + Object.values(tokensBySub).length, 0);
},
},
methods: {
...mapActions('data', {
setPanel: 'setSideBarPanel',
}),
async signin() {
try {
await googleHelper.signin();
syncSvc.requestSync();
} catch (e) {
// Cancel
}
},
async fileProperties() {
try {
await store.dispatch('modal/open', 'fileProperties');
} catch (e) {
// Cancel
}
},
print() {
window.print();
},
onImportBackup(evt) {
const file = evt.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = (e) => {
const text = e.target.result;
if (text.match(/\uFFFD/)) {
store.dispatch('notification/error', 'File is not readable.');
} else {
backupSvc.importBackup(text);
}
};
const blob = file.slice(0, 10000000);
reader.readAsText(blob);
}
},
exportWorkspace() {
window.location.href = utils.addQueryParams('app', {
...utils.queryParams,
exportWorkspace: true,
}, true);
window.location.reload();
},
async settings() {
try {
const settings = await store.dispatch('modal/open', 'settings');
store.dispatch('data/setSettings', settings);
} catch (e) {
// Cancel
}
},
async templates() {
try {
const { templates } = await store.dispatch('modal/open', 'templates');
store.dispatch('data/setTemplatesById', templates);
} catch (e) {
// Cancel
}
},
async accounts() {
try {
await store.dispatch('modal/open', 'accountManagement');
} catch (e) {
// Cancel
}
},
async reset() {
try {
await store.dispatch('modal/open', 'reset');
window.location.href = '#reset=true';
window.location.reload();
} catch (e) {
// Cancel
}
},
about() {
store.dispatch('modal/open', 'about');
},
},
};
</script>