mirror of
https://codeberg.org/yeentown/barkey
synced 2024-12-05 03:17:26 +00:00
4ac8aad50a
* feat: UserWebhook/SystemWebhookのテスト送信機能を追加 * fix CHANGELOG.md * 一部設定をパラメータから上書き出来るように修正 * remove async * regenerate autogen
294 lines
7.9 KiB
Vue
294 lines
7.9 KiB
Vue
<!--
|
|
SPDX-FileCopyrightText: syuilo and misskey-project
|
|
SPDX-License-Identifier: AGPL-3.0-only
|
|
-->
|
|
|
|
<template>
|
|
<MkModalWindow
|
|
ref="dialogEl"
|
|
:width="450"
|
|
:height="590"
|
|
:canClose="true"
|
|
:withOkButton="false"
|
|
:okButtonDisabled="false"
|
|
@click="onCancelClicked"
|
|
@close="onCancelClicked"
|
|
@closed="emit('closed')"
|
|
>
|
|
<template #header>
|
|
{{ mode === 'create' ? i18n.ts._webhookSettings.createWebhook : i18n.ts._webhookSettings.modifyWebhook }}
|
|
</template>
|
|
|
|
<div style="display: flex; flex-direction: column; min-height: 100%;">
|
|
<MkSpacer :marginMin="20" :marginMax="28" style="flex-grow: 1;">
|
|
<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.trigger }}</template>
|
|
|
|
<div class="_gaps">
|
|
<div class="_gaps_s">
|
|
<div :class="$style.switchBox">
|
|
<MkSwitch v-model="events.abuseReport" :disabled="disabledEvents.abuseReport">
|
|
<template #label>{{ i18n.ts._webhookSettings._systemEvents.abuseReport }}</template>
|
|
</MkSwitch>
|
|
<MkButton v-show="mode === 'edit'" transparent :class="$style.testButton" :disabled="!(isActive && events.abuseReport)" @click="test('abuseReport')"><i class="ti ti-send"></i></MkButton>
|
|
</div>
|
|
<div :class="$style.switchBox">
|
|
<MkSwitch v-model="events.abuseReportResolved" :disabled="disabledEvents.abuseReportResolved">
|
|
<template #label>{{ i18n.ts._webhookSettings._systemEvents.abuseReportResolved }}</template>
|
|
</MkSwitch>
|
|
<MkButton v-show="mode === 'edit'" transparent :class="$style.testButton" :disabled="!(isActive && events.abuseReportResolved)" @click="test('abuseReportResolved')"><i class="ti ti-send"></i></MkButton>
|
|
</div>
|
|
<div :class="$style.switchBox">
|
|
<MkSwitch v-model="events.userCreated" :disabled="disabledEvents.userCreated">
|
|
<template #label>{{ i18n.ts._webhookSettings._systemEvents.userCreated }}</template>
|
|
</MkSwitch>
|
|
<MkButton v-show="mode === 'edit'" transparent :class="$style.testButton" :disabled="!(isActive && events.userCreated)" @click="test('userCreated')"><i class="ti ti-send"></i></MkButton>
|
|
</div>
|
|
</div>
|
|
|
|
<div v-show="mode === 'edit'" :class="$style.description">
|
|
{{ i18n.ts._webhookSettings.testRemarks }}
|
|
</div>
|
|
</div>
|
|
</MkFolder>
|
|
|
|
<MkSwitch v-model="isActive">
|
|
<template #label>{{ i18n.ts.enable }}</template>
|
|
</MkSwitch>
|
|
</div>
|
|
</MkSpacer>
|
|
<div :class="$style.footer" class="_buttonsCenter">
|
|
<MkButton primary rounded :disabled="disableSubmitButton" @click="onSubmitClicked">
|
|
<i class="ti ti-check"></i>
|
|
{{ i18n.ts.ok }}
|
|
</MkButton>
|
|
<MkButton rounded @click="onCancelClicked"><i class="ti ti-x"></i> {{ i18n.ts.cancel }}</MkButton>
|
|
</div>
|
|
</div>
|
|
</MkModalWindow>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { computed, onMounted, ref, shallowRef, toRefs } from 'vue';
|
|
import * as Misskey from 'misskey-js';
|
|
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;
|
|
userCreated: boolean;
|
|
}
|
|
|
|
const emit = defineEmits<{
|
|
(ev: 'submitted', result: MkSystemWebhookResult): void;
|
|
(ev: 'canceled'): void;
|
|
(ev: 'closed'): void;
|
|
}>();
|
|
|
|
const dialogEl = shallowRef<InstanceType<typeof MkModalWindow>>();
|
|
|
|
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,
|
|
userCreated: true,
|
|
});
|
|
const isActive = ref<boolean>(true);
|
|
|
|
const disabledEvents = ref<EventType>({
|
|
abuseReport: false,
|
|
abuseReportResolved: false,
|
|
userCreated: 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);
|
|
dialogEl.value?.close();
|
|
emit('submitted', result);
|
|
break;
|
|
}
|
|
case 'edit': {
|
|
// eslint-disable-next-line
|
|
const result = await misskeyApi('admin/system-webhook/update', { id: id.value!, ...params });
|
|
dialogEl.value?.close();
|
|
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 });
|
|
dialogEl.value?.close();
|
|
emit('canceled');
|
|
}
|
|
});
|
|
}
|
|
|
|
function onCancelClicked() {
|
|
dialogEl.value?.close();
|
|
emit('canceled');
|
|
}
|
|
|
|
async function loadingScope<T>(fn: () => Promise<T>): Promise<T> {
|
|
loading.value++;
|
|
try {
|
|
return await fn();
|
|
} finally {
|
|
loading.value--;
|
|
}
|
|
}
|
|
|
|
async function test(type: Misskey.entities.SystemWebhook['on'][number]): Promise<void> {
|
|
if (!id.value) {
|
|
return Promise.resolve();
|
|
}
|
|
|
|
await os.apiWithDialog('admin/system-webhook/test', {
|
|
webhookId: id.value,
|
|
type,
|
|
override: {
|
|
secret: secret.value,
|
|
url: url.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 @typescript-eslint/no-explicit-any
|
|
} catch (ex: any) {
|
|
const msg = ex.message ?? i18n.ts.internalServerErrorDescription;
|
|
await os.alert({ type: 'error', title: i18n.ts.error, text: msg });
|
|
dialogEl.value?.close();
|
|
emit('canceled');
|
|
}
|
|
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 {
|
|
position: sticky;
|
|
z-index: 10000;
|
|
bottom: 0;
|
|
left: 0;
|
|
padding: 12px;
|
|
border-top: solid 0.5px var(--divider);
|
|
background: var(--acrylicBg);
|
|
-webkit-backdrop-filter: var(--blur, blur(15px));
|
|
backdrop-filter: var(--blur, blur(15px));
|
|
}
|
|
|
|
.switchBox {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: start;
|
|
|
|
.testButton {
|
|
$buttonSize: 28px;
|
|
padding: 0;
|
|
width: $buttonSize;
|
|
min-width: $buttonSize;
|
|
max-width: $buttonSize;
|
|
height: $buttonSize;
|
|
margin-left: auto;
|
|
line-height: normal;
|
|
font-size: 90%;
|
|
border-radius: 9999px;
|
|
}
|
|
}
|
|
|
|
.description {
|
|
font-size: 0.85em;
|
|
padding: 8px 0 0 0;
|
|
color: var(--fgTransparentWeak);
|
|
}
|
|
</style>
|