Showing
55 changed files
with
2186 additions
and
256 deletions
1 | -import { DeviceInfoItemType } from './model'; | |
1 | +import { DeviceInfoItemType, DeviceTypeItem } from './model'; | |
2 | 2 | import { TBPaginationResult } from '/#/axios'; |
3 | 3 | import { defHttp } from '/@/utils/http/axios'; |
4 | 4 | |
5 | 5 | enum Api { |
6 | 6 | GET_DEVICE_INFOS = '/tenant/deviceInfos', |
7 | + GET_DEVICE_TYPE = '/device/types', | |
7 | 8 | } |
8 | 9 | |
9 | 10 | export const getDeviceInfos = () => { |
... | ... | @@ -14,3 +15,12 @@ export const getDeviceInfos = () => { |
14 | 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 | +}; | ... | ... |
... | ... | @@ -132,4 +132,7 @@ export type ComponentType = |
132 | 132 | | 'OrgTreeSelect' |
133 | 133 | | 'ExtendDesc' |
134 | 134 | | 'JavaScriptFunctionEditor' |
135 | - | 'JavaScriptFilterFunctionModal'; | |
135 | + | 'JavascriptEditorWithTestModal' | |
136 | + | 'AttributeConfiguration' | |
137 | + | 'CorrelationFilters' | |
138 | + | 'RelationsQuery'; | ... | ... |
... | ... | @@ -14,8 +14,13 @@ export enum DirectionNameEnum { |
14 | 14 | * @description 关联类型 |
15 | 15 | */ |
16 | 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 | 124 | RPC_TIMEOUT = 'RPC Timeout', |
120 | 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 | 8 | export enum FetchNodeComFlagTypeENum { |
2 | 9 | CONNECTION_MODAL = 'CONNECTION_MODAL', |
3 | 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 | 13 | export enum EdgeBindDataFieldEnum { |
90 | 14 | TYPE = 'type', |
91 | 15 | } |
... | ... | @@ -93,3 +17,15 @@ export enum EdgeBindDataFieldEnum { |
93 | 17 | export enum EdgeBindDataFieldNameEnum { |
94 | 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 | +}; | ... | ... |
1 | -import { NodeBindDataFieldEnum, NodeBindDataFieldNameEnum } from '../../../enum/node'; | |
1 | +import { | |
2 | + AssignToCustomerFieldsEnum, | |
3 | + AssignToCustomerFieldsNameEnum, | |
4 | +} from '../../../enum/formField/action'; | |
2 | 5 | import { FormSchema } from '/@/components/Form'; |
3 | 6 | |
4 | 7 | export const formSchemas: FormSchema[] = [ |
5 | 8 | { |
6 | - field: NodeBindDataFieldEnum.NAME, | |
9 | + field: AssignToCustomerFieldsEnum.CUSTOMER_NAME_PATTERN, | |
7 | 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 | 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 | 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 | 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 | 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 | 3 | |
4 | 4 | export const formSchemas: FormSchema[] = [ |
5 | 5 | { |
6 | - field: NodeBindDataFieldEnum.NAME, | |
6 | + field: NodeBindDataFieldEnum.INPUT_VALUE_KEY, | |
7 | 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 | 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 | 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 | 3 | import { BasicForm, useForm } from '/@/components/Form'; |
4 | 4 | import { formSchemas } from './create.config'; |
5 | 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 | 10 | defineProps<{ |
8 | 11 | config: NodeData; |
9 | 12 | }>(); |
10 | 13 | |
14 | + const attributeControlElRef = ref<Nullable<InstanceType<typeof AttributeConfiguration>>>(); | |
15 | + | |
11 | 16 | const [register, { validate, getFieldsValue, setFieldsValue, resetFields }] = useForm({ |
12 | 17 | schemas: formSchemas, |
13 | 18 | showActionButtonGroup: false, |
14 | 19 | }); |
15 | 20 | |
16 | 21 | const getValue: CreateModalDefineExposeType['getFieldsValue'] = async () => { |
22 | + await unref(attributeControlElRef)?.validate(); | |
17 | 23 | await validate(); |
18 | 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 | 29 | const setValue: CreateModalDefineExposeType['setFieldsValue'] = (value) => { |
23 | 30 | resetFields(); |
24 | 31 | setFieldsValue(value); |
32 | + unref(attributeControlElRef)?.setFieldsValue(value?.[NodeBindDataFieldEnum.ATTR_MAPING]); | |
25 | 33 | }; |
26 | 34 | |
27 | 35 | defineExpose({ |
... | ... | @@ -31,5 +39,32 @@ |
31 | 39 | </script> |
32 | 40 | |
33 | 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 | 70 | </template> | ... | ... |
1 | +import { DetailsListEnum, DetailsListNameEnum } from '../../../enum/form'; | |
1 | 2 | import { NodeBindDataFieldEnum, NodeBindDataFieldNameEnum } from '../../../enum/node'; |
2 | 3 | import { FormSchema } from '/@/components/Form'; |
3 | 4 | |
4 | 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 | 3 | |
4 | 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 | 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 | 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 | 3 | import { BasicForm, useForm } from '/@/components/Form'; |
4 | 4 | import { formSchemas } from './create.config'; |
5 | 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 | 10 | defineProps<{ |
8 | 11 | config: NodeData; |
9 | 12 | }>(); |
10 | 13 | |
14 | + const fieldControlElRef = ref<Nullable<InstanceType<typeof AttributeConfiguration>>>(); | |
15 | + | |
11 | 16 | const [register, { validate, getFieldsValue, setFieldsValue, resetFields }] = useForm({ |
12 | 17 | schemas: formSchemas, |
13 | 18 | showActionButtonGroup: false, |
14 | 19 | }); |
15 | 20 | |
16 | 21 | const getValue: CreateModalDefineExposeType['getFieldsValue'] = async () => { |
22 | + await unref(fieldControlElRef)?.validate(); | |
17 | 23 | await validate(); |
18 | 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 | 29 | const setValue: CreateModalDefineExposeType['setFieldsValue'] = (value) => { |
23 | 30 | resetFields(); |
24 | 31 | setFieldsValue(value); |
32 | + unref(fieldControlElRef)?.setFieldsValue(value?.[NodeBindDataFieldEnum.FIELDS_MAPPING]); | |
25 | 33 | }; |
26 | 34 | |
27 | 35 | defineExpose({ |
... | ... | @@ -31,5 +39,14 @@ |
31 | 39 | </script> |
32 | 40 | |
33 | 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 | 52 | </template> | ... | ... |
1 | +import { | |
2 | + AggregationEnum, | |
3 | + AggregationNameEnum, | |
4 | + FetchModeEnum, | |
5 | + OrderByEnum, | |
6 | + TimeIntervalUnitEnum, | |
7 | + TimeIntervalUnitNameEnum, | |
8 | +} from '../../../enum/form'; | |
1 | 9 | import { NodeBindDataFieldEnum, NodeBindDataFieldNameEnum } from '../../../enum/node'; |
2 | 10 | import { FormSchema } from '/@/components/Form'; |
3 | 11 | |
4 | 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 | 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 | 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 | 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 | 3 | import { BasicForm, useForm } from '/@/components/Form'; |
4 | 4 | import { formSchemas } from './create.config'; |
5 | 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 | 11 | defineProps<{ |
8 | 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 | 19 | const [register, { validate, getFieldsValue, setFieldsValue, resetFields }] = useForm({ |
12 | 20 | schemas: formSchemas, |
13 | 21 | showActionButtonGroup: false, |
... | ... | @@ -15,13 +23,25 @@ |
15 | 23 | |
16 | 24 | const getValue: CreateModalDefineExposeType['getFieldsValue'] = async () => { |
17 | 25 | await validate(); |
26 | + await unref(relationsQueryElRef)?.validate(); | |
27 | + await unref(attributeControlElRef)?.validate(); | |
18 | 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 | 38 | const setValue: CreateModalDefineExposeType['setFieldsValue'] = (value) => { |
23 | 39 | resetFields(); |
24 | 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 | 47 | defineExpose({ |
... | ... | @@ -31,5 +51,35 @@ |
31 | 51 | </script> |
32 | 52 | |
33 | 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 | 85 | </template> | ... | ... |
1 | +import { | |
2 | + DirectionEnum, | |
3 | + DirectionNameEnum, | |
4 | + RelationTypeEnum, | |
5 | + RelationTypeNameEnum, | |
6 | +} from '../../../enum/form'; | |
1 | 7 | import { NodeBindDataFieldEnum, NodeBindDataFieldNameEnum } from '../../../enum/node'; |
8 | +import { getDeviceTypes } from '/@/api/ruleChainDesigner'; | |
2 | 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 | 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 | 1 | <script lang="ts" setup> |
2 | 2 | import type { CreateModalDefineExposeType } from '../../../types'; |
3 | 3 | import { BasicForm, useForm } from '/@/components/Form'; |
4 | - import { formSchemas } from './create.config'; | |
4 | + import { DeviceRelationsQuery, formSchemas, ValueType } from './create.config'; | |
5 | 5 | import { NodeData } from '../../../types/node'; |
6 | + import { NodeBindDataFieldEnum } from '../../../enum/node'; | |
6 | 7 | |
7 | 8 | defineProps<{ |
8 | 9 | config: NodeData; |
... | ... | @@ -16,12 +17,33 @@ |
16 | 17 | const getValue: CreateModalDefineExposeType['getFieldsValue'] = async () => { |
17 | 18 | await validate(); |
18 | 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 | 43 | const setValue: CreateModalDefineExposeType['setFieldsValue'] = (value) => { |
23 | 44 | resetFields(); |
24 | - setFieldsValue(value); | |
45 | + console.log(value); | |
46 | + setFieldsValue({ ...value, ...(value?.[NodeBindDataFieldEnum.DEVICE_RELATIONS_QUERY] || {}) }); | |
25 | 47 | }; |
26 | 48 | |
27 | 49 | defineExpose({ | ... | ... |
1 | 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 | 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 | 3 | import { BasicForm, useForm } from '/@/components/Form'; |
4 | 4 | import { formSchemas } from './create.config'; |
5 | 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 | 10 | defineProps<{ |
8 | 11 | config: NodeData; |
9 | 12 | }>(); |
10 | 13 | |
14 | + const attributeControlElRef = ref<Nullable<InstanceType<typeof AttributeConfiguration>>>(); | |
15 | + | |
11 | 16 | const [register, { validate, getFieldsValue, setFieldsValue, resetFields }] = useForm({ |
12 | 17 | schemas: formSchemas, |
13 | 18 | showActionButtonGroup: false, |
14 | 19 | }); |
15 | 20 | |
16 | 21 | const getValue: CreateModalDefineExposeType['getFieldsValue'] = async () => { |
22 | + await unref(attributeControlElRef)?.validate(); | |
17 | 23 | await validate(); |
18 | 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 | 29 | const setValue: CreateModalDefineExposeType['setFieldsValue'] = (value) => { |
23 | 30 | resetFields(); |
24 | 31 | setFieldsValue(value); |
32 | + unref(attributeControlElRef)?.setFieldsValue(value?.[NodeBindDataFieldEnum.ATTR_MAPING]); | |
25 | 33 | }; |
26 | 34 | |
27 | 35 | defineExpose({ |
... | ... | @@ -31,5 +39,32 @@ |
31 | 39 | </script> |
32 | 40 | |
33 | 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 | 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 | 6 | import { FormSchema } from '/@/components/Form'; |
3 | 7 | |
4 | 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 | 8 | label: NodeBindDataFieldNameEnum.MESSAGE_NAMES, |
9 | 9 | componentProps: { |
10 | 10 | mode: 'tags', |
11 | + open: false, | |
11 | 12 | getPopupContainer: () => document.body, |
12 | 13 | }, |
13 | 14 | }, |
... | ... | @@ -17,6 +18,7 @@ export const formSchemas: FormSchema[] = [ |
17 | 18 | label: NodeBindDataFieldNameEnum.METADATA_NAMES, |
18 | 19 | componentProps: { |
19 | 20 | mode: 'tags', |
21 | + open: false, | |
20 | 22 | getPopupContainer: () => document.body, |
21 | 23 | }, |
22 | 24 | }, | ... | ... |
... | ... | @@ -4,6 +4,7 @@ import { |
4 | 4 | EntityTypeEnum, |
5 | 5 | EntityTypeNameEnum, |
6 | 6 | RelationTypeEnum, |
7 | + RelationTypeNameEnum, | |
7 | 8 | } from '../../../enum/form'; |
8 | 9 | import { NodeBindDataFieldEnum, NodeBindDataFieldNameEnum } from '../../../enum/node'; |
9 | 10 | import { deviceProfilePage } from '/@/api/device/deviceManager'; |
... | ... | @@ -18,8 +19,10 @@ export const formSchemas: FormSchema[] = [ |
18 | 19 | { |
19 | 20 | field: NodeBindDataFieldEnum.CHECK_FOR_SINGLE_ENTITY, |
20 | 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 | 28 | field: NodeBindDataFieldEnum.DIRECTION, |
... | ... | @@ -69,10 +72,10 @@ export const formSchemas: FormSchema[] = [ |
69 | 72 | label: NodeBindDataFieldNameEnum.RELEATION_TYPE, |
70 | 73 | defaultValue: RelationTypeEnum.CONTAINS, |
71 | 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 | 24 | { |
25 | 25 | field: NodeBindDataFieldEnum.FETCH_PERIMETER_INFO_FROM_MESSAGE_METADATA, |
26 | 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 | 33 | field: NodeBindDataFieldEnum.PERIMETER_KEY_NAME, | ... | ... |
... | ... | @@ -2,14 +2,14 @@ import { h } from 'vue'; |
2 | 2 | import { NodeBindDataFieldEnum, NodeBindDataFieldNameEnum } from '../../../enum/node'; |
3 | 3 | import { FormSchema, useComponentRegister } from '/@/components/Form'; |
4 | 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 | 9 | export const formSchemas: FormSchema[] = [ |
10 | 10 | { |
11 | 11 | field: NodeBindDataFieldEnum.JS_SCRIPT, |
12 | - component: 'JavaScriptFilterFunctionModal', | |
12 | + component: 'JavascriptEditorWithTestModal', | |
13 | 13 | label: NodeBindDataFieldNameEnum.JS_SCRIPT, |
14 | 14 | changeEvent: 'update:value', |
15 | 15 | valueField: 'value', | ... | ... |
1 | 1 | import { NodeBindDataFieldEnum, NodeBindDataFieldNameEnum } from '../../../enum/node'; |
2 | 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 | 7 | export const formSchemas: FormSchema[] = [ |
7 | 8 | { |
8 | 9 | field: NodeBindDataFieldEnum.JS_SCRIPT, |
9 | - component: 'JavaScriptFilterFunctionModal', | |
10 | + component: 'JavascriptEditorWithTestModal', | |
10 | 11 | label: NodeBindDataFieldNameEnum.JS_SCRIPT, |
11 | 12 | changeEvent: 'update:value', |
12 | 13 | valueField: 'value', |
13 | 14 | componentProps: { |
14 | 15 | buttonName: 'Test Switch Function', |
15 | 16 | javaScriptEditorProps: { |
17 | + height: 230, | |
16 | 18 | functionName: 'Switch', |
17 | 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 | 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 | 3 | import { BasicForm, useForm } from '/@/components/Form'; |
4 | 4 | import { formSchemas } from './create.config'; |
5 | 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 | 10 | defineProps<{ |
8 | 11 | config: NodeData; |
9 | 12 | }>(); |
10 | 13 | |
14 | + const relationsQueryElRef = ref<Nullable<InstanceType<typeof RelationsQuery>>>(); | |
15 | + | |
11 | 16 | const [register, { validate, getFieldsValue, setFieldsValue, resetFields }] = useForm({ |
12 | 17 | schemas: formSchemas, |
13 | 18 | showActionButtonGroup: false, |
... | ... | @@ -16,12 +21,14 @@ |
16 | 21 | const getValue: CreateModalDefineExposeType['getFieldsValue'] = async () => { |
17 | 22 | await validate(); |
18 | 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 | 28 | const setValue: CreateModalDefineExposeType['setFieldsValue'] = (value) => { |
23 | 29 | resetFields(); |
24 | 30 | setFieldsValue(value); |
31 | + unref(relationsQueryElRef)?.setFieldsValue(value?.[ChangeOriginatorFieldsEnum.RELATIONS_QUERY]); | |
25 | 32 | }; |
26 | 33 | |
27 | 34 | defineExpose({ |
... | ... | @@ -31,5 +38,9 @@ |
31 | 38 | </script> |
32 | 39 | |
33 | 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 | 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 | 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 | 3 | import { FormSchema } from '/@/components/Form'; |
3 | 4 | |
4 | 5 | export const formSchemas: FormSchema[] = [ |
5 | 6 | { |
6 | - field: NodeBindDataFieldEnum.NAME, | |
7 | + field: ToEmailFieldsEnum.FROM_TEMPLATE, | |
7 | 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 | 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 | 24 | const modules = |
24 | 25 | flag === FetchNodeComFlagTypeENum.CONNECTION_MODAL ? connectionModules : createModules; |
26 | + | |
25 | 27 | const modulesName = Object.keys(modules); |
26 | 28 | const path = modulesName.find((item) => { |
27 | 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 | 34 | return path ? modules[path] : null; |
31 | 35 | }; |
... | ... | @@ -40,8 +44,7 @@ export const fetchConnectionComponent = async (config: NodeItemConfigType) => { |
40 | 44 | }; |
41 | 45 | |
42 | 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 | 50 | export const allComponents: Record< |
... | ... | @@ -56,14 +59,14 @@ export const allComponents: Record< |
56 | 59 | category: EnrichmentCategoryConfig, |
57 | 60 | components: EnrichmentComponents, |
58 | 61 | }, |
59 | - [RuleNodeTypeEnum.ACTION]: { | |
60 | - category: ActionCategoryConfig, | |
61 | - components: ActionComponents, | |
62 | - }, | |
63 | 62 | [RuleNodeTypeEnum.TRANSFORMATION]: { |
64 | 63 | category: TransformationCategoryConfig, |
65 | 64 | components: TransformationComponents, |
66 | 65 | }, |
66 | + [RuleNodeTypeEnum.ACTION]: { | |
67 | + category: ActionCategoryConfig, | |
68 | + components: ActionComponents, | |
69 | + }, | |
67 | 70 | [RuleNodeTypeEnum.EXTERNAL]: { |
68 | 71 | category: ExternalCategoryConfig, |
69 | 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 | 17 | { |
18 | 18 | field: NodeBindDataFieldEnum.DEBUG_MODE, |
19 | 19 | component: 'Checkbox', |
20 | - label: NodeBindDataFieldNameEnum.DEBUG_MODE, | |
20 | + label: '', | |
21 | 21 | colProps: { |
22 | 22 | offset: 2, |
23 | 23 | span: 6, |
24 | 24 | }, |
25 | - itemProps: { | |
26 | - labelCol: { span: 14 }, | |
27 | - wrapperCol: { span: 10 }, | |
28 | - }, | |
29 | 25 | componentProps: { |
30 | 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 | 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 | 4 | import { MessageTypesFilterEnum, MessageTypesFilterNameEnum } from '../../../enum/form'; |
5 | 5 | import { JSONEditor } from '/@/components/CodeEditor'; |
6 | - import { buildShortUUID } from '/@/utils/uuid'; | |
7 | 6 | import { Icon } from '/@/components/Icon'; |
8 | 7 | import { JavaScriptFunctionEditor } from '/@/components/Form'; |
9 | 8 | import { useJsonParse } from '/@/hooks/business/useJsonParse'; |
10 | 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 | 12 | interface Value { |
20 | 13 | msg: Recordable; |
... | ... | @@ -53,29 +46,17 @@ |
53 | 46 | humidity: 78, |
54 | 47 | }); |
55 | 48 | |
49 | + const attributeConfigurationElRef = ref<Nullable<InstanceType<typeof AttributeConfiguration>>>(); | |
50 | + | |
56 | 51 | const scriptContent = ref('return msg.temperature > 20;'); |
57 | 52 | |
58 | 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 | 57 | const { createMessage } = useMessage(); |
76 | - const handleValidate = () => { | |
58 | + const handleValidate = async () => { | |
77 | 59 | const message = unref(messageContent); |
78 | - const metadata = unref(metaData); | |
79 | 60 | const { flag } = useJsonParse(message); |
80 | 61 | |
81 | 62 | if (!flag) { |
... | ... | @@ -83,35 +64,26 @@ |
83 | 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 | 69 | return true; |
94 | 70 | }; |
95 | 71 | |
96 | 72 | const getValue = (): Value => { |
97 | 73 | const msg = unref(messageContent); |
98 | 74 | const msgType = unref(messageType); |
99 | - const metadata = unref(metaData).reduce( | |
100 | - (prev, next) => ({ ...prev, [next.label]: next.value }), | |
101 | - {} as Recordable | |
102 | - ); | |
103 | 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 | 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 | 87 | flag && emit('save', getValue()); |
116 | 88 | }; |
117 | 89 | |
... | ... | @@ -148,24 +120,19 @@ |
148 | 120 | </main> |
149 | 121 | <main> |
150 | 122 | <Card class="w-full h-full"> |
151 | - <div class="flex flex-col"> | |
123 | + <div class="flex flex-col h-full"> | |
152 | 124 | <div class="flex justify-between"> |
153 | 125 | <span class="text-gray-400">元数据</span> |
154 | 126 | <Tag color="blue">元数据</Tag> |
155 | 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 | 136 | </div> |
170 | 137 | </div> |
171 | 138 | </Card> | ... | ... |
src/views/rule/designer/src/components/JavaScriptFilterModal/JavaScriptTestModal.vue
renamed from
src/views/rule/designer/packages/Filter/Script/FilterModal.vue
1 | 1 | <script lang="ts" setup> |
2 | 2 | import { BasicModal, useModalInner } from '/@/components/Modal'; |
3 | - import ScriptFilterTest from './ScriptFilterTest.vue'; | |
3 | + import JavaScriptFilterTest from './JavaScriptFilterTest.vue'; | |
4 | 4 | import { MessageTypesFilterEnum } from '../../../enum/form'; |
5 | 5 | import { ref } from 'vue'; |
6 | 6 | import { JavaScriptFunctionEditor } from '/@/components/Form'; |
... | ... | @@ -42,7 +42,7 @@ |
42 | 42 | :showOkBtn="false" |
43 | 43 | :footer="null" |
44 | 44 | > |
45 | - <ScriptFilterTest | |
45 | + <JavaScriptFilterTest | |
46 | 46 | :javaScriptEditorProps="javaScriptEditorProps" |
47 | 47 | :value="value" |
48 | 48 | @cancel="closeModal()" | ... | ... |
src/views/rule/designer/src/components/JavaScriptFilterModal/JavascriptEditorWithTestModal.vue
renamed from
src/views/rule/designer/packages/Filter/Script/JavaScriptFilterFunctionModal.vue
1 | 1 | <script setup lang="ts"> |
2 | 2 | import { JavaScriptFunctionEditor } from '/@/components/Form'; |
3 | 3 | import { Button } from 'ant-design-vue'; |
4 | - import FilterModal from './FilterModal.vue'; | |
4 | + import JavaScriptTestModal from './JavaScriptTestModal.vue'; | |
5 | 5 | import { useModal } from '/@/components/Modal'; |
6 | 6 | import { DataActionModeEnum } from '/@/enums/toolEnum'; |
7 | 7 | import { computed } from 'vue'; |
... | ... | @@ -49,7 +49,7 @@ |
49 | 49 | <section> |
50 | 50 | <JavaScriptFunctionEditor v-model:value="getValue" v-bind="javaScriptEditorProps" /> |
51 | 51 | <Button class="mt-4" type="primary" @click="handleOpen">{{ buttonName }}</Button> |
52 | - <FilterModal | |
52 | + <JavaScriptTestModal | |
53 | 53 | :javaScriptEditorProps="javaScriptEditorProps" |
54 | 54 | @register="register" |
55 | 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 | 84 | showOkBtn |
85 | 85 | @ok="handleModalOk" |
86 | 86 | @close="handleCancel" |
87 | + wrapper-class-name="rule-node-update-drawer" | |
87 | 88 | > |
88 | 89 | <template #title> |
89 | 90 | <h2 class="font-bold text-2xl truncate">{{ nodeData?.data?.name }}</h2> |
... | ... | @@ -96,7 +97,7 @@ |
96 | 97 | <Tabs> |
97 | 98 | <Tabs.TabPane :tab="TabsPanelNameEnum[TabsPanelEnum.DETAIL]" :key="TabsPanelEnum.DETAIL"> |
98 | 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 | 101 | <BasicForm @register="topFormRegister" @vue:mounted="handleTopFormMounted" /> |
101 | 102 | <component |
102 | 103 | class="rule-node-form" |
... | ... | @@ -129,3 +130,35 @@ |
129 | 130 | } |
130 | 131 | } |
131 | 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> | ... | ... |