chore(ui): rename Upload → Import in user-facing strings

DataTools is local-first — "Upload" reads like "send data somewhere
remote", which contradicts the product positioning. Sweep replaces
the user-visible term throughout the UI:

- ``src/i18n/packs/en.json`` + ``es.json``: all ``upload.*`` strings
  (heading, intro, uploader labels, empty state, switch-back, etc.)
  and ``gate.default_name``. The ``intro_multi`` "no upload anywhere"
  phrasing dropped the verb entirely — now reads "nothing leaves
  this computer".
- All 9 tool pages: ``st.file_uploader(label="Upload …")`` →
  ``"Import …"``; matching ``st.info("Upload a …")`` empty-state
  banners; ``help="Upload …"`` strings on disabled uploaders.
- ``9_Pipeline_Runner`` + ``5_Column_Mapper``: radio-option text
  ``"Upload schema/pipeline JSON"`` → ``"Import …"`` plus the
  ``.startswith("Upload")`` branch guards that read those values.
- ``_home.py``: "**Uploaded files**" → "**Imported files**".
- ``app_demo.py``: "Uploaded file is …" → "Imported file is …".

Internal identifiers left untouched: function names
(``pickup_or_upload``, ``_StashedUpload``), session-state keys
(``home_upload``, ``home_uploads``, ``home_uploaded_*``,
``merger_file_upload``), audit-log event category (``"upload"``),
Streamlit testid CSS selectors. None of those are visible to the
user.

The file_uploader's dropzone button text is a baked-in React
literal that Streamlit's ``label=`` doesn't reach; rewritten at the
DOM level with a small ``_RENAME_UPLOAD_BUTTON_JS`` snippet shipped
through ``st.iframe`` (same pattern the sticky footer uses to mount
on ``<body>``). A ``MutationObserver`` on the parent document re-
applies the swap when Streamlit remounts the dropzone after file
add/remove or page navigation, throttled via ``requestAnimationFrame``.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-18 23:48:31 +00:00
parent 3c4b80895e
commit 444dffbc63
14 changed files with 98 additions and 44 deletions

View File

@@ -156,7 +156,7 @@ def _home_page() -> None:
# interleaving widget-key updates with state changes.
if home_uploads:
import hashlib
st.markdown("**Uploaded files**")
st.markdown("**Imported files**")
to_remove: str | None = None
for name in list(home_uploads.keys()):
digest = hashlib.sha1(