mirror of
https://github.com/directus/directus.git
synced 2026-01-27 17:38:00 -05:00
Add webhooks settings (#363)
This commit is contained in:
@@ -120,11 +120,11 @@
|
||||
|
||||
"users": "Users",
|
||||
"files": "Files",
|
||||
"Activity": "Activity",
|
||||
"activity": "Activity",
|
||||
"webhooks": "Webhooks",
|
||||
|
||||
|
||||
"about_directus": "About Directus",
|
||||
"activity": "Activity",
|
||||
"activity_log": "Activity Log",
|
||||
"add_field_filter": "Add a field filter",
|
||||
"add_new": "Add New",
|
||||
|
||||
@@ -2,7 +2,7 @@ import { defineModule } from '@/modules/define';
|
||||
import SettingsGlobal from './routes/global';
|
||||
import { SettingsCollections, SettingsFields } from './routes/data-model/';
|
||||
import SettingsRoles from './routes/roles';
|
||||
import SettingsWebhooks from './routes/webhooks';
|
||||
import { SettingsWebhooksBrowse, SettingsWebhooksDetail } from './routes/webhooks';
|
||||
import SettingsNotFound from './routes/not-found';
|
||||
|
||||
export default defineModule(({ i18n }) => ({
|
||||
@@ -36,9 +36,15 @@ export default defineModule(({ i18n }) => ({
|
||||
component: SettingsRoles,
|
||||
},
|
||||
{
|
||||
name: 'settings-webhooks',
|
||||
name: 'settings-webhooks-browse',
|
||||
path: '/webhooks',
|
||||
component: SettingsWebhooks,
|
||||
component: SettingsWebhooksBrowse,
|
||||
},
|
||||
{
|
||||
name: 'settings-webhooks-detail',
|
||||
path: '/webhooks/:primaryKey',
|
||||
component: SettingsWebhooksDetail,
|
||||
props: true,
|
||||
},
|
||||
{
|
||||
name: 'settings-not-found',
|
||||
|
||||
178
src/modules/settings/routes/webhooks/browse/browse.vue
Normal file
178
src/modules/settings/routes/webhooks/browse/browse.vue
Normal file
@@ -0,0 +1,178 @@
|
||||
<template>
|
||||
<private-view :title="$t('webhooks')">
|
||||
<template #title-outer:prepend>
|
||||
<v-button rounded disabled icon secondary>
|
||||
<v-icon name="send" />
|
||||
</v-button>
|
||||
</template>
|
||||
|
||||
<template #drawer><portal-target name="drawer" /></template>
|
||||
|
||||
<template #actions>
|
||||
<v-dialog v-model="confirmDelete">
|
||||
<template #activator="{ on }">
|
||||
<v-button
|
||||
rounded
|
||||
icon
|
||||
class="action-delete"
|
||||
v-if="selection.length > 0"
|
||||
@click="on"
|
||||
>
|
||||
<v-icon name="delete" />
|
||||
</v-button>
|
||||
</template>
|
||||
|
||||
<v-card>
|
||||
<v-card-title>{{ $tc('batch_delete_confirm', selection.length) }}</v-card-title>
|
||||
|
||||
<v-card-actions>
|
||||
<v-button @click="confirmDelete = false" secondary>
|
||||
{{ $t('cancel') }}
|
||||
</v-button>
|
||||
<v-button @click="batchDelete" class="action-delete" :loading="deleting">
|
||||
{{ $t('delete') }}
|
||||
</v-button>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
|
||||
<v-button rounded icon class="action-batch" v-if="selection.length > 1" :to="batchLink">
|
||||
<v-icon name="edit" />
|
||||
</v-button>
|
||||
|
||||
<v-button rounded icon :to="addNewLink">
|
||||
<v-icon name="add" />
|
||||
</v-button>
|
||||
</template>
|
||||
|
||||
<template #navigation>
|
||||
<settings-navigation />
|
||||
</template>
|
||||
|
||||
<layout-tabular
|
||||
class="layout"
|
||||
ref="layout"
|
||||
collection="directus_webhooks"
|
||||
:selection.sync="selection"
|
||||
:view-options.sync="viewOptions"
|
||||
:view-query.sync="viewQuery"
|
||||
:detail-route="'/{{project}}/settings/settings/webhooks/{{primaryKey}}'"
|
||||
/>
|
||||
</private-view>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, computed, ref } from '@vue/composition-api';
|
||||
import SettingsNavigation from '../../../components/navigation/';
|
||||
import useProjectsStore from '@/stores/projects';
|
||||
import { i18n } from '@/lang';
|
||||
import api from '@/api';
|
||||
import { LayoutComponent } from '@/layouts/types';
|
||||
import useCollectionPreset from '@/compositions/use-collection-preset';
|
||||
|
||||
type Item = {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
[field: string]: any;
|
||||
};
|
||||
|
||||
export default defineComponent({
|
||||
name: 'webhooks-browse',
|
||||
components: { SettingsNavigation },
|
||||
props: {},
|
||||
setup() {
|
||||
const layout = ref<LayoutComponent>(null);
|
||||
const projectsStore = useProjectsStore();
|
||||
|
||||
const selection = ref<Item[]>([]);
|
||||
|
||||
const { viewOptions, viewQuery } = useCollectionPreset(ref('directus_webhooks'));
|
||||
const { addNewLink, batchLink } = useLinks();
|
||||
const { confirmDelete, deleting, batchDelete } = useBatchDelete();
|
||||
const { breadcrumb } = useBreadcrumb();
|
||||
|
||||
return {
|
||||
addNewLink,
|
||||
batchLink,
|
||||
selection,
|
||||
breadcrumb,
|
||||
confirmDelete,
|
||||
batchDelete,
|
||||
deleting,
|
||||
layout,
|
||||
viewOptions,
|
||||
viewQuery,
|
||||
};
|
||||
|
||||
function useBatchDelete() {
|
||||
const confirmDelete = ref(false);
|
||||
const deleting = ref(false);
|
||||
|
||||
return { confirmDelete, deleting, batchDelete };
|
||||
|
||||
async function batchDelete() {
|
||||
const currentProjectKey = projectsStore.state.currentProjectKey;
|
||||
|
||||
deleting.value = true;
|
||||
|
||||
confirmDelete.value = false;
|
||||
|
||||
const batchPrimaryKeys = selection.value.map((item) => item.id).join();
|
||||
|
||||
await api.delete(`/${currentProjectKey}/settings/webhooks/${batchPrimaryKeys}`);
|
||||
|
||||
await layout.value?.refresh();
|
||||
|
||||
selection.value = [];
|
||||
deleting.value = false;
|
||||
confirmDelete.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function useLinks() {
|
||||
const addNewLink = computed<string>(() => {
|
||||
const currentProjectKey = projectsStore.state.currentProjectKey;
|
||||
return `/${currentProjectKey}/settings/webhooks/+`;
|
||||
});
|
||||
|
||||
const batchLink = computed<string>(() => {
|
||||
const currentProjectKey = projectsStore.state.currentProjectKey;
|
||||
const batchPrimaryKeys = selection.value.map((item) => item.id).join();
|
||||
return `/${currentProjectKey}/settings/webhooks/${batchPrimaryKeys}`;
|
||||
});
|
||||
|
||||
return { addNewLink, batchLink };
|
||||
}
|
||||
|
||||
function useBreadcrumb() {
|
||||
const breadcrumb = computed(() => {
|
||||
const currentProjectKey = projectsStore.state.currentProjectKey;
|
||||
|
||||
return [
|
||||
{
|
||||
name: i18n.tc('collection', 2),
|
||||
to: `/${currentProjectKey}/collections`,
|
||||
},
|
||||
];
|
||||
});
|
||||
|
||||
return { breadcrumb };
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.action-delete {
|
||||
--v-button-background-color: var(--danger);
|
||||
--v-button-background-color-hover: var(--danger-dark);
|
||||
}
|
||||
|
||||
.action-batch {
|
||||
--v-button-background-color: var(--warning);
|
||||
--v-button-background-color-hover: var(--warning-150);
|
||||
}
|
||||
|
||||
.layout {
|
||||
--layout-offset-top: 64px;
|
||||
}
|
||||
</style>
|
||||
4
src/modules/settings/routes/webhooks/browse/index.ts
Normal file
4
src/modules/settings/routes/webhooks/browse/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import FilesBrowse from './browse.vue';
|
||||
|
||||
export { FilesBrowse };
|
||||
export default FilesBrowse;
|
||||
197
src/modules/settings/routes/webhooks/detail/detail.vue
Normal file
197
src/modules/settings/routes/webhooks/detail/detail.vue
Normal file
@@ -0,0 +1,197 @@
|
||||
<template>
|
||||
<private-view :title="$t('editing', { collection: $t('webhooks') })">
|
||||
<template #title-outer:prepend>
|
||||
<v-button rounded icon secondary exact :to="breadcrumb[0].to">
|
||||
<v-icon name="arrow_back" />
|
||||
</v-button>
|
||||
</template>
|
||||
|
||||
<template #headline>
|
||||
<v-breadcrumb :items="breadcrumb" />
|
||||
</template>
|
||||
|
||||
<template #actions>
|
||||
<v-dialog v-model="confirmDelete">
|
||||
<template #activator="{ on }">
|
||||
<v-button
|
||||
rounded
|
||||
icon
|
||||
class="action-delete"
|
||||
:disabled="item === null"
|
||||
@click="on"
|
||||
>
|
||||
<v-icon name="delete" />
|
||||
</v-button>
|
||||
</template>
|
||||
|
||||
<v-card>
|
||||
<v-card-title>{{ $t('delete_are_you_sure') }}</v-card-title>
|
||||
|
||||
<v-card-actions>
|
||||
<v-button @click="confirmDelete = false" secondary>
|
||||
{{ $t('cancel') }}
|
||||
</v-button>
|
||||
<v-button @click="deleteAndQuit" class="action-delete" :loading="deleting">
|
||||
{{ $t('delete') }}
|
||||
</v-button>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
|
||||
<v-button
|
||||
rounded
|
||||
icon
|
||||
:loading="saving"
|
||||
:disabled="hasEdits === false"
|
||||
@click="saveAndQuit"
|
||||
>
|
||||
<v-icon name="check" />
|
||||
|
||||
<template #append-outer>
|
||||
<save-options
|
||||
:disabled="hasEdits === false"
|
||||
@save-and-stay="saveAndStay"
|
||||
@save-and-add-new="saveAndAddNew"
|
||||
@save-as-copy="saveAsCopyAndNavigate"
|
||||
/>
|
||||
</template>
|
||||
</v-button>
|
||||
</template>
|
||||
|
||||
<template #navigation>
|
||||
<settings-navigation />
|
||||
</template>
|
||||
|
||||
<v-form
|
||||
:loading="loading"
|
||||
:initial-values="item"
|
||||
collection="directus_webhooks"
|
||||
:batch-mode="isBatch"
|
||||
v-model="edits"
|
||||
/>
|
||||
|
||||
<template #drawer>
|
||||
<activity-drawer-detail
|
||||
v-if="isNew === false"
|
||||
collection="directus_webhooks"
|
||||
:primary-key="primaryKey"
|
||||
/>
|
||||
</template>
|
||||
</private-view>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, computed, toRefs, ref } from '@vue/composition-api';
|
||||
import useProjectsStore from '@/stores/projects';
|
||||
import SettingsNavigation from '../../../components/navigation/';
|
||||
import { i18n } from '@/lang';
|
||||
import router from '@/router';
|
||||
import ActivityDrawerDetail from '@/views/private/components/activity-drawer-detail';
|
||||
import useItem from '@/compositions/use-item';
|
||||
import SaveOptions from '@/views/private/components/save-options';
|
||||
|
||||
type Values = {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
[field: string]: any;
|
||||
};
|
||||
|
||||
export default defineComponent({
|
||||
name: 'webhooks-detail',
|
||||
components: { SettingsNavigation, ActivityDrawerDetail, SaveOptions },
|
||||
props: {
|
||||
primaryKey: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const projectsStore = useProjectsStore();
|
||||
const { currentProjectKey } = toRefs(projectsStore.state);
|
||||
const { primaryKey } = toRefs(props);
|
||||
const { breadcrumb } = useBreadcrumb();
|
||||
|
||||
const {
|
||||
isNew,
|
||||
edits,
|
||||
item,
|
||||
saving,
|
||||
loading,
|
||||
error,
|
||||
save,
|
||||
remove,
|
||||
deleting,
|
||||
saveAsCopy,
|
||||
isBatch,
|
||||
} = useItem(ref('directus_webhooks'), primaryKey);
|
||||
|
||||
const hasEdits = computed<boolean>(() => Object.keys(edits.value).length > 0);
|
||||
|
||||
const confirmDelete = ref(false);
|
||||
|
||||
return {
|
||||
item,
|
||||
loading,
|
||||
error,
|
||||
isNew,
|
||||
breadcrumb,
|
||||
edits,
|
||||
hasEdits,
|
||||
saving,
|
||||
saveAndQuit,
|
||||
deleteAndQuit,
|
||||
confirmDelete,
|
||||
deleting,
|
||||
saveAndStay,
|
||||
saveAndAddNew,
|
||||
saveAsCopyAndNavigate,
|
||||
isBatch,
|
||||
};
|
||||
|
||||
function useBreadcrumb() {
|
||||
const breadcrumb = computed(() => [
|
||||
{
|
||||
name: i18n.t('webhooks'),
|
||||
to: `/${currentProjectKey.value}/settings/webhooks/`,
|
||||
},
|
||||
]);
|
||||
|
||||
return { breadcrumb };
|
||||
}
|
||||
|
||||
async function saveAndQuit() {
|
||||
await save();
|
||||
router.push(`/${currentProjectKey.value}/webhooks`);
|
||||
}
|
||||
|
||||
async function saveAndStay() {
|
||||
await save();
|
||||
}
|
||||
|
||||
async function saveAndAddNew() {
|
||||
await save();
|
||||
router.push(`/${currentProjectKey.value}/settings/webhooks/+`);
|
||||
}
|
||||
|
||||
async function saveAsCopyAndNavigate() {
|
||||
const newPrimaryKey = await saveAsCopy();
|
||||
router.push(`/${currentProjectKey.value}/settings/webhooks/${newPrimaryKey}`);
|
||||
}
|
||||
|
||||
async function deleteAndQuit() {
|
||||
await remove();
|
||||
router.push(`/${currentProjectKey.value}/settings/webhooks`);
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.action-delete {
|
||||
--v-button-background-color: var(--danger);
|
||||
--v-button-background-color-hover: var(--danger-dark);
|
||||
}
|
||||
|
||||
.v-form {
|
||||
padding: var(--content-padding);
|
||||
}
|
||||
</style>
|
||||
4
src/modules/settings/routes/webhooks/detail/index.ts
Normal file
4
src/modules/settings/routes/webhooks/detail/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import FilesDetail from './detail.vue';
|
||||
|
||||
export { FilesDetail };
|
||||
export default FilesDetail;
|
||||
@@ -1,4 +1,5 @@
|
||||
import SettingsWebhooks from './webhooks.vue';
|
||||
import SettingsWebhooksBrowse from './browse';
|
||||
import SettingsWebhooksDetail from './detail';
|
||||
|
||||
export { SettingsWebhooks };
|
||||
export default SettingsWebhooks;
|
||||
export { SettingsWebhooksBrowse, SettingsWebhooksDetail };
|
||||
export default { SettingsWebhooksBrowse, SettingsWebhooksDetail };
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
<template>
|
||||
<private-view :title="$t('settings_webhooks')">
|
||||
<template #navigation>
|
||||
<settings-navigation />
|
||||
</template>
|
||||
</private-view>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from '@vue/composition-api';
|
||||
import SettingsNavigation from '../../components/navigation/';
|
||||
|
||||
export default defineComponent({
|
||||
components: { SettingsNavigation },
|
||||
});
|
||||
</script>
|
||||
Reference in New Issue
Block a user