Stackedit/src/components/modals/AccountManagementModal.vue
2022-06-02 07:45:13 +08:00

311 lines
10 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--account-management" aria-label="管理外部账号">
<div class="modal__content">
<div class="modal__image">
<icon-key></icon-key>
</div>
<p v-if="entries.length">Stackedit可以访问以下外部账号</p>
<p v-else>Stackedit尚未访问任何外部账号</p>
<div>
<div class="account-entry flex flex--column" v-for="entry in entries" :key="entry.token.sub">
<div class="account-entry__header flex flex--row flex--align-center">
<div class="account-entry__icon flex flex--column flex--center">
<icon-provider :provider-id="entry.providerId"></icon-provider>
</div>
<div class="account-entry__description">
{{entry.name}}
</div>
<div class="account-entry__buttons flex flex--row flex--center">
<button class="account-entry__button button" @click="remove(entry)" v-title="'删除访问'">
<icon-delete></icon-delete>
</button>
</div>
</div>
<div class="account-entry__row">
<span class="account-entry__field" v-if="entry.userId">
<b>用户ID:</b>
{{entry.userId}}
</span>
<span class="account-entry__field" v-if="entry.url">
<b>URL:</b>
{{entry.url}}
</span>
<span class="account-entry__field" v-if="entry.scopes">
<b>权限范围:</b>
{{entry.scopes.join(', ')}}
</span>
</div>
</div>
</div>
<menu-entry @click.native="addBloggerAccount">
<icon-provider slot="icon" provider-id="blogger"></icon-provider>
<span>添加Blogger账号</span>
</menu-entry>
<menu-entry @click.native="addDropboxAccount">
<icon-provider slot="icon" provider-id="dropbox"></icon-provider>
<span>添加Dropbox账号</span>
</menu-entry>
<menu-entry @click.native="addGithubAccount">
<icon-provider slot="icon" provider-id="github"></icon-provider>
<span>添加GitHub账号</span>
</menu-entry>
<menu-entry @click.native="addGiteeAccount">
<icon-provider slot="icon" provider-id="gitee"></icon-provider>
<span>添加Gitee账号</span>
</menu-entry>
<menu-entry @click.native="addGitlabAccount">
<icon-provider slot="icon" provider-id="gitlab"></icon-provider>
<span>添加GitLab账号</span>
</menu-entry>
<menu-entry @click.native="addGiteaAccount">
<icon-provider slot="icon" provider-id="gitea"></icon-provider>
<span>添加Gitea账号</span>
</menu-entry>
<menu-entry @click.native="addGoogleDriveAccount">
<icon-provider slot="icon" provider-id="googleDrive"></icon-provider>
<span>添加Google Drive账号</span>
</menu-entry>
<menu-entry @click.native="addGooglePhotosAccount">
<icon-provider slot="icon" provider-id="googlePhotos"></icon-provider>
<span>添加Google Photos账号</span>
</menu-entry>
<menu-entry @click.native="addWordpressAccount">
<icon-provider slot="icon" provider-id="wordpress"></icon-provider>
<span>添加WordPress账号</span>
</menu-entry>
<menu-entry @click.native="addZendeskAccount">
<icon-provider slot="icon" provider-id="zendesk"></icon-provider>
<span>添加Zendesk账号</span>
</menu-entry>
</div>
<div class="modal__button-bar">
<button class="button button--resolve" @click="config.resolve()">关闭</button>
</div>
</modal-inner>
</template>
<script>
import { mapGetters } from 'vuex';
import ModalInner from './common/ModalInner';
import MenuEntry from '../menus/common/MenuEntry';
import store from '../../store';
import utils from '../../services/utils';
import googleHelper from '../../services/providers/helpers/googleHelper';
import dropboxHelper from '../../services/providers/helpers/dropboxHelper';
import githubHelper from '../../services/providers/helpers/githubHelper';
import giteeHelper from '../../services/providers/helpers/giteeHelper';
import gitlabHelper from '../../services/providers/helpers/gitlabHelper';
import giteaHelper from '../../services/providers/helpers/giteaHelper';
import wordpressHelper from '../../services/providers/helpers/wordpressHelper';
import zendeskHelper from '../../services/providers/helpers/zendeskHelper';
import badgeSvc from '../../services/badgeSvc';
export default {
components: {
ModalInner,
MenuEntry,
},
computed: {
...mapGetters('modal', [
'config',
]),
entries() {
return [
...Object.values(store.getters['data/googleTokensBySub']).map(token => ({
token,
providerId: 'google',
userId: token.sub,
name: token.name,
scopes: ['openid', 'profile', ...token.scopes
.map(scope => scope.replace(/^https:\/\/www.googleapis.com\/auth\//, ''))],
})),
...Object.values(store.getters['data/couchdbTokensBySub']).map(token => ({
token,
providerId: 'couchdb',
url: token.dbUrl,
name: token.name,
})),
...Object.values(store.getters['data/dropboxTokensBySub']).map(token => ({
token,
providerId: 'dropbox',
userId: token.sub,
name: token.name,
})),
...Object.values(store.getters['data/githubTokensBySub']).map(token => ({
token,
providerId: 'github',
userId: token.sub,
name: token.name,
scopes: token.scopes,
})),
...Object.values(store.getters['data/giteeTokensBySub']).map(token => ({
token,
providerId: 'gitee',
userId: token.sub,
name: token.name,
scopes: ['projects', 'pull_requests'],
})),
...Object.values(store.getters['data/gitlabTokensBySub']).map(token => ({
token,
providerId: 'gitlab',
url: token.serverUrl,
userId: token.sub,
name: token.name,
scopes: ['api'],
})),
...Object.values(store.getters['data/giteaTokensBySub']).map(token => ({
token,
providerId: 'gitea',
url: token.serverUrl,
userId: token.sub,
name: token.name,
scopes: ['api'],
})),
...Object.values(store.getters['data/wordpressTokensBySub']).map(token => ({
token,
providerId: 'wordpress',
userId: token.sub,
name: token.name,
scopes: ['global'],
})),
...Object.values(store.getters['data/zendeskTokensBySub']).map(token => ({
token,
providerId: 'zendesk',
url: `https://${token.subdomain}.zendesk.com/`,
userId: token.sub,
name: token.name,
scopes: ['read', 'hc:write'],
})),
];
},
},
methods: {
async remove(entry) {
const tokensBySub = utils.deepCopy(store.getters[`data/${entry.providerId}TokensBySub`]);
delete tokensBySub[entry.token.sub];
await store.dispatch('data/patchTokensByType', {
[entry.providerId]: tokensBySub,
});
badgeSvc.addBadge('removeAccount');
},
async addBloggerAccount() {
try {
await googleHelper.addBloggerAccount();
} catch (e) { /* cancel */ }
},
async addDropboxAccount() {
try {
await store.dispatch('modal/open', { type: 'dropboxAccount' });
await dropboxHelper.addAccount(!store.getters['data/localSettings'].dropboxRestrictedAccess);
} catch (e) { /* cancel */ }
},
async addGithubAccount() {
try {
await store.dispatch('modal/open', { type: 'githubAccount' });
await githubHelper.addAccount(store.getters['data/localSettings'].githubRepoFullAccess);
} catch (e) { /* cancel */ }
},
async addGiteeAccount() {
try {
await store.dispatch('modal/open', { type: 'giteeAccount' });
await giteeHelper.addAccount();
} catch (e) { /* cancel */ }
},
async addGitlabAccount() {
try {
const { serverUrl, applicationId } = await store.dispatch('modal/open', { type: 'gitlabAccount' });
await gitlabHelper.addAccount(serverUrl, applicationId);
} catch (e) { /* cancel */ }
},
async addGiteaAccount() {
try {
const { serverUrl, applicationId, applicationSecret } = await store.dispatch('modal/open', { type: 'giteaAccount' });
await giteaHelper.addAccount(serverUrl, applicationId, applicationSecret);
} catch (e) { /* cancel */ }
},
async addGoogleDriveAccount() {
try {
await store.dispatch('modal/open', { type: 'googleDriveAccount' });
await googleHelper.addDriveAccount(!store.getters['data/localSettings'].googleDriveRestrictedAccess);
} catch (e) { /* cancel */ }
},
async addGooglePhotosAccount() {
try {
await googleHelper.addPhotosAccount();
} catch (e) { /* cancel */ }
},
async addWordpressAccount() {
try {
await wordpressHelper.addAccount();
} catch (e) { /* cancel */ }
},
async addZendeskAccount() {
try {
const { subdomain, clientId } = await store.dispatch('modal/open', { type: 'zendeskAccount' });
await zendeskHelper.addAccount(subdomain, clientId);
} catch (e) { /* cancel */ }
},
},
};
</script>
<style lang="scss">
@import '../../styles/variables.scss';
.account-entry {
margin: 1.5em 0;
height: auto;
font-size: 17px;
line-height: 1.5;
}
$button-size: 30px;
.account-entry__header {
line-height: $button-size;
}
.account-entry__row {
border-top: 1px solid $hr-color;
font-size: 0.67em;
padding: 0.25em 0;
}
.account-entry__field {
opacity: 0.5;
}
.account-entry__icon {
height: 22px;
width: 22px;
margin-right: 0.75rem;
flex: none;
}
.account-entry__description {
width: 100%;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.account-entry__buttons {
margin-left: 0.75rem;
}
.account-entry__button {
width: $button-size;
height: $button-size;
padding: 4px;
background-color: transparent;
opacity: 0.75;
&:active,
&:focus,
&:hover {
opacity: 1;
background-color: rgba(0, 0, 0, 0.1);
}
}
</style>