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> |