@redacto.io/consent-sdk-react 3.6.0 → 5.0.0
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/CHANGELOG.md +12 -0
- package/dist/index.d.mts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +36 -7
- package/dist/index.mjs +36 -7
- package/dist/privacy-center.d.mts +134 -51
- package/dist/privacy-center.d.ts +134 -51
- package/dist/privacy-center.js +6391 -2741
- package/dist/privacy-center.mjs +6135 -2482
- package/package.json +1 -1
- package/src/RedactoNoticeConsent/RedactoNoticeConsent.tsx +5 -5
- package/src/RedactoNoticeConsent/language-codes.ts +37 -1
- package/src/RedactoNoticeConsentInline/RedactoNoticeConsentInline.tsx +0 -3
- package/src/RedactoNoticeConsentInline/api/index.ts +0 -1
- package/src/RedactoPrivacyCenter/PrivacyCenterCaseDetailsPage.tsx +154 -0
- package/src/RedactoPrivacyCenter/PrivacyCenterHomePage.tsx +3 -0
- package/src/RedactoPrivacyCenter/PrivacyCenterLayout.tsx +81 -50
- package/src/RedactoPrivacyCenter/RedactoPrivacyCenter.tsx +4 -0
- package/src/RedactoPrivacyCenter/api/actions.ts +68 -36
- package/src/RedactoPrivacyCenter/api/client.ts +125 -14
- package/src/RedactoPrivacyCenter/components/CaseDetails/AttachmentCard.tsx +38 -0
- package/src/RedactoPrivacyCenter/components/CaseDetails/ChatBubble.tsx +31 -0
- package/src/RedactoPrivacyCenter/components/CaseDetails/DocumentRequestCard.tsx +73 -0
- package/src/RedactoPrivacyCenter/components/CaseDetails/MessageComposer.tsx +87 -0
- package/src/RedactoPrivacyCenter/components/CaseDetails/MessageItem.tsx +95 -0
- package/src/RedactoPrivacyCenter/components/CaseDetails/MessagesTab.tsx +147 -0
- package/src/RedactoPrivacyCenter/components/CaseDetails/RequestDetailsTab.tsx +171 -0
- package/src/RedactoPrivacyCenter/components/CaseDetails/StatusEvent.tsx +23 -0
- package/src/RedactoPrivacyCenter/components/CaseDetails/useFileUpload.ts +116 -0
- package/src/RedactoPrivacyCenter/components/CaseDetails/useMessagePolling.ts +36 -0
- package/src/RedactoPrivacyCenter/components/CaseDetails/utils.ts +56 -0
- package/src/RedactoPrivacyCenter/components/CaseDetailsModal.tsx +1 -0
- package/src/RedactoPrivacyCenter/components/CaseHistory.tsx +6 -13
- package/src/RedactoPrivacyCenter/components/ConsentManager.tsx +6 -0
- package/src/RedactoPrivacyCenter/components/ConsentManagerColumns.tsx +0 -1
- package/src/RedactoPrivacyCenter/components/DataRequest/CorrectionDataSection.tsx +2 -2
- package/src/RedactoPrivacyCenter/components/DataRequest/PurposeSelectionSection.tsx +2 -3
- package/src/RedactoPrivacyCenter/components/Form.tsx +152 -11
- package/src/RedactoPrivacyCenter/components/GrievanceTable.tsx +4 -6
- package/src/RedactoPrivacyCenter/components/GrievanceTablePagination.tsx +9 -2
- package/src/RedactoPrivacyCenter/components/ModifyConsentModal.tsx +1 -0
- package/src/RedactoPrivacyCenter/components/Pagination.tsx +12 -12
- package/src/RedactoPrivacyCenter/components/PrivacyCenterLayout.tsx +3 -1
- package/src/RedactoPrivacyCenter/components/RequestSubmit.tsx +15 -1
- package/src/RedactoPrivacyCenter/components/SideMenuBarPC/SideBarPC.tsx +8 -8
- package/src/RedactoPrivacyCenter/components/SideMenuBarPC/SideMenuPC.tsx +7 -11
- package/src/RedactoPrivacyCenter/components/SideMenuBarPC/types.ts +1 -1
- package/src/RedactoPrivacyCenter/components/activitiesColumns.tsx +1 -1
- package/src/RedactoPrivacyCenter/components/caseHistoryColumns.tsx +4 -24
- package/src/RedactoPrivacyCenter/components/constant.ts +3 -7
- package/src/RedactoPrivacyCenter/components/types.ts +12 -4
- package/src/RedactoPrivacyCenter/context/AuthContext.tsx +30 -16
- package/src/RedactoPrivacyCenter/context/BaseUrlContext.tsx +3 -6
- package/src/RedactoPrivacyCenter/context/NavigationContext.tsx +35 -3
- package/src/RedactoPrivacyCenter/context/OrganizationContext.tsx +1 -1
- package/src/RedactoPrivacyCenter/context/types.ts +14 -0
- package/src/RedactoPrivacyCenter/lib/api.ts +101 -3
- package/src/RedactoPrivacyCenter/lib/constants.ts +46 -1
- package/src/RedactoPrivacyCenter/lib/i18n.ts +1 -1
- package/src/RedactoPrivacyCenter/lib/queries.ts +106 -2
- package/src/RedactoPrivacyCenter/lib/types.ts +186 -1
- package/src/RedactoPrivacyCenter/lib/utils.ts +1 -0
- package/src/RedactoPrivacyCenter/locales/as/translation.json +93 -1
- package/src/RedactoPrivacyCenter/locales/bho/translation.json +93 -1
- package/src/RedactoPrivacyCenter/locales/bn/translation.json +93 -1
- package/src/RedactoPrivacyCenter/locales/brx/translation.json +93 -1
- package/src/RedactoPrivacyCenter/locales/doi/translation.json +93 -1
- package/src/RedactoPrivacyCenter/locales/en/translation.json +69 -2
- package/src/RedactoPrivacyCenter/locales/gom/translation.json +93 -1
- package/src/RedactoPrivacyCenter/locales/gu/translation.json +93 -1
- package/src/RedactoPrivacyCenter/locales/hi/translation.json +93 -1
- package/src/RedactoPrivacyCenter/locales/kn/translation.json +93 -1
- package/src/RedactoPrivacyCenter/locales/ks/translation.json +93 -1
- package/src/RedactoPrivacyCenter/locales/mai/translation.json +93 -1
- package/src/RedactoPrivacyCenter/locales/ml/translation.json +93 -1
- package/src/RedactoPrivacyCenter/locales/mni-Mtei/translation.json +93 -1
- package/src/RedactoPrivacyCenter/locales/mr/translation.json +93 -1
- package/src/RedactoPrivacyCenter/locales/ne/translation.json +93 -1
- package/src/RedactoPrivacyCenter/locales/or/translation.json +93 -1
- package/src/RedactoPrivacyCenter/locales/pa/translation.json +93 -1
- package/src/RedactoPrivacyCenter/locales/sa/translation.json +93 -1
- package/src/RedactoPrivacyCenter/locales/sat/translation.json +93 -1
- package/src/RedactoPrivacyCenter/locales/sd/translation.json +93 -1
- package/src/RedactoPrivacyCenter/locales/ta/translation.json +93 -1
- package/src/RedactoPrivacyCenter/locales/te/translation.json +93 -1
- package/src/RedactoPrivacyCenter/locales/ur/translation.json +93 -1
- package/src/RedactoPrivacyCenter/styles/injectStyles.ts +725 -0
- package/src/RedactoPrivacyCenter/styles/pcStyles.ts +0 -6
- package/src/RedactoPrivacyCenter/table/AdvancedTable.tsx +5 -3
- package/src/RedactoPrivacyCenter/table/AdvancedTablePagination.tsx +9 -12
- package/src/RedactoPrivacyCenter/ui/Footer.tsx +4 -2
- package/src/RedactoPrivacyCenter/ui/PCAccordion.tsx +24 -18
- package/src/RedactoPrivacyCenter/ui/PCCollapse.tsx +30 -20
- package/src/RedactoPrivacyCenter/ui/PCInput.tsx +17 -13
- package/src/RedactoPrivacyCenter/ui/PCLoader.tsx +3 -2
- package/src/RedactoPrivacyCenter/ui/PCModal.tsx +3 -1
- package/src/RedactoPrivacyCenter/ui/PCPopover.tsx +0 -2
- package/src/RedactoPrivacyCenter/ui/PCSelect.tsx +10 -4
- package/src/RedactoPrivacyCenter/ui/PCTable.tsx +44 -32
- package/src/RedactoPrivacyCenter/ui/PCText.tsx +5 -3
- package/src/RedactoPrivacyCenter/ui/StatusBadge.tsx +0 -2
- package/src/RedactoPrivacyCenter/ui/ThemeToggle.tsx +4 -2
- package/src/privacy-center.ts +1 -0
|
@@ -148,7 +148,7 @@ export default function CorrectionDataSection({
|
|
|
148
148
|
gap: getVar('--pc-spacing-xs'),
|
|
149
149
|
}}>
|
|
150
150
|
<PCInput
|
|
151
|
-
placeholder=
|
|
151
|
+
placeholder={t('currentValuePlaceholder')}
|
|
152
152
|
size="sm"
|
|
153
153
|
required
|
|
154
154
|
value={correctionValues[name]?.current || ''}
|
|
@@ -163,7 +163,7 @@ export default function CorrectionDataSection({
|
|
|
163
163
|
}
|
|
164
164
|
/>
|
|
165
165
|
<PCInput
|
|
166
|
-
placeholder=
|
|
166
|
+
placeholder={t('updatedValuePlaceholder')}
|
|
167
167
|
size="sm"
|
|
168
168
|
required
|
|
169
169
|
value={correctionValues[name]?.updated || ''}
|
|
@@ -3,7 +3,6 @@ import { pcStyles } from '../../styles/pcStyles';
|
|
|
3
3
|
import { ChevronDown } from 'lucide-react';
|
|
4
4
|
import { RequestTypeEnum } from '../../lib/types';
|
|
5
5
|
import type { Purpose, DataElement } from '../../lib/types';
|
|
6
|
-
import { cn } from '../../utils/cn';
|
|
7
6
|
import { useTranslation } from 'react-i18next';
|
|
8
7
|
import { useEffect, useState } from 'react';
|
|
9
8
|
|
|
@@ -206,7 +205,7 @@ export default function PurposeSelectionSection({
|
|
|
206
205
|
type="button"
|
|
207
206
|
onClick={() => toggleAccordion(index)}
|
|
208
207
|
style={{
|
|
209
|
-
marginLeft:
|
|
208
|
+
marginLeft: getVar('--pc-spacing-lg'),
|
|
210
209
|
color: getVar('--pc-text-secondary'),
|
|
211
210
|
background: 'none',
|
|
212
211
|
border: 'none',
|
|
@@ -254,7 +253,7 @@ export default function PurposeSelectionSection({
|
|
|
254
253
|
// The backend should handle consent validation
|
|
255
254
|
return de !== null && de !== undefined;
|
|
256
255
|
})
|
|
257
|
-
.map((de: DataElement
|
|
256
|
+
.map((de: DataElement) => {
|
|
258
257
|
// Find the original index in the unfiltered array for proper state updates
|
|
259
258
|
const actualIndex = item.data_elements.findIndex(
|
|
260
259
|
(el) => el.uuid === de.uuid
|
|
@@ -9,6 +9,7 @@ import { AiOutlineClose } from 'react-icons/ai';
|
|
|
9
9
|
import { PiUploadBold } from 'react-icons/pi';
|
|
10
10
|
import { toast } from '../utils/toast';
|
|
11
11
|
import { PCButton, PCCheckbox, PCInput, PCLoader, PCSelect, PCTextarea } from '../ui';
|
|
12
|
+
import { PCModal } from '../ui/PCModal';
|
|
12
13
|
import { pcStyles } from '../styles/pcStyles';
|
|
13
14
|
import { createCaseRequest, getFormData } from '../lib/api';
|
|
14
15
|
import { ensureValidToken } from '../lib/utils';
|
|
@@ -40,8 +41,8 @@ import NominationDataSection from './DataRequest/NominationDataSection';
|
|
|
40
41
|
import PurposeSelectionSection from './DataRequest/PurposeSelectionSection';
|
|
41
42
|
import RequestSubmit from './RequestSubmit';
|
|
42
43
|
import type { CaseHistoryProps } from './types';
|
|
43
|
-
import {
|
|
44
|
-
import {
|
|
44
|
+
import { FiAlertCircle, FiChevronDown, FiChevronUp, FiX } from 'react-icons/fi';
|
|
45
|
+
import { MAX_DISPLAYED_PURPOSE_NAMES_IN_ERASURE_MODAL } from './constant';
|
|
45
46
|
|
|
46
47
|
const getVar = (varName: string): string => `var(${varName})`;
|
|
47
48
|
|
|
@@ -133,6 +134,10 @@ export default function Form({
|
|
|
133
134
|
const [isTranslating, setIsTranslating] = useState(false);
|
|
134
135
|
const [isRequestDetailsExpanded, setIsRequestDetailsExpanded] =
|
|
135
136
|
useState(true);
|
|
137
|
+
const [isErasureConsentModalOpen, setIsErasureConsentModalOpen] =
|
|
138
|
+
useState(false);
|
|
139
|
+
const [revokeConsentOnFulfilment, setRevokeConsentOnFulfilment] =
|
|
140
|
+
useState(false);
|
|
136
141
|
|
|
137
142
|
const resetFileInput = () => {
|
|
138
143
|
if (fileInputRef.current) {
|
|
@@ -472,7 +477,9 @@ export default function Form({
|
|
|
472
477
|
* Maps translated correction element names back to English names using UUID lookup.
|
|
473
478
|
*/
|
|
474
479
|
const getEnglishDataElementName = useCallback((translatedName: string): string => {
|
|
475
|
-
if (!englishDataRef.current?.purposes)
|
|
480
|
+
if (!englishDataRef.current?.purposes){
|
|
481
|
+
return translatedName
|
|
482
|
+
}
|
|
476
483
|
|
|
477
484
|
// Build a map from translated name -> english name via UUID
|
|
478
485
|
const translatedToUuid = new Map<string, string>();
|
|
@@ -485,17 +492,64 @@ export default function Form({
|
|
|
485
492
|
}
|
|
486
493
|
|
|
487
494
|
const uuid = translatedToUuid.get(translatedName);
|
|
488
|
-
if (!uuid)
|
|
495
|
+
if (!uuid){
|
|
496
|
+
return translatedName
|
|
497
|
+
}
|
|
489
498
|
|
|
490
499
|
for (const pw of englishDataRef.current.purposes) {
|
|
491
500
|
const englishDe = pw.purpose?.data_elements?.find((de) => de.uuid === uuid);
|
|
492
|
-
if (englishDe)
|
|
501
|
+
if (englishDe){
|
|
502
|
+
return englishDe.name
|
|
503
|
+
}
|
|
493
504
|
}
|
|
494
505
|
return translatedName;
|
|
495
506
|
}, [data]);
|
|
496
507
|
|
|
497
|
-
const
|
|
498
|
-
|
|
508
|
+
const selectedErasurePurposeList = useMemo(
|
|
509
|
+
() =>
|
|
510
|
+
erasurePurposes
|
|
511
|
+
.filter((p) => p.selected || p.data_elements.some((de) => de.selected))
|
|
512
|
+
.map((p) => p.name)
|
|
513
|
+
.filter(Boolean),
|
|
514
|
+
[erasurePurposes]
|
|
515
|
+
);
|
|
516
|
+
|
|
517
|
+
const selectedErasurePurposeNames = useMemo(() => {
|
|
518
|
+
if (
|
|
519
|
+
selectedErasurePurposeList.length === 0 ||
|
|
520
|
+
selectedErasurePurposeList.length > MAX_DISPLAYED_PURPOSE_NAMES_IN_ERASURE_MODAL
|
|
521
|
+
) {
|
|
522
|
+
return t('revokeConsentModalYourPurposes');
|
|
523
|
+
}
|
|
524
|
+
return selectedErasurePurposeList.join(', ');
|
|
525
|
+
}, [selectedErasurePurposeList, t]);
|
|
526
|
+
|
|
527
|
+
const handleSubmitClick = () => {
|
|
528
|
+
if (!isFormValid){
|
|
529
|
+
return
|
|
530
|
+
};
|
|
531
|
+
if (requestType === RequestTypeEnum.ERASURE) {
|
|
532
|
+
setIsErasureConsentModalOpen(true);
|
|
533
|
+
return;
|
|
534
|
+
}
|
|
535
|
+
setRevokeConsentOnFulfilment(false);
|
|
536
|
+
void handleSubmit(false);
|
|
537
|
+
};
|
|
538
|
+
|
|
539
|
+
const handleErasureModalChoice = (revoke: boolean) => {
|
|
540
|
+
setRevokeConsentOnFulfilment(revoke);
|
|
541
|
+
setIsErasureConsentModalOpen(false);
|
|
542
|
+
void handleSubmit(revoke);
|
|
543
|
+
};
|
|
544
|
+
|
|
545
|
+
const handleErasureModalClose = () => {
|
|
546
|
+
setIsErasureConsentModalOpen(false);
|
|
547
|
+
};
|
|
548
|
+
|
|
549
|
+
const handleSubmit = async (revokeConsent: boolean = false) => {
|
|
550
|
+
if (!isFormValid){
|
|
551
|
+
return
|
|
552
|
+
};
|
|
499
553
|
|
|
500
554
|
const requestDetails: {
|
|
501
555
|
purposes: UpdatePurpose[];
|
|
@@ -569,6 +623,9 @@ export default function Form({
|
|
|
569
623
|
? parseInt(timePeriod || '30', 10)
|
|
570
624
|
: 0,
|
|
571
625
|
requestor_note: formData.additionalNote || '',
|
|
626
|
+
...(requestType === RequestTypeEnum.ERASURE
|
|
627
|
+
? { revoke_consent_on_fulfilment: revokeConsent }
|
|
628
|
+
: {}),
|
|
572
629
|
};
|
|
573
630
|
|
|
574
631
|
try {
|
|
@@ -626,7 +683,9 @@ export default function Form({
|
|
|
626
683
|
};
|
|
627
684
|
|
|
628
685
|
const isRequestDetailsValid = useCallback(() => {
|
|
629
|
-
if (!requestType)
|
|
686
|
+
if (!requestType){
|
|
687
|
+
return false
|
|
688
|
+
};
|
|
630
689
|
switch (requestType) {
|
|
631
690
|
case RequestTypeEnum.ACCESS:
|
|
632
691
|
return accessPurposes.some(
|
|
@@ -768,7 +827,9 @@ export default function Form({
|
|
|
768
827
|
};
|
|
769
828
|
|
|
770
829
|
const handleVerifyContact = async () => {
|
|
771
|
-
if (!isPopup)
|
|
830
|
+
if (!isPopup) {
|
|
831
|
+
return
|
|
832
|
+
};
|
|
772
833
|
if (!formData.contact) {
|
|
773
834
|
toast.error(t('pleaseEnterContactToVerify'));
|
|
774
835
|
return;
|
|
@@ -862,6 +923,8 @@ export default function Form({
|
|
|
862
923
|
caseId={caseId || ''}
|
|
863
924
|
contact={formData?.contact}
|
|
864
925
|
onCreateRequest={onCreateRequest}
|
|
926
|
+
revokeConsentOnFulfilment={revokeConsentOnFulfilment}
|
|
927
|
+
revokedPurposeNames={selectedErasurePurposeNames}
|
|
865
928
|
/>
|
|
866
929
|
) : (
|
|
867
930
|
<div>
|
|
@@ -962,7 +1025,9 @@ export default function Form({
|
|
|
962
1025
|
value={formData.contact}
|
|
963
1026
|
readOnly={!isPopup}
|
|
964
1027
|
onChange={(e) => {
|
|
965
|
-
if (!isPopup)
|
|
1028
|
+
if (!isPopup){
|
|
1029
|
+
return
|
|
1030
|
+
};
|
|
966
1031
|
setFormData({
|
|
967
1032
|
...formData,
|
|
968
1033
|
contact: e.target.value,
|
|
@@ -1428,7 +1493,7 @@ export default function Form({
|
|
|
1428
1493
|
)}
|
|
1429
1494
|
<PCButton
|
|
1430
1495
|
variant="primary"
|
|
1431
|
-
onClick={
|
|
1496
|
+
onClick={handleSubmitClick}
|
|
1432
1497
|
disabled={!isFormValid || isLoading}
|
|
1433
1498
|
isLoading={isLoading}
|
|
1434
1499
|
style={{
|
|
@@ -1450,6 +1515,82 @@ export default function Form({
|
|
|
1450
1515
|
</div>
|
|
1451
1516
|
</div>
|
|
1452
1517
|
)}
|
|
1518
|
+
<PCModal
|
|
1519
|
+
isOpen={isErasureConsentModalOpen}
|
|
1520
|
+
onClose={handleErasureModalClose}
|
|
1521
|
+
size="md"
|
|
1522
|
+
showCloseButton={false}
|
|
1523
|
+
footer={
|
|
1524
|
+
<div className="pc-erasure-modal-footer">
|
|
1525
|
+
<PCButton
|
|
1526
|
+
variant="outline"
|
|
1527
|
+
onClick={() => handleErasureModalChoice(false)}
|
|
1528
|
+
disabled={isLoading}
|
|
1529
|
+
>
|
|
1530
|
+
{t('revokeConsentNo')}
|
|
1531
|
+
</PCButton>
|
|
1532
|
+
<PCButton
|
|
1533
|
+
variant="primary"
|
|
1534
|
+
onClick={() => handleErasureModalChoice(true)}
|
|
1535
|
+
disabled={isLoading}
|
|
1536
|
+
isLoading={isLoading}
|
|
1537
|
+
>
|
|
1538
|
+
{t('revokeConsentYes')}
|
|
1539
|
+
</PCButton>
|
|
1540
|
+
</div>
|
|
1541
|
+
}
|
|
1542
|
+
>
|
|
1543
|
+
<div className="pc-erasure-modal-content">
|
|
1544
|
+
<div className="pc-erasure-modal-header">
|
|
1545
|
+
<div className="pc-erasure-modal-icon">
|
|
1546
|
+
<FiAlertCircle size={24} />
|
|
1547
|
+
</div>
|
|
1548
|
+
<p className="pc-erasure-modal-title">
|
|
1549
|
+
{t('revokeConsentModalTitle')}
|
|
1550
|
+
</p>
|
|
1551
|
+
<p className="pc-erasure-modal-question">
|
|
1552
|
+
{t('revokeConsentModalQuestion')}
|
|
1553
|
+
</p>
|
|
1554
|
+
</div>
|
|
1555
|
+
|
|
1556
|
+
<div className="pc-erasure-modal-purposes">
|
|
1557
|
+
<p className="pc-erasure-modal-purposes-label">
|
|
1558
|
+
{t('revokeConsentModalPurposesLabel')}
|
|
1559
|
+
</p>
|
|
1560
|
+
{selectedErasurePurposeList.length > 0 ? (
|
|
1561
|
+
<>
|
|
1562
|
+
{selectedErasurePurposeList
|
|
1563
|
+
.slice(0, MAX_DISPLAYED_PURPOSE_NAMES_IN_ERASURE_MODAL)
|
|
1564
|
+
.map((name) => (
|
|
1565
|
+
<div key={name} className="pc-erasure-modal-purpose-item">
|
|
1566
|
+
{name}
|
|
1567
|
+
</div>
|
|
1568
|
+
))}
|
|
1569
|
+
{selectedErasurePurposeList.length > MAX_DISPLAYED_PURPOSE_NAMES_IN_ERASURE_MODAL && (
|
|
1570
|
+
<span className="pc-erasure-modal-purposes-placeholder">
|
|
1571
|
+
{t('revokeConsentModalAndMore', {
|
|
1572
|
+
count: selectedErasurePurposeList.length - MAX_DISPLAYED_PURPOSE_NAMES_IN_ERASURE_MODAL,
|
|
1573
|
+
})}
|
|
1574
|
+
</span>
|
|
1575
|
+
)}
|
|
1576
|
+
</>
|
|
1577
|
+
) : (
|
|
1578
|
+
<span className="pc-erasure-modal-purposes-placeholder">
|
|
1579
|
+
{t('revokeConsentModalYourPurposes')}
|
|
1580
|
+
</span>
|
|
1581
|
+
)}
|
|
1582
|
+
</div>
|
|
1583
|
+
|
|
1584
|
+
<div className="pc-erasure-modal-warning">
|
|
1585
|
+
<p className="pc-erasure-modal-warning-text">
|
|
1586
|
+
<span className="pc-erasure-modal-warning-label">
|
|
1587
|
+
{t('revokeConsentModalIfYesLabel')}
|
|
1588
|
+
</span>{' '}
|
|
1589
|
+
{t('revokeConsentModalIfYesBody')}
|
|
1590
|
+
</p>
|
|
1591
|
+
</div>
|
|
1592
|
+
</div>
|
|
1593
|
+
</PCModal>
|
|
1453
1594
|
</>
|
|
1454
1595
|
);
|
|
1455
1596
|
}
|
|
@@ -3,10 +3,8 @@ import { useTranslation } from 'react-i18next';
|
|
|
3
3
|
import { flexRender } from '@tanstack/react-table';
|
|
4
4
|
import { PCTable, PCLoader, PCEmpty } from '../ui';
|
|
5
5
|
import { pcStyles } from '../styles/pcStyles';
|
|
6
|
-
import type {
|
|
7
|
-
|
|
8
|
-
Row,
|
|
9
|
-
} from '@tanstack/react-table';
|
|
6
|
+
import type { Table as ReactTableType } from '@tanstack/react-table';
|
|
7
|
+
import type { TableColumnMeta } from './types';
|
|
10
8
|
|
|
11
9
|
const getVar = (varName: string): string => `var(${varName})`;
|
|
12
10
|
|
|
@@ -74,7 +72,7 @@ export default function GrievanceTable<TData extends Record<string, any>>({
|
|
|
74
72
|
color: getVar('--pc-text-primary'),
|
|
75
73
|
backgroundColor: getVar('--pc-bg-secondary'),
|
|
76
74
|
borderBottom: `1px solid ${getVar('--pc-border-color')}`,
|
|
77
|
-
textAlign: header.column.columnDef.meta?.align || 'left',
|
|
75
|
+
textAlign: (header.column.columnDef.meta as TableColumnMeta | undefined)?.align || 'left',
|
|
78
76
|
whiteSpace: 'nowrap',
|
|
79
77
|
}}
|
|
80
78
|
>
|
|
@@ -156,7 +154,7 @@ export default function GrievanceTable<TData extends Record<string, any>>({
|
|
|
156
154
|
fontSize: pcStyles.textSm.fontSize,
|
|
157
155
|
color: getVar('--pc-text-primary'),
|
|
158
156
|
borderBottom: `1px solid ${getVar('--pc-border-color')}`,
|
|
159
|
-
textAlign: cell.column.columnDef.meta?.align || 'left',
|
|
157
|
+
textAlign: (cell.column.columnDef.meta as TableColumnMeta | undefined)?.align || 'left',
|
|
160
158
|
}}
|
|
161
159
|
>
|
|
162
160
|
{flexRender(
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
1
|
import { useTranslation } from 'react-i18next';
|
|
3
2
|
import { type Table as ReactTableType } from '@tanstack/react-table';
|
|
4
3
|
import {
|
|
@@ -7,7 +6,7 @@ import {
|
|
|
7
6
|
PiCaretLeftBold,
|
|
8
7
|
PiCaretRightBold,
|
|
9
8
|
} from 'react-icons/pi';
|
|
10
|
-
import { PCActionIcon, PCSelect, PCText
|
|
9
|
+
import { PCActionIcon, PCSelect, PCText } from '../ui';
|
|
11
10
|
import { pcStyles } from '../styles/pcStyles';
|
|
12
11
|
|
|
13
12
|
const getVar = (varName: string): string => `var(${varName})`;
|
|
@@ -161,6 +160,7 @@ export default function GrievanceTablePagination<
|
|
|
161
160
|
<PCActionIcon
|
|
162
161
|
size="sm"
|
|
163
162
|
variant="outline"
|
|
163
|
+
aria-label={t('goToFirstPage')}
|
|
164
164
|
onClick={() => handlePageChange(0)}
|
|
165
165
|
disabled={!canPreviousPage}
|
|
166
166
|
style={{
|
|
@@ -174,6 +174,7 @@ export default function GrievanceTablePagination<
|
|
|
174
174
|
<PCActionIcon
|
|
175
175
|
size="sm"
|
|
176
176
|
variant="outline"
|
|
177
|
+
aria-label={t('goToPreviousPage')}
|
|
177
178
|
onClick={() => handlePageChange(currentPageIndex - 1)}
|
|
178
179
|
disabled={!canPreviousPage}
|
|
179
180
|
style={{
|
|
@@ -187,6 +188,7 @@ export default function GrievanceTablePagination<
|
|
|
187
188
|
<PCActionIcon
|
|
188
189
|
size="sm"
|
|
189
190
|
variant="outline"
|
|
191
|
+
aria-label={t('goToNextPage')}
|
|
190
192
|
onClick={() => handlePageChange(currentPageIndex + 1)}
|
|
191
193
|
disabled={!canNextPage}
|
|
192
194
|
style={{
|
|
@@ -200,6 +202,7 @@ export default function GrievanceTablePagination<
|
|
|
200
202
|
<PCActionIcon
|
|
201
203
|
size="sm"
|
|
202
204
|
variant="outline"
|
|
205
|
+
aria-label={t('goToLastPage')}
|
|
203
206
|
onClick={() => handlePageChange(totalPages - 1)}
|
|
204
207
|
disabled={!canNextPage}
|
|
205
208
|
style={{
|
|
@@ -274,6 +277,7 @@ export default function GrievanceTablePagination<
|
|
|
274
277
|
<PCActionIcon
|
|
275
278
|
size="sm"
|
|
276
279
|
variant="outline"
|
|
280
|
+
aria-label={t('goToFirstPage')}
|
|
277
281
|
onClick={() => handlePageChange(0)}
|
|
278
282
|
disabled={!canPreviousPage}
|
|
279
283
|
style={{
|
|
@@ -287,6 +291,7 @@ export default function GrievanceTablePagination<
|
|
|
287
291
|
<PCActionIcon
|
|
288
292
|
size="sm"
|
|
289
293
|
variant="outline"
|
|
294
|
+
aria-label={t('goToPreviousPage')}
|
|
290
295
|
onClick={() => handlePageChange(currentPageIndex - 1)}
|
|
291
296
|
disabled={!canPreviousPage}
|
|
292
297
|
style={{
|
|
@@ -300,6 +305,7 @@ export default function GrievanceTablePagination<
|
|
|
300
305
|
<PCActionIcon
|
|
301
306
|
size="sm"
|
|
302
307
|
variant="outline"
|
|
308
|
+
aria-label={t('goToNextPage')}
|
|
303
309
|
onClick={() => handlePageChange(currentPageIndex + 1)}
|
|
304
310
|
disabled={!canNextPage}
|
|
305
311
|
style={{
|
|
@@ -313,6 +319,7 @@ export default function GrievanceTablePagination<
|
|
|
313
319
|
<PCActionIcon
|
|
314
320
|
size="sm"
|
|
315
321
|
variant="outline"
|
|
322
|
+
aria-label={t('goToLastPage')}
|
|
316
323
|
onClick={() => handlePageChange(totalPages - 1)}
|
|
317
324
|
disabled={!canNextPage}
|
|
318
325
|
style={{
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useTranslation } from 'react-i18next';
|
|
2
|
+
import { PCActionIcon, PCSelect, PCText } from '../ui';
|
|
2
3
|
import {
|
|
3
4
|
ChevronLeft,
|
|
4
5
|
ChevronRight,
|
|
@@ -19,6 +20,7 @@ export default function Pagination({
|
|
|
19
20
|
onPageSizeChange,
|
|
20
21
|
className,
|
|
21
22
|
}: PaginationProps) {
|
|
23
|
+
const { t } = useTranslation();
|
|
22
24
|
const handlePageChange = (newPageIndex: number) => {
|
|
23
25
|
onPageChange(newPageIndex + 1);
|
|
24
26
|
};
|
|
@@ -41,11 +43,11 @@ export default function Pagination({
|
|
|
41
43
|
}} className="pc-flex-responsive">
|
|
42
44
|
<div style={{ ...pcStyles.flex, ...pcStyles.itemsCenter, ...pcStyles.gapSm }}>
|
|
43
45
|
<PCText size="xs" color="secondary" className="pc-hidden-xs pc-block-sm">
|
|
44
|
-
|
|
46
|
+
{t('rowsPerPage')}
|
|
45
47
|
</PCText>
|
|
46
48
|
<PCSelect
|
|
47
49
|
size="sm"
|
|
48
|
-
options={PAGE_SIZE_OPTIONS
|
|
50
|
+
options={PAGE_SIZE_OPTIONS}
|
|
49
51
|
value={currentPageSizeOption}
|
|
50
52
|
onChange={(v) => {
|
|
51
53
|
if (v) {
|
|
@@ -58,7 +60,7 @@ export default function Pagination({
|
|
|
58
60
|
</div>
|
|
59
61
|
<div style={{ ...pcStyles.flex, ...pcStyles.itemsCenter, ...pcStyles.gapSm }}>
|
|
60
62
|
<PCText size="xs" color="secondary">
|
|
61
|
-
|
|
63
|
+
{t('totalRecords', { count: totalRecords })}
|
|
62
64
|
</PCText>
|
|
63
65
|
</div>
|
|
64
66
|
</div>
|
|
@@ -70,11 +72,9 @@ export default function Pagination({
|
|
|
70
72
|
width: '100%',
|
|
71
73
|
}} className="pc-flex-responsive">
|
|
72
74
|
<div style={{ ...pcStyles.flex, ...pcStyles.itemsCenter, ...pcStyles.gapSm }}>
|
|
73
|
-
<PCText size="xs" color="secondary"
|
|
74
|
-
|
|
75
|
-
{totalPages === 0 ? 0 : currentPage}
|
|
75
|
+
<PCText size="xs" color="secondary">
|
|
76
|
+
{t('pageOf', { current: totalPages === 0 ? 0 : currentPage, total: totalPages })}
|
|
76
77
|
</PCText>
|
|
77
|
-
<PCText size="xs" color="secondary">of {totalPages}</PCText>
|
|
78
78
|
</div>
|
|
79
79
|
<div style={{
|
|
80
80
|
display: 'grid',
|
|
@@ -84,7 +84,7 @@ export default function Pagination({
|
|
|
84
84
|
<PCActionIcon
|
|
85
85
|
size="sm"
|
|
86
86
|
variant="outline"
|
|
87
|
-
aria-label=
|
|
87
|
+
aria-label={t('goToFirstPage')}
|
|
88
88
|
onClick={() => handlePageChange(0)}
|
|
89
89
|
disabled={currentPage === 1}
|
|
90
90
|
style={{
|
|
@@ -97,7 +97,7 @@ export default function Pagination({
|
|
|
97
97
|
<PCActionIcon
|
|
98
98
|
size="sm"
|
|
99
99
|
variant="outline"
|
|
100
|
-
aria-label=
|
|
100
|
+
aria-label={t('goToPreviousPage')}
|
|
101
101
|
onClick={() => handlePageChange(currentPage - 2)}
|
|
102
102
|
disabled={currentPage === 1}
|
|
103
103
|
style={{
|
|
@@ -110,7 +110,7 @@ export default function Pagination({
|
|
|
110
110
|
<PCActionIcon
|
|
111
111
|
size="sm"
|
|
112
112
|
variant="outline"
|
|
113
|
-
aria-label=
|
|
113
|
+
aria-label={t('goToNextPage')}
|
|
114
114
|
onClick={() => handlePageChange(currentPage)}
|
|
115
115
|
disabled={totalRecords === 0 || currentPage === totalPages}
|
|
116
116
|
style={{
|
|
@@ -123,7 +123,7 @@ export default function Pagination({
|
|
|
123
123
|
<PCActionIcon
|
|
124
124
|
size="sm"
|
|
125
125
|
variant="outline"
|
|
126
|
-
aria-label=
|
|
126
|
+
aria-label={t('goToLastPage')}
|
|
127
127
|
onClick={() => handlePageChange(totalPages - 1)}
|
|
128
128
|
disabled={totalRecords === 0 || currentPage === totalPages}
|
|
129
129
|
style={{
|
|
@@ -40,7 +40,7 @@ export default function PrivacyCenterLayout({
|
|
|
40
40
|
|
|
41
41
|
return (
|
|
42
42
|
<LocaleContext.Provider value={{ locale, setLocale }}>
|
|
43
|
-
<Suspense fallback={<div style={{ ...pcStyles.flex, ...pcStyles.itemsCenter, ...pcStyles.justifyCenter, minHeight: '100vh' }}>
|
|
43
|
+
<Suspense fallback={<div style={{ ...pcStyles.flex, ...pcStyles.itemsCenter, ...pcStyles.justifyCenter, minHeight: '100vh' }}>{t('loadingEllipsis')}</div>}>
|
|
44
44
|
<ThemeTransitionOverlay />
|
|
45
45
|
<main
|
|
46
46
|
className="pc-root"
|
|
@@ -129,6 +129,8 @@ export default function PrivacyCenterLayout({
|
|
|
129
129
|
<PCSelect
|
|
130
130
|
size="sm"
|
|
131
131
|
searchable
|
|
132
|
+
searchPlaceholder={t('searchPlaceholder')}
|
|
133
|
+
noOptionsMessage={t('noOptionsFound')}
|
|
132
134
|
style={{
|
|
133
135
|
width: 'auto',
|
|
134
136
|
minWidth: '92px',
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import character from '../assets/character.svg';
|
|
2
2
|
import greenTick from '../assets/greenTick.svg';
|
|
3
|
-
import mailIcon from '../assets/mail.svg';
|
|
4
3
|
import sentImg from '../assets/sentImg.svg';
|
|
5
4
|
import { useTranslation } from 'react-i18next';
|
|
6
5
|
import { PCButton, PCText } from '../ui';
|
|
@@ -14,6 +13,8 @@ export default function RequestSubmit({
|
|
|
14
13
|
caseId,
|
|
15
14
|
contact,
|
|
16
15
|
onCreateRequest,
|
|
16
|
+
revokeConsentOnFulfilment,
|
|
17
|
+
revokedPurposeNames,
|
|
17
18
|
}: RequestSubmitProps) {
|
|
18
19
|
const { t } = useTranslation();
|
|
19
20
|
return (
|
|
@@ -158,6 +159,19 @@ export default function RequestSubmit({
|
|
|
158
159
|
>
|
|
159
160
|
{t('processRequest')}.
|
|
160
161
|
</PCText>
|
|
162
|
+
{revokeConsentOnFulfilment && (
|
|
163
|
+
<div className="pc-request-submit-revoke-notice">
|
|
164
|
+
<PCText
|
|
165
|
+
size="xs"
|
|
166
|
+
weight="medium"
|
|
167
|
+
className="pc-request-submit-revoke-notice-text"
|
|
168
|
+
>
|
|
169
|
+
{t('erasureConsentRevokeNotice', {
|
|
170
|
+
purposes: revokedPurposeNames,
|
|
171
|
+
})}
|
|
172
|
+
</PCText>
|
|
173
|
+
</div>
|
|
174
|
+
)}
|
|
161
175
|
</div>
|
|
162
176
|
</div>
|
|
163
177
|
<div className="pc-hidden-xs pc-block-md" style={{ width: '100%' }}>
|
|
@@ -3,7 +3,7 @@ import SimpleBar from '../../ui/SimpleBar';
|
|
|
3
3
|
import { PCText, PCAvatar, PCButton, PCActionIcon } from '../../ui';
|
|
4
4
|
import { PCTooltip } from '../../ui/PCTooltip';
|
|
5
5
|
import { pcStyles } from '../../styles/pcStyles';
|
|
6
|
-
import { useState, useEffect, useCallback, useMemo } from 'react';
|
|
6
|
+
import { useState, useEffect, useCallback, useMemo, type CSSProperties } from 'react';
|
|
7
7
|
import { useTranslation } from 'react-i18next';
|
|
8
8
|
import {
|
|
9
9
|
IoArrowBackOutline,
|
|
@@ -119,9 +119,9 @@ export default function SideBarPC({
|
|
|
119
119
|
[isCollapsed, className]
|
|
120
120
|
);
|
|
121
121
|
|
|
122
|
-
const sidebarStyle = useMemo(
|
|
122
|
+
const sidebarStyle = useMemo<CSSProperties>(
|
|
123
123
|
() => ({
|
|
124
|
-
position: 'fixed'
|
|
124
|
+
position: 'fixed',
|
|
125
125
|
top: 0,
|
|
126
126
|
bottom: 0,
|
|
127
127
|
left: 0,
|
|
@@ -131,8 +131,8 @@ export default function SideBarPC({
|
|
|
131
131
|
transition: 'width 0.3s cubic-bezier(0.4, 0, 0.2, 1), transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), background-color 0.3s ease, border-color 0.3s ease',
|
|
132
132
|
display: 'flex',
|
|
133
133
|
flexDirection: 'column',
|
|
134
|
-
overflowY: 'hidden'
|
|
135
|
-
overflowX: 'visible'
|
|
134
|
+
overflowY: 'hidden',
|
|
135
|
+
overflowX: 'visible',
|
|
136
136
|
boxSizing: 'border-box',
|
|
137
137
|
height: '100vh',
|
|
138
138
|
willChange: 'width',
|
|
@@ -226,7 +226,7 @@ export default function SideBarPC({
|
|
|
226
226
|
{!isCompact && !isMobileOpen && (
|
|
227
227
|
<PCActionIcon
|
|
228
228
|
variant="outline"
|
|
229
|
-
aria-label={isCollapsed ? '
|
|
229
|
+
aria-label={isCollapsed ? t('expandSidebar') : t('collapseSidebar')}
|
|
230
230
|
className="pc-sidebar-toggle-desktop pc-hidden-xs pc-hidden-sm pc-flex-md"
|
|
231
231
|
data-collapsed={isCollapsed ? 'true' : 'false'}
|
|
232
232
|
data-visible={(!isCollapsed || isDesktopHovered) ? 'true' : 'false'}
|
|
@@ -258,7 +258,7 @@ export default function SideBarPC({
|
|
|
258
258
|
{!isMobileOpen && (
|
|
259
259
|
<PCActionIcon
|
|
260
260
|
data-mobile-menu-button
|
|
261
|
-
aria-label=
|
|
261
|
+
aria-label={t('openSidebarMenu')}
|
|
262
262
|
variant="default"
|
|
263
263
|
style={{
|
|
264
264
|
position: 'fixed',
|
|
@@ -357,7 +357,7 @@ export default function SideBarPC({
|
|
|
357
357
|
style={{ color: getVar('--pc-text-primary') }}
|
|
358
358
|
className="pc-hidden-md"
|
|
359
359
|
onClick={handleMobileClose}
|
|
360
|
-
aria-label=
|
|
360
|
+
aria-label={t('closeSidebarMenu')}
|
|
361
361
|
>
|
|
362
362
|
<IoCloseOutline size={20} />
|
|
363
363
|
</PCActionIcon>
|