Showing
55 changed files
with
2186 additions
and
256 deletions
| 1 | -import { DeviceInfoItemType } from './model'; | 1 | +import { DeviceInfoItemType, DeviceTypeItem } from './model'; |
| 2 | import { TBPaginationResult } from '/#/axios'; | 2 | import { TBPaginationResult } from '/#/axios'; |
| 3 | import { defHttp } from '/@/utils/http/axios'; | 3 | import { defHttp } from '/@/utils/http/axios'; |
| 4 | 4 | ||
| 5 | enum Api { | 5 | enum Api { |
| 6 | GET_DEVICE_INFOS = '/tenant/deviceInfos', | 6 | GET_DEVICE_INFOS = '/tenant/deviceInfos', |
| 7 | + GET_DEVICE_TYPE = '/device/types', | ||
| 7 | } | 8 | } |
| 8 | 9 | ||
| 9 | export const getDeviceInfos = () => { | 10 | export const getDeviceInfos = () => { |
| @@ -14,3 +15,12 @@ export const getDeviceInfos = () => { | @@ -14,3 +15,12 @@ export const getDeviceInfos = () => { | ||
| 14 | { joinPrefix: false } | 15 | { joinPrefix: false } |
| 15 | ); | 16 | ); |
| 16 | }; | 17 | }; |
| 18 | + | ||
| 19 | +export const getDeviceTypes = () => { | ||
| 20 | + return defHttp.get<TBPaginationResult<DeviceTypeItem[]>>( | ||
| 21 | + { | ||
| 22 | + url: Api.GET_DEVICE_TYPE, | ||
| 23 | + }, | ||
| 24 | + { joinPrefix: false } | ||
| 25 | + ); | ||
| 26 | +}; |
| @@ -38,3 +38,9 @@ export interface Configuration { | @@ -38,3 +38,9 @@ export interface Configuration { | ||
| 38 | export interface TransportConfiguration { | 38 | export interface TransportConfiguration { |
| 39 | type: string; | 39 | type: string; |
| 40 | } | 40 | } |
| 41 | + | ||
| 42 | +export interface DeviceTypeItem { | ||
| 43 | + tenantId: Id; | ||
| 44 | + entityType: string; | ||
| 45 | + type: string; | ||
| 46 | +} |
| @@ -132,4 +132,7 @@ export type ComponentType = | @@ -132,4 +132,7 @@ export type ComponentType = | ||
| 132 | | 'OrgTreeSelect' | 132 | | 'OrgTreeSelect' |
| 133 | | 'ExtendDesc' | 133 | | 'ExtendDesc' |
| 134 | | 'JavaScriptFunctionEditor' | 134 | | 'JavaScriptFunctionEditor' |
| 135 | - | 'JavaScriptFilterFunctionModal'; | 135 | + | 'JavascriptEditorWithTestModal' |
| 136 | + | 'AttributeConfiguration' | ||
| 137 | + | 'CorrelationFilters' | ||
| 138 | + | 'RelationsQuery'; |
| @@ -14,8 +14,13 @@ export enum DirectionNameEnum { | @@ -14,8 +14,13 @@ export enum DirectionNameEnum { | ||
| 14 | * @description 关联类型 | 14 | * @description 关联类型 |
| 15 | */ | 15 | */ |
| 16 | export enum RelationTypeEnum { | 16 | export enum RelationTypeEnum { |
| 17 | - CONTAINS = 'contains', | ||
| 18 | - MANAGES = 'manages', | 17 | + CONTAINS = 'CONTAINS', |
| 18 | + MANAGES = 'MANAGES', | ||
| 19 | +} | ||
| 20 | + | ||
| 21 | +export enum RelationTypeNameEnum { | ||
| 22 | + CONTAINS = 'Contains', | ||
| 23 | + MANAGES = 'Manages', | ||
| 19 | } | 24 | } |
| 20 | 25 | ||
| 21 | /** | 26 | /** |
| @@ -119,3 +124,107 @@ export enum MessageTypesFilterNameEnum { | @@ -119,3 +124,107 @@ export enum MessageTypesFilterNameEnum { | ||
| 119 | RPC_TIMEOUT = 'RPC Timeout', | 124 | RPC_TIMEOUT = 'RPC Timeout', |
| 120 | RPC_FAILED = 'RPC Failed', | 125 | RPC_FAILED = 'RPC Failed', |
| 121 | } | 126 | } |
| 127 | + | ||
| 128 | +// Enrichment Customer details | ||
| 129 | +export enum DetailsListEnum { | ||
| 130 | + TITLE = 'TITLE', | ||
| 131 | + COUNTRY = 'COUNTRY', | ||
| 132 | + STATE = 'STATE', | ||
| 133 | + CITY = 'CITY', | ||
| 134 | + ZIP = 'ZIP', | ||
| 135 | + ADDRESS = 'ADDRESS', | ||
| 136 | + ADDRESS_2 = 'ADDRESS_2', | ||
| 137 | + PHONE = 'PHONE', | ||
| 138 | + EMAIL = 'EMAIL', | ||
| 139 | + ADDITIONAL_INFO = 'ADDITIONAL_INFO', | ||
| 140 | +} | ||
| 141 | + | ||
| 142 | +export enum DetailsListNameEnum { | ||
| 143 | + TITLE = 'Title', | ||
| 144 | + COUNTRY = 'Country', | ||
| 145 | + STATE = 'State', | ||
| 146 | + CITY = 'City', | ||
| 147 | + ZIP = 'Zip', | ||
| 148 | + ADDRESS = 'Address', | ||
| 149 | + ADDRESS_2 = 'Address2', | ||
| 150 | + PHONE = 'Phone', | ||
| 151 | + EMAIL = 'Email', | ||
| 152 | + ADDITIONAL_INFO = 'Additional Info', | ||
| 153 | +} | ||
| 154 | + | ||
| 155 | +// Enrichment Originator Telemetry FetchMode | ||
| 156 | +export enum FetchModeEnum { | ||
| 157 | + FIRST = 'FIRST', | ||
| 158 | + LAST = 'LAST', | ||
| 159 | + ALL = 'ALL', | ||
| 160 | +} | ||
| 161 | + | ||
| 162 | +// Enrichment Originator Telemetry Time interval unit | ||
| 163 | +export enum TimeIntervalUnitEnum { | ||
| 164 | + MILLISECONDS = 'MILLISECONDS', | ||
| 165 | + SECONDS = 'SECONDS', | ||
| 166 | + MINUTES = 'MINUTES', | ||
| 167 | + HOURS = 'HOURS', | ||
| 168 | + DAYS = 'DAYS', | ||
| 169 | +} | ||
| 170 | + | ||
| 171 | +export enum TimeIntervalUnitNameEnum { | ||
| 172 | + MILLISECONDS = 'Milliseconds', | ||
| 173 | + SECONDS = 'Seconds', | ||
| 174 | + MINUTES = 'Minutes', | ||
| 175 | + HOURS = 'Hours', | ||
| 176 | + DAYS = 'Days', | ||
| 177 | +} | ||
| 178 | + | ||
| 179 | +// Enrichment Originator Telemetry OrderBy | ||
| 180 | +export enum OrderByEnum { | ||
| 181 | + DESC = 'DESC', | ||
| 182 | + ASC = 'ASC', | ||
| 183 | +} | ||
| 184 | + | ||
| 185 | +// Enrichment Originator Telemetry Aggregation | ||
| 186 | +export enum AggregationEnum { | ||
| 187 | + MIN = 'MIN', | ||
| 188 | + MAX = 'MAX', | ||
| 189 | + AVG = 'AVG', | ||
| 190 | + SUM = 'SUM', | ||
| 191 | + COUNT = 'COUNT', | ||
| 192 | + NONE = 'NONE', | ||
| 193 | +} | ||
| 194 | + | ||
| 195 | +export enum AggregationNameEnum { | ||
| 196 | + MIN = '最少值', | ||
| 197 | + MAX = '最大值', | ||
| 198 | + AVG = '平均值', | ||
| 199 | + SUM = '求和', | ||
| 200 | + COUNT = '计数', | ||
| 201 | + NONE = '空', | ||
| 202 | +} | ||
| 203 | + | ||
| 204 | +// Originator source | ||
| 205 | +export enum OriginatorSourceEnum { | ||
| 206 | + CUSTOMER = 'CUSTOMER', | ||
| 207 | + TENANT = 'TENANT', | ||
| 208 | + RELATED = 'RELATED', | ||
| 209 | + ALARM_ORIGINATOR = 'ALARM_ORIGINATOR', | ||
| 210 | +} | ||
| 211 | + | ||
| 212 | +export enum OriginatorSourceNameEnum { | ||
| 213 | + CUSTOMER = 'Customer', | ||
| 214 | + TENANT = 'Tenant', | ||
| 215 | + RELATED = 'Related', | ||
| 216 | + ALARM_ORIGINATOR = 'Alarm Originator', | ||
| 217 | +} | ||
| 218 | + | ||
| 219 | +// Transformation To Email | ||
| 220 | +export enum MailBodyTypeEnum { | ||
| 221 | + DYNAMIC = 'dynamic', | ||
| 222 | + HTML = 'true', | ||
| 223 | + PLAIN_TEXT = 'false', | ||
| 224 | +} | ||
| 225 | + | ||
| 226 | +export enum MailBodyTypeNameEnum { | ||
| 227 | + DYNAMIC = 'Dynamic', | ||
| 228 | + HTML = 'HTML', | ||
| 229 | + PLAIN_TEXT = 'Plain Text', | ||
| 230 | +} |
| 1 | +// Assign to customer | ||
| 2 | +export enum AssignToCustomerFieldsEnum { | ||
| 3 | + CUSTOMER_NAME_PATTERN = 'customerNamePattern', | ||
| 4 | + CREATE_CUSTOMER_IF_NOT_EXISTS = 'createCustomerIfNotExists', | ||
| 5 | + CUSTOMER_CACHE_EXPIRATION = 'customerCacheExpiration', | ||
| 6 | +} | ||
| 7 | + | ||
| 8 | +export enum AssignToCustomerFieldsNameEnum { | ||
| 9 | + CUSTOMER_NAME_PATTERN = 'Customer name pattern', | ||
| 10 | + CREATE_CUSTOMER_IF_NOT_EXISTS = 'Create new customer if not exists', | ||
| 11 | + CUSTOMER_CACHE_EXPIRATION = 'Customers cache expiration time(sec)', | ||
| 12 | +} | ||
| 13 | + | ||
| 14 | +// clear alarm | ||
| 15 | +export enum ClearAlarmFieldsEnum { | ||
| 16 | + ALARM_TYPE = 'alarmType', | ||
| 17 | + ALARM_DETAILS_BUILD_JS = 'alarmDetailsBuildJs', | ||
| 18 | +} | ||
| 19 | + | ||
| 20 | +export enum ClearAlarmFieldsNameEnum { | ||
| 21 | + ALARM_TYPE = 'Alarm type', | ||
| 22 | + ALARM_DETAILS_BUILD_JS = 'Alarm details builder', | ||
| 23 | +} | ||
| 24 | + | ||
| 25 | +// Create alarm | ||
| 26 | +export enum CreateAlarmFieldsEnum { | ||
| 27 | + ALARM_DETAILS_BUILD_JS = 'alarmDetailsBuildJs', | ||
| 28 | + USE_MESSAGE_ALARM_DATA = 'useMessageAlarmData', | ||
| 29 | + OVERWRITE_ALARM_DETAILS = 'overwriteAlarmDetails', | ||
| 30 | + ALARM_TYPE = 'alarmType', | ||
| 31 | + SEVERITY = 'severity', | ||
| 32 | + PROPAGATE = 'propagate', | ||
| 33 | + RELATION_TYPES = 'relationTypes', | ||
| 34 | + PROPAGATE_TO_OWNER = 'propagateToOwner', | ||
| 35 | + PROPAGATE_TO_TENANT = 'propagateToTenant', | ||
| 36 | + DYNAMIC_SEVERITY = 'dynamicSeverity', | ||
| 37 | +} | ||
| 38 | + | ||
| 39 | +export enum CreateAlarmFieldsNameEnum { | ||
| 40 | + ALARM_DETAILS_BUILD_JS = 'Alarm details builder', | ||
| 41 | + USE_MESSAGE_ALARM_DATA = 'Use message alarm data', | ||
| 42 | + OVERWRITE_ALARM_DETAILS = 'overwriteAlarmDetails', | ||
| 43 | + ALARM_TYPE = 'Alarm type', | ||
| 44 | + SEVERITY = 'Alarm severity pattern', | ||
| 45 | + PROPAGATE = 'Propagate alarm to related entities', | ||
| 46 | + RELATION_TYPES = 'Relation types to propagate', | ||
| 47 | + PROPAGATE_TO_OWNER = 'Propagate alarm to entity owner (Customer or Tenant)', | ||
| 48 | + PROPAGATE_TO_TENANT = 'Propagate alarm to Tenant', | ||
| 49 | + DYNAMIC_SEVERITY = 'dynamicSeverity', | ||
| 50 | +} |
| 1 | +export enum CommonFieldsEnum { | ||
| 2 | + NAME = 'name', | ||
| 3 | + DESCRIPTION = 'description', | ||
| 4 | + DEBUG_MODE = 'debugMode', | ||
| 5 | +} | ||
| 6 | + | ||
| 7 | +export enum CommonFieldsNameEnum { | ||
| 8 | + NAME = '名称', | ||
| 9 | + DESCRIPTION = '说明', | ||
| 10 | + DEBUG_MODE = '调试模式', | ||
| 11 | +} | ||
| 12 | + | ||
| 13 | +export const CommonFields = { ...CommonFieldsEnum }; | ||
| 14 | +export const CommonFieldsName = { ...CommonFieldsNameEnum }; | ||
| 15 | +export type CommonFieldsType = typeof CommonFields; |
| 1 | +// Enrichment Calculate delta | ||
| 2 | +export enum CalculateDeltaFieldsEnum { | ||
| 3 | + INPUT_VALUE_KEY = 'inputValueKey', | ||
| 4 | + OUTPUT_VALUE_KEY = 'outputValueKey', | ||
| 5 | + ROUND = 'round', | ||
| 6 | + USE_CACHE = 'useCache', | ||
| 7 | + TELL_FAILURE_IF_DELTA_IS_NEGATIVE = 'tellFailureIfDeltaIsNegative', | ||
| 8 | + ADD_PERIOD_BETWEEN_MSGS = 'addPeriodBetweenMsgs', | ||
| 9 | + PERIOD_VALUE_KEY = 'periodValueKey', | ||
| 10 | +} | ||
| 11 | + | ||
| 12 | +export enum CalculateDeltaFieldsNameEnum { | ||
| 13 | + INPUT_VALUE_KEY = 'Input value key', | ||
| 14 | + OUTPUT_VALUE_KEY = 'Output value key', | ||
| 15 | + ROUND = 'Decimals', | ||
| 16 | + USE_CACHE = 'Use cache for latest value', | ||
| 17 | + TELL_FAILURE_IF_DELTA_IS_NEGATIVE = 'Tell Failure if delta is negative', | ||
| 18 | + ADD_PERIOD_BETWEEN_MSGS = 'Add period between messages', | ||
| 19 | + PERIOD_VALUE_KEY = 'Period value key', | ||
| 20 | +} | ||
| 21 | + | ||
| 22 | +// Enrichment Customer Attributes | ||
| 23 | +export enum CustomerAttributesFieldsEnum { | ||
| 24 | + ATTR_MAPING = 'attrMapping', | ||
| 25 | + TELEMETRY = 'telemetry', | ||
| 26 | +} | ||
| 27 | + | ||
| 28 | +export enum CustomerAttributesFieldsNameEnum { | ||
| 29 | + ATTR_MAPING = 'Attributes mapping', | ||
| 30 | + TELEMETRY = 'Latest telemetry', | ||
| 31 | +} | ||
| 32 | + | ||
| 33 | +// Enrichment Customer details | ||
| 34 | +export enum CustomerDetailsFieldsEnum { | ||
| 35 | + DETAILS_LIST = 'detailsList', | ||
| 36 | + ADD_TO_METADATA = 'addToMetadata', | ||
| 37 | +} | ||
| 38 | + | ||
| 39 | +export enum CustomerDetailsFieldsNameEnum { | ||
| 40 | + DETAILS_LIST = 'Select entity details', | ||
| 41 | + ADD_TO_METADATA = 'Add selected details to message metadata', | ||
| 42 | +} | ||
| 43 | + | ||
| 44 | +// Enrichment Originator attributes | ||
| 45 | +export enum OriginatorAttributesEnum { | ||
| 46 | + TELL_FAILURE_IF_ABSENT = 'tellFailureIfAbsent', | ||
| 47 | + CLIENT_ATTRIBUTE_NAMES = 'clientAttributeNames', | ||
| 48 | + SHARED_ATTRIBUTE_NAMES = 'sharedAttributeNames', | ||
| 49 | + SERVER_ATTRIBUTE_NAMES = 'serverAttributeNames', | ||
| 50 | + LATEST_TS_KEY_NAMES = 'latestTsKeyNames', | ||
| 51 | + GET_LATEST_VALUE_WITH_TS = 'getLatestValueWithTs', | ||
| 52 | +} | ||
| 53 | + | ||
| 54 | +export enum OriginatorAttributesNameEnum { | ||
| 55 | + TELL_FAILURE_IF_ABSENT = 'Tell Failure', | ||
| 56 | + CLIENT_ATTRIBUTE_NAMES = 'Client attributes', | ||
| 57 | + SHARED_ATTRIBUTE_NAMES = 'Shared attributes', | ||
| 58 | + SERVER_ATTRIBUTE_NAMES = 'Server attributes', | ||
| 59 | + LATEST_TS_KEY_NAMES = 'Latest timeseries', | ||
| 60 | + GET_LATEST_VALUE_WITH_TS = 'Fetch Latest telemetry with Timestamp', | ||
| 61 | +} | ||
| 62 | + | ||
| 63 | +// Enrichment Originator Fields | ||
| 64 | +export enum OriginatorFieldsEnum { | ||
| 65 | + FIELDS_MAPPING = 'fieldsMapping', | ||
| 66 | +} | ||
| 67 | + | ||
| 68 | +export enum OriginatorFieldsNameEnum { | ||
| 69 | + FIELDS_MAPPING = 'Fields mapping', | ||
| 70 | +} | ||
| 71 | + | ||
| 72 | +// Enrichment originator telemetry | ||
| 73 | +export enum OriginatorTelemetryFieldsEnum { | ||
| 74 | + AGGREGATION = 'aggregation', | ||
| 75 | + FETCH_MODE = 'fetchMode', | ||
| 76 | + ORDER_BY = 'orderBy', | ||
| 77 | + LIMIT = 'limit', | ||
| 78 | + USE_METADATA_INTERVAL_PATTERNS = 'useMetadataIntervalPatterns', | ||
| 79 | + START_INTERVAL = 'startInterval', | ||
| 80 | + START_INTERVAL_TIME_UNIT = 'startIntervalTimeUnit', | ||
| 81 | + END_INTERVAL = 'endInterval', | ||
| 82 | + END_INTERVAL_TIME_UNIT = 'endIntervalTimeUnit', | ||
| 83 | + START_INTERVAL_PATTERN = 'startIntervalPattern', | ||
| 84 | + END_INTERVAL_PATTERN = 'endIntervalPattern', | ||
| 85 | +} | ||
| 86 | + | ||
| 87 | +export enum OriginatorTelemetryFieldsNameEnum { | ||
| 88 | + AGGREGATION = '数据聚合功能', | ||
| 89 | + FETCH_MODE = 'Fetch Mode', | ||
| 90 | + ORDER_BY = 'Order by', | ||
| 91 | + LIMIT = 'Limit', | ||
| 92 | + USE_METADATA_INTERVAL_PATTERNS = 'useMetadataIntervalPatterns', | ||
| 93 | + START_INTERVAL = 'Start Interval', | ||
| 94 | + START_INTERVAL_TIME_UNIT = 'Start Interval Time Unit', | ||
| 95 | + END_INTERVAL = 'End Interval', | ||
| 96 | + END_INTERVAL_TIME_UNIT = 'End Interval Time Unit', | ||
| 97 | + START_INTERVAL_PATTERN = 'startIntervalPattern', | ||
| 98 | + END_INTERVAL_PATTERN = 'endIntervalPattern', | ||
| 99 | +} | ||
| 100 | + | ||
| 101 | +// Enrichment Related attributes | ||
| 102 | +export enum RelatedAttributesFieldsEnum { | ||
| 103 | + RELATIONS_QUERY = 'relationsQuery', | ||
| 104 | + ATTR_MAPPING = 'attrMapping', | ||
| 105 | +} | ||
| 106 | + | ||
| 107 | +export enum RelatedAttributesFieldNameEnum { | ||
| 108 | + RELATIONS_QUERY = 'Relations query', | ||
| 109 | + ATTR_MAPPING = 'Attributes mapping', | ||
| 110 | +} | ||
| 111 | + | ||
| 112 | +// Enrichment Related device Attributes | ||
| 113 | +export enum RelatedDeviceAttributeFieldsEnum { | ||
| 114 | + DEVICE_RELATIONS_QUERY = 'deviceRelationsQuery', | ||
| 115 | + TELL_FAILURE_IF_ABSENT = 'tellFailureIfAbsent', | ||
| 116 | + CLIENT_ATTRIBUTE_NAMES = 'clientAttributeNames', | ||
| 117 | + SHARED_ATTRIBUTE_NAMES = 'sharedAttributeNames', | ||
| 118 | + SERVER_ATTRIBUTE_NAMES = 'serverAttributeNames', | ||
| 119 | + LATEST_TS_KEY_NAMES = 'latestTsKeyNames', | ||
| 120 | + GET_LATEST_VALUE_WITH_TS = 'getLatestValueWithTs', | ||
| 121 | + FETCH_LAST_LEVEL_ONLY = 'fetchLastLevelOnly', | ||
| 122 | + | ||
| 123 | + // DEVICE_RELATIONS_QUERY | ||
| 124 | + DIRECTION = 'direction', | ||
| 125 | + MAX_LEVEL = 'maxLevel', | ||
| 126 | + RELATION_TYPE = 'relationType', | ||
| 127 | + DEVICE_TYPES = 'deviceTypes', | ||
| 128 | +} | ||
| 129 | + | ||
| 130 | +export enum RelatedDeviceAttributeFieldsNameEnum { | ||
| 131 | + DEVICE_RELATIONS_QUERY = 'deviceRelationsQuery', | ||
| 132 | + TELL_FAILURE_IF_ABSENT = 'Tell Failure', | ||
| 133 | + CLIENT_ATTRIBUTE_NAMES = 'Client attributes', | ||
| 134 | + SHARED_ATTRIBUTE_NAMES = 'Shared attributes', | ||
| 135 | + SERVER_ATTRIBUTE_NAMES = 'Server attributes', | ||
| 136 | + LATEST_TS_KEY_NAMES = 'Latest timeseries', | ||
| 137 | + GET_LATEST_VALUE_WITH_TS = 'Fetch Latest telemetry with Timestamp', | ||
| 138 | + FETCH_LAST_LEVEL_ONLY = '仅获取最后一级关联', | ||
| 139 | + | ||
| 140 | + // DEVICE_RELATIONS_QUERY | ||
| 141 | + DIRECTION = '方向', | ||
| 142 | + MAX_LEVEL = 'Max relation level', | ||
| 143 | + RELATION_TYPE = '关联类型', | ||
| 144 | + DEVICE_TYPES = '设备类型', | ||
| 145 | +} | ||
| 146 | + | ||
| 147 | +// Enrichment Tenant details | ||
| 148 | +export enum TenantDetailsFieldsEnum { | ||
| 149 | + DETAILS_LIST = 'detailsList', | ||
| 150 | + ADD_TO_METADATA = 'addToMetadata', | ||
| 151 | +} | ||
| 152 | + | ||
| 153 | +export enum TenantDetailsFieldsNameEnum { | ||
| 154 | + DETAILS_LIST = 'Add selected details to message metadata', | ||
| 155 | + ADD_TO_METADATA = 'Select entity details', | ||
| 156 | +} | ||
| 157 | + | ||
| 158 | +export const EnrichmentCategoryFormFields = { | ||
| 159 | + ...CalculateDeltaFieldsEnum, | ||
| 160 | + ...CustomerAttributesFieldsEnum, | ||
| 161 | + ...CustomerDetailsFieldsEnum, | ||
| 162 | + ...OriginatorAttributesEnum, | ||
| 163 | + ...OriginatorFieldsEnum, | ||
| 164 | + ...OriginatorTelemetryFieldsEnum, | ||
| 165 | + ...RelatedAttributesFieldsEnum, | ||
| 166 | + ...RelatedDeviceAttributeFieldsEnum, | ||
| 167 | + ...TenantDetailsFieldsEnum, | ||
| 168 | +}; | ||
| 169 | + | ||
| 170 | +export const EnrichmentCategoryFormFieldsName = { | ||
| 171 | + ...CalculateDeltaFieldsNameEnum, | ||
| 172 | + ...CustomerAttributesFieldsNameEnum, | ||
| 173 | + ...CustomerDetailsFieldsNameEnum, | ||
| 174 | + ...OriginatorAttributesNameEnum, | ||
| 175 | + ...OriginatorFieldsNameEnum, | ||
| 176 | + ...OriginatorTelemetryFieldsNameEnum, | ||
| 177 | + ...RelatedAttributesFieldNameEnum, | ||
| 178 | + ...RelatedDeviceAttributeFieldsNameEnum, | ||
| 179 | + ...TenantDetailsFieldsNameEnum, | ||
| 180 | +}; | ||
| 181 | + | ||
| 182 | +export type EnrichmentCategoryType = typeof EnrichmentCategoryFormFields; |
| 1 | +// Filter Check Alarm Status Fields | ||
| 2 | +export enum FilterCheckAlarmStatusFieldEnum { | ||
| 3 | + ALARM_STATUS_LIST = 'alarmStatusList', | ||
| 4 | +} | ||
| 5 | + | ||
| 6 | +export enum FilterCheckAlarmStatusFieldNameEnum { | ||
| 7 | + ALARM_STATUS_LIST = 'Alarm status filter', | ||
| 8 | +} | ||
| 9 | + | ||
| 10 | +// Filter CHeck Existence Fields | ||
| 11 | +export enum CheckExistenceFieldsEnum { | ||
| 12 | + MESSAGE_NAMES = 'messageNames', | ||
| 13 | + METADATA_NAMES = 'metadataNames', | ||
| 14 | + CHECK_ALL_KEYS = 'checkAllKeys', | ||
| 15 | +} | ||
| 16 | + | ||
| 17 | +export enum CheckExistenceFieldsNameEnum { | ||
| 18 | + MESSAGE_NAMES = '消息数据', | ||
| 19 | + METADATA_NAMES = '消息元数据', | ||
| 20 | + CHECK_ALL_KEYS = '检查所有选择的键是否都存在', | ||
| 21 | +} | ||
| 22 | + | ||
| 23 | +// Filter Check Relation Fields | ||
| 24 | +export enum CheckRelationFieldsEnum { | ||
| 25 | + DIRECTION = 'direction', | ||
| 26 | + CHECK_FOR_SINGLE_ENTITY = 'checkForSingleEntity', | ||
| 27 | + ENTITY_TYPE = 'entityType', | ||
| 28 | + RELEATION_TYPE = 'relationType', | ||
| 29 | + ENTITY_ID = 'entityId', | ||
| 30 | +} | ||
| 31 | + | ||
| 32 | +export enum CheckRelationFieldsNameEnum { | ||
| 33 | + DIRECTION = '方向', | ||
| 34 | + CHECK_FOR_SINGLE_ENTITY = 'Check relation to specific entity', | ||
| 35 | + ENTITY_TYPE = '类型', | ||
| 36 | + RELEATION_TYPE = '关联类型', | ||
| 37 | +} | ||
| 38 | + | ||
| 39 | +// Filter Gps geofencing filter | ||
| 40 | +export enum GpsGeofencingFilterFieldsEnum { | ||
| 41 | + LATITUDE_KEY_NAME = 'latitudeKeyName', | ||
| 42 | + LONGITUDE_KEY_NAME = 'longitudeKeyName', | ||
| 43 | + PERIMETER_TYPE = 'perimeterType', | ||
| 44 | + FETCH_PERIMETER_INFO_FROM_MESSAGE_METADATA = 'fetchPerimeterInfoFromMessageMetadata', | ||
| 45 | + PERIMETER_KEY_NAME = 'perimeterKeyName', | ||
| 46 | + CENTER_LATITUDE = 'centerLatitude', | ||
| 47 | + CENTER_LONGITUDE = 'centerLongitude', | ||
| 48 | + RANGE = 'range', | ||
| 49 | + RANGE_UNIT = 'rangeUnit', | ||
| 50 | + POLYGONS_DEFINITION = 'polygonsDefinition', | ||
| 51 | +} | ||
| 52 | + | ||
| 53 | +export enum GpsGeofencingFilterFieldsNameEnum { | ||
| 54 | + LATITUDE_KEY_NAME = 'Latitude Key Name', | ||
| 55 | + LONGITUDE_KEY_NAME = 'Longitude Key Name', | ||
| 56 | + PERIMETER_TYPE = 'Perimeter Type', | ||
| 57 | + FETCH_PERIMETER_INFO_FROM_MESSAGE_METADATA = 'Fetch perimeter information from message metadata', | ||
| 58 | + CENTER_LATITUDE = 'Center latitude', | ||
| 59 | + CENTER_LONGITUDE = 'Center longitude', | ||
| 60 | + RANGE = 'Range', | ||
| 61 | + RANGE_UNIT = 'Range unit', | ||
| 62 | + PERIMETER_KEY_NAME = 'Perimeter key name', | ||
| 63 | + POLYGONS_DEFINITION = 'Polygons definition', | ||
| 64 | +} | ||
| 65 | + | ||
| 66 | +// Filter Message Type | ||
| 67 | +export enum MessageTypeFieldsEnum { | ||
| 68 | + MESSAGE_TYPES = 'messageTypes', | ||
| 69 | +} | ||
| 70 | + | ||
| 71 | +export enum MessageTypeFieldsNameEnum { | ||
| 72 | + MESSAGE_TYPES = 'Message Types Filter', | ||
| 73 | +} | ||
| 74 | + | ||
| 75 | +// Filter Originator Type | ||
| 76 | +export enum OriginatorTypeFieldsEnum { | ||
| 77 | + ORIGINATOR_TYPES = 'originatorTypes', | ||
| 78 | +} | ||
| 79 | + | ||
| 80 | +export enum OriginatorTypeFieldsNameEnum { | ||
| 81 | + ORIGINATOR_TYPES = 'Originator types filter', | ||
| 82 | +} | ||
| 83 | + | ||
| 84 | +// Filter Script | ||
| 85 | +export enum ScriptFieldsEnum { | ||
| 86 | + JS_SCRIPT = 'jsScript', | ||
| 87 | +} | ||
| 88 | + | ||
| 89 | +export enum ScriptFieldsNameEnum { | ||
| 90 | + JS_SCRIPT = 'Filter', | ||
| 91 | +} | ||
| 92 | + | ||
| 93 | +export const FilterCategoryFormFields = { | ||
| 94 | + ...FilterCheckAlarmStatusFieldEnum, | ||
| 95 | + ...CheckExistenceFieldsEnum, | ||
| 96 | + ...CheckRelationFieldsEnum, | ||
| 97 | + ...GpsGeofencingFilterFieldsEnum, | ||
| 98 | + ...MessageTypeFieldsEnum, | ||
| 99 | + ...OriginatorTypeFieldsEnum, | ||
| 100 | + ...ScriptFieldsEnum, | ||
| 101 | +}; | ||
| 102 | + | ||
| 103 | +export const FilterCategoryFormFieldsName = { | ||
| 104 | + ...FilterCheckAlarmStatusFieldNameEnum, | ||
| 105 | + ...CheckExistenceFieldsNameEnum, | ||
| 106 | + ...CheckRelationFieldsNameEnum, | ||
| 107 | + ...GpsGeofencingFilterFieldsNameEnum, | ||
| 108 | + ...MessageTypeFieldsNameEnum, | ||
| 109 | + ...OriginatorTypeFieldsNameEnum, | ||
| 110 | + ...ScriptFieldsNameEnum, | ||
| 111 | +}; | ||
| 112 | + | ||
| 113 | +export type FilterCategoryFormType = typeof FilterCategoryFormFields; |
| 1 | +// Change originator | ||
| 2 | +export enum ChangeOriginatorFieldsEnum { | ||
| 3 | + ORIGINATOR_SOURCE = 'originatorSource', | ||
| 4 | + RELATIONS_QUERY = 'relationsQuery', | ||
| 5 | +} | ||
| 6 | + | ||
| 7 | +export enum ChangeOriginatorFieldsNameEnum { | ||
| 8 | + ORIGINATOR_SOURCE = 'Originator source', | ||
| 9 | + RELATIONS_QUERY = 'Relations Query', | ||
| 10 | +} | ||
| 11 | + | ||
| 12 | +export enum ScriptFieldsEnum { | ||
| 13 | + JS_SCRIPT = 'jsScript', | ||
| 14 | +} | ||
| 15 | + | ||
| 16 | +export enum ScriptFieldsNameEnum { | ||
| 17 | + JS_SCRIPT = 'Transform', | ||
| 18 | +} | ||
| 19 | + | ||
| 20 | +export enum ToEmailFieldsEnum { | ||
| 21 | + FROM_TEMPLATE = 'fromTemplate', | ||
| 22 | + TO_TEMPLATE = 'toTemplate', | ||
| 23 | + CC_TEMPLATE = 'ccTemplate', | ||
| 24 | + BCC_TEMPLATE = 'bccTemplate', | ||
| 25 | + SUBJECT_TEMPLATE = 'subjectTemplate', | ||
| 26 | + MAIL_BODY_TYPE = 'mailBodyType', | ||
| 27 | + IS_HTML_TEMPLATE = 'isHtmlTemplate', | ||
| 28 | + BODY_TEMPLATE = 'bodyTemplate', | ||
| 29 | +} | ||
| 30 | + | ||
| 31 | +export enum ToEmailFieldsNameEnum { | ||
| 32 | + FROM_TEMPLATE = 'From Template', | ||
| 33 | + TO_TEMPLATE = 'To Template', | ||
| 34 | + CC_TEMPLATE = 'Cc Template', | ||
| 35 | + BCC_TEMPLATE = 'Bcc Template', | ||
| 36 | + SUBJECT_TEMPLATE = 'Subject Template', | ||
| 37 | + MAIL_BODY_TYPE = 'Mail body type', | ||
| 38 | + IS_HTML_TEMPLATE = 'Dynamic mail body type', | ||
| 39 | + BODY_TEMPLATE = 'Body Template', | ||
| 40 | +} |
| 1 | +import { CommonFields, CommonFieldsName } from './formField/common'; | ||
| 2 | +import { | ||
| 3 | + EnrichmentCategoryFormFields, | ||
| 4 | + EnrichmentCategoryFormFieldsName, | ||
| 5 | +} from './formField/enrichment'; | ||
| 6 | +import { FilterCategoryFormFields, FilterCategoryFormFieldsName } from './formField/filter'; | ||
| 7 | + | ||
| 1 | export enum FetchNodeComFlagTypeENum { | 8 | export enum FetchNodeComFlagTypeENum { |
| 2 | CONNECTION_MODAL = 'CONNECTION_MODAL', | 9 | CONNECTION_MODAL = 'CONNECTION_MODAL', |
| 3 | CREATE_MODAL = 'CREATE_MODAL', | 10 | CREATE_MODAL = 'CREATE_MODAL', |
| 4 | } | 11 | } |
| 5 | 12 | ||
| 6 | -export enum NodeBindDataFieldEnum { | ||
| 7 | - NAME = 'name', | ||
| 8 | - DESCRIPTION = 'description', | ||
| 9 | - DEBUG_MODE = 'debugMode', | ||
| 10 | - | ||
| 11 | - // Filter Check Alarm status | ||
| 12 | - ALARM_STATUS_LIST = 'alarmStatusList', | ||
| 13 | - | ||
| 14 | - // Filter Check Existence Fields | ||
| 15 | - MESSAGE_NAMES = 'messageNames', | ||
| 16 | - METADATA_NAMES = 'metadataNames', | ||
| 17 | - CHECK_ALL_KEYS = 'checkAllKeys', | ||
| 18 | - | ||
| 19 | - // Filter Check Relation | ||
| 20 | - DIRECTION = 'direction', | ||
| 21 | - CHECK_FOR_SINGLE_ENTITY = 'checkForSingleEntity', | ||
| 22 | - ENTITY_TYPE = 'entityType', | ||
| 23 | - RELEATION_TYPE = 'relationType', | ||
| 24 | - ENTITY_ID = 'entityId', | ||
| 25 | - | ||
| 26 | - // Filter Gps geofencing filter | ||
| 27 | - LATITUDE_KEY_NAME = 'latitudeKeyName', | ||
| 28 | - LONGITUDE_KEY_NAME = 'longitudeKeyName', | ||
| 29 | - PERIMETER_TYPE = 'perimeterType', | ||
| 30 | - FETCH_PERIMETER_INFO_FROM_MESSAGE_METADATA = 'fetchPerimeterInfoFromMessageMetadata', | ||
| 31 | - PERIMETER_KEY_NAME = 'perimeterKeyName', | ||
| 32 | - CENTER_LATITUDE = 'centerLatitude', | ||
| 33 | - CENTER_LONGITUDE = 'centerLongitude', | ||
| 34 | - RANGE = 'range', | ||
| 35 | - RANGE_UNIT = 'rangeUnit', | ||
| 36 | - POLYGONS_DEFINITION = 'polygonsDefinition', | ||
| 37 | - | ||
| 38 | - // Filter Message Type | ||
| 39 | - MESSAGE_TYPES = 'messageTypes', | ||
| 40 | - | ||
| 41 | - // Filter Originator Type | ||
| 42 | - ORIGINATOR_TYPES = 'originatorTypes', | ||
| 43 | - | ||
| 44 | - // Filter Script | ||
| 45 | - JS_SCRIPT = 'jsScript', | ||
| 46 | -} | ||
| 47 | - | ||
| 48 | -export enum NodeBindDataFieldNameEnum { | ||
| 49 | - NAME = '名称', | ||
| 50 | - DESCRIPTION = '说明', | ||
| 51 | - DEBUG_MODE = '调试模式', | ||
| 52 | - | ||
| 53 | - // Filter Check Alarm status | ||
| 54 | - ALARM_STATUS_LIST = 'Alarm status filter', | ||
| 55 | - | ||
| 56 | - // Filter Check Existence Fields | ||
| 57 | - MESSAGE_NAMES = '消息数据', | ||
| 58 | - METADATA_NAMES = '消息元数据', | ||
| 59 | - CHECK_ALL_KEYS = '检查所有选择的键是否都存在', | ||
| 60 | - | ||
| 61 | - // Filter Check Relation | ||
| 62 | - DIRECTION = '方向', | ||
| 63 | - CHECK_FOR_SINGLE_ENTITY = 'Check relation to specific entity', | ||
| 64 | - ENTITY_TYPE = '类型', | ||
| 65 | - RELEATION_TYPE = '关联类型', | ||
| 66 | - | ||
| 67 | - // Filter Gps geofencing filter | ||
| 68 | - LATITUDE_KEY_NAME = 'Latitude Key Name', | ||
| 69 | - LONGITUDE_KEY_NAME = 'Longitude Key Name', | ||
| 70 | - PERIMETER_TYPE = 'Perimeter Type', | ||
| 71 | - FETCH_PERIMETER_INFO_FROM_MESSAGE_METADATA = 'Fetch perimeter information from message metadata', | ||
| 72 | - CENTER_LATITUDE = 'Center latitude', | ||
| 73 | - CENTER_LONGITUDE = 'Center longitude', | ||
| 74 | - RANGE = 'Range', | ||
| 75 | - RANGE_UNIT = 'Range unit', | ||
| 76 | - PERIMETER_KEY_NAME = 'Perimeter key name', | ||
| 77 | - POLYGONS_DEFINITION = 'Polygons definition', | ||
| 78 | - | ||
| 79 | - // Filter Message Type | ||
| 80 | - MESSAGE_TYPES = 'Message Types Filter', | ||
| 81 | - | ||
| 82 | - // Filter Originator Type | ||
| 83 | - ORIGINATOR_TYPES = 'Originator types filter', | ||
| 84 | - | ||
| 85 | - // Filter Script | ||
| 86 | - JS_SCRIPT = 'Filter', | ||
| 87 | -} | ||
| 88 | - | ||
| 89 | export enum EdgeBindDataFieldEnum { | 13 | export enum EdgeBindDataFieldEnum { |
| 90 | TYPE = 'type', | 14 | TYPE = 'type', |
| 91 | } | 15 | } |
| @@ -93,3 +17,15 @@ export enum EdgeBindDataFieldEnum { | @@ -93,3 +17,15 @@ export enum EdgeBindDataFieldEnum { | ||
| 93 | export enum EdgeBindDataFieldNameEnum { | 17 | export enum EdgeBindDataFieldNameEnum { |
| 94 | TYPE = '链接标签', | 18 | TYPE = '链接标签', |
| 95 | } | 19 | } |
| 20 | + | ||
| 21 | +export const NodeBindDataFieldEnum = { | ||
| 22 | + ...CommonFields, | ||
| 23 | + ...FilterCategoryFormFields, | ||
| 24 | + ...EnrichmentCategoryFormFields, | ||
| 25 | +}; | ||
| 26 | + | ||
| 27 | +export const NodeBindDataFieldNameEnum = { | ||
| 28 | + ...CommonFieldsName, | ||
| 29 | + ...FilterCategoryFormFieldsName, | ||
| 30 | + ...EnrichmentCategoryFormFieldsName, | ||
| 31 | +}; |
| @@ -133,7 +133,6 @@ export function useRuleFlow(options: UseRuleFlowOptionsType) { | @@ -133,7 +133,6 @@ export function useRuleFlow(options: UseRuleFlowOptionsType) { | ||
| 133 | if (!flag) return; | 133 | if (!flag) return; |
| 134 | 134 | ||
| 135 | const currentNode = findNode(node.id); | 135 | const currentNode = findNode(node.id); |
| 136 | - | ||
| 137 | (currentNode!.data as NodeData).data = data; | 136 | (currentNode!.data as NodeData).data = data; |
| 138 | }); | 137 | }); |
| 139 | 138 |
| 1 | -import { NodeBindDataFieldEnum, NodeBindDataFieldNameEnum } from '../../../enum/node'; | 1 | +import { |
| 2 | + AssignToCustomerFieldsEnum, | ||
| 3 | + AssignToCustomerFieldsNameEnum, | ||
| 4 | +} from '../../../enum/formField/action'; | ||
| 2 | import { FormSchema } from '/@/components/Form'; | 5 | import { FormSchema } from '/@/components/Form'; |
| 3 | 6 | ||
| 4 | export const formSchemas: FormSchema[] = [ | 7 | export const formSchemas: FormSchema[] = [ |
| 5 | { | 8 | { |
| 6 | - field: NodeBindDataFieldEnum.NAME, | 9 | + field: AssignToCustomerFieldsEnum.CUSTOMER_NAME_PATTERN, |
| 7 | component: 'Input', | 10 | component: 'Input', |
| 8 | - label: NodeBindDataFieldNameEnum.NAME, | 11 | + label: AssignToCustomerFieldsNameEnum.CUSTOMER_NAME_PATTERN, |
| 12 | + helpMessage: | ||
| 13 | + 'Hint: use ${metadataKey} for value from metadata, $[messageKey] for value from message body', | ||
| 14 | + componentProps: { | ||
| 15 | + placeholder: `请输入${AssignToCustomerFieldsNameEnum.CUSTOMER_NAME_PATTERN}`, | ||
| 16 | + }, | ||
| 17 | + }, | ||
| 18 | + { | ||
| 19 | + field: AssignToCustomerFieldsEnum.CREATE_CUSTOMER_IF_NOT_EXISTS, | ||
| 20 | + component: 'Checkbox', | ||
| 21 | + label: '', | ||
| 22 | + renderComponentContent: () => ({ | ||
| 23 | + default: () => AssignToCustomerFieldsNameEnum.CREATE_CUSTOMER_IF_NOT_EXISTS, | ||
| 24 | + }), | ||
| 25 | + }, | ||
| 26 | + { | ||
| 27 | + field: AssignToCustomerFieldsEnum.CUSTOMER_CACHE_EXPIRATION, | ||
| 28 | + component: 'InputNumber', | ||
| 29 | + label: AssignToCustomerFieldsNameEnum.CUSTOMER_CACHE_EXPIRATION, | ||
| 30 | + required: true, | ||
| 31 | + helpMessage: | ||
| 32 | + 'Specifies maximum time interval allowed to store found customer records. 0 value means that records will never expire.', | ||
| 33 | + componentProps: { | ||
| 34 | + placeholder: `请输入${AssignToCustomerFieldsNameEnum.CUSTOMER_CACHE_EXPIRATION}`, | ||
| 35 | + min: 0, | ||
| 36 | + }, | ||
| 9 | }, | 37 | }, |
| 10 | ]; | 38 | ]; |
| 1 | -import { NodeBindDataFieldEnum, NodeBindDataFieldNameEnum } from '../../../enum/node'; | ||
| 2 | -import { FormSchema } from '/@/components/Form'; | 1 | +import { ClearAlarmFieldsEnum, ClearAlarmFieldsNameEnum } from '../../../enum/formField/action'; |
| 2 | +import { JavascriptEditorWithTestModal } from '../../../src/components/JavaScriptFilterModal'; | ||
| 3 | +import { FormSchema, useComponentRegister } from '/@/components/Form'; | ||
| 4 | + | ||
| 5 | +useComponentRegister('JavascriptEditorWithTestModal', JavascriptEditorWithTestModal); | ||
| 3 | 6 | ||
| 4 | export const formSchemas: FormSchema[] = [ | 7 | export const formSchemas: FormSchema[] = [ |
| 5 | { | 8 | { |
| 6 | - field: NodeBindDataFieldEnum.NAME, | 9 | + field: ClearAlarmFieldsEnum.ALARM_DETAILS_BUILD_JS, |
| 10 | + component: 'JavascriptEditorWithTestModal', | ||
| 11 | + label: ClearAlarmFieldsNameEnum.ALARM_DETAILS_BUILD_JS, | ||
| 12 | + componentProps: { | ||
| 13 | + javaScriptEditorProps: { | ||
| 14 | + functionName: 'Details', | ||
| 15 | + paramsName: ['msg', 'metadata', 'msgType'], | ||
| 16 | + }, | ||
| 17 | + buttonName: 'Test details function', | ||
| 18 | + }, | ||
| 19 | + }, | ||
| 20 | + { | ||
| 21 | + field: ClearAlarmFieldsEnum.ALARM_TYPE, | ||
| 7 | component: 'Input', | 22 | component: 'Input', |
| 8 | - label: NodeBindDataFieldNameEnum.NAME, | 23 | + label: ClearAlarmFieldsNameEnum.ALARM_TYPE, |
| 24 | + required: true, | ||
| 25 | + componentProps: { | ||
| 26 | + placeholder: `请输入${ClearAlarmFieldsNameEnum.ALARM_TYPE}`, | ||
| 27 | + }, | ||
| 9 | }, | 28 | }, |
| 10 | ]; | 29 | ]; |
| 1 | -import { NodeBindDataFieldEnum, NodeBindDataFieldNameEnum } from '../../../enum/node'; | ||
| 2 | import { FormSchema } from '/@/components/Form'; | 1 | import { FormSchema } from '/@/components/Form'; |
| 3 | 2 | ||
| 4 | -export const formSchemas: FormSchema[] = [ | ||
| 5 | - { | ||
| 6 | - field: NodeBindDataFieldEnum.NAME, | ||
| 7 | - component: 'Input', | ||
| 8 | - label: NodeBindDataFieldNameEnum.NAME, | ||
| 9 | - }, | ||
| 10 | -]; | 3 | +export const formSchemas: FormSchema[] = []; |
| 1 | -import { NodeBindDataFieldEnum, NodeBindDataFieldNameEnum } from '../../../enum/node'; | ||
| 2 | -import { FormSchema } from '/@/components/Form'; | 1 | +import { CreateAlarmFieldsEnum, CreateAlarmFieldsNameEnum } from '../../../enum/formField/action'; |
| 2 | +import { JavascriptEditorWithTestModal } from '../../../src/components/JavaScriptFilterModal'; | ||
| 3 | +import { FormSchema, useComponentRegister } from '/@/components/Form'; | ||
| 4 | + | ||
| 5 | +useComponentRegister('JavascriptEditorWithTestModal', JavascriptEditorWithTestModal); | ||
| 3 | 6 | ||
| 4 | export const formSchemas: FormSchema[] = [ | 7 | export const formSchemas: FormSchema[] = [ |
| 5 | { | 8 | { |
| 6 | - field: NodeBindDataFieldEnum.NAME, | ||
| 7 | - component: 'Input', | ||
| 8 | - label: NodeBindDataFieldNameEnum.NAME, | 9 | + field: CreateAlarmFieldsEnum.USE_MESSAGE_ALARM_DATA, |
| 10 | + component: 'Checkbox', | ||
| 11 | + label: '', | ||
| 12 | + renderComponentContent: () => ({ | ||
| 13 | + default: () => CreateAlarmFieldsNameEnum.USE_MESSAGE_ALARM_DATA, | ||
| 14 | + }), | ||
| 15 | + }, | ||
| 16 | + { | ||
| 17 | + field: CreateAlarmFieldsEnum.ALARM_DETAILS_BUILD_JS, | ||
| 18 | + component: 'JavascriptEditorWithTestModal', | ||
| 19 | + label: CreateAlarmFieldsNameEnum.ALARM_DETAILS_BUILD_JS, | ||
| 9 | }, | 20 | }, |
| 10 | ]; | 21 | ]; |
| @@ -3,8 +3,64 @@ import { FormSchema } from '/@/components/Form'; | @@ -3,8 +3,64 @@ import { FormSchema } from '/@/components/Form'; | ||
| 3 | 3 | ||
| 4 | export const formSchemas: FormSchema[] = [ | 4 | export const formSchemas: FormSchema[] = [ |
| 5 | { | 5 | { |
| 6 | - field: NodeBindDataFieldEnum.NAME, | 6 | + field: NodeBindDataFieldEnum.INPUT_VALUE_KEY, |
| 7 | component: 'Input', | 7 | component: 'Input', |
| 8 | - label: NodeBindDataFieldNameEnum.NAME, | 8 | + label: NodeBindDataFieldNameEnum.INPUT_VALUE_KEY, |
| 9 | + required: true, | ||
| 10 | + colProps: { span: 8 }, | ||
| 11 | + }, | ||
| 12 | + { | ||
| 13 | + field: NodeBindDataFieldEnum.OUTPUT_VALUE_KEY, | ||
| 14 | + component: 'Input', | ||
| 15 | + label: NodeBindDataFieldNameEnum.OUTPUT_VALUE_KEY, | ||
| 16 | + required: true, | ||
| 17 | + colProps: { span: 8 }, | ||
| 18 | + }, | ||
| 19 | + { | ||
| 20 | + field: NodeBindDataFieldEnum.ROUND, | ||
| 21 | + component: 'InputNumber', | ||
| 22 | + label: NodeBindDataFieldNameEnum.ROUND, | ||
| 23 | + colProps: { span: 8 }, | ||
| 24 | + componentProps: { | ||
| 25 | + step: 1, | ||
| 26 | + max: 15, | ||
| 27 | + }, | ||
| 28 | + }, | ||
| 29 | + { | ||
| 30 | + field: NodeBindDataFieldEnum.USE_CACHE, | ||
| 31 | + component: 'Checkbox', | ||
| 32 | + label: '', | ||
| 33 | + renderComponentContent: () => { | ||
| 34 | + return { | ||
| 35 | + default: () => NodeBindDataFieldNameEnum.USE_CACHE, | ||
| 36 | + }; | ||
| 37 | + }, | ||
| 38 | + }, | ||
| 39 | + { | ||
| 40 | + field: NodeBindDataFieldEnum.TELL_FAILURE_IF_DELTA_IS_NEGATIVE, | ||
| 41 | + component: 'Checkbox', | ||
| 42 | + label: '', | ||
| 43 | + renderComponentContent: () => { | ||
| 44 | + return { | ||
| 45 | + default: () => NodeBindDataFieldNameEnum.TELL_FAILURE_IF_DELTA_IS_NEGATIVE, | ||
| 46 | + }; | ||
| 47 | + }, | ||
| 48 | + }, | ||
| 49 | + { | ||
| 50 | + field: NodeBindDataFieldEnum.ADD_PERIOD_BETWEEN_MSGS, | ||
| 51 | + component: 'Checkbox', | ||
| 52 | + label: '', | ||
| 53 | + renderComponentContent: () => { | ||
| 54 | + return { | ||
| 55 | + default: () => NodeBindDataFieldNameEnum.ADD_PERIOD_BETWEEN_MSGS, | ||
| 56 | + }; | ||
| 57 | + }, | ||
| 58 | + }, | ||
| 59 | + { | ||
| 60 | + field: NodeBindDataFieldEnum.PERIOD_VALUE_KEY, | ||
| 61 | + component: 'Input', | ||
| 62 | + label: NodeBindDataFieldNameEnum.PERIOD_VALUE_KEY, | ||
| 63 | + required: true, | ||
| 64 | + ifShow: ({ model }) => model[NodeBindDataFieldEnum.ADD_PERIOD_BETWEEN_MSGS], | ||
| 9 | }, | 65 | }, |
| 10 | ]; | 66 | ]; |
| 1 | import { NodeBindDataFieldEnum, NodeBindDataFieldNameEnum } from '../../../enum/node'; | 1 | import { NodeBindDataFieldEnum, NodeBindDataFieldNameEnum } from '../../../enum/node'; |
| 2 | -import { FormSchema } from '/@/components/Form'; | 2 | +import { FormSchema, useComponentRegister } from '/@/components/Form'; |
| 3 | +import { AttributeConfiguration } from '/@/views/rule/designer/src/components/AttributeConfiguration'; | ||
| 4 | + | ||
| 5 | +useComponentRegister('AttributeConfiguration', AttributeConfiguration); | ||
| 3 | 6 | ||
| 4 | export const formSchemas: FormSchema[] = [ | 7 | export const formSchemas: FormSchema[] = [ |
| 5 | { | 8 | { |
| 6 | - field: NodeBindDataFieldEnum.NAME, | ||
| 7 | - component: 'Input', | ||
| 8 | - label: NodeBindDataFieldNameEnum.NAME, | 9 | + field: NodeBindDataFieldEnum.TELEMETRY, |
| 10 | + component: 'Checkbox', | ||
| 11 | + label: '', | ||
| 12 | + renderComponentContent: () => { | ||
| 13 | + return { | ||
| 14 | + default: () => NodeBindDataFieldNameEnum.TELEMETRY, | ||
| 15 | + }; | ||
| 16 | + }, | ||
| 17 | + }, | ||
| 18 | + { | ||
| 19 | + field: NodeBindDataFieldEnum.ATTR_MAPING, | ||
| 20 | + component: 'AttributeConfiguration', | ||
| 21 | + label: NodeBindDataFieldNameEnum.ATTR_MAPING, | ||
| 22 | + slot: NodeBindDataFieldEnum.ATTR_MAPING, | ||
| 23 | + valueField: 'value', | ||
| 24 | + changeEvent: 'update:value', | ||
| 9 | }, | 25 | }, |
| 10 | ]; | 26 | ]; |
| @@ -3,25 +3,33 @@ | @@ -3,25 +3,33 @@ | ||
| 3 | import { BasicForm, useForm } from '/@/components/Form'; | 3 | import { BasicForm, useForm } from '/@/components/Form'; |
| 4 | import { formSchemas } from './create.config'; | 4 | import { formSchemas } from './create.config'; |
| 5 | import { NodeData } from '../../../types/node'; | 5 | import { NodeData } from '../../../types/node'; |
| 6 | + import { AttributeConfiguration } from '/@/views/rule/designer/src/components/AttributeConfiguration'; | ||
| 7 | + import { ref, unref } from 'vue'; | ||
| 8 | + import { NodeBindDataFieldEnum } from '../../../enum/node'; | ||
| 6 | 9 | ||
| 7 | defineProps<{ | 10 | defineProps<{ |
| 8 | config: NodeData; | 11 | config: NodeData; |
| 9 | }>(); | 12 | }>(); |
| 10 | 13 | ||
| 14 | + const attributeControlElRef = ref<Nullable<InstanceType<typeof AttributeConfiguration>>>(); | ||
| 15 | + | ||
| 11 | const [register, { validate, getFieldsValue, setFieldsValue, resetFields }] = useForm({ | 16 | const [register, { validate, getFieldsValue, setFieldsValue, resetFields }] = useForm({ |
| 12 | schemas: formSchemas, | 17 | schemas: formSchemas, |
| 13 | showActionButtonGroup: false, | 18 | showActionButtonGroup: false, |
| 14 | }); | 19 | }); |
| 15 | 20 | ||
| 16 | const getValue: CreateModalDefineExposeType['getFieldsValue'] = async () => { | 21 | const getValue: CreateModalDefineExposeType['getFieldsValue'] = async () => { |
| 22 | + await unref(attributeControlElRef)?.validate(); | ||
| 17 | await validate(); | 23 | await validate(); |
| 18 | const value = getFieldsValue() || {}; | 24 | const value = getFieldsValue() || {}; |
| 19 | - return value; | 25 | + const attrMapping = unref(attributeControlElRef)?.getFieldsValue(); |
| 26 | + return { ...value, [NodeBindDataFieldEnum.ATTR_MAPING]: attrMapping }; | ||
| 20 | }; | 27 | }; |
| 21 | 28 | ||
| 22 | const setValue: CreateModalDefineExposeType['setFieldsValue'] = (value) => { | 29 | const setValue: CreateModalDefineExposeType['setFieldsValue'] = (value) => { |
| 23 | resetFields(); | 30 | resetFields(); |
| 24 | setFieldsValue(value); | 31 | setFieldsValue(value); |
| 32 | + unref(attributeControlElRef)?.setFieldsValue(value?.[NodeBindDataFieldEnum.ATTR_MAPING]); | ||
| 25 | }; | 33 | }; |
| 26 | 34 | ||
| 27 | defineExpose({ | 35 | defineExpose({ |
| @@ -31,5 +39,32 @@ | @@ -31,5 +39,32 @@ | ||
| 31 | </script> | 39 | </script> |
| 32 | 40 | ||
| 33 | <template> | 41 | <template> |
| 34 | - <BasicForm @register="register" /> | 42 | + <BasicForm @register="register"> |
| 43 | + <template #attrMapping="{ field, model }"> | ||
| 44 | + <AttributeConfiguration | ||
| 45 | + v-model:value="model[field]" | ||
| 46 | + ref="attributeControlElRef" | ||
| 47 | + :keyLabel="`Source ${model[NodeBindDataFieldEnum.TELEMETRY] ? 'telemetry' : 'attribute'}`" | ||
| 48 | + valueLabel="Target attribute" | ||
| 49 | + > | ||
| 50 | + <template #afterForm> | ||
| 51 | + <div class="text-xs text-gray-500"> | ||
| 52 | + Hint: use | ||
| 53 | + <code> | ||
| 54 | + <span class="text-dark-500">${</span> | ||
| 55 | + metadataKey | ||
| 56 | + <span class="text-dark-500">}</span> | ||
| 57 | + </code> | ||
| 58 | + for value from metadata, | ||
| 59 | + <code> | ||
| 60 | + <span class="text-dark-500"> $[</span> | ||
| 61 | + messageKey | ||
| 62 | + <span class="text-dark-500">] </span> | ||
| 63 | + </code> | ||
| 64 | + for value from message body to substitute "Source" and "Target" key names | ||
| 65 | + </div> | ||
| 66 | + </template> | ||
| 67 | + </AttributeConfiguration> | ||
| 68 | + </template> | ||
| 69 | + </BasicForm> | ||
| 35 | </template> | 70 | </template> |
| 1 | +import { DetailsListEnum, DetailsListNameEnum } from '../../../enum/form'; | ||
| 1 | import { NodeBindDataFieldEnum, NodeBindDataFieldNameEnum } from '../../../enum/node'; | 2 | import { NodeBindDataFieldEnum, NodeBindDataFieldNameEnum } from '../../../enum/node'; |
| 2 | import { FormSchema } from '/@/components/Form'; | 3 | import { FormSchema } from '/@/components/Form'; |
| 3 | 4 | ||
| 4 | export const formSchemas: FormSchema[] = [ | 5 | export const formSchemas: FormSchema[] = [ |
| 5 | { | 6 | { |
| 6 | - field: NodeBindDataFieldEnum.NAME, | ||
| 7 | - component: 'Input', | ||
| 8 | - label: NodeBindDataFieldNameEnum.NAME, | 7 | + field: NodeBindDataFieldEnum.DETAILS_LIST, |
| 8 | + component: 'Select', | ||
| 9 | + label: NodeBindDataFieldNameEnum.DETAILS_LIST, | ||
| 10 | + componentProps: { | ||
| 11 | + mode: 'multiple', | ||
| 12 | + options: Object.keys(DetailsListEnum).map((item) => ({ | ||
| 13 | + label: DetailsListNameEnum[item], | ||
| 14 | + value: item, | ||
| 15 | + getPopupContainer: () => document.body, | ||
| 16 | + })), | ||
| 17 | + }, | ||
| 18 | + }, | ||
| 19 | + { | ||
| 20 | + field: NodeBindDataFieldEnum.ADD_TO_METADATA, | ||
| 21 | + component: 'Checkbox', | ||
| 22 | + label: '', | ||
| 23 | + renderComponentContent: () => { | ||
| 24 | + return { | ||
| 25 | + default: () => NodeBindDataFieldNameEnum.ADD_TO_METADATA, | ||
| 26 | + }; | ||
| 27 | + }, | ||
| 9 | }, | 28 | }, |
| 10 | ]; | 29 | ]; |
| @@ -3,8 +3,73 @@ import { FormSchema } from '/@/components/Form'; | @@ -3,8 +3,73 @@ import { FormSchema } from '/@/components/Form'; | ||
| 3 | 3 | ||
| 4 | export const formSchemas: FormSchema[] = [ | 4 | export const formSchemas: FormSchema[] = [ |
| 5 | { | 5 | { |
| 6 | - field: NodeBindDataFieldEnum.NAME, | ||
| 7 | - component: 'Input', | ||
| 8 | - label: NodeBindDataFieldNameEnum.NAME, | 6 | + field: NodeBindDataFieldEnum.TELL_FAILURE_IF_ABSENT, |
| 7 | + component: 'Checkbox', | ||
| 8 | + label: '', | ||
| 9 | + // helpMessage: [ | ||
| 10 | + // 'If at least one selected key doesn\'t exist the outbound message will report "Failure".', | ||
| 11 | + // ], | ||
| 12 | + renderComponentContent: () => ({ | ||
| 13 | + default: () => NodeBindDataFieldNameEnum.TELL_FAILURE_IF_ABSENT, | ||
| 14 | + }), | ||
| 15 | + }, | ||
| 16 | + { | ||
| 17 | + field: NodeBindDataFieldEnum.CLIENT_ATTRIBUTE_NAMES, | ||
| 18 | + component: 'Select', | ||
| 19 | + label: NodeBindDataFieldNameEnum.CLIENT_ATTRIBUTE_NAMES, | ||
| 20 | + helpMessage: [ | ||
| 21 | + `Hint: use \${metadataKey} for value from metadata, $[messageKey] for value from message body`, | ||
| 22 | + ], | ||
| 23 | + componentProps: { | ||
| 24 | + mode: 'tags', | ||
| 25 | + open: false, | ||
| 26 | + }, | ||
| 27 | + }, | ||
| 28 | + { | ||
| 29 | + field: NodeBindDataFieldEnum.SHARED_ATTRIBUTE_NAMES, | ||
| 30 | + component: 'Select', | ||
| 31 | + label: NodeBindDataFieldNameEnum.SHARED_ATTRIBUTE_NAMES, | ||
| 32 | + helpMessage: [ | ||
| 33 | + `Hint: use \${metadataKey} for value from metadata, $[messageKey] for value from message body`, | ||
| 34 | + ], | ||
| 35 | + componentProps: { | ||
| 36 | + mode: 'tags', | ||
| 37 | + open: false, | ||
| 38 | + }, | ||
| 39 | + }, | ||
| 40 | + { | ||
| 41 | + field: NodeBindDataFieldEnum.SERVER_ATTRIBUTE_NAMES, | ||
| 42 | + component: 'Select', | ||
| 43 | + label: NodeBindDataFieldNameEnum.SERVER_ATTRIBUTE_NAMES, | ||
| 44 | + helpMessage: [ | ||
| 45 | + `Hint: use \${metadataKey} for value from metadata, $[messageKey] for value from message body`, | ||
| 46 | + ], | ||
| 47 | + componentProps: { | ||
| 48 | + mode: 'tags', | ||
| 49 | + open: false, | ||
| 50 | + }, | ||
| 51 | + }, | ||
| 52 | + { | ||
| 53 | + field: NodeBindDataFieldEnum.LATEST_TS_KEY_NAMES, | ||
| 54 | + component: 'Select', | ||
| 55 | + label: NodeBindDataFieldNameEnum.LATEST_TS_KEY_NAMES, | ||
| 56 | + helpMessage: [ | ||
| 57 | + `Hint: use \${metadataKey} for value from metadata, $[messageKey] for value from message body`, | ||
| 58 | + ], | ||
| 59 | + componentProps: { | ||
| 60 | + mode: 'tags', | ||
| 61 | + open: false, | ||
| 62 | + }, | ||
| 63 | + }, | ||
| 64 | + { | ||
| 65 | + field: NodeBindDataFieldEnum.GET_LATEST_VALUE_WITH_TS, | ||
| 66 | + component: 'Checkbox', | ||
| 67 | + label: '', | ||
| 68 | + // helpMessage: [ | ||
| 69 | + // 'If selected, latest telemetry values will be added to the outbound message metadata with timestamp, e.g: "temp": "{"ts":1574329385897, "value":42}"', | ||
| 70 | + // ], | ||
| 71 | + renderComponentContent: () => ({ | ||
| 72 | + default: () => NodeBindDataFieldNameEnum.GET_LATEST_VALUE_WITH_TS, | ||
| 73 | + }), | ||
| 9 | }, | 74 | }, |
| 10 | ]; | 75 | ]; |
| 1 | import { NodeBindDataFieldEnum, NodeBindDataFieldNameEnum } from '../../../enum/node'; | 1 | import { NodeBindDataFieldEnum, NodeBindDataFieldNameEnum } from '../../../enum/node'; |
| 2 | -import { FormSchema } from '/@/components/Form'; | 2 | +import { FormSchema, useComponentRegister } from '/@/components/Form'; |
| 3 | +import { AttributeConfiguration } from '/@/views/rule/designer/src/components/AttributeConfiguration'; | ||
| 4 | + | ||
| 5 | +useComponentRegister('AttributeConfiguration', AttributeConfiguration); | ||
| 3 | 6 | ||
| 4 | export const formSchemas: FormSchema[] = [ | 7 | export const formSchemas: FormSchema[] = [ |
| 5 | { | 8 | { |
| 6 | - field: NodeBindDataFieldEnum.NAME, | ||
| 7 | - component: 'Input', | ||
| 8 | - label: NodeBindDataFieldNameEnum.NAME, | 9 | + field: NodeBindDataFieldEnum.FIELDS_MAPPING, |
| 10 | + component: 'AttributeConfiguration', | ||
| 11 | + label: NodeBindDataFieldNameEnum.FIELDS_MAPPING, | ||
| 12 | + slot: NodeBindDataFieldEnum.FIELDS_MAPPING, | ||
| 13 | + valueField: 'value', | ||
| 14 | + changeEvent: 'update:value', | ||
| 9 | }, | 15 | }, |
| 10 | ]; | 16 | ]; |
| @@ -3,25 +3,33 @@ | @@ -3,25 +3,33 @@ | ||
| 3 | import { BasicForm, useForm } from '/@/components/Form'; | 3 | import { BasicForm, useForm } from '/@/components/Form'; |
| 4 | import { formSchemas } from './create.config'; | 4 | import { formSchemas } from './create.config'; |
| 5 | import { NodeData } from '../../../types/node'; | 5 | import { NodeData } from '../../../types/node'; |
| 6 | + import { AttributeConfiguration } from '/@/views/rule/designer/src/components/AttributeConfiguration'; | ||
| 7 | + import { ref, unref } from 'vue'; | ||
| 8 | + import { NodeBindDataFieldEnum } from '../../../enum/node'; | ||
| 6 | 9 | ||
| 7 | defineProps<{ | 10 | defineProps<{ |
| 8 | config: NodeData; | 11 | config: NodeData; |
| 9 | }>(); | 12 | }>(); |
| 10 | 13 | ||
| 14 | + const fieldControlElRef = ref<Nullable<InstanceType<typeof AttributeConfiguration>>>(); | ||
| 15 | + | ||
| 11 | const [register, { validate, getFieldsValue, setFieldsValue, resetFields }] = useForm({ | 16 | const [register, { validate, getFieldsValue, setFieldsValue, resetFields }] = useForm({ |
| 12 | schemas: formSchemas, | 17 | schemas: formSchemas, |
| 13 | showActionButtonGroup: false, | 18 | showActionButtonGroup: false, |
| 14 | }); | 19 | }); |
| 15 | 20 | ||
| 16 | const getValue: CreateModalDefineExposeType['getFieldsValue'] = async () => { | 21 | const getValue: CreateModalDefineExposeType['getFieldsValue'] = async () => { |
| 22 | + await unref(fieldControlElRef)?.validate(); | ||
| 17 | await validate(); | 23 | await validate(); |
| 18 | const value = getFieldsValue() || {}; | 24 | const value = getFieldsValue() || {}; |
| 19 | - return value; | 25 | + const fieldsMapping = unref(fieldControlElRef)?.getFieldsValue(); |
| 26 | + return { ...value, [NodeBindDataFieldEnum.FIELDS_MAPPING]: fieldsMapping }; | ||
| 20 | }; | 27 | }; |
| 21 | 28 | ||
| 22 | const setValue: CreateModalDefineExposeType['setFieldsValue'] = (value) => { | 29 | const setValue: CreateModalDefineExposeType['setFieldsValue'] = (value) => { |
| 23 | resetFields(); | 30 | resetFields(); |
| 24 | setFieldsValue(value); | 31 | setFieldsValue(value); |
| 32 | + unref(fieldControlElRef)?.setFieldsValue(value?.[NodeBindDataFieldEnum.FIELDS_MAPPING]); | ||
| 25 | }; | 33 | }; |
| 26 | 34 | ||
| 27 | defineExpose({ | 35 | defineExpose({ |
| @@ -31,5 +39,14 @@ | @@ -31,5 +39,14 @@ | ||
| 31 | </script> | 39 | </script> |
| 32 | 40 | ||
| 33 | <template> | 41 | <template> |
| 34 | - <BasicForm @register="register" /> | 42 | + <BasicForm @register="register"> |
| 43 | + <template #fieldsMapping="{ field, model }"> | ||
| 44 | + <AttributeConfiguration | ||
| 45 | + v-model:value="model[field]" | ||
| 46 | + ref="fieldControlElRef" | ||
| 47 | + keyLabel="Source Field" | ||
| 48 | + valueLabel="Target attribute" | ||
| 49 | + /> | ||
| 50 | + </template> | ||
| 51 | + </BasicForm> | ||
| 35 | </template> | 52 | </template> |
| 1 | +import { | ||
| 2 | + AggregationEnum, | ||
| 3 | + AggregationNameEnum, | ||
| 4 | + FetchModeEnum, | ||
| 5 | + OrderByEnum, | ||
| 6 | + TimeIntervalUnitEnum, | ||
| 7 | + TimeIntervalUnitNameEnum, | ||
| 8 | +} from '../../../enum/form'; | ||
| 1 | import { NodeBindDataFieldEnum, NodeBindDataFieldNameEnum } from '../../../enum/node'; | 9 | import { NodeBindDataFieldEnum, NodeBindDataFieldNameEnum } from '../../../enum/node'; |
| 2 | import { FormSchema } from '/@/components/Form'; | 10 | import { FormSchema } from '/@/components/Form'; |
| 3 | 11 | ||
| 4 | export const formSchemas: FormSchema[] = [ | 12 | export const formSchemas: FormSchema[] = [ |
| 5 | { | 13 | { |
| 6 | - field: NodeBindDataFieldEnum.NAME, | 14 | + field: NodeBindDataFieldEnum.LATEST_TS_KEY_NAMES, |
| 15 | + component: 'Select', | ||
| 16 | + label: NodeBindDataFieldNameEnum.LATEST_TS_KEY_NAMES, | ||
| 17 | + componentProps: { | ||
| 18 | + mode: 'tags', | ||
| 19 | + open: false, | ||
| 20 | + }, | ||
| 21 | + }, | ||
| 22 | + { | ||
| 23 | + field: NodeBindDataFieldEnum.FETCH_MODE, | ||
| 24 | + component: 'Select', | ||
| 25 | + label: NodeBindDataFieldNameEnum.FETCH_MODE, | ||
| 26 | + required: true, | ||
| 27 | + componentProps: { | ||
| 28 | + options: Object.keys(FetchModeEnum).map((value) => ({ label: value, value })), | ||
| 29 | + }, | ||
| 30 | + }, | ||
| 31 | + { | ||
| 32 | + field: NodeBindDataFieldEnum.AGGREGATION, | ||
| 33 | + component: 'Select', | ||
| 34 | + label: NodeBindDataFieldNameEnum.AGGREGATION, | ||
| 35 | + required: true, | ||
| 36 | + show: ({ model }) => model[NodeBindDataFieldEnum.FETCH_MODE] === FetchModeEnum.ALL, | ||
| 37 | + componentProps: { | ||
| 38 | + options: Object.keys(AggregationEnum).map((value) => ({ | ||
| 39 | + label: AggregationNameEnum[value], | ||
| 40 | + value, | ||
| 41 | + })), | ||
| 42 | + }, | ||
| 43 | + }, | ||
| 44 | + { | ||
| 45 | + field: NodeBindDataFieldEnum.ORDER_BY, | ||
| 46 | + component: 'Select', | ||
| 47 | + label: NodeBindDataFieldNameEnum.ORDER_BY, | ||
| 48 | + required: true, | ||
| 49 | + show: ({ model }) => model[NodeBindDataFieldEnum.FETCH_MODE] === FetchModeEnum.ALL, | ||
| 50 | + componentProps: { | ||
| 51 | + options: Object.keys(OrderByEnum).map((value) => ({ label: value, value })), | ||
| 52 | + }, | ||
| 53 | + }, | ||
| 54 | + { | ||
| 55 | + field: NodeBindDataFieldEnum.ORDER_BY, | ||
| 56 | + component: 'Select', | ||
| 57 | + label: NodeBindDataFieldNameEnum.ORDER_BY, | ||
| 58 | + required: true, | ||
| 59 | + helpMessage: ['Select to choose telemetry sampling order.'], | ||
| 60 | + show: ({ model }) => model[NodeBindDataFieldEnum.FETCH_MODE] === FetchModeEnum.ALL, | ||
| 61 | + componentProps: { | ||
| 62 | + options: Object.keys(OrderByEnum).map((value) => ({ label: value, value })), | ||
| 63 | + }, | ||
| 64 | + }, | ||
| 65 | + { | ||
| 66 | + field: NodeBindDataFieldEnum.LIMIT, | ||
| 67 | + component: 'InputNumber', | ||
| 68 | + label: NodeBindDataFieldNameEnum.LIMIT, | ||
| 69 | + required: true, | ||
| 70 | + helpMessage: [ | ||
| 71 | + "Min limit value is 2, max - 1000. In case you want to fetch a single entry, select fetch mode 'FIRST' or 'LAST'.", | ||
| 72 | + ], | ||
| 73 | + show: ({ model }) => model[NodeBindDataFieldEnum.FETCH_MODE] === FetchModeEnum.ALL, | ||
| 74 | + componentProps: { | ||
| 75 | + min: 2, | ||
| 76 | + max: 1000, | ||
| 77 | + step: 1, | ||
| 78 | + }, | ||
| 79 | + }, | ||
| 80 | + { | ||
| 81 | + field: NodeBindDataFieldEnum.USE_METADATA_INTERVAL_PATTERNS, | ||
| 82 | + component: 'Checkbox', | ||
| 83 | + label: '', | ||
| 84 | + renderComponentContent: () => ({ | ||
| 85 | + default: () => NodeBindDataFieldNameEnum.USE_METADATA_INTERVAL_PATTERNS, | ||
| 86 | + }), | ||
| 87 | + }, | ||
| 88 | + { | ||
| 89 | + field: NodeBindDataFieldEnum.START_INTERVAL, | ||
| 90 | + component: 'InputNumber', | ||
| 91 | + label: NodeBindDataFieldNameEnum.START_INTERVAL, | ||
| 92 | + colProps: { span: 12 }, | ||
| 93 | + required: true, | ||
| 94 | + show: ({ model }) => !model[NodeBindDataFieldEnum.USE_METADATA_INTERVAL_PATTERNS], | ||
| 95 | + componentProps: { | ||
| 96 | + step: 1, | ||
| 97 | + min: 0, | ||
| 98 | + }, | ||
| 99 | + }, | ||
| 100 | + { | ||
| 101 | + field: NodeBindDataFieldEnum.START_INTERVAL_TIME_UNIT, | ||
| 102 | + component: 'Select', | ||
| 103 | + label: NodeBindDataFieldNameEnum.START_INTERVAL_TIME_UNIT, | ||
| 104 | + colProps: { span: 12 }, | ||
| 105 | + required: true, | ||
| 106 | + show: ({ model }) => !model[NodeBindDataFieldEnum.USE_METADATA_INTERVAL_PATTERNS], | ||
| 107 | + componentProps: { | ||
| 108 | + options: Object.keys(TimeIntervalUnitEnum).map((value) => ({ | ||
| 109 | + label: TimeIntervalUnitNameEnum[value], | ||
| 110 | + value, | ||
| 111 | + })), | ||
| 112 | + }, | ||
| 113 | + }, | ||
| 114 | + { | ||
| 115 | + field: NodeBindDataFieldEnum.END_INTERVAL, | ||
| 116 | + component: 'InputNumber', | ||
| 117 | + label: NodeBindDataFieldNameEnum.END_INTERVAL, | ||
| 118 | + colProps: { span: 12 }, | ||
| 119 | + required: true, | ||
| 120 | + show: ({ model }) => !model[NodeBindDataFieldEnum.USE_METADATA_INTERVAL_PATTERNS], | ||
| 121 | + componentProps: { | ||
| 122 | + step: 1, | ||
| 123 | + min: 0, | ||
| 124 | + }, | ||
| 125 | + }, | ||
| 126 | + { | ||
| 127 | + field: NodeBindDataFieldEnum.END_INTERVAL_TIME_UNIT, | ||
| 128 | + component: 'Select', | ||
| 129 | + label: NodeBindDataFieldNameEnum.END_INTERVAL_TIME_UNIT, | ||
| 130 | + colProps: { span: 12 }, | ||
| 131 | + required: true, | ||
| 132 | + show: ({ model }) => !model[NodeBindDataFieldEnum.USE_METADATA_INTERVAL_PATTERNS], | ||
| 133 | + componentProps: { | ||
| 134 | + options: Object.keys(TimeIntervalUnitEnum).map((value) => ({ | ||
| 135 | + label: TimeIntervalUnitNameEnum[value], | ||
| 136 | + value, | ||
| 137 | + })), | ||
| 138 | + }, | ||
| 139 | + }, | ||
| 140 | + { | ||
| 141 | + field: NodeBindDataFieldEnum.START_INTERVAL_PATTERN, | ||
| 142 | + component: 'Input', | ||
| 143 | + label: NodeBindDataFieldNameEnum.START_INTERVAL_PATTERN, | ||
| 144 | + required: true, | ||
| 145 | + helpMessage: [ | ||
| 146 | + 'Hint: use ${metadataKey} for value from metadata, $[messageKey] for value from message body', | ||
| 147 | + ], | ||
| 148 | + show: ({ model }) => model[NodeBindDataFieldEnum.USE_METADATA_INTERVAL_PATTERNS], | ||
| 149 | + }, | ||
| 150 | + { | ||
| 151 | + field: NodeBindDataFieldEnum.END_INTERVAL_PATTERN, | ||
| 7 | component: 'Input', | 152 | component: 'Input', |
| 8 | - label: NodeBindDataFieldNameEnum.NAME, | 153 | + label: NodeBindDataFieldNameEnum.END_INTERVAL_PATTERN, |
| 154 | + required: true, | ||
| 155 | + helpMessage: [ | ||
| 156 | + 'Hint: use ${metadataKey} for value from metadata, $[messageKey] for value from message body', | ||
| 157 | + ], | ||
| 158 | + show: ({ model }) => model[NodeBindDataFieldEnum.USE_METADATA_INTERVAL_PATTERNS], | ||
| 9 | }, | 159 | }, |
| 10 | ]; | 160 | ]; |
| 1 | import { NodeBindDataFieldEnum, NodeBindDataFieldNameEnum } from '../../../enum/node'; | 1 | import { NodeBindDataFieldEnum, NodeBindDataFieldNameEnum } from '../../../enum/node'; |
| 2 | -import { FormSchema } from '/@/components/Form'; | 2 | +import { AttributeConfiguration } from '/@/views/rule/designer/src/components/AttributeConfiguration'; |
| 3 | +import { FormSchema, useComponentRegister } from '/@/components/Form'; | ||
| 4 | +import { RelationsQuery } from '/@/views/rule/designer/src/components/RelationsQuery'; | ||
| 5 | + | ||
| 6 | +useComponentRegister('RelationsQuery', RelationsQuery); | ||
| 7 | +useComponentRegister('AttributeConfiguration', AttributeConfiguration); | ||
| 3 | 8 | ||
| 4 | export const formSchemas: FormSchema[] = [ | 9 | export const formSchemas: FormSchema[] = [ |
| 5 | { | 10 | { |
| 6 | - field: NodeBindDataFieldEnum.NAME, | ||
| 7 | - component: 'Input', | ||
| 8 | - label: NodeBindDataFieldNameEnum.NAME, | 11 | + field: NodeBindDataFieldEnum.RELATIONS_QUERY, |
| 12 | + component: 'RelationsQuery', | ||
| 13 | + label: NodeBindDataFieldNameEnum.RELATIONS_QUERY, | ||
| 14 | + changeEvent: 'update:value', | ||
| 15 | + valueField: 'value', | ||
| 16 | + slot: NodeBindDataFieldEnum.RELATIONS_QUERY, | ||
| 17 | + }, | ||
| 18 | + { | ||
| 19 | + field: NodeBindDataFieldEnum.TELEMETRY, | ||
| 20 | + component: 'Checkbox', | ||
| 21 | + label: '', | ||
| 22 | + renderComponentContent: () => ({ | ||
| 23 | + default: () => NodeBindDataFieldNameEnum.TELEMETRY, | ||
| 24 | + }), | ||
| 25 | + }, | ||
| 26 | + { | ||
| 27 | + field: NodeBindDataFieldEnum.ATTR_MAPING, | ||
| 28 | + component: 'AttributeConfiguration', | ||
| 29 | + label: '', | ||
| 30 | + slot: NodeBindDataFieldEnum.ATTR_MAPING, | ||
| 9 | }, | 31 | }, |
| 10 | ]; | 32 | ]; |
| @@ -3,11 +3,19 @@ | @@ -3,11 +3,19 @@ | ||
| 3 | import { BasicForm, useForm } from '/@/components/Form'; | 3 | import { BasicForm, useForm } from '/@/components/Form'; |
| 4 | import { formSchemas } from './create.config'; | 4 | import { formSchemas } from './create.config'; |
| 5 | import { NodeData } from '../../../types/node'; | 5 | import { NodeData } from '../../../types/node'; |
| 6 | + import { RelationsQuery } from '/@/views/rule/designer/src/components/RelationsQuery'; | ||
| 7 | + import { ref, unref } from 'vue'; | ||
| 8 | + import { NodeBindDataFieldEnum } from '../../../enum/node'; | ||
| 9 | + import { AttributeConfiguration } from '/@/views/rule/designer/src/components/AttributeConfiguration'; | ||
| 6 | 10 | ||
| 7 | defineProps<{ | 11 | defineProps<{ |
| 8 | config: NodeData; | 12 | config: NodeData; |
| 9 | }>(); | 13 | }>(); |
| 10 | 14 | ||
| 15 | + const relationsQueryElRef = ref<Nullable<InstanceType<typeof RelationsQuery>>>(); | ||
| 16 | + | ||
| 17 | + const attributeControlElRef = ref<Nullable<InstanceType<typeof AttributeConfiguration>>>(); | ||
| 18 | + | ||
| 11 | const [register, { validate, getFieldsValue, setFieldsValue, resetFields }] = useForm({ | 19 | const [register, { validate, getFieldsValue, setFieldsValue, resetFields }] = useForm({ |
| 12 | schemas: formSchemas, | 20 | schemas: formSchemas, |
| 13 | showActionButtonGroup: false, | 21 | showActionButtonGroup: false, |
| @@ -15,13 +23,25 @@ | @@ -15,13 +23,25 @@ | ||
| 15 | 23 | ||
| 16 | const getValue: CreateModalDefineExposeType['getFieldsValue'] = async () => { | 24 | const getValue: CreateModalDefineExposeType['getFieldsValue'] = async () => { |
| 17 | await validate(); | 25 | await validate(); |
| 26 | + await unref(relationsQueryElRef)?.validate(); | ||
| 27 | + await unref(attributeControlElRef)?.validate(); | ||
| 18 | const value = getFieldsValue() || {}; | 28 | const value = getFieldsValue() || {}; |
| 19 | - return value; | 29 | + const queryValue = unref(relationsQueryElRef)?.getFieldsValue(); |
| 30 | + const attrMapping = unref(attributeControlElRef)?.getFieldsValue(); | ||
| 31 | + return { | ||
| 32 | + ...value, | ||
| 33 | + [NodeBindDataFieldEnum.RELATIONS_QUERY]: queryValue, | ||
| 34 | + [NodeBindDataFieldEnum.ATTR_MAPING]: attrMapping, | ||
| 35 | + }; | ||
| 20 | }; | 36 | }; |
| 21 | 37 | ||
| 22 | const setValue: CreateModalDefineExposeType['setFieldsValue'] = (value) => { | 38 | const setValue: CreateModalDefineExposeType['setFieldsValue'] = (value) => { |
| 23 | resetFields(); | 39 | resetFields(); |
| 24 | setFieldsValue(value); | 40 | setFieldsValue(value); |
| 41 | + unref(relationsQueryElRef)?.setFieldsValue( | ||
| 42 | + value?.[NodeBindDataFieldEnum.RELATIONS_QUERY] as Recordable | ||
| 43 | + ); | ||
| 44 | + unref(attributeControlElRef)?.setFieldsValue(value?.[NodeBindDataFieldEnum.ATTR_MAPING]); | ||
| 25 | }; | 45 | }; |
| 26 | 46 | ||
| 27 | defineExpose({ | 47 | defineExpose({ |
| @@ -31,5 +51,35 @@ | @@ -31,5 +51,35 @@ | ||
| 31 | </script> | 51 | </script> |
| 32 | 52 | ||
| 33 | <template> | 53 | <template> |
| 34 | - <BasicForm @register="register" /> | 54 | + <BasicForm @register="register"> |
| 55 | + <template #relationsQuery="{ field, model }"> | ||
| 56 | + <RelationsQuery ref="relationsQueryElRef" v-model:value="model[field]" /> | ||
| 57 | + </template> | ||
| 58 | + <template #attrMapping="{ field, model }"> | ||
| 59 | + <AttributeConfiguration | ||
| 60 | + v-model:value="model[field]" | ||
| 61 | + ref="attributeControlElRef" | ||
| 62 | + :keyLabel="`Source ${model[NodeBindDataFieldEnum.TELEMETRY] ? 'telemetry' : 'attribute'}`" | ||
| 63 | + valueLabel="Target attribute" | ||
| 64 | + > | ||
| 65 | + <template #afterForm> | ||
| 66 | + <div class="text-xs text-gray-500"> | ||
| 67 | + Hint: use | ||
| 68 | + <code> | ||
| 69 | + <span class="text-dark-500">${</span> | ||
| 70 | + metadataKey | ||
| 71 | + <span class="text-dark-500">}</span> | ||
| 72 | + </code> | ||
| 73 | + for value from metadata, | ||
| 74 | + <code> | ||
| 75 | + <span class="text-dark-500"> $[</span> | ||
| 76 | + messageKey | ||
| 77 | + <span class="text-dark-500">] </span> | ||
| 78 | + </code> | ||
| 79 | + for value from message body to substitute "Source" and "Target" key names | ||
| 80 | + </div> | ||
| 81 | + </template> | ||
| 82 | + </AttributeConfiguration> | ||
| 83 | + </template> | ||
| 84 | + </BasicForm> | ||
| 35 | </template> | 85 | </template> |
| 1 | +import { | ||
| 2 | + DirectionEnum, | ||
| 3 | + DirectionNameEnum, | ||
| 4 | + RelationTypeEnum, | ||
| 5 | + RelationTypeNameEnum, | ||
| 6 | +} from '../../../enum/form'; | ||
| 1 | import { NodeBindDataFieldEnum, NodeBindDataFieldNameEnum } from '../../../enum/node'; | 7 | import { NodeBindDataFieldEnum, NodeBindDataFieldNameEnum } from '../../../enum/node'; |
| 8 | +import { getDeviceTypes } from '/@/api/ruleChainDesigner'; | ||
| 2 | import { FormSchema } from '/@/components/Form'; | 9 | import { FormSchema } from '/@/components/Form'; |
| 3 | 10 | ||
| 11 | +export interface ValueType { | ||
| 12 | + deviceRelationsQuery: DeviceRelationsQuery; | ||
| 13 | + tellFailureIfAbsent: boolean; | ||
| 14 | + clientAttributeNames: string[]; | ||
| 15 | + sharedAttributeNames: string[]; | ||
| 16 | + serverAttributeNames: string[]; | ||
| 17 | + latestTsKeyNames: string[]; | ||
| 18 | + getLatestValueWithTs: boolean; | ||
| 19 | +} | ||
| 20 | + | ||
| 21 | +export interface DeviceRelationsQuery { | ||
| 22 | + fetchLastLevelOnly: boolean; | ||
| 23 | + direction: string; | ||
| 24 | + maxLevel: number; | ||
| 25 | + relationType: string; | ||
| 26 | + deviceTypes: string[]; | ||
| 27 | +} | ||
| 28 | + | ||
| 4 | export const formSchemas: FormSchema[] = [ | 29 | export const formSchemas: FormSchema[] = [ |
| 5 | { | 30 | { |
| 6 | - field: NodeBindDataFieldEnum.NAME, | ||
| 7 | - component: 'Input', | ||
| 8 | - label: NodeBindDataFieldNameEnum.NAME, | 31 | + field: NodeBindDataFieldEnum.FETCH_LAST_LEVEL_ONLY, |
| 32 | + component: 'Checkbox', | ||
| 33 | + label: '', | ||
| 34 | + renderComponentContent: () => ({ | ||
| 35 | + default: () => NodeBindDataFieldNameEnum.FETCH_LAST_LEVEL_ONLY, | ||
| 36 | + }), | ||
| 37 | + }, | ||
| 38 | + { | ||
| 39 | + field: NodeBindDataFieldEnum.DIRECTION, | ||
| 40 | + component: 'Select', | ||
| 41 | + label: NodeBindDataFieldNameEnum.DIRECTION, | ||
| 42 | + required: true, | ||
| 43 | + colProps: { span: 12 }, | ||
| 44 | + componentProps: { | ||
| 45 | + options: Object.keys(DirectionEnum).map((value) => ({ | ||
| 46 | + label: DirectionNameEnum[value], | ||
| 47 | + value, | ||
| 48 | + })), | ||
| 49 | + placeholder: `请选择${NodeBindDataFieldNameEnum.DIRECTION}`, | ||
| 50 | + getPopupContainer: () => document.body, | ||
| 51 | + }, | ||
| 52 | + }, | ||
| 53 | + { | ||
| 54 | + field: NodeBindDataFieldEnum.MAX_LEVEL, | ||
| 55 | + component: 'InputNumber', | ||
| 56 | + label: NodeBindDataFieldNameEnum.MAX_LEVEL, | ||
| 57 | + colProps: { span: 12 }, | ||
| 58 | + componentProps: { | ||
| 59 | + min: 1, | ||
| 60 | + }, | ||
| 61 | + }, | ||
| 62 | + { | ||
| 63 | + field: NodeBindDataFieldEnum.RELATION_TYPE, | ||
| 64 | + component: 'Select', | ||
| 65 | + label: NodeBindDataFieldNameEnum.RELATION_TYPE, | ||
| 66 | + componentProps: { | ||
| 67 | + options: Object.keys(RelationTypeEnum).map((value) => ({ | ||
| 68 | + label: RelationTypeNameEnum[value], | ||
| 69 | + value, | ||
| 70 | + })), | ||
| 71 | + placeholder: `请选择${NodeBindDataFieldNameEnum.RELATION_TYPE}`, | ||
| 72 | + getPopupContainer: () => document.body, | ||
| 73 | + }, | ||
| 74 | + }, | ||
| 75 | + { | ||
| 76 | + field: NodeBindDataFieldEnum.DEVICE_TYPES, | ||
| 77 | + component: 'ApiSelect', | ||
| 78 | + label: NodeBindDataFieldNameEnum.DEVICE_TYPES, | ||
| 79 | + componentProps: { | ||
| 80 | + mode: 'multiple', | ||
| 81 | + api: getDeviceTypes, | ||
| 82 | + labelField: 'type', | ||
| 83 | + valueField: 'type', | ||
| 84 | + getPopupContainer: () => document.body, | ||
| 85 | + placeholder: `请选择${NodeBindDataFieldNameEnum.DEVICE_TYPES}`, | ||
| 86 | + }, | ||
| 87 | + }, | ||
| 88 | + { | ||
| 89 | + field: NodeBindDataFieldEnum.TELL_FAILURE_IF_ABSENT, | ||
| 90 | + component: 'Checkbox', | ||
| 91 | + label: '', | ||
| 92 | + renderComponentContent: () => ({ | ||
| 93 | + default: () => NodeBindDataFieldNameEnum.TELL_FAILURE_IF_ABSENT, | ||
| 94 | + }), | ||
| 95 | + }, | ||
| 96 | + { | ||
| 97 | + field: NodeBindDataFieldEnum.CLIENT_ATTRIBUTE_NAMES, | ||
| 98 | + component: 'Select', | ||
| 99 | + label: NodeBindDataFieldNameEnum.CLIENT_ATTRIBUTE_NAMES, | ||
| 100 | + componentProps: { | ||
| 101 | + open: false, | ||
| 102 | + mode: 'tags', | ||
| 103 | + placeholder: NodeBindDataFieldNameEnum.CLIENT_ATTRIBUTE_NAMES, | ||
| 104 | + }, | ||
| 105 | + }, | ||
| 106 | + { | ||
| 107 | + field: NodeBindDataFieldEnum.SHARED_ATTRIBUTE_NAMES, | ||
| 108 | + component: 'Select', | ||
| 109 | + label: NodeBindDataFieldNameEnum.SHARED_ATTRIBUTE_NAMES, | ||
| 110 | + componentProps: { | ||
| 111 | + open: false, | ||
| 112 | + mode: 'tags', | ||
| 113 | + placeholder: NodeBindDataFieldNameEnum.SHARED_ATTRIBUTE_NAMES, | ||
| 114 | + }, | ||
| 115 | + }, | ||
| 116 | + { | ||
| 117 | + field: NodeBindDataFieldEnum.SERVER_ATTRIBUTE_NAMES, | ||
| 118 | + component: 'Select', | ||
| 119 | + label: NodeBindDataFieldNameEnum.SERVER_ATTRIBUTE_NAMES, | ||
| 120 | + componentProps: { | ||
| 121 | + open: false, | ||
| 122 | + mode: 'tags', | ||
| 123 | + placeholder: NodeBindDataFieldNameEnum.SERVER_ATTRIBUTE_NAMES, | ||
| 124 | + }, | ||
| 125 | + }, | ||
| 126 | + { | ||
| 127 | + field: NodeBindDataFieldEnum.LATEST_TS_KEY_NAMES, | ||
| 128 | + component: 'Select', | ||
| 129 | + label: NodeBindDataFieldNameEnum.LATEST_TS_KEY_NAMES, | ||
| 130 | + componentProps: { | ||
| 131 | + open: false, | ||
| 132 | + mode: 'tags', | ||
| 133 | + placeholder: NodeBindDataFieldNameEnum.LATEST_TS_KEY_NAMES, | ||
| 134 | + }, | ||
| 135 | + }, | ||
| 136 | + { | ||
| 137 | + field: NodeBindDataFieldEnum.GET_LATEST_VALUE_WITH_TS, | ||
| 138 | + component: 'Checkbox', | ||
| 139 | + label: '', | ||
| 140 | + renderComponentContent: () => ({ | ||
| 141 | + default: () => NodeBindDataFieldNameEnum.GET_LATEST_VALUE_WITH_TS, | ||
| 142 | + }), | ||
| 9 | }, | 143 | }, |
| 10 | ]; | 144 | ]; |
| 1 | <script lang="ts" setup> | 1 | <script lang="ts" setup> |
| 2 | import type { CreateModalDefineExposeType } from '../../../types'; | 2 | import type { CreateModalDefineExposeType } from '../../../types'; |
| 3 | import { BasicForm, useForm } from '/@/components/Form'; | 3 | import { BasicForm, useForm } from '/@/components/Form'; |
| 4 | - import { formSchemas } from './create.config'; | 4 | + import { DeviceRelationsQuery, formSchemas, ValueType } from './create.config'; |
| 5 | import { NodeData } from '../../../types/node'; | 5 | import { NodeData } from '../../../types/node'; |
| 6 | + import { NodeBindDataFieldEnum } from '../../../enum/node'; | ||
| 6 | 7 | ||
| 7 | defineProps<{ | 8 | defineProps<{ |
| 8 | config: NodeData; | 9 | config: NodeData; |
| @@ -16,12 +17,33 @@ | @@ -16,12 +17,33 @@ | ||
| 16 | const getValue: CreateModalDefineExposeType['getFieldsValue'] = async () => { | 17 | const getValue: CreateModalDefineExposeType['getFieldsValue'] = async () => { |
| 17 | await validate(); | 18 | await validate(); |
| 18 | const value = getFieldsValue() || {}; | 19 | const value = getFieldsValue() || {}; |
| 19 | - return value; | 20 | + return { |
| 21 | + [NodeBindDataFieldEnum.DEVICE_RELATIONS_QUERY]: { | ||
| 22 | + [NodeBindDataFieldEnum.FETCH_LAST_LEVEL_ONLY]: | ||
| 23 | + value[NodeBindDataFieldEnum.FETCH_LAST_LEVEL_ONLY], | ||
| 24 | + [NodeBindDataFieldEnum.DEVICE_TYPES]: value[NodeBindDataFieldEnum.DEVICE_TYPES], | ||
| 25 | + [NodeBindDataFieldEnum.DIRECTION]: value[NodeBindDataFieldEnum.DIRECTION], | ||
| 26 | + [NodeBindDataFieldEnum.MAX_LEVEL]: value[NodeBindDataFieldEnum.MAX_LEVEL], | ||
| 27 | + [NodeBindDataFieldEnum.RELATION_TYPE]: value[NodeBindDataFieldEnum.RELATION_TYPE], | ||
| 28 | + } as DeviceRelationsQuery, | ||
| 29 | + [NodeBindDataFieldEnum.CLIENT_ATTRIBUTE_NAMES]: | ||
| 30 | + value[NodeBindDataFieldEnum.CLIENT_ATTRIBUTE_NAMES], | ||
| 31 | + [NodeBindDataFieldEnum.GET_LATEST_VALUE_WITH_TS]: | ||
| 32 | + value[NodeBindDataFieldEnum.GET_LATEST_VALUE_WITH_TS], | ||
| 33 | + [NodeBindDataFieldEnum.LATEST_TS_KEY_NAMES]: value[NodeBindDataFieldEnum.LATEST_TS_KEY_NAMES], | ||
| 34 | + [NodeBindDataFieldEnum.SERVER_ATTRIBUTE_NAMES]: | ||
| 35 | + value[NodeBindDataFieldEnum.SERVER_ATTRIBUTE_NAMES], | ||
| 36 | + [NodeBindDataFieldEnum.SHARED_ATTRIBUTE_NAMES]: | ||
| 37 | + value[NodeBindDataFieldEnum.SHARED_ATTRIBUTE_NAMES], | ||
| 38 | + [NodeBindDataFieldEnum.TELL_FAILURE_IF_ABSENT]: | ||
| 39 | + value[NodeBindDataFieldEnum.TELL_FAILURE_IF_ABSENT], | ||
| 40 | + } as ValueType; | ||
| 20 | }; | 41 | }; |
| 21 | 42 | ||
| 22 | const setValue: CreateModalDefineExposeType['setFieldsValue'] = (value) => { | 43 | const setValue: CreateModalDefineExposeType['setFieldsValue'] = (value) => { |
| 23 | resetFields(); | 44 | resetFields(); |
| 24 | - setFieldsValue(value); | 45 | + console.log(value); |
| 46 | + setFieldsValue({ ...value, ...(value?.[NodeBindDataFieldEnum.DEVICE_RELATIONS_QUERY] || {}) }); | ||
| 25 | }; | 47 | }; |
| 26 | 48 | ||
| 27 | defineExpose({ | 49 | defineExpose({ |
| 1 | import { NodeBindDataFieldEnum, NodeBindDataFieldNameEnum } from '../../../enum/node'; | 1 | import { NodeBindDataFieldEnum, NodeBindDataFieldNameEnum } from '../../../enum/node'; |
| 2 | -import { FormSchema } from '/@/components/Form'; | 2 | +import { FormSchema, useComponentRegister } from '/@/components/Form'; |
| 3 | +import { AttributeConfiguration } from '/@/views/rule/designer/src/components/AttributeConfiguration'; | ||
| 4 | + | ||
| 5 | +useComponentRegister('AttributeConfiguration', AttributeConfiguration); | ||
| 3 | 6 | ||
| 4 | export const formSchemas: FormSchema[] = [ | 7 | export const formSchemas: FormSchema[] = [ |
| 5 | { | 8 | { |
| 6 | - field: NodeBindDataFieldEnum.NAME, | ||
| 7 | - component: 'Input', | ||
| 8 | - label: NodeBindDataFieldNameEnum.NAME, | 9 | + field: NodeBindDataFieldEnum.TELEMETRY, |
| 10 | + component: 'Checkbox', | ||
| 11 | + label: '', | ||
| 12 | + renderComponentContent: () => { | ||
| 13 | + return { | ||
| 14 | + default: () => NodeBindDataFieldNameEnum.TELEMETRY, | ||
| 15 | + }; | ||
| 16 | + }, | ||
| 17 | + }, | ||
| 18 | + { | ||
| 19 | + field: NodeBindDataFieldEnum.ATTR_MAPING, | ||
| 20 | + component: 'AttributeConfiguration', | ||
| 21 | + label: NodeBindDataFieldNameEnum.ATTR_MAPING, | ||
| 22 | + slot: NodeBindDataFieldEnum.ATTR_MAPING, | ||
| 23 | + valueField: 'value', | ||
| 24 | + changeEvent: 'update:value', | ||
| 9 | }, | 25 | }, |
| 10 | ]; | 26 | ]; |
| @@ -3,25 +3,33 @@ | @@ -3,25 +3,33 @@ | ||
| 3 | import { BasicForm, useForm } from '/@/components/Form'; | 3 | import { BasicForm, useForm } from '/@/components/Form'; |
| 4 | import { formSchemas } from './create.config'; | 4 | import { formSchemas } from './create.config'; |
| 5 | import { NodeData } from '../../../types/node'; | 5 | import { NodeData } from '../../../types/node'; |
| 6 | + import { AttributeConfiguration } from '/@/views/rule/designer/src/components/AttributeConfiguration'; | ||
| 7 | + import { ref, unref } from 'vue'; | ||
| 8 | + import { NodeBindDataFieldEnum } from '../../../enum/node'; | ||
| 6 | 9 | ||
| 7 | defineProps<{ | 10 | defineProps<{ |
| 8 | config: NodeData; | 11 | config: NodeData; |
| 9 | }>(); | 12 | }>(); |
| 10 | 13 | ||
| 14 | + const attributeControlElRef = ref<Nullable<InstanceType<typeof AttributeConfiguration>>>(); | ||
| 15 | + | ||
| 11 | const [register, { validate, getFieldsValue, setFieldsValue, resetFields }] = useForm({ | 16 | const [register, { validate, getFieldsValue, setFieldsValue, resetFields }] = useForm({ |
| 12 | schemas: formSchemas, | 17 | schemas: formSchemas, |
| 13 | showActionButtonGroup: false, | 18 | showActionButtonGroup: false, |
| 14 | }); | 19 | }); |
| 15 | 20 | ||
| 16 | const getValue: CreateModalDefineExposeType['getFieldsValue'] = async () => { | 21 | const getValue: CreateModalDefineExposeType['getFieldsValue'] = async () => { |
| 22 | + await unref(attributeControlElRef)?.validate(); | ||
| 17 | await validate(); | 23 | await validate(); |
| 18 | const value = getFieldsValue() || {}; | 24 | const value = getFieldsValue() || {}; |
| 19 | - return value; | 25 | + const attrMapping = unref(attributeControlElRef)?.getFieldsValue(); |
| 26 | + return { ...value, [NodeBindDataFieldEnum.ATTR_MAPING]: attrMapping }; | ||
| 20 | }; | 27 | }; |
| 21 | 28 | ||
| 22 | const setValue: CreateModalDefineExposeType['setFieldsValue'] = (value) => { | 29 | const setValue: CreateModalDefineExposeType['setFieldsValue'] = (value) => { |
| 23 | resetFields(); | 30 | resetFields(); |
| 24 | setFieldsValue(value); | 31 | setFieldsValue(value); |
| 32 | + unref(attributeControlElRef)?.setFieldsValue(value?.[NodeBindDataFieldEnum.ATTR_MAPING]); | ||
| 25 | }; | 33 | }; |
| 26 | 34 | ||
| 27 | defineExpose({ | 35 | defineExpose({ |
| @@ -31,5 +39,32 @@ | @@ -31,5 +39,32 @@ | ||
| 31 | </script> | 39 | </script> |
| 32 | 40 | ||
| 33 | <template> | 41 | <template> |
| 34 | - <BasicForm @register="register" /> | 42 | + <BasicForm @register="register"> |
| 43 | + <template #attrMapping="{ field, model }"> | ||
| 44 | + <AttributeConfiguration | ||
| 45 | + v-model:value="model[field]" | ||
| 46 | + ref="attributeControlElRef" | ||
| 47 | + :keyLabel="`Source ${model[NodeBindDataFieldEnum.TELEMETRY] ? 'telemetry' : 'attribute'}`" | ||
| 48 | + valueLabel="Target attribute" | ||
| 49 | + > | ||
| 50 | + <template #afterForm> | ||
| 51 | + <div class="text-xs text-gray-500"> | ||
| 52 | + Hint: use | ||
| 53 | + <code> | ||
| 54 | + <span class="text-dark-500">${</span> | ||
| 55 | + metadataKey | ||
| 56 | + <span class="text-dark-500">}</span> | ||
| 57 | + </code> | ||
| 58 | + for value from metadata, | ||
| 59 | + <code> | ||
| 60 | + <span class="text-dark-500"> $[</span> | ||
| 61 | + messageKey | ||
| 62 | + <span class="text-dark-500">] </span> | ||
| 63 | + </code> | ||
| 64 | + for value from message body to substitute "Source" and "Target" key names | ||
| 65 | + </div> | ||
| 66 | + </template> | ||
| 67 | + </AttributeConfiguration> | ||
| 68 | + </template> | ||
| 69 | + </BasicForm> | ||
| 35 | </template> | 70 | </template> |
| 1 | -import { NodeBindDataFieldEnum, NodeBindDataFieldNameEnum } from '../../../enum/node'; | 1 | +import { DetailsListEnum, DetailsListNameEnum } from '../../../enum/form'; |
| 2 | +import { | ||
| 3 | + TenantDetailsFieldsEnum, | ||
| 4 | + TenantDetailsFieldsNameEnum, | ||
| 5 | +} from '../../../enum/formField/enrichment'; | ||
| 2 | import { FormSchema } from '/@/components/Form'; | 6 | import { FormSchema } from '/@/components/Form'; |
| 3 | 7 | ||
| 4 | export const formSchemas: FormSchema[] = [ | 8 | export const formSchemas: FormSchema[] = [ |
| 5 | { | 9 | { |
| 6 | - field: NodeBindDataFieldEnum.NAME, | ||
| 7 | - component: 'Input', | ||
| 8 | - label: NodeBindDataFieldNameEnum.NAME, | 10 | + field: TenantDetailsFieldsEnum.DETAILS_LIST, |
| 11 | + component: 'Select', | ||
| 12 | + label: TenantDetailsFieldsNameEnum.DETAILS_LIST, | ||
| 13 | + required: true, | ||
| 14 | + componentProps: { | ||
| 15 | + mode: 'multiple', | ||
| 16 | + options: Object.keys(DetailsListEnum).map((value) => ({ | ||
| 17 | + label: DetailsListNameEnum[value], | ||
| 18 | + value, | ||
| 19 | + })), | ||
| 20 | + getPopupContainer: () => document.body, | ||
| 21 | + placeholder: `请选择${TenantDetailsFieldsNameEnum.DETAILS_LIST}`, | ||
| 22 | + }, | ||
| 23 | + }, | ||
| 24 | + { | ||
| 25 | + field: TenantDetailsFieldsEnum.ADD_TO_METADATA, | ||
| 26 | + component: 'Checkbox', | ||
| 27 | + label: '', | ||
| 28 | + renderComponentContent: () => ({ | ||
| 29 | + default: () => TenantDetailsFieldsNameEnum.DETAILS_LIST, | ||
| 30 | + }), | ||
| 9 | }, | 31 | }, |
| 10 | ]; | 32 | ]; |
| @@ -8,6 +8,7 @@ export const formSchemas: FormSchema[] = [ | @@ -8,6 +8,7 @@ export const formSchemas: FormSchema[] = [ | ||
| 8 | label: NodeBindDataFieldNameEnum.MESSAGE_NAMES, | 8 | label: NodeBindDataFieldNameEnum.MESSAGE_NAMES, |
| 9 | componentProps: { | 9 | componentProps: { |
| 10 | mode: 'tags', | 10 | mode: 'tags', |
| 11 | + open: false, | ||
| 11 | getPopupContainer: () => document.body, | 12 | getPopupContainer: () => document.body, |
| 12 | }, | 13 | }, |
| 13 | }, | 14 | }, |
| @@ -17,6 +18,7 @@ export const formSchemas: FormSchema[] = [ | @@ -17,6 +18,7 @@ export const formSchemas: FormSchema[] = [ | ||
| 17 | label: NodeBindDataFieldNameEnum.METADATA_NAMES, | 18 | label: NodeBindDataFieldNameEnum.METADATA_NAMES, |
| 18 | componentProps: { | 19 | componentProps: { |
| 19 | mode: 'tags', | 20 | mode: 'tags', |
| 21 | + open: false, | ||
| 20 | getPopupContainer: () => document.body, | 22 | getPopupContainer: () => document.body, |
| 21 | }, | 23 | }, |
| 22 | }, | 24 | }, |
| @@ -4,6 +4,7 @@ import { | @@ -4,6 +4,7 @@ import { | ||
| 4 | EntityTypeEnum, | 4 | EntityTypeEnum, |
| 5 | EntityTypeNameEnum, | 5 | EntityTypeNameEnum, |
| 6 | RelationTypeEnum, | 6 | RelationTypeEnum, |
| 7 | + RelationTypeNameEnum, | ||
| 7 | } from '../../../enum/form'; | 8 | } from '../../../enum/form'; |
| 8 | import { NodeBindDataFieldEnum, NodeBindDataFieldNameEnum } from '../../../enum/node'; | 9 | import { NodeBindDataFieldEnum, NodeBindDataFieldNameEnum } from '../../../enum/node'; |
| 9 | import { deviceProfilePage } from '/@/api/device/deviceManager'; | 10 | import { deviceProfilePage } from '/@/api/device/deviceManager'; |
| @@ -18,8 +19,10 @@ export const formSchemas: FormSchema[] = [ | @@ -18,8 +19,10 @@ export const formSchemas: FormSchema[] = [ | ||
| 18 | { | 19 | { |
| 19 | field: NodeBindDataFieldEnum.CHECK_FOR_SINGLE_ENTITY, | 20 | field: NodeBindDataFieldEnum.CHECK_FOR_SINGLE_ENTITY, |
| 20 | component: 'Checkbox', | 21 | component: 'Checkbox', |
| 21 | - label: NodeBindDataFieldNameEnum.CHECK_FOR_SINGLE_ENTITY, | ||
| 22 | - labelWidth: 220, | 22 | + label: '', |
| 23 | + renderComponentContent: () => ({ | ||
| 24 | + default: () => NodeBindDataFieldNameEnum.CHECK_FOR_SINGLE_ENTITY, | ||
| 25 | + }), | ||
| 23 | }, | 26 | }, |
| 24 | { | 27 | { |
| 25 | field: NodeBindDataFieldEnum.DIRECTION, | 28 | field: NodeBindDataFieldEnum.DIRECTION, |
| @@ -69,10 +72,10 @@ export const formSchemas: FormSchema[] = [ | @@ -69,10 +72,10 @@ export const formSchemas: FormSchema[] = [ | ||
| 69 | label: NodeBindDataFieldNameEnum.RELEATION_TYPE, | 72 | label: NodeBindDataFieldNameEnum.RELEATION_TYPE, |
| 70 | defaultValue: RelationTypeEnum.CONTAINS, | 73 | defaultValue: RelationTypeEnum.CONTAINS, |
| 71 | componentProps: { | 74 | componentProps: { |
| 72 | - options: [ | ||
| 73 | - { label: RelationTypeEnum.CONTAINS, value: RelationTypeEnum.CONTAINS }, | ||
| 74 | - { label: RelationTypeEnum.MANAGES, value: RelationTypeEnum.MANAGES }, | ||
| 75 | - ], | 75 | + options: Object.keys(RelationTypeEnum).map((value) => ({ |
| 76 | + label: RelationTypeNameEnum[value], | ||
| 77 | + value, | ||
| 78 | + })), | ||
| 76 | }, | 79 | }, |
| 77 | }, | 80 | }, |
| 78 | ]; | 81 | ]; |
| @@ -24,8 +24,10 @@ export const formSchemas: FormSchema[] = [ | @@ -24,8 +24,10 @@ export const formSchemas: FormSchema[] = [ | ||
| 24 | { | 24 | { |
| 25 | field: NodeBindDataFieldEnum.FETCH_PERIMETER_INFO_FROM_MESSAGE_METADATA, | 25 | field: NodeBindDataFieldEnum.FETCH_PERIMETER_INFO_FROM_MESSAGE_METADATA, |
| 26 | component: 'Checkbox', | 26 | component: 'Checkbox', |
| 27 | - label: NodeBindDataFieldNameEnum.FETCH_PERIMETER_INFO_FROM_MESSAGE_METADATA, | ||
| 28 | - labelWidth: 350, | 27 | + label: '', |
| 28 | + renderComponentContent: () => ({ | ||
| 29 | + default: () => NodeBindDataFieldNameEnum.FETCH_PERIMETER_INFO_FROM_MESSAGE_METADATA, | ||
| 30 | + }), | ||
| 29 | }, | 31 | }, |
| 30 | { | 32 | { |
| 31 | field: NodeBindDataFieldEnum.PERIMETER_KEY_NAME, | 33 | field: NodeBindDataFieldEnum.PERIMETER_KEY_NAME, |
| @@ -2,14 +2,14 @@ import { h } from 'vue'; | @@ -2,14 +2,14 @@ import { h } from 'vue'; | ||
| 2 | import { NodeBindDataFieldEnum, NodeBindDataFieldNameEnum } from '../../../enum/node'; | 2 | import { NodeBindDataFieldEnum, NodeBindDataFieldNameEnum } from '../../../enum/node'; |
| 3 | import { FormSchema, useComponentRegister } from '/@/components/Form'; | 3 | import { FormSchema, useComponentRegister } from '/@/components/Form'; |
| 4 | import HelpMessage from './HelpMessage.vue'; | 4 | import HelpMessage from './HelpMessage.vue'; |
| 5 | -import JavaScriptFilterFunctionModal from './JavaScriptFilterFunctionModal.vue'; | 5 | +import { JavascriptEditorWithTestModal } from '/@/views/rule/designer/src/components/JavaScriptFilterModal'; |
| 6 | 6 | ||
| 7 | -useComponentRegister('JavaScriptFilterFunctionModal', JavaScriptFilterFunctionModal); | 7 | +useComponentRegister('JavascriptEditorWithTestModal', JavascriptEditorWithTestModal); |
| 8 | 8 | ||
| 9 | export const formSchemas: FormSchema[] = [ | 9 | export const formSchemas: FormSchema[] = [ |
| 10 | { | 10 | { |
| 11 | field: NodeBindDataFieldEnum.JS_SCRIPT, | 11 | field: NodeBindDataFieldEnum.JS_SCRIPT, |
| 12 | - component: 'JavaScriptFilterFunctionModal', | 12 | + component: 'JavascriptEditorWithTestModal', |
| 13 | label: NodeBindDataFieldNameEnum.JS_SCRIPT, | 13 | label: NodeBindDataFieldNameEnum.JS_SCRIPT, |
| 14 | changeEvent: 'update:value', | 14 | changeEvent: 'update:value', |
| 15 | valueField: 'value', | 15 | valueField: 'value', |
| 1 | import { NodeBindDataFieldEnum, NodeBindDataFieldNameEnum } from '../../../enum/node'; | 1 | import { NodeBindDataFieldEnum, NodeBindDataFieldNameEnum } from '../../../enum/node'; |
| 2 | import { FormSchema, useComponentRegister } from '/@/components/Form'; | 2 | import { FormSchema, useComponentRegister } from '/@/components/Form'; |
| 3 | -import JavaScriptFilterFunctionModal from '../Script/JavaScriptFilterFunctionModal.vue'; | 3 | +import { JavascriptEditorWithTestModal } from '/@/views/rule/designer/src/components/JavaScriptFilterModal'; |
| 4 | + | ||
| 5 | +useComponentRegister('JavascriptEditorWithTestModal', JavascriptEditorWithTestModal); | ||
| 4 | 6 | ||
| 5 | -useComponentRegister('JavaScriptFilterFunctionModal', JavaScriptFilterFunctionModal); | ||
| 6 | export const formSchemas: FormSchema[] = [ | 7 | export const formSchemas: FormSchema[] = [ |
| 7 | { | 8 | { |
| 8 | field: NodeBindDataFieldEnum.JS_SCRIPT, | 9 | field: NodeBindDataFieldEnum.JS_SCRIPT, |
| 9 | - component: 'JavaScriptFilterFunctionModal', | 10 | + component: 'JavascriptEditorWithTestModal', |
| 10 | label: NodeBindDataFieldNameEnum.JS_SCRIPT, | 11 | label: NodeBindDataFieldNameEnum.JS_SCRIPT, |
| 11 | changeEvent: 'update:value', | 12 | changeEvent: 'update:value', |
| 12 | valueField: 'value', | 13 | valueField: 'value', |
| 13 | componentProps: { | 14 | componentProps: { |
| 14 | buttonName: 'Test Switch Function', | 15 | buttonName: 'Test Switch Function', |
| 15 | javaScriptEditorProps: { | 16 | javaScriptEditorProps: { |
| 17 | + height: 230, | ||
| 16 | functionName: 'Switch', | 18 | functionName: 'Switch', |
| 17 | paramsName: ['msg', 'metadata', 'mstType'], | 19 | paramsName: ['msg', 'metadata', 'mstType'], |
| 18 | }, | 20 | }, |
| 1 | -import { NodeBindDataFieldEnum, NodeBindDataFieldNameEnum } from '../../../enum/node'; | ||
| 2 | -import { FormSchema } from '/@/components/Form'; | 1 | +import { OriginatorSourceEnum, OriginatorSourceNameEnum } from '../../../enum/form'; |
| 2 | +import { | ||
| 3 | + ChangeOriginatorFieldsEnum, | ||
| 4 | + ChangeOriginatorFieldsNameEnum, | ||
| 5 | +} from '../../../enum/formField/transformation'; | ||
| 6 | +import { RelationsQuery } from '../../../src/components/RelationsQuery'; | ||
| 7 | +import { FormSchema, useComponentRegister } from '/@/components/Form'; | ||
| 8 | + | ||
| 9 | +useComponentRegister('RelationsQuery', RelationsQuery); | ||
| 3 | 10 | ||
| 4 | export const formSchemas: FormSchema[] = [ | 11 | export const formSchemas: FormSchema[] = [ |
| 5 | { | 12 | { |
| 6 | - field: NodeBindDataFieldEnum.NAME, | ||
| 7 | - component: 'Input', | ||
| 8 | - label: NodeBindDataFieldNameEnum.NAME, | 13 | + field: ChangeOriginatorFieldsEnum.ORIGINATOR_SOURCE, |
| 14 | + component: 'Select', | ||
| 15 | + label: ChangeOriginatorFieldsNameEnum.ORIGINATOR_SOURCE, | ||
| 16 | + required: true, | ||
| 17 | + componentProps: { | ||
| 18 | + options: Object.keys(OriginatorSourceEnum).map((value) => ({ | ||
| 19 | + label: OriginatorSourceNameEnum[value], | ||
| 20 | + value, | ||
| 21 | + })), | ||
| 22 | + getPopupContainer: () => document.body, | ||
| 23 | + placeholder: `请选择${ChangeOriginatorFieldsNameEnum.ORIGINATOR_SOURCE}`, | ||
| 24 | + }, | ||
| 25 | + }, | ||
| 26 | + { | ||
| 27 | + field: ChangeOriginatorFieldsEnum.RELATIONS_QUERY, | ||
| 28 | + component: 'RelationsQuery', | ||
| 29 | + label: ChangeOriginatorFieldsNameEnum.RELATIONS_QUERY, | ||
| 30 | + slot: ChangeOriginatorFieldsEnum.RELATIONS_QUERY, | ||
| 9 | }, | 31 | }, |
| 10 | ]; | 32 | ]; |
| @@ -3,11 +3,16 @@ | @@ -3,11 +3,16 @@ | ||
| 3 | import { BasicForm, useForm } from '/@/components/Form'; | 3 | import { BasicForm, useForm } from '/@/components/Form'; |
| 4 | import { formSchemas } from './create.config'; | 4 | import { formSchemas } from './create.config'; |
| 5 | import { NodeData } from '../../../types/node'; | 5 | import { NodeData } from '../../../types/node'; |
| 6 | + import { RelationsQuery } from '../../../src/components/RelationsQuery'; | ||
| 7 | + import { ref, unref } from 'vue'; | ||
| 8 | + import { ChangeOriginatorFieldsEnum } from '../../../enum/formField/transformation'; | ||
| 6 | 9 | ||
| 7 | defineProps<{ | 10 | defineProps<{ |
| 8 | config: NodeData; | 11 | config: NodeData; |
| 9 | }>(); | 12 | }>(); |
| 10 | 13 | ||
| 14 | + const relationsQueryElRef = ref<Nullable<InstanceType<typeof RelationsQuery>>>(); | ||
| 15 | + | ||
| 11 | const [register, { validate, getFieldsValue, setFieldsValue, resetFields }] = useForm({ | 16 | const [register, { validate, getFieldsValue, setFieldsValue, resetFields }] = useForm({ |
| 12 | schemas: formSchemas, | 17 | schemas: formSchemas, |
| 13 | showActionButtonGroup: false, | 18 | showActionButtonGroup: false, |
| @@ -16,12 +21,14 @@ | @@ -16,12 +21,14 @@ | ||
| 16 | const getValue: CreateModalDefineExposeType['getFieldsValue'] = async () => { | 21 | const getValue: CreateModalDefineExposeType['getFieldsValue'] = async () => { |
| 17 | await validate(); | 22 | await validate(); |
| 18 | const value = getFieldsValue() || {}; | 23 | const value = getFieldsValue() || {}; |
| 19 | - return value; | 24 | + const relationsQuery = unref(relationsQueryElRef)?.getFieldsValue(); |
| 25 | + return { ...value, [ChangeOriginatorFieldsEnum.RELATIONS_QUERY]: relationsQuery }; | ||
| 20 | }; | 26 | }; |
| 21 | 27 | ||
| 22 | const setValue: CreateModalDefineExposeType['setFieldsValue'] = (value) => { | 28 | const setValue: CreateModalDefineExposeType['setFieldsValue'] = (value) => { |
| 23 | resetFields(); | 29 | resetFields(); |
| 24 | setFieldsValue(value); | 30 | setFieldsValue(value); |
| 31 | + unref(relationsQueryElRef)?.setFieldsValue(value?.[ChangeOriginatorFieldsEnum.RELATIONS_QUERY]); | ||
| 25 | }; | 32 | }; |
| 26 | 33 | ||
| 27 | defineExpose({ | 34 | defineExpose({ |
| @@ -31,5 +38,9 @@ | @@ -31,5 +38,9 @@ | ||
| 31 | </script> | 38 | </script> |
| 32 | 39 | ||
| 33 | <template> | 40 | <template> |
| 34 | - <BasicForm @register="register" /> | 41 | + <BasicForm @register="register"> |
| 42 | + <template #relationsQuery="{ field, model }"> | ||
| 43 | + <RelationsQuery ref="relationsQueryElRef" v-model:value="model[field]" /> | ||
| 44 | + </template> | ||
| 45 | + </BasicForm> | ||
| 35 | </template> | 46 | </template> |
| 1 | -import { NodeBindDataFieldEnum, NodeBindDataFieldNameEnum } from '../../../enum/node'; | ||
| 2 | -import { FormSchema } from '/@/components/Form'; | 1 | +import { ScriptFieldsEnum, ScriptFieldsNameEnum } from '../../../enum/formField/transformation'; |
| 2 | +import { JavascriptEditorWithTestModal } from '../../../src/components/JavaScriptFilterModal'; | ||
| 3 | +import { FormSchema, useComponentRegister } from '/@/components/Form'; | ||
| 4 | + | ||
| 5 | +useComponentRegister('JavascriptEditorWithTestModal', JavascriptEditorWithTestModal); | ||
| 3 | 6 | ||
| 4 | export const formSchemas: FormSchema[] = [ | 7 | export const formSchemas: FormSchema[] = [ |
| 5 | { | 8 | { |
| 6 | - field: NodeBindDataFieldEnum.NAME, | ||
| 7 | - component: 'Input', | ||
| 8 | - label: NodeBindDataFieldNameEnum.NAME, | 9 | + field: ScriptFieldsEnum.JS_SCRIPT, |
| 10 | + component: 'JavascriptEditorWithTestModal', | ||
| 11 | + label: ScriptFieldsNameEnum.JS_SCRIPT, | ||
| 12 | + changeEvent: 'update:value', | ||
| 13 | + valueField: 'value', | ||
| 14 | + componentProps: { | ||
| 15 | + javaScriptEditorProps: { | ||
| 16 | + functionName: 'Transform', | ||
| 17 | + paramsName: ['msg', 'metadata', 'msgType'], | ||
| 18 | + }, | ||
| 19 | + buttonName: 'Test transformer function', | ||
| 20 | + }, | ||
| 9 | }, | 21 | }, |
| 10 | ]; | 22 | ]; |
| 1 | -import { NodeBindDataFieldEnum, NodeBindDataFieldNameEnum } from '../../../enum/node'; | 1 | +import { MailBodyTypeEnum, MailBodyTypeNameEnum } from '../../../enum/form'; |
| 2 | +import { ToEmailFieldsEnum, ToEmailFieldsNameEnum } from '../../../enum/formField/transformation'; | ||
| 2 | import { FormSchema } from '/@/components/Form'; | 3 | import { FormSchema } from '/@/components/Form'; |
| 3 | 4 | ||
| 4 | export const formSchemas: FormSchema[] = [ | 5 | export const formSchemas: FormSchema[] = [ |
| 5 | { | 6 | { |
| 6 | - field: NodeBindDataFieldEnum.NAME, | 7 | + field: ToEmailFieldsEnum.FROM_TEMPLATE, |
| 7 | component: 'Input', | 8 | component: 'Input', |
| 8 | - label: NodeBindDataFieldNameEnum.NAME, | 9 | + label: ToEmailFieldsNameEnum.FROM_TEMPLATE, |
| 10 | + helpMessage: [ | ||
| 11 | + 'Hint: use ${metadataKey} for value from metadata, $[messageKey] for value from message body', | ||
| 12 | + ], | ||
| 13 | + componentProps: { | ||
| 14 | + placeholder: `请输入${ToEmailFieldsNameEnum.FROM_TEMPLATE}`, | ||
| 15 | + }, | ||
| 16 | + }, | ||
| 17 | + { | ||
| 18 | + field: ToEmailFieldsEnum.TO_TEMPLATE, | ||
| 19 | + component: 'Input', | ||
| 20 | + label: ToEmailFieldsNameEnum.TO_TEMPLATE, | ||
| 21 | + helpMessage: [ | ||
| 22 | + 'Comma separated address list, use ${metadataKey} for value from metadata, $[messageKey] for value from message body', | ||
| 23 | + ], | ||
| 24 | + componentProps: { | ||
| 25 | + placeholder: `请输入${ToEmailFieldsNameEnum.FROM_TEMPLATE}`, | ||
| 26 | + }, | ||
| 27 | + }, | ||
| 28 | + { | ||
| 29 | + field: ToEmailFieldsEnum.CC_TEMPLATE, | ||
| 30 | + component: 'Input', | ||
| 31 | + label: ToEmailFieldsNameEnum.CC_TEMPLATE, | ||
| 32 | + helpMessage: [ | ||
| 33 | + 'Comma separated address list, use ${metadataKey} for value from metadata, $[messageKey] for value from message body', | ||
| 34 | + ], | ||
| 35 | + componentProps: { | ||
| 36 | + placeholder: `请输入${ToEmailFieldsNameEnum.FROM_TEMPLATE}`, | ||
| 37 | + }, | ||
| 38 | + }, | ||
| 39 | + { | ||
| 40 | + field: ToEmailFieldsEnum.BCC_TEMPLATE, | ||
| 41 | + component: 'Input', | ||
| 42 | + label: ToEmailFieldsNameEnum.BCC_TEMPLATE, | ||
| 43 | + helpMessage: [ | ||
| 44 | + 'Comma separated address list, use ${metadataKey} for value from metadata, $[messageKey] for value from message body', | ||
| 45 | + ], | ||
| 46 | + componentProps: { | ||
| 47 | + placeholder: `请输入${ToEmailFieldsNameEnum.FROM_TEMPLATE}`, | ||
| 48 | + }, | ||
| 49 | + }, | ||
| 50 | + { | ||
| 51 | + field: ToEmailFieldsEnum.SUBJECT_TEMPLATE, | ||
| 52 | + component: 'Input', | ||
| 53 | + label: ToEmailFieldsNameEnum.SUBJECT_TEMPLATE, | ||
| 54 | + helpMessage: [ | ||
| 55 | + 'Hint: use ${metadataKey} for value from metadata, $[messageKey] for value from message body', | ||
| 56 | + ], | ||
| 57 | + componentProps: { | ||
| 58 | + placeholder: `请输入${ToEmailFieldsNameEnum.FROM_TEMPLATE}`, | ||
| 59 | + }, | ||
| 60 | + }, | ||
| 61 | + { | ||
| 62 | + field: ToEmailFieldsEnum.MAIL_BODY_TYPE, | ||
| 63 | + component: 'Select', | ||
| 64 | + label: ToEmailFieldsNameEnum.MAIL_BODY_TYPE, | ||
| 65 | + componentProps: ({ formActionType }) => { | ||
| 66 | + const { setFieldsValue } = formActionType; | ||
| 67 | + return { | ||
| 68 | + options: [ | ||
| 69 | + { label: MailBodyTypeNameEnum.PLAIN_TEXT, value: MailBodyTypeEnum.PLAIN_TEXT }, | ||
| 70 | + { label: MailBodyTypeNameEnum.HTML, value: MailBodyTypeEnum.HTML }, | ||
| 71 | + { label: MailBodyTypeNameEnum.DYNAMIC, value: MailBodyTypeEnum.DYNAMIC }, | ||
| 72 | + ], | ||
| 73 | + placeholder: `请选择${ToEmailFieldsNameEnum.MAIL_BODY_TYPE}`, | ||
| 74 | + getPopupContainer: () => document.body, | ||
| 75 | + onChange: () => { | ||
| 76 | + setFieldsValue({ [ToEmailFieldsEnum.IS_HTML_TEMPLATE]: null }); | ||
| 77 | + }, | ||
| 78 | + }; | ||
| 79 | + }, | ||
| 80 | + }, | ||
| 81 | + { | ||
| 82 | + field: ToEmailFieldsEnum.IS_HTML_TEMPLATE, | ||
| 83 | + component: 'Input', | ||
| 84 | + label: ToEmailFieldsNameEnum.IS_HTML_TEMPLATE, | ||
| 85 | + show: ({ model }) => model[ToEmailFieldsEnum.MAIL_BODY_TYPE] === MailBodyTypeEnum.DYNAMIC, | ||
| 86 | + helpMessage: [ | ||
| 87 | + 'Hint: use ${metadataKey} for value from metadata, $[messageKey] for value from message body', | ||
| 88 | + ], | ||
| 89 | + componentProps: { | ||
| 90 | + placeholder: `请输入${ToEmailFieldsNameEnum.IS_HTML_TEMPLATE}`, | ||
| 91 | + }, | ||
| 92 | + }, | ||
| 93 | + { | ||
| 94 | + field: ToEmailFieldsEnum.BODY_TEMPLATE, | ||
| 95 | + component: 'InputTextArea', | ||
| 96 | + label: ToEmailFieldsEnum.BODY_TEMPLATE, | ||
| 97 | + componentProps: { | ||
| 98 | + placeholder: `请输入${ToEmailFieldsNameEnum.BODY_TEMPLATE}`, | ||
| 99 | + autoSize: { minRows: 3 }, | ||
| 100 | + }, | ||
| 9 | }, | 101 | }, |
| 10 | ]; | 102 | ]; |
| @@ -19,13 +19,17 @@ const BasicConnectionComponent = { | @@ -19,13 +19,17 @@ const BasicConnectionComponent = { | ||
| 19 | import('../src/components/CreateEdgeModal/CustomRelations.vue'), | 19 | import('../src/components/CreateEdgeModal/CustomRelations.vue'), |
| 20 | }; | 20 | }; |
| 21 | 21 | ||
| 22 | -export const fetchNodeComponent = (key: string, flag: FetchNodeComFlagTypeENum) => { | 22 | +export const fetchNodeComponent = (config: NodeItemConfigType, flag: FetchNodeComFlagTypeENum) => { |
| 23 | + const { key, categoryType } = config; | ||
| 23 | const modules = | 24 | const modules = |
| 24 | flag === FetchNodeComFlagTypeENum.CONNECTION_MODAL ? connectionModules : createModules; | 25 | flag === FetchNodeComFlagTypeENum.CONNECTION_MODAL ? connectionModules : createModules; |
| 26 | + | ||
| 25 | const modulesName = Object.keys(modules); | 27 | const modulesName = Object.keys(modules); |
| 26 | const path = modulesName.find((item) => { | 28 | const path = modulesName.find((item) => { |
| 27 | const temp = item.split('/'); | 29 | const temp = item.split('/'); |
| 28 | - return temp[temp.length - 2] === key; | 30 | + const categoryName = temp[temp.length - 3]; |
| 31 | + const fileName = temp[temp.length - 2]; | ||
| 32 | + return fileName === key && categoryType.toUpperCase() === categoryName.toUpperCase(); | ||
| 29 | }); | 33 | }); |
| 30 | return path ? modules[path] : null; | 34 | return path ? modules[path] : null; |
| 31 | }; | 35 | }; |
| @@ -40,8 +44,7 @@ export const fetchConnectionComponent = async (config: NodeItemConfigType) => { | @@ -40,8 +44,7 @@ export const fetchConnectionComponent = async (config: NodeItemConfigType) => { | ||
| 40 | }; | 44 | }; |
| 41 | 45 | ||
| 42 | export const fetchCreateComponent = async (config: NodeItemConfigType) => { | 46 | export const fetchCreateComponent = async (config: NodeItemConfigType) => { |
| 43 | - const { key } = config; | ||
| 44 | - return fetchNodeComponent(key, FetchNodeComFlagTypeENum.CREATE_MODAL); | 47 | + return fetchNodeComponent(config, FetchNodeComFlagTypeENum.CREATE_MODAL); |
| 45 | }; | 48 | }; |
| 46 | 49 | ||
| 47 | export const allComponents: Record< | 50 | export const allComponents: Record< |
| @@ -56,14 +59,14 @@ export const allComponents: Record< | @@ -56,14 +59,14 @@ export const allComponents: Record< | ||
| 56 | category: EnrichmentCategoryConfig, | 59 | category: EnrichmentCategoryConfig, |
| 57 | components: EnrichmentComponents, | 60 | components: EnrichmentComponents, |
| 58 | }, | 61 | }, |
| 59 | - [RuleNodeTypeEnum.ACTION]: { | ||
| 60 | - category: ActionCategoryConfig, | ||
| 61 | - components: ActionComponents, | ||
| 62 | - }, | ||
| 63 | [RuleNodeTypeEnum.TRANSFORMATION]: { | 62 | [RuleNodeTypeEnum.TRANSFORMATION]: { |
| 64 | category: TransformationCategoryConfig, | 63 | category: TransformationCategoryConfig, |
| 65 | components: TransformationComponents, | 64 | components: TransformationComponents, |
| 66 | }, | 65 | }, |
| 66 | + [RuleNodeTypeEnum.ACTION]: { | ||
| 67 | + category: ActionCategoryConfig, | ||
| 68 | + components: ActionComponents, | ||
| 69 | + }, | ||
| 67 | [RuleNodeTypeEnum.EXTERNAL]: { | 70 | [RuleNodeTypeEnum.EXTERNAL]: { |
| 68 | category: ExternalCategoryConfig, | 71 | category: ExternalCategoryConfig, |
| 69 | components: ExternalComponents, | 72 | components: ExternalComponents, |
| 1 | +export { default as AttributeConfiguration } from './index.vue'; |
| 1 | +<script setup lang="ts"> | ||
| 2 | + import { Button, Tooltip, Row, Col } from 'ant-design-vue'; | ||
| 3 | + import { Icon } from '/@/components/Icon'; | ||
| 4 | + import { BasicForm, FormActionType, FormProps, FormSchema } from '/@/components/Form'; | ||
| 5 | + import { computed, ref, unref, watch } from 'vue'; | ||
| 6 | + import { buildShortUUID } from '/@/utils/uuid'; | ||
| 7 | + import { isNullOrUnDef } from '/@/utils/is'; | ||
| 8 | + import { ComponentType } from '/@/components/Form/src/types'; | ||
| 9 | + | ||
| 10 | + enum FormFieldEnum { | ||
| 11 | + KEY = 'key', | ||
| 12 | + VALUE = 'value', | ||
| 13 | + } | ||
| 14 | + | ||
| 15 | + interface ListItemType { | ||
| 16 | + [FormFieldEnum.KEY]?: string; | ||
| 17 | + [FormFieldEnum.VALUE]?: string; | ||
| 18 | + uuid: string; | ||
| 19 | + } | ||
| 20 | + | ||
| 21 | + const props = withDefaults( | ||
| 22 | + defineProps<{ | ||
| 23 | + value?: Recordable; | ||
| 24 | + formProps?: FormProps; | ||
| 25 | + hiddenInputBorder?: boolean; | ||
| 26 | + showLabel?: boolean; | ||
| 27 | + keyLabel?: string; | ||
| 28 | + valueLabel?: string; | ||
| 29 | + keyComponent?: ComponentType; | ||
| 30 | + valueComponent?: ComponentType; | ||
| 31 | + }>(), | ||
| 32 | + { | ||
| 33 | + keyComponent: 'Input', | ||
| 34 | + valueComponent: 'Input', | ||
| 35 | + value: () => ({}), | ||
| 36 | + formProps: () => ({ layout: 'vertical' }), | ||
| 37 | + showLabel: true, | ||
| 38 | + hiddenInputBorder: true, | ||
| 39 | + } | ||
| 40 | + ); | ||
| 41 | + | ||
| 42 | + const emit = defineEmits(['update:value']); | ||
| 43 | + | ||
| 44 | + const getPlaceholder = (label = '') => `请输入${label}`; | ||
| 45 | + | ||
| 46 | + const getRules = (label = '') => { | ||
| 47 | + return [{ required: true, message: getPlaceholder(label), trigger: ['change', 'blur'] }]; | ||
| 48 | + }; | ||
| 49 | + | ||
| 50 | + const mergeComponentProps = (label = '') => { | ||
| 51 | + return { | ||
| 52 | + placeholder: getPlaceholder(label), | ||
| 53 | + onBlur: handleOnBlur, | ||
| 54 | + }; | ||
| 55 | + }; | ||
| 56 | + | ||
| 57 | + const getSchemas = computed<FormSchema[]>(() => { | ||
| 58 | + const { keyComponent, valueComponent, keyLabel, valueLabel } = props; | ||
| 59 | + return [ | ||
| 60 | + { | ||
| 61 | + field: FormFieldEnum.KEY, | ||
| 62 | + label: '', | ||
| 63 | + colProps: { span: 11 }, | ||
| 64 | + component: keyComponent, | ||
| 65 | + rules: getRules(keyLabel), | ||
| 66 | + componentProps: mergeComponentProps(keyLabel), | ||
| 67 | + }, | ||
| 68 | + { | ||
| 69 | + field: FormFieldEnum.VALUE, | ||
| 70 | + label: '', | ||
| 71 | + colProps: { span: 11, offset: 1 }, | ||
| 72 | + component: valueComponent, | ||
| 73 | + rules: getRules(valueLabel), | ||
| 74 | + componentProps: mergeComponentProps(valueLabel), | ||
| 75 | + }, | ||
| 76 | + ] as FormSchema[]; | ||
| 77 | + }); | ||
| 78 | + | ||
| 79 | + const handleOnBlur = () => { | ||
| 80 | + const value = getFieldsValue(); | ||
| 81 | + | ||
| 82 | + if ( | ||
| 83 | + unref(list).length === Object.keys(value).length && | ||
| 84 | + Object.values(value).some((item) => isNullOrUnDef(item)) | ||
| 85 | + ) | ||
| 86 | + return; | ||
| 87 | + emit('update:value', value); | ||
| 88 | + }; | ||
| 89 | + | ||
| 90 | + const list = ref<ListItemType[]>([{ uuid: buildShortUUID() }]); | ||
| 91 | + | ||
| 92 | + const formListElRef = ref<Nullable<FormActionType>[]>([]); | ||
| 93 | + | ||
| 94 | + const handleAdd = () => { | ||
| 95 | + list.value.push({ uuid: buildShortUUID() }); | ||
| 96 | + }; | ||
| 97 | + | ||
| 98 | + const handleDelete = (string: string) => { | ||
| 99 | + const index = unref(list).findIndex((item) => item.uuid === string); | ||
| 100 | + ~index && unref(list).splice(index, 1); | ||
| 101 | + }; | ||
| 102 | + | ||
| 103 | + const validate = async () => { | ||
| 104 | + for (const item of unref(formListElRef)) { | ||
| 105 | + await item?.validate(); | ||
| 106 | + } | ||
| 107 | + }; | ||
| 108 | + | ||
| 109 | + const getFieldsValue = (): Recordable => { | ||
| 110 | + return unref(formListElRef) | ||
| 111 | + .map((item) => item?.getFieldsValue() as Record<FormFieldEnum, string>) | ||
| 112 | + .reduce( | ||
| 113 | + (prev, next) => ({ ...prev, ...(next.key ? { [next.key]: next.value } : {}) }), | ||
| 114 | + {} as Recordable | ||
| 115 | + ); | ||
| 116 | + }; | ||
| 117 | + | ||
| 118 | + const setFieldsValue = (record: Recordable) => { | ||
| 119 | + const keys = Object.keys(record); | ||
| 120 | + | ||
| 121 | + const valueList: ListItemType[] = []; | ||
| 122 | + | ||
| 123 | + for (const key of keys) { | ||
| 124 | + const value = record[key]; | ||
| 125 | + const itemValue: ListItemType = { | ||
| 126 | + uuid: buildShortUUID(), | ||
| 127 | + [FormFieldEnum.KEY]: key, | ||
| 128 | + [FormFieldEnum.VALUE]: value, | ||
| 129 | + }; | ||
| 130 | + valueList.push(itemValue); | ||
| 131 | + } | ||
| 132 | + | ||
| 133 | + list.value = valueList; | ||
| 134 | + | ||
| 135 | + if (!list.value.length) list.value = [{ uuid: buildShortUUID() }]; | ||
| 136 | + }; | ||
| 137 | + | ||
| 138 | + watch( | ||
| 139 | + () => props.value, | ||
| 140 | + (value) => { | ||
| 141 | + setFieldsValue(value); | ||
| 142 | + }, | ||
| 143 | + { | ||
| 144 | + immediate: true, | ||
| 145 | + } | ||
| 146 | + ); | ||
| 147 | + | ||
| 148 | + defineExpose({ | ||
| 149 | + validate, | ||
| 150 | + getFieldsValue, | ||
| 151 | + setFieldsValue, | ||
| 152 | + }); | ||
| 153 | +</script> | ||
| 154 | + | ||
| 155 | +<template> | ||
| 156 | + <section | ||
| 157 | + :class="[hiddenInputBorder && 'hidden-input-border', 'attribute-configuration-form']" | ||
| 158 | + class="h-full flex flex-col" | ||
| 159 | + > | ||
| 160 | + <slot name="beforeForm"></slot> | ||
| 161 | + <Row v-if="showLabel" type="flex" class="w-full h-6 font-medium"> | ||
| 162 | + <Col :span="11">{{ keyLabel }}</Col> | ||
| 163 | + <Col :span="11" :offset="1">{{ valueLabel }}</Col> | ||
| 164 | + <Col :span="1" /> | ||
| 165 | + </Row> | ||
| 166 | + <section class="pr-2 overflow-x-hidden overflow-y-auto"> | ||
| 167 | + <main class="flex items-center justify-between" v-for="item in list" :key="item.uuid"> | ||
| 168 | + <BasicForm | ||
| 169 | + ref="formListElRef" | ||
| 170 | + :model="item" | ||
| 171 | + class="w-full" | ||
| 172 | + :schemas="getSchemas" | ||
| 173 | + :showActionButtonGroup="false" | ||
| 174 | + /> | ||
| 175 | + <Tooltip title="删除"> | ||
| 176 | + <Icon | ||
| 177 | + icon="material-symbols:close" | ||
| 178 | + class="cursor-pointer svg:text-2xl" | ||
| 179 | + @click="handleDelete(item.uuid)" | ||
| 180 | + /> | ||
| 181 | + </Tooltip> | ||
| 182 | + </main> | ||
| 183 | + </section> | ||
| 184 | + | ||
| 185 | + <slot name="afterForm"></slot> | ||
| 186 | + | ||
| 187 | + <footer> | ||
| 188 | + <Button type="primary" class="text-light-50 mt-4 !flex items-center" @click="handleAdd"> | ||
| 189 | + <Icon icon="material-symbols:add" class="svg:text-xl" /> | ||
| 190 | + <span>添加</span> | ||
| 191 | + </Button> | ||
| 192 | + </footer> | ||
| 193 | + </section> | ||
| 194 | +</template> | ||
| 195 | + | ||
| 196 | +<style lang="less" scoped> | ||
| 197 | + .attribute-configuration-form.hidden-input-border { | ||
| 198 | + :deep(.ant-input-affix-wrapper) { | ||
| 199 | + @apply border-t-transparent border-l-transparent border-r-transparent; | ||
| 200 | + } | ||
| 201 | + | ||
| 202 | + :deep(.ant-input-affix-wrapper-focused) { | ||
| 203 | + @apply shadow-none; | ||
| 204 | + } | ||
| 205 | + } | ||
| 206 | +</style> |
| 1 | +import { EntityTypeEnum, RelationTypeEnum } from '../../../enum/form'; | ||
| 2 | + | ||
| 3 | +export enum FormFieldsEnum { | ||
| 4 | + RELATION_TYPE = 'relationType', | ||
| 5 | + ENTITY_TYPES = 'entityTypes', | ||
| 6 | + UUID = 'uuid', | ||
| 7 | +} | ||
| 8 | + | ||
| 9 | +export interface ListItemType { | ||
| 10 | + uuid?: string; | ||
| 11 | + [FormFieldsEnum.RELATION_TYPE]: RelationTypeEnum; | ||
| 12 | + [FormFieldsEnum.ENTITY_TYPES]: EntityTypeEnum[]; | ||
| 13 | +} |
| 1 | +export { default as CorrelationFilters } from './index.vue'; |
| 1 | +<script lang="ts" setup> | ||
| 2 | + import { Card, Row, Button, Tooltip, Col, Empty } from 'ant-design-vue'; | ||
| 3 | + import { computed, nextTick, ref, toRaw, unref, watch } from 'vue'; | ||
| 4 | + import { | ||
| 5 | + EntityTypeEnum, | ||
| 6 | + EntityTypeNameEnum, | ||
| 7 | + RelationTypeEnum, | ||
| 8 | + RelationTypeNameEnum, | ||
| 9 | + } from '../../../enum/form'; | ||
| 10 | + import { ListItemType, FormFieldsEnum } from './config'; | ||
| 11 | + import { BasicForm, FormActionType, FormSchema } from '/@/components/Form'; | ||
| 12 | + import { Icon } from '/@/components/Icon'; | ||
| 13 | + import { isArray } from '/@/utils/is'; | ||
| 14 | + import { buildShortUUID } from '/@/utils/uuid'; | ||
| 15 | + | ||
| 16 | + const props = withDefaults( | ||
| 17 | + defineProps<{ | ||
| 18 | + value?: ListItemType[]; | ||
| 19 | + allowAddFilters?: boolean; | ||
| 20 | + required?: boolean; | ||
| 21 | + }>(), | ||
| 22 | + { | ||
| 23 | + value: () => [], | ||
| 24 | + allowAddFilters: true, | ||
| 25 | + } | ||
| 26 | + ); | ||
| 27 | + | ||
| 28 | + const emit = defineEmits(['update:value', 'change']); | ||
| 29 | + | ||
| 30 | + const list = ref<ListItemType[]>([]); | ||
| 31 | + | ||
| 32 | + const listFormElRef = ref<Nullable<FormActionType>[]>([]); | ||
| 33 | + | ||
| 34 | + const focusFlag = ref(false); | ||
| 35 | + | ||
| 36 | + const getFormSchemas = computed<FormSchema[]>(() => { | ||
| 37 | + const { required, allowAddFilters } = props; | ||
| 38 | + return [ | ||
| 39 | + { | ||
| 40 | + field: FormFieldsEnum.RELATION_TYPE, | ||
| 41 | + component: 'Select', | ||
| 42 | + label: allowAddFilters ? '' : '关联类型', | ||
| 43 | + colProps: allowAddFilters ? { span: 11 } : undefined, | ||
| 44 | + required, | ||
| 45 | + componentProps: { | ||
| 46 | + options: Object.keys(RelationTypeEnum).map((value) => ({ | ||
| 47 | + label: RelationTypeNameEnum[value], | ||
| 48 | + value, | ||
| 49 | + })), | ||
| 50 | + placeholder: '请选择类型', | ||
| 51 | + onFocus: () => (focusFlag.value = true), | ||
| 52 | + onBlur: () => (focusFlag.value = false), | ||
| 53 | + onChange: handleSelectChange, | ||
| 54 | + getPopupContainer: () => document.body, | ||
| 55 | + }, | ||
| 56 | + }, | ||
| 57 | + { | ||
| 58 | + field: FormFieldsEnum.ENTITY_TYPES, | ||
| 59 | + component: 'Select', | ||
| 60 | + label: allowAddFilters ? '' : '设备类型', | ||
| 61 | + colProps: allowAddFilters ? { span: 11, offset: 1 } : undefined, | ||
| 62 | + required, | ||
| 63 | + componentProps: { | ||
| 64 | + mode: 'multiple', | ||
| 65 | + options: Object.keys(EntityTypeEnum).map((value) => ({ | ||
| 66 | + label: EntityTypeNameEnum[value], | ||
| 67 | + value, | ||
| 68 | + })), | ||
| 69 | + onFocus: () => (focusFlag.value = true), | ||
| 70 | + onBlur: () => (focusFlag.value = false), | ||
| 71 | + onChange: handleSelectChange, | ||
| 72 | + placeholder: '请选择实体类型', | ||
| 73 | + getPopupContainer: () => document.body, | ||
| 74 | + }, | ||
| 75 | + }, | ||
| 76 | + ]; | ||
| 77 | + }); | ||
| 78 | + | ||
| 79 | + function getDefaultItem(): ListItemType { | ||
| 80 | + return { | ||
| 81 | + uuid: buildShortUUID(), | ||
| 82 | + entityTypes: [], | ||
| 83 | + relationType: RelationTypeEnum.CONTAINS, | ||
| 84 | + }; | ||
| 85 | + } | ||
| 86 | + | ||
| 87 | + function setFieldsValue(value: ListItemType[]) { | ||
| 88 | + const res: ListItemType[] = []; | ||
| 89 | + value = isArray(value) ? value : []; | ||
| 90 | + | ||
| 91 | + for (const item of value) { | ||
| 92 | + res.push({ | ||
| 93 | + ...item, | ||
| 94 | + uuid: item.uuid ? item.uuid : buildShortUUID(), | ||
| 95 | + }); | ||
| 96 | + } | ||
| 97 | + | ||
| 98 | + if (!res.length) res.push(getDefaultItem()); | ||
| 99 | + | ||
| 100 | + list.value = res; | ||
| 101 | + } | ||
| 102 | + | ||
| 103 | + const handleAdd = () => { | ||
| 104 | + emit('update:value', [...getFieldsValue(), getDefaultItem()]); | ||
| 105 | + }; | ||
| 106 | + | ||
| 107 | + const handleDelete = (item: ListItemType) => { | ||
| 108 | + const index = unref(list).findIndex((temp) => temp.uuid === item.uuid); | ||
| 109 | + ~index && unref(list).splice(index, 1); | ||
| 110 | + ~index && unref(listFormElRef).splice(index, 1); | ||
| 111 | + emit('update:value', getFieldsValue()); | ||
| 112 | + }; | ||
| 113 | + | ||
| 114 | + const validate = async () => { | ||
| 115 | + for (const item of unref(listFormElRef)) { | ||
| 116 | + await item?.validate(); | ||
| 117 | + } | ||
| 118 | + | ||
| 119 | + return getFieldsValue(); | ||
| 120 | + }; | ||
| 121 | + | ||
| 122 | + const getFieldsValue = (): ListItemType[] => { | ||
| 123 | + return unref(listFormElRef).map((item) => ({ | ||
| 124 | + ...((item?.getFieldsValue() || {}) as ListItemType), | ||
| 125 | + uuid: (item as any)?.model?.uuid, | ||
| 126 | + })); | ||
| 127 | + }; | ||
| 128 | + | ||
| 129 | + const handleSelectChange = async () => { | ||
| 130 | + await nextTick(); | ||
| 131 | + const value = getFieldsValue(); | ||
| 132 | + emit('change', value); | ||
| 133 | + emit('update:value', value); | ||
| 134 | + }; | ||
| 135 | + | ||
| 136 | + watch( | ||
| 137 | + () => props.value, | ||
| 138 | + (target) => { | ||
| 139 | + if (unref(focusFlag)) return; | ||
| 140 | + setFieldsValue(toRaw(unref(target))); | ||
| 141 | + }, | ||
| 142 | + { | ||
| 143 | + immediate: true, | ||
| 144 | + } | ||
| 145 | + ); | ||
| 146 | + | ||
| 147 | + defineExpose({ | ||
| 148 | + validate, | ||
| 149 | + setFieldsValue, | ||
| 150 | + getFieldsValue, | ||
| 151 | + }); | ||
| 152 | +</script> | ||
| 153 | + | ||
| 154 | +<template> | ||
| 155 | + <section class="correlation-filters-form"> | ||
| 156 | + <section v-if="allowAddFilters"> | ||
| 157 | + <Row v-if="list.length" class="w-full px-4 py-2 font-semibold"> | ||
| 158 | + <Col :span="11"> 类型 </Col> | ||
| 159 | + <Col :span="11" :offset="1"> 实体类型 </Col> | ||
| 160 | + </Row> | ||
| 161 | + <Card v-for="item in list" :key="item.uuid" class="shadow-lg"> | ||
| 162 | + <main class="flex justify-between items-top"> | ||
| 163 | + <BasicForm | ||
| 164 | + ref="listFormElRef" | ||
| 165 | + class="w-full" | ||
| 166 | + :schemas="getFormSchemas" | ||
| 167 | + :model="item" | ||
| 168 | + :showActionButtonGroup="false" | ||
| 169 | + /> | ||
| 170 | + <Tooltip title="删除"> | ||
| 171 | + <Icon | ||
| 172 | + icon="material-symbols:close" | ||
| 173 | + class="svg:text-2xl cursor-pointer" | ||
| 174 | + @click="handleDelete(item)" | ||
| 175 | + /> | ||
| 176 | + </Tooltip> | ||
| 177 | + </main> | ||
| 178 | + </Card> | ||
| 179 | + | ||
| 180 | + <Empty | ||
| 181 | + v-if="!list.length" | ||
| 182 | + description="任意关联" | ||
| 183 | + :image="Empty.PRESENTED_IMAGE_SIMPLE" | ||
| 184 | + class="text-gray-600" | ||
| 185 | + /> | ||
| 186 | + </section> | ||
| 187 | + | ||
| 188 | + <BasicForm | ||
| 189 | + v-if="!allowAddFilters" | ||
| 190 | + :schemas="getFormSchemas" | ||
| 191 | + :model="list[0]" | ||
| 192 | + :showActionButtonGroup="false" | ||
| 193 | + /> | ||
| 194 | + | ||
| 195 | + <Button | ||
| 196 | + v-if="allowAddFilters" | ||
| 197 | + class="mt-4 !flex items-center" | ||
| 198 | + @click="handleAdd" | ||
| 199 | + type="primary" | ||
| 200 | + > | ||
| 201 | + <Icon icon="material-symbols:add" /> | ||
| 202 | + <span>添加</span> | ||
| 203 | + </Button> | ||
| 204 | + </section> | ||
| 205 | +</template> | ||
| 206 | + | ||
| 207 | +<style lang="less" scoped> | ||
| 208 | + .correlation-filters-form { | ||
| 209 | + :deep(.ant-card) { | ||
| 210 | + & ~ .ant-card { | ||
| 211 | + @apply mt-2; | ||
| 212 | + } | ||
| 213 | + | ||
| 214 | + .ant-card-body { | ||
| 215 | + @apply p-4; | ||
| 216 | + } | ||
| 217 | + } | ||
| 218 | + } | ||
| 219 | +</style> |
| @@ -17,18 +17,19 @@ export const TopFormSchemas: FormSchema[] = [ | @@ -17,18 +17,19 @@ export const TopFormSchemas: FormSchema[] = [ | ||
| 17 | { | 17 | { |
| 18 | field: NodeBindDataFieldEnum.DEBUG_MODE, | 18 | field: NodeBindDataFieldEnum.DEBUG_MODE, |
| 19 | component: 'Checkbox', | 19 | component: 'Checkbox', |
| 20 | - label: NodeBindDataFieldNameEnum.DEBUG_MODE, | 20 | + label: '', |
| 21 | colProps: { | 21 | colProps: { |
| 22 | offset: 2, | 22 | offset: 2, |
| 23 | span: 6, | 23 | span: 6, |
| 24 | }, | 24 | }, |
| 25 | - itemProps: { | ||
| 26 | - labelCol: { span: 14 }, | ||
| 27 | - wrapperCol: { span: 10 }, | ||
| 28 | - }, | ||
| 29 | componentProps: { | 25 | componentProps: { |
| 30 | placeholder: `请输入${NodeBindDataFieldNameEnum.NAME}`, | 26 | placeholder: `请输入${NodeBindDataFieldNameEnum.NAME}`, |
| 31 | }, | 27 | }, |
| 28 | + renderComponentContent: () => { | ||
| 29 | + return { | ||
| 30 | + default: () => NodeBindDataFieldNameEnum.DEBUG_MODE, | ||
| 31 | + }; | ||
| 32 | + }, | ||
| 32 | }, | 33 | }, |
| 33 | ]; | 34 | ]; |
| 34 | 35 |
src/views/rule/designer/src/components/JavaScriptFilterModal/JavaScriptFilterTest.vue
renamed from
src/views/rule/designer/packages/Filter/Script/ScriptFilterTest.vue
| 1 | <script lang="ts" setup> | 1 | <script lang="ts" setup> |
| 2 | - import { Card, Select, Tag, Form, Button, Input } from 'ant-design-vue'; | ||
| 3 | - import { ref, unref, watch } from 'vue'; | 2 | + import { Card, Select, Tag, Form, Button } from 'ant-design-vue'; |
| 3 | + import { ref, toRaw, unref, watch } from 'vue'; | ||
| 4 | import { MessageTypesFilterEnum, MessageTypesFilterNameEnum } from '../../../enum/form'; | 4 | import { MessageTypesFilterEnum, MessageTypesFilterNameEnum } from '../../../enum/form'; |
| 5 | import { JSONEditor } from '/@/components/CodeEditor'; | 5 | import { JSONEditor } from '/@/components/CodeEditor'; |
| 6 | - import { buildShortUUID } from '/@/utils/uuid'; | ||
| 7 | import { Icon } from '/@/components/Icon'; | 6 | import { Icon } from '/@/components/Icon'; |
| 8 | import { JavaScriptFunctionEditor } from '/@/components/Form'; | 7 | import { JavaScriptFunctionEditor } from '/@/components/Form'; |
| 9 | import { useJsonParse } from '/@/hooks/business/useJsonParse'; | 8 | import { useJsonParse } from '/@/hooks/business/useJsonParse'; |
| 10 | import { useMessage } from '/@/hooks/web/useMessage'; | 9 | import { useMessage } from '/@/hooks/web/useMessage'; |
| 11 | - import { isNullOrUnDef } from '/@/utils/is'; | ||
| 12 | - | ||
| 13 | - interface MetaDataItemType { | ||
| 14 | - label: string; | ||
| 15 | - value: string; | ||
| 16 | - uuid: string; | ||
| 17 | - } | 10 | + import { AttributeConfiguration } from '../AttributeConfiguration'; |
| 18 | 11 | ||
| 19 | interface Value { | 12 | interface Value { |
| 20 | msg: Recordable; | 13 | msg: Recordable; |
| @@ -53,29 +46,17 @@ | @@ -53,29 +46,17 @@ | ||
| 53 | humidity: 78, | 46 | humidity: 78, |
| 54 | }); | 47 | }); |
| 55 | 48 | ||
| 49 | + const attributeConfigurationElRef = ref<Nullable<InstanceType<typeof AttributeConfiguration>>>(); | ||
| 50 | + | ||
| 56 | const scriptContent = ref('return msg.temperature > 20;'); | 51 | const scriptContent = ref('return msg.temperature > 20;'); |
| 57 | 52 | ||
| 58 | const outputContent = ref(''); | 53 | const outputContent = ref(''); |
| 59 | 54 | ||
| 60 | - const metaData = ref<MetaDataItemType[]>([ | ||
| 61 | - { uuid: buildShortUUID(), label: 'deviceName', value: 'Test Device' }, | ||
| 62 | - { uuid: buildShortUUID(), label: 'deviceType', value: 'default' }, | ||
| 63 | - { uuid: buildShortUUID(), label: 'ts', value: Date.now().toString() }, | ||
| 64 | - ]); | ||
| 65 | - | ||
| 66 | - const handleAddMetadata = () => { | ||
| 67 | - metaData.value.push({ uuid: buildShortUUID(), label: '', value: '' }); | ||
| 68 | - }; | ||
| 69 | - | ||
| 70 | - const handleRemove = (data: MetaDataItemType) => { | ||
| 71 | - const index = unref(metaData).findIndex((item) => item.uuid === data.uuid); | ||
| 72 | - ~index && unref(metaData).splice(index, 1); | ||
| 73 | - }; | 55 | + const metadata = ref({ deviceName: 'Test Device', deviceType: 'default', ts: Date.now() }); |
| 74 | 56 | ||
| 75 | const { createMessage } = useMessage(); | 57 | const { createMessage } = useMessage(); |
| 76 | - const handleValidate = () => { | 58 | + const handleValidate = async () => { |
| 77 | const message = unref(messageContent); | 59 | const message = unref(messageContent); |
| 78 | - const metadata = unref(metaData); | ||
| 79 | const { flag } = useJsonParse(message); | 60 | const { flag } = useJsonParse(message); |
| 80 | 61 | ||
| 81 | if (!flag) { | 62 | if (!flag) { |
| @@ -83,35 +64,26 @@ | @@ -83,35 +64,26 @@ | ||
| 83 | return false; | 64 | return false; |
| 84 | } | 65 | } |
| 85 | 66 | ||
| 86 | - for (const item of metadata) { | ||
| 87 | - const { label, value } = item; | ||
| 88 | - if (isNullOrUnDef(label) || isNullOrUnDef(value)) { | ||
| 89 | - createMessage.warning('元数据的键名和键值为必填项'); | ||
| 90 | - return false; | ||
| 91 | - } | ||
| 92 | - } | 67 | + await unref(attributeConfigurationElRef)?.validate(); |
| 68 | + | ||
| 93 | return true; | 69 | return true; |
| 94 | }; | 70 | }; |
| 95 | 71 | ||
| 96 | const getValue = (): Value => { | 72 | const getValue = (): Value => { |
| 97 | const msg = unref(messageContent); | 73 | const msg = unref(messageContent); |
| 98 | const msgType = unref(messageType); | 74 | const msgType = unref(messageType); |
| 99 | - const metadata = unref(metaData).reduce( | ||
| 100 | - (prev, next) => ({ ...prev, [next.label]: next.value }), | ||
| 101 | - {} as Recordable | ||
| 102 | - ); | ||
| 103 | const javascriptFunction = unref(scriptContent); | 75 | const javascriptFunction = unref(scriptContent); |
| 104 | - return { msg, msgType, metadata, javascriptFunction }; | ||
| 105 | - }; | ||
| 106 | 76 | ||
| 107 | - const handleTestScript = () => { | ||
| 108 | - const flag = handleValidate(); | 77 | + return { msg, msgType, metadata: toRaw(unref(metadata)), javascriptFunction }; |
| 78 | + }; | ||
| 109 | 79 | ||
| 80 | + const handleTestScript = async () => { | ||
| 81 | + const flag = await handleValidate(); | ||
| 110 | flag && emit('test', getValue()); | 82 | flag && emit('test', getValue()); |
| 111 | }; | 83 | }; |
| 112 | 84 | ||
| 113 | - const handleSave = () => { | ||
| 114 | - const flag = handleValidate(); | 85 | + const handleSave = async () => { |
| 86 | + const flag = await handleValidate(); | ||
| 115 | flag && emit('save', getValue()); | 87 | flag && emit('save', getValue()); |
| 116 | }; | 88 | }; |
| 117 | 89 | ||
| @@ -148,24 +120,19 @@ | @@ -148,24 +120,19 @@ | ||
| 148 | </main> | 120 | </main> |
| 149 | <main> | 121 | <main> |
| 150 | <Card class="w-full h-full"> | 122 | <Card class="w-full h-full"> |
| 151 | - <div class="flex flex-col"> | 123 | + <div class="flex flex-col h-full"> |
| 152 | <div class="flex justify-between"> | 124 | <div class="flex justify-between"> |
| 153 | <span class="text-gray-400">元数据</span> | 125 | <span class="text-gray-400">元数据</span> |
| 154 | <Tag color="blue">元数据</Tag> | 126 | <Tag color="blue">元数据</Tag> |
| 155 | </div> | 127 | </div> |
| 156 | - <div class="mt-4 overflow-y-auto"> | ||
| 157 | - <div v-for="item in metaData" :key="item.uuid" class="flex mt-2 gap-2 items-end"> | ||
| 158 | - <Input v-model:value="item.label" placeholder="请输入键名" /> | ||
| 159 | - <Input v-model:value="item.value" placeholder="请输入键值" /> | ||
| 160 | - <Icon | ||
| 161 | - icon="material-symbols:close" | ||
| 162 | - class="svg:text-2xl cursor-pointer" | ||
| 163 | - @click="handleRemove(item)" | ||
| 164 | - /> | ||
| 165 | - </div> | ||
| 166 | - </div> | ||
| 167 | - <div class="mt-4"> | ||
| 168 | - <Button type="primary" @click="handleAddMetadata">添加</Button> | 128 | + <div class="pt-4 flex-auto"> |
| 129 | + <AttributeConfiguration | ||
| 130 | + ref="attributeConfigurationElRef" | ||
| 131 | + v-model:value="metadata" | ||
| 132 | + keyLabel="键名" | ||
| 133 | + valueLabel="键值" | ||
| 134 | + :showLabel="false" | ||
| 135 | + /> | ||
| 169 | </div> | 136 | </div> |
| 170 | </div> | 137 | </div> |
| 171 | </Card> | 138 | </Card> |
src/views/rule/designer/src/components/JavaScriptFilterModal/JavaScriptTestModal.vue
renamed from
src/views/rule/designer/packages/Filter/Script/FilterModal.vue
| 1 | <script lang="ts" setup> | 1 | <script lang="ts" setup> |
| 2 | import { BasicModal, useModalInner } from '/@/components/Modal'; | 2 | import { BasicModal, useModalInner } from '/@/components/Modal'; |
| 3 | - import ScriptFilterTest from './ScriptFilterTest.vue'; | 3 | + import JavaScriptFilterTest from './JavaScriptFilterTest.vue'; |
| 4 | import { MessageTypesFilterEnum } from '../../../enum/form'; | 4 | import { MessageTypesFilterEnum } from '../../../enum/form'; |
| 5 | import { ref } from 'vue'; | 5 | import { ref } from 'vue'; |
| 6 | import { JavaScriptFunctionEditor } from '/@/components/Form'; | 6 | import { JavaScriptFunctionEditor } from '/@/components/Form'; |
| @@ -42,7 +42,7 @@ | @@ -42,7 +42,7 @@ | ||
| 42 | :showOkBtn="false" | 42 | :showOkBtn="false" |
| 43 | :footer="null" | 43 | :footer="null" |
| 44 | > | 44 | > |
| 45 | - <ScriptFilterTest | 45 | + <JavaScriptFilterTest |
| 46 | :javaScriptEditorProps="javaScriptEditorProps" | 46 | :javaScriptEditorProps="javaScriptEditorProps" |
| 47 | :value="value" | 47 | :value="value" |
| 48 | @cancel="closeModal()" | 48 | @cancel="closeModal()" |
src/views/rule/designer/src/components/JavaScriptFilterModal/JavascriptEditorWithTestModal.vue
renamed from
src/views/rule/designer/packages/Filter/Script/JavaScriptFilterFunctionModal.vue
| 1 | <script setup lang="ts"> | 1 | <script setup lang="ts"> |
| 2 | import { JavaScriptFunctionEditor } from '/@/components/Form'; | 2 | import { JavaScriptFunctionEditor } from '/@/components/Form'; |
| 3 | import { Button } from 'ant-design-vue'; | 3 | import { Button } from 'ant-design-vue'; |
| 4 | - import FilterModal from './FilterModal.vue'; | 4 | + import JavaScriptTestModal from './JavaScriptTestModal.vue'; |
| 5 | import { useModal } from '/@/components/Modal'; | 5 | import { useModal } from '/@/components/Modal'; |
| 6 | import { DataActionModeEnum } from '/@/enums/toolEnum'; | 6 | import { DataActionModeEnum } from '/@/enums/toolEnum'; |
| 7 | import { computed } from 'vue'; | 7 | import { computed } from 'vue'; |
| @@ -49,7 +49,7 @@ | @@ -49,7 +49,7 @@ | ||
| 49 | <section> | 49 | <section> |
| 50 | <JavaScriptFunctionEditor v-model:value="getValue" v-bind="javaScriptEditorProps" /> | 50 | <JavaScriptFunctionEditor v-model:value="getValue" v-bind="javaScriptEditorProps" /> |
| 51 | <Button class="mt-4" type="primary" @click="handleOpen">{{ buttonName }}</Button> | 51 | <Button class="mt-4" type="primary" @click="handleOpen">{{ buttonName }}</Button> |
| 52 | - <FilterModal | 52 | + <JavaScriptTestModal |
| 53 | :javaScriptEditorProps="javaScriptEditorProps" | 53 | :javaScriptEditorProps="javaScriptEditorProps" |
| 54 | @register="register" | 54 | @register="register" |
| 55 | @save="handleSave" | 55 | @save="handleSave" |
| 1 | +import { DirectionEnum, DirectionNameEnum } from '../../../enum/form'; | ||
| 2 | +import { FormSchema, useComponentRegister } from '/@/components/Form'; | ||
| 3 | +import { CorrelationFilters } from '../CorrelationFilters'; | ||
| 4 | +import { ListItemType } from '../CorrelationFilters/config'; | ||
| 5 | + | ||
| 6 | +useComponentRegister('CorrelationFilters', CorrelationFilters); | ||
| 7 | + | ||
| 8 | +export enum RelationsQueryFormFieldsEnum { | ||
| 9 | + FETCH_LAST_LEVEL_ONLY = 'fetchLastLevelOnly', | ||
| 10 | + DIRECTION = 'direction', | ||
| 11 | + MAX_LEVEL = 'maxLevel', | ||
| 12 | + FILTERS = 'filters', | ||
| 13 | +} | ||
| 14 | + | ||
| 15 | +export enum RelationsQueryFormFieldsNameEnum { | ||
| 16 | + FETCH_LAST_LEVEL_ONLY = '仅获取最后一级关联', | ||
| 17 | + DIRECTION = '方向', | ||
| 18 | + MAX_LEVEL = 'Max relation level', | ||
| 19 | + FILTERS = '关联筛选器', | ||
| 20 | +} | ||
| 21 | + | ||
| 22 | +export interface ValueType { | ||
| 23 | + [RelationsQueryFormFieldsEnum.DIRECTION]?: DirectionEnum; | ||
| 24 | + [RelationsQueryFormFieldsEnum.FILTERS]?: ListItemType[]; | ||
| 25 | + [RelationsQueryFormFieldsEnum.FETCH_LAST_LEVEL_ONLY]?: boolean; | ||
| 26 | + [RelationsQueryFormFieldsEnum.MAX_LEVEL]?: number; | ||
| 27 | +} | ||
| 28 | + | ||
| 29 | +export const getFormSchemas = (allowAddFilters: boolean): FormSchema[] => { | ||
| 30 | + return [ | ||
| 31 | + { | ||
| 32 | + field: RelationsQueryFormFieldsEnum.FETCH_LAST_LEVEL_ONLY, | ||
| 33 | + component: 'Checkbox', | ||
| 34 | + label: '', | ||
| 35 | + required: true, | ||
| 36 | + renderComponentContent: () => ({ | ||
| 37 | + default: () => RelationsQueryFormFieldsNameEnum.FETCH_LAST_LEVEL_ONLY, | ||
| 38 | + }), | ||
| 39 | + }, | ||
| 40 | + { | ||
| 41 | + field: RelationsQueryFormFieldsEnum.DIRECTION, | ||
| 42 | + component: 'Select', | ||
| 43 | + label: RelationsQueryFormFieldsNameEnum.DIRECTION, | ||
| 44 | + colProps: { span: 12 }, | ||
| 45 | + required: true, | ||
| 46 | + componentProps: { | ||
| 47 | + options: Object.keys(DirectionEnum).map((value) => ({ | ||
| 48 | + label: DirectionNameEnum[value], | ||
| 49 | + value, | ||
| 50 | + })), | ||
| 51 | + getPopupContainer: () => document.body, | ||
| 52 | + placeholder: `请选择${RelationsQueryFormFieldsNameEnum.DIRECTION}`, | ||
| 53 | + componentProps: {}, | ||
| 54 | + }, | ||
| 55 | + }, | ||
| 56 | + { | ||
| 57 | + field: RelationsQueryFormFieldsEnum.MAX_LEVEL, | ||
| 58 | + label: RelationsQueryFormFieldsNameEnum.MAX_LEVEL, | ||
| 59 | + component: 'InputNumber', | ||
| 60 | + colProps: { span: 12 }, | ||
| 61 | + required: true, | ||
| 62 | + componentProps: { | ||
| 63 | + min: 1, | ||
| 64 | + }, | ||
| 65 | + }, | ||
| 66 | + { | ||
| 67 | + field: RelationsQueryFormFieldsEnum.FILTERS, | ||
| 68 | + label: allowAddFilters ? RelationsQueryFormFieldsNameEnum.FILTERS : '', | ||
| 69 | + component: 'CorrelationFilters', | ||
| 70 | + valueField: 'value', | ||
| 71 | + changeEvent: 'update:value', | ||
| 72 | + slot: RelationsQueryFormFieldsEnum.FILTERS, | ||
| 73 | + }, | ||
| 74 | + ]; | ||
| 75 | +}; |
| 1 | +export { default as RelationsQuery } from './index.vue'; |
| 1 | +<script lang="ts" setup> | ||
| 2 | + import { onMounted, ref, toRaw, unref, watch } from 'vue'; | ||
| 3 | + import { getFormSchemas, RelationsQueryFormFieldsEnum, ValueType } from './config'; | ||
| 4 | + import { BasicForm, useForm } from '/@/components/Form'; | ||
| 5 | + import { CorrelationFilters } from '../CorrelationFilters'; | ||
| 6 | + import { FormFieldsEnum as CorrelationFiltersFormFieldsEnum } from '../CorrelationFilters/config'; | ||
| 7 | + | ||
| 8 | + const props = withDefaults( | ||
| 9 | + defineProps<{ | ||
| 10 | + value?: ValueType; | ||
| 11 | + allowAddFilters?: boolean; | ||
| 12 | + }>(), | ||
| 13 | + { | ||
| 14 | + value: () => ({}), | ||
| 15 | + allowAddFilters: true, | ||
| 16 | + } | ||
| 17 | + ); | ||
| 18 | + | ||
| 19 | + const correlationFiltersElRef = ref<Nullable<InstanceType<typeof CorrelationFilters>>>(); | ||
| 20 | + | ||
| 21 | + const [register, formactionType] = useForm({ | ||
| 22 | + showActionButtonGroup: false, | ||
| 23 | + schemas: getFormSchemas(props.allowAddFilters), | ||
| 24 | + }); | ||
| 25 | + | ||
| 26 | + watch( | ||
| 27 | + () => props.value, | ||
| 28 | + (target) => { | ||
| 29 | + setFieldsValue(toRaw(unref(target))); | ||
| 30 | + } | ||
| 31 | + ); | ||
| 32 | + | ||
| 33 | + onMounted(() => { | ||
| 34 | + setFieldsValue(toRaw(unref(props.value))); | ||
| 35 | + }); | ||
| 36 | + | ||
| 37 | + const getFieldsValue = () => { | ||
| 38 | + const value = formactionType.getFieldsValue(); | ||
| 39 | + const correlationValue = unref(correlationFiltersElRef)?.getFieldsValue(); | ||
| 40 | + return { | ||
| 41 | + ...value, | ||
| 42 | + [RelationsQueryFormFieldsEnum.FILTERS]: correlationValue?.map((item) => ({ | ||
| 43 | + [CorrelationFiltersFormFieldsEnum.ENTITY_TYPES]: | ||
| 44 | + item[CorrelationFiltersFormFieldsEnum.ENTITY_TYPES], | ||
| 45 | + [CorrelationFiltersFormFieldsEnum.RELATION_TYPE]: | ||
| 46 | + item[CorrelationFiltersFormFieldsEnum.RELATION_TYPE], | ||
| 47 | + })), | ||
| 48 | + }; | ||
| 49 | + }; | ||
| 50 | + | ||
| 51 | + const setFieldsValue = (value?: ValueType) => { | ||
| 52 | + formactionType.setFieldsValue(value); | ||
| 53 | + unref(correlationFiltersElRef)?.setFieldsValue( | ||
| 54 | + value?.[RelationsQueryFormFieldsEnum.FILTERS] || [] | ||
| 55 | + ); | ||
| 56 | + }; | ||
| 57 | + | ||
| 58 | + const validate = async () => { | ||
| 59 | + await formactionType.validate(); | ||
| 60 | + await unref(correlationFiltersElRef)?.validate(); | ||
| 61 | + | ||
| 62 | + return getFieldsValue(); | ||
| 63 | + }; | ||
| 64 | + | ||
| 65 | + defineExpose({ | ||
| 66 | + getFieldsValue, | ||
| 67 | + setFieldsValue, | ||
| 68 | + validate, | ||
| 69 | + }); | ||
| 70 | +</script> | ||
| 71 | + | ||
| 72 | +<template> | ||
| 73 | + <BasicForm @register="register"> | ||
| 74 | + <template #filters="{ field, model }"> | ||
| 75 | + <CorrelationFilters | ||
| 76 | + ref="correlationFiltersElRef" | ||
| 77 | + v-model:value="model[field]" | ||
| 78 | + :allowAddFilters="allowAddFilters" | ||
| 79 | + /> | ||
| 80 | + </template> | ||
| 81 | + </BasicForm> | ||
| 82 | +</template> |
| @@ -84,6 +84,7 @@ | @@ -84,6 +84,7 @@ | ||
| 84 | showOkBtn | 84 | showOkBtn |
| 85 | @ok="handleModalOk" | 85 | @ok="handleModalOk" |
| 86 | @close="handleCancel" | 86 | @close="handleCancel" |
| 87 | + wrapper-class-name="rule-node-update-drawer" | ||
| 87 | > | 88 | > |
| 88 | <template #title> | 89 | <template #title> |
| 89 | <h2 class="font-bold text-2xl truncate">{{ nodeData?.data?.name }}</h2> | 90 | <h2 class="font-bold text-2xl truncate">{{ nodeData?.data?.name }}</h2> |
| @@ -96,7 +97,7 @@ | @@ -96,7 +97,7 @@ | ||
| 96 | <Tabs> | 97 | <Tabs> |
| 97 | <Tabs.TabPane :tab="TabsPanelNameEnum[TabsPanelEnum.DETAIL]" :key="TabsPanelEnum.DETAIL"> | 98 | <Tabs.TabPane :tab="TabsPanelNameEnum[TabsPanelEnum.DETAIL]" :key="TabsPanelEnum.DETAIL"> |
| 98 | <Spin :spinning="spinning"> | 99 | <Spin :spinning="spinning"> |
| 99 | - <section v-if="shadowComponent" class="w-full h-full"> | 100 | + <section v-if="shadowComponent" class="w-full h-full overflow-y-auto"> |
| 100 | <BasicForm @register="topFormRegister" @vue:mounted="handleTopFormMounted" /> | 101 | <BasicForm @register="topFormRegister" @vue:mounted="handleTopFormMounted" /> |
| 101 | <component | 102 | <component |
| 102 | class="rule-node-form" | 103 | class="rule-node-form" |
| @@ -129,3 +130,35 @@ | @@ -129,3 +130,35 @@ | ||
| 129 | } | 130 | } |
| 130 | } | 131 | } |
| 131 | </style> | 132 | </style> |
| 133 | + | ||
| 134 | +<style lang="less"> | ||
| 135 | + .rule-node-update-drawer { | ||
| 136 | + .ant-drawer-wrapper-body { | ||
| 137 | + @apply flex flex-col; | ||
| 138 | + | ||
| 139 | + .ant-drawer-body { | ||
| 140 | + @apply flex flex-auto overflow-hidden; | ||
| 141 | + | ||
| 142 | + .ant-tabs-bar { | ||
| 143 | + box-shadow: 6px -1px 9px 3px #00000040; | ||
| 144 | + } | ||
| 145 | + | ||
| 146 | + .scroll-container { | ||
| 147 | + .scrollbar__wrap { | ||
| 148 | + .scrollbar__view { | ||
| 149 | + @apply h-full; | ||
| 150 | + | ||
| 151 | + .ant-tabs { | ||
| 152 | + @apply h-full flex flex-col; | ||
| 153 | + | ||
| 154 | + .ant-tabs-content { | ||
| 155 | + @apply flex-auto overflow-x-hidden overflow-y-auto pr-4; | ||
| 156 | + } | ||
| 157 | + } | ||
| 158 | + } | ||
| 159 | + } | ||
| 160 | + } | ||
| 161 | + } | ||
| 162 | + } | ||
| 163 | + } | ||
| 164 | +</style> |