Stackedit/src/components/modals/AccountManagementModal.vue
2022-05-25 13:43:45 +08:00

311 lines
10 KiB
Vue

<template>
<modal-inner class="modal__inner-1--account-management" aria-label="Manage external accounts">
<div class="modal__content">
<div class="modal__image">
<icon-key></icon-key>
</div>
<p v-if="entries.length">StackEdit has access to the following external accounts:</p>
<p v-else>StackEdit has no access to any external account yet.</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="'Remove access'">
<icon-delete></icon-delete>
</button>
</div>
</div>
<div class="account-entry__row">
<span class="account-entry__field" v-if="entry.userId">
<b>User 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>Scopes:</b>
{{entry.scopes.join(', ')}}
</span>
</div>
</div>
</div>
<menu-entry @click.native="addBloggerAccount">
<icon-provider slot="icon" provider-id="blogger"></icon-provider>
<span>Add Blogger account</span>
</menu-entry>
<menu-entry @click.native="addDropboxAccount">
<icon-provider slot="icon" provider-id="dropbox"></icon-provider>
<span>Add Dropbox account</span>
</menu-entry>
<menu-entry @click.native="addGithubAccount">
<icon-provider slot="icon" provider-id="github"></icon-provider>
<span>Add GitHub account</span>
</menu-entry>
<menu-entry @click.native="addGiteeAccount">
<icon-provider slot="icon" provider-id="gitee"></icon-provider>
<span>Add Gitee account</span>
</menu-entry>
<menu-entry @click.native="addGitlabAccount">
<icon-provider slot="icon" provider-id="gitlab"></icon-provider>
<span>Add GitLab account</span>
</menu-entry>
<menu-entry @click.native="addGiteaAccount">
<icon-provider slot="icon" provider-id="gitea"></icon-provider>
<span>Add Gitea account</span>
</menu-entry>
<menu-entry @click.native="addGoogleDriveAccount">
<icon-provider slot="icon" provider-id="googleDrive"></icon-provider>
<span>Add Google Drive account</span>
</menu-entry>
<menu-entry @click.native="addGooglePhotosAccount">
<icon-provider slot="icon" provider-id="googlePhotos"></icon-provider>
<span>Add Google Photos account</span>
</menu-entry>
<menu-entry @click.native="addWordpressAccount">
<icon-provider slot="icon" provider-id="wordpress"></icon-provider>
<span>Add WordPress account</span>
</menu-entry>
<menu-entry @click.native="addZendeskAccount">
<icon-provider slot="icon" provider-id="zendesk"></icon-provider>
<span>Add Zendesk account</span>
</menu-entry>
</div>
<div class="modal__button-bar">
<button class="button button--resolve" @click="config.resolve()">Close</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>