Spaces:
Running
Running
solidprivacy-nl commited on
Commit ·
09184e8
1
Parent(s): 74cdf0d
Integrate Scrub Key import UI into Streamlit patch
Browse files- fix_streamlit_nested_expanders.py +112 -134
fix_streamlit_nested_expanders.py
CHANGED
|
@@ -14,6 +14,7 @@ Patches currently applied:
|
|
| 14 |
- v12.6: show advisory export sanity warnings before download/export.
|
| 15 |
- v13.1: add local Scrub Key JSON export after review.
|
| 16 |
- v13.1 hotfix: map Streamlit review-table columns to Scrub Key fields before JSON export.
|
|
|
|
| 17 |
"""
|
| 18 |
|
| 19 |
from pathlib import Path
|
|
@@ -53,7 +54,7 @@ text = replace_once(
|
|
| 53 |
'from pathlib import Path\nfrom datetime import datetime, timezone\n',
|
| 54 |
)
|
| 55 |
|
| 56 |
-
# v12
|
| 57 |
text = replace_once(
|
| 58 |
text,
|
| 59 |
'from display_labels_nl import entity_label, source_label, confidence_label\n',
|
|
@@ -69,93 +70,35 @@ text = replace_once(
|
|
| 69 |
' AI_USAGE_GUIDANCE,\n'
|
| 70 |
' EXPORT_GUIDANCE,\n'
|
| 71 |
')\n'
|
| 72 |
-
'from review_summary import build_review_summary, review_summary_markdown\n'
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
text = replace_once(
|
| 77 |
-
text,
|
| 78 |
-
'from review_status import review_status_for_source, review_status_label, review_status_order\n',
|
| 79 |
-
'from review_status import review_status_for_source, review_status_label, review_status_order\n'
|
| 80 |
-
'from review_filters import REVIEW_FILTER_OPTIONS, FILTER_SHOW_ALL, filter_review_dataframe\n'
|
| 81 |
-
'from review_table_config import main_review_columns, technical_display_columns\n'
|
| 82 |
-
'from review_guidance import (\n'
|
| 83 |
-
' REVIEW_INTRO_GUIDANCE,\n'
|
| 84 |
-
' CANDIDATE_GUIDANCE,\n'
|
| 85 |
-
' FOCUS_FILTER_GUIDANCE,\n'
|
| 86 |
-
' TECHNICAL_DETAILS_GUIDANCE,\n'
|
| 87 |
-
' AI_USAGE_GUIDANCE,\n'
|
| 88 |
-
' EXPORT_GUIDANCE,\n'
|
| 89 |
-
')\n'
|
| 90 |
-
'from review_summary import build_review_summary, review_summary_markdown\n',
|
| 91 |
-
)
|
| 92 |
-
|
| 93 |
-
text = replace_once(
|
| 94 |
-
text,
|
| 95 |
-
'from review_filters import REVIEW_FILTER_OPTIONS, FILTER_SHOW_ALL, filter_review_dataframe\n',
|
| 96 |
-
'from review_filters import REVIEW_FILTER_OPTIONS, FILTER_SHOW_ALL, filter_review_dataframe\n'
|
| 97 |
-
'from review_table_config import main_review_columns, technical_display_columns\n'
|
| 98 |
-
'from review_guidance import (\n'
|
| 99 |
-
' REVIEW_INTRO_GUIDANCE,\n'
|
| 100 |
-
' CANDIDATE_GUIDANCE,\n'
|
| 101 |
-
' FOCUS_FILTER_GUIDANCE,\n'
|
| 102 |
-
' TECHNICAL_DETAILS_GUIDANCE,\n'
|
| 103 |
-
' AI_USAGE_GUIDANCE,\n'
|
| 104 |
-
' EXPORT_GUIDANCE,\n'
|
| 105 |
-
')\n'
|
| 106 |
-
'from review_summary import build_review_summary, review_summary_markdown\n',
|
| 107 |
-
)
|
| 108 |
-
|
| 109 |
-
text = replace_once(
|
| 110 |
-
text,
|
| 111 |
-
'from review_table_config import main_review_columns, technical_display_columns\n',
|
| 112 |
-
'from review_table_config import main_review_columns, technical_display_columns\n'
|
| 113 |
-
'from review_guidance import (\n'
|
| 114 |
-
' REVIEW_INTRO_GUIDANCE,\n'
|
| 115 |
-
' CANDIDATE_GUIDANCE,\n'
|
| 116 |
-
' FOCUS_FILTER_GUIDANCE,\n'
|
| 117 |
-
' TECHNICAL_DETAILS_GUIDANCE,\n'
|
| 118 |
-
' AI_USAGE_GUIDANCE,\n'
|
| 119 |
-
' EXPORT_GUIDANCE,\n'
|
| 120 |
-
')\n'
|
| 121 |
-
'from review_summary import build_review_summary, review_summary_markdown\n',
|
| 122 |
)
|
| 123 |
|
|
|
|
| 124 |
text = replace_once(
|
| 125 |
text,
|
| 126 |
-
'from review_guidance import (\n'
|
| 127 |
-
' REVIEW_INTRO_GUIDANCE,\n'
|
| 128 |
-
' CANDIDATE_GUIDANCE,\n'
|
| 129 |
-
' FOCUS_FILTER_GUIDANCE,\n'
|
| 130 |
-
' TECHNICAL_DETAILS_GUIDANCE,\n'
|
| 131 |
-
' AI_USAGE_GUIDANCE,\n'
|
| 132 |
-
' EXPORT_GUIDANCE,\n'
|
| 133 |
-
')\n',
|
| 134 |
-
'from review_guidance import (\n'
|
| 135 |
-
' REVIEW_INTRO_GUIDANCE,\n'
|
| 136 |
-
' CANDIDATE_GUIDANCE,\n'
|
| 137 |
-
' FOCUS_FILTER_GUIDANCE,\n'
|
| 138 |
-
' TECHNICAL_DETAILS_GUIDANCE,\n'
|
| 139 |
-
' AI_USAGE_GUIDANCE,\n'
|
| 140 |
-
' EXPORT_GUIDANCE,\n'
|
| 141 |
-
')\n'
|
| 142 |
'from review_summary import build_review_summary, review_summary_markdown\n',
|
|
|
|
|
|
|
|
|
|
|
|
|
| 143 |
)
|
| 144 |
|
| 145 |
-
# v12.6: import advisory export sanity helpers without changing export behavior.
|
| 146 |
text = replace_once(
|
| 147 |
text,
|
| 148 |
-
'from review_summary import build_review_summary, review_summary_markdown\n',
|
| 149 |
-
'from review_summary import build_review_summary, review_summary_markdown\n'
|
| 150 |
'from export_sanity import build_export_sanity_checks, export_sanity_warnings\n',
|
|
|
|
|
|
|
|
|
|
| 151 |
)
|
| 152 |
|
| 153 |
-
# v13.1: import Scrub Key JSON export helpers.
|
| 154 |
text = replace_once(
|
| 155 |
text,
|
| 156 |
-
'from export_sanity import build_export_sanity_checks, export_sanity_warnings\n',
|
| 157 |
-
'from export_sanity import build_export_sanity_checks, export_sanity_warnings\n'
|
| 158 |
'from scrub_key import build_scrub_key, scrub_key_to_json, validate_scrub_key\n',
|
|
|
|
|
|
|
| 159 |
)
|
| 160 |
|
| 161 |
# v12.1: add review status fields to remembered rows.
|
|
@@ -222,6 +165,46 @@ text = replace_once(
|
|
| 222 |
''',
|
| 223 |
)
|
| 224 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 225 |
# v12.1/v12.2/v12.3/v12.4: sort review rows, show guidance/status summary, focus filters and technical view.
|
| 226 |
text = replace_once(
|
| 227 |
text,
|
|
@@ -269,40 +252,12 @@ text = replace_once(
|
|
| 269 |
''',
|
| 270 |
)
|
| 271 |
|
| 272 |
-
# v12.4: if v12.1/v12.2/v12.3 block is already present, add guidance to that block.
|
| 273 |
-
text = replace_once(
|
| 274 |
-
text,
|
| 275 |
-
''' replacement_editor_df = pd.DataFrame(default_editor_rows)
|
| 276 |
-
if "review_order" in replacement_editor_df.columns:
|
| 277 |
-
''',
|
| 278 |
-
''' replacement_editor_df = pd.DataFrame(default_editor_rows)
|
| 279 |
-
st.info(REVIEW_INTRO_GUIDANCE)
|
| 280 |
-
with st.expander("Uitleg bij deze controle", expanded=False):
|
| 281 |
-
st.markdown(f"- {CANDIDATE_GUIDANCE}")
|
| 282 |
-
st.markdown(f"- {FOCUS_FILTER_GUIDANCE}")
|
| 283 |
-
st.markdown(f"- {TECHNICAL_DETAILS_GUIDANCE}")
|
| 284 |
-
st.markdown(f"- {AI_USAGE_GUIDANCE}")
|
| 285 |
-
if "review_order" in replacement_editor_df.columns:
|
| 286 |
-
''',
|
| 287 |
-
)
|
| 288 |
-
|
| 289 |
text = replace_once(
|
| 290 |
text,
|
| 291 |
' help="Gebruik dit als overzichtsfilter. De volledige vervangtabel hieronder blijft leidend voor de export.",\n',
|
| 292 |
' help=FOCUS_FILTER_GUIDANCE,\n',
|
| 293 |
)
|
| 294 |
|
| 295 |
-
text = replace_once(
|
| 296 |
-
text,
|
| 297 |
-
''' with st.expander("Technische details bij de vervangtabel", expanded=False):
|
| 298 |
-
technical_columns = technical_display_columns(replacement_editor_df.columns)
|
| 299 |
-
''',
|
| 300 |
-
''' with st.expander("Technische details bij de vervangtabel", expanded=False):
|
| 301 |
-
st.caption(TECHNICAL_DETAILS_GUIDANCE)
|
| 302 |
-
technical_columns = technical_display_columns(replacement_editor_df.columns)
|
| 303 |
-
''',
|
| 304 |
-
)
|
| 305 |
-
|
| 306 |
# v12.1: make status visible in the editor.
|
| 307 |
text = replace_once(
|
| 308 |
text,
|
|
@@ -376,6 +331,48 @@ scrub_key_mapping_block = ''' scrub_key_rows = edited_replacements_df.cop
|
|
| 376 |
scrub_key = build_scrub_key(scrub_key_rows)
|
| 377 |
'''
|
| 378 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 379 |
review_summary_block = ''' st.subheader("4. Download opgeschoonde bestanden")
|
| 380 |
final_review_summary = build_review_summary(edited_replacements_df)
|
| 381 |
st.markdown("**Eindcontrole vóór download**")
|
|
@@ -398,16 +395,17 @@ review_summary_block = ''' st.subheader("4. Download opgeschoonde bestand
|
|
| 398 |
if scrub_key.get("item_count", 0) == 0:
|
| 399 |
st.info("Er zijn geen geselecteerde vervangingen voor de Scrub Key. De JSON bevat dan geen mapping-items.")
|
| 400 |
st.download_button(
|
| 401 |
-
"Download Scrub Key (.json)
|
|
|
|
| 402 |
data=scrub_key_to_json(scrub_key),
|
| 403 |
file_name="solidprivacy_scrub_key.json",
|
| 404 |
mime="application/json",
|
| 405 |
)
|
| 406 |
-
st.warning(EXPORT_GUIDANCE)
|
| 407 |
'''
|
| 408 |
|
| 409 |
-
# v12.5/v12.6/v13.1: add final review summary, advisory export sanity warnings
|
| 410 |
-
#
|
| 411 |
text = replace_once(
|
| 412 |
text,
|
| 413 |
''' st.subheader("4. Download opgeschoonde bestanden")
|
|
@@ -423,44 +421,24 @@ text = replace_once(
|
|
| 423 |
review_summary_block,
|
| 424 |
)
|
| 425 |
|
| 426 |
-
#
|
| 427 |
-
text = replace_once(
|
| 428 |
-
text,
|
| 429 |
-
''' st.markdown(review_summary_markdown(final_review_summary))
|
| 430 |
-
st.warning(EXPORT_GUIDANCE)
|
| 431 |
-
''',
|
| 432 |
-
''' st.markdown(review_summary_markdown(final_review_summary))
|
| 433 |
-
export_sanity_checks = build_export_sanity_checks(edited_replacements_df)
|
| 434 |
-
st.markdown("**Extra exportcontrole**")
|
| 435 |
-
for export_sanity_warning in export_sanity_warnings(export_sanity_checks):
|
| 436 |
-
st.warning(export_sanity_warning)
|
| 437 |
-
st.caption("Deze exportcontrole is adviserend: downloads blijven beschikbaar en de exportinstellingen blijven ongewijzigd.")
|
| 438 |
-
st.warning(EXPORT_GUIDANCE)
|
| 439 |
-
''',
|
| 440 |
-
)
|
| 441 |
-
|
| 442 |
-
# v13.1: extend an existing v12.6 block with Scrub Key JSON export.
|
| 443 |
text = replace_once(
|
| 444 |
text,
|
| 445 |
-
'''
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 446 |
st.warning(EXPORT_GUIDANCE)
|
| 447 |
''',
|
| 448 |
-
'''
|
| 449 |
-
st.markdown("**Scrub Key (JSON)**")
|
| 450 |
-
st.warning("Let op: een Scrub Key maakt de vervangen waarden lokaal herleidbaar. Dit is pseudonimisering, geen volledige anonimisering. Deel deze sleutel niet met AI-diensten of derden tenzij dat bewust en toegestaan is.")
|
| 451 |
-
''' + scrub_key_mapping_block + ''' scrub_key_issues = validate_scrub_key(scrub_key)
|
| 452 |
-
if scrub_key_issues:
|
| 453 |
-
st.warning("Scrub Key kan nog niet betrouwbaar worden geëxporteerd: " + "; ".join(scrub_key_issues[:3]))
|
| 454 |
-
else:
|
| 455 |
-
if scrub_key.get("item_count", 0) == 0:
|
| 456 |
-
st.info("Er zijn geen geselecteerde vervangingen voor de Scrub Key. De JSON bevat dan geen mapping-items.")
|
| 457 |
-
st.download_button(
|
| 458 |
"Download Scrub Key (.json)",
|
| 459 |
data=scrub_key_to_json(scrub_key),
|
| 460 |
file_name="solidprivacy_scrub_key.json",
|
| 461 |
mime="application/json",
|
| 462 |
)
|
| 463 |
-
st.warning(EXPORT_GUIDANCE)
|
| 464 |
''',
|
| 465 |
)
|
| 466 |
|
|
|
|
| 14 |
- v12.6: show advisory export sanity warnings before download/export.
|
| 15 |
- v13.1: add local Scrub Key JSON export after review.
|
| 16 |
- v13.1 hotfix: map Streamlit review-table columns to Scrub Key fields before JSON export.
|
| 17 |
+
- v13.2: add local Scrub Key import/reload UI using the pure import helper.
|
| 18 |
"""
|
| 19 |
|
| 20 |
from pathlib import Path
|
|
|
|
| 54 |
'from pathlib import Path\nfrom datetime import datetime, timezone\n',
|
| 55 |
)
|
| 56 |
|
| 57 |
+
# v12/v13: import review, export sanity, Scrub Key export and Scrub Key import helpers.
|
| 58 |
text = replace_once(
|
| 59 |
text,
|
| 60 |
'from display_labels_nl import entity_label, source_label, confidence_label\n',
|
|
|
|
| 70 |
' AI_USAGE_GUIDANCE,\n'
|
| 71 |
' EXPORT_GUIDANCE,\n'
|
| 72 |
')\n'
|
| 73 |
+
'from review_summary import build_review_summary, review_summary_markdown\n'
|
| 74 |
+
'from export_sanity import build_export_sanity_checks, export_sanity_warnings\n'
|
| 75 |
+
'from scrub_key import build_scrub_key, scrub_key_to_json, validate_scrub_key\n'
|
| 76 |
+
'from scrub_key_import import IMPORT_PRIVACY_WARNING, build_scrub_key_import_result\n',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 77 |
)
|
| 78 |
|
| 79 |
+
# v12.6/v13.1/v13.2: extend imports on already partially patched app files.
|
| 80 |
text = replace_once(
|
| 81 |
text,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 82 |
'from review_summary import build_review_summary, review_summary_markdown\n',
|
| 83 |
+
'from review_summary import build_review_summary, review_summary_markdown\n'
|
| 84 |
+
'from export_sanity import build_export_sanity_checks, export_sanity_warnings\n'
|
| 85 |
+
'from scrub_key import build_scrub_key, scrub_key_to_json, validate_scrub_key\n'
|
| 86 |
+
'from scrub_key_import import IMPORT_PRIVACY_WARNING, build_scrub_key_import_result\n',
|
| 87 |
)
|
| 88 |
|
|
|
|
| 89 |
text = replace_once(
|
| 90 |
text,
|
|
|
|
|
|
|
| 91 |
'from export_sanity import build_export_sanity_checks, export_sanity_warnings\n',
|
| 92 |
+
'from export_sanity import build_export_sanity_checks, export_sanity_warnings\n'
|
| 93 |
+
'from scrub_key import build_scrub_key, scrub_key_to_json, validate_scrub_key\n'
|
| 94 |
+
'from scrub_key_import import IMPORT_PRIVACY_WARNING, build_scrub_key_import_result\n',
|
| 95 |
)
|
| 96 |
|
|
|
|
| 97 |
text = replace_once(
|
| 98 |
text,
|
|
|
|
|
|
|
| 99 |
'from scrub_key import build_scrub_key, scrub_key_to_json, validate_scrub_key\n',
|
| 100 |
+
'from scrub_key import build_scrub_key, scrub_key_to_json, validate_scrub_key\n'
|
| 101 |
+
'from scrub_key_import import IMPORT_PRIVACY_WARNING, build_scrub_key_import_result\n',
|
| 102 |
)
|
| 103 |
|
| 104 |
# v12.1: add review status fields to remembered rows.
|
|
|
|
| 165 |
''',
|
| 166 |
)
|
| 167 |
|
| 168 |
+
scrub_key_import_merge_block = ''' if "scrub_key_import_rows" in st.session_state:
|
| 169 |
+
imported_scrub_key_rows = st.session_state.pop("scrub_key_import_rows")
|
| 170 |
+
added_scrub_key_rows = 0
|
| 171 |
+
existing_find_values = {str(row.get("find", "")).strip() for row in default_editor_rows}
|
| 172 |
+
if len(default_editor_rows) == 1 and not str(default_editor_rows[0].get("find", "")).strip():
|
| 173 |
+
default_editor_rows = []
|
| 174 |
+
existing_find_values = set()
|
| 175 |
+
for imported_scrub_key_row in imported_scrub_key_rows:
|
| 176 |
+
imported_find = str(imported_scrub_key_row.get("find", "")).strip()
|
| 177 |
+
imported_replace = str(imported_scrub_key_row.get("replace_with", "")).strip()
|
| 178 |
+
if not imported_find or not imported_replace or imported_find in existing_find_values:
|
| 179 |
+
continue
|
| 180 |
+
imported_row = dict(imported_scrub_key_row)
|
| 181 |
+
imported_row.setdefault("include", True)
|
| 182 |
+
imported_row.setdefault("remember", False)
|
| 183 |
+
imported_row.setdefault("source", "scrub_key_import")
|
| 184 |
+
imported_row.setdefault("source_label", "Scrub Key")
|
| 185 |
+
imported_row.setdefault("reason", "Geladen uit Scrub Key")
|
| 186 |
+
imported_row.setdefault("context", "")
|
| 187 |
+
imported_row.setdefault("confidence", "")
|
| 188 |
+
imported_row.setdefault("score", None)
|
| 189 |
+
imported_row.setdefault("type_label", entity_label(imported_row.get("entity_type", "MANUAL")))
|
| 190 |
+
imported_row.setdefault("review_status_label", review_status_label(imported_row.get("review_status", "manual")))
|
| 191 |
+
imported_row.setdefault("review_order", review_status_order(imported_row.get("review_status", "manual")))
|
| 192 |
+
default_editor_rows.append(imported_row)
|
| 193 |
+
existing_find_values.add(imported_find)
|
| 194 |
+
added_scrub_key_rows += 1
|
| 195 |
+
if added_scrub_key_rows:
|
| 196 |
+
st.success(f"{added_scrub_key_rows} Scrub Key regel(s) geladen in de vervangtabel.")
|
| 197 |
+
'''
|
| 198 |
+
|
| 199 |
+
# v13.2: merge imported Scrub Key mappings into the review table only after a visible user action.
|
| 200 |
+
text = replace_once(
|
| 201 |
+
text,
|
| 202 |
+
''' replacement_editor_df = pd.DataFrame(default_editor_rows)
|
| 203 |
+
''',
|
| 204 |
+
scrub_key_import_merge_block + ''' replacement_editor_df = pd.DataFrame(default_editor_rows)
|
| 205 |
+
''',
|
| 206 |
+
)
|
| 207 |
+
|
| 208 |
# v12.1/v12.2/v12.3/v12.4: sort review rows, show guidance/status summary, focus filters and technical view.
|
| 209 |
text = replace_once(
|
| 210 |
text,
|
|
|
|
| 252 |
''',
|
| 253 |
)
|
| 254 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 255 |
text = replace_once(
|
| 256 |
text,
|
| 257 |
' help="Gebruik dit als overzichtsfilter. De volledige vervangtabel hieronder blijft leidend voor de export.",\n',
|
| 258 |
' help=FOCUS_FILTER_GUIDANCE,\n',
|
| 259 |
)
|
| 260 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 261 |
# v12.1: make status visible in the editor.
|
| 262 |
text = replace_once(
|
| 263 |
text,
|
|
|
|
| 331 |
scrub_key = build_scrub_key(scrub_key_rows)
|
| 332 |
'''
|
| 333 |
|
| 334 |
+
scrub_key_import_ui_block = ''' st.markdown("**Scrub Key laden**")
|
| 335 |
+
st.warning("Let op: een Scrub Key maakt vervangen waarden lokaal herleidbaar. Dit is pseudonimisering, geen volledige anonimisering. Bewaar deze sleutel lokaal en deel deze niet met AI-diensten of derden tenzij dat bewust en toegestaan is.")
|
| 336 |
+
st.caption("Upload of plak een eerder geëxporteerde Scrub Key JSON. De sleutel wordt eerst gevalideerd en daarna pas na jouw klik aan de vervangtabel toegevoegd.")
|
| 337 |
+
scrub_key_import_file = st.file_uploader(
|
| 338 |
+
"Upload Scrub Key JSON (.json)",
|
| 339 |
+
type=["json"],
|
| 340 |
+
key="scrub_key_import_file",
|
| 341 |
+
help="Gebruik alleen een lokale Scrub Key die bij dit dossier of document hoort.",
|
| 342 |
+
)
|
| 343 |
+
scrub_key_import_paste = st.text_area(
|
| 344 |
+
"Of plak Scrub Key JSON",
|
| 345 |
+
value="",
|
| 346 |
+
height=120,
|
| 347 |
+
key="scrub_key_import_paste",
|
| 348 |
+
)
|
| 349 |
+
scrub_key_import_text = ""
|
| 350 |
+
scrub_key_import_decode_error = None
|
| 351 |
+
if scrub_key_import_file is not None:
|
| 352 |
+
try:
|
| 353 |
+
scrub_key_import_text = scrub_key_import_file.getvalue().decode("utf-8")
|
| 354 |
+
except UnicodeDecodeError:
|
| 355 |
+
scrub_key_import_decode_error = "Scrub Key bestand is geen geldige UTF-8 tekst."
|
| 356 |
+
elif scrub_key_import_paste.strip():
|
| 357 |
+
scrub_key_import_text = scrub_key_import_paste
|
| 358 |
+
if st.button("Valideer en laad Scrub Key", key="load_scrub_key_import"):
|
| 359 |
+
if scrub_key_import_decode_error:
|
| 360 |
+
st.error(scrub_key_import_decode_error)
|
| 361 |
+
else:
|
| 362 |
+
scrub_key_import_result = build_scrub_key_import_result(scrub_key_import_text)
|
| 363 |
+
for scrub_key_import_warning in scrub_key_import_result.get("warnings", [IMPORT_PRIVACY_WARNING]):
|
| 364 |
+
st.warning(scrub_key_import_warning)
|
| 365 |
+
if scrub_key_import_result.get("ok"):
|
| 366 |
+
st.success(f"Scrub Key geldig: {scrub_key_import_result.get('item_count', 0)} mappingregel(s) gevonden.")
|
| 367 |
+
st.session_state["scrub_key_import_rows"] = scrub_key_import_result.get("mapping_rows", [])
|
| 368 |
+
if "replacement_editor" in st.session_state:
|
| 369 |
+
del st.session_state["replacement_editor"]
|
| 370 |
+
st.rerun()
|
| 371 |
+
else:
|
| 372 |
+
for scrub_key_import_error in scrub_key_import_result.get("errors", []):
|
| 373 |
+
st.error(scrub_key_import_error)
|
| 374 |
+
'''
|
| 375 |
+
|
| 376 |
review_summary_block = ''' st.subheader("4. Download opgeschoonde bestanden")
|
| 377 |
final_review_summary = build_review_summary(edited_replacements_df)
|
| 378 |
st.markdown("**Eindcontrole vóór download**")
|
|
|
|
| 395 |
if scrub_key.get("item_count", 0) == 0:
|
| 396 |
st.info("Er zijn geen geselecteerde vervangingen voor de Scrub Key. De JSON bevat dan geen mapping-items.")
|
| 397 |
st.download_button(
|
| 398 |
+
"Download Scrub Key (.json)
|
| 399 |
+
",
|
| 400 |
data=scrub_key_to_json(scrub_key),
|
| 401 |
file_name="solidprivacy_scrub_key.json",
|
| 402 |
mime="application/json",
|
| 403 |
)
|
| 404 |
+
''' + scrub_key_import_ui_block + ''' st.warning(EXPORT_GUIDANCE)
|
| 405 |
'''
|
| 406 |
|
| 407 |
+
# v12.5/v12.6/v13.1/v13.2: add final review summary, advisory export sanity warnings,
|
| 408 |
+
# Scrub Key JSON export and Scrub Key import/reload.
|
| 409 |
text = replace_once(
|
| 410 |
text,
|
| 411 |
''' st.subheader("4. Download opgeschoonde bestanden")
|
|
|
|
| 421 |
review_summary_block,
|
| 422 |
)
|
| 423 |
|
| 424 |
+
# v13.2: extend an already patched Scrub Key JSON export block with import/reload UI.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 425 |
text = replace_once(
|
| 426 |
text,
|
| 427 |
+
''' st.download_button(
|
| 428 |
+
"Download Scrub Key (.json)",
|
| 429 |
+
data=scrub_key_to_json(scrub_key),
|
| 430 |
+
file_name="solidprivacy_scrub_key.json",
|
| 431 |
+
mime="application/json",
|
| 432 |
+
)
|
| 433 |
st.warning(EXPORT_GUIDANCE)
|
| 434 |
''',
|
| 435 |
+
''' st.download_button(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 436 |
"Download Scrub Key (.json)",
|
| 437 |
data=scrub_key_to_json(scrub_key),
|
| 438 |
file_name="solidprivacy_scrub_key.json",
|
| 439 |
mime="application/json",
|
| 440 |
)
|
| 441 |
+
''' + scrub_key_import_ui_block + ''' st.warning(EXPORT_GUIDANCE)
|
| 442 |
''',
|
| 443 |
)
|
| 444 |
|