mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
✨ Added api key setup view.
This commit is contained in:
parent
f98813cdc6
commit
88ec0b5313
14
packages/editor-ui/src/api/api-keys.ts
Normal file
14
packages/editor-ui/src/api/api-keys.ts
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
import {IRestApiContext} from "@/Interface";
|
||||||
|
import {makeRestApiRequest} from "@/api/helpers";
|
||||||
|
|
||||||
|
export function getApiKey(context: IRestApiContext): Promise<{ apiKey: string | null }> {
|
||||||
|
return makeRestApiRequest(context, 'GET', '/me/api-key');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createApiKey(context: IRestApiContext): Promise<{ apiKey: string | null }> {
|
||||||
|
return makeRestApiRequest(context, 'POST', '/users/me/api-key');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function deleteApiKey(context: IRestApiContext): Promise<{ success: boolean }> {
|
||||||
|
return makeRestApiRequest(context, 'DELETE', '/me/api-key');
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
import { IRestApiContext, IN8nPrompts, IN8nValueSurveyData, IN8nUISettings } from '../Interface';
|
import {IRestApiContext, IN8nPrompts, IN8nValueSurveyData, IN8nUISettings} from '../Interface';
|
||||||
import { makeRestApiRequest, get, post } from './helpers';
|
import { makeRestApiRequest, get, post } from './helpers';
|
||||||
import { N8N_IO_BASE_URL } from '@/constants';
|
import { N8N_IO_BASE_URL } from '@/constants';
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,12 @@
|
||||||
</i>
|
</i>
|
||||||
<span slot="title">{{ $locale.baseText('settings.users') }}</span>
|
<span slot="title">{{ $locale.baseText('settings.users') }}</span>
|
||||||
</n8n-menu-item>
|
</n8n-menu-item>
|
||||||
|
<n8n-menu-item index="/settings/api" :class="$style.tab">
|
||||||
|
<i :class="$style.icon">
|
||||||
|
<font-awesome-icon icon="plug" />
|
||||||
|
</i>
|
||||||
|
<span slot="title">{{ $locale.baseText('settings.api') }}</span>
|
||||||
|
</n8n-menu-item>
|
||||||
</n8n-menu>
|
</n8n-menu>
|
||||||
<div :class="$style.versionContainer">
|
<div :class="$style.versionContainer">
|
||||||
<n8n-link @click="onVersionClick" size="small">
|
<n8n-link @click="onVersionClick" size="small">
|
||||||
|
|
|
@ -234,5 +234,6 @@ export enum VIEWS {
|
||||||
CHANGE_PASSWORD = "ChangePasswordView",
|
CHANGE_PASSWORD = "ChangePasswordView",
|
||||||
USERS_SETTINGS = "UsersSettings",
|
USERS_SETTINGS = "UsersSettings",
|
||||||
PERSONAL_SETTINGS = "PersonalSettings",
|
PERSONAL_SETTINGS = "PersonalSettings",
|
||||||
|
API_SETTINGS = "APISettings",
|
||||||
NOT_FOUND = "NotFoundView",
|
NOT_FOUND = "NotFoundView",
|
||||||
}
|
}
|
||||||
|
|
|
@ -647,6 +647,18 @@
|
||||||
"settings.users.usersEmailedError": "Couldn't send invite email",
|
"settings.users.usersEmailedError": "Couldn't send invite email",
|
||||||
"settings.users.usersInvited": "Users invited",
|
"settings.users.usersInvited": "Users invited",
|
||||||
"settings.users.usersInvitedError": "Could not invite users",
|
"settings.users.usersInvitedError": "Could not invite users",
|
||||||
|
"settings.api": "API",
|
||||||
|
"settings.api.create.title": "Set up your API Key",
|
||||||
|
"settings.api.create.description": "You can use API keys for accessing n8n's",
|
||||||
|
"settings.api.create.description.link": "REST API",
|
||||||
|
"settings.api.create.button": "Create an API Key",
|
||||||
|
"settings.api.create.button.loading": "Creating API Key...",
|
||||||
|
"settings.api.error.title": "Something went wrong",
|
||||||
|
"settings.api.error.get": "Could not check if an api key already exists.",
|
||||||
|
"settings.api.error.create": "Creating the API Key failed.",
|
||||||
|
"settings.api.error.delete": "Deleting the API Key failed.",
|
||||||
|
"settings.api.view.info": "Use your API Key to access n8n's REST API to build your own integrations.",
|
||||||
|
"settings.api.view.myKey": "My API Key",
|
||||||
"settings.version": "Version",
|
"settings.version": "Version",
|
||||||
"showMessage.cancel": "@:_reusableBaseText.cancel",
|
"showMessage.cancel": "@:_reusableBaseText.cancel",
|
||||||
"showMessage.ok": "OK",
|
"showMessage.ok": "OK",
|
||||||
|
|
|
@ -64,6 +64,7 @@ import {
|
||||||
faPencilAlt,
|
faPencilAlt,
|
||||||
faPlay,
|
faPlay,
|
||||||
faPlayCircle,
|
faPlayCircle,
|
||||||
|
faPlug,
|
||||||
faPlus,
|
faPlus,
|
||||||
faPlusCircle,
|
faPlusCircle,
|
||||||
faPlusSquare,
|
faPlusSquare,
|
||||||
|
@ -166,6 +167,7 @@ addIcon(faPen);
|
||||||
addIcon(faPencilAlt);
|
addIcon(faPencilAlt);
|
||||||
addIcon(faPlay);
|
addIcon(faPlay);
|
||||||
addIcon(faPlayCircle);
|
addIcon(faPlayCircle);
|
||||||
|
addIcon(faPlug);
|
||||||
addIcon(faPlus);
|
addIcon(faPlus);
|
||||||
addIcon(faPlusCircle);
|
addIcon(faPlusCircle);
|
||||||
addIcon(faPlusSquare);
|
addIcon(faPlusSquare);
|
||||||
|
|
|
@ -8,6 +8,7 @@ import MainSidebar from '@/components/MainSidebar.vue';
|
||||||
import NodeView from '@/views/NodeView.vue';
|
import NodeView from '@/views/NodeView.vue';
|
||||||
import SettingsPersonalView from './views/SettingsPersonalView.vue';
|
import SettingsPersonalView from './views/SettingsPersonalView.vue';
|
||||||
import SettingsUsersView from './views/SettingsUsersView.vue';
|
import SettingsUsersView from './views/SettingsUsersView.vue';
|
||||||
|
import SettingsApiView from './views/SettingsApiView.vue';
|
||||||
import SetupView from './views/SetupView.vue';
|
import SetupView from './views/SetupView.vue';
|
||||||
import SigninView from './views/SigninView.vue';
|
import SigninView from './views/SigninView.vue';
|
||||||
import SignupView from './views/SignupView.vue';
|
import SignupView from './views/SignupView.vue';
|
||||||
|
@ -360,6 +361,23 @@ const router = new Router({
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/settings/api',
|
||||||
|
name: VIEWS.API_SETTINGS,
|
||||||
|
components: {
|
||||||
|
default: SettingsApiView,
|
||||||
|
},
|
||||||
|
meta: {
|
||||||
|
telemetry: {
|
||||||
|
pageCategory: 'settings',
|
||||||
|
},
|
||||||
|
permissions: {
|
||||||
|
allow: {
|
||||||
|
loginStatus: [LOGIN_STATUS.LoggedIn],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '*',
|
path: '*',
|
||||||
name: VIEWS.NOT_FOUND,
|
name: VIEWS.NOT_FOUND,
|
||||||
|
|
124
packages/editor-ui/src/views/SettingsApiView.vue
Normal file
124
packages/editor-ui/src/views/SettingsApiView.vue
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
<template>
|
||||||
|
<SettingsView>
|
||||||
|
<div :class="$style.container">
|
||||||
|
<div :class="$style.header">
|
||||||
|
<n8n-heading size="2xlarge">
|
||||||
|
{{ $locale.baseText('settings.api') }}
|
||||||
|
</n8n-heading>
|
||||||
|
</div>
|
||||||
|
<n8n-card v-if="apiKey">
|
||||||
|
Hello
|
||||||
|
</n8n-card>
|
||||||
|
<div :class="$style.placeholder" v-else>
|
||||||
|
<n8n-heading size="xlarge">
|
||||||
|
{{ $locale.baseText('settings.api.create.title') }}
|
||||||
|
</n8n-heading>
|
||||||
|
<p class="mt-2xs mb-l">
|
||||||
|
{{$locale.baseText('settings.api.create.description')}}
|
||||||
|
<a href="https://docs.n8n.io/reference/glossary/#rest-api" target="_blank">
|
||||||
|
{{$locale.baseText('settings.api.create.description.link')}}
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
<n8n-button :loading="loading" size="large" class="mt-l" @click="createApiKey">
|
||||||
|
{{$locale.baseText(loading ? 'settings.api.create.button.loading' : 'settings.api.create.button')}}
|
||||||
|
</n8n-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</SettingsView>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import {createApiKey, deleteApiKey, getApiKey } from '../api/api-keys';
|
||||||
|
import { showMessage } from '@/components/mixins/showMessage';
|
||||||
|
import { IUser } from '@/Interface';
|
||||||
|
import mixins from 'vue-typed-mixins';
|
||||||
|
|
||||||
|
import SettingsView from './SettingsView.vue';
|
||||||
|
|
||||||
|
export default mixins(
|
||||||
|
showMessage,
|
||||||
|
).extend({
|
||||||
|
name: 'SettingsPersonalView',
|
||||||
|
components: {
|
||||||
|
SettingsView,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
apiKey: '' as string | null,
|
||||||
|
loading: false,
|
||||||
|
mounted: false,
|
||||||
|
error: '',
|
||||||
|
};
|
||||||
|
},
|
||||||
|
async mounted() {
|
||||||
|
this.getApiKey();
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
currentUser() {
|
||||||
|
return this.$store.getters['users/currentUser'] as IUser;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async getApiKey() {
|
||||||
|
try {
|
||||||
|
const { apiKey } = await getApiKey(this.$store.getters['getRestApiContext']);
|
||||||
|
this.apiKey = apiKey;
|
||||||
|
} catch (error) {
|
||||||
|
this.$showError(error, this.$locale.baseText('settings.api.error.get'));
|
||||||
|
} finally {
|
||||||
|
this.mounted = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async createApiKey() {
|
||||||
|
this.loading = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const { apiKey } = await createApiKey(this.$store.getters['getRestApiContext']);
|
||||||
|
this.apiKey = apiKey;
|
||||||
|
} catch (error) {
|
||||||
|
this.$showError(error, this.$locale.baseText('settings.api.error.create'));
|
||||||
|
} finally {
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async deleteApiKey() {
|
||||||
|
this.loading = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await deleteApiKey(this.$store.getters['getRestApiContext']);
|
||||||
|
} catch (error) {
|
||||||
|
this.$showError(error, this.$locale.baseText('settings.api.error.delete'));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" module>
|
||||||
|
.container {
|
||||||
|
> * {
|
||||||
|
margin-bottom: var(--spacing-2xl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
|
*:first-child {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.placeholder {
|
||||||
|
border-radius: var(--border-radius-xlarge);
|
||||||
|
border: 2px dashed var(--color-foreground-light);
|
||||||
|
height: 245px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
Loading…
Reference in a new issue