23 changed files with 940 additions and 40 deletions
@ -0,0 +1 @@ |
|||
export { default as groupBy } from 'lodash.groupby'; |
|||
@ -1,3 +1,5 @@ |
|||
export { default as FeatureDefinitionTable } from './definitions/features/FeatureDefinitionTable.vue'; |
|||
export { default as FeatureGroupDefinitionTable } from './definitions/groups/FeatureGroupDefinitionTable.vue'; |
|||
export { default as FeatureModal } from './features/FeatureModal.vue'; |
|||
export { default as FeatureStateCheck } from './state-check/FeatureStateCheck.vue'; |
|||
export { default as GlobalFeatureStateCheck } from './state-check/GlobalFeatureStateCheck.vue'; |
|||
|
|||
@ -0,0 +1,135 @@ |
|||
<script setup lang="ts"> |
|||
import type { |
|||
FeatureDefinitionDto, |
|||
FeatureGroupDefinitionDto, |
|||
} from '../../types'; |
|||
|
|||
import { computed, onMounted, ref } from 'vue'; |
|||
|
|||
import { |
|||
listToTree, |
|||
useLocalization, |
|||
useLocalizationSerializer, |
|||
} from '@abp/core'; |
|||
import { Checkbox, FormItemRest, TreeSelect } from 'ant-design-vue'; |
|||
|
|||
import { useFeatureDefinitionsApi } from '../../api/useFeatureDefinitionsApi'; |
|||
import { useFeatureGroupDefinitionsApi } from '../../api/useFeatureGroupDefinitionsApi'; |
|||
|
|||
interface FeatureTreeData { |
|||
checkable?: boolean; |
|||
children: FeatureTreeData[]; |
|||
displayName: string; |
|||
groupName: string; |
|||
name: string; |
|||
} |
|||
|
|||
const emits = defineEmits(['blur', 'change']); |
|||
|
|||
const { getListApi: getFeaturesApi } = useFeatureDefinitionsApi(); |
|||
const { getListApi: getFeatureGroupsApi } = useFeatureGroupDefinitionsApi(); |
|||
const { deserialize } = useLocalizationSerializer(); |
|||
const { Lr } = useLocalization(); |
|||
|
|||
const features = ref<FeatureDefinitionDto[]>([]); |
|||
const featureGroups = ref<FeatureGroupDefinitionDto[]>([]); |
|||
const modelValue = defineModel<{ |
|||
featureNames: string[]; |
|||
requiresAll: boolean; |
|||
}>({ |
|||
default: { |
|||
featureNames: [], |
|||
requiresAll: false, |
|||
}, |
|||
}); |
|||
|
|||
const getFeatureOptions = computed(() => { |
|||
const featureOptions: FeatureTreeData[] = []; |
|||
featureGroups.value.forEach((group) => { |
|||
featureOptions.push({ |
|||
checkable: false, |
|||
displayName: group.displayName, |
|||
groupName: group.name, |
|||
name: group.name, |
|||
children: listToTree( |
|||
features.value.filter((x) => x.groupName === group.name), |
|||
{ |
|||
id: 'name', |
|||
pid: 'parentName', |
|||
}, |
|||
), |
|||
}); |
|||
}); |
|||
return featureOptions; |
|||
}); |
|||
const getRequiredFeatures = computed(() => { |
|||
const featureNames = modelValue.value?.featureNames ?? []; |
|||
const requiredFeatures = features.value |
|||
.filter((feature) => featureNames.includes(feature.name)) |
|||
.map((feature) => { |
|||
return { |
|||
label: feature.displayName, |
|||
value: feature.name, |
|||
}; |
|||
}); |
|||
return requiredFeatures; |
|||
}); |
|||
|
|||
function onChange() { |
|||
emits('change', modelValue.value); |
|||
} |
|||
|
|||
function onFeaturesChange(value: any[]) { |
|||
modelValue.value.featureNames = value.map((item) => item.value); |
|||
emits('change', modelValue.value); |
|||
} |
|||
|
|||
async function onInit() { |
|||
const [featureGroupRes, featuresRes] = await Promise.all([ |
|||
getFeatureGroupsApi(), |
|||
getFeaturesApi(), |
|||
]); |
|||
featureGroups.value = featureGroupRes.items.map((item) => { |
|||
const displayName = deserialize(item.displayName); |
|||
return { |
|||
...item, |
|||
displayName: Lr(displayName.resourceName, displayName.name), |
|||
}; |
|||
}); |
|||
features.value = featuresRes.items.map((item) => { |
|||
const displayName = deserialize(item.displayName); |
|||
return { |
|||
...item, |
|||
displayName: Lr(displayName.resourceName, displayName.name), |
|||
}; |
|||
}); |
|||
} |
|||
|
|||
onMounted(onInit); |
|||
</script> |
|||
|
|||
<template> |
|||
<div class="flex w-full flex-col gap-5"> |
|||
<FormItemRest> |
|||
<Checkbox |
|||
v-model:checked="modelValue.requiresAll" |
|||
@blur="emits('blur')" |
|||
@change="onChange" |
|||
> |
|||
{{ $t('component.simple_state_checking.requireFeatures.requiresAll') }} |
|||
</Checkbox> |
|||
<TreeSelect |
|||
:tree-data="getFeatureOptions" |
|||
allow-clear |
|||
tree-checkable |
|||
tree-check-strictly |
|||
:field-names="{ label: 'displayName', value: 'name' }" |
|||
:value="getRequiredFeatures" |
|||
@blur="emits('blur')" |
|||
@change="onFeaturesChange" |
|||
/> |
|||
</FormItemRest> |
|||
</div> |
|||
</template> |
|||
|
|||
<style scoped></style> |
|||
@ -0,0 +1,65 @@ |
|||
<script setup lang="ts"> |
|||
import { computed } from 'vue'; |
|||
|
|||
import { useAbpStore } from '@abp/core'; |
|||
import { Checkbox, FormItemRest, Select } from 'ant-design-vue'; |
|||
|
|||
const emits = defineEmits(['blur', 'change']); |
|||
|
|||
const modelValue = defineModel<{ |
|||
globalFeatureNames: string[]; |
|||
requiresAll: boolean; |
|||
}>({ |
|||
default: { |
|||
globalFeatureNames: [], |
|||
requiresAll: false, |
|||
}, |
|||
}); |
|||
|
|||
const abpStore = useAbpStore(); |
|||
|
|||
const getFeatureOptions = computed(() => { |
|||
if (!abpStore.application?.globalFeatures) { |
|||
return []; |
|||
} |
|||
return abpStore.application.globalFeatures.enabledFeatures.map((feature) => { |
|||
return { |
|||
label: feature, |
|||
value: feature, |
|||
}; |
|||
}); |
|||
}); |
|||
|
|||
function onChange() { |
|||
emits('change', modelValue.value); |
|||
} |
|||
|
|||
function onFeaturesChange(value: any) { |
|||
modelValue.value.globalFeatureNames = value; |
|||
emits('change', modelValue.value); |
|||
} |
|||
</script> |
|||
|
|||
<template> |
|||
<div class="flex w-full flex-col gap-5"> |
|||
<FormItemRest> |
|||
<Checkbox |
|||
v-model:checked="modelValue.requiresAll" |
|||
@blur="emits('blur')" |
|||
@change="onChange" |
|||
> |
|||
{{ $t('component.simple_state_checking.requireFeatures.requiresAll') }} |
|||
</Checkbox> |
|||
<Select |
|||
:value="modelValue.globalFeatureNames" |
|||
:options="getFeatureOptions" |
|||
show-search |
|||
mode="tags" |
|||
@blur="emits('blur')" |
|||
@change="onFeaturesChange" |
|||
/> |
|||
</FormItemRest> |
|||
</div> |
|||
</template> |
|||
|
|||
<style scoped></style> |
|||
@ -1,3 +1,4 @@ |
|||
export { default as PermissionGroupDefinitionTable } from './definitions/groups/PermissionGroupDefinitionTable.vue'; |
|||
export { default as PermissionDefinitionTable } from './definitions/permissions/PermissionDefinitionTable.vue'; |
|||
export { default as PermissionModal } from './permissions/PermissionModal.vue'; |
|||
export { default as PermissionStateCheck } from './state-check/PermissionStateCheck.vue'; |
|||
|
|||
@ -0,0 +1,134 @@ |
|||
<script setup lang="ts"> |
|||
import type { PermissionDefinitionDto } from '../../types/definitions'; |
|||
import type { PermissionGroupDefinitionDto } from '../../types/groups'; |
|||
|
|||
import { computed, onMounted, ref } from 'vue'; |
|||
|
|||
import { |
|||
listToTree, |
|||
useLocalization, |
|||
useLocalizationSerializer, |
|||
} from '@abp/core'; |
|||
import { Checkbox, FormItemRest, TreeSelect } from 'ant-design-vue'; |
|||
|
|||
import { usePermissionDefinitionsApi } from '../../api/usePermissionDefinitionsApi'; |
|||
import { usePermissionGroupDefinitionsApi } from '../../api/usePermissionGroupDefinitionsApi'; |
|||
|
|||
interface TreeData { |
|||
checkable?: boolean; |
|||
children: TreeData[]; |
|||
displayName: string; |
|||
groupName: string; |
|||
name: string; |
|||
} |
|||
|
|||
const emits = defineEmits(['blur', 'change']); |
|||
|
|||
const { getListApi: getPermissionsApi } = usePermissionDefinitionsApi(); |
|||
const { getListApi: getPermissionGroupsApi } = |
|||
usePermissionGroupDefinitionsApi(); |
|||
const { deserialize } = useLocalizationSerializer(); |
|||
const { Lr } = useLocalization(); |
|||
|
|||
const permissions = ref<PermissionDefinitionDto[]>([]); |
|||
const permissionGroups = ref<PermissionGroupDefinitionDto[]>([]); |
|||
const modelValue = defineModel<{ |
|||
permissions: string[]; |
|||
requiresAll: boolean; |
|||
}>({ |
|||
default: { |
|||
permissions: [], |
|||
requiresAll: false, |
|||
}, |
|||
}); |
|||
const getPermissionOptions = computed(() => { |
|||
const permissionOptions: TreeData[] = []; |
|||
permissionGroups.value.forEach((group) => { |
|||
permissionOptions.push({ |
|||
checkable: false, |
|||
displayName: group.displayName, |
|||
groupName: group.name, |
|||
name: group.name, |
|||
children: listToTree( |
|||
permissions.value.filter((x) => x.groupName === group.name), |
|||
{ |
|||
id: 'name', |
|||
pid: 'parentName', |
|||
}, |
|||
), |
|||
}); |
|||
}); |
|||
return permissionOptions; |
|||
}); |
|||
const getRequiredPermissions = computed(() => { |
|||
const permissionNames = modelValue.value?.permissions ?? []; |
|||
return permissions.value |
|||
.filter((permission) => permissionNames.includes(permission.name)) |
|||
.map((permission) => { |
|||
return { |
|||
label: permission.displayName, |
|||
value: permission.name, |
|||
}; |
|||
}); |
|||
}); |
|||
|
|||
function onChange() { |
|||
emits('change', modelValue.value); |
|||
} |
|||
|
|||
function onPermissionsChange(value: any[]) { |
|||
modelValue.value.permissions = value.map((item) => item.value); |
|||
emits('change', modelValue.value); |
|||
} |
|||
|
|||
async function onInit() { |
|||
const [permissionGroupRes, permissionsRes] = await Promise.all([ |
|||
getPermissionGroupsApi(), |
|||
getPermissionsApi(), |
|||
]); |
|||
permissionGroups.value = permissionGroupRes.items.map((item) => { |
|||
const displayName = deserialize(item.displayName); |
|||
return { |
|||
...item, |
|||
displayName: Lr(displayName.resourceName, displayName.name), |
|||
}; |
|||
}); |
|||
permissions.value = permissionsRes.items.map((item) => { |
|||
const displayName = deserialize(item.displayName); |
|||
return { |
|||
...item, |
|||
displayName: Lr(displayName.resourceName, displayName.name), |
|||
}; |
|||
}); |
|||
} |
|||
|
|||
onMounted(onInit); |
|||
</script> |
|||
|
|||
<template> |
|||
<div class="flex w-full flex-col gap-5"> |
|||
<FormItemRest> |
|||
<Checkbox |
|||
v-model:checked="modelValue.requiresAll" |
|||
@blur="emits('blur')" |
|||
@change="onChange" |
|||
> |
|||
{{ |
|||
$t('component.simple_state_checking.requirePermissions.requiresAll') |
|||
}} |
|||
</Checkbox> |
|||
<TreeSelect |
|||
:tree-data="getPermissionOptions" |
|||
allow-clear |
|||
tree-checkable |
|||
tree-check-strictly |
|||
:field-names="{ label: 'displayName', value: 'name' }" |
|||
:value="getRequiredPermissions" |
|||
@blur="emits('blur')" |
|||
@change="onPermissionsChange" |
|||
/> |
|||
</FormItemRest> |
|||
</div> |
|||
</template> |
|||
|
|||
<style scoped></style> |
|||
@ -1,5 +1,6 @@ |
|||
export { default as LocalizableInput } from './localizable-input/LocalizableInput.vue'; |
|||
export { default as PropertyTable } from './properties/PropertyTable.vue'; |
|||
export * from './properties/types'; |
|||
export * from './simple-state-checking'; |
|||
export * from './string-value-type'; |
|||
export type * from './vxe-table'; |
|||
|
|||
@ -0,0 +1,265 @@ |
|||
<script setup lang="ts"> |
|||
import type { ColumnsType } from 'ant-design-vue/lib/table'; |
|||
|
|||
import type { PropType } from 'vue'; |
|||
|
|||
import type { SimplaCheckStateBase } from './interface'; |
|||
|
|||
import { computed, reactive, unref } from 'vue'; |
|||
|
|||
import { useVbenModal } from '@vben/common-ui'; |
|||
import { createIconifyIcon } from '@vben/icons'; |
|||
import { $t } from '@vben/locales'; |
|||
|
|||
import { isNullOrUnDef, useSimpleStateCheck } from '@abp/core'; |
|||
import { Button, Card, Col, Row, Table, Tag } from 'ant-design-vue'; |
|||
|
|||
import SimpleStateCheckingModal from './SimpleStateCheckingModal.vue'; |
|||
|
|||
const props = defineProps({ |
|||
allowDelete: { |
|||
default: false, |
|||
type: Boolean, |
|||
}, |
|||
allowEdit: { |
|||
default: false, |
|||
type: Boolean, |
|||
}, |
|||
disabled: { |
|||
default: false, |
|||
type: Boolean, |
|||
}, |
|||
state: { |
|||
required: true, |
|||
type: Object as PropType<SimplaCheckStateBase>, |
|||
}, |
|||
value: { |
|||
default: '', |
|||
type: String, |
|||
}, |
|||
}); |
|||
const emits = defineEmits(['change', 'update:value']); |
|||
const DeleteOutlined = createIconifyIcon('ant-design:delete-outlined'); |
|||
const EditOutlined = createIconifyIcon('ant-design:edit-outlined'); |
|||
|
|||
const simpleCheckerMap = reactive<{ [key: string]: string }>({ |
|||
A: $t('component.simple_state_checking.requireAuthenticated.title'), |
|||
F: $t('component.simple_state_checking.requireFeatures.title'), |
|||
G: $t('component.simple_state_checking.requireGlobalFeatures.title'), |
|||
P: $t('component.simple_state_checking.requirePermissions.title'), |
|||
}); |
|||
|
|||
const { deserialize, deserializeArray, serializeArray } = useSimpleStateCheck(); |
|||
|
|||
const [Modal, modalApi] = useVbenModal({ |
|||
connectedComponent: SimpleStateCheckingModal, |
|||
}); |
|||
|
|||
const getTableColumns = computed(() => { |
|||
const columns: ColumnsType = [ |
|||
{ |
|||
align: 'left', |
|||
dataIndex: 'name', |
|||
fixed: 'left', |
|||
key: 'name', |
|||
maxWidth: 150, |
|||
title: $t('component.simple_state_checking.table.name'), |
|||
}, |
|||
{ |
|||
align: 'left', |
|||
dataIndex: 'properties', |
|||
fixed: 'left', |
|||
key: 'properties', |
|||
title: $t('component.simple_state_checking.table.properties'), |
|||
}, |
|||
]; |
|||
return [ |
|||
...columns, |
|||
...(props.disabled |
|||
? [] |
|||
: [ |
|||
{ |
|||
align: 'center', |
|||
dataIndex: 'action', |
|||
fixed: 'right', |
|||
key: 'action', |
|||
title: $t('component.simple_state_checking.table.actions'), |
|||
width: 180, |
|||
}, |
|||
]), |
|||
]; |
|||
}); |
|||
const getSimpleCheckers = computed(() => { |
|||
if (isNullOrUnDef(props.value) || props.value.length === 0) { |
|||
return []; |
|||
} |
|||
const simpleCheckers = deserializeArray(props.value, props.state); |
|||
return simpleCheckers; |
|||
}); |
|||
const getStateCheckerOptions = computed(() => { |
|||
const stateCheckers = unref(getSimpleCheckers); |
|||
return Object.keys(simpleCheckerMap).map((key) => { |
|||
return { |
|||
disabled: stateCheckers.some((x) => (x as any).name === key), |
|||
label: simpleCheckerMap[key], |
|||
value: key, |
|||
}; |
|||
}); |
|||
}); |
|||
|
|||
function handleAddNew() { |
|||
modalApi.setData({ |
|||
options: getStateCheckerOptions.value, |
|||
}); |
|||
modalApi.open(); |
|||
} |
|||
|
|||
function handleEdit(record: any) { |
|||
modalApi.setData({ |
|||
options: getStateCheckerOptions.value, |
|||
record, |
|||
}); |
|||
modalApi.open(); |
|||
} |
|||
|
|||
function onChange(record: any) { |
|||
const stateChecker = deserialize(record, props.state)!; |
|||
const stateCheckers = unref(getSimpleCheckers); |
|||
const inputIndex = stateCheckers.findIndex( |
|||
(x) => (x as any).name === record.name, |
|||
); |
|||
if (inputIndex === -1) { |
|||
stateCheckers.push(stateChecker); |
|||
} else { |
|||
stateCheckers[inputIndex] = stateChecker; |
|||
} |
|||
const updateValue = serializeArray(stateCheckers); |
|||
|
|||
emits('change', updateValue); |
|||
emits('update:value', updateValue); |
|||
} |
|||
|
|||
function handleDelete(record: any) { |
|||
const stateCheckers = unref(getSimpleCheckers); |
|||
const filtedStateCheckers = stateCheckers.filter( |
|||
(x) => (x as any).name !== record.name, |
|||
); |
|||
if (filtedStateCheckers.length === 0) { |
|||
handleClean(); |
|||
return; |
|||
} |
|||
const serializedCheckers = serializeArray(filtedStateCheckers); |
|||
emits('change', serializedCheckers); |
|||
emits('update:value', serializedCheckers); |
|||
} |
|||
|
|||
function handleClean() { |
|||
emits('change', undefined); |
|||
emits('update:value', undefined); |
|||
} |
|||
</script> |
|||
|
|||
<template> |
|||
<div class="w-full"> |
|||
<div class="card"> |
|||
<Card> |
|||
<template #title> |
|||
<Row> |
|||
<Col :span="12"> |
|||
<span>{{ $t('component.simple_state_checking.title') }}</span> |
|||
</Col> |
|||
<Col :span="12"> |
|||
<div class="toolbar" v-if="!props.disabled"> |
|||
<Button type="primary" @click="handleAddNew"> |
|||
{{ $t('component.simple_state_checking.actions.create') }} |
|||
</Button> |
|||
<Button danger @click="handleClean"> |
|||
{{ $t('component.simple_state_checking.actions.clean') }} |
|||
</Button> |
|||
</div> |
|||
</Col> |
|||
</Row> |
|||
</template> |
|||
<Table :columns="getTableColumns" :data-source="getSimpleCheckers"> |
|||
<template #bodyCell="{ column, record }"> |
|||
<template v-if="column.key === 'name'"> |
|||
<span>{{ simpleCheckerMap[record.name] }}</span> |
|||
</template> |
|||
<template v-else-if="column.key === 'properties'"> |
|||
<div v-if="record.name === 'F'"> |
|||
<Tag v-for="feature in record.featureNames" :key="feature"> |
|||
{{ feature }} |
|||
</Tag> |
|||
</div> |
|||
<div v-else-if="record.name === 'G'"> |
|||
<Tag |
|||
v-for="feature in record.globalFeatureNames" |
|||
:key="feature" |
|||
> |
|||
{{ feature }} |
|||
</Tag> |
|||
</div> |
|||
<div v-else-if="record.name === 'P'"> |
|||
<Tag |
|||
v-for="permission in record.model.permissions" |
|||
:key="permission" |
|||
> |
|||
{{ permission }} |
|||
</Tag> |
|||
</div> |
|||
<div v-else-if="record.name === 'A'"> |
|||
<span>{{ |
|||
$t( |
|||
'component.simple_state_checking.requireAuthenticated.title', |
|||
) |
|||
}}</span> |
|||
</div> |
|||
</template> |
|||
<template v-else-if="column.key === 'action'"> |
|||
<div class="flex flex-row"> |
|||
<Button |
|||
v-if="props.allowEdit" |
|||
type="link" |
|||
@click="() => handleEdit(record)" |
|||
> |
|||
<template #icon> |
|||
<EditOutlined /> |
|||
</template> |
|||
{{ $t('component.simple_state_checking.actions.update') }} |
|||
</Button> |
|||
<Button |
|||
v-if="props.allowDelete" |
|||
type="link" |
|||
@click="() => handleDelete(record)" |
|||
danger |
|||
> |
|||
<template #icon> |
|||
<DeleteOutlined /> |
|||
</template> |
|||
{{ $t('component.simple_state_checking.actions.delete') }} |
|||
</Button> |
|||
</div> |
|||
</template> |
|||
</template> |
|||
</Table> |
|||
</Card> |
|||
</div> |
|||
</div> |
|||
<Modal @change="onChange" /> |
|||
</template> |
|||
|
|||
<style lang="less" scoped> |
|||
.card { |
|||
.toolbar { |
|||
flex: 1; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: flex-end; |
|||
margin-bottom: 8px; |
|||
|
|||
> * { |
|||
margin-right: 8px; |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,231 @@ |
|||
<script setup lang="ts"> |
|||
import { toRaw } from 'vue'; |
|||
|
|||
import { useVbenForm, useVbenModal, z } from '@vben/common-ui'; |
|||
import { $t } from '@vben/locales'; |
|||
|
|||
interface ModalState { |
|||
options: { disabled?: boolean; label: string; value: string }[]; |
|||
record: any; |
|||
} |
|||
|
|||
const emits = defineEmits(['change']); |
|||
const [Modal, modalApi] = useVbenModal({ |
|||
closeOnClickModal: false, |
|||
closeOnPressEscape: false, |
|||
onConfirm: onSubmit, |
|||
onOpenChange(isOpen) { |
|||
if (isOpen) { |
|||
onInit(); |
|||
} |
|||
}, |
|||
}); |
|||
|
|||
const [Form, formApi] = useVbenForm({ |
|||
schema: [ |
|||
{ |
|||
component: 'Select', |
|||
fieldName: 'name', |
|||
label: $t('component.simple_state_checking.form.name'), |
|||
rules: 'selectRequired', |
|||
}, |
|||
{ |
|||
component: 'Empty', |
|||
disabledOnChangeListener: false, |
|||
fieldName: 'value', |
|||
label: '', |
|||
}, |
|||
], |
|||
showDefaultActions: false, |
|||
}); |
|||
|
|||
async function onInit() { |
|||
const state = modalApi.getData<ModalState>(); |
|||
formApi.updateSchema([ |
|||
{ |
|||
componentProps: { |
|||
disabled: !!state.record, |
|||
onChange, |
|||
options: state.options, |
|||
}, |
|||
fieldName: 'name', |
|||
}, |
|||
{ |
|||
component: 'Empty', |
|||
fieldName: 'value', |
|||
label: '', |
|||
rules: z.object({}).optional(), |
|||
}, |
|||
]); |
|||
formApi.setValues({ |
|||
name: state.record?.name, |
|||
value: {}, |
|||
}); |
|||
if (state.record) { |
|||
onRecordChange(state.record); |
|||
} |
|||
} |
|||
|
|||
async function onRecordChange(record: any) { |
|||
await formApi.setFieldValue('name', record.name); |
|||
onChange(record.name); |
|||
switch (record.name) { |
|||
case 'F': { |
|||
await formApi.setFieldValue('value', { |
|||
featureNames: record.featureNames, |
|||
requiresAll: record.requiresAll, |
|||
}); |
|||
break; |
|||
} |
|||
case 'G': { |
|||
await formApi.setFieldValue('value', { |
|||
globalFeatureNames: record.globalFeatureNames, |
|||
requiresAll: record.requiresAll, |
|||
}); |
|||
break; |
|||
} |
|||
case 'P': { |
|||
await formApi.setFieldValue('value', { |
|||
permissions: record.permissions, |
|||
requiresAll: record.requiresAll, |
|||
}); |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
|
|||
function onChange(value: string) { |
|||
formApi.updateSchema([ |
|||
{ |
|||
component: 'Empty', |
|||
controlClass: '', |
|||
fieldName: 'value', |
|||
label: '', |
|||
rules: z.object({}).optional(), |
|||
}, |
|||
]); |
|||
formApi.setFieldValue('value', {}); |
|||
switch (value) { |
|||
case 'A': { |
|||
formApi.updateSchema([ |
|||
{ |
|||
controlClass: 'invisible', |
|||
fieldName: 'value', |
|||
}, |
|||
]); |
|||
break; |
|||
} |
|||
case 'F': { |
|||
formApi.updateSchema([ |
|||
{ |
|||
component: 'FeatureStateCheck', |
|||
fieldName: 'value', |
|||
label: $t( |
|||
'component.simple_state_checking.requireFeatures.featureNames', |
|||
), |
|||
// TODO: vben应该做到用户能自定义验证器, 在组件的适配器中而不是单独使用时 |
|||
rules: z |
|||
.object({ |
|||
featureNames: z.array(z.string()), |
|||
requiresAll: z.boolean().optional(), |
|||
}) |
|||
.refine((v) => v.featureNames.length > 0, { |
|||
message: `${$t('ui.placeholder.select')}${$t('component.simple_state_checking.requireFeatures.featureNames')}`, |
|||
}), |
|||
}, |
|||
]); |
|||
formApi.setFieldValue('value', { |
|||
featureNames: [], |
|||
requiresAll: false, |
|||
}); |
|||
break; |
|||
} |
|||
case 'G': { |
|||
formApi.updateSchema([ |
|||
{ |
|||
component: 'GlobalFeatureStateCheck', |
|||
fieldName: 'value', |
|||
label: $t( |
|||
'component.simple_state_checking.requireFeatures.featureNames', |
|||
), |
|||
// TODO: vben应该做到用户能自定义验证器, 在组件的适配器中而不是单独使用时 |
|||
rules: z |
|||
.object({ |
|||
globalFeatureNames: z.array(z.string()), |
|||
requiresAll: z.boolean().optional(), |
|||
}) |
|||
.refine((v) => v.globalFeatureNames.length > 0, { |
|||
message: `${$t('ui.placeholder.select')}${$t('component.simple_state_checking.requireFeatures.featureNames')}`, |
|||
}), |
|||
}, |
|||
]); |
|||
formApi.setFieldValue('value', { |
|||
globalFeatureNames: [], |
|||
requiresAll: false, |
|||
}); |
|||
break; |
|||
} |
|||
case 'P': { |
|||
formApi.updateSchema([ |
|||
{ |
|||
component: 'PermissionStateCheck', |
|||
fieldName: 'value', |
|||
label: $t( |
|||
'component.simple_state_checking.requirePermissions.permissions', |
|||
), |
|||
// TODO: vben应该做到用户能自定义验证器, 在组件的适配器中而不是单独使用时 |
|||
rules: z |
|||
.object({ |
|||
permissions: z.array(z.string()), |
|||
requiresAll: z.boolean().optional(), |
|||
}) |
|||
.refine((v) => v.permissions.length > 0, { |
|||
message: `${$t('ui.placeholder.select')}${$t('component.simple_state_checking.requirePermissions.permissions')}`, |
|||
}), |
|||
}, |
|||
]); |
|||
formApi.setFieldValue('value', { |
|||
permissions: [], |
|||
requiresAll: false, |
|||
}); |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
|
|||
async function onSubmit() { |
|||
const result = await formApi.validate(); |
|||
if (result.valid) { |
|||
const values = await formApi.getValues(); |
|||
const value = toRaw(values.value); |
|||
const stateChecker: { [key: string]: any } = { |
|||
A: value.requiresAll, |
|||
T: values.name, |
|||
}; |
|||
switch (values.name) { |
|||
case 'F': { |
|||
stateChecker.N = value.featureNames; |
|||
break; |
|||
} |
|||
case 'G': { |
|||
stateChecker.N = value.globalFeatureNames; |
|||
break; |
|||
} |
|||
case 'P': { |
|||
stateChecker.N = value.permissions; |
|||
break; |
|||
} |
|||
} |
|||
emits('change', stateChecker); |
|||
modalApi.close(); |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<template> |
|||
<Modal :title="$t('component.simple_state_checking.title')"> |
|||
<Form /> |
|||
</Modal> |
|||
</template> |
|||
|
|||
<style scoped></style> |
|||
@ -0,0 +1,2 @@ |
|||
export * from './interface'; |
|||
export { default as SimpleStateChecking } from './SimpleStateChecking.vue'; |
|||
@ -0,0 +1,6 @@ |
|||
import type { IHasSimpleStateCheckers, ISimpleStateChecker } from '@abp/core'; |
|||
|
|||
export interface SimplaCheckStateBase |
|||
extends IHasSimpleStateCheckers<SimplaCheckStateBase> { |
|||
stateCheckers: ISimpleStateChecker<SimplaCheckStateBase>[]; |
|||
} |
|||
Loading…
Reference in new issue