ethyca-fides 2.65.0rc11__py2.py3-none-any.whl → 2.65.1__py2.py3-none-any.whl

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.

Potentially problematic release.


This version of ethyca-fides might be problematic. Click here for more details.

Files changed (111) hide show
  1. {ethyca_fides-2.65.0rc11.dist-info → ethyca_fides-2.65.1.dist-info}/METADATA +1 -1
  2. {ethyca_fides-2.65.0rc11.dist-info → ethyca_fides-2.65.1.dist-info}/RECORD +108 -108
  3. fides/_version.py +3 -3
  4. fides/api/api/v1/endpoints/privacy_request_endpoints.py +24 -1
  5. fides/api/oauth/roles.py +2 -0
  6. fides/api/schemas/api.py +6 -0
  7. fides/api/service/connectors/base_email_connector.py +1 -1
  8. fides/api/service/connectors/base_erasure_email_connector.py +39 -2
  9. fides/api/service/connectors/consent_email_connector.py +1 -1
  10. fides/api/service/connectors/dynamic_erasure_email_connector.py +14 -48
  11. fides/api/service/connectors/erasure_email_connector.py +14 -8
  12. fides/api/service/privacy_request/email_batch_service.py +68 -52
  13. fides/api/tasks/scheduled/scheduler.py +5 -0
  14. fides/api/util/lock.py +3 -0
  15. fides/common/api/scope_registry.py +4 -0
  16. fides/common/api/v1/urn_registry.py +3 -0
  17. fides/config/execution_settings.py +8 -0
  18. fides/ui-build/static/admin/404.html +1 -1
  19. fides/ui-build/static/admin/_next/static/chunks/3988-e8e0424b117d813b.js +1 -0
  20. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-93f0fed887d9e98e.js +1 -0
  21. fides/ui-build/static/admin/_next/static/css/{5f8af79f94072e0f.css → d522df24a125b46f.css} +1 -1
  22. fides/ui-build/static/admin/_next/static/e4X4A9FU3w3buLKgvkCKW/_buildManifest.js +1 -0
  23. fides/ui-build/static/admin/add-systems/manual.html +1 -1
  24. fides/ui-build/static/admin/add-systems/multiple.html +1 -1
  25. fides/ui-build/static/admin/add-systems.html +1 -1
  26. fides/ui-build/static/admin/consent/configure/add-vendors.html +1 -1
  27. fides/ui-build/static/admin/consent/configure.html +1 -1
  28. fides/ui-build/static/admin/consent/privacy-experience/[id].html +1 -1
  29. fides/ui-build/static/admin/consent/privacy-experience/new.html +1 -1
  30. fides/ui-build/static/admin/consent/privacy-experience.html +1 -1
  31. fides/ui-build/static/admin/consent/privacy-notices/[id].html +1 -1
  32. fides/ui-build/static/admin/consent/privacy-notices/new.html +1 -1
  33. fides/ui-build/static/admin/consent/privacy-notices.html +1 -1
  34. fides/ui-build/static/admin/consent/properties.html +1 -1
  35. fides/ui-build/static/admin/consent/reporting.html +1 -1
  36. fides/ui-build/static/admin/consent.html +1 -1
  37. fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn]/[resourceUrn].html +1 -1
  38. fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn].html +1 -1
  39. fides/ui-build/static/admin/data-catalog/[systemId]/projects.html +1 -1
  40. fides/ui-build/static/admin/data-catalog/[systemId]/resources/[resourceUrn].html +1 -1
  41. fides/ui-build/static/admin/data-catalog/[systemId]/resources.html +1 -1
  42. fides/ui-build/static/admin/data-catalog.html +1 -1
  43. fides/ui-build/static/admin/data-discovery/action-center/[monitorId]/[systemId].html +1 -1
  44. fides/ui-build/static/admin/data-discovery/action-center/[monitorId].html +1 -1
  45. fides/ui-build/static/admin/data-discovery/action-center.html +1 -1
  46. fides/ui-build/static/admin/data-discovery/activity.html +1 -1
  47. fides/ui-build/static/admin/data-discovery/detection/[resourceUrn].html +1 -1
  48. fides/ui-build/static/admin/data-discovery/detection.html +1 -1
  49. fides/ui-build/static/admin/data-discovery/discovery/[resourceUrn].html +1 -1
  50. fides/ui-build/static/admin/data-discovery/discovery.html +1 -1
  51. fides/ui-build/static/admin/datamap.html +1 -1
  52. fides/ui-build/static/admin/dataset/[datasetId]/[collectionName]/[...subfieldNames].html +1 -1
  53. fides/ui-build/static/admin/dataset/[datasetId]/[collectionName].html +1 -1
  54. fides/ui-build/static/admin/dataset/[datasetId].html +1 -1
  55. fides/ui-build/static/admin/dataset/new.html +1 -1
  56. fides/ui-build/static/admin/dataset.html +1 -1
  57. fides/ui-build/static/admin/datastore-connection/[id].html +1 -1
  58. fides/ui-build/static/admin/datastore-connection/new.html +1 -1
  59. fides/ui-build/static/admin/datastore-connection.html +1 -1
  60. fides/ui-build/static/admin/index.html +1 -1
  61. fides/ui-build/static/admin/integrations/[id].html +1 -1
  62. fides/ui-build/static/admin/integrations.html +1 -1
  63. fides/ui-build/static/admin/login/[provider].html +1 -1
  64. fides/ui-build/static/admin/login.html +1 -1
  65. fides/ui-build/static/admin/messaging/[id].html +1 -1
  66. fides/ui-build/static/admin/messaging/add-template.html +1 -1
  67. fides/ui-build/static/admin/messaging.html +1 -1
  68. fides/ui-build/static/admin/poc/ant-components.html +1 -1
  69. fides/ui-build/static/admin/poc/form-experiments/AntForm.html +1 -1
  70. fides/ui-build/static/admin/poc/form-experiments/FormikAntFormItem.html +1 -1
  71. fides/ui-build/static/admin/poc/form-experiments/FormikControlled.html +1 -1
  72. fides/ui-build/static/admin/poc/form-experiments/FormikField.html +1 -1
  73. fides/ui-build/static/admin/poc/form-experiments/FormikSpreadField.html +1 -1
  74. fides/ui-build/static/admin/poc/forms.html +1 -1
  75. fides/ui-build/static/admin/poc/table-migration.html +1 -1
  76. fides/ui-build/static/admin/privacy-requests/[id].html +1 -1
  77. fides/ui-build/static/admin/privacy-requests/configure/messaging.html +1 -1
  78. fides/ui-build/static/admin/privacy-requests/configure/storage.html +1 -1
  79. fides/ui-build/static/admin/privacy-requests/configure.html +1 -1
  80. fides/ui-build/static/admin/privacy-requests.html +1 -1
  81. fides/ui-build/static/admin/properties/[id].html +1 -1
  82. fides/ui-build/static/admin/properties/add-property.html +1 -1
  83. fides/ui-build/static/admin/properties.html +1 -1
  84. fides/ui-build/static/admin/reporting/datamap.html +1 -1
  85. fides/ui-build/static/admin/settings/about/alpha.html +1 -1
  86. fides/ui-build/static/admin/settings/about.html +1 -1
  87. fides/ui-build/static/admin/settings/consent/[configuration_id]/[purpose_id].html +1 -1
  88. fides/ui-build/static/admin/settings/consent.html +1 -1
  89. fides/ui-build/static/admin/settings/custom-fields.html +1 -1
  90. fides/ui-build/static/admin/settings/domain-records.html +1 -1
  91. fides/ui-build/static/admin/settings/domains.html +1 -1
  92. fides/ui-build/static/admin/settings/email-templates.html +1 -1
  93. fides/ui-build/static/admin/settings/locations.html +1 -1
  94. fides/ui-build/static/admin/settings/organization.html +1 -1
  95. fides/ui-build/static/admin/settings/regulations.html +1 -1
  96. fides/ui-build/static/admin/systems/configure/[id]/test-datasets.html +1 -1
  97. fides/ui-build/static/admin/systems/configure/[id].html +1 -1
  98. fides/ui-build/static/admin/systems.html +1 -1
  99. fides/ui-build/static/admin/taxonomy.html +1 -1
  100. fides/ui-build/static/admin/user-management/new.html +1 -1
  101. fides/ui-build/static/admin/user-management/profile/[id].html +1 -1
  102. fides/ui-build/static/admin/user-management.html +1 -1
  103. fides/ui-build/static/admin/_next/static/BK56P69fQA7jyWB8H568y/_buildManifest.js +0 -1
  104. fides/ui-build/static/admin/_next/static/chunks/3988-046b3a2866b5cb99.js +0 -1
  105. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-b1772281866cb827.js +0 -1
  106. {ethyca_fides-2.65.0rc11.dist-info → ethyca_fides-2.65.1.dist-info}/WHEEL +0 -0
  107. {ethyca_fides-2.65.0rc11.dist-info → ethyca_fides-2.65.1.dist-info}/entry_points.txt +0 -0
  108. {ethyca_fides-2.65.0rc11.dist-info → ethyca_fides-2.65.1.dist-info}/licenses/LICENSE +0 -0
  109. {ethyca_fides-2.65.0rc11.dist-info → ethyca_fides-2.65.1.dist-info}/top_level.txt +0 -0
  110. /fides/ui-build/static/admin/_next/static/chunks/pages/{_app-3e486cab9a918260.js → _app-be66c01c2b1de442.js} +0 -0
  111. /fides/ui-build/static/admin/_next/static/{BK56P69fQA7jyWB8H568y → e4X4A9FU3w3buLKgvkCKW}/_ssgManifest.js +0 -0
@@ -22,7 +22,6 @@ from fides.api.schemas.connection_configuration.connection_secrets_dynamic_erasu
22
22
  DynamicErasureEmailSchema,
23
23
  )
24
24
  from fides.api.schemas.policy import ActionType
25
- from fides.api.schemas.privacy_request import PrivacyRequestStatus
26
25
  from fides.api.service.connectors.base_connector import BaseConnector
27
26
  from fides.api.service.connectors.base_erasure_email_connector import (
28
27
  BaseErasureEmailConnector,
@@ -67,9 +66,11 @@ class DynamicErasureEmailConnector(BaseErasureEmailConnector):
67
66
  def get_config(self, configuration: ConnectionConfig) -> DynamicErasureEmailSchema:
68
67
  return DynamicErasureEmailSchema(**configuration.secrets or {})
69
68
 
70
- def batch_email_send(self, privacy_requests: Query) -> None:
69
+ def batch_email_send(self, privacy_requests: Query, batch_id: str) -> None:
71
70
  logger.debug(
72
- "Starting batch_email_send for connector: {} ...", self.configuration.key
71
+ "Starting batch erasure email {} for connector: {} ...",
72
+ batch_id,
73
+ self.configuration.key,
73
74
  )
74
75
 
75
76
  db: Session = Session.object_session(self.configuration)
@@ -133,14 +134,16 @@ class DynamicErasureEmailConnector(BaseErasureEmailConnector):
133
134
 
134
135
  if not batched_identities:
135
136
  logger.info(
136
- "Skipping erasure email send for connector: '{}'. "
137
+ "Skipping erasure email send for connector '{}' and batch '{}'. "
137
138
  "No corresponding user identities or email addresses found for pending privacy requests.",
138
139
  self.configuration.key,
140
+ batch_id,
139
141
  )
140
142
  return
141
143
 
142
144
  logger.info(
143
- "Sending batched erasure email for connector {}...",
145
+ "Sending batch erasure email {} for connector {}...",
146
+ batch_id,
144
147
  self.configuration.key,
145
148
  )
146
149
 
@@ -155,15 +158,14 @@ class DynamicErasureEmailConnector(BaseErasureEmailConnector):
155
158
  test_mode=False,
156
159
  )
157
160
  except MessageDispatchException as exc:
158
- logger.error(
159
- "Dynamic erasure email for connector {} failed with exception {}",
160
- self.configuration.key,
161
- exc,
162
- )
161
+ message = f"Dynamic batch erasure email {batch_id} for connector {self.configuration.key} failed with exception {exc}"
162
+ logger.error(message)
163
163
  self.error_all_privacy_requests(
164
164
  db,
165
- privacy_requests,
166
- f"Dynamic erasure email for connector failed with MessageDispatchException. Error: {exc}",
165
+ privacy_requests.filter(
166
+ PrivacyRequest.id.notin_(skipped_privacy_requests)
167
+ ),
168
+ message,
167
169
  )
168
170
  raise exc
169
171
 
@@ -470,42 +472,6 @@ class DynamicErasureEmailConnector(BaseErasureEmailConnector):
470
472
 
471
473
  return email, vendor
472
474
 
473
- def error_all_privacy_requests(
474
- self, db: Session, privacy_requests: Query, failure_reason: str
475
- ) -> None:
476
- """
477
- Creates an ExecutionLog with status error for each privacy request in the batch, and sets the
478
- privacy request status to error.
479
- """
480
- for privacy_request in privacy_requests:
481
- self.error_privacy_request(db, privacy_request, failure_reason)
482
-
483
- def error_privacy_request(
484
- self,
485
- db: Session,
486
- privacy_request: PrivacyRequest,
487
- failure_reason: Optional[str],
488
- ) -> None:
489
- """
490
- Creates an ExecutionLog with status error for the privacy request, using the failure_reason
491
- as the message, and sets the privacy request status to error.
492
- """
493
- ExecutionLog.create(
494
- db=db,
495
- data={
496
- "connection_key": self.configuration.key,
497
- "dataset_name": self.configuration.name_or_key,
498
- "collection_name": self.configuration.name_or_key,
499
- "privacy_request_id": privacy_request.id,
500
- "action_type": ActionType.erasure,
501
- "status": ExecutionLogStatus.error,
502
- "message": failure_reason
503
- or "An error occurred when trying to send the erasure email",
504
- },
505
- )
506
- privacy_request.status = PrivacyRequestStatus.error
507
- privacy_request.save(db)
508
-
509
475
  def test_connection(self) -> Optional[ConnectionTestStatus]:
510
476
  """
511
477
  Sends an email to the "test_email" configured, just to establish that the email workflow is working.
@@ -9,7 +9,7 @@ from fides.api.models.connectionconfig import (
9
9
  ConnectionTestStatus,
10
10
  ConnectionType,
11
11
  )
12
- from fides.api.models.privacy_request import ExecutionLog
12
+ from fides.api.models.privacy_request import ExecutionLog, PrivacyRequest
13
13
  from fides.api.models.worker_task import ExecutionLogStatus
14
14
  from fides.api.schemas.connection_configuration import EmailSchema
15
15
  from fides.api.schemas.policy import ActionType
@@ -67,7 +67,7 @@ class GenericErasureEmailConnector(BaseErasureEmailConnector):
67
67
  return ConnectionTestStatus.failed
68
68
  return ConnectionTestStatus.succeeded
69
69
 
70
- def batch_email_send(self, privacy_requests: Query) -> None:
70
+ def batch_email_send(self, privacy_requests: Query, batch_id: str) -> None:
71
71
  skipped_privacy_requests: List[str] = []
72
72
  batched_identities: List[str] = []
73
73
  db = Session.object_session(self.configuration)
@@ -85,14 +85,16 @@ class GenericErasureEmailConnector(BaseErasureEmailConnector):
85
85
 
86
86
  if not batched_identities:
87
87
  logger.info(
88
- "Skipping erasure email send for connector: '{}'. "
88
+ "Skipping erasure email send for connector '{}' and batch '{}'. "
89
89
  "No corresponding user identities found for pending privacy requests.",
90
90
  self.configuration.key,
91
+ batch_id,
91
92
  )
92
93
  return
93
94
 
94
95
  logger.info(
95
- "Sending batched erasure email for connector {}...",
96
+ "Sending batch erasure email {} for connector {}...",
97
+ batch_id,
96
98
  self.configuration.key,
97
99
  )
98
100
 
@@ -105,10 +107,14 @@ class GenericErasureEmailConnector(BaseErasureEmailConnector):
105
107
  test_mode=False,
106
108
  )
107
109
  except MessageDispatchException as exc:
108
- logger.info(
109
- "Erasure email for connector {} failed with exception {}",
110
- self.configuration.key,
111
- exc,
110
+ message = f"Batch erasure email {batch_id} for connector {self.configuration.key} failed with exception {exc}"
111
+ logger.error(message)
112
+ self.error_all_privacy_requests(
113
+ db,
114
+ privacy_requests.filter(
115
+ PrivacyRequest.id.notin_(skipped_privacy_requests)
116
+ ),
117
+ message,
112
118
  )
113
119
  raise
114
120
 
@@ -1,3 +1,4 @@
1
+ import uuid
1
2
  from enum import Enum
2
3
 
3
4
  from loguru import logger
@@ -14,12 +15,15 @@ from fides.api.service.privacy_request.request_runner_service import (
14
15
  get_erasure_email_connection_configs,
15
16
  )
16
17
  from fides.api.tasks import DatabaseTask, celery_app
17
- from fides.api.tasks.scheduled.scheduler import scheduler
18
+ from fides.api.tasks.scheduled.scheduler import create_cron_trigger, scheduler
19
+ from fides.api.util.lock import redis_lock
18
20
  from fides.config import get_config
19
21
  from fides.service.privacy_request.privacy_request_service import queue_privacy_request
20
22
 
21
23
  CONFIG = get_config()
22
24
  BATCH_EMAIL_SEND = "batch_email_send"
25
+ BATCH_EMAIL_SEND_LOCK = "batch_email_send_lock"
26
+ BATCH_EMAIL_SEND_LOCK_TIMEOUT = 600
23
27
 
24
28
 
25
29
  class EmailExitState(Enum):
@@ -31,63 +35,74 @@ class EmailExitState(Enum):
31
35
  missing_required_data = "missing_required_data"
32
36
  email_send_failed = "email_send_failed"
33
37
  complete = "complete"
38
+ email_send_already_running = "email_send_already_running"
34
39
 
35
40
 
36
41
  @celery_app.task(base=DatabaseTask, bind=True)
37
42
  def send_email_batch(self: DatabaseTask) -> EmailExitState:
38
43
  """Sends emails for each relevant connector with applicable user details batched together."""
39
-
40
- logger.info("Starting batched email send...")
41
- with self.get_new_session() as session:
42
- privacy_requests: Query = (
43
- session.query(PrivacyRequest)
44
- .filter(PrivacyRequest.status == PrivacyRequestStatus.awaiting_email_send)
45
- .filter(PrivacyRequest.deleted_at.is_(None))
46
- .order_by(PrivacyRequest.created_at.asc()) # oldest first
47
- )
48
- if not privacy_requests.first():
49
- logger.info(
50
- "Skipping batch email send with status: {}",
51
- EmailExitState.no_applicable_privacy_requests.value,
52
- )
53
- return EmailExitState.no_applicable_privacy_requests
54
-
55
- consent_configs: Query = get_consent_email_connection_configs(session)
56
- erasure_configs: Query = get_erasure_email_connection_configs(session)
57
- combined_configs = consent_configs.union_all(erasure_configs)
58
- if not combined_configs.first():
59
- requeue_privacy_requests_after_email_send(privacy_requests, session)
60
- logger.info(
61
- "Skipping batch email send with status: {}",
62
- EmailExitState.no_applicable_connectors.value,
44
+ with redis_lock(
45
+ lock_key=BATCH_EMAIL_SEND_LOCK, timeout=BATCH_EMAIL_SEND_LOCK_TIMEOUT
46
+ ) as lock:
47
+ if not lock:
48
+ return EmailExitState.email_send_already_running
49
+
50
+ batch_id = str(uuid.uuid4())
51
+ logger.info("Starting batch email send {}...", batch_id)
52
+ with self.get_new_session() as session:
53
+ privacy_requests: Query = (
54
+ session.query(PrivacyRequest)
55
+ .filter(
56
+ PrivacyRequest.status == PrivacyRequestStatus.awaiting_email_send
57
+ )
58
+ .filter(PrivacyRequest.deleted_at.is_(None))
59
+ .order_by(PrivacyRequest.created_at.asc()) # oldest first
63
60
  )
64
- return EmailExitState.no_applicable_connectors
65
-
66
- try:
67
- # erasure
68
- for connection_config in erasure_configs:
69
- get_connector(connection_config).batch_email_send( # type: ignore
70
- filter_privacy_requests_by_action_type(
71
- privacy_requests, ActionType.erasure
72
- )
61
+ if not privacy_requests.first():
62
+ logger.info(
63
+ "Skipping batch email send with status: {}",
64
+ EmailExitState.no_applicable_privacy_requests.value,
73
65
  )
66
+ return EmailExitState.no_applicable_privacy_requests
67
+
68
+ consent_configs: Query = get_consent_email_connection_configs(session)
69
+ erasure_configs: Query = get_erasure_email_connection_configs(session)
70
+ combined_configs = consent_configs.union_all(erasure_configs)
71
+ if not combined_configs.first():
72
+ requeue_privacy_requests_after_email_send(privacy_requests, session)
73
+ logger.info(
74
+ "Skipping batch email send with status: {}",
75
+ EmailExitState.no_applicable_connectors.value,
76
+ )
77
+ return EmailExitState.no_applicable_connectors
78
+
79
+ try:
80
+ # erasure
81
+ for connection_config in erasure_configs:
82
+ get_connector(connection_config).batch_email_send( # type: ignore
83
+ filter_privacy_requests_by_action_type(
84
+ privacy_requests, ActionType.erasure
85
+ ),
86
+ batch_id,
87
+ )
74
88
 
75
- # consent
76
- for connection_config in consent_configs:
77
- get_connector(connection_config).batch_email_send( # type: ignore
78
- filter_privacy_requests_by_action_type(
79
- privacy_requests, ActionType.consent
89
+ # consent
90
+ for connection_config in consent_configs:
91
+ get_connector(connection_config).batch_email_send( # type: ignore
92
+ filter_privacy_requests_by_action_type(
93
+ privacy_requests, ActionType.consent
94
+ ),
95
+ batch_id,
80
96
  )
97
+ except MessageDispatchException as exc:
98
+ logger.error(
99
+ "Batch email send for connector failed with exception: '{}'",
100
+ exc,
81
101
  )
82
- except MessageDispatchException as exc:
83
- logger.error(
84
- "Batch email send for connector failed with exception: '{}'",
85
- exc,
86
- )
87
- return EmailExitState.email_send_failed
102
+ return EmailExitState.email_send_failed
88
103
 
89
- requeue_privacy_requests_after_email_send(privacy_requests, session)
90
- return EmailExitState.complete
104
+ requeue_privacy_requests_after_email_send(privacy_requests, session)
105
+ return EmailExitState.complete
91
106
 
92
107
 
93
108
  def filter_privacy_requests_by_action_type(
@@ -135,6 +150,11 @@ def initiate_scheduled_batch_email_send() -> None:
135
150
 
136
151
  assert scheduler.running, "Scheduler is not running! Cannot add Batch Email job."
137
152
 
153
+ cron_trigger = create_cron_trigger(
154
+ cron_expression=CONFIG.execution.email_send_cron_expression,
155
+ timezone=CONFIG.execution.email_send_timezone,
156
+ )
157
+
138
158
  logger.info("Initiating scheduler for batch email send")
139
159
  scheduler.add_job(
140
160
  func=send_email_batch,
@@ -142,9 +162,5 @@ def initiate_scheduled_batch_email_send() -> None:
142
162
  id=BATCH_EMAIL_SEND,
143
163
  coalesce=False,
144
164
  replace_existing=True,
145
- trigger="cron",
146
- minute="0",
147
- hour="12",
148
- day_of_week="mon",
149
- timezone="US/Eastern",
165
+ trigger=cron_trigger,
150
166
  )
@@ -1,5 +1,10 @@
1
1
  from apscheduler.schedulers.asyncio import AsyncIOScheduler
2
2
  from apscheduler.schedulers.background import BackgroundScheduler
3
+ from apscheduler.triggers.cron import CronTrigger
3
4
 
4
5
  scheduler = BackgroundScheduler()
5
6
  async_scheduler = AsyncIOScheduler()
7
+
8
+
9
+ def create_cron_trigger(cron_expression: str, timezone: str) -> CronTrigger:
10
+ return CronTrigger.from_crontab(cron_expression, timezone=timezone)
fides/api/util/lock.py CHANGED
@@ -24,6 +24,9 @@ def redis_lock(lock_key: str, timeout: int) -> Generator[Lock | None, None, None
24
24
  If the lock is acquired, it yields the lock object.
25
25
  If the lock is not acquired, it yields None.
26
26
  The lock is automatically released on exiting the context.
27
+
28
+ Timeout is the maximum number of seconds for the lock to be held,
29
+ after which the lock will be released.
27
30
  """
28
31
  lock = get_redis_lock(lock_key, timeout)
29
32
 
@@ -48,6 +48,7 @@ PRIVACY_NOTICE = "privacy-notice"
48
48
  PRIVACY_PREFERENCE_HISTORY = "privacy-preference-history"
49
49
  PRIVACY_REQUEST = "privacy-request"
50
50
  PRIVACY_REQUEST_ACCESS_RESULTS = "privacy-request-access-results"
51
+ PRIVACY_REQUEST_EMAIL_INTEGRATIONS = "privacy-request-email-integrations"
51
52
  PRIVACY_REQUEST_NOTIFICATIONS = "privacy-request-notifications"
52
53
  READ = "read"
53
54
  REGISTER = "register"
@@ -58,6 +59,7 @@ REVIEW = "review"
58
59
  RULE = "rule"
59
60
  SAAS_CONFIG = "saas_config"
60
61
  SCOPE = "scope"
62
+ SEND = "send"
61
63
  STORAGE = "storage"
62
64
  SYSTEM = "system"
63
65
  SYSTEM_MANAGER = "system_manager"
@@ -176,6 +178,7 @@ PRIVACY_PREFERENCE_HISTORY_READ = f"{PRIVACY_PREFERENCE_HISTORY}:{READ}"
176
178
  PRIVACY_REQUEST_CALLBACK_RESUME = f"{PRIVACY_REQUEST}:{RESUME}" # User has permission to restart a paused privacy request
177
179
  PRIVACY_REQUEST_CREATE = f"{PRIVACY_REQUEST}:{CREATE}"
178
180
  PRIVACY_REQUEST_DELETE = f"{PRIVACY_REQUEST}:{DELETE}"
181
+ PRIVACY_REQUEST_EMAIL_INTEGRATIONS_SEND = f"{PRIVACY_REQUEST_EMAIL_INTEGRATIONS}:{SEND}"
179
182
  PRIVACY_REQUEST_MANUAL_STEPS_REVIEW = f"{PRIVACY_REQUEST}:{MANUAL_STEPS}:{REVIEW}"
180
183
  PRIVACY_REQUEST_MANUAL_STEPS_RESPOND = f"{PRIVACY_REQUEST}:{MANUAL_STEPS}:{RESPOND}"
181
184
  PRIVACY_REQUEST_NOTIFICATIONS_CREATE_OR_UPDATE = (
@@ -316,6 +319,7 @@ SCOPE_DOCS = {
316
319
  PRIVACY_REQUEST_CALLBACK_RESUME: "Restart paused privacy requests",
317
320
  PRIVACY_REQUEST_READ_ACCESS_RESULTS: "Download access data for the privacy request",
318
321
  PRIVACY_REQUEST_DELETE: "Remove privacy requests",
322
+ PRIVACY_REQUEST_EMAIL_INTEGRATIONS_SEND: "Send email for email integrations for the privacy request",
319
323
  PRIVACY_REQUEST_MANUAL_STEPS_RESPOND: "Respond to manual steps for the privacy request",
320
324
  PRIVACY_REQUEST_MANUAL_STEPS_REVIEW: "Review manual steps for the privacy request",
321
325
  PRIVACY_REQUEST_NOTIFICATIONS_CREATE_OR_UPDATE: "",
@@ -76,6 +76,9 @@ POLICY_DETAIL = "/dsr/policy/{policy_key}"
76
76
  # Privacy request URLs
77
77
  PRIVACY_REQUESTS = "/privacy-request"
78
78
  PRIVACY_REQUEST_APPROVE = "/privacy-request/administrate/approve"
79
+ PRIVACY_REQUEST_BATCH_EMAIL_SEND = (
80
+ "/privacy-request/administrate/process-awaiting-email-send"
81
+ )
79
82
  PRIVACY_REQUEST_AUTHENTICATED = "/privacy-request/authenticated"
80
83
  PRIVACY_REQUEST_BULK_RETRY = "/privacy-request/bulk/retry"
81
84
  PRIVACY_REQUEST_BULK_SOFT_DELETE = "/privacy-request/bulk/soft-delete"
@@ -65,4 +65,12 @@ class ExecutionSettings(FidesSettings):
65
65
  default=True,
66
66
  description="Whether fuzzy search is enabled for privacy request lookups.",
67
67
  )
68
+ email_send_cron_expression: str = Field(
69
+ default="0 12 * * mon",
70
+ description="The cron expression to send batch emails for DSR email integration. Defaults to weekly on Mondays at 12pm (noon).",
71
+ )
72
+ email_send_timezone: str = Field(
73
+ default="US/Eastern",
74
+ description="The timezone to send batch emails for DSR email integration.",
75
+ )
68
76
  model_config = SettingsConfigDict(env_prefix=ENV_PREFIX)
@@ -1 +1 @@
1
- <!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link data-next-font="" rel="preconnect" href="/" crossorigin="anonymous"/><link rel="preload" href="/_next/static/css/5f8af79f94072e0f.css" as="style"/><link rel="stylesheet" href="/_next/static/css/5f8af79f94072e0f.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/_next/static/chunks/polyfills-42372ed130431b0a.js"></script><script src="/_next/static/chunks/webpack-8fc1c717e1c0f7ae.js" defer=""></script><script src="/_next/static/chunks/framework-c92fc3344e6fd165.js" defer=""></script><script src="/_next/static/chunks/main-090643377c8254e6.js" defer=""></script><script src="/_next/static/chunks/pages/_app-3e486cab9a918260.js" defer=""></script><script src="/_next/static/chunks/pages/404-ac335065bc49f818.js" defer=""></script><script src="/_next/static/BK56P69fQA7jyWB8H568y/_buildManifest.js" defer=""></script><script src="/_next/static/BK56P69fQA7jyWB8H568y/_ssgManifest.js" defer=""></script><style>.data-ant-cssinjs-cache-path{content:"";}</style></head><body><div id="__next"><div style="height:100%;display:flex"></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/404","query":{},"buildId":"BK56P69fQA7jyWB8H568y","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
1
+ <!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link data-next-font="" rel="preconnect" href="/" crossorigin="anonymous"/><link rel="preload" href="/_next/static/css/d522df24a125b46f.css" as="style"/><link rel="stylesheet" href="/_next/static/css/d522df24a125b46f.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/_next/static/chunks/polyfills-42372ed130431b0a.js"></script><script src="/_next/static/chunks/webpack-8fc1c717e1c0f7ae.js" defer=""></script><script src="/_next/static/chunks/framework-c92fc3344e6fd165.js" defer=""></script><script src="/_next/static/chunks/main-090643377c8254e6.js" defer=""></script><script src="/_next/static/chunks/pages/_app-be66c01c2b1de442.js" defer=""></script><script src="/_next/static/chunks/pages/404-ac335065bc49f818.js" defer=""></script><script src="/_next/static/e4X4A9FU3w3buLKgvkCKW/_buildManifest.js" defer=""></script><script src="/_next/static/e4X4A9FU3w3buLKgvkCKW/_ssgManifest.js" defer=""></script><style>.data-ant-cssinjs-cache-path{content:"";}</style></head><body><div id="__next"><div style="height:100%;display:flex"></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/404","query":{},"buildId":"e4X4A9FU3w3buLKgvkCKW","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[3988],{59969:function(e,t,i){var n=i(24246),r=i(86920);i(27378);var l=i(8557);t.Z=e=>{let{daysLeft:t,includeText:i,status:s}=e;if(!t||s===l.q.COMPLETE||s===l.q.CANCELED||s===l.q.DENIED||s===l.q.IDENTITY_UNVERIFIED)return(0,n.jsx)("span",{children:"-"});let a="";switch(!0){case t>=10:a="success";break;case t<10&&t>4:a="warning";break;case t<5:a="error"}return(0,n.jsx)(r.j8w,{color:a,children:i?"".concat(t," days left"):t})}},18225:function(e,t,i){var n=i(24246),r=i(86920);t.Z=e=>{let{alignment:t="center",...i}=e;return(0,n.jsx)(r.kCb,{boxSize:"full",align:"center",justify:t,children:(0,n.jsx)(r.$jN,{color:"primary",...i})})}},58754:function(e,t,i){var n=i(24246),r=i(86920),l=i(70788);t.Z=e=>{let{heading:t,breadcrumbItems:i,isSticky:s=!0,children:a,rightContent:d,style:o,...c}=e;return(0,n.jsxs)("div",{...c,style:s?{position:"sticky",top:"-24px",paddingTop:"24px",paddingBottom:"24px",paddingLeft:"40px",marginLeft:"-40px",paddingRight:"40px",marginRight:"-40px",marginTop:"-24px",left:0,zIndex:20,backgroundColor:"white",...o}:{paddingBottom:"24px",...o},children:[(0,n.jsxs)(r.jqI,{justify:"space-between",children:["string"==typeof t?(0,n.jsx)(r.lQT,{className:i||a?"pb-4":void 0,level:1,"data-testid":"page-heading",children:t}):t,d&&(0,n.jsx)("div",{"data-testid":"page-header-right-content",children:d})]}),!!i&&(0,n.jsx)(l.m,{className:a?"pb-4":void 0,items:i,"data-testid":"page-breadcrumb"}),a]})}},19904:function(e,t,i){i.d(t,{Tg:function(){return s}});var n=i(24246),r=i(16134),l=i(31793);let s=e=>(0,r.C)(l.uu).filter(t=>e.includes(t)).length>0;t.ZP=e=>{let{scopes:t,children:i}=e;return s(t)?(0,n.jsx)(n.Fragment,{children:i}):null}},14047:function(e,t,i){i.d(t,{H:function(){return l},V:function(){return n.V}});var n=i(84306),r=i(812);let l=()=>{let{errorAlert:e}=(0,n.V)();return{handleError:t=>{let i="An unexpected error occurred. Please try again.";(0,r.Ot)(t)?i=t.data.detail:(0,r.tB)(t)&&(i=t.data.detail[0].msg),e(i)}}}},84306:function(e,t,i){i.d(t,{V:function(){return l}});var n=i(24246),r=i(86920);let l=()=>{let e=(0,r.pmc)();return{errorAlert:(t,i,l)=>{let s={...l,position:(null==l?void 0:l.position)||"top",render:e=>{let{onClose:l}=e;return(0,n.jsxs)(r.bZj,{alignItems:"normal",status:"error","data-testid":"error-alert",children:[(0,n.jsx)(r.zMQ,{}),(0,n.jsxs)(r.xuv,{children:[i&&(0,n.jsx)(r.CdC,{children:i}),(0,n.jsx)(r.XaZ,{children:t})]}),(0,n.jsx)(r.PZ7,{onClick:l,position:"relative",right:0,size:"sm",top:-1})]})}};(null==l?void 0:l.id)&&e.isActive(l.id)?e.update(l.id,s):e(s)},successAlert:(t,i,l)=>{let s={...l,position:(null==l?void 0:l.position)||"top",render:e=>{let{onClose:l}=e;return(0,n.jsxs)(r.bZj,{alignItems:"normal",status:"success",variant:"subtle","data-testid":"success-alert",children:[(0,n.jsx)(r.zMQ,{}),(0,n.jsxs)(r.xuv,{children:[i&&(0,n.jsx)(r.CdC,{children:i}),(0,n.jsx)(r.XaZ,{children:t})]}),(0,n.jsx)(r.PZ7,{onClick:l,position:"relative",right:0,size:"sm",top:-1})]})}};(null==l?void 0:l.id)&&e.isActive(l.id)?e.update(l.id,s):e(s)}}}},70788:function(e,t,i){i.d(t,{m:function(){return o}});var n=i(24246),r=i(86920),l=i(79894),s=i.n(l),a=i(27378);let{Text:d}=r.AntTypography,o=e=>{let{items:t,...i}=e,l=(0,a.useMemo)(()=>null==t?void 0:t.map((e,i)=>{let l=i===t.length-1,a={...e},o=a.onClick&&!a.href;return("string"==typeof a.title&&(a.title=(0,n.jsx)(d,{style:{color:"inherit",maxWidth:l?void 0:400},ellipsis:!l,children:a.title})),o)?a.title=(0,n.jsx)(r.wpx,{type:"text",size:"small",icon:a.icon,onClick:a.onClick,className:"ant-breadcrumb-link -mt-px px-1 text-inherit",children:a.title}):(a.icon&&(a.title=(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)("span",{className:"anticon align-text-bottom",children:a.icon}),a.title]})),a.href&&a.title&&(a.title=(0,n.jsx)(s(),{href:a.href,className:"ant-breadcrumb-link",children:a.title}),delete a.href)),a}),[t]);return(0,n.jsx)(r.zrq,{items:l,...i})}},57526:function(e,t,i){var n=i(24246),r=i(86920),l=i(27378);t.Z=e=>{let{isOpen:t,onClose:i,onApproveRequest:s,isLoading:a,subjectRequest:d}=e,{identity:o,identity_verified_at:c,custom_privacy_request_fields:u}=d,h=(0,l.useCallback)(()=>{s().then(()=>{i()})},[s,i]);return(0,n.jsxs)(r.u_l,{isOpen:t,onClose:i,size:"lg",isCentered:!0,children:[(0,n.jsx)(r.ZAr,{}),(0,n.jsxs)(r.hzk,{children:[(0,n.jsx)(r.xBx,{children:"Privacy request approval"}),(0,n.jsxs)(r.fef,{paddingTop:0,paddingBottom:0,children:[(0,n.jsx)(r.xvT,{color:"gray.500",fontSize:"14px",marginBottom:4,children:"Are you sure you want to approve this privacy request?"}),(0,n.jsxs)(r.QI$,{children:[Object.entries(o).filter(e=>{let[,{value:t}]=e;return null!==t}).map(e=>{let[t,{value:i,label:l}]=e;return(0,n.jsx)(r.HCh,{children:(0,n.jsxs)(r.kCb,{alignItems:"flex-start",children:[(0,n.jsxs)(r.xvT,{mr:2,fontSize:"sm",color:"gray.900",fontWeight:"500",children:[l,":"]}),(0,n.jsx)(r.xvT,{color:"gray.600",fontWeight:"500",fontSize:"sm",mr:2,children:i}),"(",c?"Verified":"Unverified",")"]},t)},t)}),u&&Object.entries(u).filter(e=>{let[,t]=e;return t.value}).map(e=>{let[t,i]=e;return(0,n.jsx)(r.HCh,{children:(0,n.jsxs)(r.kCb,{alignItems:"flex-start",children:[(0,n.jsxs)(r.xvT,{mr:2,fontSize:"sm",color:"gray.900",fontWeight:"500",children:[i.label,":"]}),(0,n.jsxs)(r.xvT,{color:"gray.600",fontWeight:"500",fontSize:"sm",mr:2,children:[Array.isArray(i.value)?i.value.join(", "):i.value," "]}),"(Unverified)"]},t)},t)})]})]}),(0,n.jsx)(r.mzw,{children:(0,n.jsxs)(r.MIq,{columns:2,width:"100%",children:[(0,n.jsx)(r.wpx,{onClick:i,className:"mr-3","data-testid":"cancel-btn",children:"Cancel"}),(0,n.jsx)(r.wpx,{type:"primary","data-testid":"continue-btn",onClick:h,loading:a,children:"Confirm"})]})})]})]})}},66548:function(e,t,i){var n=i(24246),r=i(40324),l=i(86920),s=i(34090),a=i(27378),d=i(55484);let o={denialReason:""};t.Z=e=>{let{isOpen:t,onClose:i,onDenyRequest:c}=e,u=(0,a.useCallback)((e,t)=>{let{setSubmitting:n}=t;c(e.denialReason).then(()=>{n(!1),i()})},[c,i]);return(0,n.jsxs)(l.u_l,{isOpen:t,onClose:i,isCentered:!0,returnFocusOnClose:!1,children:[(0,n.jsx)(l.ZAr,{}),(0,n.jsx)(l.hzk,{width:"100%",maxWidth:"456px","data-testid":"deny-privacy-request-modal",children:(0,n.jsx)(s.J9,{initialValues:o,validationSchema:d.Ry({denialReason:d.Z_().required().label("Reason for denial")}),onSubmit:u,children:e=>{let{isSubmitting:t,dirty:a,isValid:d}=e;return(0,n.jsxs)(s.l0,{children:[(0,n.jsx)(l.xBx,{children:"Privacy request denial"}),(0,n.jsx)(l.fef,{color:"gray.500",fontSize:"14px",children:"Please enter a reason for denying this privacy request. Please note: this can be seen by the user in their notification email."}),(0,n.jsx)(l.fef,{children:(0,n.jsx)(r.Ks,{name:"denialReason",textAreaProps:{focusBorderColor:"primary.600",resize:"none"}})}),(0,n.jsxs)(l.mzw,{className:"flex w-full gap-4",children:[(0,n.jsx)(l.wpx,{disabled:t,onClick:i,className:"grow",children:"Cancel"}),(0,n.jsx)(l.wpx,{htmlType:"submit",type:"primary",disabled:!a||!d,loading:t,className:"grow","data-testid":"deny-privacy-request-modal-btn",children:"Confirm"})]})]})}})})]})}},45489:function(e,t,i){i.d(t,{Z:function(){return r}});var n=i(90867);let r=e=>{let{subjectRequest:t}=e,[i,r]=(0,n.RW)({fixedCacheKey:t.id}),[l,s]=(0,n.F1)({fixedCacheKey:t.id}),[a,d]=(0,n.rC)({fixedCacheKey:t.id}),o=s.isLoading||r.isLoading;return{approveRequest:i,approveRequestResult:r,denyRequest:l,denyRequestResult:s,handleApproveRequest:()=>i(t),handleDenyRequest:e=>l({id:t.id,reason:e}),handleDeleteRequest:()=>a(t),softDeleteRequestResult:d,isLoading:o}}},72281:function(e,t,i){i.d(t,{G:function(){return l},d:function(){return s}});var n=i(86677),r=i(27378);let l={REQUEST:"request",MANUAL_TASK:"manual-tasks"},s=()=>{let e=(0,n.useRouter)(),[t,i]=(0,r.useState)(l.REQUEST),s=(0,r.useMemo)(()=>({request:!0,manualTask:!0}),[]),a=(0,r.useCallback)(()=>{let{tab:t}=e.query;return t&&"string"==typeof t&&Object.values(l).includes(t)?t:null},[e.query]),d=(0,r.useCallback)(t=>{e.replace({pathname:e.pathname,query:{tab:t}},void 0,{shallow:!0})},[e]);return(0,r.useEffect)(()=>{if(!e.isReady)return;let t=a();if(t&&(t===l.REQUEST||t===l.MANUAL_TASK&&s.manualTask)){i(t);return}i(l.REQUEST),d(l.REQUEST)},[e.isReady,e.query,s,a,d]),{activeTab:t,handleTabChange:(0,r.useCallback)(e=>{Object.values(l).includes(e)&&(i(e),d(e))},[d]),availableTabs:s}}}}]);
@@ -0,0 +1 @@
1
+ (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[2369],{56141:function(e,t,s){var l=s(32866);e.exports=function(e,t){return l(e,t)}},1565:function(e,t,s){(window.__NEXT_P=window.__NEXT_P||[]).push(["/privacy-requests",function(){return s(27822)}])},35287:function(e,t,s){"use strict";var l=s(24246),i=s(86920),a=s(88038),r=s.n(a);s(27378),t.Z=e=>{let{children:t,title:s,mainProps:a}=e;return(0,l.jsxs)(i.kCb,{"data-testid":s,direction:"column",height:"calc(100vh - 48px)",width:"calc(100vw - 240px)",children:[(0,l.jsxs)(r(),{children:[(0,l.jsxs)("title",{children:["Fides Admin UI - ",s]}),(0,l.jsx)("meta",{name:"description",content:"Privacy Engineering Platform"}),(0,l.jsx)("link",{rel:"icon",href:"/favicon.ico"})]}),(0,l.jsx)(i.kCb,{px:10,py:6,as:"main",overflow:"auto",direction:"column",flex:1,minWidth:0,...a,children:t})]})}},87361:function(e,t,s){"use strict";var l=s(24246),i=s(86920);t.Z=e=>{let{title:t,text:s,onClose:a}=e;return(0,l.jsxs)(i.Ugi,{backgroundColor:"gray.50",border:"1px solid",borderRadius:"md",justifyContent:"space-between",py:4,pr:6,pl:3,"data-testid":"empty-state",gap:2,position:"relative",children:[a&&(0,l.jsx)(i.Two,{boxSize:5,position:"absolute",right:3,top:3,zIndex:1,cursor:"pointer",p:1,onClick:a}),(0,l.jsx)(i.iid,{alignSelf:"start",color:"minos",mt:.5,flexGrow:0}),(0,l.jsxs)(i.kCb,{direction:"column",gap:2,flexGrow:1,children:[(0,l.jsx)(i.X6q,{fontSize:"md",children:t}),(0,l.jsx)(i.xvT,{fontSize:"sm",color:"gray.600",lineHeight:"5",children:s})]})]})}},96718:function(e,t,s){"use strict";s.d(t,{z:function(){return a}});var l=s(24246),i=s(86920);let a=e=>{let{...t}=e,s="multiple"===t.mode;return(0,l.jsx)(i.WPr,{defaultActiveFirstOption:!1,maxTagCount:"responsive",allowClear:!0,dropdownStyle:s?void 0:{width:"auto",minWidth:"200px"},className:"w-auto","data-testid":"filter-select",...t})}},97181:function(e,t,s){"use strict";s.d(t,{d:function(){return o}});var l=s(24246),i=s(86920),a=s(34090),r=s(27378),n=s(46238),d=s(40324);let o=e=>{let{name:t,label:s,labelProps:o,tooltip:u,isRequired:c,layout:p="inline",helperText:m,...h}=e,[x,y,{setValue:v}]=(0,a.U$)(t),j=!!(y.touched&&y.error),[f,g]=(0,r.useState)("");x.value||"tags"!==h.mode&&"multiple"!==h.mode||(x.value=[]),"tags"===h.mode&&"string"==typeof x.value&&(x.value=[x.value]);let _="tags"===h.mode?(e,t)=>e?e.value!==f||x.value.includes(f)?h.optionRender?h.optionRender(e,t):e.label:'Create "'.concat(f,'"'):void 0:h.optionRender||void 0,b=e=>{g(e),h.onSearch&&h.onSearch(e)},C=(e,t)=>{v(e),h.onChange&&h.onChange(e,t)};return"inline"===p?(0,l.jsx)(i.NIc,{isInvalid:j,isRequired:c,children:(0,l.jsxs)(i.rjZ,{templateColumns:s?"1fr 3fr":"1fr",children:[s?(0,l.jsx)(d.__,{htmlFor:h.id||t,...o,children:s}):null,(0,l.jsxs)(i.jqI,{align:"center",children:[(0,l.jsxs)(i.jqI,{vertical:!0,flex:1,className:"mr-2",children:[(0,l.jsx)(i.WPr,{...x,id:h.id||t,"data-testid":"controlled-select-".concat(x.name),...h,optionRender:_,onSearch:"tags"===h.mode?b:void 0,onChange:C,value:x.value||void 0,status:j?"error":void 0}),m&&(0,l.jsx)(i.Q6r,{children:m}),(0,l.jsx)(d.Bc,{isInvalid:j,message:y.error,fieldName:x.name})]}),(0,l.jsx)(n.b,{label:u,className:j?"mt-2 self-start":void 0})]})]})}):(0,l.jsx)(i.NIc,{isInvalid:j,isRequired:c,children:(0,l.jsxs)(i.gCW,{alignItems:"start",children:[(0,l.jsxs)(i.jqI,{align:"center",children:[s?(0,l.jsx)(d.__,{htmlFor:h.id||t,fontSize:"xs",my:0,mr:1,...o,children:s}):null,(0,l.jsx)(n.b,{label:u})]}),(0,l.jsx)(i.WPr,{...x,id:h.id||t,"data-testid":"controlled-select-".concat(x.name),...h,optionRender:_,onSearch:"tags"===h.mode?b:void 0,onChange:C,value:x.value||void 0,status:j?"error":void 0}),m&&(0,l.jsx)(i.Q6r,{style:{marginTop:0},children:m}),(0,l.jsx)(d.Bc,{isInvalid:j,message:y.error,fieldName:x.name})]})})}},71784:function(e,t,s){"use strict";s.d(t,{DE:function(){return d},I3:function(){return i},kN:function(){return r},qX:function(){return n},rE:function(){return a}});var l=s(68309);let i=[...new Map([[l.q2.APPROVED,"Approved"],[l.q2.AWAITING_EMAIL_SEND,"Awaiting email send"],[l.q2.CANCELED,"Canceled"],[l.q2.COMPLETE,"Completed"],[l.q2.DENIED,"Denied"],[l.q2.ERROR,"Error"],[l.q2.IN_PROCESSING,"In progress"],[l.q2.PENDING,"New"],[l.q2.PAUSED,"Paused"],[l.q2.IDENTITY_UNVERIFIED,"Unverified"],[l.q2.REQUIRES_INPUT,"Requires input"]])].map(e=>{let[t,s]=e;return{label:s,value:t}}),a=new Map([[l.Us.ACCESS,"Access"],[l.Us.ERASURE,"Erasure"],[l.Us.CONSENT,"Consent"],[l.Us.UPDATE,"Update"]]),r=[...a].map(e=>{let[t,s]=e;return{label:s,value:t}}),n={mailgun:"mailgun",twilio_email:"twilio_email",twilio_text:"twilio_text"},d={local:"local",s3:"s3",gcs:"gcs"}},27822:function(e,t,s){"use strict";s.r(t),s.d(t,{default:function(){return eT}});var l,i,a=s(24246),r=s(35287),n=s(86920),d=s(65218),o=s.n(d),u=s(27378),c=s(25980),p=s(19904),m=s(56141),h=s.n(m),x=s(86677),y=s(16134),v=s(91317),j=s(59969),f=s(18225),g=s(77830),_=s(28407),b=s(42904),C=s(16394),q=s(71784),k=s(68309),S=s(45116);let E=e=>{let{label:t,children:s}=e;return(0,a.jsxs)("div",{className:"flex items-center",children:[(0,a.jsx)("div",{className:"shrink-0 grow-0 basis-1/3 pr-2",children:(0,a.jsxs)(n.AntTypography.Text,{className:"text-gray-700",children:[t,":"]})}),(0,a.jsx)("div",{className:"min-w-0 shrink grow text-gray-600",children:s})]})},w=e=>{let{task:t}=e,s=t.request_type===k.k6.ACCESS?k.Us.ACCESS:k.Us.ERASURE,l=q.rE.get(s)||t.request_type;return(0,a.jsxs)("div",{className:"flex flex-col space-y-3","data-testid":"task-details-container",children:[(0,a.jsx)(E,{label:"Name",children:(0,a.jsx)(n.AntTypography.Text,{children:t.name})}),(0,a.jsx)(E,{label:"Description",children:(0,a.jsx)(n.AntTypography.Text,{children:t.description||"-"})}),(0,a.jsx)(E,{label:"Request Type",children:(0,a.jsx)(n.AntTypography.Text,{children:l})}),(0,a.jsx)(E,{label:"Assigned To",children:t.assigned_users&&t.assigned_users.length>0?(0,a.jsx)("div",{className:"flex flex-wrap gap-1","data-testid":"assigned-users-tags",children:t.assigned_users.map(e=>(0,a.jsx)(n.j8w,{"data-testid":"assigned-user-tag-".concat(e.id),children:"".concat(e.first_name||""," ").concat(e.last_name||"").trim()||e.email_address||"Unknown User"},e.id))}):(0,a.jsx)(n.AntTypography.Text,{children:"No one assigned"})}),t.privacy_request.subject_identities&&Object.keys(t.privacy_request.subject_identities).length>0?(0,a.jsx)(E,{label:"Subject identities",children:(0,a.jsx)("div",{className:"flex flex-wrap gap-1",children:Object.entries(t.privacy_request.subject_identities).map(e=>{let[t,s]=e;return(0,a.jsxs)(n.j8w,{children:[t,": ",String(s)]},t)})})}):null,t.privacy_request.custom_fields&&Object.keys(t.privacy_request.custom_fields).length>0?(0,a.jsx)(E,{label:"Custom fields",children:(0,a.jsx)("div",{className:"flex flex-wrap gap-1",children:Object.entries(t.privacy_request.custom_fields).filter(e=>{let[,t]=e;return t}).map(e=>{let[t,s]=e;return(0,a.jsxs)(n.j8w,{children:[t,": ",s]},t)})})}):null]})},R=e=>{let{isOpen:t,onClose:s,task:l}=e,[i,{isLoading:r}]=(0,S.HP)(),[d,o]=(0,u.useState)(""),[c,p]=(0,u.useState)(!1),[m,h]=(0,u.useState)(""),[x,y]=(0,u.useState)([]),v=async()=>{try{await i({privacy_request_id:l.privacy_request.id,manual_field_id:l.manual_field_id,field_key:l.manual_field_id,field_value:l.input_type===k.PF.TEXT?d:l.input_type===k.PF.CHECKBOX?c.toString():void 0,comment_text:m||void 0,attachment:x.length>0?x[0].originFileObj:void 0}).unwrap(),o(""),p(!1),h(""),y([]),s()}catch(e){n.Pg3.error("Failed to complete task. Please try again.")}};return(0,a.jsxs)(n.u_l,{isOpen:t,onClose:s,size:"700px",isCentered:!0,children:[(0,a.jsx)(n.ZAr,{}),(0,a.jsxs)(n.hzk,{maxWidth:"700px","data-testid":"complete-task-modal",children:[(0,a.jsx)(n.xBx,{children:(0,a.jsx)(n.AntTypography.Title,{level:4,children:"Complete Task"})}),(0,a.jsx)(n.fef,{children:(0,a.jsxs)("div",{className:"flex flex-col space-y-6",children:[(0,a.jsx)("div",{children:(0,a.jsx)(w,{task:l})}),(0,a.jsx)(n.htM,{}),(0,a.jsx)("div",{children:(0,a.jsxs)("div",{className:"flex flex-col space-y-4",children:[(()=>{switch(l.input_type){case k.PF.TEXT:return(0,a.jsxs)("div",{className:"space-y-2",children:[(0,a.jsx)("div",{className:"text-sm font-medium text-gray-700",children:"Subject data"}),(0,a.jsx)(n.uFc.TextArea,{value:d,onChange:e=>o(e.target.value),placeholder:"Enter your response...",rows:4,"data-testid":"complete-modal-text-input"})]});case k.PF.CHECKBOX:return(0,a.jsx)("div",{className:"space-y-2",children:(0,a.jsx)(n.E_O,{checked:c,onChange:e=>p(e.target.checked),"data-testid":"complete-modal-checkbox",children:"The task has been completed"})});default:return(0,a.jsxs)("div",{className:"space-y-2",children:[(0,a.jsx)("div",{className:"text-sm font-medium text-gray-700",children:"Upload File"}),(0,a.jsx)("div",{children:(0,a.jsx)(n.pMK,{fileList:x,onChange:e=>{let{fileList:t}=e;return y(t)},beforeUpload:()=>!1,"data-testid":"complete-modal-file-upload",children:(0,a.jsx)(n.wpx,{"data-testid":"complete-modal-upload-button",children:"Click to Upload"})})})]})}})(),(0,a.jsxs)("div",{className:"space-y-2",children:[(0,a.jsx)("div",{className:"text-sm font-medium text-gray-700",children:"Internal comment"}),(0,a.jsx)(n.uFc.TextArea,{value:m,onChange:e=>h(e.target.value),placeholder:"Add any additional comments...",rows:3,"data-testid":"complete-modal-comment-input"})]})]})})]})}),(0,a.jsx)(n.mzw,{children:(0,a.jsxs)(n.vyj,{children:[(0,a.jsx)(n.wpx,{onClick:()=>{o(""),p(!1),h(""),y([]),s()},disabled:r,"data-testid":"complete-modal-cancel-button",children:"Cancel"}),(0,a.jsx)(n.wpx,{type:"primary",onClick:v,loading:r,disabled:!(()=>{switch(l.input_type){case k.PF.TEXT:return d.trim().length>0;case k.PF.CHECKBOX:return c;default:return x.length>0}})(),"data-testid":"complete-modal-save-button",children:"Save"})]})})]})]})},T=e=>{let{isOpen:t,onClose:s,task:l}=e,[i,{isLoading:r}]=(0,S.DA)(),[d,o]=(0,u.useState)(""),c=async()=>{try{await i({privacy_request_id:l.privacy_request.id,manual_field_id:l.manual_field_id,field_key:l.manual_field_id,skip_reason:d}).unwrap(),o(""),s()}catch(e){n.Pg3.error("Failed to skip task. Please try again.")}};return(0,a.jsxs)(n.u_l,{isOpen:t,onClose:s,size:"700px",isCentered:!0,children:[(0,a.jsx)(n.ZAr,{}),(0,a.jsxs)(n.hzk,{maxWidth:"700px","data-testid":"skip-task-modal",children:[(0,a.jsx)(n.xBx,{children:(0,a.jsx)(n.AntTypography.Title,{level:4,children:"Skip Task"})}),(0,a.jsx)(n.fef,{children:(0,a.jsxs)("div",{className:"flex flex-col space-y-6",children:[(0,a.jsx)("div",{children:(0,a.jsx)(w,{task:l})}),(0,a.jsx)(n.htM,{}),(0,a.jsx)("div",{children:(0,a.jsx)("div",{className:"flex flex-col space-y-4",children:(0,a.jsxs)("div",{className:"space-y-2",children:[(0,a.jsx)("div",{className:"text-sm font-medium text-gray-700",children:"Reason for skipping (Required)"}),(0,a.jsx)(n.uFc.TextArea,{value:d,onChange:e=>o(e.target.value),placeholder:"Please provide a reason for skipping this task...",rows:4,"data-testid":"skip-modal-comment-input"})]})})})]})}),(0,a.jsx)(n.mzw,{children:(0,a.jsxs)(n.vyj,{children:[(0,a.jsx)(n.wpx,{onClick:()=>{o(""),s()},disabled:r,"data-testid":"skip-modal-cancel-button",children:"Cancel"}),(0,a.jsx)(n.wpx,{type:"primary",onClick:c,loading:r,disabled:!d.trim(),danger:!0,"data-testid":"skip-modal-skip-button",children:"Skip Task"})]})})]})]})},P=e=>{let{task:t}=e,s=(0,x.useRouter)(),{isOpen:l,onOpen:i,onClose:r}=(0,n.qY0)(),{isOpen:d,onOpen:o,onClose:u}=(0,n.qY0)();if(t.status!==k.OS.NEW)return null;let c=[{key:"skip",label:"Skip task",onClick:o},{key:"go-to-request",label:"Go to request",onClick:()=>{s.push({pathname:g.ld,query:{id:t.privacy_request.id}})}}];return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)(n.vyj,{size:"small",children:[(0,a.jsx)(n.wpx,{type:"default",onClick:i,size:"small",children:"Complete"}),(0,a.jsx)(n.S0p,{menu:{items:c},trigger:["click"],placement:"bottomRight",overlayStyle:{minWidth:120},children:(0,a.jsx)(n.wpx,{size:"small",icon:(0,a.jsx)(n.PJP.r43,{}),"aria-label":"More actions"})})]}),(0,a.jsx)(R,{isOpen:l,onClose:r,task:t}),(0,a.jsx)(T,{isOpen:d,onClose:u,task:t})]})},I={[k.OS.NEW]:{color:"info",label:"New"},[k.OS.COMPLETED]:{color:"success",label:"Completed"},[k.OS.SKIPPED]:{color:"marble",label:"Skipped"}},A=[{text:"New",value:k.OS.NEW},{text:"Completed",value:k.OS.COMPLETED},{text:"Skipped",value:k.OS.SKIPPED}],N=[{text:"Access",value:k.k6.ACCESS},{text:"Erasure",value:k.k6.ERASURE}],O=(e,t,s,l)=>[{title:"Task name",dataIndex:"name",key:"name",width:300,render:e=>(0,a.jsx)(n.AntTypography.Text,{ellipsis:{tooltip:e},children:e})},{title:"Status",dataIndex:"status",key:"status",width:120,render:e=>(0,a.jsx)(n.j8w,{color:I[e].color,"data-testid":"manual-task-status-tag",children:I[e].label}),filters:A,filterMultiple:!1},{title:"System",dataIndex:["system","name"],key:"system_name",width:210,filters:e,filterMultiple:!1},{title:"Type",dataIndex:"request_type",key:"request_type",width:150,render:e=>{let t=e===k.k6.ACCESS?k.Us.ACCESS:k.Us.ERASURE,s=q.rE.get(t)||e;return(0,a.jsx)(n.AntTypography.Text,{children:s})},filters:N,filterMultiple:!1},{title:"Assigned to",dataIndex:"assigned_users",key:"assigned_users",width:380,render:e=>{if(!e||0===e.length)return(0,a.jsx)(n.AntTypography.Text,{children:"-"});let t=e.map(e=>({label:(0,C.gJ)(e),value:e.id})),l=e.map(e=>e.id);return(0,a.jsx)(n.d3V,{value:l,options:t,readonly:!0,onTagClick:e=>s(String(e))})},filters:t,filterMultiple:!1,defaultFilteredValue:l.assignedUsers?[l.assignedUsers]:void 0},{title:"Days left",dataIndex:["privacy_request","days_left"],key:"days_left",width:140,render:e=>(0,a.jsx)(j.Z,{daysLeft:e||0,includeText:!1,status:k.q2.PENDING})},{title:"Subject identity",dataIndex:["privacy_request","subject_identities"],key:"subject_identities",width:200,render:e=>{if(!e)return(0,a.jsx)(n.AntTypography.Text,{children:"-"});let t=e.email||e.phone_number||"";return(0,a.jsx)(n.AntTypography.Text,{ellipsis:{tooltip:t},children:t})}},{title:"Actions",key:"actions",width:120,render:(e,t)=>(0,a.jsx)(P,{task:t})}],U=()=>{let e=(0,x.useRouter)(),t=(0,y.C)(v.dy),[s,l]=(0,u.useState)(1),[i,r]=(0,u.useState)(25),d=e.query.privacy_request_id||void 0,o=(0,u.useMemo)(()=>{let e={};return(null==t?void 0:t.id)&&!d&&(e.assignedUsers=t.id),d&&"string"==typeof d&&(e.privacyRequestId=d),e},[null==t?void 0:t.id,d]),[c,p]=(0,u.useState)(o),{data:m,isLoading:j,isFetching:q}=(0,S.Ym)({page:s,size:i,status:c.status,systemName:c.systemName,requestType:c.requestType,assignedUserId:c.assignedUsers,privacyRequestId:c.privacyRequestId}),{data:k}=(0,S.Ym)({page:1,size:1}),{items:E,total:w}=(0,u.useMemo)(()=>m||{items:[],total:0,pages:0,filter_options:{assigned_users:[],systems:[]}},[m]),R=(0,u.useMemo)(()=>(null==k?void 0:k.filter_options)||{assigned_users:[],systems:[]},[k]),T=(0,u.useMemo)(()=>{var e;return(null==R?void 0:null===(e=R.systems)||void 0===e?void 0:e.map(e=>({text:e.name,value:e.name})))||[]},[null==R?void 0:R.systems]),P=(0,u.useMemo)(()=>{var e;let s=(null==R?void 0:null===(e=R.assigned_users)||void 0===e?void 0:e.map(e=>({text:(0,C.gJ)(e),value:e.id})))||[];return(null==t?void 0:t.id)&&!(null==t?void 0:t.id.startsWith("fid_"))&&s.push({text:(null==t?void 0:t.username)||(null==t?void 0:t.id),value:t.id}),s},[null==R?void 0:R.assigned_users,null==t?void 0:t.id,null==t?void 0:t.username]),I=(0,u.useMemo)(()=>O(T,P,t=>{e.push({pathname:g.fw,query:{id:t}})},c),[T,P,e,c]),A=(0,u.useMemo)(()=>h()(c,o),[c,o]);return j?(0,a.jsx)(f.Z,{}):(0,a.jsxs)("div",{className:"mt-2 space-y-4",children:[(0,a.jsx)(n.kCb,{gap:3,align:"center",className:"mb-4",children:(0,a.jsx)(_.H,{globalFilter:c.privacyRequestId||"",setGlobalFilter:e=>{let t={...c};e&&e.trim()?t.privacyRequestId=e.trim():delete t.privacyRequestId,p(t),l(1)},placeholder:"Search by privacy request ID",testid:"privacy-request-id-filter"})}),(0,a.jsx)(n.V5H,{columns:I,dataSource:E,rowKey:e=>"".concat(e.privacy_request.id,"-").concat(e.manual_field_id),pagination:{current:s,pageSize:i,total:w||0,showSizeChanger:!0,pageSizeOptions:b.W3,showTotal:(e,t)=>"".concat(t[0],"-").concat(t[1]," of ").concat(e," items"),onChange:(e,t)=>{l(e),t!==i&&(r(t),l(1))}},onChange:(e,t)=>{let s={privacyRequestId:c.privacyRequestId};t.status&&([s.status]=t.status),t.system_name&&([s.systemName]=t.system_name),t.request_type&&([s.requestType]=t.request_type),t.assigned_users&&([s.assignedUsers]=t.assigned_users),p(s),l(1)},locale:{emptyText:A?(0,a.jsx)("div",{"data-testid":"empty-state-current-user",className:"my-4",children:(0,a.jsx)(n.AntTypography.Paragraph,{children:'You have no tasks assigned. You can modify the "Assigned to" column filter to view tasks assigned to other users.'})}):(0,a.jsx)("div",{"data-testid":"empty-state",className:"my-4",children:"No results found."})},loading:j||q})]})};var D=s(59003),F=s(92222),z=s(16125),M=s(14048),Z=s(47935),V=s(90867);let L={approved:{colorScheme:"success",label:"Approved"},complete:{label:"Completed",colorScheme:"success"},awaiting_email_send:{label:"Awaiting Email Send",colorScheme:"marble"},denied:{label:"Denied",colorScheme:"warning"},canceled:{label:"Canceled",colorScheme:"marble"},error:{label:"Error",colorScheme:"error"},in_processing:{label:"In Progress",colorScheme:"caution"},paused:{label:"Paused",colorScheme:"marble"},pending:{label:"New",colorScheme:"info"},identity_unverified:{label:"Unverified",colorScheme:"marble"},requires_input:{colorScheme:"minos",label:"Requires Input"}},Y=e=>{let{value:t}=e;return(0,a.jsx)(Z.A4,{color:L[t].colorScheme,value:L[t].label,"data-testid":"request-status-badge"})},W=e=>{let t,{daysLeft:s,timeframe:l=45,status:i,includeText:r=!1}=e;if(null==s||i===k.q2.COMPLETE||i===k.q2.CANCELED||i===k.q2.DENIED||i===k.q2.IDENTITY_UNVERIFIED)return null;let n=100*s/l;return n<25?t="error":n>=75?t="success":n>=25&&(t="warning"),(0,a.jsx)(Z.A4,{value:r?"".concat(s," days left"):s.toString(),color:t})},B=e=>Array.from(new Set(e.filter(e=>Object.values(k.Us).includes(e.action_type)).map(e=>e.action_type))),G=e=>{let{value:t}=e,s=B(t).map(e=>q.rE.get(e));return(0,a.jsx)(Z.WP,{value:s,cellState:{isExpanded:!0}})};var K=s(58452),X=s(57526),H=s(66548),Q=s(45489);let J=e=>{let{subjectRequest:t,...s}=e,l=(0,n.qY0)(),i=(0,n.qY0)(),r=(0,n.qY0)(),{handleApproveRequest:d,handleDenyRequest:o,handleDeleteRequest:u,isLoading:c}=(0,Q.Z)({subjectRequest:t});return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)(n.Ugi,{...s,children:["pending"!==t.status?null:(0,a.jsx)(n.wpx,{title:"Approve","aria-label":"Approve",icon:(0,a.jsx)(n.PJP.MCw,{}),onClick:l.onOpen,loading:c,disabled:c,"data-testid":"privacy-request-approve-btn",size:"small"}),"pending"!==t.status?null:(0,a.jsx)(n.wpx,{title:"Deny","aria-label":"Deny",icon:(0,a.jsx)(n.PJP.x8P,{}),onClick:i.onOpen,loading:c,disabled:c,"data-testid":"privacy-request-deny-btn",size:"small"}),(0,a.jsx)(p.ZP,{scopes:[k.Sh.PRIVACY_REQUEST_DELETE],children:(0,a.jsx)(n.wpx,{title:"Delete","aria-label":"Delete",icon:(0,a.jsx)(n.PJP.ZNm,{size:14}),onClick:r.onOpen,loading:c,disabled:c,"data-testid":"privacy-request-delete-btn",size:"small"})})]}),(0,a.jsx)(n.h_i,{children:(0,a.jsx)(X.Z,{isOpen:l.isOpen,isLoading:c,onClose:l.onClose,onApproveRequest:d,subjectRequest:t})}),(0,a.jsx)(n.h_i,{children:(0,a.jsx)(H.Z,{isOpen:i.isOpen,onClose:i.onClose,onDenyRequest:o})}),(0,a.jsx)(K.Z,{isOpen:r.isOpen,onClose:r.onClose,onConfirm:u,message:(0,a.jsx)(n.xvT,{children:"You are about to permanently delete the privacy request. Are you sure you would like to continue?"})})]})};(l=i||(i={})).STATUS="status",l.DAYS_LEFT="due_date",l.SOURCE="source",l.REQUEST_TYPE="request_type",l.SUBJECT_IDENTITY="subject_identity",l.TIME_RECEIVED="created_at",l.CREATED_BY="created_by",l.REVIEWER="reviewer",l.ID="id",l.ACTIONS="actions";let $=(0,F.Cl)(),ee=function(){let e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];return[$.accessor(e=>e.status,{id:"status",cell:e=>{let{getValue:t}=e;return(0,a.jsx)(Y,{value:t()})},header:e=>(0,a.jsx)(Z.Rr,{value:"Status",...e})}),$.accessor(e=>e.days_left,{id:"due_date",cell:e=>{let{row:t,getValue:s}=e;return(0,a.jsx)(W,{daysLeft:s(),timeframe:t.original.policy.execution_timeframe,status:t.original.status})},header:e=>(0,a.jsx)(Z.Rr,{value:"Days left",...e})}),...e?[$.accessor(e=>e.source,{id:"source",cell:e=>e.getValue()?(0,a.jsx)(Z.A4,{value:e.getValue()}):(0,a.jsx)(Z.G3,{value:void 0}),header:e=>(0,a.jsx)(Z.Rr,{value:"Source",...e}),enableSorting:!1})]:[],$.accessor(e=>e.policy.rules,{id:"request_type",cell:e=>{let{getValue:t}=e;return(0,a.jsx)(G,{value:t()})},header:e=>(0,a.jsx)(Z.Rr,{value:"Request type",...e}),enableSorting:!1}),$.accessor(e=>{var t,s;return(null===(t=e.identity)||void 0===t?void 0:t.email.value)||(null===(s=e.identity)||void 0===s?void 0:s.phone_number.value)||""},{id:"subject_identity",cell:e=>{let{getValue:t}=e;return(0,a.jsx)(Z.G3,{value:t()})},header:e=>(0,a.jsx)(Z.Rr,{value:"Subject identity",...e}),enableSorting:!1}),$.accessor(e=>e.created_at,{id:"created_at",cell:e=>{let{getValue:t}=e;return(0,a.jsx)(Z.G3,{value:(0,C.p6)(t())})},header:e=>(0,a.jsx)(Z.Rr,{value:"Time received",...e})}),$.accessor(e=>{var t;return(null===(t=e.reviewer)||void 0===t?void 0:t.username)||""},{id:"reviewer",cell:e=>{let{getValue:t}=e;return(0,a.jsx)(Z.G3,{value:t()})},header:e=>(0,a.jsx)(Z.Rr,{value:"Reviewed by",...e}),enableSorting:!1}),$.accessor(e=>e.id,{id:"id",cell:e=>{let{getValue:t}=e;return(0,a.jsx)(Z.G3,{value:t()})},header:e=>(0,a.jsx)(Z.Rr,{value:"Request ID",...e}),enableSorting:!1}),$.display({id:"actions",cell:e=>{let{row:t}=e;return(0,a.jsx)(J,{subjectRequest:t.original})},header:e=>(0,a.jsx)(Z.Rr,{value:"Actions",...e}),meta:{disableRowClick:!0}})]},et=e=>{let t=(0,z.v9)(V.dp),s=(0,z.I0)();return{handleStatusChange:t=>{s((0,V.CI)(t)),e()},handleActionTypeChange:t=>{s((0,V.aM)(t)),e()},handleFromChange:t=>{s((0,V.su)(null==t?void 0:t.target.value)),e()},handleToChange:t=>{s((0,V.Ue)(null==t?void 0:t.target.value)),e()},handleClearAllFilters:()=>{s((0,V.Mk)()),e()},...t}};var es=s(96718);let el=e=>{let{onClose:t,onFilterChange:s,...l}=e,{handleStatusChange:i,handleActionTypeChange:r,handleFromChange:d,handleToChange:o,handleClearAllFilters:u,from:c,to:p,status:m,action_type:h}=et(s);return(0,a.jsxs)(n.u_l,{onClose:t,size:"xl",...l,children:[(0,a.jsx)(n.ZAr,{}),(0,a.jsxs)(n.hzk,{children:[(0,a.jsx)(n.xBx,{borderBottomWidth:1,borderBottomColor:"gray.200",children:"All Filters"}),(0,a.jsx)(n.olH,{}),(0,a.jsx)(n.fef,{py:4,sx:{"& label":{mb:0}},children:(0,a.jsxs)(n.Kqy,{gap:4,children:[(0,a.jsxs)(n.Kqy,{children:[(0,a.jsx)(n.lXp,{size:"md",id:"request-date-range-label",children:"Date range"}),(0,a.jsxs)(n.Ugi,{gap:3,children:[(0,a.jsxs)(n.BZy,{size:"sm",flex:1,children:[(0,a.jsx)(n.UiE,{as:"label",htmlFor:"from-date",borderRadius:"md",children:"From"}),(0,a.jsx)(n.IIB,{type:"date",name:"From",value:c,max:p||void 0,onChange:d,borderRadius:"md",id:"from-date","aria-describedby":"request-date-range-label"})]}),(0,a.jsxs)(n.BZy,{size:"sm",flex:1,children:[(0,a.jsx)(n.UiE,{as:"label",htmlFor:"to-date",borderRadius:"md",children:"To"}),(0,a.jsx)(n.IIB,{type:"date",borderRadius:"md",name:"To",value:p,min:c||void 0,onChange:o,id:"to-date","aria-describedby":"request-date-range-label"})]})]})]}),(0,a.jsxs)(n.Kqy,{children:[(0,a.jsx)(n.lXp,{size:"md",htmlFor:"request-status",children:"Status"}),(0,a.jsx)(es.z,{id:"request-status",mode:"multiple",options:q.I3,value:m,onChange:i,"data-testid":"request-status-filter"})]}),(0,a.jsxs)(n.Kqy,{children:[(0,a.jsx)(n.lXp,{size:"md",htmlFor:"request-action-type",children:"Request Type"}),(0,a.jsx)(es.z,{id:"request-action-type",mode:"multiple",options:q.kN,value:h,onChange:r,"data-testid":"request-action-type-filter"})]})]})}),(0,a.jsxs)(n.mzw,{justifyContent:"space-between",children:[(0,a.jsx)(n.wpx,{type:"text",onClick:u,children:"Clear all"}),(0,a.jsx)(n.wpx,{type:"primary",onClick:t,children:"Done"})]})]})]})},ei=e=>{let{...t}=e,{plus:s}=(0,c.hz)(),[l,i]=(0,u.useState)(""),r=(0,z.v9)(V.dp),d=(0,z.v9)(v.rK),o=(0,n.pmc)(),p=(0,x.useRouter)(),m=(0,z.I0)(),{PAGE_SIZES:h,pageSize:y,setPageSize:j,onPreviousPageClick:f,isPreviousPageDisabled:g,onNextPageClick:_,isNextPageDisabled:b,startRange:C,endRange:q,pageIndex:k,setTotalPages:S,resetPageIndexToDefault:E}=(0,Z.oi)(),{isOpen:w,onOpen:R,onClose:T}=(0,n.qY0)(),{data:P,isLoading:I,isFetching:A}=(0,V.QA)({...r,page:k,size:y}),{items:N,total:O}=(0,u.useMemo)(()=>{let e=P||{items:[],total:0,pages:0};return S(e.pages),e},[P,S]),U=(0,u.useCallback)(e=>{m((0,V.mU)(e)),i(e),E()},[m,E,i]),L=async()=>{let e;try{await (0,V.py)({...r,token:d})}catch(t){e=t instanceof Error?t.message:"Unknown error occurred"}e&&o({description:"".concat(e),duration:5e3,status:"error"})},Y=e=>{p.push("/privacy-requests/".concat(e))},W=(0,D.b7)({getCoreRowModel:(0,F.sC)(),data:N,columns:(0,u.useMemo)(()=>ee(s),[s]),getRowId:e=>"".concat(e.status,"-").concat(e.id),manualPagination:!0,columnResizeMode:"onChange"});return(0,a.jsxs)(n.xuv,{...t,children:[(0,a.jsxs)(Z.Q$,{children:[(0,a.jsx)(Z.HO,{globalFilter:l,setGlobalFilter:U,placeholder:"Search by request ID or identity value"}),(0,a.jsxs)(n.Ugi,{alignItems:"center",spacing:2,children:[(0,a.jsx)(n.wpx,{"data-testid":"filter-btn",onClick:R,children:"Filter"}),(0,a.jsx)(n.wpx,{"aria-label":"Export report","data-testid":"export-btn",icon:(0,a.jsx)(M.nM,{ml:"1.5px"}),onClick:L})]}),(0,a.jsx)(n.h_i,{children:(0,a.jsx)(el,{isOpen:w,onClose:T,onFilterChange:E})})]}),I?(0,a.jsx)(n.xuv,{p:2,borderWidth:1,children:(0,a.jsx)(Z.I4,{rowHeight:26,numRows:10})}):(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(Z.ZK,{tableInstance:W,onRowClick:e=>Y(e.id),onSort:e=>{if(!e){m((0,V.p2)()),E();return}let{id:t,desc:s}=e;m((0,V.PU)(t)),m((0,V.iX)(s?"desc":"asc")),E()}}),(0,a.jsx)(Z.s8,{totalRows:O||0,pageSizes:h,setPageSize:j,onPreviousPageClick:f,isPreviousPageDisabled:g||A,onNextPageClick:_,isNextPageDisabled:b||A,startRange:C,endRange:q})]})]})};var ea=s(812),er=s(87361),en=s(46628),ed=s(32885),eo=s(34090),eu=s(55484),ec=s(40324);let ep=(e,t)=>null==t?void 0:t.find(t=>t.policy_key===e),em=e=>{var t,s;if(!e)return eu.Ry().shape({policy_key:eu.Z_().required().label("Request type")});let l=e.custom_privacy_request_fields?Object.entries(e.custom_privacy_request_fields).map(e=>{let[t,s]=e;return{[t]:eu.Ry().shape({value:s.required&&!s.hidden?eu.Z_().required().label(s.label):eu.Z_().nullable()})}}).reduce((e,t)=>({...e,...t}),{}):{};return eu.Ry().shape({policy_key:eu.Z_().required().label("Request type"),identity:eu.Ry().shape({email:(null===(t=e.identity_inputs)||void 0===t?void 0:t.email)==="required"?eu.Z_().email().required().label("Email address"):eu.Z_().nullable(),phone_number:(null===(s=e.identity_inputs)||void 0===s?void 0:s.phone)==="required"?eu.Z_().matches(/^\+?[1-9]\d{1,14}$/,"Phone number must be formatted correctly (e.g. 15555555555)").required().label("Phone number"):eu.Z_().matches(/^\+?[1-9]\d{1,14}$/,"Phone number must be formatted correctly (e.g. 15555555555)").nullable()}),custom_privacy_request_fields:eu.Ry().shape(l)})};var eh=s(97181);let ex={is_verified:!1,policy_key:"",identity:{}},ey=e=>{let{identityInputs:t}=e;return t?(0,a.jsxs)(a.Fragment,{children:[t.email?(0,a.jsx)(ec.j0,{name:"identity.email",label:"User email address",isRequired:"required"===t.email,variant:"stacked"}):null,t.phone?(0,a.jsx)(ec.j0,{name:"identity.phone_number",label:"User phone number",isRequired:"required"===t.phone,variant:"stacked"}):null]}):null},ev=e=>{let{customFieldInputs:t}=e;if(!t)return null;let s=Object.entries(t);return(0,a.jsx)(a.Fragment,{children:s.map(e=>{let[t,s]=e;return(0,a.jsx)(ec.j0,{name:"custom_privacy_request_fields.".concat(t,".value"),label:s.label,isRequired:!!s.required,variant:"stacked"},t)})})},ej=e=>{let{onSubmit:t,onCancel:s,privacyCenterUrl:l}=e,{onCopy:i}=(0,n.VPI)(""),r=(0,n.pmc)();return(0,a.jsx)(eo.J9,{initialValues:{identity:{email:""}},onSubmit:e=>{i("".concat(l,"?email=").concat(encodeURIComponent(e.identity.email))),t(e),r({status:"success",description:"DSR Link Copied!"})},validationSchema:()=>eu.Ry().shape({identity:eu.Ry().shape({email:eu.Z_().email().required().label("Email Address")})}),children:e=>{let{dirty:t,isValid:l}=e;return(0,a.jsx)(eo.l0,{children:(0,a.jsxs)(n.Kqy,{spacing:6,mb:2,children:[(0,a.jsx)(ey,{identityInputs:{email:"required"}}),(0,a.jsxs)("div",{className:"flex gap-4 self-end",children:[(0,a.jsx)(n.wpx,{onClick:s,children:"Cancel"}),(0,a.jsx)(n.wpx,{htmlType:"submit",type:"primary",disabled:!t||!l,"data-testid":"submit-btn",icon:(0,a.jsx)(n.xPt,{}),children:"Copy"})]})]})})}})};var ef=e=>{let{onSubmit:t,onCancel:s}=e,{data:l}=(0,V.xv)();return(0,a.jsx)(eo.J9,{initialValues:ex,onSubmit:t,validationSchema:()=>(0,eu.Vo)(e=>em(ep(e.policy_key,null==l?void 0:l.actions))),children:e=>{var t;let{values:i,dirty:r,isValid:d,isSubmitting:o,setFieldValue:u}=e,c=ep(i.policy_key,null==l?void 0:l.actions);return(0,a.jsx)(eo.l0,{children:(0,a.jsxs)(n.Kqy,{spacing:6,mb:2,children:[(0,a.jsx)(eh.d,{name:"policy_key",label:"Request type",options:null!==(t=null==l?void 0:l.actions.map(e=>({label:e.title,value:e.policy_key})))&&void 0!==t?t:[],onChange:e=>{let t=ep(e,null==l?void 0:l.actions);if(!(null==t?void 0:t.custom_privacy_request_fields)){u("custom_privacy_request_fields",void 0);return}u("custom_privacy_request_fields",Object.entries(t.custom_privacy_request_fields).map(e=>{let[t,s]=e;return{[t]:{label:s.label,value:s.default_value}}}).reduce((e,t)=>({...e,...t}),{}))},layout:"stacked",isRequired:!0}),(0,a.jsx)(ey,{identityInputs:null==c?void 0:c.identity_inputs}),(0,a.jsx)(ev,{customFieldInputs:null==c?void 0:c.custom_privacy_request_fields}),(0,a.jsx)(ec.Xl,{name:"is_verified",label:"I confirm that I have verified this user information"}),(0,a.jsxs)("div",{className:"flex gap-4 self-end",children:[(0,a.jsx)(n.wpx,{onClick:s,children:"Cancel"}),(0,a.jsx)(n.wpx,{htmlType:"submit",type:"primary",disabled:!i.is_verified||!r||!d,loading:o,"data-testid":"submit-btn",children:"Create"})]})]})})}})},eg=s(31883);let e_=e=>{let{isOpen:t,onClose:s}=e,[l]=(0,V.M6)(),i=(0,n.pmc)(),r=async e=>{let{is_verified:t,...a}=e,r=a.custom_privacy_request_fields?Object.entries(a.custom_privacy_request_fields).map(e=>{let[t,s]=e;return s.value?{[t]:s}:{}}).reduce((e,t)=>({...e,...t}),{}):void 0,n={...a,custom_privacy_request_fields:r},d=await l([n]);(0,eg.D4)(d)?i((0,en.Vo)((0,ea.e$)(d.error,"An error occurred while creating this privacy request. Please try again"))):i((0,en.t5)("Privacy request created")),s()};return(0,a.jsxs)(n.u_l,{isOpen:t,onClose:s,size:"2xl",isCentered:!0,children:[(0,a.jsx)(n.ZAr,{}),(0,a.jsxs)(n.hzk,{"data-testid":"submit-request-modal",maxHeight:"80%",overflowY:"auto",children:[(0,a.jsx)(n.xBx,{children:"Create privacy request"}),(0,a.jsx)(n.fef,{children:(0,a.jsxs)(n.Kqy,{spacing:4,children:[(0,a.jsx)(er.Z,{title:"Warning: You are bypassing identity verification",text:"You are bypassing Fides' built-in identity verification step. Please ensure that you are only entering information on behalf of a verified and approved user's privacy request."}),(0,a.jsx)(ef,{onSubmit:r,onCancel:()=>s()})]})})]})]})},eb=e=>{let{isOpen:t,onClose:s,privacyCenterUrl:l}=e;return(0,a.jsxs)(n.u_l,{size:"md",isOpen:t,onClose:s,children:[(0,a.jsx)(n.ZAr,{}),(0,a.jsxs)(n.hzk,{children:[(0,a.jsx)(n.xBx,{children:"Create a Privacy Request Link"}),(0,a.jsxs)(n.fef,{children:[(0,a.jsx)(n.Kqy,{spacing:4}),(0,a.jsx)(ej,{privacyCenterUrl:l,onSubmit:s,onCancel:s})]})]})]})};var eC=()=>{var e;let[t,s]=(0,u.useState)("closed"),l=()=>s("closed"),{data:i}=(0,ed.Vh)(),r=(null!==(e=null==i?void 0:i.privacy_center_url)&&void 0!==e?e:"").trim(),d=r.length>0;return(0,a.jsxs)(a.Fragment,{children:[d?(0,a.jsx)(eb,{isOpen:"create-link"===t,onClose:l,privacyCenterUrl:r}):null,(0,a.jsx)(e_,{isOpen:"submit-request"===t,onClose:l}),(0,a.jsx)(n.S0p.Button,{type:"primary",onClick:()=>s("submit-request"),"data-testid":"submit-request-btn",menu:{items:[{label:"Create request link",key:"create-request-link",icon:(0,a.jsx)(n.xPt,{}),onClick:()=>s("create-link"),disabled:!d}]},icon:(0,a.jsx)(n.v4q,{}),children:"Create request"})]})},eq=s(58754),ek=s(14047);let eS=()=>{let{errorAlert:e}=(0,ek.V)(),[t,s]=(0,u.useState)(!1),[l,i]=(0,u.useState)({count:0,total:0}),[r,d]=(0,u.useState)(!0),o=k.q2.ERROR,{data:c}=(0,V.tE)(),{data:p}=(0,V.QA)({status:[o]},{pollingInterval:15e3,skip:r});return(0,u.useEffect)(()=>{d(!(c&&c.notify_after_failures>0))},[c]),(0,u.useEffect)(()=>{let e=(null==p?void 0:p.total)||0;e>=((null==c?void 0:c.notify_after_failures)||0)&&e>l.total?(i({count:e-l.total,total:e}),s(!0)):s(!1)},[null==p?void 0:p.total,null==c?void 0:c.notify_after_failures,l.total]),{processing:()=>{t&&e((0,a.jsxs)(n.xuv,{children:["DSR automation has failed for"," ",(0,a.jsx)(n.xvT,{as:"span",fontWeight:"semibold",children:l.count})," ","privacy request(s). Please review the event log for further details."]}),void 0,{containerStyle:{maxWidth:"max-content"},duration:null,id:"dsrErrorAlert"})}}};var eE=s(72281);let ew=o()(()=>s.e(9676).then(s.bind(s,59676)),{loadableGenerated:{webpack:()=>[59676]},loading:()=>(0,a.jsx)("div",{children:"Loading..."})});var eR=()=>{let{processing:e}=eS(),{plus:t}=(0,c.hz)(),{activeTab:s,handleTabChange:l,availableTabs:i}=(0,eE.d)();(0,u.useEffect)(()=>{e()},[e]);let r=(0,u.useMemo)(()=>{let e=[{key:eE.G.REQUEST,label:"Request",children:(0,a.jsx)(ei,{})}];return i.manualTask&&e.push({key:eE.G.MANUAL_TASK,label:"Manual tasks",children:(0,a.jsx)(U,{})}),e},[i.manualTask]);return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(eq.Z,{heading:"Privacy Requests",breadcrumbItems:[{title:"All requests"}],rightContent:(0,a.jsxs)(n.vyj,{children:[t&&(0,a.jsx)(p.ZP,{scopes:[k.Sh.PRIVACY_REQUEST_CREATE],children:(0,a.jsx)(eC,{})}),(0,a.jsx)(ew,{})]}),"data-testid":"privacy-requests"}),(0,a.jsx)(n.A5g,{activeKey:s,onChange:l,items:r})]})},eT=()=>(0,a.jsx)(r.Z,{title:"Privacy Requests",children:(0,a.jsx)(eR,{})})},31883:function(e,t,s){"use strict";s.d(t,{Bw:function(){return l.Bw},D4:function(){return l.D4}});var l=s(19043)},76737:function(e,t,s){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var s in t)Object.defineProperty(e,s,{enumerable:!0,get:t[s]})}(t,{default:function(){return n},noSSR:function(){return r}});let l=s(51538);s(24246),s(27378);let i=l._(s(21887));function a(e){return{default:(null==e?void 0:e.default)||e}}function r(e,t){return delete t.webpack,delete t.modules,e(t)}function n(e,t){let s=i.default,l={loading:e=>{let{error:t,isLoading:s,pastDelay:l}=e;return null}};e instanceof Promise?l.loader=()=>e:"function"==typeof e?l.loader=e:"object"==typeof e&&(l={...l,...e});let n=(l={...l,...t}).loader;return(l.loadableGenerated&&(l={...l,...l.loadableGenerated},delete l.loadableGenerated),"boolean"!=typeof l.ssr||l.ssr)?s({...l,loader:()=>null!=n?n().then(a):Promise.resolve(a(()=>null))}):(delete l.webpack,delete l.modules,r(s,l))}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},28438:function(e,t,s){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"LoadableContext",{enumerable:!0,get:function(){return l}});let l=s(51538)._(s(27378)).default.createContext(null)},21887:function(e,t,s){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return p}});let l=s(51538)._(s(27378)),i=s(28438),a=[],r=[],n=!1;function d(e){let t=e(),s={loading:!0,loaded:null,error:null};return s.promise=t.then(e=>(s.loading=!1,s.loaded=e,e)).catch(e=>{throw s.loading=!1,s.error=e,e}),s}class o{promise(){return this._res.promise}retry(){this._clearTimeouts(),this._res=this._loadFn(this._opts.loader),this._state={pastDelay:!1,timedOut:!1};let{_res:e,_opts:t}=this;e.loading&&("number"==typeof t.delay&&(0===t.delay?this._state.pastDelay=!0:this._delay=setTimeout(()=>{this._update({pastDelay:!0})},t.delay)),"number"==typeof t.timeout&&(this._timeout=setTimeout(()=>{this._update({timedOut:!0})},t.timeout))),this._res.promise.then(()=>{this._update({}),this._clearTimeouts()}).catch(e=>{this._update({}),this._clearTimeouts()}),this._update({})}_update(e){this._state={...this._state,error:this._res.error,loaded:this._res.loaded,loading:this._res.loading,...e},this._callbacks.forEach(e=>e())}_clearTimeouts(){clearTimeout(this._delay),clearTimeout(this._timeout)}getCurrentValue(){return this._state}subscribe(e){return this._callbacks.add(e),()=>{this._callbacks.delete(e)}}constructor(e,t){this._loadFn=e,this._opts=t,this._callbacks=new Set,this._delay=null,this._timeout=null,this.retry()}}function u(e){return function(e,t){let s=Object.assign({loader:null,loading:null,delay:200,timeout:null,webpack:null,modules:null},t),a=null;function d(){if(!a){let t=new o(e,s);a={getCurrentValue:t.getCurrentValue.bind(t),subscribe:t.subscribe.bind(t),retry:t.retry.bind(t),promise:t.promise.bind(t)}}return a.promise()}if(!n){let e=s.webpack?s.webpack():s.modules;e&&r.push(t=>{for(let s of e)if(t.includes(s))return d()})}function u(e,t){!function(){d();let e=l.default.useContext(i.LoadableContext);e&&Array.isArray(s.modules)&&s.modules.forEach(t=>{e(t)})}();let r=l.default.useSyncExternalStore(a.subscribe,a.getCurrentValue,a.getCurrentValue);return l.default.useImperativeHandle(t,()=>({retry:a.retry}),[]),l.default.useMemo(()=>{var t;return r.loading||r.error?l.default.createElement(s.loading,{isLoading:r.loading,pastDelay:r.pastDelay,timedOut:r.timedOut,error:r.error,retry:a.retry}):r.loaded?l.default.createElement((t=r.loaded)&&t.default?t.default:t,e):null},[e,r])}return u.preload=()=>d(),u.displayName="LoadableComponent",l.default.forwardRef(u)}(d,e)}function c(e,t){let s=[];for(;e.length;){let l=e.pop();s.push(l(t))}return Promise.all(s).then(()=>{if(e.length)return c(e,t)})}u.preloadAll=()=>new Promise((e,t)=>{c(a).then(e,t)}),u.preloadReady=e=>(void 0===e&&(e=[]),new Promise(t=>{let s=()=>(n=!0,t());c(r,e).then(s,s)})),window.__NEXT_PRELOADREADY=u.preloadReady;let p=u},65218:function(e,t,s){e.exports=s(76737)}},function(e){e.O(0,[2858,2866,3988,2888,9774,179],function(){return e(e.s=1565)}),_N_E=e.O()}]);