@redacto.io/consent-sdk-react 9.2.0-beta.0 → 9.2.0-beta.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 (51) hide show
  1. package/.turbo/turbo-build.log +15 -10
  2. package/CHANGELOG.md +6 -0
  3. package/dist/privacy-center.d.mts +56 -2
  4. package/dist/privacy-center.d.ts +56 -2
  5. package/dist/privacy-center.js +4213 -1256
  6. package/dist/privacy-center.mjs +4030 -1073
  7. package/package.json +1 -1
  8. package/src/RedactoPrivacyCenter/PrivacyCenterHomePage.tsx +3 -0
  9. package/src/RedactoPrivacyCenter/PrivacyCenterMyReceiptPage.tsx +26 -0
  10. package/src/RedactoPrivacyCenter/api/actions.ts +66 -0
  11. package/src/RedactoPrivacyCenter/api/client.ts +79 -0
  12. package/src/RedactoPrivacyCenter/components/DataRequest/ProductSelectionSection.tsx +222 -0
  13. package/src/RedactoPrivacyCenter/components/Form.tsx +828 -33
  14. package/src/RedactoPrivacyCenter/components/ReceiptsList.tsx +492 -0
  15. package/src/RedactoPrivacyCenter/components/RequestSubmit.tsx +284 -71
  16. package/src/RedactoPrivacyCenter/components/SideMenuBarPC/constants.tsx +6 -1
  17. package/src/RedactoPrivacyCenter/components/groupHelpers.ts +56 -0
  18. package/src/RedactoPrivacyCenter/components/receiptColumns.tsx +203 -0
  19. package/src/RedactoPrivacyCenter/components/types.ts +26 -2
  20. package/src/RedactoPrivacyCenter/context/NavigationContext.tsx +2 -2
  21. package/src/RedactoPrivacyCenter/lib/api.ts +95 -1
  22. package/src/RedactoPrivacyCenter/lib/constants.ts +5 -0
  23. package/src/RedactoPrivacyCenter/lib/types.ts +105 -0
  24. package/src/RedactoPrivacyCenter/locales/as/translation.json +39 -1
  25. package/src/RedactoPrivacyCenter/locales/bho/translation.json +39 -1
  26. package/src/RedactoPrivacyCenter/locales/bn/translation.json +39 -1
  27. package/src/RedactoPrivacyCenter/locales/brx/translation.json +39 -1
  28. package/src/RedactoPrivacyCenter/locales/doi/translation.json +39 -1
  29. package/src/RedactoPrivacyCenter/locales/en/translation.json +44 -1
  30. package/src/RedactoPrivacyCenter/locales/gom/translation.json +39 -1
  31. package/src/RedactoPrivacyCenter/locales/gu/translation.json +39 -1
  32. package/src/RedactoPrivacyCenter/locales/hi/translation.json +39 -1
  33. package/src/RedactoPrivacyCenter/locales/kn/translation.json +39 -1
  34. package/src/RedactoPrivacyCenter/locales/ks/translation.json +39 -1
  35. package/src/RedactoPrivacyCenter/locales/mai/translation.json +39 -1
  36. package/src/RedactoPrivacyCenter/locales/ml/translation.json +39 -1
  37. package/src/RedactoPrivacyCenter/locales/mni-Mtei/translation.json +39 -1
  38. package/src/RedactoPrivacyCenter/locales/mr/translation.json +39 -1
  39. package/src/RedactoPrivacyCenter/locales/ne/translation.json +39 -1
  40. package/src/RedactoPrivacyCenter/locales/or/translation.json +39 -1
  41. package/src/RedactoPrivacyCenter/locales/pa/translation.json +39 -1
  42. package/src/RedactoPrivacyCenter/locales/sa/translation.json +39 -1
  43. package/src/RedactoPrivacyCenter/locales/sat/translation.json +39 -1
  44. package/src/RedactoPrivacyCenter/locales/sd/translation.json +39 -1
  45. package/src/RedactoPrivacyCenter/locales/ta/translation.json +39 -1
  46. package/src/RedactoPrivacyCenter/locales/te/translation.json +39 -1
  47. package/src/RedactoPrivacyCenter/locales/ur/translation.json +39 -1
  48. package/src/RedactoPrivacyCenter/styles/injectStyles.ts +301 -0
  49. package/tests/Form.test.tsx +1170 -0
  50. package/tests/ProductSelectionSection.test.tsx +293 -0
  51. package/tests/RequestSubmit.test.tsx +295 -0
@@ -1,5 +1,9 @@
1
1
  import type { ReactNode } from 'react';
2
- import type { CaseRequest, ConsentModalRecord } from '../lib/types';
2
+ import type {
3
+ BatchCaseSubmitResult,
4
+ CaseRequest,
5
+ ConsentModalRecord,
6
+ } from '../lib/types';
3
7
 
4
8
  export type TableColumnAlign = 'left' | 'center' | 'right';
5
9
 
@@ -26,10 +30,30 @@ export type CaseDetailsModalProps = {
26
30
  selectedCase: CaseRequest | null;
27
31
  };
28
32
 
33
+ /**
34
+ * P2-SDK-4 of TECH-3712. `RequestSubmit` is invoked from two paths:
35
+ *
36
+ * 1. The grouped DSAR batch path, where `result.succeeded` lists every
37
+ * case_id created (one per product-group), `result.failed` lists
38
+ * per-group failures, and `onRetry(groupKey)` re-issues a single
39
+ * POST for the one group the user clicks retry on.
40
+ * 2. The legacy single-case path (nomination / grievance / non-grouped
41
+ * fallback), which wraps its lone response into a synthetic
42
+ * `BatchCaseSubmitResult` with one `succeeded` entry and an empty
43
+ * `failed` list. The same UI logic renders both shapes.
44
+ *
45
+ * Retry is keyed by `group_key` (productGroupKey on the source group),
46
+ * NOT `product_uuid`, so that a product picked both directly AND via a
47
+ * nominator can be retried independently. `retryingGroupKeys` lets the
48
+ * parent indicate which rows are currently mid-retry (button shows the
49
+ * retrying spinner copy and is disabled).
50
+ */
29
51
  export type RequestSubmitProps = Readonly<{
30
- caseId: string;
52
+ result: BatchCaseSubmitResult;
31
53
  contact: string;
32
54
  onCreateRequest: () => void;
55
+ onRetry?: (groupKey: string) => void;
56
+ retryingGroupKeys?: ReadonlySet<string>;
33
57
  revokeConsentOnFulfilment?: boolean;
34
58
  revokedPurposeNames?: string;
35
59
  }>;
@@ -1,13 +1,13 @@
1
1
  import { createContext, useContext, useState, useCallback, type ReactNode } from 'react';
2
2
  import type { CaseRequest } from '../lib/types';
3
3
 
4
- export type InternalPage = 'consent-manager' | 'form' | 'activity' | 'case-details' | 'notifications';
4
+ export type InternalPage = 'consent-manager' | 'form' | 'activity' | 'case-details' | 'notifications' | 'receipts';
5
5
 
6
6
  const NAV_STORAGE_KEY = 'pc_current_page';
7
7
  const CASE_UUID_STORAGE_KEY = 'pc_selected_case_uuid';
8
8
 
9
9
  const VALID_PAGES: ReadonlySet<string> = new Set<InternalPage>([
10
- 'consent-manager', 'form', 'activity', 'case-details', 'notifications',
10
+ 'consent-manager', 'form', 'activity', 'case-details', 'notifications', 'receipts',
11
11
  ]);
12
12
 
13
13
  function getStoredPage(fallback: InternalPage): InternalPage {
@@ -1,6 +1,8 @@
1
1
  import {
2
2
  createCaseRequestServer,
3
3
  fetchActivitiesServer,
4
+ fetchReceiptsServer,
5
+ fetchReceiptPdfServer,
4
6
  fetchCaseHistoryServer,
5
7
  fetchProductsServer,
6
8
  fetchUserConsentsServer,
@@ -36,6 +38,8 @@ import type {
36
38
  UserConsentDetail,
37
39
  UserDataRequest,
38
40
  GroupPurposesOut,
41
+ ReceiptEventType,
42
+ ReceiptPurposeStatus,
39
43
  } from './types';
40
44
  import { ensureValidToken } from './utils';
41
45
 
@@ -169,7 +173,18 @@ export const getFormData = async (
169
173
  }
170
174
  };
171
175
 
172
- export const createCaseRequest = async (
176
+ /**
177
+ * Internal-only variant of `createCaseRequest` that THROWS on non-auth
178
+ * errors so callers can read the backend's `[status] message` (e.g.
179
+ * `[400] invalid_data_principal`). Used by the multi-product batch path
180
+ * in Form.tsx, where `Promise.allSettled` aggregates rich errors into
181
+ * the per-row `failed[].error` field.
182
+ *
183
+ * NOT exported at the package boundary (`privacy-center.ts`) — public
184
+ * consumers should use `createCaseRequest` below, which preserves the
185
+ * documented `Promise<CreateCaseResponse | null>` contract.
186
+ */
187
+ export const createCaseRequestUnsafe = async (
173
188
  organizationId: string,
174
189
  workspaceId: string,
175
190
  data: UserDataRequest,
@@ -213,6 +228,46 @@ export const createCaseRequest = async (
213
228
  consentClient
214
229
  );
215
230
  }
231
+ // P2-SDK-3/4 of TECH-3712. Rethrow non-auth errors so the batch path's
232
+ // `Promise.allSettled` can surface the backend's `[status] message` to
233
+ // the data principal (e.g. `[400] invalid_data_principal`) via the
234
+ // `failed[].error` field.
235
+ console.error('Error creating case request:', error);
236
+ throw error;
237
+ }
238
+ };
239
+
240
+ /**
241
+ * Public helper for creating a case request. Returns `null` on error
242
+ * (preserves the original `Promise<CreateCaseResponse | null>` contract
243
+ * the SDK exposes to consumers) — does NOT throw. Internally wraps
244
+ * `createCaseRequestUnsafe` and swallows non-auth errors.
245
+ *
246
+ * The batch-submission path in Form.tsx uses `createCaseRequestUnsafe`
247
+ * directly so partial-failure UI can surface per-row backend messages;
248
+ * everywhere else (including the legacy single-case path) should use
249
+ * this helper.
250
+ */
251
+ export const createCaseRequest = async (
252
+ organizationId: string,
253
+ workspaceId: string,
254
+ data: UserDataRequest,
255
+ isPopup?: boolean,
256
+ useSessionAuth?: boolean,
257
+ authContext?: AuthContext,
258
+ consentClient?: BaseUrlContextValue['consentClient']
259
+ ): Promise<CreateCaseResponse | null> => {
260
+ try {
261
+ return await createCaseRequestUnsafe(
262
+ organizationId,
263
+ workspaceId,
264
+ data,
265
+ isPopup,
266
+ useSessionAuth,
267
+ authContext,
268
+ consentClient,
269
+ );
270
+ } catch (error) {
216
271
  console.error('Error creating case request:', error);
217
272
  return null;
218
273
  }
@@ -622,6 +677,45 @@ export const getCaseDocument = async (
622
677
  getCaseDocumentServer({ organizationId, workspaceId, caseUuid, documentUuid, authToken: token, consentClient })
623
678
  );
624
679
 
680
+ // ─── Receipts ────────────────────────────────────────────────────────────────
681
+
682
+ export type FetchReceiptsParams = {
683
+ skip?: number;
684
+ limit?: number;
685
+ notice_uuid?: string;
686
+ event_type?: ReceiptEventType;
687
+ status?: ReceiptPurposeStatus;
688
+ created_after?: string;
689
+ created_before?: string;
690
+ language?: string;
691
+ };
692
+
693
+ export const fetchReceipts = async (
694
+ organizationId: string,
695
+ workspaceId: string,
696
+ params?: FetchReceiptsParams,
697
+ authContext?: AuthContext,
698
+ consentClient?: BaseUrlContextValue['consentClient'],
699
+ ): Promise<unknown | null> =>
700
+ withAuthRetry(organizationId, workspaceId, authContext, consentClient, 'Error fetching receipts:', (token) =>
701
+ fetchReceiptsServer({ organizationId, workspaceId, ...params, authToken: token, consentClient })
702
+ );
703
+
704
+ /**
705
+ * Download a single receipt as a PDF Blob. The UI builds an object URL from the
706
+ * Blob to open/save it (PDF UI is a later pass; the SDK function is ready now).
707
+ */
708
+ export const fetchReceiptPdf = async (
709
+ organizationId: string,
710
+ workspaceId: string,
711
+ receiptUuid: string,
712
+ authContext?: AuthContext,
713
+ consentClient?: BaseUrlContextValue['consentClient'],
714
+ ): Promise<Blob | null> =>
715
+ withAuthRetry(organizationId, workspaceId, authContext, consentClient, 'Error downloading receipt PDF:', (token) =>
716
+ fetchReceiptPdfServer({ organizationId, workspaceId, receiptUuid, authToken: token, consentClient })
717
+ );
718
+
625
719
  // ─── Notification Hub ───────────────────────────────────────────────────────
626
720
 
627
721
  export const fetchNotifications = async (
@@ -94,12 +94,17 @@ export const PAGE_CHROME_BY_PAGE: Record<InternalPage, PageChromeConfig> = {
94
94
  titleKey: 'notificationHub',
95
95
  descriptionKey: 'notificationHubSubtitle',
96
96
  },
97
+ receipts: {
98
+ titleKey: 'myReceipt',
99
+ descriptionKey: 'myReceiptSubtitle',
100
+ },
97
101
  };
98
102
 
99
103
  const HREF_TO_NAME_KEY: Record<string, string> = {
100
104
  'consent-manager': 'consentManager',
101
105
  form: 'grievance',
102
106
  activity: 'activity',
107
+ receipts: 'myReceipt',
103
108
  };
104
109
 
105
110
  export const useMenuItemsPC = (): MenuItem[] => {
@@ -87,12 +87,42 @@ export type GrievanceOptions = {
87
87
  label: string;
88
88
  };
89
89
 
90
+ /**
91
+ * Product-scoped form-data group.
92
+ *
93
+ * Phase 2 of TECH-3712. Mirrors the backend `FormProductGroupOut`. Used to
94
+ * render per-product sections inside the privacy-center form. `nominator`
95
+ * is populated on nominated groups and `null` on direct (own-data) groups.
96
+ */
97
+ export type FormProductGroup = {
98
+ product_uuid: string;
99
+ product_name: string;
100
+ product_description: string | null;
101
+ nominator: NominatorInfo | null;
102
+ // Bare `Purpose[]` — matches the backend `FormProductGroupOut.purposes`
103
+ // contract (`List[PurposeConsentFormOut]`). The legacy `FormData.purposes`
104
+ // field below remains wrapped (`RawPurposeWrapper[]`) for back-compat.
105
+ purposes: Purpose[];
106
+ };
107
+
90
108
  export type FormData = {
91
109
  uuid: string;
92
110
  name: string;
93
111
  contact: string;
94
112
  grievance_options: GrievanceOptions[];
113
+ // Legacy flat list, retained for backwards compatibility with older SDK
114
+ // consumers. The backend continues to populate this alongside the grouped
115
+ // fields below.
95
116
  purposes: RawPurposeWrapper[];
117
+ // Phase 2 of TECH-3712. Product-grouped purposes for the data principal's
118
+ // own consents. Empty array when the backend has no direct groups to emit.
119
+ // Optional so legacy backends (pre-Phase 1) typecheck — the runtime
120
+ // grouped-render guard already handles the absent case.
121
+ direct_groups?: FormProductGroup[];
122
+ // Phase 2 of TECH-3712. Product-grouped purposes the data principal can
123
+ // act on as a nominee. Empty array when there are no nominator grants.
124
+ // Optional for the same backwards-compatibility reason as `direct_groups`.
125
+ nominated_groups?: FormProductGroup[];
96
126
  };
97
127
 
98
128
  export type FormDataResponse = {
@@ -156,6 +186,13 @@ export type UserDataRequest = {
156
186
  time_period: number | null;
157
187
  requestor_note: string;
158
188
  revoke_consent_on_fulfilment?: boolean;
189
+ // Phase 2 of TECH-3712. Optional product anchor for the case. When set,
190
+ // the case is created against the (product, optional nominator) consent
191
+ // group; when omitted, the case is created as a legacy org-level case.
192
+ product_uuid?: string;
193
+ // Phase 2 of TECH-3712. Optional data-principal anchor used when the
194
+ // requestor is acting on behalf of a nominator. Omit for direct cases.
195
+ data_principal_uuid?: string;
159
196
  };
160
197
 
161
198
  export type CreateCaseResponse = {
@@ -167,6 +204,37 @@ export type CreateCaseResponse = {
167
204
  };
168
205
  };
169
206
 
207
+ /**
208
+ * Aggregated result of submitting one case per product in a multi-product
209
+ * form submission.
210
+ *
211
+ * Phase 2 of TECH-3712. The backend has no batch endpoint; the SDK Form
212
+ * fans `createCaseRequest` calls out via `Promise.allSettled` and the
213
+ * consumer (P2-SDK-3) aggregates the outcomes into this shape so the UI
214
+ * can render partial-success states clearly.
215
+ *
216
+ * `group_key` is the stable selection key for the source consent group
217
+ * (encodes `product_uuid` and, for nominated groups, the nominator uuid).
218
+ * Use it — not `product_uuid` — to address an entry for retry/update,
219
+ * since the same product can appear in both `succeeded` and `failed`
220
+ * when picked directly AND via a nominator.
221
+ */
222
+ export type BatchCaseSubmitResult = {
223
+ succeeded: Array<{
224
+ group_key: string;
225
+ product_uuid: string;
226
+ product_name: string;
227
+ case_id: string;
228
+ uuid: string;
229
+ }>;
230
+ failed: Array<{
231
+ group_key: string;
232
+ product_uuid: string;
233
+ product_name: string;
234
+ error: string;
235
+ }>;
236
+ };
237
+
170
238
  export type OtpResponse = {
171
239
  uuid: string;
172
240
  to: string;
@@ -350,6 +418,29 @@ export type ActivityDetail = {
350
418
  pagination: Pagination;
351
419
  };
352
420
 
421
+ // ─── Receipts ────────────────────────────────────────────────────────────────
422
+
423
+ export type ReceiptEventType = 'GRANTED' | 'WITHDRAWN' | 'DECLINED' | 'EXPIRED';
424
+ export type ReceiptPurposeStatus = 'CONSENTED' | 'DECLINED' | 'WITHDRAWN';
425
+
426
+ /**
427
+ * A single consent receipt row. The backend returns localized `*_display`
428
+ * fields alongside the raw enum/value — render the `*_display`, branch on the raw.
429
+ */
430
+ export type Receipt = {
431
+ uuid: string;
432
+ event_type: ReceiptEventType | string;
433
+ event_type_display?: string | null;
434
+ product_name?: string | null;
435
+ product_name_display?: string | null;
436
+ created_at: string;
437
+ };
438
+
439
+ export type ReceiptListResponse = {
440
+ data: Receipt[];
441
+ pagination: Pagination;
442
+ };
443
+
353
444
  export type ActivityResponse = {
354
445
  code: number;
355
446
  status: string;
@@ -383,6 +474,20 @@ export type CaseRequest = {
383
474
  completed_at?: string;
384
475
  due_date?: string;
385
476
  request_details?: CaseRequestDetails;
477
+ // Phase 2 of TECH-3712. Product anchor (when the case was created against
478
+ // a product consent group). Undefined for legacy org-level cases.
479
+ product_uuid?: string;
480
+ // Phase 2 of TECH-3712. Product display name hydrated by the console list
481
+ // endpoint. Undefined on legacy cases or when the product is not joinable.
482
+ product_name?: string;
483
+ // Phase 2 of TECH-3712. Data-principal anchor for nominee-driven cases.
484
+ data_principal_uuid?: string;
485
+ // Phase 2 of TECH-3712. UUID of the user who initiated the case (may be
486
+ // the data principal themselves or a nominee acting on their behalf).
487
+ requestor_uuid?: string;
488
+ // Phase 2 of TECH-3712. UUID of the nominator whose grant authorised the
489
+ // nominee to file this case. Undefined for direct cases.
490
+ nominator_uuid?: string;
386
491
  };
387
492
 
388
493
  export type RequestDetailsTabProps = {
@@ -1,4 +1,25 @@
1
1
  {
2
+ "consented": "সন্মতি দিয়া হ’ল",
3
+ "declined": "প্ৰত্যাখ্যান কৰা হ’ল",
4
+ "withdrawn": "প্ৰত্যাহাৰ কৰা হ’ল",
5
+ "dateRange": "তাৰিখৰ পৰিসৰ",
6
+ "allTime": "সকলো সময়",
7
+ "customRange": "নিজস্ব পৰিসৰ",
8
+ "from": "পৰা",
9
+ "to": "লৈ",
10
+ "clearFilters": "ফিল্টাৰ পৰিষ্কাৰ কৰক",
11
+ "myReceipt": "মোৰ ৰচিদ",
12
+ "myReceiptSubtitle": "আপোনাৰ সন্মতিৰ ৰচিদ চাওক",
13
+ "event": "ঘটনা",
14
+ "date": "তাৰিখ",
15
+ "time": "সময়",
16
+ "download": "ডাউনল'ড কৰক",
17
+ "consentGranted": "সন্মতি দিয়া হ’ল",
18
+ "consentRevoked": "সন্মতি প্ৰত্যাহাৰ কৰা হ’ল",
19
+ "consentDeclined": "সন্মতি প্ৰত্যাখ্যান কৰা হ’ল",
20
+ "consentExpired": "সন্মতিৰ ম্যাদ উকলিল",
21
+ "failedToFetchReceipts": "ৰচিদ আনিবলৈ ব্যৰ্থ",
22
+ "failedToDownloadReceipt": "ৰচিদ ডাউনল'ড কৰিবলৈ ব্যৰ্থ",
2
23
  "yourPrivacyCenter": "আপোনাৰ গোপনীয়তা কেন্দ্ৰ",
3
24
  "yourRightsOverDataSimplified": "আপোনাৰ ডেটাত আপোনাৰ অধিকাৰ, সহজ ভাষাত",
4
25
  "description": "গোপনীয়তা আইনে আপোনাক আপোনাৰ তথ্য সংগ্ৰহ, ব্যৱহাৰ, শ্বেয়াৰ আৰু সংৰক্ষণ সন্দর্ভত কিছুমান অধিকাৰ প্ৰদান কৰে আৰু আমি সেই অধিকাৰ ব্যৱহাৰৰ বাবে আপোনাক স্বাগতম জনাইছো। অনুগ্ৰহ কৰি তলৰ ফৰ্মটো পূৰণ কৰক যাতে আমি আপোনাৰ অনুৰোধৰ প্ৰমাণীকৰণ কৰি প্ৰসেছ কৰিব পাৰোঁ। অধিক তথ্যৰ বাবে অনুগ্ৰহ কৰি আমাৰ গোপনীয়তা নীতি পঢ়ক।",
@@ -288,5 +309,22 @@
288
309
  "withdrawnWithCount": "{{count}} withdrawn",
289
310
  "expiredWithCount": "{{count}} expired",
290
311
  "declinedWithCount": "{{count}} declined",
291
- "productsAndConsentsSummary": "{{products}} products, {{consents}} consents"
312
+ "productsAndConsentsSummary": "{{products}} products, {{consents}} consents",
313
+ "selectProductsForRequest": "Select one or more products for your {{requestType}} request",
314
+ "selectProductsForRequestGeneric": "Select one or more products to continue",
315
+ "yourData": "Your data",
316
+ "actingOnBehalfOf": "Acting on behalf of {{nominator}}",
317
+ "activePurposes_one": "{{count}} active purpose",
318
+ "activePurposes_other": "{{count}} active purposes",
319
+ "autoSelected": "Auto-selected",
320
+ "noProductsAvailable": "No products available",
321
+ "noProductsAvailableDescription": "You have no consents to manage yet.",
322
+ "forProduct": "For {{productName}}",
323
+ "actingOnBehalfOfShort": "acting on behalf of {{nominator}}",
324
+ "selectPurposesForThisProduct": "Select purposes within this product.",
325
+ "casesCreatedCount_one": "{{count}} case created",
326
+ "casesCreatedCount_other": "{{count}} cases created",
327
+ "someRequestsFailed": "Some requests failed",
328
+ "retry": "Retry",
329
+ "retrying": "Retrying..."
292
330
  }
@@ -1,4 +1,25 @@
1
1
  {
2
+ "consented": "सहमति दिहल गइल",
3
+ "declined": "अस्वीकार कइल गइल",
4
+ "withdrawn": "वापस लिहल गइल",
5
+ "dateRange": "तारीख सीमा",
6
+ "allTime": "सब समय",
7
+ "customRange": "कस्टम सीमा",
8
+ "from": "से",
9
+ "to": "तक",
10
+ "clearFilters": "फिल्टर साफ करीं",
11
+ "myReceipt": "हमार रसीद",
12
+ "myReceiptSubtitle": "आपन सहमति के रसीद देखीं",
13
+ "event": "घटना",
14
+ "date": "तारीख",
15
+ "time": "समय",
16
+ "download": "डाउनलोड करीं",
17
+ "consentGranted": "सहमति दिहल गइल",
18
+ "consentRevoked": "सहमति वापस लिहल गइल",
19
+ "consentDeclined": "सहमति अस्वीकार कइल गइल",
20
+ "consentExpired": "सहमति के अवधि खतम",
21
+ "failedToFetchReceipts": "रसीद पावे में विफल",
22
+ "failedToDownloadReceipt": "रसीद डाउनलोड करे में विफल",
2
23
  "yourPrivacyCenter": "रउरा गोपनीयता केंद्र",
3
24
  "yourRightsOverDataSimplified": "रउरा डेटा पर अधिकार, सरल रूप में",
4
25
  "description": "एप्लिकेशन गोपनीयता कानून रउरा के कुछ अधिकार देला जवन हमनी के द्वारा रउरा जानकारी के संग्रह, उपयोग, साझा करे आ संग्रह करे से जुड़ल बा, आ हम रउरा के ई अधिकार के प्रयोग करे के स्वागत करिला। कृपया नीचे दिहल फॉर्म भर दीं ताकि हम रउरा अनुरोध के सत्यापित आ पूरा कर सकीं। अधिक जानकारी खातिर, कृपया हमार आंतरिक गोपनीयता नीति पढ़ीं।",
@@ -288,5 +309,22 @@
288
309
  "withdrawnWithCount": "{{count}} withdrawn",
289
310
  "expiredWithCount": "{{count}} expired",
290
311
  "declinedWithCount": "{{count}} declined",
291
- "productsAndConsentsSummary": "{{products}} products, {{consents}} consents"
312
+ "productsAndConsentsSummary": "{{products}} products, {{consents}} consents",
313
+ "selectProductsForRequest": "Select one or more products for your {{requestType}} request",
314
+ "selectProductsForRequestGeneric": "Select one or more products to continue",
315
+ "yourData": "Your data",
316
+ "actingOnBehalfOf": "Acting on behalf of {{nominator}}",
317
+ "activePurposes_one": "{{count}} active purpose",
318
+ "activePurposes_other": "{{count}} active purposes",
319
+ "autoSelected": "Auto-selected",
320
+ "noProductsAvailable": "No products available",
321
+ "noProductsAvailableDescription": "You have no consents to manage yet.",
322
+ "forProduct": "For {{productName}}",
323
+ "actingOnBehalfOfShort": "acting on behalf of {{nominator}}",
324
+ "selectPurposesForThisProduct": "Select purposes within this product.",
325
+ "casesCreatedCount_one": "{{count}} case created",
326
+ "casesCreatedCount_other": "{{count}} cases created",
327
+ "someRequestsFailed": "Some requests failed",
328
+ "retry": "Retry",
329
+ "retrying": "Retrying..."
292
330
  }
@@ -1,4 +1,25 @@
1
1
  {
2
+ "consented": "সম্মত",
3
+ "declined": "প্রত্যাখ্যাত",
4
+ "withdrawn": "প্রত্যাহৃত",
5
+ "dateRange": "তারিখের পরিসর",
6
+ "allTime": "সমস্ত সময়",
7
+ "customRange": "কাস্টম পরিসর",
8
+ "from": "থেকে",
9
+ "to": "পর্যন্ত",
10
+ "clearFilters": "ফিল্টার সাফ করুন",
11
+ "myReceipt": "আমার রসিদ",
12
+ "myReceiptSubtitle": "আপনার সম্মতির রসিদ দেখুন",
13
+ "event": "ইভেন্ট",
14
+ "date": "তারিখ",
15
+ "time": "সময়",
16
+ "download": "ডাউনলোড করুন",
17
+ "consentGranted": "সম্মতি দেওয়া হয়েছে",
18
+ "consentRevoked": "সম্মতি প্রত্যাহার করা হয়েছে",
19
+ "consentDeclined": "সম্মতি প্রত্যাখ্যাত",
20
+ "consentExpired": "সম্মতির মেয়াদ শেষ",
21
+ "failedToFetchReceipts": "রসিদ আনতে ব্যর্থ",
22
+ "failedToDownloadReceipt": "রসিদ ডাউনলোড করতে ব্যর্থ",
2
23
  "yourPrivacyCenter": "আপনার গোপনীয়তা কেন্দ্র",
3
24
  "yourRightsOverDataSimplified": "আপনার ডেটার উপর আপনার অধিকার, সরলীকৃত",
4
25
  "description": "অ্যাপ্লিকেশন গোপনীয়তা আইনগুলি আপনাকে আমাদের সংগ্রহ, ব্যবহার, ভাগ করে নেওয়া এবং আপনার তথ্য সংরক্ষণের ক্ষেত্রে কিছু অধিকার দেয় এবং আমরা সেই অধিকারগুলির আপনার অনুশীলনকে স্বাগত জানাই। অনুগ্রহ করে নীচের ফর্মটি পূরণ করুন যাতে আমরা আপনার অনুরোধ যাচাই করতে এবং পূরণ করতে পারি। আরো বিস্তারিত জানার জন্য, অনুগ্রহ করে আমাদের অভ্যন্তরীণ গোপনীয়তা নীতি পড়ুন",
@@ -288,5 +309,22 @@
288
309
  "withdrawnWithCount": "{{count}} withdrawn",
289
310
  "expiredWithCount": "{{count}} expired",
290
311
  "declinedWithCount": "{{count}} declined",
291
- "productsAndConsentsSummary": "{{products}} products, {{consents}} consents"
312
+ "productsAndConsentsSummary": "{{products}} products, {{consents}} consents",
313
+ "selectProductsForRequest": "Select one or more products for your {{requestType}} request",
314
+ "selectProductsForRequestGeneric": "Select one or more products to continue",
315
+ "yourData": "Your data",
316
+ "actingOnBehalfOf": "Acting on behalf of {{nominator}}",
317
+ "activePurposes_one": "{{count}} active purpose",
318
+ "activePurposes_other": "{{count}} active purposes",
319
+ "autoSelected": "Auto-selected",
320
+ "noProductsAvailable": "No products available",
321
+ "noProductsAvailableDescription": "You have no consents to manage yet.",
322
+ "forProduct": "For {{productName}}",
323
+ "actingOnBehalfOfShort": "acting on behalf of {{nominator}}",
324
+ "selectPurposesForThisProduct": "Select purposes within this product.",
325
+ "casesCreatedCount_one": "{{count}} case created",
326
+ "casesCreatedCount_other": "{{count}} cases created",
327
+ "someRequestsFailed": "Some requests failed",
328
+ "retry": "Retry",
329
+ "retrying": "Retrying..."
292
330
  }
@@ -1,4 +1,25 @@
1
1
  {
2
+ "consented": "सहमति होबाय",
3
+ "declined": "नेवबाय",
4
+ "withdrawn": "वापस लाबाय",
5
+ "dateRange": "तारिख सिमा",
6
+ "allTime": "गासै सम",
7
+ "customRange": "कस्टम सिमा",
8
+ "from": "निफ्राय",
9
+ "to": "सिम",
10
+ "clearFilters": "फिल्टार सावदिन खालाम",
11
+ "myReceipt": "आंनि रसिद",
12
+ "myReceiptSubtitle": "नोंथांनि सहमतिनि रसिदफोरखौ नाय",
13
+ "event": "जाथाय",
14
+ "date": "तारिख",
15
+ "time": "समाय",
16
+ "download": "डाउनलोड खालाम",
17
+ "consentGranted": "सहमति होबाय",
18
+ "consentRevoked": "सहमति वापस लाबाय",
19
+ "consentDeclined": "सहमति नेवबाय",
20
+ "consentExpired": "सहमतिनि समाय जोबाय",
21
+ "failedToFetchReceipts": "रसिदफोरखौ मोननो हायाखै",
22
+ "failedToDownloadReceipt": "रसिदखौ डाउनलोड खालामनो हायाखै",
2
23
  "yourPrivacyCenter": "नोंथांनि गोपनारि केन्द्र",
3
24
  "yourRightsOverDataSimplified": "नोंथांनि डाटा उपरि नोंथांनि अधिकार, सहजाव",
4
25
  "description": "एप्लिकेसन गोपनारि नायजाथायफोर नोंथांनि गोजौनि मोनसेखौ होनाय, बाहायनाय, सोलायनाय आरो थाखायनायनि बाबदआव किछु अधिकार होनायो, आरो नोंथांनि बे अधिकार बाहायनायखौ जों स्वागतम खालामो। मेहरबानि खालामनाय, गाहायनि फर्मखौ भराय, जाहाथे जों नोंथांनि अरजिखौ जाथाय आरो फुरायनो पारगोन। गोबां बिथोननि थाखाय, जोंनि इन्टारनाल गोपनारि नितिखौ फराय।",
@@ -288,5 +309,22 @@
288
309
  "withdrawnWithCount": "{{count}} withdrawn",
289
310
  "expiredWithCount": "{{count}} expired",
290
311
  "declinedWithCount": "{{count}} declined",
291
- "productsAndConsentsSummary": "{{products}} products, {{consents}} consents"
312
+ "productsAndConsentsSummary": "{{products}} products, {{consents}} consents",
313
+ "selectProductsForRequest": "Select one or more products for your {{requestType}} request",
314
+ "selectProductsForRequestGeneric": "Select one or more products to continue",
315
+ "yourData": "Your data",
316
+ "actingOnBehalfOf": "Acting on behalf of {{nominator}}",
317
+ "activePurposes_one": "{{count}} active purpose",
318
+ "activePurposes_other": "{{count}} active purposes",
319
+ "autoSelected": "Auto-selected",
320
+ "noProductsAvailable": "No products available",
321
+ "noProductsAvailableDescription": "You have no consents to manage yet.",
322
+ "forProduct": "For {{productName}}",
323
+ "actingOnBehalfOfShort": "acting on behalf of {{nominator}}",
324
+ "selectPurposesForThisProduct": "Select purposes within this product.",
325
+ "casesCreatedCount_one": "{{count}} case created",
326
+ "casesCreatedCount_other": "{{count}} cases created",
327
+ "someRequestsFailed": "Some requests failed",
328
+ "retry": "Retry",
329
+ "retrying": "Retrying..."
292
330
  }
@@ -1,4 +1,25 @@
1
1
  {
2
+ "consented": "सहमति देई",
3
+ "declined": "नकारी",
4
+ "withdrawn": "वापस लेई",
5
+ "dateRange": "तरीक श्रेणी",
6
+ "allTime": "सारा समां",
7
+ "customRange": "कस्टम श्रेणी",
8
+ "from": "थमां",
9
+ "to": "तगर",
10
+ "clearFilters": "फिल्टर साफ करो",
11
+ "myReceipt": "मेरी रसीद",
12
+ "myReceiptSubtitle": "अपनियां सहमति रसीदां दिक्खो",
13
+ "event": "घटना",
14
+ "date": "तारीक",
15
+ "time": "समय",
16
+ "download": "डाउनलोड करो",
17
+ "consentGranted": "सहमति देई गेई",
18
+ "consentRevoked": "सहमति वापस लेई गेई",
19
+ "consentDeclined": "सहमति नकारी गेई",
20
+ "consentExpired": "सहमति दी म्याद खतम",
21
+ "failedToFetchReceipts": "रसीदां हासल करने च असफल",
22
+ "failedToDownloadReceipt": "रसीद डाउनलोड करने च असफल",
2
23
  "yourPrivacyCenter": "तुम्हार गोपनीयता केंद्र",
3
24
  "yourRightsOverDataSimplified": "तुम्हारे डाटा पर तुम्हारे अधिकार, सादी भाषा में",
4
25
  "description": "गोपनीयता दे कानून तुम्हें तुम्हारे जानकारियाँ इकट्ठा करन, इस्तेमाल करन, बांटन अते संग्रह करन बारे कइ अधिकार दिनदे ने, असीं तुम्हारे ए अधिकार इस्तेमाल करन दा स्वागत करदे हाँ। किरपा करके थल्ले दित्ते गए फॉर्म नूं भरो, जिणा नाल असीं तुम्हारी अरज नूं मान्यता दे सकिए अते ओस नूं पूरा कर सकिए। होर जानकारी लेई, किरपा करके साडी गोपनीयता नीति पड़ो।",
@@ -288,5 +309,22 @@
288
309
  "withdrawnWithCount": "{{count}} withdrawn",
289
310
  "expiredWithCount": "{{count}} expired",
290
311
  "declinedWithCount": "{{count}} declined",
291
- "productsAndConsentsSummary": "{{products}} products, {{consents}} consents"
312
+ "productsAndConsentsSummary": "{{products}} products, {{consents}} consents",
313
+ "selectProductsForRequest": "Select one or more products for your {{requestType}} request",
314
+ "selectProductsForRequestGeneric": "Select one or more products to continue",
315
+ "yourData": "Your data",
316
+ "actingOnBehalfOf": "Acting on behalf of {{nominator}}",
317
+ "activePurposes_one": "{{count}} active purpose",
318
+ "activePurposes_other": "{{count}} active purposes",
319
+ "autoSelected": "Auto-selected",
320
+ "noProductsAvailable": "No products available",
321
+ "noProductsAvailableDescription": "You have no consents to manage yet.",
322
+ "forProduct": "For {{productName}}",
323
+ "actingOnBehalfOfShort": "acting on behalf of {{nominator}}",
324
+ "selectPurposesForThisProduct": "Select purposes within this product.",
325
+ "casesCreatedCount_one": "{{count}} case created",
326
+ "casesCreatedCount_other": "{{count}} cases created",
327
+ "someRequestsFailed": "Some requests failed",
328
+ "retry": "Retry",
329
+ "retrying": "Retrying..."
292
330
  }