@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
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useEffect } from 'react';
|
|
1
|
+
import React, { useEffect, useRef, useState } from 'react';
|
|
2
2
|
import { DeviceEventEmitter, NativeModules, View } from 'react-native';
|
|
3
3
|
import type {
|
|
4
4
|
QmsActiveAccountPayload,
|
|
@@ -27,9 +27,91 @@ const { QmsModule } = NativeModules as {
|
|
|
27
27
|
setAccentColor?: (hexColor?: string) => void;
|
|
28
28
|
setFontFamily?: (fontFamily?: string) => void;
|
|
29
29
|
setPushToken?: (pushToken?: string) => void;
|
|
30
|
+
consumePendingLogout?: () => Promise<boolean>;
|
|
30
31
|
};
|
|
31
32
|
};
|
|
32
33
|
|
|
34
|
+
const isRecord = (value: unknown): value is Record<string, unknown> =>
|
|
35
|
+
value != null && typeof value === 'object' && !Array.isArray(value);
|
|
36
|
+
|
|
37
|
+
const parseRecord = (value: unknown): Record<string, unknown> | null => {
|
|
38
|
+
if (isRecord(value)) {
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
41
|
+
if (typeof value !== 'string') {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
const trimmed = value.trim();
|
|
45
|
+
if (!trimmed.startsWith('{')) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
const parsed = JSON.parse(trimmed);
|
|
50
|
+
return isRecord(parsed) ? parsed : null;
|
|
51
|
+
} catch {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const mergeRecord = (
|
|
57
|
+
target: Record<string, unknown>,
|
|
58
|
+
source: Record<string, unknown> | null
|
|
59
|
+
) => {
|
|
60
|
+
if (!source) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
Object.entries(source).forEach(([key, value]) => {
|
|
64
|
+
if (value != null && target[key] == null) {
|
|
65
|
+
target[key] = value;
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const normalizeNotificationPayload = (
|
|
71
|
+
rawPayload?: Record<string, unknown> | null
|
|
72
|
+
): Record<string, unknown> | null => {
|
|
73
|
+
if (!rawPayload || Object.keys(rawPayload).length === 0) {
|
|
74
|
+
return rawPayload ?? null;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const normalized: Record<string, unknown> = { ...rawPayload };
|
|
78
|
+
const nestedKeys = [
|
|
79
|
+
'Data',
|
|
80
|
+
'data',
|
|
81
|
+
'payload',
|
|
82
|
+
'notificationData',
|
|
83
|
+
'remoteMessage',
|
|
84
|
+
'message',
|
|
85
|
+
];
|
|
86
|
+
|
|
87
|
+
nestedKeys.forEach((key) => {
|
|
88
|
+
const nested = parseRecord(rawPayload[key]);
|
|
89
|
+
mergeRecord(normalized, nested);
|
|
90
|
+
mergeRecord(normalized, parseRecord(nested?.Data));
|
|
91
|
+
mergeRecord(normalized, parseRecord(nested?.data));
|
|
92
|
+
mergeRecord(normalized, parseRecord(nested?.payload));
|
|
93
|
+
mergeRecord(normalized, parseRecord(nested?.notificationData));
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
const notification = parseRecord(rawPayload.notification);
|
|
97
|
+
if (notification) {
|
|
98
|
+
if (normalized.title == null && notification.title != null) {
|
|
99
|
+
normalized.title = notification.title;
|
|
100
|
+
}
|
|
101
|
+
if (normalized.body == null && notification.body != null) {
|
|
102
|
+
normalized.body = notification.body;
|
|
103
|
+
}
|
|
104
|
+
if (normalized.message == null && notification.body != null) {
|
|
105
|
+
normalized.message = notification.body;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (normalized.message == null && normalized.body != null) {
|
|
109
|
+
normalized.message = normalized.body;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return normalized;
|
|
113
|
+
};
|
|
114
|
+
|
|
33
115
|
export const QmsDashboardView: React.FC<QmsDashboardViewProps> = ({
|
|
34
116
|
style,
|
|
35
117
|
onClose,
|
|
@@ -58,12 +140,82 @@ export const QmsDashboardView: React.FC<QmsDashboardViewProps> = ({
|
|
|
58
140
|
owner_version,
|
|
59
141
|
payload,
|
|
60
142
|
}) => {
|
|
143
|
+
const onLogoutRef = useRef(onLogout);
|
|
144
|
+
const logoutDeliveredRef = useRef(false);
|
|
145
|
+
const [logoutGate, setLogoutGate] = useState<
|
|
146
|
+
'checking' | 'clear' | 'blocked'
|
|
147
|
+
>('checking');
|
|
148
|
+
|
|
149
|
+
useEffect(() => {
|
|
150
|
+
onLogoutRef.current = onLogout;
|
|
151
|
+
}, [onLogout]);
|
|
152
|
+
|
|
61
153
|
useEffect(() => {
|
|
154
|
+
let mounted = true;
|
|
155
|
+
|
|
156
|
+
const deliverLogout = () => {
|
|
157
|
+
if (logoutDeliveredRef.current) return;
|
|
158
|
+
logoutDeliveredRef.current = true;
|
|
159
|
+
if (mounted) {
|
|
160
|
+
setLogoutGate('blocked');
|
|
161
|
+
}
|
|
162
|
+
onLogoutRef.current?.();
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
const consumePendingLogout = QmsModule?.consumePendingLogout;
|
|
166
|
+
const subscription = DeviceEventEmitter.addListener(
|
|
167
|
+
'QmsSdkOnLogout',
|
|
168
|
+
() => {
|
|
169
|
+
if (mounted) {
|
|
170
|
+
setLogoutGate('blocked');
|
|
171
|
+
}
|
|
172
|
+
if (consumePendingLogout) {
|
|
173
|
+
consumePendingLogout().catch(() => false).finally(deliverLogout);
|
|
174
|
+
} else {
|
|
175
|
+
deliverLogout();
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
// A final-account logout may recreate the React host, making the event sent
|
|
181
|
+
// to the previous ReactContext impossible to receive. Consume the persisted
|
|
182
|
+
// handoff only after this component and its callback are ready.
|
|
183
|
+
if (consumePendingLogout) {
|
|
184
|
+
consumePendingLogout()
|
|
185
|
+
.then((wasPending) => {
|
|
186
|
+
if (wasPending) {
|
|
187
|
+
deliverLogout();
|
|
188
|
+
} else if (mounted) {
|
|
189
|
+
setLogoutGate('clear');
|
|
190
|
+
}
|
|
191
|
+
})
|
|
192
|
+
.catch(() => {
|
|
193
|
+
if (mounted) {
|
|
194
|
+
setLogoutGate('clear');
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
} else {
|
|
198
|
+
setLogoutGate('clear');
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
return () => {
|
|
202
|
+
mounted = false;
|
|
203
|
+
subscription.remove();
|
|
204
|
+
};
|
|
205
|
+
}, []);
|
|
206
|
+
|
|
207
|
+
useEffect(() => {
|
|
208
|
+
if (logoutGate !== 'clear') {
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
|
|
62
212
|
const resolvedClientID = clientID ?? ClientID ?? '';
|
|
63
213
|
const resolvedClientCode = clientCode ?? ClientCode ?? '';
|
|
64
214
|
const resolvedToken = user_token ?? token ?? userToken ?? '';
|
|
65
215
|
const resolvedOwnerVersion = ownerVersion ?? owner_version ?? '';
|
|
66
|
-
const
|
|
216
|
+
const normalizedPayload = normalizeNotificationPayload(payload);
|
|
217
|
+
const hasPayload =
|
|
218
|
+
normalizedPayload != null && Object.keys(normalizedPayload).length > 0;
|
|
67
219
|
|
|
68
220
|
if (autoShow && QmsModule?.showQms) {
|
|
69
221
|
if (QmsModule?.setOwnerVersion) {
|
|
@@ -93,7 +245,7 @@ export const QmsDashboardView: React.FC<QmsDashboardViewProps> = ({
|
|
|
93
245
|
resolvedClientID,
|
|
94
246
|
resolvedClientCode,
|
|
95
247
|
isOrigin,
|
|
96
|
-
|
|
248
|
+
normalizedPayload
|
|
97
249
|
);
|
|
98
250
|
} else {
|
|
99
251
|
QmsModule.showQms(
|
|
@@ -123,6 +275,7 @@ export const QmsDashboardView: React.FC<QmsDashboardViewProps> = ({
|
|
|
123
275
|
ownerVersion,
|
|
124
276
|
owner_version,
|
|
125
277
|
payload,
|
|
278
|
+
logoutGate,
|
|
126
279
|
]);
|
|
127
280
|
|
|
128
281
|
useEffect(() => {
|
|
@@ -165,14 +318,6 @@ export const QmsDashboardView: React.FC<QmsDashboardViewProps> = ({
|
|
|
165
318
|
return () => subscription.remove();
|
|
166
319
|
}, [onClose]);
|
|
167
320
|
|
|
168
|
-
useEffect(() => {
|
|
169
|
-
if (!onLogout) return;
|
|
170
|
-
const subscription = DeviceEventEmitter.addListener('QmsSdkOnLogout', () =>
|
|
171
|
-
onLogout()
|
|
172
|
-
);
|
|
173
|
-
return () => subscription.remove();
|
|
174
|
-
}, [onLogout]);
|
|
175
|
-
|
|
176
321
|
useEffect(() => {
|
|
177
322
|
if (!onActiveAccountChange) return;
|
|
178
323
|
const subscription = DeviceEventEmitter.addListener(
|
package/src/QmsPlugin.ts
CHANGED
|
@@ -6,8 +6,184 @@ export type InAppNotificationPayload = {
|
|
|
6
6
|
data?: Record<string, unknown>;
|
|
7
7
|
};
|
|
8
8
|
|
|
9
|
+
type DirectLaunchPayload = {
|
|
10
|
+
userToken?: string;
|
|
11
|
+
token?: string;
|
|
12
|
+
user_token?: string;
|
|
13
|
+
userId?: string | number;
|
|
14
|
+
USER_ID?: string | number;
|
|
15
|
+
user_id?: string | number;
|
|
16
|
+
createdBy?: string | number;
|
|
17
|
+
created_by?: string | number;
|
|
18
|
+
created_by_id?: string | number;
|
|
19
|
+
userName?: string;
|
|
20
|
+
USER_NAME?: string;
|
|
21
|
+
user_name?: string;
|
|
22
|
+
createdByName?: string;
|
|
23
|
+
created_by_name?: string;
|
|
24
|
+
userEmail?: string;
|
|
25
|
+
USER_EMAIL?: string;
|
|
26
|
+
user_email?: string;
|
|
27
|
+
email?: string;
|
|
28
|
+
userAvatar?: string;
|
|
29
|
+
USER_AVATAR?: string;
|
|
30
|
+
user_avatar?: string;
|
|
31
|
+
avatar?: string;
|
|
32
|
+
profilePicture?: string;
|
|
33
|
+
profile_picture?: string;
|
|
34
|
+
icPassport?: string;
|
|
35
|
+
IC_PASSPORT?: string;
|
|
36
|
+
ic_passport?: string;
|
|
37
|
+
clientID?: string;
|
|
38
|
+
ClientID?: string;
|
|
39
|
+
clientCode?: string;
|
|
40
|
+
ClientCode?: string;
|
|
41
|
+
isOrigin?: boolean;
|
|
42
|
+
themePrimaryColor?: string;
|
|
43
|
+
primaryColor?: string;
|
|
44
|
+
THEME_PRIMARY_COLOR?: string;
|
|
45
|
+
PRIMARY_COLOR?: string;
|
|
46
|
+
themeHeaderBackgroundColor?: string;
|
|
47
|
+
headerBackgroundColor?: string;
|
|
48
|
+
themeHeaderColor?: string;
|
|
49
|
+
headerColor?: string;
|
|
50
|
+
THEME_HEADER_BACKGROUND_COLOR?: string;
|
|
51
|
+
HEADER_BACKGROUND_COLOR?: string;
|
|
52
|
+
THEME_HEADER_COLOR?: string;
|
|
53
|
+
HEADER_COLOR?: string;
|
|
54
|
+
themeHeaderTextColor?: string;
|
|
55
|
+
headerTextColor?: string;
|
|
56
|
+
THEME_HEADER_TEXT_COLOR?: string;
|
|
57
|
+
HEADER_TEXT_COLOR?: string;
|
|
58
|
+
themeHeaderIconColor?: string;
|
|
59
|
+
headerIconColor?: string;
|
|
60
|
+
THEME_HEADER_ICON_COLOR?: string;
|
|
61
|
+
HEADER_ICON_COLOR?: string;
|
|
62
|
+
themeAccentColor?: string;
|
|
63
|
+
accentColor?: string;
|
|
64
|
+
THEME_ACCENT_COLOR?: string;
|
|
65
|
+
ACCENT_COLOR?: string;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
type SelectedUnitPayload = {
|
|
69
|
+
drawingPlanId?: string | number;
|
|
70
|
+
DRAWING_PLAN_ID?: string | number;
|
|
71
|
+
drawing_plan_id?: string | number;
|
|
72
|
+
plan_id?: string | number;
|
|
73
|
+
unitId?: string | number;
|
|
74
|
+
unit_id?: string | number;
|
|
75
|
+
unitName?: string;
|
|
76
|
+
UNIT_NAME?: string;
|
|
77
|
+
unit_name?: string;
|
|
78
|
+
projectId?: string | number;
|
|
79
|
+
PROJECT_ID?: string | number;
|
|
80
|
+
project_id?: string | number;
|
|
81
|
+
projectName?: string;
|
|
82
|
+
PROJECT_NAME?: string;
|
|
83
|
+
project_name?: string;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
export type OpenAddIssuePayload = DirectLaunchPayload &
|
|
87
|
+
SelectedUnitPayload & {
|
|
88
|
+
issueLimitStatus?: string;
|
|
89
|
+
ISSUE_LIMIT_STATUS?: string;
|
|
90
|
+
issueLimitWarningText?: string;
|
|
91
|
+
ISSUE_LIMIT_WARNING_TEXT?: string;
|
|
92
|
+
issueLimitErrorText?: string;
|
|
93
|
+
ISSUE_LIMIT_ERROR_TEXT?: string;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
export type OpenThirdPartyLinkPayload = DirectLaunchPayload &
|
|
97
|
+
SelectedUnitPayload & {
|
|
98
|
+
lotId?: string | number;
|
|
99
|
+
LOT_ID?: string | number;
|
|
100
|
+
lot_id?: string | number;
|
|
101
|
+
unitLotId?: string | number;
|
|
102
|
+
unit_lot_id?: string | number;
|
|
103
|
+
userId?: string | number;
|
|
104
|
+
USER_ID?: string | number;
|
|
105
|
+
user_id?: string | number;
|
|
106
|
+
createdBy?: string | number;
|
|
107
|
+
created_by?: string | number;
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
export type OpenPropertyInfoPayload = DirectLaunchPayload & SelectedUnitPayload;
|
|
111
|
+
export type OpenAccessItemPayload = DirectLaunchPayload & SelectedUnitPayload;
|
|
112
|
+
export type OpenProjectUpdatePayload = DirectLaunchPayload &
|
|
113
|
+
SelectedUnitPayload;
|
|
114
|
+
export type OpenInboxPayload = DirectLaunchPayload & SelectedUnitPayload;
|
|
115
|
+
export type OpenIssueListPayload = DirectLaunchPayload & SelectedUnitPayload;
|
|
116
|
+
export type OpenDraftIssuesPayload = DirectLaunchPayload & SelectedUnitPayload;
|
|
117
|
+
export type GetDraftIssueCountPayload = DirectLaunchPayload &
|
|
118
|
+
SelectedUnitPayload;
|
|
119
|
+
export type OpenPoaSignOffPayload = DirectLaunchPayload & SelectedUnitPayload;
|
|
120
|
+
export type OpenMakeAppointmentPayload = DirectLaunchPayload &
|
|
121
|
+
SelectedUnitPayload & {
|
|
122
|
+
preferredAppointmentType?: string;
|
|
123
|
+
PREFERRED_APPOINTMENT_TYPE?: string;
|
|
124
|
+
preferred_appointment_type?: string;
|
|
125
|
+
};
|
|
126
|
+
export type OpenAppointmentListPayload = DirectLaunchPayload &
|
|
127
|
+
SelectedUnitPayload & {
|
|
128
|
+
handoverStatus?: string;
|
|
129
|
+
handover_status?: string;
|
|
130
|
+
readyToHandover?: string | boolean | number;
|
|
131
|
+
ready_to_handover?: string | boolean | number;
|
|
132
|
+
clearanceLetter?: string | boolean | number;
|
|
133
|
+
clearance_letter?: string | boolean | number;
|
|
134
|
+
clearanceLetterIssuanceMessage?: string;
|
|
135
|
+
clearance_letter_issuance_message?: string;
|
|
136
|
+
ownerHandover?: string | boolean | number;
|
|
137
|
+
owner_handover?: string | boolean | number;
|
|
138
|
+
ownerAppointmentAlert?: string;
|
|
139
|
+
owner_appointment_alert?: string;
|
|
140
|
+
ownerJointInspection?: string | boolean | number;
|
|
141
|
+
owner_joint_inspection?: string | boolean | number;
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
type DirectNativeMethod = (
|
|
145
|
+
userToken?: string,
|
|
146
|
+
clientID?: string,
|
|
147
|
+
clientCode?: string,
|
|
148
|
+
isOrigin?: boolean,
|
|
149
|
+
options?: Record<string, unknown> | null
|
|
150
|
+
) => Promise<boolean>;
|
|
151
|
+
|
|
152
|
+
type DirectNativeCountMethod = (
|
|
153
|
+
userToken?: string,
|
|
154
|
+
clientID?: string,
|
|
155
|
+
clientCode?: string,
|
|
156
|
+
isOrigin?: boolean,
|
|
157
|
+
options?: Record<string, unknown> | null
|
|
158
|
+
) => Promise<number>;
|
|
159
|
+
|
|
160
|
+
type DirectMethodName =
|
|
161
|
+
| 'openAddIssue'
|
|
162
|
+
| 'openThirdPartyLink'
|
|
163
|
+
| 'openPropertyInfo'
|
|
164
|
+
| 'openAccessItem'
|
|
165
|
+
| 'openProjectUpdate'
|
|
166
|
+
| 'openInbox'
|
|
167
|
+
| 'openIssueList'
|
|
168
|
+
| 'openDraftIssues'
|
|
169
|
+
| 'openPoaSignOff'
|
|
170
|
+
| 'openMakeAppointment'
|
|
171
|
+
| 'openAppointmentList';
|
|
172
|
+
|
|
9
173
|
const { QmsModule } = NativeModules as {
|
|
10
174
|
QmsModule?: {
|
|
175
|
+
openAddIssue?: DirectNativeMethod;
|
|
176
|
+
openThirdPartyLink?: DirectNativeMethod;
|
|
177
|
+
openPropertyInfo?: DirectNativeMethod;
|
|
178
|
+
openAccessItem?: DirectNativeMethod;
|
|
179
|
+
openProjectUpdate?: DirectNativeMethod;
|
|
180
|
+
openInbox?: DirectNativeMethod;
|
|
181
|
+
openIssueList?: DirectNativeMethod;
|
|
182
|
+
openDraftIssues?: DirectNativeMethod;
|
|
183
|
+
getDraftIssueCount?: DirectNativeCountMethod;
|
|
184
|
+
openPoaSignOff?: DirectNativeMethod;
|
|
185
|
+
openMakeAppointment?: DirectNativeMethod;
|
|
186
|
+
openAppointmentList?: DirectNativeMethod;
|
|
11
187
|
emitInAppNotification?: (title?: string, body?: string) => void;
|
|
12
188
|
emitInAppNotificationWithPayload?: (
|
|
13
189
|
title?: string,
|
|
@@ -17,7 +193,142 @@ const { QmsModule } = NativeModules as {
|
|
|
17
193
|
};
|
|
18
194
|
};
|
|
19
195
|
|
|
196
|
+
function resolveCredentials(payload: DirectLaunchPayload) {
|
|
197
|
+
return {
|
|
198
|
+
token: payload.userToken ?? payload.token ?? payload.user_token ?? '',
|
|
199
|
+
clientID: payload.clientID ?? payload.ClientID ?? '',
|
|
200
|
+
clientCode: payload.clientCode ?? payload.ClientCode ?? '',
|
|
201
|
+
isOrigin: payload.isOrigin ?? false,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function callDirectMethod<T extends DirectLaunchPayload>(
|
|
206
|
+
methodName: DirectMethodName,
|
|
207
|
+
unavailableMessage: string,
|
|
208
|
+
payload: T
|
|
209
|
+
): Promise<boolean> {
|
|
210
|
+
const method = QmsModule?.[methodName];
|
|
211
|
+
if (!method) {
|
|
212
|
+
return Promise.reject(new Error(unavailableMessage));
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const credentials = resolveCredentials(payload);
|
|
216
|
+
return method(
|
|
217
|
+
credentials.token,
|
|
218
|
+
credentials.clientID,
|
|
219
|
+
credentials.clientCode,
|
|
220
|
+
credentials.isOrigin,
|
|
221
|
+
payload as Record<string, unknown>
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
|
|
20
225
|
export const QmsPlugin = {
|
|
226
|
+
openAddIssue(payload: OpenAddIssuePayload): Promise<boolean> {
|
|
227
|
+
return callDirectMethod(
|
|
228
|
+
'openAddIssue',
|
|
229
|
+
'QMS openAddIssue is not available.',
|
|
230
|
+
payload
|
|
231
|
+
);
|
|
232
|
+
},
|
|
233
|
+
|
|
234
|
+
openThirdPartyLink(payload: OpenThirdPartyLinkPayload): Promise<boolean> {
|
|
235
|
+
return callDirectMethod(
|
|
236
|
+
'openThirdPartyLink',
|
|
237
|
+
'QMS openThirdPartyLink is not available.',
|
|
238
|
+
payload
|
|
239
|
+
);
|
|
240
|
+
},
|
|
241
|
+
|
|
242
|
+
openPropertyInfo(payload: OpenPropertyInfoPayload): Promise<boolean> {
|
|
243
|
+
return callDirectMethod(
|
|
244
|
+
'openPropertyInfo',
|
|
245
|
+
'QMS openPropertyInfo is not available.',
|
|
246
|
+
payload
|
|
247
|
+
);
|
|
248
|
+
},
|
|
249
|
+
|
|
250
|
+
openAccessItem(payload: OpenAccessItemPayload): Promise<boolean> {
|
|
251
|
+
return callDirectMethod(
|
|
252
|
+
'openAccessItem',
|
|
253
|
+
'QMS openAccessItem is not available.',
|
|
254
|
+
payload
|
|
255
|
+
);
|
|
256
|
+
},
|
|
257
|
+
|
|
258
|
+
openProjectUpdate(payload: OpenProjectUpdatePayload): Promise<boolean> {
|
|
259
|
+
return callDirectMethod(
|
|
260
|
+
'openProjectUpdate',
|
|
261
|
+
'QMS openProjectUpdate is not available.',
|
|
262
|
+
payload
|
|
263
|
+
);
|
|
264
|
+
},
|
|
265
|
+
|
|
266
|
+
openInbox(payload: OpenInboxPayload): Promise<boolean> {
|
|
267
|
+
return callDirectMethod(
|
|
268
|
+
'openInbox',
|
|
269
|
+
'QMS openInbox is not available.',
|
|
270
|
+
payload
|
|
271
|
+
);
|
|
272
|
+
},
|
|
273
|
+
|
|
274
|
+
openIssueList(payload: OpenIssueListPayload): Promise<boolean> {
|
|
275
|
+
return callDirectMethod(
|
|
276
|
+
'openIssueList',
|
|
277
|
+
'QMS openIssueList is not available.',
|
|
278
|
+
payload
|
|
279
|
+
);
|
|
280
|
+
},
|
|
281
|
+
|
|
282
|
+
openDraftIssues(payload: OpenDraftIssuesPayload): Promise<boolean> {
|
|
283
|
+
return callDirectMethod(
|
|
284
|
+
'openDraftIssues',
|
|
285
|
+
'QMS openDraftIssues is not available.',
|
|
286
|
+
payload
|
|
287
|
+
);
|
|
288
|
+
},
|
|
289
|
+
|
|
290
|
+
getDraftIssueCount(payload: GetDraftIssueCountPayload): Promise<number> {
|
|
291
|
+
const method = QmsModule?.getDraftIssueCount;
|
|
292
|
+
if (!method) {
|
|
293
|
+
return Promise.reject(
|
|
294
|
+
new Error('QMS getDraftIssueCount is not available.')
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
const credentials = resolveCredentials(payload);
|
|
299
|
+
return method(
|
|
300
|
+
credentials.token,
|
|
301
|
+
credentials.clientID,
|
|
302
|
+
credentials.clientCode,
|
|
303
|
+
credentials.isOrigin,
|
|
304
|
+
payload as Record<string, unknown>
|
|
305
|
+
).then((count: number) => Number(count) || 0);
|
|
306
|
+
},
|
|
307
|
+
|
|
308
|
+
openPoaSignOff(payload: OpenPoaSignOffPayload): Promise<boolean> {
|
|
309
|
+
return callDirectMethod(
|
|
310
|
+
'openPoaSignOff',
|
|
311
|
+
'QMS openPoaSignOff is not available.',
|
|
312
|
+
payload
|
|
313
|
+
);
|
|
314
|
+
},
|
|
315
|
+
|
|
316
|
+
openMakeAppointment(payload: OpenMakeAppointmentPayload): Promise<boolean> {
|
|
317
|
+
return callDirectMethod(
|
|
318
|
+
'openMakeAppointment',
|
|
319
|
+
'QMS openMakeAppointment is not available.',
|
|
320
|
+
payload
|
|
321
|
+
);
|
|
322
|
+
},
|
|
323
|
+
|
|
324
|
+
openAppointmentList(payload: OpenAppointmentListPayload): Promise<boolean> {
|
|
325
|
+
return callDirectMethod(
|
|
326
|
+
'openAppointmentList',
|
|
327
|
+
'QMS openAppointmentList is not available.',
|
|
328
|
+
payload
|
|
329
|
+
);
|
|
330
|
+
},
|
|
331
|
+
|
|
21
332
|
emitInAppNotification(payload: InAppNotificationPayload): void {
|
|
22
333
|
if (QmsModule?.emitInAppNotificationWithPayload) {
|
|
23
334
|
QmsModule.emitInAppNotificationWithPayload(
|
|
@@ -27,6 +338,7 @@ export const QmsPlugin = {
|
|
|
27
338
|
);
|
|
28
339
|
return;
|
|
29
340
|
}
|
|
341
|
+
|
|
30
342
|
QmsModule?.emitInAppNotification?.(
|
|
31
343
|
payload.title ?? 'Notification',
|
|
32
344
|
payload.body ?? ''
|
package/src/index.tsx
CHANGED
|
@@ -4,4 +4,16 @@ export type {
|
|
|
4
4
|
QmsDashboardViewProps,
|
|
5
5
|
} from './QmsDashboardView.types';
|
|
6
6
|
export { QmsPlugin } from './QmsPlugin';
|
|
7
|
-
export type {
|
|
7
|
+
export type {
|
|
8
|
+
InAppNotificationPayload,
|
|
9
|
+
OpenAccessItemPayload,
|
|
10
|
+
OpenAddIssuePayload,
|
|
11
|
+
OpenAppointmentListPayload,
|
|
12
|
+
OpenInboxPayload,
|
|
13
|
+
OpenIssueListPayload,
|
|
14
|
+
OpenMakeAppointmentPayload,
|
|
15
|
+
OpenPoaSignOffPayload,
|
|
16
|
+
OpenProjectUpdatePayload,
|
|
17
|
+
OpenPropertyInfoPayload,
|
|
18
|
+
OpenThirdPartyLinkPayload,
|
|
19
|
+
} from './QmsPlugin';
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
3
|
-
<plist version="1.0">
|
|
4
|
-
<dict>
|
|
5
|
-
<key>AvailableLibraries</key>
|
|
6
|
-
<array>
|
|
7
|
-
<dict>
|
|
8
|
-
<key>BinaryPath</key>
|
|
9
|
-
<string>QmsPluginFramework.framework/QmsPluginFramework</string>
|
|
10
|
-
<key>LibraryIdentifier</key>
|
|
11
|
-
<string>ios-arm64_x86_64-simulator</string>
|
|
12
|
-
<key>LibraryPath</key>
|
|
13
|
-
<string>QmsPluginFramework.framework</string>
|
|
14
|
-
<key>SupportedArchitectures</key>
|
|
15
|
-
<array>
|
|
16
|
-
<string>arm64</string>
|
|
17
|
-
<string>x86_64</string>
|
|
18
|
-
</array>
|
|
19
|
-
<key>SupportedPlatform</key>
|
|
20
|
-
<string>ios</string>
|
|
21
|
-
<key>SupportedPlatformVariant</key>
|
|
22
|
-
<string>simulator</string>
|
|
23
|
-
</dict>
|
|
24
|
-
<dict>
|
|
25
|
-
<key>BinaryPath</key>
|
|
26
|
-
<string>QmsPluginFramework.framework/QmsPluginFramework</string>
|
|
27
|
-
<key>LibraryIdentifier</key>
|
|
28
|
-
<string>ios-arm64</string>
|
|
29
|
-
<key>LibraryPath</key>
|
|
30
|
-
<string>QmsPluginFramework.framework</string>
|
|
31
|
-
<key>SupportedArchitectures</key>
|
|
32
|
-
<array>
|
|
33
|
-
<string>arm64</string>
|
|
34
|
-
</array>
|
|
35
|
-
<key>SupportedPlatform</key>
|
|
36
|
-
<string>ios</string>
|
|
37
|
-
</dict>
|
|
38
|
-
</array>
|
|
39
|
-
<key>CFBundlePackageType</key>
|
|
40
|
-
<string>XFWK</string>
|
|
41
|
-
<key>XCFrameworkFormatVersion</key>
|
|
42
|
-
<string>1.0</string>
|
|
43
|
-
</dict>
|
|
44
|
-
</plist>
|
package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/Assets.car
DELETED
|
Binary file
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
//QmsPlugin.h
|
|
2
|
-
#import <Foundation/Foundation.h>
|
|
3
|
-
#import <UIKit/UIKit.h>
|
|
4
|
-
|
|
5
|
-
NS_ASSUME_NONNULL_BEGIN
|
|
6
|
-
|
|
7
|
-
@interface QmsPluginUI : NSObject
|
|
8
|
-
|
|
9
|
-
+ (UIViewController *)makeViewController;
|
|
10
|
-
|
|
11
|
-
/// Fetches project list data and presents DashboardViewController fully configured
|
|
12
|
-
/// for the given FCM deep-link payload. The payload must contain at minimum
|
|
13
|
-
/// `project_id` and `plan_id`. Auth/base-URL must already be configured in APIConfig
|
|
14
|
-
/// (i.e. the SDK has already been initialised by the user opening the app).
|
|
15
|
-
///
|
|
16
|
-
/// @param payload The FCM notification data dictionary.
|
|
17
|
-
/// @param presenter The view controller from which the dashboard will be presented modally.
|
|
18
|
-
+ (void)presentDashboardFromPayload:(NSDictionary *)payload
|
|
19
|
-
fromViewController:(UIViewController *)presenter;
|
|
20
|
-
|
|
21
|
-
/// Configures APIConfig with the project/plan context from the payload, then
|
|
22
|
-
/// presents AppointmentDetailsViewController modally. The payload must contain
|
|
23
|
-
/// `project_id`, `plan_id`, and `appointment_id` (or `id` as a fallback).
|
|
24
|
-
/// Auth/base-URL must already be configured in APIConfig.
|
|
25
|
-
///
|
|
26
|
-
/// @param payload The FCM notification data dictionary.
|
|
27
|
-
/// @param presenter The view controller from which the appointment screen will be presented.
|
|
28
|
-
+ (void)presentAppointmentFromPayload:(NSDictionary *)payload
|
|
29
|
-
fromViewController:(UIViewController *)presenter;
|
|
30
|
-
|
|
31
|
-
/// Fetches the issue list, finds the matching issue by `issue_id` from the payload,
|
|
32
|
-
/// and presents IssueDetailViewController fully configured. The payload must contain
|
|
33
|
-
/// at minimum `project_id`, `plan_id`, and `issue_id`. Auth/base-URL must already
|
|
34
|
-
/// be configured in APIConfig.
|
|
35
|
-
///
|
|
36
|
-
/// @param payload The FCM notification data dictionary.
|
|
37
|
-
/// @param presenter The view controller from which the issue screen will be presented.
|
|
38
|
-
+ (void)presentIssueFromPayload:(NSDictionary *)payload
|
|
39
|
-
fromViewController:(UIViewController *)presenter;
|
|
40
|
-
|
|
41
|
-
@end
|
|
42
|
-
|
|
43
|
-
NS_ASSUME_NONNULL_END
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// QmsPluginFramework.h
|
|
3
|
-
// QmsPluginFramework
|
|
4
|
-
//
|
|
5
|
-
|
|
6
|
-
#import <Foundation/Foundation.h>
|
|
7
|
-
#import <UIKit/UIKit.h>
|
|
8
|
-
|
|
9
|
-
//! Project version number for QmsPluginFramework.
|
|
10
|
-
FOUNDATION_EXPORT double QmsPluginFrameworkVersionNumber;
|
|
11
|
-
|
|
12
|
-
//! Project version string for QmsPluginFramework.
|
|
13
|
-
FOUNDATION_EXPORT const unsigned char QmsPluginFrameworkVersionString[];
|
|
14
|
-
|
|
15
|
-
// Public headers
|
|
16
|
-
#import <QmsPluginFramework/QmsPlugin.h>
|
|
17
|
-
|
package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/Info.plist
DELETED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|