@convep_mobilogy/react-native-qms-plugin 1.8.13 → 1.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/QmsPlugin.podspec +2 -4
- package/QmsPluginFramework.podspec +12 -0
- package/README.md +24 -8
- package/android/build.gradle +2 -1
- package/android/consumer-rules.pro +13 -0
- package/ios/QmsPlugin/QmsDashboardViewManager.mm +68 -26
- package/ios/QmsPlugin/QmsModule.mm +1293 -0
- package/ios/QmsPlugin/UIViewController+QmsAnalytics.m +3 -1
- package/lib/module/QmsDashboardView.android.js +121 -9
- package/lib/module/QmsDashboardView.android.js.map +1 -1
- package/lib/module/QmsPlugin.js +57 -0
- package/lib/module/QmsPlugin.js.map +1 -1
- package/lib/typescript/src/QmsDashboardView.android.d.ts.map +1 -1
- package/lib/typescript/src/QmsPlugin.d.ts +137 -0
- package/lib/typescript/src/QmsPlugin.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/package.json +7 -4
- package/src/QmsDashboardView.android.tsx +156 -11
- package/src/QmsPlugin.ts +312 -0
- package/src/index.tsx +13 -1
- package/ios/QmsPluginFramework.xcframework/Info.plist +0 -44
- package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/Assets.car +0 -0
- package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/Headers/QmsPlugin.h +0 -43
- package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/Headers/QmsPluginFramework.h +0 -17
- package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/Info.plist +0 -0
- package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/Modules/module.modulemap +0 -6
- package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/Montserrat-Bold.ttf +0 -0
- package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/Montserrat-BoldItalic.ttf +0 -0
- package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/Montserrat-ExtraBold.ttf +0 -0
- package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/Montserrat-ExtraLight.ttf +0 -0
- package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/Montserrat-Italic.ttf +0 -0
- package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/Montserrat-Light.ttf +0 -0
- package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/Montserrat-Medium.ttf +0 -0
- package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/Montserrat-Regular.ttf +0 -0
- package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/Montserrat-SemiBold.ttf +0 -0
- package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/Montserrat-Thin.ttf +0 -0
- package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/QmsPluginFramework +0 -0
- package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/_CodeSignature/CodeResources +0 -289
- package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/bm.json +0 -781
- package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/cn.json +0 -782
- package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/en.json +0 -782
- package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/Assets.car +0 -0
- package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/Headers/QmsPlugin.h +0 -43
- package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/Headers/QmsPluginFramework.h +0 -17
- package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/Info.plist +0 -0
- package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/Modules/module.modulemap +0 -6
- package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/Montserrat-Bold.ttf +0 -0
- package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/Montserrat-BoldItalic.ttf +0 -0
- package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/Montserrat-ExtraBold.ttf +0 -0
- package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/Montserrat-ExtraLight.ttf +0 -0
- package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/Montserrat-Italic.ttf +0 -0
- package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/Montserrat-Light.ttf +0 -0
- package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/Montserrat-Medium.ttf +0 -0
- package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/Montserrat-Regular.ttf +0 -0
- package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/Montserrat-SemiBold.ttf +0 -0
- package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/Montserrat-Thin.ttf +0 -0
- package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/QmsPluginFramework +0 -0
- package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/_CodeSignature/CodeResources +0 -289
- package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/bm.json +0 -781
- package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/cn.json +0 -782
- package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/en.json +0 -782
|
@@ -73,6 +73,865 @@ RCT_EXPORT_MODULE(QmsModule)
|
|
|
73
73
|
} @catch (__unused NSException *exception) {}
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
+
- (NSString *)stringFromDictionary:(NSDictionary *)dictionary keys:(NSArray<NSString *> *)keys {
|
|
77
|
+
if (![dictionary isKindOfClass:[NSDictionary class]]) return @"";
|
|
78
|
+
for (NSString *key in keys) {
|
|
79
|
+
id value = dictionary[key];
|
|
80
|
+
if ((!value || value == [NSNull null]) && [dictionary[@"data"] isKindOfClass:[NSDictionary class]]) {
|
|
81
|
+
value = dictionary[@"data"][key];
|
|
82
|
+
}
|
|
83
|
+
if (value && value != [NSNull null]) {
|
|
84
|
+
NSString *text = [[value description] stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet];
|
|
85
|
+
if (text.length > 0 && ![text.lowercaseString isEqualToString:@"null"]) return text;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return @"";
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
- (void)callAPIConfigSelector:(NSString *)selectorName stringValue:(NSString *)value {
|
|
92
|
+
if (selectorName.length == 0 || value.length == 0) return;
|
|
93
|
+
Class apiConfig = NSClassFromString(@"APIConfig");
|
|
94
|
+
SEL selector = NSSelectorFromString(selectorName);
|
|
95
|
+
if (!apiConfig || ![apiConfig respondsToSelector:selector]) return;
|
|
96
|
+
|
|
97
|
+
NSMethodSignature *signature = [apiConfig methodSignatureForSelector:selector];
|
|
98
|
+
if (!signature) return;
|
|
99
|
+
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
|
|
100
|
+
[invocation setSelector:selector];
|
|
101
|
+
[invocation setTarget:apiConfig];
|
|
102
|
+
NSString *argument = value;
|
|
103
|
+
[invocation setArgument:&argument atIndex:2];
|
|
104
|
+
[invocation invoke];
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
- (void)callAPIConfigSelector:(NSString *)selectorName boolValue:(BOOL)value {
|
|
108
|
+
Class apiConfig = NSClassFromString(@"APIConfig");
|
|
109
|
+
SEL selector = NSSelectorFromString(selectorName);
|
|
110
|
+
if (!apiConfig || ![apiConfig respondsToSelector:selector]) return;
|
|
111
|
+
|
|
112
|
+
NSMethodSignature *signature = [apiConfig methodSignatureForSelector:selector];
|
|
113
|
+
if (!signature) return;
|
|
114
|
+
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
|
|
115
|
+
[invocation setSelector:selector];
|
|
116
|
+
[invocation setTarget:apiConfig];
|
|
117
|
+
BOOL argument = value;
|
|
118
|
+
[invocation setArgument:&argument atIndex:2];
|
|
119
|
+
[invocation invoke];
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
- (void)configureAPIForAddIssueWithToken:(NSString *)userToken
|
|
123
|
+
clientID:(NSString *)clientID
|
|
124
|
+
clientCode:(NSString *)clientCode
|
|
125
|
+
isOrigin:(BOOL)isOrigin
|
|
126
|
+
options:(NSDictionary *)options {
|
|
127
|
+
[self callAPIConfigSelector:@"setAuthToken:" stringValue:userToken ?: @""];
|
|
128
|
+
[self callAPIConfigSelector:@"setClientId:" stringValue:clientID ?: @""];
|
|
129
|
+
[self callAPIConfigSelector:@"setClientCode:" stringValue:clientCode ?: @""];
|
|
130
|
+
[self callAPIConfigSelector:@"setIsOrigin:" boolValue:isOrigin];
|
|
131
|
+
|
|
132
|
+
NSString *projectId = [self stringFromDictionary:options keys:@[@"projectId", @"PROJECT_ID", @"project_id"]];
|
|
133
|
+
NSString *planId = [self stringFromDictionary:options keys:@[@"drawingPlanId", @"DRAWING_PLAN_ID", @"drawing_plan_id", @"plan_id", @"unitId", @"unit_id"]];
|
|
134
|
+
NSString *projectName = [self stringFromDictionary:options keys:@[@"projectName", @"PROJECT_NAME", @"project_name"]];
|
|
135
|
+
NSString *projectCode = [self stringFromDictionary:options keys:@[@"unitName", @"UNIT_NAME", @"unit_name"]];
|
|
136
|
+
NSString *userRole = [self stringFromDictionary:options keys:@[@"userRole", @"USER_ROLE", @"user_role", @"roleUser", @"ROLE_USER", @"role_user"]];
|
|
137
|
+
NSString *userId = [self stringFromDictionary:options keys:@[@"userId", @"USER_ID", @"user_id", @"roleUserId", @"ROLEUSER_ID", @"roleuser_id"]];
|
|
138
|
+
NSString *userName = [self stringFromDictionary:options keys:@[@"userName", @"USER_NAME", @"user_name"]];
|
|
139
|
+
|
|
140
|
+
[self callAPIConfigSelector:@"setProjectId:" stringValue:projectId];
|
|
141
|
+
[self callAPIConfigSelector:@"setDrawingPlanId:" stringValue:planId];
|
|
142
|
+
[self callAPIConfigSelector:@"setProjName:" stringValue:projectName];
|
|
143
|
+
[self callAPIConfigSelector:@"setProjCode:" stringValue:projectCode];
|
|
144
|
+
[self callAPIConfigSelector:@"setUserName:" stringValue:userName];
|
|
145
|
+
|
|
146
|
+
if (userRole.length > 0) [self callAPIConfigSelector:@"setUserRole:" stringValue:userRole];
|
|
147
|
+
if (userId.length > 0) [self callAPIConfigSelector:@"setUserId:" stringValue:userId];
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
- (void)fetchCompanyUrlForAddIssueWithToken:(NSString *)userToken
|
|
151
|
+
clientCode:(NSString *)clientCode
|
|
152
|
+
isOrigin:(BOOL)isOrigin
|
|
153
|
+
completion:(dispatch_block_t)completion {
|
|
154
|
+
if (clientCode.length == 0) {
|
|
155
|
+
completion();
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
NSURL *url = [NSURL URLWithString:@"https://qms1.commudesk.com/api/framework/companycode/get"];
|
|
160
|
+
if (!url) {
|
|
161
|
+
completion();
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
NSDictionary *data = @{
|
|
166
|
+
@"os": @"IOS",
|
|
167
|
+
@"imei": [[[UIDevice currentDevice] identifierForVendor] UUIDString] ?: @"IOS",
|
|
168
|
+
@"os_version": [[UIDevice currentDevice] systemVersion] ?: @"",
|
|
169
|
+
@"sdk_version": [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"] ?: @"",
|
|
170
|
+
@"devices_model": [[UIDevice currentDevice] model] ?: @"",
|
|
171
|
+
@"is_origin": @(isOrigin ? 1 : 0),
|
|
172
|
+
@"company_code": clientCode ?: @""
|
|
173
|
+
};
|
|
174
|
+
NSDictionary *payload = @{@"data": data};
|
|
175
|
+
NSError *bodyError = nil;
|
|
176
|
+
NSData *body = [NSJSONSerialization dataWithJSONObject:payload options:0 error:&bodyError];
|
|
177
|
+
if (!body || bodyError) {
|
|
178
|
+
completion();
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
|
|
183
|
+
request.HTTPMethod = @"POST";
|
|
184
|
+
request.HTTPBody = body;
|
|
185
|
+
[request setValue:@"application/json; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
|
|
186
|
+
[request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
|
|
187
|
+
if (userToken.length > 0) {
|
|
188
|
+
[request setValue:[NSString stringWithFormat:@"Bearer %@", userToken] forHTTPHeaderField:@"Authorization"];
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request
|
|
192
|
+
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
|
|
193
|
+
if (!error && data.length > 0) {
|
|
194
|
+
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
|
|
195
|
+
if ([json isKindOfClass:[NSDictionary class]]) {
|
|
196
|
+
NSDictionary *responseData = json[@"Data"] ?: json[@"data"];
|
|
197
|
+
NSString *urlPath = [responseData isKindOfClass:[NSDictionary class]] ? [responseData[@"url_path"] description] : @"";
|
|
198
|
+
if (urlPath.length > 0) {
|
|
199
|
+
NSString *baseURL = [urlPath stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet];
|
|
200
|
+
while ([baseURL hasSuffix:@"/"]) {
|
|
201
|
+
baseURL = [baseURL substringToIndex:baseURL.length - 1];
|
|
202
|
+
}
|
|
203
|
+
if (![baseURL hasSuffix:@"/api"]) {
|
|
204
|
+
baseURL = [baseURL stringByAppendingString:@"/api"];
|
|
205
|
+
}
|
|
206
|
+
[self callAPIConfigSelector:@"setBaseURL:" stringValue:baseURL];
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
dispatch_async(dispatch_get_main_queue(), completion);
|
|
211
|
+
}];
|
|
212
|
+
[task resume];
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
- (void)presentAddIssueWithOptions:(NSDictionary *)options
|
|
216
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
217
|
+
rejecter:(RCTPromiseRejectBlock)reject {
|
|
218
|
+
NSString *planId = [self stringFromDictionary:options keys:@[@"drawingPlanId", @"DRAWING_PLAN_ID", @"drawing_plan_id", @"plan_id", @"unitId", @"unit_id"]];
|
|
219
|
+
if (planId.length == 0) {
|
|
220
|
+
reject(@"QMS_ADD_ISSUE_MISSING_DRAWING_PLAN_ID", @"drawingPlanId/drawing_plan_id/plan_id is required to open Add Issue directly.", nil);
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
UIViewController *presenter = [self topViewController];
|
|
225
|
+
if (!presenter) {
|
|
226
|
+
reject(@"QMS_ADD_ISSUE_NO_PRESENTER", @"Unable to find a view controller to present Add Issue.", nil);
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
Class planClass = NSClassFromString(@"PlanViewController");
|
|
231
|
+
if (!planClass) {
|
|
232
|
+
reject(@"QMS_ADD_ISSUE_UNAVAILABLE", @"QMS Add Issue screen is not available.", nil);
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
UIViewController *planVC = [[planClass alloc] init];
|
|
237
|
+
NSString *projectName = [self stringFromDictionary:options keys:@[@"projectName", @"PROJECT_NAME", @"project_name"]];
|
|
238
|
+
NSString *projectCode = [self stringFromDictionary:options keys:@[@"unitName", @"UNIT_NAME", @"unit_name"]];
|
|
239
|
+
NSString *unitName = [self stringFromDictionary:options keys:@[@"unitName", @"UNIT_NAME", @"unit_name", @"draw_plan_name"]];
|
|
240
|
+
NSString *issueLimit = [self stringFromDictionary:options keys:@[@"issueLimit", @"ISSUE_LIMIT", @"issue_limit"]];
|
|
241
|
+
NSString *issueLimitWarning = [self stringFromDictionary:options keys:@[@"issueLimitWarningText", @"ISSUE_LIMIT_WARNING_TEXT", @"issue_limit_warning_text"]];
|
|
242
|
+
NSString *draftCount = [self stringFromDictionary:options keys:@[@"draftCount", @"DRAFT_COUNT", @"draft_count"]];
|
|
243
|
+
NSString *userName = [self stringFromDictionary:options keys:@[@"userName", @"USER_NAME", @"user_name"]];
|
|
244
|
+
|
|
245
|
+
@try {
|
|
246
|
+
[planVC setValue:planId forKey:@"planId"];
|
|
247
|
+
if (unitName.length > 0) [planVC setValue:unitName forKey:@"unitName"];
|
|
248
|
+
if (projectName.length > 0) [planVC setValue:projectName forKey:@"projectName"];
|
|
249
|
+
if (projectCode.length > 0) [planVC setValue:projectCode forKey:@"projectCode"];
|
|
250
|
+
if (issueLimit.length > 0) [planVC setValue:@(issueLimit.integerValue) forKey:@"issueLimit"];
|
|
251
|
+
if (issueLimitWarning.length > 0) [planVC setValue:issueLimitWarning forKey:@"issueLimitWarning"];
|
|
252
|
+
if (draftCount.length > 0) [planVC setValue:@(draftCount.integerValue) forKey:@"draftCount"];
|
|
253
|
+
if (userName.length > 0) [planVC setValue:userName forKey:@"userName"];
|
|
254
|
+
} @catch (__unused NSException *exception) {}
|
|
255
|
+
|
|
256
|
+
Class delegateClass = NSClassFromString(@"QmsSlideModalTransitionDelegate");
|
|
257
|
+
if (delegateClass && [delegateClass respondsToSelector:NSSelectorFromString(@"shared")]) {
|
|
258
|
+
@try {
|
|
259
|
+
id delegate = [delegateClass performSelector:NSSelectorFromString(@"shared")];
|
|
260
|
+
planVC.modalPresentationStyle = UIModalPresentationCustom;
|
|
261
|
+
planVC.transitioningDelegate = delegate;
|
|
262
|
+
} @catch (__unused NSException *exception) {
|
|
263
|
+
planVC.modalPresentationStyle = UIModalPresentationFullScreen;
|
|
264
|
+
}
|
|
265
|
+
} else {
|
|
266
|
+
planVC.modalPresentationStyle = UIModalPresentationFullScreen;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
[presenter presentViewController:planVC animated:YES completion:^{
|
|
270
|
+
resolve(@YES);
|
|
271
|
+
}];
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
- (void)presentPropertyInfoWithOptions:(NSDictionary *)options
|
|
275
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
276
|
+
rejecter:(RCTPromiseRejectBlock)reject {
|
|
277
|
+
NSString *planId = [self stringFromDictionary:options keys:@[@"drawingPlanId", @"DRAWING_PLAN_ID", @"drawing_plan_id", @"plan_id", @"unitId", @"unit_id"]];
|
|
278
|
+
if (planId.length == 0) {
|
|
279
|
+
reject(@"QMS_PROPERTY_INFO_MISSING_PLAN_ID", @"drawingPlanId/drawing_plan_id/plan_id is required to open Property Info directly.", nil);
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
UIViewController *presenter = [self topViewController];
|
|
284
|
+
if (!presenter) {
|
|
285
|
+
reject(@"QMS_PROPERTY_INFO_NO_PRESENTER", @"Unable to find a view controller to present Property Info.", nil);
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
Class vcClass = NSClassFromString(@"GeneralInfoViewController");
|
|
290
|
+
if (!vcClass) {
|
|
291
|
+
reject(@"QMS_PROPERTY_INFO_UNAVAILABLE", @"QMS Property Info screen is not available.", nil);
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
UIViewController *vc = [[vcClass alloc] init];
|
|
296
|
+
NSString *unitName = [self stringFromDictionary:options keys:@[@"unitName", @"UNIT_NAME", @"unit_name", @"draw_plan_name"]];
|
|
297
|
+
NSString *projectName = [self stringFromDictionary:options keys:@[@"projectName", @"PROJECT_NAME", @"project_name"]];
|
|
298
|
+
NSString *projectId = [self stringFromDictionary:options keys:@[@"projectId", @"PROJECT_ID", @"project_id"]];
|
|
299
|
+
|
|
300
|
+
@try {
|
|
301
|
+
[vc setValue:planId forKey:@"planId"];
|
|
302
|
+
if (unitName.length > 0) [vc setValue:unitName forKey:@"unitName"];
|
|
303
|
+
if (projectName.length > 0) [vc setValue:projectName forKey:@"projectName"];
|
|
304
|
+
if (projectId.length > 0) [vc setValue:@(projectId.integerValue) forKey:@"projectId"];
|
|
305
|
+
} @catch (__unused NSException *exception) {}
|
|
306
|
+
|
|
307
|
+
Class delegateClass = NSClassFromString(@"QmsSlideModalTransitionDelegate");
|
|
308
|
+
if (delegateClass && [delegateClass respondsToSelector:NSSelectorFromString(@"shared")]) {
|
|
309
|
+
@try {
|
|
310
|
+
id delegate = [delegateClass performSelector:NSSelectorFromString(@"shared")];
|
|
311
|
+
vc.modalPresentationStyle = UIModalPresentationCustom;
|
|
312
|
+
vc.transitioningDelegate = delegate;
|
|
313
|
+
} @catch (__unused NSException *exception) {
|
|
314
|
+
vc.modalPresentationStyle = UIModalPresentationFullScreen;
|
|
315
|
+
}
|
|
316
|
+
} else {
|
|
317
|
+
vc.modalPresentationStyle = UIModalPresentationFullScreen;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
[presenter presentViewController:vc animated:YES completion:^{
|
|
321
|
+
resolve(@YES);
|
|
322
|
+
}];
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
- (void)presentAppointmentListWithOptions:(NSDictionary *)options
|
|
326
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
327
|
+
rejecter:(RCTPromiseRejectBlock)reject {
|
|
328
|
+
UIViewController *presenter = [self topViewController];
|
|
329
|
+
if (!presenter) {
|
|
330
|
+
reject(@"QMS_APPT_LIST_NO_PRESENTER", @"Unable to find a view controller to present Appointment List.", nil);
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
Class vcClass = NSClassFromString(@"AppointmentViewMoreViewController");
|
|
335
|
+
if (!vcClass) {
|
|
336
|
+
reject(@"QMS_APPT_LIST_UNAVAILABLE", @"QMS Appointment List screen is not available.", nil);
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
UIViewController *vc = [[vcClass alloc] init];
|
|
341
|
+
NSString *projectName = [self stringFromDictionary:options keys:@[@"projectName", @"PROJECT_NAME", @"project_name"]];
|
|
342
|
+
NSString *unitName = [self stringFromDictionary:options keys:@[@"unitName", @"UNIT_NAME", @"unit_name"]];
|
|
343
|
+
NSString *planId = [self stringFromDictionary:options keys:@[@"drawingPlanId", @"DRAWING_PLAN_ID", @"drawing_plan_id", @"plan_id", @"unitId", @"unit_id"]];
|
|
344
|
+
|
|
345
|
+
// AppointmentViewMoreViewController uses projectCode for the unit name
|
|
346
|
+
@try {
|
|
347
|
+
if (projectName.length > 0) [vc setValue:projectName forKey:@"projectName"];
|
|
348
|
+
if (unitName.length > 0) [vc setValue:unitName forKey:@"projectCode"];
|
|
349
|
+
if (planId.length > 0) [self callAPIConfigSelector:@"setDrawingPlanId:" stringValue:planId];
|
|
350
|
+
} @catch (__unused NSException *exception) {}
|
|
351
|
+
|
|
352
|
+
Class delegateClass = NSClassFromString(@"QmsSlideModalTransitionDelegate");
|
|
353
|
+
if (delegateClass && [delegateClass respondsToSelector:NSSelectorFromString(@"shared")]) {
|
|
354
|
+
@try {
|
|
355
|
+
id delegate = [delegateClass performSelector:NSSelectorFromString(@"shared")];
|
|
356
|
+
vc.modalPresentationStyle = UIModalPresentationCustom;
|
|
357
|
+
vc.transitioningDelegate = delegate;
|
|
358
|
+
} @catch (__unused NSException *exception) {
|
|
359
|
+
vc.modalPresentationStyle = UIModalPresentationFullScreen;
|
|
360
|
+
}
|
|
361
|
+
} else {
|
|
362
|
+
vc.modalPresentationStyle = UIModalPresentationFullScreen;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
[presenter presentViewController:vc animated:YES completion:^{
|
|
366
|
+
resolve(@YES);
|
|
367
|
+
}];
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
- (void)presentMakeAppointmentWithOptions:(NSDictionary *)options
|
|
371
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
372
|
+
rejecter:(RCTPromiseRejectBlock)reject {
|
|
373
|
+
UIViewController *presenter = [self topViewController];
|
|
374
|
+
if (!presenter) {
|
|
375
|
+
reject(@"QMS_MAKE_APPT_NO_PRESENTER", @"Unable to find a view controller to present Make Appointment.", nil);
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
Class vcClass = NSClassFromString(@"AppointmentViewController");
|
|
380
|
+
if (!vcClass) {
|
|
381
|
+
reject(@"QMS_MAKE_APPT_UNAVAILABLE", @"QMS Make Appointment screen is not available.", nil);
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
UIViewController *vc = [[vcClass alloc] init];
|
|
386
|
+
NSString *projectId = [self stringFromDictionary:options keys:@[@"projectId", @"PROJECT_ID", @"project_id"]];
|
|
387
|
+
NSString *projectName = [self stringFromDictionary:options keys:@[@"projectName", @"PROJECT_NAME", @"project_name"]];
|
|
388
|
+
NSString *unitName = [self stringFromDictionary:options keys:@[@"unitName", @"UNIT_NAME", @"unit_name"]];
|
|
389
|
+
NSString *planId = [self stringFromDictionary:options keys:@[@"drawingPlanId", @"DRAWING_PLAN_ID", @"drawing_plan_id", @"plan_id", @"unitId", @"unit_id"]];
|
|
390
|
+
|
|
391
|
+
@try {
|
|
392
|
+
if (projectId.length > 0) [vc setValue:projectId forKey:@"projectId"];
|
|
393
|
+
if (projectName.length > 0) [vc setValue:projectName forKey:@"projectName"];
|
|
394
|
+
if (unitName.length > 0) [vc setValue:unitName forKey:@"projectCode"];
|
|
395
|
+
if (planId.length > 0) [self callAPIConfigSelector:@"setDrawingPlanId:" stringValue:planId];
|
|
396
|
+
} @catch (__unused NSException *exception) {}
|
|
397
|
+
|
|
398
|
+
Class delegateClass = NSClassFromString(@"QmsSlideModalTransitionDelegate");
|
|
399
|
+
if (delegateClass && [delegateClass respondsToSelector:NSSelectorFromString(@"shared")]) {
|
|
400
|
+
@try {
|
|
401
|
+
id delegate = [delegateClass performSelector:NSSelectorFromString(@"shared")];
|
|
402
|
+
vc.modalPresentationStyle = UIModalPresentationCustom;
|
|
403
|
+
vc.transitioningDelegate = delegate;
|
|
404
|
+
} @catch (__unused NSException *exception) {
|
|
405
|
+
vc.modalPresentationStyle = UIModalPresentationFullScreen;
|
|
406
|
+
}
|
|
407
|
+
} else {
|
|
408
|
+
vc.modalPresentationStyle = UIModalPresentationFullScreen;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
[presenter presentViewController:vc animated:YES completion:^{
|
|
412
|
+
resolve(@YES);
|
|
413
|
+
}];
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
- (void)presentPoaSignOffWithOptions:(NSDictionary *)options
|
|
417
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
418
|
+
rejecter:(RCTPromiseRejectBlock)reject {
|
|
419
|
+
UIViewController *presenter = [self topViewController];
|
|
420
|
+
if (!presenter) {
|
|
421
|
+
reject(@"QMS_POA_NO_PRESENTER", @"Unable to find a view controller to present POA Sign-Off.", nil);
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
Class vcClass = NSClassFromString(@"POAViewController");
|
|
426
|
+
if (!vcClass) {
|
|
427
|
+
reject(@"QMS_POA_UNAVAILABLE", @"QMS POA Sign-Off screen is not available.", nil);
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
UIViewController *vc = [[vcClass alloc] init];
|
|
432
|
+
NSString *projectName = [self stringFromDictionary:options keys:@[@"projectName", @"PROJECT_NAME", @"project_name"]];
|
|
433
|
+
NSString *unitName = [self stringFromDictionary:options keys:@[@"unitName", @"UNIT_NAME", @"unit_name"]];
|
|
434
|
+
NSString *tnc = [self stringFromDictionary:options keys:@[@"tnc", @"TNC", @"terms_and_condition"]];
|
|
435
|
+
|
|
436
|
+
@try {
|
|
437
|
+
if (projectName.length > 0) [vc setValue:projectName forKey:@"projectName"];
|
|
438
|
+
if (unitName.length > 0) [vc setValue:unitName forKey:@"projectCode"];
|
|
439
|
+
if (tnc.length > 0) [vc setValue:tnc forKey:@"tnc"];
|
|
440
|
+
} @catch (__unused NSException *exception) {}
|
|
441
|
+
|
|
442
|
+
Class delegateClass = NSClassFromString(@"QmsSlideModalTransitionDelegate");
|
|
443
|
+
if (delegateClass && [delegateClass respondsToSelector:NSSelectorFromString(@"shared")]) {
|
|
444
|
+
@try {
|
|
445
|
+
id delegate = [delegateClass performSelector:NSSelectorFromString(@"shared")];
|
|
446
|
+
vc.modalPresentationStyle = UIModalPresentationCustom;
|
|
447
|
+
vc.transitioningDelegate = delegate;
|
|
448
|
+
} @catch (__unused NSException *exception) {
|
|
449
|
+
vc.modalPresentationStyle = UIModalPresentationFullScreen;
|
|
450
|
+
}
|
|
451
|
+
} else {
|
|
452
|
+
vc.modalPresentationStyle = UIModalPresentationFullScreen;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
[presenter presentViewController:vc animated:YES completion:^{
|
|
456
|
+
resolve(@YES);
|
|
457
|
+
}];
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
- (void)presentIssueListWithOptions:(NSDictionary *)options
|
|
461
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
462
|
+
rejecter:(RCTPromiseRejectBlock)reject {
|
|
463
|
+
UIViewController *presenter = [self topViewController];
|
|
464
|
+
if (!presenter) {
|
|
465
|
+
reject(@"QMS_ISSUE_LIST_NO_PRESENTER", @"Unable to find a view controller to present Issue List.", nil);
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
Class vcClass = NSClassFromString(@"IssuesViewController");
|
|
470
|
+
if (!vcClass) {
|
|
471
|
+
reject(@"QMS_ISSUE_LIST_UNAVAILABLE", @"QMS Issue List screen is not available.", nil);
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
UIViewController *vc = [[vcClass alloc] init];
|
|
476
|
+
NSString *projectName = [self stringFromDictionary:options keys:@[@"projectName", @"PROJECT_NAME", @"project_name"]];
|
|
477
|
+
NSString *unitName = [self stringFromDictionary:options keys:@[@"unitName", @"UNIT_NAME", @"unit_name"]];
|
|
478
|
+
NSString *planId = [self stringFromDictionary:options keys:@[@"drawingPlanId", @"DRAWING_PLAN_ID", @"drawing_plan_id", @"plan_id", @"unitId", @"unit_id"]];
|
|
479
|
+
NSString *headerTitle = [self stringFromDictionary:options keys:@[@"headerTitle", @"HEADER_TITLE", @"header_title"]];
|
|
480
|
+
|
|
481
|
+
// IssuesViewController uses projectCode for the unit/draw-plan name and
|
|
482
|
+
// projectName for the project name. The drawing plan id flows via APIConfig.
|
|
483
|
+
@try {
|
|
484
|
+
if (projectName.length > 0) [vc setValue:projectName forKey:@"projectName"];
|
|
485
|
+
if (unitName.length > 0) [vc setValue:unitName forKey:@"projectCode"];
|
|
486
|
+
if (planId.length > 0) [self callAPIConfigSelector:@"setDrawingPlanId:" stringValue:planId];
|
|
487
|
+
if (headerTitle.length > 0) [vc setValue:headerTitle forKey:@"headerTitle"];
|
|
488
|
+
|
|
489
|
+
// roa flag — accept "1"/1 as true, anything else as false
|
|
490
|
+
id roaRaw = options[@"roa"] ?: options[@"ROA"];
|
|
491
|
+
BOOL roaBln = [roaRaw isKindOfClass:[NSNumber class]] ? [roaRaw isEqualToNumber:@1] :
|
|
492
|
+
[roaRaw isKindOfClass:[NSString class]] ? [roaRaw isEqualToString:@"1"] : NO;
|
|
493
|
+
[self callAPIConfigSelector:@"setIsRoaBln:" boolValue:roaBln];
|
|
494
|
+
[vc setValue:@(roaBln) forKey:@"roaBln"];
|
|
495
|
+
|
|
496
|
+
// multiZone flag — accept YES/true/1/"1" as true
|
|
497
|
+
id multiZoneRaw = options[@"multiZone"] ?: options[@"MULTI_ZONE"] ?: options[@"multi_zone"];
|
|
498
|
+
NSLog(@"🔍 [openIssueList] multiZone raw value: %@ (class: %@)", multiZoneRaw, NSStringFromClass([multiZoneRaw class]));
|
|
499
|
+
BOOL multiZoneBln = [multiZoneRaw isKindOfClass:[NSNumber class]] ? [multiZoneRaw boolValue] :
|
|
500
|
+
[multiZoneRaw isKindOfClass:[NSString class]] ? [multiZoneRaw isEqualToString:@"1"] : NO;
|
|
501
|
+
NSLog(@"🔍 [openIssueList] multiZone resolved BOOL: %@", multiZoneBln ? @"YES" : @"NO");
|
|
502
|
+
[self callAPIConfigSelector:@"setIsMulti:" boolValue:multiZoneBln];
|
|
503
|
+
NSLog(@"🔍 [openIssueList] APIConfig.isMulti after set: %@", [NSClassFromString(@"APIConfig") valueForKey:@"isMulti"] ? @"YES" : @"NO");
|
|
504
|
+
[vc setValue:@(multiZoneBln) forKey:@"isMulti"];
|
|
505
|
+
} @catch (__unused NSException *exception) {
|
|
506
|
+
NSLog(@"⚠️ [openIssueList] exception while setting multiZone: %@", exception);
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
Class delegateClass = NSClassFromString(@"QmsSlideModalTransitionDelegate");
|
|
510
|
+
if (delegateClass && [delegateClass respondsToSelector:NSSelectorFromString(@"shared")]) {
|
|
511
|
+
@try {
|
|
512
|
+
id delegate = [delegateClass performSelector:NSSelectorFromString(@"shared")];
|
|
513
|
+
vc.modalPresentationStyle = UIModalPresentationCustom;
|
|
514
|
+
vc.transitioningDelegate = delegate;
|
|
515
|
+
} @catch (__unused NSException *exception) {
|
|
516
|
+
vc.modalPresentationStyle = UIModalPresentationFullScreen;
|
|
517
|
+
}
|
|
518
|
+
} else {
|
|
519
|
+
vc.modalPresentationStyle = UIModalPresentationFullScreen;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
[presenter presentViewController:vc animated:YES completion:^{
|
|
523
|
+
resolve(@YES);
|
|
524
|
+
}];
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
- (void)presentAnnouncementWithOptions:(NSDictionary *)options
|
|
528
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
529
|
+
rejecter:(RCTPromiseRejectBlock)reject {
|
|
530
|
+
UIViewController *presenter = [self topViewController];
|
|
531
|
+
if (!presenter) {
|
|
532
|
+
reject(@"QMS_ANNOUNCEMENT_NO_PRESENTER", @"Unable to find a view controller to present Announcement.", nil);
|
|
533
|
+
return;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
Class vcClass = NSClassFromString(@"AnnouncementViewController");
|
|
537
|
+
if (!vcClass) {
|
|
538
|
+
reject(@"QMS_ANNOUNCEMENT_UNAVAILABLE", @"QMS Announcement screen is not available.", nil);
|
|
539
|
+
return;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
UIViewController *vc = [[vcClass alloc] init];
|
|
543
|
+
NSString *projectId = [self stringFromDictionary:options keys:@[@"projectId", @"PROJECT_ID", @"project_id"]];
|
|
544
|
+
NSString *projectName = [self stringFromDictionary:options keys:@[@"projectName", @"PROJECT_NAME", @"project_name"]];
|
|
545
|
+
NSString *listTitle = [self stringFromDictionary:options keys:@[@"announcementTitle", @"ANNOUNCEMENT_TITLE", @"announcement_title"]];
|
|
546
|
+
NSString *detailTitle = [self stringFromDictionary:options keys:@[@"announcementDetailTitle", @"ANNOUNCEMENT_DETAIL_TITLE", @"announcement_detail_title"]];
|
|
547
|
+
|
|
548
|
+
@try {
|
|
549
|
+
if (projectId.length > 0) [self callAPIConfigSelector:@"setProjectId:" stringValue:projectId];
|
|
550
|
+
if (projectName.length > 0) [self callAPIConfigSelector:@"setProjName:" stringValue:projectName];
|
|
551
|
+
if (listTitle.length > 0) [vc setValue:listTitle forKey:@"screenTitle"];
|
|
552
|
+
if (detailTitle.length > 0) [vc setValue:detailTitle forKey:@"detailScreenTitle"];
|
|
553
|
+
} @catch (__unused NSException *exception) {}
|
|
554
|
+
|
|
555
|
+
Class delegateClass = NSClassFromString(@"QmsSlideModalTransitionDelegate");
|
|
556
|
+
if (delegateClass && [delegateClass respondsToSelector:NSSelectorFromString(@"shared")]) {
|
|
557
|
+
@try {
|
|
558
|
+
id delegate = [delegateClass performSelector:NSSelectorFromString(@"shared")];
|
|
559
|
+
vc.modalPresentationStyle = UIModalPresentationCustom;
|
|
560
|
+
vc.transitioningDelegate = delegate;
|
|
561
|
+
} @catch (__unused NSException *exception) {
|
|
562
|
+
vc.modalPresentationStyle = UIModalPresentationFullScreen;
|
|
563
|
+
}
|
|
564
|
+
} else {
|
|
565
|
+
vc.modalPresentationStyle = UIModalPresentationFullScreen;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
[presenter presentViewController:vc animated:YES completion:^{
|
|
569
|
+
resolve(@YES);
|
|
570
|
+
}];
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
- (void)presentAnnouncementDetailsWithOptions:(NSDictionary *)options
|
|
574
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
575
|
+
rejecter:(RCTPromiseRejectBlock)reject {
|
|
576
|
+
UIViewController *presenter = [self topViewController];
|
|
577
|
+
if (!presenter) {
|
|
578
|
+
reject(@"QMS_ANNOUNCEMENT_DETAILS_NO_PRESENTER", @"Unable to find a view controller to present Announcement Details.", nil);
|
|
579
|
+
return;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
Class vcClass = NSClassFromString(@"AnnouncementDetailsViewController");
|
|
583
|
+
NSLog(@"[QmsModule] AnnouncementDetailsViewController class lookup: %@", vcClass ? NSStringFromClass(vcClass) : @"NIL — class not found in binary");
|
|
584
|
+
if (!vcClass) {
|
|
585
|
+
NSLog(@"[QmsModule] AnnouncementDetailsViewController not found — falling back to RN screen");
|
|
586
|
+
reject(@"QMS_ANNOUNCEMENT_DETAILS_UNAVAILABLE", @"QMS Announcement Details screen is not available.", nil);
|
|
587
|
+
return;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
UIViewController *vc = [[vcClass alloc] init];
|
|
591
|
+
|
|
592
|
+
// Build the data dict that AnnouncementDetailsViewController.data expects.
|
|
593
|
+
// The JS caller passes the announcement fields as top-level keys in options.
|
|
594
|
+
NSMutableDictionary *announcementData = [NSMutableDictionary dictionary];
|
|
595
|
+
NSArray *dataKeys = @[@"id", @"title", @"description", @"start_date", @"end_date",
|
|
596
|
+
@"created_at", @"image", @"cover", @"popup", @"date"];
|
|
597
|
+
for (NSString *key in dataKeys) {
|
|
598
|
+
id value = options[key];
|
|
599
|
+
if (value && value != [NSNull null]) {
|
|
600
|
+
announcementData[key] = value;
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
NSString *screenTitle = [self stringFromDictionary:options
|
|
605
|
+
keys:@[@"announcementDetailTitle",
|
|
606
|
+
@"ANNOUNCEMENT_DETAIL_TITLE",
|
|
607
|
+
@"announcement_detail_title"]];
|
|
608
|
+
|
|
609
|
+
@try {
|
|
610
|
+
[vc setValue:[announcementData copy] forKey:@"data"];
|
|
611
|
+
// "from" is used by the details VC to choose the date key ("start_date" vs "date")
|
|
612
|
+
[vc setValue:@"announcement" forKey:@"from"];
|
|
613
|
+
if (screenTitle.length > 0) [vc setValue:screenTitle forKey:@"screenTitle"];
|
|
614
|
+
} @catch (__unused NSException *exception) {}
|
|
615
|
+
|
|
616
|
+
Class delegateClass = NSClassFromString(@"QmsSlideModalTransitionDelegate");
|
|
617
|
+
if (delegateClass && [delegateClass respondsToSelector:NSSelectorFromString(@"shared")]) {
|
|
618
|
+
@try {
|
|
619
|
+
id delegate = [delegateClass performSelector:NSSelectorFromString(@"shared")];
|
|
620
|
+
vc.modalPresentationStyle = UIModalPresentationCustom;
|
|
621
|
+
vc.transitioningDelegate = delegate;
|
|
622
|
+
} @catch (__unused NSException *exception) {
|
|
623
|
+
vc.modalPresentationStyle = UIModalPresentationFullScreen;
|
|
624
|
+
}
|
|
625
|
+
} else {
|
|
626
|
+
vc.modalPresentationStyle = UIModalPresentationFullScreen;
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
[presenter presentViewController:vc animated:YES completion:^{
|
|
630
|
+
resolve(@YES);
|
|
631
|
+
}];
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
- (void)presentProjectUpdateWithOptions:(NSDictionary *)options
|
|
635
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
636
|
+
rejecter:(RCTPromiseRejectBlock)reject {
|
|
637
|
+
UIViewController *presenter = [self topViewController];
|
|
638
|
+
if (!presenter) {
|
|
639
|
+
reject(@"QMS_PROJECT_UPDATE_NO_PRESENTER", @"Unable to find a view controller to present Community Notice.", nil);
|
|
640
|
+
return;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
// Prefer project-specific announcement screen; fall back to client-level one.
|
|
644
|
+
// Class vcClass = NSClassFromString(@"AnnouncementViewController");
|
|
645
|
+
Class vcClass = NSClassFromString(@"ClientAnnouncementViewController");
|
|
646
|
+
// if (!vcClass) {
|
|
647
|
+
// vcClass = NSClassFromString(@"ClientAnnouncementViewController");
|
|
648
|
+
|
|
649
|
+
// }
|
|
650
|
+
if (!vcClass) {
|
|
651
|
+
reject(@"QMS_PROJECT_UPDATE_UNAVAILABLE", @"QMS Community Notice screen is not available.", nil);
|
|
652
|
+
return;
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
UIViewController *vc = [[vcClass alloc] init];
|
|
656
|
+
NSString *projectId = [self stringFromDictionary:options keys:@[@"projectId", @"PROJECT_ID", @"project_id"]];
|
|
657
|
+
NSString *projectName = [self stringFromDictionary:options keys:@[@"projectName", @"PROJECT_NAME", @"project_name"]];
|
|
658
|
+
NSString *listTitle = [self stringFromDictionary:options keys:@[@"projectUpdateTitle", @"PROJECT_UPDATE_TITLE", @"project_update_title"]];
|
|
659
|
+
NSString *detailTitle = [self stringFromDictionary:options keys:@[@"projectUpdateDetailTitle", @"PROJECT_UPDATE_DETAIL_TITLE", @"project_update_detail_title"]];
|
|
660
|
+
|
|
661
|
+
@try {
|
|
662
|
+
if (projectId.length > 0) [self callAPIConfigSelector:@"setProjectId:" stringValue:projectId];
|
|
663
|
+
if (projectName.length > 0) [self callAPIConfigSelector:@"setProjName:" stringValue:projectName];
|
|
664
|
+
// Pass custom screen titles supplied by the JS caller (e.g. "Community Notice").
|
|
665
|
+
if (listTitle.length > 0) [vc setValue:listTitle forKey:@"screenTitle"];
|
|
666
|
+
if (detailTitle.length > 0) [vc setValue:detailTitle forKey:@"detailScreenTitle"];
|
|
667
|
+
} @catch (__unused NSException *exception) {}
|
|
668
|
+
|
|
669
|
+
Class delegateClass = NSClassFromString(@"QmsSlideModalTransitionDelegate");
|
|
670
|
+
if (delegateClass && [delegateClass respondsToSelector:NSSelectorFromString(@"shared")]) {
|
|
671
|
+
@try {
|
|
672
|
+
id delegate = [delegateClass performSelector:NSSelectorFromString(@"shared")];
|
|
673
|
+
vc.modalPresentationStyle = UIModalPresentationCustom;
|
|
674
|
+
vc.transitioningDelegate = delegate;
|
|
675
|
+
} @catch (__unused NSException *exception) {
|
|
676
|
+
vc.modalPresentationStyle = UIModalPresentationFullScreen;
|
|
677
|
+
}
|
|
678
|
+
} else {
|
|
679
|
+
vc.modalPresentationStyle = UIModalPresentationFullScreen;
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
[presenter presentViewController:vc animated:YES completion:^{
|
|
683
|
+
resolve(@YES);
|
|
684
|
+
}];
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
- (void)presentAccessItemWithOptions:(NSDictionary *)options
|
|
688
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
689
|
+
rejecter:(RCTPromiseRejectBlock)reject {
|
|
690
|
+
UIViewController *presenter = [self topViewController];
|
|
691
|
+
if (!presenter) {
|
|
692
|
+
reject(@"QMS_ACCESS_ITEM_NO_PRESENTER", @"Unable to find a view controller to present Access Item.", nil);
|
|
693
|
+
return;
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
Class vcClass = NSClassFromString(@"AccessItemViewController");
|
|
697
|
+
if (!vcClass) {
|
|
698
|
+
reject(@"QMS_ACCESS_ITEM_UNAVAILABLE", @"QMS Access Item screen is not available.", nil);
|
|
699
|
+
return;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
UIViewController *vc = [[vcClass alloc] init];
|
|
703
|
+
NSString *projectName = [self stringFromDictionary:options keys:@[@"projectName", @"PROJECT_NAME", @"project_name"]];
|
|
704
|
+
NSString *projectCode = [self stringFromDictionary:options keys:@[@"unitName", @"UNIT_NAME", @"unit_name"]];
|
|
705
|
+
|
|
706
|
+
@try {
|
|
707
|
+
if (projectName.length > 0) [vc setValue:projectName forKey:@"projectName"];
|
|
708
|
+
if (projectCode.length > 0) [vc setValue:projectCode forKey:@"projectCode"];
|
|
709
|
+
} @catch (__unused NSException *exception) {}
|
|
710
|
+
|
|
711
|
+
Class delegateClass = NSClassFromString(@"QmsSlideModalTransitionDelegate");
|
|
712
|
+
if (delegateClass && [delegateClass respondsToSelector:NSSelectorFromString(@"shared")]) {
|
|
713
|
+
@try {
|
|
714
|
+
id delegate = [delegateClass performSelector:NSSelectorFromString(@"shared")];
|
|
715
|
+
vc.modalPresentationStyle = UIModalPresentationCustom;
|
|
716
|
+
vc.transitioningDelegate = delegate;
|
|
717
|
+
} @catch (__unused NSException *exception) {
|
|
718
|
+
vc.modalPresentationStyle = UIModalPresentationFullScreen;
|
|
719
|
+
}
|
|
720
|
+
} else {
|
|
721
|
+
vc.modalPresentationStyle = UIModalPresentationFullScreen;
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
[presenter presentViewController:vc animated:YES completion:^{
|
|
725
|
+
resolve(@YES);
|
|
726
|
+
}];
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
- (void)presentInboxWithOptions:(NSDictionary *)options
|
|
730
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
731
|
+
rejecter:(RCTPromiseRejectBlock)reject {
|
|
732
|
+
UIViewController *presenter = [self topViewController];
|
|
733
|
+
if (!presenter) {
|
|
734
|
+
reject(@"QMS_INBOX_NO_PRESENTER", @"Unable to find a view controller to present Inbox.", nil);
|
|
735
|
+
return;
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
Class vcClass = NSClassFromString(@"NotificationViewController");
|
|
739
|
+
if (!vcClass) {
|
|
740
|
+
reject(@"QMS_INBOX_UNAVAILABLE", @"QMS Inbox screen is not available.", nil);
|
|
741
|
+
return;
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
UIViewController *vc = [[vcClass alloc] init];
|
|
745
|
+
NSString *projectId = [self stringFromDictionary:options keys:@[@"projectId", @"PROJECT_ID", @"project_id"]];
|
|
746
|
+
NSString *projectName = [self stringFromDictionary:options keys:@[@"projectName", @"PROJECT_NAME", @"project_name"]];
|
|
747
|
+
NSString *planId = [self stringFromDictionary:options keys:@[@"drawingPlanId", @"DRAWING_PLAN_ID", @"drawing_plan_id", @"plan_id", @"unitId", @"unit_id"]];
|
|
748
|
+
NSString *unitName = [self stringFromDictionary:options keys:@[@"unitName", @"UNIT_NAME", @"unit_name"]];
|
|
749
|
+
|
|
750
|
+
@try {
|
|
751
|
+
if (projectId.length > 0) [vc setValue:@(projectId.integerValue) forKey:@"projectId"];
|
|
752
|
+
if (projectName.length > 0) [vc setValue:projectName forKey:@"projectName"];
|
|
753
|
+
if (planId.length > 0) [vc setValue:planId forKey:@"planId"];
|
|
754
|
+
if (unitName.length > 0) [vc setValue:unitName forKey:@"unitName"];
|
|
755
|
+
} @catch (__unused NSException *exception) {}
|
|
756
|
+
|
|
757
|
+
Class delegateClass = NSClassFromString(@"QmsSlideModalTransitionDelegate");
|
|
758
|
+
if (delegateClass && [delegateClass respondsToSelector:NSSelectorFromString(@"shared")]) {
|
|
759
|
+
@try {
|
|
760
|
+
id delegate = [delegateClass performSelector:NSSelectorFromString(@"shared")];
|
|
761
|
+
vc.modalPresentationStyle = UIModalPresentationCustom;
|
|
762
|
+
vc.transitioningDelegate = delegate;
|
|
763
|
+
} @catch (__unused NSException *exception) {
|
|
764
|
+
vc.modalPresentationStyle = UIModalPresentationFullScreen;
|
|
765
|
+
}
|
|
766
|
+
} else {
|
|
767
|
+
vc.modalPresentationStyle = UIModalPresentationFullScreen;
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
[presenter presentViewController:vc animated:YES completion:^{
|
|
771
|
+
resolve(@YES);
|
|
772
|
+
}];
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
- (void)presentAppointmentDetailsWithOptions:(NSDictionary *)options
|
|
776
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
777
|
+
rejecter:(RCTPromiseRejectBlock)reject {
|
|
778
|
+
UIViewController *presenter = [self topViewController];
|
|
779
|
+
if (!presenter) {
|
|
780
|
+
reject(@"QMS_APPT_DETAILS_NO_PRESENTER", @"Unable to find a view controller to present Appointment Details.", nil);
|
|
781
|
+
return;
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
Class vcClass = NSClassFromString(@"AppointmentDetailsViewController");
|
|
785
|
+
if (!vcClass) {
|
|
786
|
+
reject(@"QMS_APPT_DETAILS_UNAVAILABLE", @"QMS Appointment Details screen is not available.", nil);
|
|
787
|
+
return;
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
UIViewController *vc = [[vcClass alloc] init];
|
|
791
|
+
|
|
792
|
+
NSString *appointmentIdStr = [self stringFromDictionary:options
|
|
793
|
+
keys:@[@"appointmentId", @"appointment_id", @"APPOINTMENT_ID"]];
|
|
794
|
+
NSString *planId = [self stringFromDictionary:options keys:@[@"drawingPlanId", @"DRAWING_PLAN_ID", @"drawing_plan_id", @"plan_id", @"unitId", @"unit_id"]];
|
|
795
|
+
NSString *projectName = [self stringFromDictionary:options keys:@[@"projectName", @"PROJECT_NAME", @"project_name"]];
|
|
796
|
+
NSString *unitName = [self stringFromDictionary:options keys:@[@"unitName", @"UNIT_NAME", @"unit_name"]];
|
|
797
|
+
|
|
798
|
+
@try {
|
|
799
|
+
if (appointmentIdStr.length > 0) {
|
|
800
|
+
[vc setValue:@(appointmentIdStr.integerValue) forKey:@"appointmentId"];
|
|
801
|
+
}
|
|
802
|
+
if (planId.length > 0) [self callAPIConfigSelector:@"setDrawingPlanId:" stringValue:planId];
|
|
803
|
+
if (projectName.length > 0) [vc setValue:projectName forKey:@"projectName"];
|
|
804
|
+
if (unitName.length > 0) [vc setValue:unitName forKey:@"projectCode"];
|
|
805
|
+
} @catch (__unused NSException *exception) {}
|
|
806
|
+
|
|
807
|
+
Class delegateClass = NSClassFromString(@"QmsSlideModalTransitionDelegate");
|
|
808
|
+
if (delegateClass && [delegateClass respondsToSelector:NSSelectorFromString(@"shared")]) {
|
|
809
|
+
@try {
|
|
810
|
+
id delegate = [delegateClass performSelector:NSSelectorFromString(@"shared")];
|
|
811
|
+
vc.modalPresentationStyle = UIModalPresentationCustom;
|
|
812
|
+
vc.transitioningDelegate = delegate;
|
|
813
|
+
} @catch (__unused NSException *exception) {
|
|
814
|
+
vc.modalPresentationStyle = UIModalPresentationFullScreen;
|
|
815
|
+
}
|
|
816
|
+
} else {
|
|
817
|
+
vc.modalPresentationStyle = UIModalPresentationFullScreen;
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
[presenter presentViewController:vc animated:YES completion:^{
|
|
821
|
+
resolve(@YES);
|
|
822
|
+
}];
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
- (void)presentIssueDetailsWithOptions:(NSDictionary *)options
|
|
826
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
827
|
+
rejecter:(RCTPromiseRejectBlock)reject {
|
|
828
|
+
UIViewController *presenter = [self topViewController];
|
|
829
|
+
if (!presenter) {
|
|
830
|
+
reject(@"QMS_ISSUE_DETAILS_NO_PRESENTER", @"Unable to find a view controller to present Issue Details.", nil);
|
|
831
|
+
return;
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
Class vcClass = NSClassFromString(@"IssueDetailViewController");
|
|
835
|
+
if (!vcClass) {
|
|
836
|
+
reject(@"QMS_ISSUE_DETAILS_UNAVAILABLE", @"QMS Issue Details screen is not available.", nil);
|
|
837
|
+
return;
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
UIViewController *vc = [[vcClass alloc] init];
|
|
841
|
+
|
|
842
|
+
NSString *issueIdStr = [self stringFromDictionary:options keys:@[@"issueId", @"issue_id", @"ISSUE_ID"]];
|
|
843
|
+
NSString *planId = [self stringFromDictionary:options keys:@[@"drawingPlanId", @"DRAWING_PLAN_ID", @"drawing_plan_id", @"plan_id", @"unitId", @"unit_id"]];
|
|
844
|
+
NSString *projectName = [self stringFromDictionary:options keys:@[@"projectName", @"PROJECT_NAME", @"project_name"]];
|
|
845
|
+
NSString *unitName = [self stringFromDictionary:options keys:@[@"unitName", @"UNIT_NAME", @"unit_name"]];
|
|
846
|
+
|
|
847
|
+
@try {
|
|
848
|
+
if (issueIdStr.length > 0) {
|
|
849
|
+
[vc setValue:@(issueIdStr.integerValue) forKey:@"issueId"];
|
|
850
|
+
}
|
|
851
|
+
if (planId.length > 0) [vc setValue:planId forKey:@"planId"];
|
|
852
|
+
if (projectName.length > 0) [vc setValue:projectName forKey:@"projectName"];
|
|
853
|
+
if (unitName.length > 0) [vc setValue:unitName forKey:@"projectCode"];
|
|
854
|
+
// Provide a minimal issueDetails dict so viewWillAppear doesn't crash
|
|
855
|
+
// before requestIssue fills in the real data.
|
|
856
|
+
[vc setValue:@{} forKey:@"issueDetails"];
|
|
857
|
+
} @catch (__unused NSException *exception) {}
|
|
858
|
+
|
|
859
|
+
Class delegateClass = NSClassFromString(@"QmsSlideModalTransitionDelegate");
|
|
860
|
+
if (delegateClass && [delegateClass respondsToSelector:NSSelectorFromString(@"shared")]) {
|
|
861
|
+
@try {
|
|
862
|
+
id delegate = [delegateClass performSelector:NSSelectorFromString(@"shared")];
|
|
863
|
+
vc.modalPresentationStyle = UIModalPresentationCustom;
|
|
864
|
+
vc.transitioningDelegate = delegate;
|
|
865
|
+
} @catch (__unused NSException *exception) {
|
|
866
|
+
vc.modalPresentationStyle = UIModalPresentationFullScreen;
|
|
867
|
+
}
|
|
868
|
+
} else {
|
|
869
|
+
vc.modalPresentationStyle = UIModalPresentationFullScreen;
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
[presenter presentViewController:vc animated:YES completion:^{
|
|
873
|
+
resolve(@YES);
|
|
874
|
+
}];
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
- (void)presentThirdPartyLinkWithOptions:(NSDictionary *)options
|
|
878
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
879
|
+
rejecter:(RCTPromiseRejectBlock)reject {
|
|
880
|
+
NSString *lotId = [self stringFromDictionary:options keys:@[@"lotId", @"LOT_ID", @"lot_id", @"unit_lot_id"]];
|
|
881
|
+
if (lotId.length == 0) {
|
|
882
|
+
reject(@"QMS_THIRD_PARTY_MISSING_LOT_ID", @"lotId/LOT_ID/lot_id is required to open 3rd Party Link directly.", nil);
|
|
883
|
+
return;
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
UIViewController *presenter = [self topViewController];
|
|
887
|
+
if (!presenter) {
|
|
888
|
+
reject(@"QMS_THIRD_PARTY_NO_PRESENTER", @"Unable to find a view controller to present 3rd Party Link.", nil);
|
|
889
|
+
return;
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
Class vcClass = NSClassFromString(@"ThirdPartyViewController");
|
|
893
|
+
if (!vcClass) {
|
|
894
|
+
reject(@"QMS_THIRD_PARTY_UNAVAILABLE", @"QMS 3rd Party Link screen is not available.", nil);
|
|
895
|
+
return;
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
// Set lot_id into APIConfig so ThirdPartyViewController picks it up
|
|
899
|
+
[self callAPIConfigSelector:@"setLotId:" stringValue:lotId];
|
|
900
|
+
|
|
901
|
+
UIViewController *vc = [[vcClass alloc] init];
|
|
902
|
+
NSString *planId = [self stringFromDictionary:options keys:@[@"drawingPlanId", @"DRAWING_PLAN_ID", @"drawing_plan_id", @"plan_id", @"unitId", @"unit_id"]];
|
|
903
|
+
NSString *userId = [self stringFromDictionary:options keys:@[@"userId", @"USER_ID", @"user_id"]];
|
|
904
|
+
NSString *unitName = [self stringFromDictionary:options keys:@[@"unitName", @"UNIT_NAME", @"unit_name"]];
|
|
905
|
+
NSString *projectName = [self stringFromDictionary:options keys:@[@"projectName", @"PROJECT_NAME", @"project_name"]];
|
|
906
|
+
NSString *projectId = [self stringFromDictionary:options keys:@[@"projectId", @"PROJECT_ID", @"project_id"]];
|
|
907
|
+
|
|
908
|
+
@try {
|
|
909
|
+
[vc setValue:lotId forKey:@"lotId"];
|
|
910
|
+
if (planId.length > 0) [vc setValue:planId forKey:@"planId"];
|
|
911
|
+
if (userId.length > 0) [vc setValue:@(userId.integerValue) forKey:@"userId"];
|
|
912
|
+
if (unitName.length > 0) [vc setValue:unitName forKey:@"unitName"];
|
|
913
|
+
if (projectName.length > 0) [vc setValue:projectName forKey:@"projectName"];
|
|
914
|
+
if (projectId.length > 0) [vc setValue:@(projectId.integerValue) forKey:@"projectId"];
|
|
915
|
+
} @catch (__unused NSException *exception) {}
|
|
916
|
+
|
|
917
|
+
Class delegateClass = NSClassFromString(@"QmsSlideModalTransitionDelegate");
|
|
918
|
+
if (delegateClass && [delegateClass respondsToSelector:NSSelectorFromString(@"shared")]) {
|
|
919
|
+
@try {
|
|
920
|
+
id delegate = [delegateClass performSelector:NSSelectorFromString(@"shared")];
|
|
921
|
+
vc.modalPresentationStyle = UIModalPresentationCustom;
|
|
922
|
+
vc.transitioningDelegate = delegate;
|
|
923
|
+
} @catch (__unused NSException *exception) {
|
|
924
|
+
vc.modalPresentationStyle = UIModalPresentationFullScreen;
|
|
925
|
+
}
|
|
926
|
+
} else {
|
|
927
|
+
vc.modalPresentationStyle = UIModalPresentationFullScreen;
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
[presenter presentViewController:vc animated:YES completion:^{
|
|
931
|
+
resolve(@YES);
|
|
932
|
+
}];
|
|
933
|
+
}
|
|
934
|
+
|
|
76
935
|
- (void)routePayload:(NSDictionary *)payload {
|
|
77
936
|
NSLog(@"📨 [QmsModule] routePayload called — payload class=%@", NSStringFromClass([payload class]));
|
|
78
937
|
if (![payload isKindOfClass:[NSDictionary class]] || payload.count == 0) {
|
|
@@ -128,6 +987,270 @@ RCT_EXPORT_METHOD(showQmsWithPayload:(NSString *)userToken
|
|
|
128
987
|
}];
|
|
129
988
|
}
|
|
130
989
|
|
|
990
|
+
RCT_EXPORT_METHOD(openAddIssue:(NSString *)userToken
|
|
991
|
+
ClientID:(NSString *)clientID
|
|
992
|
+
ClientCode:(NSString *)clientCode
|
|
993
|
+
isOrigin:(BOOL)isOrigin
|
|
994
|
+
options:(NSDictionary *)options
|
|
995
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
996
|
+
rejecter:(RCTPromiseRejectBlock)reject) {
|
|
997
|
+
NSDictionary *safeOptions = [options isKindOfClass:[NSDictionary class]] ? options : @{};
|
|
998
|
+
[self configureAPIForAddIssueWithToken:userToken ?: @""
|
|
999
|
+
clientID:clientID ?: @""
|
|
1000
|
+
clientCode:clientCode ?: @""
|
|
1001
|
+
isOrigin:isOrigin
|
|
1002
|
+
options:safeOptions];
|
|
1003
|
+
|
|
1004
|
+
[self fetchCompanyUrlForAddIssueWithToken:userToken ?: @""
|
|
1005
|
+
clientCode:clientCode ?: @""
|
|
1006
|
+
isOrigin:isOrigin
|
|
1007
|
+
completion:^{
|
|
1008
|
+
[self presentAddIssueWithOptions:safeOptions resolver:resolve rejecter:reject];
|
|
1009
|
+
}];
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
RCT_EXPORT_METHOD(openPropertyInfo:(NSString *)userToken
|
|
1013
|
+
ClientID:(NSString *)clientID
|
|
1014
|
+
ClientCode:(NSString *)clientCode
|
|
1015
|
+
isOrigin:(BOOL)isOrigin
|
|
1016
|
+
options:(NSDictionary *)options
|
|
1017
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
1018
|
+
rejecter:(RCTPromiseRejectBlock)reject) {
|
|
1019
|
+
NSDictionary *safeOptions = [options isKindOfClass:[NSDictionary class]] ? options : @{};
|
|
1020
|
+
[self configureAPIForAddIssueWithToken:userToken ?: @""
|
|
1021
|
+
clientID:clientID ?: @""
|
|
1022
|
+
clientCode:clientCode ?: @""
|
|
1023
|
+
isOrigin:isOrigin
|
|
1024
|
+
options:safeOptions];
|
|
1025
|
+
|
|
1026
|
+
[self fetchCompanyUrlForAddIssueWithToken:userToken ?: @""
|
|
1027
|
+
clientCode:clientCode ?: @""
|
|
1028
|
+
isOrigin:isOrigin
|
|
1029
|
+
completion:^{
|
|
1030
|
+
[self presentPropertyInfoWithOptions:safeOptions resolver:resolve rejecter:reject];
|
|
1031
|
+
}];
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
RCT_EXPORT_METHOD(openThirdPartyLink:(NSString *)userToken
|
|
1035
|
+
ClientID:(NSString *)clientID
|
|
1036
|
+
ClientCode:(NSString *)clientCode
|
|
1037
|
+
isOrigin:(BOOL)isOrigin
|
|
1038
|
+
options:(NSDictionary *)options
|
|
1039
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
1040
|
+
rejecter:(RCTPromiseRejectBlock)reject) {
|
|
1041
|
+
NSDictionary *safeOptions = [options isKindOfClass:[NSDictionary class]] ? options : @{};
|
|
1042
|
+
[self configureAPIForAddIssueWithToken:userToken ?: @""
|
|
1043
|
+
clientID:clientID ?: @""
|
|
1044
|
+
clientCode:clientCode ?: @""
|
|
1045
|
+
isOrigin:isOrigin
|
|
1046
|
+
options:safeOptions];
|
|
1047
|
+
|
|
1048
|
+
[self fetchCompanyUrlForAddIssueWithToken:userToken ?: @""
|
|
1049
|
+
clientCode:clientCode ?: @""
|
|
1050
|
+
isOrigin:isOrigin
|
|
1051
|
+
completion:^{
|
|
1052
|
+
[self presentThirdPartyLinkWithOptions:safeOptions resolver:resolve rejecter:reject];
|
|
1053
|
+
}];
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
RCT_EXPORT_METHOD(openAccessItem:(NSString *)userToken
|
|
1057
|
+
ClientID:(NSString *)clientID
|
|
1058
|
+
ClientCode:(NSString *)clientCode
|
|
1059
|
+
isOrigin:(BOOL)isOrigin
|
|
1060
|
+
options:(NSDictionary *)options
|
|
1061
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
1062
|
+
rejecter:(RCTPromiseRejectBlock)reject) {
|
|
1063
|
+
NSDictionary *safeOptions = [options isKindOfClass:[NSDictionary class]] ? options : @{};
|
|
1064
|
+
[self configureAPIForAddIssueWithToken:userToken ?: @""
|
|
1065
|
+
clientID:clientID ?: @""
|
|
1066
|
+
clientCode:clientCode ?: @""
|
|
1067
|
+
isOrigin:isOrigin
|
|
1068
|
+
options:safeOptions];
|
|
1069
|
+
|
|
1070
|
+
[self fetchCompanyUrlForAddIssueWithToken:userToken ?: @""
|
|
1071
|
+
clientCode:clientCode ?: @""
|
|
1072
|
+
isOrigin:isOrigin
|
|
1073
|
+
completion:^{
|
|
1074
|
+
[self presentAccessItemWithOptions:safeOptions resolver:resolve rejecter:reject];
|
|
1075
|
+
}];
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
RCT_EXPORT_METHOD(openAppointmentList:(NSString *)userToken
|
|
1079
|
+
ClientID:(NSString *)clientID
|
|
1080
|
+
ClientCode:(NSString *)clientCode
|
|
1081
|
+
isOrigin:(BOOL)isOrigin
|
|
1082
|
+
options:(NSDictionary *)options
|
|
1083
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
1084
|
+
rejecter:(RCTPromiseRejectBlock)reject) {
|
|
1085
|
+
NSDictionary *safeOptions = [options isKindOfClass:[NSDictionary class]] ? options : @{};
|
|
1086
|
+
[self configureAPIForAddIssueWithToken:userToken ?: @""
|
|
1087
|
+
clientID:clientID ?: @""
|
|
1088
|
+
clientCode:clientCode ?: @""
|
|
1089
|
+
isOrigin:isOrigin
|
|
1090
|
+
options:safeOptions];
|
|
1091
|
+
|
|
1092
|
+
[self fetchCompanyUrlForAddIssueWithToken:userToken ?: @""
|
|
1093
|
+
clientCode:clientCode ?: @""
|
|
1094
|
+
isOrigin:isOrigin
|
|
1095
|
+
completion:^{
|
|
1096
|
+
[self presentAppointmentListWithOptions:safeOptions resolver:resolve rejecter:reject];
|
|
1097
|
+
}];
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
RCT_EXPORT_METHOD(openMakeAppointment:(NSString *)userToken
|
|
1101
|
+
ClientID:(NSString *)clientID
|
|
1102
|
+
ClientCode:(NSString *)clientCode
|
|
1103
|
+
isOrigin:(BOOL)isOrigin
|
|
1104
|
+
options:(NSDictionary *)options
|
|
1105
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
1106
|
+
rejecter:(RCTPromiseRejectBlock)reject) {
|
|
1107
|
+
NSDictionary *safeOptions = [options isKindOfClass:[NSDictionary class]] ? options : @{};
|
|
1108
|
+
[self configureAPIForAddIssueWithToken:userToken ?: @""
|
|
1109
|
+
clientID:clientID ?: @""
|
|
1110
|
+
clientCode:clientCode ?: @""
|
|
1111
|
+
isOrigin:isOrigin
|
|
1112
|
+
options:safeOptions];
|
|
1113
|
+
|
|
1114
|
+
[self fetchCompanyUrlForAddIssueWithToken:userToken ?: @""
|
|
1115
|
+
clientCode:clientCode ?: @""
|
|
1116
|
+
isOrigin:isOrigin
|
|
1117
|
+
completion:^{
|
|
1118
|
+
[self presentMakeAppointmentWithOptions:safeOptions resolver:resolve rejecter:reject];
|
|
1119
|
+
}];
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
RCT_EXPORT_METHOD(openPoaSignOff:(NSString *)userToken
|
|
1123
|
+
ClientID:(NSString *)clientID
|
|
1124
|
+
ClientCode:(NSString *)clientCode
|
|
1125
|
+
isOrigin:(BOOL)isOrigin
|
|
1126
|
+
options:(NSDictionary *)options
|
|
1127
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
1128
|
+
rejecter:(RCTPromiseRejectBlock)reject) {
|
|
1129
|
+
NSDictionary *safeOptions = [options isKindOfClass:[NSDictionary class]] ? options : @{};
|
|
1130
|
+
[self configureAPIForAddIssueWithToken:userToken ?: @""
|
|
1131
|
+
clientID:clientID ?: @""
|
|
1132
|
+
clientCode:clientCode ?: @""
|
|
1133
|
+
isOrigin:isOrigin
|
|
1134
|
+
options:safeOptions];
|
|
1135
|
+
|
|
1136
|
+
[self fetchCompanyUrlForAddIssueWithToken:userToken ?: @""
|
|
1137
|
+
clientCode:clientCode ?: @""
|
|
1138
|
+
isOrigin:isOrigin
|
|
1139
|
+
completion:^{
|
|
1140
|
+
[self presentPoaSignOffWithOptions:safeOptions resolver:resolve rejecter:reject];
|
|
1141
|
+
}];
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
RCT_EXPORT_METHOD(openIssueList:(NSString *)userToken
|
|
1145
|
+
ClientID:(NSString *)clientID
|
|
1146
|
+
ClientCode:(NSString *)clientCode
|
|
1147
|
+
isOrigin:(BOOL)isOrigin
|
|
1148
|
+
options:(NSDictionary *)options
|
|
1149
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
1150
|
+
rejecter:(RCTPromiseRejectBlock)reject) {
|
|
1151
|
+
NSDictionary *safeOptions = [options isKindOfClass:[NSDictionary class]] ? options : @{};
|
|
1152
|
+
[self configureAPIForAddIssueWithToken:userToken ?: @""
|
|
1153
|
+
clientID:clientID ?: @""
|
|
1154
|
+
clientCode:clientCode ?: @""
|
|
1155
|
+
isOrigin:isOrigin
|
|
1156
|
+
options:safeOptions];
|
|
1157
|
+
|
|
1158
|
+
[self fetchCompanyUrlForAddIssueWithToken:userToken ?: @""
|
|
1159
|
+
clientCode:clientCode ?: @""
|
|
1160
|
+
isOrigin:isOrigin
|
|
1161
|
+
completion:^{
|
|
1162
|
+
[self presentIssueListWithOptions:safeOptions resolver:resolve rejecter:reject];
|
|
1163
|
+
}];
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
RCT_EXPORT_METHOD(openProjectUpdate:(NSString *)userToken
|
|
1167
|
+
ClientID:(NSString *)clientID
|
|
1168
|
+
ClientCode:(NSString *)clientCode
|
|
1169
|
+
isOrigin:(BOOL)isOrigin
|
|
1170
|
+
options:(NSDictionary *)options
|
|
1171
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
1172
|
+
rejecter:(RCTPromiseRejectBlock)reject) {
|
|
1173
|
+
NSDictionary *safeOptions = [options isKindOfClass:[NSDictionary class]] ? options : @{};
|
|
1174
|
+
[self configureAPIForAddIssueWithToken:userToken ?: @""
|
|
1175
|
+
clientID:clientID ?: @""
|
|
1176
|
+
clientCode:clientCode ?: @""
|
|
1177
|
+
isOrigin:isOrigin
|
|
1178
|
+
options:safeOptions];
|
|
1179
|
+
|
|
1180
|
+
[self fetchCompanyUrlForAddIssueWithToken:userToken ?: @""
|
|
1181
|
+
clientCode:clientCode ?: @""
|
|
1182
|
+
isOrigin:isOrigin
|
|
1183
|
+
completion:^{
|
|
1184
|
+
[self presentProjectUpdateWithOptions:safeOptions resolver:resolve rejecter:reject];
|
|
1185
|
+
}];
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
RCT_EXPORT_METHOD(openAnnouncement:(NSString *)userToken
|
|
1189
|
+
ClientID:(NSString *)clientID
|
|
1190
|
+
ClientCode:(NSString *)clientCode
|
|
1191
|
+
isOrigin:(BOOL)isOrigin
|
|
1192
|
+
options:(NSDictionary *)options
|
|
1193
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
1194
|
+
rejecter:(RCTPromiseRejectBlock)reject) {
|
|
1195
|
+
NSDictionary *safeOptions = [options isKindOfClass:[NSDictionary class]] ? options : @{};
|
|
1196
|
+
[self configureAPIForAddIssueWithToken:userToken ?: @""
|
|
1197
|
+
clientID:clientID ?: @""
|
|
1198
|
+
clientCode:clientCode ?: @""
|
|
1199
|
+
isOrigin:isOrigin
|
|
1200
|
+
options:safeOptions];
|
|
1201
|
+
|
|
1202
|
+
[self fetchCompanyUrlForAddIssueWithToken:userToken ?: @""
|
|
1203
|
+
clientCode:clientCode ?: @""
|
|
1204
|
+
isOrigin:isOrigin
|
|
1205
|
+
completion:^{
|
|
1206
|
+
[self presentAnnouncementWithOptions:safeOptions resolver:resolve rejecter:reject];
|
|
1207
|
+
}];
|
|
1208
|
+
}
|
|
1209
|
+
|
|
1210
|
+
RCT_EXPORT_METHOD(openAnnouncementDetails:(NSString *)userToken
|
|
1211
|
+
ClientID:(NSString *)clientID
|
|
1212
|
+
ClientCode:(NSString *)clientCode
|
|
1213
|
+
isOrigin:(BOOL)isOrigin
|
|
1214
|
+
options:(NSDictionary *)options
|
|
1215
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
1216
|
+
rejecter:(RCTPromiseRejectBlock)reject) {
|
|
1217
|
+
NSDictionary *safeOptions = [options isKindOfClass:[NSDictionary class]] ? options : @{};
|
|
1218
|
+
[self configureAPIForAddIssueWithToken:userToken ?: @""
|
|
1219
|
+
clientID:clientID ?: @""
|
|
1220
|
+
clientCode:clientCode ?: @""
|
|
1221
|
+
isOrigin:isOrigin
|
|
1222
|
+
options:safeOptions];
|
|
1223
|
+
|
|
1224
|
+
[self fetchCompanyUrlForAddIssueWithToken:userToken ?: @""
|
|
1225
|
+
clientCode:clientCode ?: @""
|
|
1226
|
+
isOrigin:isOrigin
|
|
1227
|
+
completion:^{
|
|
1228
|
+
[self presentAnnouncementDetailsWithOptions:safeOptions resolver:resolve rejecter:reject];
|
|
1229
|
+
}];
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1232
|
+
RCT_EXPORT_METHOD(openInbox:(NSString *)userToken
|
|
1233
|
+
ClientID:(NSString *)clientID
|
|
1234
|
+
ClientCode:(NSString *)clientCode
|
|
1235
|
+
isOrigin:(BOOL)isOrigin
|
|
1236
|
+
options:(NSDictionary *)options
|
|
1237
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
1238
|
+
rejecter:(RCTPromiseRejectBlock)reject) {
|
|
1239
|
+
NSDictionary *safeOptions = [options isKindOfClass:[NSDictionary class]] ? options : @{};
|
|
1240
|
+
[self configureAPIForAddIssueWithToken:userToken ?: @""
|
|
1241
|
+
clientID:clientID ?: @""
|
|
1242
|
+
clientCode:clientCode ?: @""
|
|
1243
|
+
isOrigin:isOrigin
|
|
1244
|
+
options:safeOptions];
|
|
1245
|
+
|
|
1246
|
+
[self fetchCompanyUrlForAddIssueWithToken:userToken ?: @""
|
|
1247
|
+
clientCode:clientCode ?: @""
|
|
1248
|
+
isOrigin:isOrigin
|
|
1249
|
+
completion:^{
|
|
1250
|
+
[self presentInboxWithOptions:safeOptions resolver:resolve rejecter:reject];
|
|
1251
|
+
}];
|
|
1252
|
+
}
|
|
1253
|
+
|
|
131
1254
|
RCT_EXPORT_METHOD(setPrimaryColor:(NSString *)hexColor) {
|
|
132
1255
|
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
|
133
1256
|
if (hexColor.length > 0) [defaults setObject:hexColor forKey:kQmsThemePrimaryColorKey];
|
|
@@ -259,4 +1382,174 @@ RCT_EXPORT_METHOD(emitInAppNotificationWithPayload:(NSString *)title
|
|
|
259
1382
|
if (self.bannerView == gesture.view) self.bannerView = nil;
|
|
260
1383
|
}
|
|
261
1384
|
|
|
1385
|
+
// ---------------------------------------------------------------------------
|
|
1386
|
+
// Draft Issues
|
|
1387
|
+
// ---------------------------------------------------------------------------
|
|
1388
|
+
|
|
1389
|
+
RCT_EXPORT_METHOD(openAppointmentDetails:(NSString *)userToken
|
|
1390
|
+
ClientID:(NSString *)clientID
|
|
1391
|
+
ClientCode:(NSString *)clientCode
|
|
1392
|
+
isOrigin:(BOOL)isOrigin
|
|
1393
|
+
options:(NSDictionary *)options
|
|
1394
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
1395
|
+
rejecter:(RCTPromiseRejectBlock)reject) {
|
|
1396
|
+
NSDictionary *safeOptions = [options isKindOfClass:[NSDictionary class]] ? options : @{};
|
|
1397
|
+
[self configureAPIForAddIssueWithToken:userToken ?: @""
|
|
1398
|
+
clientID:clientID ?: @""
|
|
1399
|
+
clientCode:clientCode ?: @""
|
|
1400
|
+
isOrigin:isOrigin
|
|
1401
|
+
options:safeOptions];
|
|
1402
|
+
|
|
1403
|
+
[self fetchCompanyUrlForAddIssueWithToken:userToken ?: @""
|
|
1404
|
+
clientCode:clientCode ?: @""
|
|
1405
|
+
isOrigin:isOrigin
|
|
1406
|
+
completion:^{
|
|
1407
|
+
[self presentAppointmentDetailsWithOptions:safeOptions resolver:resolve rejecter:reject];
|
|
1408
|
+
}];
|
|
1409
|
+
}
|
|
1410
|
+
|
|
1411
|
+
RCT_EXPORT_METHOD(openIssueDetails:(NSString *)userToken
|
|
1412
|
+
ClientID:(NSString *)clientID
|
|
1413
|
+
ClientCode:(NSString *)clientCode
|
|
1414
|
+
isOrigin:(BOOL)isOrigin
|
|
1415
|
+
options:(NSDictionary *)options
|
|
1416
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
1417
|
+
rejecter:(RCTPromiseRejectBlock)reject) {
|
|
1418
|
+
NSDictionary *safeOptions = [options isKindOfClass:[NSDictionary class]] ? options : @{};
|
|
1419
|
+
[self configureAPIForAddIssueWithToken:userToken ?: @""
|
|
1420
|
+
clientID:clientID ?: @""
|
|
1421
|
+
clientCode:clientCode ?: @""
|
|
1422
|
+
isOrigin:isOrigin
|
|
1423
|
+
options:safeOptions];
|
|
1424
|
+
|
|
1425
|
+
[self fetchCompanyUrlForAddIssueWithToken:userToken ?: @""
|
|
1426
|
+
clientCode:clientCode ?: @""
|
|
1427
|
+
isOrigin:isOrigin
|
|
1428
|
+
completion:^{
|
|
1429
|
+
[self presentIssueDetailsWithOptions:safeOptions resolver:resolve rejecter:reject];
|
|
1430
|
+
}];
|
|
1431
|
+
}
|
|
1432
|
+
|
|
1433
|
+
/// Returns the number of draft (offline) issues for the given projectCode.
|
|
1434
|
+
/// Reads OFFLINE_SYNC_QUEUE from LocalStorage and counts ADD_ISSUE entries
|
|
1435
|
+
/// whose unitName matches the provided projectCode (unit name in QMS terms).
|
|
1436
|
+
RCT_EXPORT_METHOD(getDraftCount:(NSString *)projectCode
|
|
1437
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
1438
|
+
rejecter:(RCTPromiseRejectBlock)reject) {
|
|
1439
|
+
Class localStorageClass = NSClassFromString(@"LocalStorage");
|
|
1440
|
+
if (!localStorageClass) {
|
|
1441
|
+
resolve(@(0));
|
|
1442
|
+
return;
|
|
1443
|
+
}
|
|
1444
|
+
|
|
1445
|
+
SEL loadSel = NSSelectorFromString(@"loadArrayForKey:");
|
|
1446
|
+
if (![localStorageClass respondsToSelector:loadSel]) {
|
|
1447
|
+
resolve(@(0));
|
|
1448
|
+
return;
|
|
1449
|
+
}
|
|
1450
|
+
|
|
1451
|
+
NSArray *queue = [localStorageClass performSelector:loadSel withObject:@"OFFLINE_SYNC_QUEUE"];
|
|
1452
|
+
if (![queue isKindOfClass:[NSArray class]] || queue.count == 0) {
|
|
1453
|
+
resolve(@(0));
|
|
1454
|
+
return;
|
|
1455
|
+
}
|
|
1456
|
+
|
|
1457
|
+
NSString *safeCode = (projectCode.length > 0) ? projectCode : @"";
|
|
1458
|
+
NSInteger count = 0;
|
|
1459
|
+
for (id obj in queue) {
|
|
1460
|
+
if (![obj isKindOfClass:[NSDictionary class]]) continue;
|
|
1461
|
+
NSString *type = [obj[@"type"] description] ?: @"";
|
|
1462
|
+
if (![type isEqualToString:@"ADD_ISSUE"]) continue;
|
|
1463
|
+
NSString *unitName = [obj[@"unitName"] description] ?: @"";
|
|
1464
|
+
if (safeCode.length == 0 || [unitName isEqualToString:safeCode]) {
|
|
1465
|
+
count++;
|
|
1466
|
+
}
|
|
1467
|
+
}
|
|
1468
|
+
resolve(@(count));
|
|
1469
|
+
}
|
|
1470
|
+
|
|
1471
|
+
/// Opens the DraftIssuesViewController for the current unit's draft issues.
|
|
1472
|
+
RCT_EXPORT_METHOD(openDraftIssues:(NSString *)userToken
|
|
1473
|
+
ClientID:(NSString *)clientID
|
|
1474
|
+
ClientCode:(NSString *)clientCode
|
|
1475
|
+
isOrigin:(BOOL)isOrigin
|
|
1476
|
+
options:(NSDictionary *)options
|
|
1477
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
1478
|
+
rejecter:(RCTPromiseRejectBlock)reject) {
|
|
1479
|
+
NSDictionary *safeOptions = [options isKindOfClass:[NSDictionary class]] ? options : @{};
|
|
1480
|
+
[self configureAPIForAddIssueWithToken:userToken ?: @""
|
|
1481
|
+
clientID:clientID ?: @""
|
|
1482
|
+
clientCode:clientCode ?: @""
|
|
1483
|
+
isOrigin:isOrigin
|
|
1484
|
+
options:safeOptions];
|
|
1485
|
+
|
|
1486
|
+
[self fetchCompanyUrlForAddIssueWithToken:userToken ?: @""
|
|
1487
|
+
clientCode:clientCode ?: @""
|
|
1488
|
+
isOrigin:isOrigin
|
|
1489
|
+
completion:^{
|
|
1490
|
+
UIViewController *presenter = [self topViewController];
|
|
1491
|
+
if (!presenter) {
|
|
1492
|
+
reject(@"QMS_DRAFT_NO_PRESENTER", @"Unable to find a view controller to present Draft Issues.", nil);
|
|
1493
|
+
return;
|
|
1494
|
+
}
|
|
1495
|
+
|
|
1496
|
+
Class vcClass = NSClassFromString(@"DraftIssuesViewController");
|
|
1497
|
+
if (!vcClass) {
|
|
1498
|
+
reject(@"QMS_DRAFT_UNAVAILABLE", @"DraftIssuesViewController is not available.", nil);
|
|
1499
|
+
return;
|
|
1500
|
+
}
|
|
1501
|
+
|
|
1502
|
+
UIViewController *vc = [[vcClass alloc] init];
|
|
1503
|
+
|
|
1504
|
+
NSString *projectName = [self stringFromDictionary:safeOptions
|
|
1505
|
+
keys:@[@"projectName", @"PROJECT_NAME", @"project_name"]];
|
|
1506
|
+
NSString *projectCode = [self stringFromDictionary:safeOptions
|
|
1507
|
+
keys:@[@"unitName", @"UNIT_NAME", @"unit_name"]];
|
|
1508
|
+
NSString *issueLimitStr = [self stringFromDictionary:safeOptions
|
|
1509
|
+
keys:@[@"issueLimit", @"ISSUE_LIMIT", @"issue_limit"]];
|
|
1510
|
+
NSString *issueLimitWarning = [self stringFromDictionary:safeOptions
|
|
1511
|
+
keys:@[@"issueLimitWarningText",
|
|
1512
|
+
@"ISSUE_LIMIT_WARNING_TEXT",
|
|
1513
|
+
@"issue_limit_warning_text"]];
|
|
1514
|
+
NSString *projectId = [self stringFromDictionary:options keys:@[@"projectId", @"PROJECT_ID", @"project_id"]];
|
|
1515
|
+
NSString *planId = [self stringFromDictionary:options keys:@[@"drawingPlanId", @"DRAWING_PLAN_ID", @"drawing_plan_id", @"plan_id", @"unitId", @"unit_id"]];
|
|
1516
|
+
|
|
1517
|
+
@try {
|
|
1518
|
+
if (projectName.length > 0) [vc setValue:projectName forKey:@"projectName"];
|
|
1519
|
+
if (projectCode.length > 0) [vc setValue:projectCode forKey:@"projectCode"];
|
|
1520
|
+
if (issueLimitStr.length > 0) [vc setValue:@(issueLimitStr.integerValue) forKey:@"issueLimit"];
|
|
1521
|
+
if (issueLimitWarning.length > 0) [vc setValue:issueLimitWarning forKey:@"issueLimitWarning"];
|
|
1522
|
+
|
|
1523
|
+
// multiZone flag
|
|
1524
|
+
id multiZoneRaw = safeOptions[@"multiZone"] ?: safeOptions[@"MULTI_ZONE"] ?: safeOptions[@"multi_zone"];
|
|
1525
|
+
NSLog(@"🔍 [openDraftIssues] multiZone raw value: %@ (class: %@)", multiZoneRaw, NSStringFromClass([multiZoneRaw class]));
|
|
1526
|
+
BOOL multiZoneBln = [multiZoneRaw isKindOfClass:[NSNumber class]] ? [multiZoneRaw boolValue] :
|
|
1527
|
+
[multiZoneRaw isKindOfClass:[NSString class]] ? [multiZoneRaw isEqualToString:@"1"] : NO;
|
|
1528
|
+
NSLog(@"🔍 [openDraftIssues] multiZone resolved BOOL: %@", multiZoneBln ? @"YES" : @"NO");
|
|
1529
|
+
[self callAPIConfigSelector:@"setIsMulti:" boolValue:multiZoneBln];
|
|
1530
|
+
NSLog(@"🔍 [openDraftIssues] APIConfig.isMulti after set: %@", [NSClassFromString(@"APIConfig") valueForKey:@"isMulti"] ? @"YES" : @"NO");
|
|
1531
|
+
[vc setValue:@(multiZoneBln) forKey:@"isMulti"];
|
|
1532
|
+
} @catch (__unused NSException *exception) {
|
|
1533
|
+
NSLog(@"⚠️ [openDraftIssues] exception while setting multiZone: %@", exception);
|
|
1534
|
+
}
|
|
1535
|
+
|
|
1536
|
+
Class delegateClass = NSClassFromString(@"QmsSlideModalTransitionDelegate");
|
|
1537
|
+
if (delegateClass && [delegateClass respondsToSelector:NSSelectorFromString(@"shared")]) {
|
|
1538
|
+
@try {
|
|
1539
|
+
id delegate = [delegateClass performSelector:NSSelectorFromString(@"shared")];
|
|
1540
|
+
vc.modalPresentationStyle = UIModalPresentationCustom;
|
|
1541
|
+
vc.transitioningDelegate = delegate;
|
|
1542
|
+
} @catch (__unused NSException *exception) {
|
|
1543
|
+
vc.modalPresentationStyle = UIModalPresentationFullScreen;
|
|
1544
|
+
}
|
|
1545
|
+
} else {
|
|
1546
|
+
vc.modalPresentationStyle = UIModalPresentationFullScreen;
|
|
1547
|
+
}
|
|
1548
|
+
|
|
1549
|
+
[presenter presentViewController:vc animated:YES completion:^{
|
|
1550
|
+
resolve(@YES);
|
|
1551
|
+
}];
|
|
1552
|
+
}];
|
|
1553
|
+
}
|
|
1554
|
+
|
|
262
1555
|
@end
|