diff options
| author | おさむのひと <46447427+samunohito@users.noreply.github.com> | 2024-06-08 15:34:19 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-06-08 15:34:19 +0900 |
| commit | 61fae45390283aee7ac582aa5303aae863de0f7a (patch) | |
| tree | 17182172ef9f932182fc55f2aabd7243d2be66b2 /packages/frontend/src/components/MkSystemWebhookEditor.vue | |
| parent | 配信停止したインスタンス一覧が見れなくなる問題を修... (diff) | |
| download | sharkey-61fae45390283aee7ac582aa5303aae863de0f7a.tar.gz sharkey-61fae45390283aee7ac582aa5303aae863de0f7a.tar.bz2 sharkey-61fae45390283aee7ac582aa5303aae863de0f7a.zip | |
feat: 通報を受けた際にメールまたはWebhookで通知を送出出来るようにする (#13758)
* feat: 通報を受けた際にメールまたはWebhookで通知を送出出来るようにする
* モデログに対応&エンドポイントを単一オブジェクトでのサポートに変更(API経由で大量に作るシチュエーションもないと思うので)
* fix spdx
* fix migration
* fix migration
* fix models
* add e2e webhook
* tweak
* fix modlog
* fix bugs
* add tests and fix bugs
* add tests and fix bugs
* add tests
* fix path
* regenerate locale
* 混入除去
* 混入除去
* add abuseReportResolved
* fix pnpm-lock.yaml
* add abuseReportResolved test
* fix bugs
* fix ui
* add tests
* fix CHANGELOG.md
* add tests
* add RoleService.getModeratorIds tests
* WebhookServiceをUserとSystemに分割
* fix CHANGELOG.md
* fix test
* insertOneを使う用に
* fix
* regenerate locales
* revert version
* separate webhook job queue
* fix
* :art:
* Update QueueProcessorService.ts
---------
Co-authored-by: osamu <46447427+sam-osamu@users.noreply.github.com>
Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com>
Diffstat (limited to 'packages/frontend/src/components/MkSystemWebhookEditor.vue')
| -rw-r--r-- | packages/frontend/src/components/MkSystemWebhookEditor.vue | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/packages/frontend/src/components/MkSystemWebhookEditor.vue b/packages/frontend/src/components/MkSystemWebhookEditor.vue new file mode 100644 index 0000000000..007d841f00 --- /dev/null +++ b/packages/frontend/src/components/MkSystemWebhookEditor.vue @@ -0,0 +1,217 @@ +<!-- +SPDX-FileCopyrightText: syuilo and misskey-project +SPDX-License-Identifier: AGPL-3.0-only +--> + +<template> +<MkModalWindow + :width="450" + :height="590" + :canClose="true" + :withOkButton="false" + :okButtonDisabled="false" + @click="onCancelClicked" + @close="onCancelClicked" + @closed="onCancelClicked" +> + <template #header> + {{ mode === 'create' ? i18n.ts._webhookSettings.createWebhook : i18n.ts._webhookSettings.modifyWebhook }} + </template> + <MkSpacer :marginMin="20" :marginMax="28"> + <MkLoading v-if="loading !== 0"/> + <div v-else :class="$style.root" class="_gaps_m"> + <MkInput v-model="title"> + <template #label>{{ i18n.ts._webhookSettings.name }}</template> + </MkInput> + <MkInput v-model="url"> + <template #label>URL</template> + </MkInput> + <MkInput v-model="secret"> + <template #label>{{ i18n.ts._webhookSettings.secret }}</template> + </MkInput> + <MkFolder :defaultOpen="true"> + <template #label>{{ i18n.ts._webhookSettings.events }}</template> + + <div class="_gaps_s"> + <MkSwitch v-model="events.abuseReport" :disabled="disabledEvents.abuseReport"> + <template #label>{{ i18n.ts._webhookSettings._systemEvents.abuseReport }}</template> + </MkSwitch> + <MkSwitch v-model="events.abuseReportResolved" :disabled="disabledEvents.abuseReportResolved"> + <template #label>{{ i18n.ts._webhookSettings._systemEvents.abuseReportResolved }}</template> + </MkSwitch> + </div> + </MkFolder> + + <MkSwitch v-model="isActive"> + <template #label>{{ i18n.ts.enable }}</template> + </MkSwitch> + + <div :class="$style.footer" class="_buttonsCenter"> + <MkButton primary :disabled="disableSubmitButton" @click="onSubmitClicked"> + <i class="ti ti-check"></i> + {{ i18n.ts.ok }} + </MkButton> + <MkButton @click="onCancelClicked"><i class="ti ti-x"></i> {{ i18n.ts.cancel }}</MkButton> + </div> + </div> + </MkSpacer> +</MkModalWindow> +</template> + +<script setup lang="ts"> +import { computed, onMounted, ref, toRefs } from 'vue'; +import FormSection from '@/components/form/section.vue'; +import MkInput from '@/components/MkInput.vue'; +import MkSwitch from '@/components/MkSwitch.vue'; +import { + MkSystemWebhookEditorProps, + MkSystemWebhookResult, + SystemWebhookEventType, +} from '@/components/MkSystemWebhookEditor.impl.js'; +import { i18n } from '@/i18n.js'; +import MkButton from '@/components/MkButton.vue'; +import { misskeyApi } from '@/scripts/misskey-api.js'; +import MkModalWindow from '@/components/MkModalWindow.vue'; +import MkFolder from '@/components/MkFolder.vue'; +import * as os from '@/os.js'; + +type EventType = { + abuseReport: boolean; + abuseReportResolved: boolean; +} + +const emit = defineEmits<{ + (ev: 'submitted', result: MkSystemWebhookResult): void; + (ev: 'closed'): void; +}>(); + +const props = defineProps<MkSystemWebhookEditorProps>(); + +const { mode, id, requiredEvents } = toRefs(props); + +const loading = ref<number>(0); + +const title = ref<string>(''); +const url = ref<string>(''); +const secret = ref<string>(''); +const events = ref<EventType>({ + abuseReport: true, + abuseReportResolved: true, +}); +const isActive = ref<boolean>(true); + +const disabledEvents = ref<EventType>({ + abuseReport: false, + abuseReportResolved: false, +}); + +const disableSubmitButton = computed(() => { + if (!title.value) { + return true; + } + if (!url.value) { + return true; + } + if (!secret.value) { + return true; + } + + return false; +}); + +async function onSubmitClicked() { + await loadingScope(async () => { + const params = { + isActive: isActive.value, + name: title.value, + url: url.value, + secret: secret.value, + on: Object.keys(events.value).filter(ev => events.value[ev as keyof EventType]) as SystemWebhookEventType[], + }; + + try { + switch (mode.value) { + case 'create': { + const result = await misskeyApi('admin/system-webhook/create', params); + emit('submitted', result); + break; + } + case 'edit': { + // eslint-disable-next-line + const result = await misskeyApi('admin/system-webhook/update', { id: id.value!, ...params }); + emit('submitted', result); + break; + } + } + // eslint-disable-next-line + } catch (ex: any) { + const msg = ex.message ?? i18n.ts.internalServerErrorDescription; + await os.alert({ type: 'error', title: i18n.ts.error, text: msg }); + emit('closed'); + } + }); +} + +function onCancelClicked() { + emit('closed'); +} + +async function loadingScope<T>(fn: () => Promise<T>): Promise<T> { + loading.value++; + try { + return await fn(); + } finally { + loading.value--; + } +} + +onMounted(async () => { + await loadingScope(async () => { + switch (mode.value) { + case 'edit': { + if (!id.value) { + throw new Error('id is required'); + } + + try { + const res = await misskeyApi('admin/system-webhook/show', { id: id.value }); + + title.value = res.name; + url.value = res.url; + secret.value = res.secret; + isActive.value = res.isActive; + for (const ev of Object.keys(events.value)) { + events.value[ev] = res.on.includes(ev as SystemWebhookEventType); + } + // eslint-disable-next-line + } catch (ex: any) { + const msg = ex.message ?? i18n.ts.internalServerErrorDescription; + await os.alert({ type: 'error', title: i18n.ts.error, text: msg }); + emit('closed'); + } + break; + } + } + + for (const ev of requiredEvents.value ?? []) { + disabledEvents.value[ev] = true; + } + }); +}); +</script> + +<style module lang="scss"> +.root { + display: flex; + flex-direction: column; + justify-content: center; + align-items: stretch; +} + +.footer { + display: flex; + justify-content: center; + align-items: flex-end; + margin-top: 20px; +} +</style> |