timon_playgroud/frontend/src/components/admin/domains/MailsPermDeletion.vue

345 lines
9.1 KiB
Vue

<template style="max-width: 100vw">
<div>
<a-card class="panel-content">
<a-form
:class="page.status.Active ? 'disabled-div' : ''"
:label-col="labelCol"
:wrapper-col="wrapperCol"
>
<a-form-item
:label="t(`components.admin.domains.mails_perm_deletion.filter`)"
>
<div style="text-align: center">
<a-flex gap="middle" vertical>
<a-row>
<a-col flex="auto">
<a-radio-group v-model:value="page.status.Condition.Op">
<a-radio-button value="and">{{
t("components.common.rules.edit_conditions_all")
}}</a-radio-button>
<a-radio-button value="or">{{
t("components.common.rules.edit_conditions_any")
}}</a-radio-button>
</a-radio-group>
</a-col>
<a-col flex="100px"> </a-col>
</a-row>
<template v-if="page.renderConditions">
<div v-for="(condition, i) in page.status.Condition.Conditions">
<a-row>
<a-col flex="auto">
<Conditions
:value="condition"
:update="(newVal: string[]) => updateCondition(i, newVal)"
:conditions="conditionsListForMailDeletion"
>
<template #condition-value="valueProps">
<ConditionValue
:change="valueProps.change"
:value="valueProps.value"
:type="valueProps.type"
>
</ConditionValue>
</template>
</Conditions>
</a-col>
<a-col flex="100px">
<a-button
:disabled="i === 0"
danger
@click="deleteCondition(i)"
>
{{ t("components.common.rules.delete") }}
</a-button>
</a-col>
</a-row>
</div>
</template>
<a-row>
<a-col flex="auto">
<a-button
style="width: fit-content; margin: auto"
@click="addCondition"
>
<PlusOutlined> </PlusOutlined>
{{ t("components.common.rules.add_condition") }}
</a-button>
</a-col>
<a-col flex="100px"> </a-col>
</a-row>
</a-flex>
</div>
</a-form-item>
</a-form>
<a-divider></a-divider>
<div>
<a-space style="width: 100%" direction="vertical">
<a-alert
v-if="page.status.Error"
type="error"
showIcon
:message="page.status.Error"
/>
<a-alert
v-if="page.status.Percent === 100 && !page.status.OnlyFind"
type="success"
showIcon
:message="t(`components.admin.domains.mails_perm_deletion.success`)"
/>
<a-progress
v-if="
(page.status.Count || page.status.Percent) &&
!page.status.OnlyFind
"
:percent="page.status.Percent"
/>
<a-row>
<a-col flex="2"> </a-col>
<a-col>
<a-space>
<a-button
:type="page.status.Count === 0 ? `primary` : undefined"
:loading="page.status.OnlyFind && page.status.Active"
:disabled="page.status.Active"
@click="start(true)"
>
{{ t("components.admin.domains.mails_perm_deletion.find") }}
</a-button>
<a-button
danger
:type="`primary`"
:disabled="page.status.Active || !page.status.Count"
:loading="!page.status.OnlyFind && page.status.Active"
@click="confirmDelete"
>
{{ t("components.admin.domains.mails_perm_deletion.delete") }}
{{ page.status.Count }}
</a-button>
</a-space>
</a-col>
</a-row>
</a-space>
</div>
</a-card>
</div>
</template>
<script setup lang="ts">
import { notifyError, notifySuccess } from "@/composables/alert";
import { apiFetch } from "@/composables/apiFetch";
import { Modal } from "ant-design-vue";
import { createVNode, onMounted, onUnmounted, reactive } from "vue";
import { saveAndRestart } from "@/composables/restart";
import { message } from "ant-design-vue";
import Conditions from "@/components/common/rules/Conditions.vue";
import ConditionValue from "@/components/common/rules/incoming/Conditions.vue";
import { conditionsListForMailDeletion } from "@/components/common/rules/incoming/Conditions.vue";
import { useI18n } from "vue-i18n";
import router from "@/router";
import {
DomainPlaceholder,
RouteAdminDomainsDomainMailStorageSettings,
} from "@/router/consts";
import {
ArrowLeftOutlined,
DeleteOutlined,
DownOutlined,
ExclamationCircleOutlined,
HomeOutlined,
PlusOutlined,
UpOutlined,
} from "@ant-design/icons-vue";
import { useRoute } from "vue-router";
import type { Condition } from "@/components/common/rules/Conditions.vue";
import { nextTick } from "vue";
import { getStatusClassNames } from "ant-design-vue/es/_util/statusUtils";
const route = useRoute();
const { t } = useI18n();
const labelCol = { span: 3, style: { "text-align": "left" } };
const wrapperCol = { span: 21, style: { "text-align": "center" } };
interface ConditionStruct {
Op: string;
Conditions: string[][];
}
interface DeleteStatus {
Condition: ConditionStruct;
OnlyFind: boolean;
Active: boolean;
Count: number;
Percent: number;
Error: string;
}
const page = reactive<{
// @ts-ignore
timeout: NodeJS.Timeout | undefined;
interval: number | undefined;
domain: string;
loading: boolean;
valid: boolean;
renderConditions: boolean;
status: DeleteStatus;
}>({
interval: 1000,
timeout: undefined,
domain: "",
loading: false,
renderConditions: true,
valid: true,
status: {
Condition: {
Op: "and",
Conditions: [[...conditionsListForMailDeletion[0].Args]],
},
OnlyFind: true,
Active: false,
Count: 0,
Percent: 0,
Error: "",
},
});
onMounted(() => {
page.domain = route.params.domain as string;
get();
});
onUnmounted(() => {
page.interval = undefined;
clearTimeout(page.timeout);
});
async function get() {
clearTimeout(page.timeout);
page.loading = true;
const res = await apiFetch(
`/admin/domains/${page.domain}/mails_perm_deletion`
);
if (res.error) {
notifyError(res.error);
return;
}
page.loading = false;
page.status = res.data as DeleteStatus;
page.renderConditions = false;
validate();
nextTick(() => {
page.renderConditions = true;
});
if (page.status.Active && page.interval) {
page.timeout = setTimeout(get, page.interval);
}
return;
}
async function start(onlyFind: boolean) {
page.loading = true;
page.status.OnlyFind = onlyFind;
if (page.status.OnlyFind) {
page.status.Count = 0;
}
page.status.Active = true;
page.status.Error = "";
page.status.Percent = 0;
const res = await apiFetch(
`/admin/domains/${page.domain}/mails_perm_deletion`,
{
method: "POST",
body: page.status,
}
);
page.loading = false;
if (res.error) {
notifyError(res.error);
return;
}
return get();
}
function updateCondition(i: number, newVal: string[]) {
page.status.Condition.Conditions[i] = newVal;
validate();
}
function deleteCondition(i: number) {
page.status.Condition.Conditions.splice(i, 1);
page.renderConditions = false;
validate();
nextTick(() => {
page.renderConditions = true;
});
}
function validate() {
let ok = true;
page.status.Condition.Conditions.forEach((args) => {
let cond = conditionsListForMailDeletion.find(
(a: Condition) => a.Value === args[0]
) as Condition;
if (cond.ValIdx != -1 && args[cond.ValIdx] === "") {
ok = false;
}
});
page.valid = ok;
}
function addCondition() {
page.status.Condition.Conditions.push(conditionsListForMailDeletion[0].Args);
validate();
}
function confirmDelete() {
Modal.confirm({
title:
t("components.admin.domains.mails_perm_deletion.delete") +
page.status.Count,
icon: createVNode(ExclamationCircleOutlined),
content: t("components.admin.domains.mails_perm_deletion.delete_text"),
okText: t("components.admin.domains.mails_perm_deletion.ok"),
okType: "danger",
cancelText: t("components.admin.domains.mails_perm_deletion.cancel"),
async onOk() {
start(false);
},
});
}
</script>
<style scoped>
.panel-content {
min-width: 800px;
max-width: 60%;
margin: auto;
}
.save-button {
width: 30%;
min-width: 150px;
display: block;
margin: auto;
}
</style>