Files
ctms/frontend/src/views/admin/ProjectForm.vue
T
2026-01-12 11:14:04 +08:00

133 lines
4.6 KiB
Vue

<template>
<el-dialog :title="project ? TEXT.modules.adminProjects.editTitle : TEXT.modules.adminProjects.newTitle" width="560px" v-model="visibleProxy" :close-on-click-modal="false">
<el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
<el-form-item :label="TEXT.common.fields.projectCode" prop="code">
<el-input v-model="form.code" :disabled="!!project" :placeholder="TEXT.common.placeholders.input + TEXT.common.fields.projectCode" />
</el-form-item>
<el-form-item :label="TEXT.common.fields.projectName" prop="name">
<el-input v-model="form.name" :placeholder="TEXT.common.placeholders.input + TEXT.common.fields.projectName" />
</el-form-item>
<el-form-item :label="TEXT.common.fields.sponsor" prop="sponsor">
<el-input v-model="form.sponsor" :placeholder="TEXT.modules.adminProjects.sponsorPlaceholder" />
</el-form-item>
<el-form-item :label="TEXT.common.fields.protocolNo" prop="protocol_no">
<el-input v-model="form.protocol_no" :placeholder="TEXT.modules.adminProjects.protocolPlaceholder" />
</el-form-item>
<el-form-item :label="TEXT.common.fields.phase" prop="phase">
<el-input v-model="form.phase" :placeholder="TEXT.modules.adminProjects.phasePlaceholder" />
</el-form-item>
<el-form-item :label="TEXT.common.fields.status" prop="status">
<el-select v-model="form.status" :placeholder="TEXT.common.placeholders.select">
<el-option :label="TEXT.enums.projectStatus.DRAFT" value="DRAFT" />
<el-option :label="TEXT.enums.projectStatus.ACTIVE" value="ACTIVE" />
<el-option :label="TEXT.enums.projectStatus.CLOSED" value="CLOSED" />
</el-select>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="visibleProxy = false">{{ TEXT.common.actions.cancel }}</el-button>
<el-button type="primary" :loading="submitting" @click="onSubmit">{{ TEXT.common.actions.save }}</el-button>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import { computed, reactive, ref, watch } from "vue";
import { ElMessage, type FormInstance, type FormRules } from "element-plus";
import { createStudy, updateStudy } from "../../api/studies";
import type { Study } from "../../types/api";
import { TEXT, requiredMessage } from "../../locales";
const props = defineProps<{
visible: boolean;
project?: Study | null;
}>();
const emit = defineEmits<{
(e: "update:visible", value: boolean): void;
(e: "saved"): void;
}>();
const visibleProxy = computed({
get: () => props.visible,
set: (val: boolean) => emit("update:visible", val),
});
const formRef = ref<FormInstance>();
const submitting = ref(false);
const form = reactive({
code: "",
name: "",
sponsor: "",
protocol_no: "",
phase: "",
status: "DRAFT",
});
const rules = reactive<FormRules>({
code: [{ required: true, message: requiredMessage(TEXT.common.fields.projectCode), trigger: "blur" }],
name: [{ required: true, message: requiredMessage(TEXT.common.fields.projectName), trigger: "blur" }],
status: [{ required: true, message: requiredMessage(TEXT.common.fields.status), trigger: "change" }],
});
const resetForm = () => {
form.code = "";
form.name = "";
form.sponsor = "";
form.protocol_no = "";
form.phase = "";
form.status = "DRAFT";
};
watch(
() => props.visible,
(val) => {
if (val) {
resetForm();
if (props.project) {
form.code = props.project.code;
form.name = props.project.name;
form.sponsor = props.project.sponsor || "";
form.protocol_no = props.project.protocol_no || "";
form.phase = props.project.phase || "";
form.status = props.project.status || "DRAFT";
}
}
}
);
const onSubmit = async () => {
if (!formRef.value) return;
await formRef.value.validate();
submitting.value = true;
try {
if (props.project) {
await updateStudy(props.project.id, {
name: form.name,
sponsor: form.sponsor,
protocol_no: form.protocol_no,
phase: form.phase,
status: form.status,
});
ElMessage.success(TEXT.modules.adminProjects.updateSuccess);
} else {
await createStudy({
code: form.code,
name: form.name,
sponsor: form.sponsor,
protocol_no: form.protocol_no,
phase: form.phase,
status: form.status,
});
ElMessage.success(TEXT.modules.adminProjects.createSuccess);
}
emit("saved");
visibleProxy.value = false;
} catch (e: any) {
ElMessage.error(e?.response?.data?.message || TEXT.common.messages.saveFailed);
} finally {
submitting.value = false;
}
};
</script>