3 changed files with 307 additions and 3 deletions
@ -0,0 +1,289 @@ |
|||
<script setup lang="ts"> |
|||
import type { ResourceDto } from '@abp/localization'; |
|||
import type { PropertyInfo } from '@abp/ui'; |
|||
import type { FormInstance } from 'ant-design-vue'; |
|||
|
|||
import type { TextTemplateDefinitionDto } from '../../types'; |
|||
|
|||
import { computed, ref, useTemplateRef } from 'vue'; |
|||
|
|||
import { useAccess } from '@vben/access'; |
|||
import { useVbenModal } from '@vben/common-ui'; |
|||
import { $t } from '@vben/locales'; |
|||
|
|||
import { |
|||
isNullOrWhiteSpace, |
|||
useAbpStore, |
|||
useLocalization, |
|||
useLocalizationSerializer, |
|||
} from '@abp/core'; |
|||
import { useResourcesApi } from '@abp/localization'; |
|||
import { LocalizableInput, PropertyTable } from '@abp/ui'; |
|||
import { Checkbox, Form, Input, message, Select, Tabs } from 'ant-design-vue'; |
|||
|
|||
import { useTemplateDefinitionsApi } from '../../api'; |
|||
|
|||
defineOptions({ |
|||
name: 'TemplateDefinitionModal', |
|||
}); |
|||
const emits = defineEmits<{ |
|||
(event: 'change', data: TextTemplateDefinitionDto): void; |
|||
}>(); |
|||
|
|||
const FormItem = Form.Item; |
|||
const TabPane = Tabs.TabPane; |
|||
|
|||
type TabKey = 'basic' | 'properties'; |
|||
|
|||
const activeTabKey = ref<TabKey>('basic'); |
|||
const isEditModel = ref(false); |
|||
const form = useTemplateRef<FormInstance>('form'); |
|||
const formModel = ref<TextTemplateDefinitionDto>(); |
|||
const textTemplateLayouts = ref<TextTemplateDefinitionDto[]>([]); |
|||
const textTemplateResources = ref<ResourceDto[]>([]); |
|||
|
|||
const abpStore = useAbpStore(); |
|||
|
|||
const { Lr } = useLocalization(); |
|||
const { hasAccessByCodes } = useAccess(); |
|||
const { deserialize } = useLocalizationSerializer(); |
|||
const { getListApi: getResourcesApi } = useResourcesApi(); |
|||
const { cancel, createApi, getApi, getListApi, updateApi } = |
|||
useTemplateDefinitionsApi(); |
|||
|
|||
const getLanguageOptions = computed(() => { |
|||
const languages = abpStore.application?.localization.languages; |
|||
if (!languages) { |
|||
return []; |
|||
} |
|||
return languages.map((language) => { |
|||
return { |
|||
label: language.displayName, |
|||
value: language.cultureName, |
|||
}; |
|||
}); |
|||
}); |
|||
|
|||
const [Modal, modalApi] = useVbenModal({ |
|||
class: 'w-1/2', |
|||
draggable: true, |
|||
fullscreenButton: false, |
|||
onCancel() { |
|||
modalApi.close(); |
|||
}, |
|||
onClosed() { |
|||
cancel('TemplateDefinitionModal has closed!'); |
|||
}, |
|||
onConfirm: async () => { |
|||
await form.value?.validate(); |
|||
const api = isEditModel.value |
|||
? updateApi(formModel.value!.name, formModel.value!) |
|||
: createApi(formModel.value!); |
|||
modalApi.setState({ submitting: true }); |
|||
api |
|||
.then((res) => { |
|||
message.success($t('AbpUi.SavedSuccessfully')); |
|||
emits('change', res); |
|||
modalApi.close(); |
|||
}) |
|||
.finally(() => { |
|||
modalApi.setState({ submitting: false }); |
|||
}); |
|||
}, |
|||
onOpenChange: async (isOpen: boolean) => { |
|||
if (isOpen) { |
|||
isEditModel.value = false; |
|||
activeTabKey.value = 'basic'; |
|||
formModel.value = undefined; |
|||
await Promise.all([onGet(), onInitLayouts(), onInitResources()]); |
|||
} |
|||
}, |
|||
title: $t('AbpTextTemplating.TextTemplates:AddNew'), |
|||
}); |
|||
|
|||
async function onGet() { |
|||
const { name } = modalApi.getData<TextTemplateDefinitionDto>(); |
|||
if (isNullOrWhiteSpace(name)) { |
|||
modalApi.setState({ title: $t('AbpTextTemplating.TextTemplates:AddNew') }); |
|||
formModel.value = { |
|||
displayName: '', |
|||
extraProperties: {}, |
|||
isInlineLocalized: false, |
|||
isLayout: false, |
|||
isStatic: false, |
|||
name: '', |
|||
}; |
|||
return; |
|||
} |
|||
try { |
|||
modalApi.setState({ loading: true }); |
|||
formModel.value = await getApi(name); |
|||
modalApi.setState({ |
|||
title: `${$t('AbpTextTemplating.TextTemplates')} - ${name}`, |
|||
}); |
|||
} finally { |
|||
modalApi.setState({ loading: false }); |
|||
} |
|||
} |
|||
|
|||
async function onInitLayouts() { |
|||
const { items } = await getListApi({ |
|||
isLayout: true, |
|||
}); |
|||
textTemplateLayouts.value = items.map((item) => { |
|||
const localizableString = deserialize(item.displayName); |
|||
return { |
|||
...item, |
|||
displayName: Lr(localizableString.resourceName, localizableString.name), |
|||
}; |
|||
}); |
|||
} |
|||
|
|||
async function onInitResources() { |
|||
// TODO: 是否暴露localization、模块常量 |
|||
if (!hasAccessByCodes(['LocalizationManagement.Resource'])) { |
|||
return; |
|||
} |
|||
const { items } = await getResourcesApi(); |
|||
textTemplateResources.value = items; |
|||
} |
|||
|
|||
function onIsInlineLocalizedChange(isInlineLocalized: boolean) { |
|||
if (isInlineLocalized) { |
|||
formModel.value!.localizationResourceName = undefined; |
|||
} |
|||
} |
|||
|
|||
function onIsLayoutChange(isLayout: boolean) { |
|||
if (isLayout) { |
|||
formModel.value!.layout = undefined; |
|||
} |
|||
} |
|||
|
|||
function onPropChange(prop: PropertyInfo) { |
|||
formModel.value!.extraProperties ??= {}; |
|||
formModel.value!.extraProperties[prop.key] = prop.value; |
|||
} |
|||
|
|||
function onPropDelete(prop: PropertyInfo) { |
|||
formModel.value!.extraProperties ??= {}; |
|||
delete formModel.value!.extraProperties[prop.key]; |
|||
} |
|||
</script> |
|||
|
|||
<template> |
|||
<Modal> |
|||
<Form |
|||
v-if="formModel" |
|||
ref="form" |
|||
:label-col="{ span: 6 }" |
|||
:model="formModel" |
|||
:wrapper-col="{ span: 18 }" |
|||
> |
|||
<Tabs v-model:active-key="activeTabKey"> |
|||
<TabPane key="basic" :tab="$t('AbpTextTemplating.BasicInfo')"> |
|||
<FormItem |
|||
name="name" |
|||
required |
|||
:label="$t('AbpTextTemplating.DisplayName:Name')" |
|||
> |
|||
<Input |
|||
allow-clear |
|||
autocomplete="off" |
|||
:disabled="!isEditModel || formModel.isStatic" |
|||
v-model:value="formModel.name" |
|||
/> |
|||
</FormItem> |
|||
<FormItem |
|||
:label="$t('WebhooksManagement.DisplayName:DisplayName')" |
|||
name="displayName" |
|||
required |
|||
> |
|||
<LocalizableInput |
|||
v-model:value="formModel.displayName" |
|||
:disabled="formModel.isStatic" |
|||
/> |
|||
</FormItem> |
|||
<FormItem |
|||
name="isInlineLocalized" |
|||
:label="$t('AbpTextTemplating.DisplayName:IsInlineLocalized')" |
|||
> |
|||
<Checkbox |
|||
:disabled="formModel.isStatic" |
|||
v-model:checked="formModel.isInlineLocalized" |
|||
@change="(e) => onIsInlineLocalizedChange(e.target.checked)" |
|||
> |
|||
{{ $t('AbpTextTemplating.DisplayName:IsInlineLocalized') }} |
|||
</Checkbox> |
|||
</FormItem> |
|||
<FormItem |
|||
v-if="!formModel.isInlineLocalized" |
|||
name="defaultCultureName" |
|||
:label="$t('AbpTextTemplating.DisplayName:DefaultCultureName')" |
|||
> |
|||
<Select |
|||
allow-clear |
|||
:disabled="formModel.isStatic" |
|||
v-model:value="formModel.defaultCultureName" |
|||
:options="getLanguageOptions" |
|||
/> |
|||
</FormItem> |
|||
<FormItem |
|||
v-if="formModel.isInlineLocalized" |
|||
name="localizationResourceName" |
|||
:label="$t('AbpTextTemplating.LocalizationResource')" |
|||
> |
|||
<Select |
|||
allow-clear |
|||
:disabled="formModel.isStatic" |
|||
v-model:value="formModel.localizationResourceName" |
|||
:options="textTemplateResources" |
|||
:field-names="{ |
|||
label: 'displayName', |
|||
value: 'name', |
|||
}" |
|||
/> |
|||
</FormItem> |
|||
<FormItem |
|||
name="isLayout" |
|||
:label="$t('AbpTextTemplating.DisplayName:IsLayout')" |
|||
> |
|||
<Checkbox |
|||
:disabled="formModel.isStatic" |
|||
v-model:checked="formModel.isLayout" |
|||
@change="(e) => onIsLayoutChange(e.target.checked)" |
|||
> |
|||
{{ $t('AbpTextTemplating.DisplayName:IsLayout') }} |
|||
</Checkbox> |
|||
</FormItem> |
|||
<FormItem |
|||
v-if="!formModel.isLayout" |
|||
name="layout" |
|||
:label="$t('AbpTextTemplating.DisplayName:Layout')" |
|||
> |
|||
<Select |
|||
allow-clear |
|||
:disabled="formModel.isStatic" |
|||
v-model:value="formModel.layout" |
|||
:options="textTemplateLayouts" |
|||
:field-names="{ |
|||
label: 'displayName', |
|||
value: 'name', |
|||
}" |
|||
/> |
|||
</FormItem> |
|||
</TabPane> |
|||
<TabPane key="properties" :tab="$t('AbpTextTemplating.Properties')"> |
|||
<PropertyTable |
|||
:data="formModel.extraProperties" |
|||
:disabled="formModel.isStatic" |
|||
@change="onPropChange" |
|||
@delete="onPropDelete" |
|||
/> |
|||
</TabPane> |
|||
</Tabs> |
|||
</Form> |
|||
</Modal> |
|||
</template> |
|||
|
|||
<style scoped></style> |
|||
Loading…
Reference in new issue