Add webhooks settings (#363)

This commit is contained in:
Rijk van Zanten
2020-04-08 14:38:03 -04:00
committed by GitHub
parent 6979fadb6c
commit eb7153cbfc
8 changed files with 398 additions and 24 deletions

View File

@@ -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",

View File

@@ -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',

View 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>

View File

@@ -0,0 +1,4 @@
import FilesBrowse from './browse.vue';
export { FilesBrowse };
export default FilesBrowse;

View 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>

View File

@@ -0,0 +1,4 @@
import FilesDetail from './detail.vue';
export { FilesDetail };
export default FilesDetail;

View File

@@ -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 };

View File

@@ -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>