@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.
Files changed (62) hide show
  1. package/QmsPlugin.podspec +2 -4
  2. package/QmsPluginFramework.podspec +12 -0
  3. package/README.md +24 -8
  4. package/android/build.gradle +2 -1
  5. package/android/consumer-rules.pro +13 -0
  6. package/ios/QmsPlugin/QmsDashboardViewManager.mm +68 -26
  7. package/ios/QmsPlugin/QmsModule.mm +1293 -0
  8. package/ios/QmsPlugin/UIViewController+QmsAnalytics.m +3 -1
  9. package/lib/module/QmsDashboardView.android.js +121 -9
  10. package/lib/module/QmsDashboardView.android.js.map +1 -1
  11. package/lib/module/QmsPlugin.js +57 -0
  12. package/lib/module/QmsPlugin.js.map +1 -1
  13. package/lib/typescript/src/QmsDashboardView.android.d.ts.map +1 -1
  14. package/lib/typescript/src/QmsPlugin.d.ts +137 -0
  15. package/lib/typescript/src/QmsPlugin.d.ts.map +1 -1
  16. package/lib/typescript/src/index.d.ts +1 -1
  17. package/lib/typescript/src/index.d.ts.map +1 -1
  18. package/package.json +7 -4
  19. package/src/QmsDashboardView.android.tsx +156 -11
  20. package/src/QmsPlugin.ts +312 -0
  21. package/src/index.tsx +13 -1
  22. package/ios/QmsPluginFramework.xcframework/Info.plist +0 -44
  23. package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/Assets.car +0 -0
  24. package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/Headers/QmsPlugin.h +0 -43
  25. package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/Headers/QmsPluginFramework.h +0 -17
  26. package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/Info.plist +0 -0
  27. package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/Modules/module.modulemap +0 -6
  28. package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/Montserrat-Bold.ttf +0 -0
  29. package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/Montserrat-BoldItalic.ttf +0 -0
  30. package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/Montserrat-ExtraBold.ttf +0 -0
  31. package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/Montserrat-ExtraLight.ttf +0 -0
  32. package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/Montserrat-Italic.ttf +0 -0
  33. package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/Montserrat-Light.ttf +0 -0
  34. package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/Montserrat-Medium.ttf +0 -0
  35. package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/Montserrat-Regular.ttf +0 -0
  36. package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/Montserrat-SemiBold.ttf +0 -0
  37. package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/Montserrat-Thin.ttf +0 -0
  38. package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/QmsPluginFramework +0 -0
  39. package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/_CodeSignature/CodeResources +0 -289
  40. package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/bm.json +0 -781
  41. package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/cn.json +0 -782
  42. package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/en.json +0 -782
  43. package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/Assets.car +0 -0
  44. package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/Headers/QmsPlugin.h +0 -43
  45. package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/Headers/QmsPluginFramework.h +0 -17
  46. package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/Info.plist +0 -0
  47. package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/Modules/module.modulemap +0 -6
  48. package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/Montserrat-Bold.ttf +0 -0
  49. package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/Montserrat-BoldItalic.ttf +0 -0
  50. package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/Montserrat-ExtraBold.ttf +0 -0
  51. package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/Montserrat-ExtraLight.ttf +0 -0
  52. package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/Montserrat-Italic.ttf +0 -0
  53. package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/Montserrat-Light.ttf +0 -0
  54. package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/Montserrat-Medium.ttf +0 -0
  55. package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/Montserrat-Regular.ttf +0 -0
  56. package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/Montserrat-SemiBold.ttf +0 -0
  57. package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/Montserrat-Thin.ttf +0 -0
  58. package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/QmsPluginFramework +0 -0
  59. package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/_CodeSignature/CodeResources +0 -289
  60. package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/bm.json +0 -781
  61. package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/cn.json +0 -782
  62. package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/en.json +0 -782
package/QmsPlugin.podspec CHANGED
@@ -14,16 +14,14 @@ Pod::Spec.new do |s|
14
14
  s.homepage = homepage
15
15
  s.license = package["license"]
16
16
  s.authors = package["author"]
17
- s.platforms = { :ios => "12.4" }
17
+ s.platforms = { :ios => "15.1" }
18
18
 
19
19
  s.source = { :git => "http://convep.ddns.me:20000/WeiHan/weihan-plugin.git", :tag => "#{s.version}" }
20
20
  s.source_files = "ios/QmsPlugin/**/*.{h,m,mm,cpp}", "ios/QmsPluginSpec/**/*.{h,mm}"
21
21
  s.private_header_files = "ios/QmsPlugin/**/*.h"
22
22
  s.public_header_files = "ios/QmsPluginSpec/**/*.h"
23
23
 
24
- s.preserve_paths = "ios/QmsPluginFramework.xcframework"
25
- s.vendored_frameworks = "ios/QmsPluginFramework.xcframework"
26
-
24
+ s.dependency "QmsPluginFramework", "1.31.0"
27
25
  s.dependency "React-Core"
28
26
  s.dependency "ReactCommon"
29
27
  s.dependency "React-Codegen"
@@ -0,0 +1,12 @@
1
+ Pod::Spec.new do |s|
2
+ s.name = "QmsPluginFramework"
3
+ s.version = "1.31.0"
4
+ s.summary = "QMS Native iOS Framework"
5
+ s.description = "Native QMS iOS SDK distributed as XCFramework."
6
+ s.homepage = "https://sdk.convep.com"
7
+ s.license = { :type => "Proprietary", :text => "Copyright © Convep Mobilogy. All rights reserved." }
8
+ s.author = { "Convep Mobilogy" => "developer@convep.com" }
9
+ s.platform = :ios, "15.1"
10
+ s.source = { :http => "https://sdk.convep.com/ios/QMS/qms-plugin/1.31.0", :type => "zip", :sha256 => "6bae9da81e3b0df77a98edf939279290990539e954407dae90904b96192705cf" }
11
+ s.vendored_frameworks = "QmsPluginFramework.xcframework"
12
+ end
package/README.md CHANGED
@@ -2,8 +2,6 @@
2
2
 
3
3
  A React Native plugin that provides QMS (Quality Management System) components and APIs for defect management, dashboard visualization, and QMS workflow operations.
4
4
 
5
- ---
6
-
7
5
  # Installation
8
6
 
9
7
  Install using npm:
@@ -22,20 +20,35 @@ yarn add @convep_mobilogy/react-native-qms-plugin
22
20
 
23
21
  # iOS Setup
24
22
 
25
- Autolinking should set up everything automatically.
23
+ Add the hosted native framework pod to the application `Podfile`. The podspec
24
+ is shipped with the npm package and CocoaPods downloads the matching ZIP from
25
+ `sdk.convep.com`:
26
26
 
27
- 1. Navigate to your iOS folder:
27
+ ```ruby
28
+ qms_plugin_package = Pod::Executable.execute_command('node', ['-p',
29
+ 'require.resolve(
30
+ "@convep_mobilogy/react-native-qms-plugin/package.json",
31
+ {paths: [process.argv[1]]},
32
+ )', __dir__]).strip
33
+
34
+ target 'YourApp' do
35
+ pod 'QmsPluginFramework',
36
+ :path => File.dirname(qms_plugin_package)
37
+ end
38
+ ```
39
+
40
+ Autolinking sets up the React Native wrapper. From the application's root
41
+ directory, install all CocoaPods dependencies:
28
42
 
29
43
  ```sh
30
44
  cd ios
31
45
  pod install
32
46
  ```
33
47
 
34
- ---
35
-
36
48
  # Android Setup
37
49
 
38
- Autolinking should set up everything automatically, but you need to add the private Maven repo and enable core library desugaring.
50
+ Autolinking should set up everything automatically, but you need to add the QMS
51
+ Maven repository and enable core library desugaring.
39
52
 
40
53
  1. In `android/build.gradle`, add the Maven repo:
41
54
 
@@ -47,7 +60,10 @@ allprojects {
47
60
  maven { url = uri("https://www.jitpack.io") }
48
61
 
49
62
  maven {
50
- url = uri("https://raw.githubusercontent.com/ConvepMobilogy/QMS_framework/main/maven-repo")
63
+ url = uri("https://sdk.convep.com/maven")
64
+ content {
65
+ includeGroup("com.convep.qms")
66
+ }
51
67
  }
52
68
  }
53
69
  }
@@ -43,6 +43,7 @@ android {
43
43
  defaultConfig {
44
44
  minSdkVersion getExtOrIntegerDefault("minSdkVersion")
45
45
  targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
46
+ consumerProguardFiles "consumer-rules.pro"
46
47
  }
47
48
 
48
49
  buildFeatures {
@@ -85,7 +86,7 @@ dependencies {
85
86
  implementation "com.facebook.react:react-android"
86
87
  implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
87
88
  implementation 'com.facebook.react:react-native:+'
88
- implementation "com.convep.qms:qms-plugin:1.26.2"
89
+ implementation "com.convep.qms:qms-plugin:1.31.0"
89
90
  implementation 'androidx.appcompat:appcompat:1.6.1'
90
91
 
91
92
  implementation 'com.squareup.okhttp3:logging-interceptor:4.12.0'
@@ -0,0 +1,13 @@
1
+ # React Native creates this package from the generated PackageList. Keep the
2
+ # package and its native module entry points stable in minified host apps.
3
+ -keep class com.qmsplugin.QmsPluginPackage { *; }
4
+ -keep class com.qmsplugin.QmsPluginModule { *; }
5
+
6
+ # The wrapper returns the native framework module to React Native. ReactMethod
7
+ # methods are invoked through bridge metadata rather than ordinary Java calls.
8
+ -keep class com.convep.qms.QmsModule { *; }
9
+ -keepclassmembers class com.convep.qms.** {
10
+ @com.facebook.react.bridge.ReactMethod <methods>;
11
+ }
12
+
13
+ -keepattributes RuntimeVisibleAnnotations,RuntimeVisibleParameterAnnotations,AnnotationDefault
@@ -310,7 +310,7 @@ static NSString * const kQmsRoutePayloadNotification = @"QmsRoutePayloadNotifica
310
310
  @"new_issue", @"new_info", @"accept_issue", @"reject_issue", @"decline_issue",
311
311
  @"start_fix", @"redo", @"completed", @"close_internal", @"close_external",
312
312
  @"pending_owner_acceptance", @"assign_issue", @"reassign_issue", @"poa_reminder",
313
- @"auto_close_reminder", @"pending_access_reminder", @"overdue_reminder",
313
+ @"auto_close_reminder", @"overdue_reminder",
314
314
  @"issue_summary_reminder", @"lodge_summary_reminder", @"overdue_summary_reminder"
315
315
  ]];
316
316
  });
@@ -322,8 +322,15 @@ static NSString * const kQmsRoutePayloadNotification = @"QmsRoutePayloadNotifica
322
322
  [type isEqualToString:@"unattend_appt_reminder"];
323
323
  }
324
324
 
325
- - (BOOL)isDraftReminderType:(NSString *)type {
326
- return [type isEqualToString:@"draft_reminder"];
325
+ - (BOOL)isDashboardType:(NSString *)type {
326
+ static NSSet<NSString *> *types;
327
+ static dispatch_once_t onceToken;
328
+ dispatch_once(&onceToken, ^{
329
+ types = [NSSet setWithArray:@[
330
+ @"pending_access_reminder", @"completion_letter", @"key_collection", @"defect_summary", @"clearance_letter"
331
+ ]];
332
+ });
333
+ return type.length > 0 && [types containsObject:type];
327
334
  }
328
335
 
329
336
  - (void)applyPayloadContext:(NSDictionary *)payload {
@@ -440,23 +447,9 @@ static NSString * const kQmsRoutePayloadNotification = @"QmsRoutePayloadNotifica
440
447
  UIViewController *presenter = self.dashboardVC;
441
448
  if (!presenter) return;
442
449
 
443
- Class cls = NSClassFromString(@"DraftListingViewController");
444
- if (!cls) {
445
- NSLog(@"🧭 [DraftReminder] DraftListingViewController class not found");
446
- return;
447
- }
448
-
449
- UIViewController *vc = [[cls alloc] init];
450
- if (!vc) return;
451
-
452
- // Pass project name if available so the listing filters to the right project
453
- NSString *projectName = payload[@"project_name"];
454
- if (projectName.length > 0) {
455
- @try { [vc setValue:projectName forKey:@"projectName"]; }
456
- @catch (__unused NSException *e) {}
457
- }
458
-
459
- [self presentDeepLinkVC:vc];
450
+ // Delegate to QmsPluginUI which handles account switching + presentation.
451
+ // AccountManager and DraftListingViewController are both inside the framework.
452
+ [QmsPluginUI presentDraftListingFromPayload:payload fromViewController:presenter];
460
453
  }
461
454
 
462
455
  - (void)routePayloadIfNeeded:(NSDictionary *)payload force:(BOOL)force {
@@ -496,13 +489,12 @@ static NSString * const kQmsRoutePayloadNotification = @"QmsRoutePayloadNotifica
496
489
  } else if ([self isAppointmentType:type]) {
497
490
  NSLog(@"🧭 [QmsDashboardView] routing → presentAppointmentFromPayload (appointment type: %@)", type);
498
491
  [self presentAppointmentDetailsViewControllerWithPayload:payload title:title ?: @""];
499
- } else if ([type isEqualToString:@"clearance_letter"]) {
500
- NSLog(@"🧭 [QmsDashboardView] routing → presentDashboardFromPayload (clearance_letter)");
492
+ } else if ([self isDashboardType:type]) {
493
+ NSLog(@"🧭 [QmsDashboardView] routing → presentDashboardFromPayload (dashboard type: %@)", type);
501
494
  [self presentDashboardViewControllerWithPayload:payload title:title ?: @""];
502
- } else if ([self isDraftReminderType:type]) {
495
+ } else if ([type isEqualToString:@"draft_reminder"]) {
503
496
  NSLog(@"🧭 [QmsDashboardView] routing → presentDraftListingViewController (draft_reminder)");
504
- // [self presentDraftListingViewControllerWithPayload:payload];
505
- [self presentDashboardViewControllerWithPayload:payload title:title ?: @""];
497
+ [self presentDraftListingViewControllerWithPayload:payload];
506
498
  } else {
507
499
  NSLog(@"🧭 [QmsDashboardView] routePayloadIfNeeded — no route matched for type=%@", type ?: @"(none)");
508
500
  }
@@ -555,6 +547,12 @@ static NSString * const kQmsRoutePayloadNotification = @"QmsRoutePayloadNotifica
555
547
  - (void)applyHeaderThemeRecursivelyOnView:(UIView *)view textColor:(UIColor *)textColor iconColor:(UIColor *)iconColor {
556
548
  if (!view) return;
557
549
 
550
+ // Skip views tagged 9001 and their entire subtree — they manage their own colour.
551
+ if (view.tag == 9001) return;
552
+
553
+ // Never reach into UISegmentedControl internals.
554
+ if ([view isKindOfClass:[UISegmentedControl class]]) return;
555
+
558
556
  if (textColor && [view isKindOfClass:[UILabel class]]) {
559
557
  UILabel *label = (UILabel *)view;
560
558
  CGPoint originInRoot = [label.superview convertPoint:label.frame.origin toView:_dashboardVC.view];
@@ -599,6 +597,13 @@ static NSString * const kQmsRoutePayloadNotification = @"QmsRoutePayloadNotifica
599
597
  - (void)applyThemeRecursivelyOnView:(UIView *)view color:(UIColor *)themeColor {
600
598
  if (!view || !themeColor) return;
601
599
 
600
+ // Skip views tagged 9001 and their entire subtree — they manage their own colour.
601
+ if (view.tag == 9001) return;
602
+
603
+ // Never reach into UISegmentedControl internals — its tint/selected colour
604
+ // is set directly via selectedSegmentTintColor and must not be overwritten here.
605
+ if ([view isKindOfClass:[UISegmentedControl class]]) return;
606
+
602
607
  CGPoint originInRoot = [view.superview convertPoint:view.frame.origin toView:_dashboardVC.view];
603
608
  BOOL nearHeader = originInRoot.y <= 140.0 && view.bounds.size.height <= 120.0;
604
609
  if (nearHeader && [self isDefaultQmsBlueColor:view.backgroundColor]) {
@@ -655,6 +660,16 @@ static NSString * const kQmsRoutePayloadNotification = @"QmsRoutePayloadNotifica
655
660
  - (void)applyAccentRecursivelyOnView:(UIView *)view color:(UIColor *)color {
656
661
  if (!view || !color) return;
657
662
 
663
+ // Skip views (and their entire subtree) that have been tagged 9001 —
664
+ // this lets individual controls opt-out of theme colour replacement.
665
+ if (view.tag == 9001) return;
666
+
667
+ if ([view isKindOfClass:[UISegmentedControl class]]) {
668
+ // Never touch the internals of a UISegmentedControl — its
669
+ // selectedSegmentTintColor is managed by the VC that owns it.
670
+ return;
671
+ }
672
+
658
673
  if ([view isKindOfClass:[UIButton class]]) {
659
674
  UIButton *button = (UIButton *)view;
660
675
  button.tintColor = color;
@@ -809,7 +824,10 @@ RCT_EXPORT_MODULE();
809
824
  @"onAnalyticsScreen",
810
825
  @"onAnalyticsEvent",
811
826
  @"QmsSdkOnAnalyticsScreen",
812
- @"QmsSdkOnAnalyticsEvent"
827
+ @"QmsSdkOnAnalyticsEvent",
828
+ @"onDraftIssueCreated",
829
+ @"onDraftIssueDeleted",
830
+ @"onPoaSignOffCompleted"
813
831
  ];
814
832
  }
815
833
 
@@ -837,6 +855,18 @@ RCT_EXPORT_MODULE();
837
855
  selector:@selector(handleActiveAccountChangeEmitter:)
838
856
  name:@"QmsActiveAccountDidChangeNotification"
839
857
  object:nil];
858
+ [center addObserver:self
859
+ selector:@selector(handleDraftIssueCreated:)
860
+ name:@"QmsDraftIssueCreatedNotification"
861
+ object:nil];
862
+ [center addObserver:self
863
+ selector:@selector(handleDraftIssueDeleted:)
864
+ name:@"QmsDraftIssueDeletedNotification"
865
+ object:nil];
866
+ [center addObserver:self
867
+ selector:@selector(handlePoaSignOffCompleted:)
868
+ name:@"QmsPoaSignOffCompleted"
869
+ object:nil];
840
870
  }
841
871
 
842
872
  - (void)stopObserving {
@@ -866,6 +896,18 @@ RCT_EXPORT_MODULE();
866
896
  [self sendEventWithName:@"onActiveAccountChange" body:note.userInfo];
867
897
  }
868
898
 
899
+ - (void)handleDraftIssueCreated:(NSNotification *)note {
900
+ [self sendEventWithName:@"onDraftIssueCreated" body:note.userInfo];
901
+ }
902
+
903
+ - (void)handleDraftIssueDeleted:(NSNotification *)note {
904
+ [self sendEventWithName:@"onDraftIssueDeleted" body:note.userInfo];
905
+ }
906
+
907
+ - (void)handlePoaSignOffCompleted:(NSNotification *)note {
908
+ [self sendEventWithName:@"onPoaSignOffCompleted" body:note.userInfo ?: @{}];
909
+ }
910
+
869
911
  - (void)dealloc {
870
912
  [self stopObserving];
871
913
  }