@redacto.io/consent-sdk-react-native 5.0.0-beta.0 → 5.0.0-beta.2

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/README.md CHANGED
@@ -136,6 +136,7 @@ import { RedactoNoticeConsent } from "@redacto.io/consent-sdk-react-native";
136
136
  | `accessToken` | `string` | ✓ | JWT access token |
137
137
  | `refreshToken` | `string` | ✓ | JWT refresh token |
138
138
  | `baseUrl` | `string` | | Override API base URL |
139
+ | `ledgerBaseUrl` | `string` | | Go ledger base URL. When set, consent writes and prior-consent checks route through the ledger (falls back: ledger → baseUrl → default). Omit to keep the legacy consent-server path. |
139
140
  | `settings` | `Partial<Settings>` | | UI customisation (colours, border radius, fonts) |
140
141
  | `language` | `string` | | Initial language code (e.g. `"en"`) |
141
142
  | `blockUI` | `boolean` | | Block the modal from being dismissed |
@@ -173,6 +174,7 @@ import { RedactoNoticeConsentInline } from "@redacto.io/consent-sdk-react-native
173
174
  | `notice_uuid` | `string` | ✓ | Notice UUID |
174
175
  | `accessToken` | `string` | | JWT access token (triggers auto-submit when set) |
175
176
  | `baseUrl` | `string` | | Override API base URL |
177
+ | `ledgerBaseUrl` | `string` | | Go ledger base URL. When set, consent writes and already-consented checks route through the ledger. Omit for legacy behavior. |
176
178
  | `language` | `string` | | Language code |
177
179
  | `settings` | `Partial<Settings>` | | UI customisation |
178
180
  | `applicationId` | `string` | | Application-specific UUID |
@@ -217,6 +219,7 @@ import { RedactoPrivacyCenter } from "@redacto.io/consent-sdk-react-native/priva
217
219
  | Prop | Type | Required | Default | Description |
218
220
  | -------------- | ----------------------------------------------------------------------------- | -------- | -------------------- | ---------------------------------------- |
219
221
  | `baseUrl` | `string` | ✓ | - | Consent server base URL |
222
+ | `ledgerBaseUrl` | `string` | | - | Go ledger base URL. When set, user consents, group purposes, receipts, and manage-consent route through the ledger. Omit to use the legacy `/dsar/privacy-center/*` routes. See the note below on the DSAR form picker. |
220
223
  | `slug` | `string` | ✓ | - | Workspace slug |
221
224
  | `accessToken` | `string` | ✓ | - | JWT access token |
222
225
  | `refreshToken` | `string` | ✓ | - | JWT refresh token |
@@ -274,6 +277,18 @@ For consumers who want fully custom UI, the headless core exposes the API client
274
277
  - Keep API keys and server secrets on your backend only.
275
278
  - In Expo apps, values read from `EXPO_PUBLIC_*` are bundled into the app and should only contain non-sensitive config like UUIDs and URLs.
276
279
  - If you do not pass `baseUrl`, the SDK defaults to `https://api.redacto.io/consent` for both notice and Privacy Center surfaces.
280
+ - `ledgerBaseUrl` is optional and independent of `baseUrl` — pass both when routing consent through the Go ledger. Omitting it keeps the legacy consent-server behavior.
281
+
282
+ ## Ledger mode
283
+
284
+ Passing `ledgerBaseUrl` routes consent-bearing reads and writes to the Go ledger:
285
+
286
+ - **Notice components** — `submit-consent` goes to the ledger, and the already-consented check uses the ledger's `check-consent` endpoint instead of the legacy HTTP 409 signal. Notice content, tokens, and TTS always stay on `baseUrl`.
287
+ - **Privacy Center** — user consents, group purposes, receipts (including the `/download` PDF path), and manage-consent (sent as a `partial: true` write) route to the ledger. DSAR form, cases, activities, OTP, and notifications stay on `baseUrl`.
288
+
289
+ Every ledger read degrades to the legacy path on failure, so a ledger outage does not break the consent flow.
290
+
291
+ > **Known limitation.** Unlike the React SDK, the DSAR form's product picker is **not** overlaid from ledger-served consents. Against a workspace cut over to the ledger — where the legacy `form/data` response carries no product groups — the picker renders empty. If your DSAR form depends on the product picker, stay on the legacy path until this is addressed.
277
292
 
278
293
  ## License
279
294
 
@@ -0,0 +1,48 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined") return require.apply(this, arguments);
5
+ throw Error('Dynamic require of "' + x + '" is not supported');
6
+ });
7
+
8
+ // src/shared/languages.ts
9
+ var languageOptions = [
10
+ { value: "en", label: "English" },
11
+ { value: "hi", label: "\u0939\u093F\u0928\u094D\u0926\u0940 (Hindi)" },
12
+ { value: "te", label: "\u0C24\u0C46\u0C32\u0C41\u0C17\u0C41 (Telugu)" },
13
+ { value: "mr", label: "\u092E\u0930\u093E\u0920\u0940 (Marathi)" },
14
+ { value: "ta", label: "\u0BA4\u0BAE\u0BBF\u0BB4\u0BCD (Tamil)" },
15
+ { value: "ur", label: "\u0627\u0631\u062F\u0648 (Urdu)" },
16
+ { value: "gu", label: "\u0A97\u0AC1\u0A9C\u0AB0\u0ABE\u0AA4\u0AC0 (Gujarati)" },
17
+ { value: "kn", label: "\u0C95\u0CA8\u0CCD\u0CA8\u0CA1 (Kannada)" },
18
+ { value: "ml", label: "\u0D2E\u0D32\u0D2F\u0D3E\u0D33\u0D02 (Malayalam)" },
19
+ { value: "pa", label: "\u0A2A\u0A70\u0A1C\u0A3E\u0A2C\u0A40 (Punjabi)" },
20
+ { value: "or", label: "\u0B13\u0B21\u0B3C\u0B3F\u0B06 (Odia)" },
21
+ { value: "as", label: "\u0985\u09B8\u09AE\u09C0\u09AF\u09BC\u09BE (Assamese)" },
22
+ { value: "bn", label: "\u09AC\u09BE\u0982\u09B2\u09BE (Bengali)" },
23
+ { value: "mai", label: "\u092E\u0948\u0925\u093F\u0932\u0940 (Maithili)" },
24
+ { value: "ne", label: "\u0928\u0947\u092A\u093E\u0932\u0940 (Nepali)" },
25
+ { value: "sd", label: "\u0633\u0646\u068C\u064A (Sindhi)" },
26
+ { value: "doi", label: "\u0921\u094B\u0917\u0930\u0940 (Dogri)" },
27
+ { value: "mni-Mtei", label: "\uABC3\uABE9\uABC7\uABE9\uABC2\uABE3\uABDF (Manipuri)" },
28
+ { value: "gom", label: "\u0915\u094B\u0902\u0915\u0923\u0940 (Goan Konkani)" },
29
+ { value: "sa", label: "\u0938\u0902\u0938\u094D\u0915\u0943\u0924\u092E\u094D (Sanskrit)" },
30
+ { value: "brx", label: "\u092C\u0921\u093C\u094B (Bodo)" },
31
+ { value: "ks", label: "\u0643\u0672\u0634\u064F\u0631 (Kashmiri)" },
32
+ { value: "sat", label: "\u1C65\u1C5F\u1C71\u1C5B\u1C5F\u1C72\u1C64 (Santali)" }
33
+ ];
34
+ var codeByLabel = new Map(languageOptions.map((o) => [o.label, o.value]));
35
+ var codeByLower = new Map(languageOptions.map((o) => [o.value.toLowerCase(), o.value]));
36
+ function toLanguageCode(lang) {
37
+ var _a, _b;
38
+ if (!lang) return void 0;
39
+ const trimmed = lang.trim();
40
+ if (!trimmed) return void 0;
41
+ return (_b = (_a = codeByLabel.get(trimmed)) != null ? _a : codeByLower.get(trimmed.toLowerCase())) != null ? _b : trimmed;
42
+ }
43
+
44
+ export {
45
+ __require,
46
+ languageOptions,
47
+ toLanguageCode
48
+ };
package/dist/index.js CHANGED
@@ -46,6 +46,42 @@ var import_jwt_decode = require("jwt-decode");
46
46
  // src/constants.ts
47
47
  var DEFAULT_CONSENT_API_BASE_URL = "https://api.redacto.io/consent";
48
48
 
49
+ // src/shared/languages.ts
50
+ var languageOptions = [
51
+ { value: "en", label: "English" },
52
+ { value: "hi", label: "\u0939\u093F\u0928\u094D\u0926\u0940 (Hindi)" },
53
+ { value: "te", label: "\u0C24\u0C46\u0C32\u0C41\u0C17\u0C41 (Telugu)" },
54
+ { value: "mr", label: "\u092E\u0930\u093E\u0920\u0940 (Marathi)" },
55
+ { value: "ta", label: "\u0BA4\u0BAE\u0BBF\u0BB4\u0BCD (Tamil)" },
56
+ { value: "ur", label: "\u0627\u0631\u062F\u0648 (Urdu)" },
57
+ { value: "gu", label: "\u0A97\u0AC1\u0A9C\u0AB0\u0ABE\u0AA4\u0AC0 (Gujarati)" },
58
+ { value: "kn", label: "\u0C95\u0CA8\u0CCD\u0CA8\u0CA1 (Kannada)" },
59
+ { value: "ml", label: "\u0D2E\u0D32\u0D2F\u0D3E\u0D33\u0D02 (Malayalam)" },
60
+ { value: "pa", label: "\u0A2A\u0A70\u0A1C\u0A3E\u0A2C\u0A40 (Punjabi)" },
61
+ { value: "or", label: "\u0B13\u0B21\u0B3C\u0B3F\u0B06 (Odia)" },
62
+ { value: "as", label: "\u0985\u09B8\u09AE\u09C0\u09AF\u09BC\u09BE (Assamese)" },
63
+ { value: "bn", label: "\u09AC\u09BE\u0982\u09B2\u09BE (Bengali)" },
64
+ { value: "mai", label: "\u092E\u0948\u0925\u093F\u0932\u0940 (Maithili)" },
65
+ { value: "ne", label: "\u0928\u0947\u092A\u093E\u0932\u0940 (Nepali)" },
66
+ { value: "sd", label: "\u0633\u0646\u068C\u064A (Sindhi)" },
67
+ { value: "doi", label: "\u0921\u094B\u0917\u0930\u0940 (Dogri)" },
68
+ { value: "mni-Mtei", label: "\uABC3\uABE9\uABC7\uABE9\uABC2\uABE3\uABDF (Manipuri)" },
69
+ { value: "gom", label: "\u0915\u094B\u0902\u0915\u0923\u0940 (Goan Konkani)" },
70
+ { value: "sa", label: "\u0938\u0902\u0938\u094D\u0915\u0943\u0924\u092E\u094D (Sanskrit)" },
71
+ { value: "brx", label: "\u092C\u0921\u093C\u094B (Bodo)" },
72
+ { value: "ks", label: "\u0643\u0672\u0634\u064F\u0631 (Kashmiri)" },
73
+ { value: "sat", label: "\u1C65\u1C5F\u1C71\u1C5B\u1C5F\u1C72\u1C64 (Santali)" }
74
+ ];
75
+ var codeByLabel = new Map(languageOptions.map((o) => [o.label, o.value]));
76
+ var codeByLower = new Map(languageOptions.map((o) => [o.value.toLowerCase(), o.value]));
77
+ function toLanguageCode(lang) {
78
+ var _a, _b;
79
+ if (!lang) return void 0;
80
+ const trimmed = lang.trim();
81
+ if (!trimmed) return void 0;
82
+ return (_b = (_a = codeByLabel.get(trimmed)) != null ? _a : codeByLower.get(trimmed.toLowerCase())) != null ? _b : trimmed;
83
+ }
84
+
49
85
  // src/RedactoNoticeConsent/api/index.ts
50
86
  var apiCache = /* @__PURE__ */ new Map();
51
87
  var CACHE_TTL = 5 * 60 * 1e3;
@@ -154,6 +190,7 @@ var submitConsentEvent = async ({
154
190
  meta_data,
155
191
  guardianVerificationReference,
156
192
  selfDeclaredAdult,
193
+ language,
157
194
  signal
158
195
  }) => {
159
196
  if (!noticeUuid || !accessToken || !Array.isArray(purposes)) {
@@ -190,7 +227,8 @@ var submitConsentEvent = async ({
190
227
  declined: Boolean(declined),
191
228
  meta_data: meta_data ? { specific_uuid: meta_data.specific_uuid } : void 0,
192
229
  guardian_verification_reference: guardianVerificationReference,
193
- self_declared_adult: selfDeclaredAdult
230
+ self_declared_adult: selfDeclaredAdult,
231
+ language: toLanguageCode(language)
194
232
  };
195
233
  const response = await fetch(
196
234
  `${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/submit-consent`,
@@ -2329,7 +2367,8 @@ var RedactoNoticeConsent = ({
2329
2367
  declined: false,
2330
2368
  meta_data: applicationId ? { specific_uuid: applicationId } : void 0,
2331
2369
  guardianVerificationReference: verificationReferenceRef.current || void 0,
2332
- selfDeclaredAdult: selfDeclaredAdult || void 0
2370
+ selfDeclaredAdult: selfDeclaredAdult || void 0,
2371
+ language: selectedLanguage
2333
2372
  });
2334
2373
  await stopAudio();
2335
2374
  clearApiCache();
@@ -2344,7 +2383,7 @@ var RedactoNoticeConsent = ({
2344
2383
  } finally {
2345
2384
  setIsSubmitting(false);
2346
2385
  }
2347
- }, [content, accessToken, baseUrl, ledgerBaseUrl, applicationId, selectedPurposes, selectedDataElements, stopAudio, onAccept, onError]);
2386
+ }, [content, accessToken, baseUrl, ledgerBaseUrl, applicationId, selectedPurposes, selectedDataElements, selectedLanguage, stopAudio, onAccept, onError]);
2348
2387
  const handleDecline = (0, import_react2.useCallback)(() => {
2349
2388
  stopAudio();
2350
2389
  stopPolling();
@@ -2996,7 +3035,8 @@ var submitConsentEvent2 = async ({
2996
3035
  noticeUuid,
2997
3036
  purposes,
2998
3037
  declined,
2999
- meta_data
3038
+ meta_data,
3039
+ language
3000
3040
  }) => {
3001
3041
  var _a, _b;
3002
3042
  const apiBaseUrl = ledgerBaseUrl || baseUrl || DEFAULT_CONSENT_API_BASE_URL;
@@ -3019,7 +3059,8 @@ var submitConsentEvent2 = async ({
3019
3059
  select_all_mandatory: false,
3020
3060
  source: "MOBILE",
3021
3061
  declined,
3022
- meta_data
3062
+ meta_data,
3063
+ language: toLanguageCode(language)
3023
3064
  };
3024
3065
  const response = await fetch(
3025
3066
  `${apiBaseUrl}/public/organisations/${org_uuid}/workspaces/${workspace_uuid}/submit-consent`,
@@ -3567,7 +3608,8 @@ var RedactoConsentInlineComponent = ({
3567
3608
  };
3568
3609
  }),
3569
3610
  declined: false,
3570
- meta_data: applicationId ? { specific_uuid: applicationId } : void 0
3611
+ meta_data: applicationId ? { specific_uuid: applicationId } : void 0,
3612
+ language: selectedLanguage
3571
3613
  });
3572
3614
  onAccept == null ? void 0 : onAccept();
3573
3615
  hasSubmittedRef.current = false;
@@ -3590,6 +3632,7 @@ var RedactoConsentInlineComponent = ({
3590
3632
  selectedDataElements,
3591
3633
  selectedPurposes,
3592
3634
  applicationId,
3635
+ selectedLanguage,
3593
3636
  onAccept
3594
3637
  ]
3595
3638
  );
package/dist/index.mjs CHANGED
@@ -1,4 +1,6 @@
1
- import "./chunk-Y6FXYEAI.mjs";
1
+ import {
2
+ toLanguageCode
3
+ } from "./chunk-IVOOB4JK.mjs";
2
4
 
3
5
  // src/RedactoNoticeConsent/RedactoNoticeConsent.tsx
4
6
  import {
@@ -138,6 +140,7 @@ var submitConsentEvent = async ({
138
140
  meta_data,
139
141
  guardianVerificationReference,
140
142
  selfDeclaredAdult,
143
+ language,
141
144
  signal
142
145
  }) => {
143
146
  if (!noticeUuid || !accessToken || !Array.isArray(purposes)) {
@@ -174,7 +177,8 @@ var submitConsentEvent = async ({
174
177
  declined: Boolean(declined),
175
178
  meta_data: meta_data ? { specific_uuid: meta_data.specific_uuid } : void 0,
176
179
  guardian_verification_reference: guardianVerificationReference,
177
- self_declared_adult: selfDeclaredAdult
180
+ self_declared_adult: selfDeclaredAdult,
181
+ language: toLanguageCode(language)
178
182
  };
179
183
  const response = await fetch(
180
184
  `${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/submit-consent`,
@@ -2320,7 +2324,8 @@ var RedactoNoticeConsent = ({
2320
2324
  declined: false,
2321
2325
  meta_data: applicationId ? { specific_uuid: applicationId } : void 0,
2322
2326
  guardianVerificationReference: verificationReferenceRef.current || void 0,
2323
- selfDeclaredAdult: selfDeclaredAdult || void 0
2327
+ selfDeclaredAdult: selfDeclaredAdult || void 0,
2328
+ language: selectedLanguage
2324
2329
  });
2325
2330
  await stopAudio();
2326
2331
  clearApiCache();
@@ -2335,7 +2340,7 @@ var RedactoNoticeConsent = ({
2335
2340
  } finally {
2336
2341
  setIsSubmitting(false);
2337
2342
  }
2338
- }, [content, accessToken, baseUrl, ledgerBaseUrl, applicationId, selectedPurposes, selectedDataElements, stopAudio, onAccept, onError]);
2343
+ }, [content, accessToken, baseUrl, ledgerBaseUrl, applicationId, selectedPurposes, selectedDataElements, selectedLanguage, stopAudio, onAccept, onError]);
2339
2344
  const handleDecline = useCallback(() => {
2340
2345
  stopAudio();
2341
2346
  stopPolling();
@@ -3000,7 +3005,8 @@ var submitConsentEvent2 = async ({
3000
3005
  noticeUuid,
3001
3006
  purposes,
3002
3007
  declined,
3003
- meta_data
3008
+ meta_data,
3009
+ language
3004
3010
  }) => {
3005
3011
  var _a, _b;
3006
3012
  const apiBaseUrl = ledgerBaseUrl || baseUrl || DEFAULT_CONSENT_API_BASE_URL;
@@ -3023,7 +3029,8 @@ var submitConsentEvent2 = async ({
3023
3029
  select_all_mandatory: false,
3024
3030
  source: "MOBILE",
3025
3031
  declined,
3026
- meta_data
3032
+ meta_data,
3033
+ language: toLanguageCode(language)
3027
3034
  };
3028
3035
  const response = await fetch(
3029
3036
  `${apiBaseUrl}/public/organisations/${org_uuid}/workspaces/${workspace_uuid}/submit-consent`,
@@ -3571,7 +3578,8 @@ var RedactoConsentInlineComponent = ({
3571
3578
  };
3572
3579
  }),
3573
3580
  declined: false,
3574
- meta_data: applicationId ? { specific_uuid: applicationId } : void 0
3581
+ meta_data: applicationId ? { specific_uuid: applicationId } : void 0,
3582
+ language: selectedLanguage
3575
3583
  });
3576
3584
  onAccept == null ? void 0 : onAccept();
3577
3585
  hasSubmittedRef.current = false;
@@ -3594,6 +3602,7 @@ var RedactoConsentInlineComponent = ({
3594
3602
  selectedDataElements,
3595
3603
  selectedPurposes,
3596
3604
  applicationId,
3605
+ selectedLanguage,
3597
3606
  onAccept
3598
3607
  ]
3599
3608
  );
@@ -14133,7 +14133,8 @@ function purposeItemToUserConsent(purpose, group) {
14133
14133
  product_uuid: group.product_uuid,
14134
14134
  product_name: group.product_name,
14135
14135
  product_description: group.product_description,
14136
- nominator_info: (_d = group.nominator) != null ? _d : void 0
14136
+ nominator_info: (_d = group.nominator) != null ? _d : void 0,
14137
+ notice_uuid: purpose.notice_uuid
14137
14138
  };
14138
14139
  }
14139
14140
  function getDisplayProductGroups(detail, tab) {
@@ -14211,7 +14212,7 @@ var ConsentStatusEnum = /* @__PURE__ */ ((ConsentStatusEnum2) => {
14211
14212
  return ConsentStatusEnum2;
14212
14213
  })(ConsentStatusEnum || {});
14213
14214
 
14214
- // src/RedactoPrivacyCenter/lib/constants.ts
14215
+ // src/shared/languages.ts
14215
14216
  var languageOptions = [
14216
14217
  { value: "en", label: "English" },
14217
14218
  { value: "hi", label: "\u0939\u093F\u0928\u094D\u0926\u0940 (Hindi)" },
@@ -14237,6 +14238,10 @@ var languageOptions = [
14237
14238
  { value: "ks", label: "\u0643\u0672\u0634\u064F\u0631 (Kashmiri)" },
14238
14239
  { value: "sat", label: "\u1C65\u1C5F\u1C71\u1C5B\u1C5F\u1C72\u1C64 (Santali)" }
14239
14240
  ];
14241
+ var codeByLabel = new Map(languageOptions.map((o) => [o.label, o.value]));
14242
+ var codeByLower = new Map(languageOptions.map((o) => [o.value.toLowerCase(), o.value]));
14243
+
14244
+ // src/RedactoPrivacyCenter/lib/constants.ts
14240
14245
  var PAGE_CHROME_BY_PAGE = {
14241
14246
  home: {
14242
14247
  titleKey: "privacyCenter",
@@ -14315,6 +14320,7 @@ var useTimePeriodOptions = () => {
14315
14320
  };
14316
14321
  var MAX_DISPLAYED_PURPOSE_NAMES_IN_ERASURE_MODAL = 3;
14317
14322
  var SEARCH_DEBOUNCE_DELAY = 500;
14323
+ var FORM_PICKER_GROUP_LIMIT = 100;
14318
14324
  var POLL_INTERVAL = 3e4;
14319
14325
  var NOTIFICATION_PAGE_SIZE = 10;
14320
14326
  var TAB_TO_CATEGORY = {
@@ -16271,6 +16277,41 @@ var styles32 = import_react_native43.StyleSheet.create({
16271
16277
 
16272
16278
  // src/RedactoPrivacyCenter/components/groupHelpers.ts
16273
16279
  var productGroupKey = (group) => group.nominator ? `${group.product_uuid}:${group.nominator.uuid}` : group.product_uuid;
16280
+ var consentGroupToFormProductGroup = (group) => {
16281
+ var _a3;
16282
+ return {
16283
+ product_uuid: group.product_uuid,
16284
+ product_name: group.product_name,
16285
+ product_description: group.product_description,
16286
+ nominator: group.nominator,
16287
+ purposes: ((_a3 = group.purposes) != null ? _a3 : []).map(purposeItemToFormPurpose)
16288
+ };
16289
+ };
16290
+ var purposeItemToFormPurpose = (purpose) => {
16291
+ var _a3, _b;
16292
+ return {
16293
+ uuid: purpose.purpose_uuid,
16294
+ purpose_uuid: purpose.purpose_uuid,
16295
+ name: purpose.name,
16296
+ description: (_a3 = purpose.description) != null ? _a3 : "",
16297
+ industries: "",
16298
+ selected: false,
16299
+ given_consent: false,
16300
+ status: purpose.status,
16301
+ validity: null,
16302
+ enabled: true,
16303
+ data_elements: ((_b = purpose.data_elements) != null ? _b : []).map(consentDataElementToFormDataElement)
16304
+ };
16305
+ };
16306
+ var consentDataElementToFormDataElement = (element) => ({
16307
+ uuid: element.uuid,
16308
+ name: element.name,
16309
+ description: "",
16310
+ enabled: element.enabled,
16311
+ required: element.required,
16312
+ given_consent: element.selected,
16313
+ selected: element.selected
16314
+ });
16274
16315
  var buildGroupPurposes = (group) => group.purposes.filter((p) => p !== null && p !== void 0).map((p) => {
16275
16316
  const validDataElements = Array.isArray(p.data_elements) ? p.data_elements.filter((de) => de !== null && de !== void 0 && Boolean(de.uuid)).map((de) => ({ ...de, selected: false })) : [];
16276
16317
  return {
@@ -16305,7 +16346,7 @@ var isProductScopedRequestType = (rt) => PRODUCT_SCOPED_REQUEST_TYPES.has(rt);
16305
16346
  function Form({ onCreateRequest }) {
16306
16347
  const { t } = (0, import_react_i18next16.useTranslation)();
16307
16348
  const { accessToken, refreshToken, email, organizationId, workspaceId, updateTokens, onError } = useAuth();
16308
- const { consentClient, baseUrl } = useBaseUrl();
16349
+ const { consentClient, baseUrl, ledgerBaseUrl } = useBaseUrl();
16309
16350
  const { colors } = useTheme();
16310
16351
  const requestTypeLabels = useRequestTypeLabels();
16311
16352
  const timePeriodOptions = useTimePeriodOptions();
@@ -16342,15 +16383,60 @@ function Form({ onCreateRequest }) {
16342
16383
  });
16343
16384
  const [uploadedDocs, setUploadedDocs] = (0, import_react29.useState)([]);
16344
16385
  const [isUploading, setIsUploading] = (0, import_react29.useState)(false);
16386
+ const withLedgerPickerGroups = (0, import_react29.useCallback)(
16387
+ async (form, language) => {
16388
+ var _a3, _b;
16389
+ if (!ledgerBaseUrl || !organizationId || !workspaceId) {
16390
+ return form;
16391
+ }
16392
+ const consents = await fetchUserConsents({
16393
+ organizationId,
16394
+ workspaceId,
16395
+ // No status filter: include every status (active / expired / withdrawn
16396
+ // / declined), matching Python form/data, so a DSAR can target products
16397
+ // the user no longer actively consents to.
16398
+ limit: FORM_PICKER_GROUP_LIMIT,
16399
+ nominatedLimit: FORM_PICKER_GROUP_LIMIT,
16400
+ language,
16401
+ authContext,
16402
+ consentClient
16403
+ });
16404
+ if (!consents) {
16405
+ return form;
16406
+ }
16407
+ return {
16408
+ ...form,
16409
+ direct_groups: ((_a3 = consents.direct) != null ? _a3 : []).map(consentGroupToFormProductGroup),
16410
+ nominated_groups: ((_b = consents.nominated) != null ? _b : []).map(consentGroupToFormProductGroup)
16411
+ };
16412
+ },
16413
+ [ledgerBaseUrl, organizationId, workspaceId, authContext, consentClient]
16414
+ );
16345
16415
  (0, import_react29.useEffect)(() => {
16346
16416
  if (!organizationId || !workspaceId || !contact) return;
16417
+ let isCancelled = false;
16347
16418
  setIsLoading(true);
16348
- getFormData(organizationId, workspaceId, contact, false, false, authContext, consentClient, langParam).then((data) => {
16349
- if (data) setFormDataResponse(data);
16419
+ getFormData(organizationId, workspaceId, contact, false, false, authContext, consentClient, langParam).then(async (data) => {
16420
+ if (!data) return;
16421
+ const withGroups = await withLedgerPickerGroups(data, langParam);
16422
+ if (!isCancelled) setFormDataResponse(withGroups);
16350
16423
  }).catch((error) => {
16351
16424
  console.warn("Error fetching form data:", error);
16352
- }).finally(() => setIsLoading(false));
16353
- }, [organizationId, workspaceId, contact, authContext, consentClient, langParam]);
16425
+ }).finally(() => {
16426
+ if (!isCancelled) setIsLoading(false);
16427
+ });
16428
+ return () => {
16429
+ isCancelled = true;
16430
+ };
16431
+ }, [
16432
+ organizationId,
16433
+ workspaceId,
16434
+ contact,
16435
+ authContext,
16436
+ consentClient,
16437
+ langParam,
16438
+ withLedgerPickerGroups
16439
+ ]);
16354
16440
  const allGroups = (0, import_react29.useMemo)(() => {
16355
16441
  var _a3, _b;
16356
16442
  if (!formDataResponse) return [];
@@ -1,6 +1,7 @@
1
1
  import {
2
- __require
3
- } from "./chunk-Y6FXYEAI.mjs";
2
+ __require,
3
+ languageOptions
4
+ } from "./chunk-IVOOB4JK.mjs";
4
5
 
5
6
  // src/RedactoPrivacyCenter/RedactoPrivacyCenter.tsx
6
7
  import { useEffect as useEffect20 } from "react";
@@ -14142,7 +14143,8 @@ function purposeItemToUserConsent(purpose, group) {
14142
14143
  product_uuid: group.product_uuid,
14143
14144
  product_name: group.product_name,
14144
14145
  product_description: group.product_description,
14145
- nominator_info: (_d = group.nominator) != null ? _d : void 0
14146
+ nominator_info: (_d = group.nominator) != null ? _d : void 0,
14147
+ notice_uuid: purpose.notice_uuid
14146
14148
  };
14147
14149
  }
14148
14150
  function getDisplayProductGroups(detail, tab) {
@@ -14221,31 +14223,6 @@ var ConsentStatusEnum = /* @__PURE__ */ ((ConsentStatusEnum2) => {
14221
14223
  })(ConsentStatusEnum || {});
14222
14224
 
14223
14225
  // src/RedactoPrivacyCenter/lib/constants.ts
14224
- var languageOptions = [
14225
- { value: "en", label: "English" },
14226
- { value: "hi", label: "\u0939\u093F\u0928\u094D\u0926\u0940 (Hindi)" },
14227
- { value: "te", label: "\u0C24\u0C46\u0C32\u0C41\u0C17\u0C41 (Telugu)" },
14228
- { value: "mr", label: "\u092E\u0930\u093E\u0920\u0940 (Marathi)" },
14229
- { value: "ta", label: "\u0BA4\u0BAE\u0BBF\u0BB4\u0BCD (Tamil)" },
14230
- { value: "ur", label: "\u0627\u0631\u062F\u0648 (Urdu)" },
14231
- { value: "gu", label: "\u0A97\u0AC1\u0A9C\u0AB0\u0ABE\u0AA4\u0AC0 (Gujarati)" },
14232
- { value: "kn", label: "\u0C95\u0CA8\u0CCD\u0CA8\u0CA1 (Kannada)" },
14233
- { value: "ml", label: "\u0D2E\u0D32\u0D2F\u0D3E\u0D33\u0D02 (Malayalam)" },
14234
- { value: "pa", label: "\u0A2A\u0A70\u0A1C\u0A3E\u0A2C\u0A40 (Punjabi)" },
14235
- { value: "or", label: "\u0B13\u0B21\u0B3C\u0B3F\u0B06 (Odia)" },
14236
- { value: "as", label: "\u0985\u09B8\u09AE\u09C0\u09AF\u09BC\u09BE (Assamese)" },
14237
- { value: "bn", label: "\u09AC\u09BE\u0982\u09B2\u09BE (Bengali)" },
14238
- { value: "mai", label: "\u092E\u0948\u0925\u093F\u0932\u0940 (Maithili)" },
14239
- { value: "ne", label: "\u0928\u0947\u092A\u093E\u0932\u0940 (Nepali)" },
14240
- { value: "sd", label: "\u0633\u0646\u068C\u064A (Sindhi)" },
14241
- { value: "doi", label: "\u0921\u094B\u0917\u0930\u0940 (Dogri)" },
14242
- { value: "mni-Mtei", label: "\uABC3\uABE9\uABC7\uABE9\uABC2\uABE3\uABDF (Manipuri)" },
14243
- { value: "gom", label: "\u0915\u094B\u0902\u0915\u0923\u0940 (Goan Konkani)" },
14244
- { value: "sa", label: "\u0938\u0902\u0938\u094D\u0915\u0943\u0924\u092E\u094D (Sanskrit)" },
14245
- { value: "brx", label: "\u092C\u0921\u093C\u094B (Bodo)" },
14246
- { value: "ks", label: "\u0643\u0672\u0634\u064F\u0631 (Kashmiri)" },
14247
- { value: "sat", label: "\u1C65\u1C5F\u1C71\u1C5B\u1C5F\u1C72\u1C64 (Santali)" }
14248
- ];
14249
14226
  var PAGE_CHROME_BY_PAGE = {
14250
14227
  home: {
14251
14228
  titleKey: "privacyCenter",
@@ -14324,6 +14301,7 @@ var useTimePeriodOptions = () => {
14324
14301
  };
14325
14302
  var MAX_DISPLAYED_PURPOSE_NAMES_IN_ERASURE_MODAL = 3;
14326
14303
  var SEARCH_DEBOUNCE_DELAY = 500;
14304
+ var FORM_PICKER_GROUP_LIMIT = 100;
14327
14305
  var POLL_INTERVAL = 3e4;
14328
14306
  var NOTIFICATION_PAGE_SIZE = 10;
14329
14307
  var TAB_TO_CATEGORY = {
@@ -16303,6 +16281,41 @@ var styles32 = StyleSheet33.create({
16303
16281
 
16304
16282
  // src/RedactoPrivacyCenter/components/groupHelpers.ts
16305
16283
  var productGroupKey = (group) => group.nominator ? `${group.product_uuid}:${group.nominator.uuid}` : group.product_uuid;
16284
+ var consentGroupToFormProductGroup = (group) => {
16285
+ var _a3;
16286
+ return {
16287
+ product_uuid: group.product_uuid,
16288
+ product_name: group.product_name,
16289
+ product_description: group.product_description,
16290
+ nominator: group.nominator,
16291
+ purposes: ((_a3 = group.purposes) != null ? _a3 : []).map(purposeItemToFormPurpose)
16292
+ };
16293
+ };
16294
+ var purposeItemToFormPurpose = (purpose) => {
16295
+ var _a3, _b;
16296
+ return {
16297
+ uuid: purpose.purpose_uuid,
16298
+ purpose_uuid: purpose.purpose_uuid,
16299
+ name: purpose.name,
16300
+ description: (_a3 = purpose.description) != null ? _a3 : "",
16301
+ industries: "",
16302
+ selected: false,
16303
+ given_consent: false,
16304
+ status: purpose.status,
16305
+ validity: null,
16306
+ enabled: true,
16307
+ data_elements: ((_b = purpose.data_elements) != null ? _b : []).map(consentDataElementToFormDataElement)
16308
+ };
16309
+ };
16310
+ var consentDataElementToFormDataElement = (element) => ({
16311
+ uuid: element.uuid,
16312
+ name: element.name,
16313
+ description: "",
16314
+ enabled: element.enabled,
16315
+ required: element.required,
16316
+ given_consent: element.selected,
16317
+ selected: element.selected
16318
+ });
16306
16319
  var buildGroupPurposes = (group) => group.purposes.filter((p) => p !== null && p !== void 0).map((p) => {
16307
16320
  const validDataElements = Array.isArray(p.data_elements) ? p.data_elements.filter((de) => de !== null && de !== void 0 && Boolean(de.uuid)).map((de) => ({ ...de, selected: false })) : [];
16308
16321
  return {
@@ -16337,7 +16350,7 @@ var isProductScopedRequestType = (rt) => PRODUCT_SCOPED_REQUEST_TYPES.has(rt);
16337
16350
  function Form({ onCreateRequest }) {
16338
16351
  const { t } = useTranslation15();
16339
16352
  const { accessToken, refreshToken, email, organizationId, workspaceId, updateTokens, onError } = useAuth();
16340
- const { consentClient, baseUrl } = useBaseUrl();
16353
+ const { consentClient, baseUrl, ledgerBaseUrl } = useBaseUrl();
16341
16354
  const { colors } = useTheme();
16342
16355
  const requestTypeLabels = useRequestTypeLabels();
16343
16356
  const timePeriodOptions = useTimePeriodOptions();
@@ -16374,15 +16387,60 @@ function Form({ onCreateRequest }) {
16374
16387
  });
16375
16388
  const [uploadedDocs, setUploadedDocs] = useState16([]);
16376
16389
  const [isUploading, setIsUploading] = useState16(false);
16390
+ const withLedgerPickerGroups = useCallback10(
16391
+ async (form, language) => {
16392
+ var _a3, _b;
16393
+ if (!ledgerBaseUrl || !organizationId || !workspaceId) {
16394
+ return form;
16395
+ }
16396
+ const consents = await fetchUserConsents({
16397
+ organizationId,
16398
+ workspaceId,
16399
+ // No status filter: include every status (active / expired / withdrawn
16400
+ // / declined), matching Python form/data, so a DSAR can target products
16401
+ // the user no longer actively consents to.
16402
+ limit: FORM_PICKER_GROUP_LIMIT,
16403
+ nominatedLimit: FORM_PICKER_GROUP_LIMIT,
16404
+ language,
16405
+ authContext,
16406
+ consentClient
16407
+ });
16408
+ if (!consents) {
16409
+ return form;
16410
+ }
16411
+ return {
16412
+ ...form,
16413
+ direct_groups: ((_a3 = consents.direct) != null ? _a3 : []).map(consentGroupToFormProductGroup),
16414
+ nominated_groups: ((_b = consents.nominated) != null ? _b : []).map(consentGroupToFormProductGroup)
16415
+ };
16416
+ },
16417
+ [ledgerBaseUrl, organizationId, workspaceId, authContext, consentClient]
16418
+ );
16377
16419
  useEffect14(() => {
16378
16420
  if (!organizationId || !workspaceId || !contact) return;
16421
+ let isCancelled = false;
16379
16422
  setIsLoading(true);
16380
- getFormData(organizationId, workspaceId, contact, false, false, authContext, consentClient, langParam).then((data) => {
16381
- if (data) setFormDataResponse(data);
16423
+ getFormData(organizationId, workspaceId, contact, false, false, authContext, consentClient, langParam).then(async (data) => {
16424
+ if (!data) return;
16425
+ const withGroups = await withLedgerPickerGroups(data, langParam);
16426
+ if (!isCancelled) setFormDataResponse(withGroups);
16382
16427
  }).catch((error) => {
16383
16428
  console.warn("Error fetching form data:", error);
16384
- }).finally(() => setIsLoading(false));
16385
- }, [organizationId, workspaceId, contact, authContext, consentClient, langParam]);
16429
+ }).finally(() => {
16430
+ if (!isCancelled) setIsLoading(false);
16431
+ });
16432
+ return () => {
16433
+ isCancelled = true;
16434
+ };
16435
+ }, [
16436
+ organizationId,
16437
+ workspaceId,
16438
+ contact,
16439
+ authContext,
16440
+ consentClient,
16441
+ langParam,
16442
+ withLedgerPickerGroups
16443
+ ]);
16386
16444
  const allGroups = useMemo14(() => {
16387
16445
  var _a3, _b;
16388
16446
  if (!formDataResponse) return [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redacto.io/consent-sdk-react-native",
3
- "version": "5.0.0-beta.0",
3
+ "version": "5.0.0-beta.2",
4
4
  "description": "React Native SDK for integrating Redacto consent notices and privacy center in mobile apps.",
5
5
  "keywords": [
6
6
  "consent",
@@ -1,10 +0,0 @@
1
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
- }) : x)(function(x) {
4
- if (typeof require !== "undefined") return require.apply(this, arguments);
5
- throw Error('Dynamic require of "' + x + '" is not supported');
6
- });
7
-
8
- export {
9
- __require
10
- };