Действия с записями¶
Метод, вызываемый после публикации черновика записи¶
Точка расширения UEAfterPublishRecord позволяет вызывать функции после публикации черновика записи.
Описание UEAfterPublishRecord:
export type UEAfterPublishRecord<T extends IRecordEntity> = UeModuleBase & {
default: {
fn: (dataCardStore: AbstractCardStore<T>) => void;
resolver: (dataCardStore: AbstractCardStore<T>) => boolean;
};
}
Пример UEAfterPublishRecord: дополнительное сообщение, если настроен процесс согласования при публикации записи.
function afterPublish () {
Dialog.showMessage(i18n.t('module.workflow>dataCardAfterPublish>message'));
}
export const afterPublishRecordUe: UEAfterPublishRecord<any> = {
'default': {
type: UEList.AfterPublishRecord,
moduleId: 'afterPublishWorkflow',
active: true,
system: false,
fn: afterPublish,
resolver: (store: AbstractCardStore<any>) => {
return store.draftStore?.selectedDraft?.state.getValue() === 'DELAYED_BY_WORKFLOW';
},
meta: {}
}
};
Метод, вызываемый после публикации c ошибкой¶
Точка расширения UEAfterPublishRecordFailure позволяет вызывать функции после публикации черновика записи с ошибкой.
Описание UEAfterPublishRecordFailure:
export type UEAfterPublishRecordFailure<T extends IRecordEntity> = UeModuleBase & {
default: {
fn: (dataCardStore: AbstractCardStore<T>, errors: ServerDetailsError[]) => void;
resolver: (dataCardStore: AbstractCardStore<T>, errors: ServerDetailsError[]) => boolean;
};
}
Клонирование записи¶
Точка расширения UECloneRecord предназначена для добавления фрагмента к запросу на клонирование записи, а также для вывода в окне настроек клонирования интерфейса (для изменения передаваемых во фрагменте параметров).
Используемые типы:
interface ICloneInnerStore<T extends keyof UniverseUE.ICloneAtomicPayload> {
/*
* Возвращаемый фрагмент запроса на клонирование и ключ, под которым он будет добавлен в запрос, должны быть
* глобально объявлены в пространстве имен UniverseUE
*/
payloadContent: {
key: T;
content: UniverseUE.ICloneAtomicPayload[T];
};
/*
* Возвращает true, если нужно запретить подтверждение клонирования записи
*/
readonly hasErrors: boolean;
}
/*
* Передаваемые в компонент параметров пропсы
*/
interface ICloneRecordParametersProps {
store: CloneStore;
}
type UECloneRecordResolver = (cloneStore: CloneStore) => boolean;
type UECloneRecordMeta = {
/*
* @param key - передается meta.key текущего User Exit
*/
getStore: (cloneStore: CloneStore, key: string) => ICloneInnerStore;
key: string;
};
export type UECloneRecord = UeModuleBase<UECloneRecordResolver, UECloneRecordMeta> & {
component: ComponentType<ICloneRecordParametersProps>;
};
Пример UECloneRecord:
const CLONE_RECORD_ADDITIONAL_PAYLOAD_KEY = 'clone_record_additional_fragment_v1' as const;
interface ICloneRecordAdditionalPayload {
cleanUnique: boolean;
}
declare global {
namespace UniverseUE {
export interface ICloneAtomicPayload {
[CLONE_RECORD_ADDITIONAL_PAYLOAD_KEY]: ICloneRecordAdditionalPayload;
}
}
}
class CloneRecordAdditionalFragmentStore implements ICloneInnerStore {
@observable
cleanUnique: boolean;
@action
setCleanUnique (cleanUnique: boolean) {
this.cleanUnique = cleanUnique;
}
get payloadContent () {
return {
key: CLONE_RECORD_ADDITIONAL_PAYLOAD_KEY,
content: {
cleanUnique: this.cleanUnique
}
}
}
get hasErrors () {
return false;
}
}
@observer
class CloneRecordUserExit extends React.Component<ICloneRecordParametersProps> {
get store () {
return this.props.store.getStore(CLONE_RECORD_ADDITIONAL_PAYLOAD_KEY) as CloneRecordAdditionalFragmentStore;
}
override render () {
const {store} = this;
return (
<CardPanel
internal={true}
title={'Дополнительные параметры клонирования'}>
<Field.Checkbox
label={'Очистить уникальные значения?'}
defaultChecked={store.cleanUnique}
onChange={(name, value) => store.setCleanUnique(value)}
/>
</CardPanel>
);
}
}
ueModuleManager.addModule('CloneRecord', {
active: true,
component: CloneRecordUserExit,
meta: {
key: CLONE_RECORD_ADDITIONAL_PAYLOAD_KEY,
getStore: () => {
return new CloneRecordAdditionalFragmentStore();
}
},
moduleId: CLONE_RECORD_ADDITIONAL_PAYLOAD_KEY,
resolver: (cloneStore: CloneStore) => {
const dataRecordInnerStore = cloneStore.dataCardStore.getInnerStore('data-record-additional-store');
return dataRecordInnerStore !== undefined;
},
system: false
});
Рисунок 1 - Модальное окно клонирования записи
Расширенный поиск атрибута "Ссылка на справочник"¶
Точка расширения LookupExtendedSearchEnabled используется для активации и деактивации расширенного поиска по атрибутам типа "Ссылка на справочник".
User exit влияет на отображение расширенного поиска в карточке записи (кнопка "Расширенный поиск" при выборе значения атрибута) и в окне поиска записей типа актива.
Для того чтобы активировать расширенный поиск, необходимо добавить этот модуль в проект. Если модуль уже добавлен, а от расширенного поиска необходимо отказаться, то модуль нужно отключить.
По аналогии был создан User exit HierarchyLookupExtendedSearchEnabled для иерархических атрибутов типа "Ссылка на справочник".
Описание LookupExtendedSearchEnabled:
import {DefaultUeResolver, UeModuleBase} from '@universe-platform/user-exit';
export type UEHierarchyLookupExtendedSearchEnabled = UeModuleBase<DefaultUeResolver, {}>
Добавление доп. вкладки в модель типов активов/справочников¶
Точка расширения UEMetaModelTab предназначена для добавления вкладок в модели типов активов/справочников.
Можно расширять существующую модель через CustomProperties или показывать дополнительную информацию по связанным сущностям.
Описание UEMetaModelTab:
type TabDisabledConfig = {
isDisabled: boolean;
disableReasons?: string[];
}
export type UEMetaModelTab = UeModuleBase & {
default: {
component: ComponentType<{
attributesStore: AttributesStore;
metaModel: IMetaModel;
draftId?: DraftId;
}>; // Компонент для рендеринга, если выбрана текущая вкладка
meta: {
name: string; // Ключ вкладки
getDisplayName: () => string; // Заголовок вкладки
getTabDisabledConfig?: (metaModel: IMetaModel) => TabDisabledConfig; // Функция проверки отключения вкладки и получения причин отключения
};
resolver: (metaModel: IMetaModel) => boolean;
};
}
Пример UEMetaModelTab: вкладка "Внешний вид".
export const metaModelTabs: UEMetaModelTab[] = [
{
'default': {
type: UEList.MetaModelTab,
moduleId: 'dataCardLayoutTab',
active: true,
system: false,
meta: {
name: 'layout',
getDisplayName: () => {
return i18n.t('module.meta-se>layoutTab');
},
getTabDisabledConfig: (metaModel: IMetaModel) => {
const hasPhantomAttribute = metaModel.getAttributes()
.some((attribute) => {
return attribute.getPhantom();
});
return {
isDisabled: hasPhantomAttribute,
disableReasons: [
i18n.t('module.meta-se>tabDisableReason')
]
};
}
},
resolver: (metaModel: IMetaModel) => {
return metaModel ? (MetaDataTypeGuards.isEntity(metaModel) || MetaDataTypeGuards.isLookupEntity(metaModel)) : false;
},
component: EntityLayoutTab
}
}
];