<script lang="ts" setup>
|
import { computed, inject, nextTick, reactive, ref, toRefs, unref } from 'vue';
|
|
import { useMessage } from '@jnpf/hooks';
|
import { BasicDrawer, useDrawer } from '@jnpf/ui/drawer';
|
import { BasicModal, useModal } from '@jnpf/ui/modal';
|
import { BasicPopup, usePopup } from '@jnpf/ui/popup';
|
import { createAsyncComponent, getDateTimeUnit, getScriptFunc } from '@jnpf/utils';
|
|
import { useAccessStore, useUserStore } from '@vben/stores';
|
|
import { Result } from 'ant-design-vue';
|
import dayjs from 'dayjs';
|
import { cloneDeep } from 'lodash-es';
|
|
import { createAuditCorrelationId } from '#/api/onlineDev/auditHeaders';
|
import { createModel, getModelInfo, updateModel } from '#/api/onlineDev/visualDev';
|
import FormExtraPanel from '#/components/FormExtraPanel/index.vue';
|
import { createAuditRequestOnlineUtils } from '#/components/FormGenerator/src/helper/auditDisplay';
|
import { buildDisplayOnlySubmitData } from '#/components/FormGenerator/src/helper/displayOnly';
|
import { $t } from '#/locales';
|
import { useGeneratorStore } from '#/store';
|
|
interface State {
|
formConf: any;
|
defaultFormConf: any;
|
formData: any;
|
config: any;
|
loading: boolean;
|
loadError: boolean;
|
loadErrorText: string;
|
prevBtnLoading: boolean;
|
nextBtnLoading: boolean;
|
key: number;
|
dataForm: any;
|
formOperates: any[];
|
title: string;
|
continueText: string;
|
allList: any[];
|
currIndex: number;
|
isContinue: boolean;
|
submitType: number;
|
showContinueBtn: boolean;
|
reviewPassed: boolean;
|
reviewVisible: boolean;
|
}
|
|
const emit = defineEmits(['reload']);
|
const getLeftTreeActiveInfo: (() => any) | null = inject('getLeftTreeActiveInfo', null);
|
const userStore = useUserStore();
|
const accessStore = useAccessStore();
|
const { permissionList } = accessStore;
|
const generatorStore = useGeneratorStore();
|
const { createMessage } = useMessage();
|
const [registerPopup, { openPopup, setPopupProps }] = usePopup();
|
const [registerModal, { openModal, setModalProps }] = useModal();
|
const [registerDrawer, { openDrawer, setDrawerProps }] = useDrawer();
|
const parserRef = ref<any>(null);
|
const state = reactive<State>({
|
formConf: {},
|
defaultFormConf: {},
|
formData: {},
|
config: {},
|
loading: true,
|
loadError: false,
|
loadErrorText: '',
|
prevBtnLoading: false,
|
nextBtnLoading: false,
|
key: Date.now(),
|
dataForm: {
|
id: '',
|
data: '',
|
},
|
formOperates: [],
|
title: '',
|
continueText: '',
|
allList: [],
|
currIndex: 0,
|
isContinue: false,
|
submitType: 0,
|
showContinueBtn: true,
|
reviewPassed: true,
|
reviewVisible: true,
|
});
|
const { title, formConf, key, loading, loadError, loadErrorText, continueText, showContinueBtn, submitType } = toRefs(state);
|
const Parser = createAsyncComponent(() => import('#/components/FormGenerator/src/components/Parser.vue'));
|
|
const getPrevDisabled = computed(() => state.currIndex === 0);
|
const getNextDisabled = computed(() => state.currIndex === state.allList.length - 1);
|
const getShowMoreBtn = computed(() => state.config.id && state.config.showMoreBtn && state.formConf.hasConfirmAndAddBtn);
|
const getOkText = computed(() => {
|
const text = state.formConf.confirmButtonTextI18nCode
|
? $t(state.formConf.confirmButtonTextI18nCode, state.formConf.confirmButtonText)
|
: state.formConf.confirmButtonText;
|
return text || $t('common.okText');
|
});
|
const getReviewText = computed(() => {
|
const text = state.formConf.reviewButtonTextI18nCode
|
? $t(state.formConf.reviewButtonTextI18nCode, state.formConf.reviewButtonText)
|
: state.formConf.reviewButtonText;
|
return text || $t('common.reviewText');
|
});
|
const getCancelText = computed(() => {
|
const text = state.formConf.cancelButtonTextI18nCode
|
? $t(state.formConf.cancelButtonTextI18nCode, state.formConf.cancelButtonText)
|
: state.formConf.cancelButtonText;
|
return text || $t('common.cancelText');
|
});
|
const getFormExtraBind = computed(() => {
|
return {
|
showLog: state.formConf.dataLog,
|
modelId: state.config.modelId,
|
formDataId: state.config.id,
|
};
|
});
|
|
defineExpose({ init });
|
|
function fillFormData(form, data, isAdd) {
|
const userInfo = userStore.getUserInfo;
|
const currDate = new Date();
|
const loop = (list, parent?) => {
|
for (const item of list) {
|
if (item.__vModel__) {
|
const hasField = Object.prototype.hasOwnProperty.call(data, item.__vModel__);
|
const dataVal = hasField ? data[item.__vModel__] : undefined;
|
const isEmptyVal = dataVal === null || dataVal === undefined || dataVal === '' || (Array.isArray(dataVal) && dataVal.length === 0);
|
const val = hasField ? dataVal : item.__config__.defaultValue;
|
if (!item.__config__.isSubTable) item.__config__.defaultValue = val;
|
// 应用"当前用户/系统时间"默认值的时机:新建、子表、或编辑模式下字段值为空
|
if ((isAdd || item.__config__.isSubTable || isEmptyVal) && item.__config__.defaultCurrent) {
|
if (item.__config__.jnpfKey === 'datePicker') {
|
item.__config__.defaultValue = dayjs(currDate).startOf(getDateTimeUnit(item.format)).valueOf();
|
}
|
if (item.__config__.jnpfKey === 'timePicker') {
|
item.__config__.defaultValue = dayjs(currDate).format(item.format || 'HH:mm:ss');
|
}
|
if (item.__config__.jnpfKey === 'organizeSelect' && userInfo?.organizeIds?.length) {
|
item.__config__.defaultValue = item.multiple ? userInfo.organizeIds : userInfo.organizeId;
|
}
|
if (item.__config__.jnpfKey === 'userSelect' && userInfo?.userId) {
|
item.__config__.defaultValue = item.multiple ? [userInfo.userId] : userInfo.userId;
|
}
|
if (item.__config__.jnpfKey === 'usersSelect' && userInfo?.userId) {
|
item.__config__.defaultValue = [`${userInfo?.userId}--user`];
|
}
|
if (item.__config__.jnpfKey === 'posSelect' && userInfo?.positionIds?.length) {
|
item.__config__.defaultValue = item.multiple ? userInfo.positionIds : userInfo.positionId;
|
}
|
if (item.__config__.jnpfKey === 'sign' && userInfo?.signImg) {
|
item.__config__.defaultValue = userInfo.signImg;
|
}
|
}
|
if (isAdd && !item.__config__.isSubTable && Object.prototype.hasOwnProperty.call(data, item.__vModel__))
|
item.__config__.defaultValue = data[item.__vModel__];
|
if (!state.config.isPreview && !state.config.isDataManage && !state.config.isOnlineUtilsOpen && state.config.useFormPermission) {
|
const id = item.__config__.isSubTable && parent?.__vModel__ ? `${parent.__vModel__}-${item.__vModel__}` : item.__vModel__;
|
let noShow = true;
|
if (state.formOperates && state.formOperates.length) {
|
noShow = !state.formOperates.some((o) => o.enCode === id);
|
}
|
noShow = item.__config__.noShow ? item.__config__.noShow : noShow;
|
item.__config__.noShow = noShow;
|
}
|
}
|
if (item.__config__ && item.__config__.children && Array.isArray(item.__config__.children)) {
|
loop(item.__config__.children, item);
|
}
|
}
|
};
|
loop(form.fields);
|
form.formData = data;
|
}
|
function init(data) {
|
state.loading = true;
|
state.loadError = false;
|
state.loadErrorText = '';
|
state.submitType = 0;
|
state.isContinue = false;
|
state.prevBtnLoading = false;
|
state.nextBtnLoading = false;
|
state.title = data.title ? data.title : !data.id || data.id === 'jnpfAdd' ? $t('common.add2Text') : $t('common.editText');
|
state.continueText = data.id ? $t('common.continueText') : $t('common.continueAndAddText');
|
state.config = data;
|
state.defaultFormConf = cloneDeep(data.formConf);
|
state.formConf = cloneDeep(state.defaultFormConf);
|
state.reviewVisible = !!state.formConf.hasReviewBtn && !state.formConf.reviewBtnConfig?.noShow;
|
state.reviewPassed = !state.reviewVisible || !!state.formConf.reviewBtnConfig?.biz_review_optional;
|
state.showContinueBtn = !data.formData && state.formConf.hasConfirmAndAddBtn;
|
state.dataForm.id = !data.id || data.id === 'jnpfAdd' ? '' : data.id;
|
getFormOperates();
|
openForm();
|
state.allList = data.allList || [];
|
state.currIndex = state.allList.length && data.id ? state.allList.findIndex((item) => item.id === data.id) : 0;
|
nextTick(() => {
|
if (!data.formData) return setTimeout(initData, 0);
|
// 行内编辑
|
setTimeout(() => {
|
state.formData = { ...data.formData, id: state.dataForm.id };
|
setFormValue();
|
}, 0);
|
});
|
}
|
function initData() {
|
changeLoading(true);
|
state.loading = true;
|
state.loadError = false;
|
state.loadErrorText = '';
|
if (state.config.id) {
|
const extra = { modelId: state.config.modelId, id: state.config.id, type: 2 };
|
generatorStore.setDynamicModelExtra(extra);
|
getInfo(state.config.id);
|
} else {
|
generatorStore.setDynamicModelExtra({});
|
state.formData = {};
|
setFormValue(true);
|
}
|
}
|
function getInfo(id) {
|
getModelInfo(state.config.modelId, id, state.config.menuId, { onlineUtilsOpen: !!state.config.isOnlineUtilsOpen }).then(
|
(res) => {
|
state.dataForm = res.data || {};
|
setDataFormValue(state.dataForm, () => showLoadError('数据加载失败,未获取到表单数据'));
|
},
|
() => {
|
showLoadError('数据加载失败,请稍后重试');
|
},
|
);
|
}
|
function setDataFormValue(dataForm, fallback) {
|
if (!dataForm.data) return fallback();
|
let formData = {};
|
try {
|
formData = JSON.parse(dataForm.data);
|
} catch {
|
return fallback();
|
}
|
state.formData = { ...formData, id: dataForm.id || state.config.id };
|
setFormValue();
|
}
|
function setFormValue(isAdd = false) {
|
state.loadError = false;
|
state.loadErrorText = '';
|
if (isAdd && getLeftTreeActiveInfo) state.formData = { ...getLeftTreeActiveInfo() };
|
state.formConf = cloneDeep(state.defaultFormConf);
|
state.reviewVisible = !!state.formConf.hasReviewBtn && !state.formConf.reviewBtnConfig?.noShow;
|
state.reviewPassed = !state.reviewVisible || !!state.formConf.reviewBtnConfig?.biz_review_optional;
|
fillFormData(state.formConf, state.formData, isAdd);
|
nextTick(() => {
|
state.key = Date.now();
|
state.loading = false;
|
state.prevBtnLoading = false;
|
state.nextBtnLoading = false;
|
changeLoading(false);
|
});
|
}
|
function getFormOperates() {
|
if (state.config.isPreview || state.config.isDataManage || state.config.isOnlineUtilsOpen || !state.config.useFormPermission) return;
|
const modelId = state.config.menuId;
|
const list = permissionList.find((o) => o.modelId === modelId);
|
state.formOperates = list && list.form ? list.form : [];
|
}
|
function submitForm(data, callback, scriptParameter = {}, auditDisplayFields = [], getAuditDisplayFields?) {
|
if (!data) return;
|
setFormProps({ confirmLoading: true });
|
const formData = buildDisplayOnlySubmitData(state.formConf.fields, { ...state.formData, ...data });
|
state.dataForm.data = JSON.stringify(formData);
|
state.dataForm.auditDisplayFields = auditDisplayFields;
|
if (state.formConf.funcs?.customSubmit) {
|
runCustomSubmit(formData, scriptParameter, auditDisplayFields, getAuditDisplayFields)
|
.then((res) => {
|
if (res?.msg) createMessage.success(res.msg);
|
handleSubmitSuccess(callback, { formData: getLatestSubmitData(formData, scriptParameter), id: state.dataForm.id, response: res });
|
})
|
.catch(() => {
|
setFormProps({ confirmLoading: false });
|
});
|
return;
|
}
|
const formMethod = state.dataForm.id ? updateModel : createModel;
|
formMethod(state.config.modelId, { ...state.dataForm, menuId: state.config.menuId, onlineUtilsOpen: !!state.config.isOnlineUtilsOpen })
|
.then((res) => {
|
createMessage.success(res.msg);
|
handleSubmitSuccess(callback, { formData, id: res?.data?.id || state.dataForm.id, response: res });
|
})
|
.catch(() => {
|
setFormProps({ confirmLoading: false });
|
});
|
}
|
function getLatestSubmitData(formData, scriptParameter) {
|
const currentFormData = scriptParameter?.formData || formData;
|
return buildDisplayOnlySubmitData(state.formConf.fields, { ...state.formData, ...currentFormData });
|
}
|
function syncLatestSubmitData(formData, scriptParameter) {
|
const latestFormData = getLatestSubmitData(formData, scriptParameter);
|
Object.keys(formData).forEach((key) => delete formData[key]);
|
Object.assign(formData, latestFormData);
|
}
|
function runCustomSubmit(formData, scriptParameter, auditDisplayFields, getAuditDisplayFields?) {
|
const func: any = getScriptFunc(state.formConf.funcs?.customSubmitFunc);
|
if (!func) return Promise.reject();
|
const auditCorrelationId = createAuditCorrelationId();
|
const setFormData = (prop, value) => {
|
scriptParameter?.setFormData?.(prop, value);
|
syncLatestSubmitData(formData, scriptParameter);
|
};
|
const formContext = {
|
id: state.dataForm.id,
|
isEdit: !!state.dataForm.id,
|
submit: (resolve, reject) => {
|
const latestFormData = getLatestSubmitData(formData, scriptParameter);
|
state.dataForm.data = JSON.stringify(latestFormData);
|
state.dataForm.auditDisplayFields = typeof getAuditDisplayFields === 'function' ? getAuditDisplayFields(latestFormData) : auditDisplayFields;
|
const formMethod = state.dataForm.id ? updateModel : createModel;
|
formMethod(
|
state.config.modelId,
|
{ ...state.dataForm, menuId: state.config.menuId, onlineUtilsOpen: !!state.config.isOnlineUtilsOpen },
|
auditCorrelationId,
|
)
|
.then((res) => {
|
resolve?.(res);
|
})
|
.catch((error) => {
|
reject?.(error);
|
});
|
},
|
};
|
const scopedOnlineUtils = createAuditRequestOnlineUtils(
|
scriptParameter?.onlineUtils,
|
() => {
|
const latestFormData = getLatestSubmitData(formData, scriptParameter);
|
return typeof getAuditDisplayFields === 'function' ? getAuditDisplayFields(latestFormData) : auditDisplayFields;
|
},
|
() => {
|
const latestFormData = getLatestSubmitData(formData, scriptParameter);
|
return latestFormData.biz_sign ?? latestFormData.biz_sign_jnpfId;
|
},
|
auditCorrelationId,
|
);
|
try {
|
return Promise.resolve(func({ ...scriptParameter, formData, setFormData, formContext, onlineUtils: scopedOnlineUtils }));
|
} catch {
|
return Promise.reject();
|
}
|
}
|
function handleSubmitSuccess(callback, result?) {
|
if (callback && typeof callback === 'function') callback();
|
try {
|
state.config.onSuccess?.(result);
|
} catch (error) {
|
console.error('[onlineUtils.openAdd/openEdit] onSuccess error:', error);
|
}
|
setFormProps({ confirmLoading: false });
|
if (state.submitType == 1) {
|
initData();
|
state.isContinue = true;
|
} else {
|
setFormProps({ open: false });
|
emit('reload');
|
}
|
}
|
function handleReset() {
|
state.reviewVisible = !!state.formConf.hasReviewBtn && !state.formConf.reviewBtnConfig?.noShow;
|
state.reviewPassed = !state.reviewVisible || !!state.formConf.reviewBtnConfig?.biz_review_optional;
|
const parser = unref(parserRef);
|
parser?.handleReset();
|
}
|
function handleReview() {
|
getParser().handleReview();
|
}
|
function handleSubmit() {
|
if (state.loadError) return createMessage.error(state.loadErrorText || '数据加载失败,不能保存');
|
if (state.config.isPreview) return createMessage.warning('功能预览不支持数据保存');
|
getParser().handleSubmit();
|
}
|
function handlePrev() {
|
state.currIndex--;
|
// state.prevBtnLoading = true;
|
handleGetNewInfo();
|
}
|
function handleNext() {
|
state.currIndex++;
|
// state.nextBtnLoading = true;
|
handleGetNewInfo();
|
}
|
function handleGetNewInfo() {
|
changeLoading(true);
|
state.loading = true;
|
state.loadError = false;
|
state.loadErrorText = '';
|
handleReset();
|
state.config.id = state.allList[state.currIndex].id;
|
getInfo(state.config.id);
|
}
|
function getParser() {
|
const parser = unref(parserRef);
|
if (!parser) throw new Error('parser is null!');
|
return parser;
|
}
|
function openForm() {
|
if (state.formConf.popupType === 'fullScreen') return openPopup();
|
if (state.formConf.popupType === 'drawer') return openDrawer();
|
openModal();
|
}
|
function setFormProps(data) {
|
if (state.formConf.popupType === 'fullScreen') return setPopupProps(data);
|
if (state.formConf.popupType === 'drawer') return setDrawerProps(data);
|
setModalProps(data);
|
}
|
function changeLoading(loading) {
|
setFormProps({ loading });
|
}
|
function closeFormLoading() {
|
state.loading = false;
|
state.prevBtnLoading = false;
|
state.nextBtnLoading = false;
|
changeLoading(false);
|
}
|
function showLoadError(message) {
|
state.loadError = true;
|
state.loadErrorText = message;
|
createMessage.error(message);
|
closeFormLoading();
|
}
|
async function onClose() {
|
if (state.isContinue) emit('reload');
|
return true;
|
}
|
</script>
|
<template>
|
<BasicPopup
|
v-bind="$attrs"
|
@register="registerPopup"
|
show-ok-btn
|
:ok-text="getOkText"
|
:cancel-text="getCancelText"
|
:ok-button-props="{ disabled: state.reviewVisible && !state.reviewPassed }"
|
destroy-on-close
|
@ok="handleSubmit"
|
:close-func="onClose"
|
class="full-popup">
|
<template #title>
|
<a-space :size="10">
|
<div class="text-[16px] font-medium">{{ title }}</div>
|
<a-space-compact size="small" block v-if="getShowMoreBtn">
|
<a-tooltip :title="$t('common.prevRecord')">
|
<a-button size="small" :loading="state.prevBtnLoading" :disabled="getPrevDisabled" @click="handlePrev">
|
<i class="icon-ym icon-ym-caret-left text-[10px]"></i>
|
</a-button>
|
</a-tooltip>
|
<a-tooltip :title="$t('common.nextRecord')">
|
<a-button size="small" :loading="state.nextBtnLoading" :disabled="getNextDisabled" @click="handleNext">
|
<i class="icon-ym icon-ym-caret-right text-[10px]"></i>
|
</a-button>
|
</a-tooltip>
|
</a-space-compact>
|
</a-space>
|
</template>
|
<template #insertToolbar>
|
<JnpfCheckboxSingle v-model:value="submitType" :label="continueText" v-if="showContinueBtn" />
|
<a-button v-if="state.reviewVisible" class="mr-[10px]" @click="handleReview">{{ getReviewText }}</a-button>
|
</template>
|
<div class="jnpf-common-form-wrapper">
|
<div class="jnpf-common-form-wrapper__main p-[10px]" :style="{ margin: '0 auto', width: formConf.fullScreenWidth || '100%' }">
|
<Result status="error" title="数据加载失败" :sub-title="loadErrorText" v-if="!loading && loadError" />
|
<Parser
|
ref="parserRef"
|
:form-conf="formConf"
|
:is-preview="state.config.isPreview"
|
:model-id="state.config.modelId"
|
@review-status-change="state.reviewPassed = $event"
|
@review-visibility-change="state.reviewVisible = $event"
|
@submit="submitForm"
|
:key="key"
|
v-if="!loading && !loadError" />
|
</div>
|
<FormExtraPanel v-bind="getFormExtraBind" v-if="state.dataForm.id && formConf.dataLog && !loading && !loadError" :key="key" />
|
</div>
|
</BasicPopup>
|
<BasicModal
|
v-bind="$attrs"
|
@register="registerModal"
|
:width="formConf.generalWidth"
|
:min-height="100"
|
:ok-text="getOkText"
|
:cancel-text="getCancelText"
|
:ok-button-props="{ disabled: state.reviewVisible && !state.reviewPassed }"
|
@ok="handleSubmit"
|
:close-func="onClose">
|
<template #title>
|
<a-space :size="10">
|
<div class="text-[16px] font-medium">{{ title }}</div>
|
<a-space-compact size="small" block v-if="getShowMoreBtn">
|
<a-tooltip :title="$t('common.prevRecord')">
|
<a-button size="small" :loading="state.prevBtnLoading" :disabled="getPrevDisabled" @click="handlePrev">
|
<i class="icon-ym icon-ym-caret-left text-[10px]"></i>
|
</a-button>
|
</a-tooltip>
|
<a-tooltip :title="$t('common.nextRecord')">
|
<a-button size="small" :loading="state.nextBtnLoading" :disabled="getNextDisabled" @click="handleNext">
|
<i class="icon-ym icon-ym-caret-right text-[10px]"></i>
|
</a-button>
|
</a-tooltip>
|
</a-space-compact>
|
</a-space>
|
</template>
|
<template #insertFooter>
|
<div class="float-left mt-[5px]" v-if="showContinueBtn || state.reviewVisible">
|
<JnpfCheckboxSingle v-model:value="submitType" :label="continueText" v-if="showContinueBtn" />
|
<a-button v-if="state.reviewVisible" class="mr-[10px]" @click="handleReview">{{ getReviewText }}</a-button>
|
</div>
|
</template>
|
<Result status="error" title="数据加载失败" :sub-title="loadErrorText" v-if="!loading && loadError" />
|
<Parser
|
ref="parserRef"
|
:form-conf="formConf"
|
:is-preview="state.config.isPreview"
|
:model-id="state.config.modelId"
|
@review-status-change="state.reviewPassed = $event"
|
@review-visibility-change="state.reviewVisible = $event"
|
@submit="submitForm"
|
:key="key"
|
v-if="!loading && !loadError" />
|
</BasicModal>
|
<BasicDrawer
|
v-bind="$attrs"
|
@register="registerDrawer"
|
:width="formConf.drawerWidth"
|
show-footer
|
:ok-text="getOkText"
|
:cancel-text="getCancelText"
|
:ok-button-props="{ disabled: state.reviewVisible && !state.reviewPassed }"
|
@ok="handleSubmit"
|
:close-func="onClose">
|
<template #title>
|
<div class="flex items-center justify-between">
|
<div class="text-[16px] font-medium">{{ title }}</div>
|
<a-space-compact size="small" v-if="getShowMoreBtn">
|
<a-tooltip :title="$t('common.prevRecord')">
|
<a-button size="small" :loading="state.prevBtnLoading" :disabled="getPrevDisabled" @click="handlePrev">
|
<i class="icon-ym icon-ym-caret-left text-[10px]"></i>
|
</a-button>
|
</a-tooltip>
|
<a-tooltip :title="$t('common.nextRecord')">
|
<a-button size="small" :loading="state.nextBtnLoading" :disabled="getNextDisabled" @click="handleNext">
|
<i class="icon-ym icon-ym-caret-right text-[10px]"></i>
|
</a-button>
|
</a-tooltip>
|
</a-space-compact>
|
</div>
|
</template>
|
<template #insertFooter>
|
<div class="float-left mt-[5px]" v-if="showContinueBtn || state.reviewVisible">
|
<JnpfCheckboxSingle v-model:value="submitType" :label="continueText" v-if="showContinueBtn" />
|
<a-button v-if="state.reviewVisible" class="mr-[10px]" @click="handleReview">{{ getReviewText }}</a-button>
|
</div>
|
</template>
|
<div class="p-[10px]">
|
<Result status="error" title="数据加载失败" :sub-title="loadErrorText" v-if="!loading && loadError" />
|
<Parser
|
ref="parserRef"
|
:form-conf="formConf"
|
:is-preview="state.config.isPreview"
|
:model-id="state.config.modelId"
|
@review-status-change="state.reviewPassed = $event"
|
@review-visibility-change="state.reviewVisible = $event"
|
@submit="submitForm"
|
:key="key"
|
v-if="!loading && !loadError" />
|
</div>
|
</BasicDrawer>
|
</template>
|