From a1dae24cb97059d1f6fcda361892d59503d63c22 Mon Sep 17 00:00:00 2001 From: Richard Iannone Date: Fri, 24 Apr 2026 15:54:00 -0400 Subject: [PATCH 1/8] Add filter & placeholder styles; page_size=10 --- great_docs/_tbl_explorer.py | 65 ++++++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/great_docs/_tbl_explorer.py b/great_docs/_tbl_explorer.py index 8b3532c..4ad8aac 100644 --- a/great_docs/_tbl_explorer.py +++ b/great_docs/_tbl_explorer.py @@ -205,6 +205,21 @@ def _render_explorer_css(uid: str) -> str: background: #eef3fb; border-radius: 3px; }} +{s} .gd-tbl-filter-hint {{ + color: #b0b0b0; + font-size: 12px; + font-style: italic; + display: inline-flex; + align-items: center; + gap: 4px; + padding-left: 4px; + user-select: none; + pointer-events: none; +}} +{s} .gd-tbl-filter-hint svg {{ + flex-shrink: 0; + stroke: #b0b0b0; +}} /* ── Filter wizard dropdown ──────────────────────── */ {s} .gd-tbl-filter-wizard {{ position: absolute; @@ -584,6 +599,16 @@ def _render_explorer_css(uid: str) -> str: :root[data-bs-theme="dark"] {s} .gd-tbl-filter-add:hover {{ background: #353550; }} +body.quarto-dark {s} .gd-tbl-filter-hint, +html.quarto-dark {s} .gd-tbl-filter-hint, +:root[data-bs-theme="dark"] {s} .gd-tbl-filter-hint {{ + color: #666; +}} +body.quarto-dark {s} .gd-tbl-filter-hint svg, +html.quarto-dark {s} .gd-tbl-filter-hint svg, +:root[data-bs-theme="dark"] {s} .gd-tbl-filter-hint svg {{ + stroke: #666; +}} body.quarto-dark {s} .gd-tbl-filter-wizard, html.quarto-dark {s} .gd-tbl-filter-wizard, :root[data-bs-theme="dark"] {s} .gd-tbl-filter-wizard {{ @@ -706,6 +731,44 @@ def _render_explorer_css(uid: str) -> str: color: #4ade80; border-color: #4ade80; }} +/* ── Placeholder rows (stable height) ────────────── */ +{s} .gd-tbl-placeholder-row td {{ + border-top: none !important; + border-bottom: none !important; + padding: 0 !important; + height: 0; + line-height: 0; + overflow: hidden; + position: relative; +}} +{s} .gd-tbl-placeholder-row td .gd-tbl-placeholder-dot {{ + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 4px; + height: 4px; + border-radius: 50%; + background: #d0d0d0; +}} +{s} .gd-tbl-empty-msg {{ + text-align: center; + color: #999; + font-size: 13px; + font-style: italic; + padding: 8px 0 4px 0; + user-select: none; +}} +body.quarto-dark {s} .gd-tbl-placeholder-row td .gd-tbl-placeholder-dot, +html.quarto-dark {s} .gd-tbl-placeholder-row td .gd-tbl-placeholder-dot, +:root[data-bs-theme="dark"] {s} .gd-tbl-placeholder-row td .gd-tbl-placeholder-dot {{ + background: #555; +}} +body.quarto-dark {s} .gd-tbl-empty-msg, +html.quarto-dark {s} .gd-tbl-empty-msg, +:root[data-bs-theme="dark"] {s} .gd-tbl-empty-msg {{ + color: #777; +}} """ @@ -757,7 +820,7 @@ def tbl_explorer( min_tbl_width: int = 500, caption: str | None = None, highlight_missing: bool = True, - page_size: int = 20, + page_size: int = 10, sortable: bool = True, filterable: bool = True, column_toggle: bool = True, From 7ad4f96dd7e515ff65b7210bc53dbcf680d21728 Mon Sep 17 00:00:00 2001 From: Richard Iannone Date: Fri, 24 Apr 2026 15:54:17 -0400 Subject: [PATCH 2/8] Add i18n, filter hint, and table placeholders --- great_docs/assets/tbl-explorer.js | 117 ++++++++++++++++++++++++++++-- 1 file changed, 111 insertions(+), 6 deletions(-) diff --git a/great_docs/assets/tbl-explorer.js b/great_docs/assets/tbl-explorer.js index 13c6d5b..1eacf7c 100644 --- a/great_docs/assets/tbl-explorer.js +++ b/great_docs/assets/tbl-explorer.js @@ -14,6 +14,18 @@ var COPIED_MS = 2000; var PAGE_WINDOW = 2; + // i18n helper — read translations from + var _i18nCache = null; + function _gdT(key, fallback) { + if (!_i18nCache) { + try { + var meta = document.querySelector('meta[name="gd-i18n"]'); + _i18nCache = meta ? JSON.parse(meta.getAttribute('content')) : {}; + } catch (e) { _i18nCache = {}; } + } + return _i18nCache[key] || fallback; + } + // SVG sort indicator icons (all same viewBox for consistent width) var SORT_W = 10, SORT_H = 14; var SVG_SORT_NONE = '' + @@ -68,7 +80,7 @@ this.filterQuery = ""; // kept for search highlight compat this.visibleCols = this.columns.map(function (_, i) { return i; }); this.currentPage = 1; - this.pageSize = this.cfg.pageSize || 20; + this.pageSize = this.cfg.pageSize != null ? this.cfg.pageSize : 10; this._nextFilterId = 1; } @@ -185,6 +197,12 @@ }); filterBar.appendChild(addBtn); + // Placeholder hint for empty filter bar + var filterHint = document.createElement("span"); + filterHint.className = "gd-tbl-filter-hint"; + filterHint.innerHTML = ' ' + _gdT("tbl_filter_hint", "Add Data Filter"); + filterBar.appendChild(filterHint); + bar.appendChild(filterBar); } @@ -193,7 +211,7 @@ } if (state.cfg.copyable) { - var copy = makeIconBtn(SVG_COPY, "Copy table to clipboard", "Copy"); + var copy = makeIconBtn(SVG_COPY, "Copy table to clipboard", _gdT("tbl_copy_tooltip", "Copy")); copy.btn.addEventListener("click", function () { handleCopy(state, false, copy.btn); }); @@ -201,7 +219,7 @@ } if (state.cfg.downloadable) { - var dl = makeIconBtn(SVG_DOWNLOAD, "Download as CSV", "Download"); + var dl = makeIconBtn(SVG_DOWNLOAD, "Download as CSV", _gdT("tbl_download_tooltip", "Download")); dl.btn.addEventListener("click", function () { handleDownload(state); }); @@ -209,7 +227,7 @@ } // Reset button (always present if toolbar exists) - var reset = makeIconBtn(SVG_RESET, "Reset all filters and sorting", "Reset"); + var reset = makeIconBtn(SVG_RESET, "Reset all filters and sorting", _gdT("tbl_reset_tooltip", "Reset")); reset.btn.addEventListener("click", function () { handleReset(el, state); }); @@ -229,6 +247,10 @@ // Remove any existing wizard closeFilterWizard(filterBar); + // Hide the hint while wizard is open + var hint = filterBar.querySelector(".gd-tbl-filter-hint"); + if (hint) hint.style.display = "none"; + var wizard = document.createElement("div"); wizard.className = "gd-tbl-filter-wizard"; wizard.addEventListener("click", function (e) { e.stopPropagation(); }); @@ -485,11 +507,24 @@ pill.appendChild(closeBtn); tokenArea.appendChild(pill); } + // Update hint visibility based on token count + var filterBar = tokenArea.closest ? tokenArea.closest(".gd-tbl-filter-bar") : tokenArea.parentNode; + if (filterBar) updateFilterHint(filterBar); } function closeFilterWizard(filterBar) { var w = filterBar.querySelector(".gd-tbl-filter-wizard"); if (w && w.parentNode) w.parentNode.removeChild(w); + // Show hint again if no tokens + updateFilterHint(filterBar); + } + + function updateFilterHint(container) { + var hint = container.querySelector(".gd-tbl-filter-hint"); + if (!hint) return; + var hasTokens = container.querySelector(".gd-tbl-filter-token") != null; + var hasWizard = container.querySelector(".gd-tbl-filter-wizard") != null; + hint.style.display = (hasTokens || hasWizard) ? "none" : ""; } // ── Column Toggle ────────────────────────────────────────── @@ -569,7 +604,7 @@ } function updateColBtnLabel(btn, state) { - btn.textContent = "Columns"; + btn.textContent = _gdT("tbl_columns_btn", "Columns"); } // ── Sorting ──────────────────────────────────────────────── @@ -874,7 +909,10 @@ // Close any open filter wizard var filterBar = el.querySelector(".gd-tbl-filter-bar"); - if (filterBar) closeFilterWizard(filterBar); + if (filterBar) { + closeFilterWizard(filterBar); + updateFilterHint(filterBar); + } // Reset column checkboxes var cbs = el.querySelectorAll(".gd-tbl-col-menu input[type=checkbox]"); @@ -905,10 +943,12 @@ var pageRows = getVisiblePageRows(state); var startIdx = state.pageSize > 0 ? (state.currentPage - 1) * state.pageSize : 0; + var colCount = state.visibleCols.length + (state.cfg.showRowNumbers ? 1 : 0); var tbody = document.createElement("tbody"); tbody.className = "gt_table_body"; + // Render data rows for (var r = 0; r < pageRows.length; r++) { var row = pageRows[r]; var tr = document.createElement("tr"); @@ -946,12 +986,77 @@ tbody.appendChild(tr); } + // "Empty Table" message when filtering removes all rows + if (pageRows.length === 0 && state.filteredRows.length === 0 && state.filterTokens.length > 0) { + var msgTr = document.createElement("tr"); + msgTr.className = "gd-tbl-placeholder-row"; + var msgTd = document.createElement("td"); + msgTd.setAttribute("colspan", String(colCount)); + msgTd.className = "gt_row"; + msgTd.style.cssText = "border:none !important; padding:0 !important;"; + var msgDiv = document.createElement("div"); + msgDiv.className = "gd-tbl-empty-msg"; + msgDiv.textContent = _gdT("tbl_no_matching_rows", "No matching rows"); + msgTd.appendChild(msgDiv); + msgTr.appendChild(msgTd); + tbody.appendChild(msgTr); + } + + // Stable height: pad with placeholder rows to maintain consistent table size + var MIN_VISIBLE_ROWS = 10; + if (state.pageSize > 0 || pageRows.length < MIN_VISIBLE_ROWS) { + if (!state._rowHeight) { + state._rowHeight = 23; // fallback + } + var targetRows = state.pageSize > 0 ? state.pageSize : MIN_VISIBLE_ROWS; + var renderedDataRows = pageRows.length; + // The empty-message row counts as one row for spacing + var fillerStart = renderedDataRows + (pageRows.length === 0 && state.filterTokens.length > 0 ? 1 : 0); + for (var p = fillerStart; p < targetRows; p++) { + var ptr = document.createElement("tr"); + ptr.className = "gd-tbl-placeholder-row"; + for (var pc = 0; pc < colCount; pc++) { + var ptd = document.createElement("td"); + ptd.className = "gt_row"; + var dot = document.createElement("span"); + dot.className = "gd-tbl-placeholder-dot"; + ptd.appendChild(dot); + ptr.appendChild(ptd); + } + tbody.appendChild(ptr); + } + } + if (oldBody) { tbl.replaceChild(tbody, oldBody); } else { tbl.appendChild(tbody); } + // Measure actual row height from first data row for placeholder sizing + var hasPlaceholders = tbody.querySelector(".gd-tbl-placeholder-row") != null; + if (hasPlaceholders && !state._rowHeightMeasured) { + var firstDataRow = tbody.querySelector("tr:not(.gd-tbl-placeholder-row)"); + if (firstDataRow) { + var measuredH = firstDataRow.getBoundingClientRect().height; + if (measuredH > 0) { + state._rowHeight = measuredH; + state._rowHeightMeasured = true; + // Apply measured height to placeholder rows + var placeholders = tbody.querySelectorAll(".gd-tbl-placeholder-row td"); + for (var ph = 0; ph < placeholders.length; ph++) { + placeholders[ph].style.height = measuredH + "px"; + } + } + } + } else if (hasPlaceholders && state._rowHeightMeasured) { + // Apply stored height to placeholder rows + var placeholders = tbody.querySelectorAll(".gd-tbl-placeholder-row td"); + for (var ph = 0; ph < placeholders.length; ph++) { + placeholders[ph].style.height = state._rowHeight + "px"; + } + } + // Update colgroup to hide toggled columns updateColgroup(el, state); // Update column headers visibility From 1195ddff33562d851be743066d46e420fb546e8e Mon Sep 17 00:00:00 2001 From: Richard Iannone Date: Fri, 24 Apr 2026 15:54:47 -0400 Subject: [PATCH 3/8] Add Table Explorer translations and fix Hebrew --- great_docs/_translations.py | 165 +++++++++++++++++++++++++++++++++++- 1 file changed, 164 insertions(+), 1 deletion(-) diff --git a/great_docs/_translations.py b/great_docs/_translations.py index 914c556..b6b1d5d 100644 --- a/great_docs/_translations.py +++ b/great_docs/_translations.py @@ -5039,7 +5039,170 @@ "el": "Εξέλιξη υπογραφής για {symbol}", "hi": "{symbol} के हस्ताक्षर का विकास", "ar": "تطور توقيع {symbol}", - "he": "התפתחות חתימה עבור {symbol}", + "he": "התפתחות חتימה עבור {symbol}", + }, + # ── Table Explorer ──────────────────────────────────────────────────── + "tbl_filter_hint": { + "en": "Add Data Filter", + "fr": "Ajouter un filtre", + "de": "Datenfilter hinzufügen", + "es": "Agregar filtro de datos", + "pt": "Adicionar filtro de dados", + "it": "Aggiungi filtro dati", + "nl": "Gegevensfilter toevoegen", + "ja": "データフィルターを追加", + "ko": "데이터 필터 추가", + "zh-Hans": "添加数据筛选", + "zh-Hant": "新增資料篩選", + "ru": "Добавить фильтр данных", + "pl": "Dodaj filtr danych", + "tr": "Veri filtresi ekle", + "sv": "Lägg till datafilter", + "da": "Tilføj datafilter", + "nb": "Legg til datafilter", + "is": "Bæta við gagnasíu", + "fi": "Lisää datasuodatin", + "cs": "Přidat filtr dat", + "ro": "Adăugare filtru de date", + "el": "Προσθήκη φίλτρου δεδομένων", + "hi": "डेटा फ़िल्टर जोड़ें", + "ar": "إضافة فلتر بيانات", + "he": "הוספת מסנן נתונים", + }, + "tbl_no_matching_rows": { + "en": "No matching rows", + "fr": "Aucune ligne correspondante", + "de": "Keine passenden Zeilen", + "es": "No hay filas coincidentes", + "pt": "Nenhuma linha correspondente", + "it": "Nessuna riga corrispondente", + "nl": "Geen overeenkomende rijen", + "ja": "一致する行がありません", + "ko": "일치하는 행 없음", + "zh-Hans": "没有匹配的行", + "zh-Hant": "沒有符合的列", + "ru": "Нет подходящих строк", + "pl": "Brak pasujących wierszy", + "tr": "Eşleşen satır yok", + "sv": "Inga matchande rader", + "da": "Ingen matchende rækker", + "nb": "Ingen treff", + "is": "Engar samsvarandi línur", + "fi": "Ei vastaavia rivejä", + "cs": "Žádné odpovídající řádky", + "ro": "Niciun rând corespunzător", + "el": "Δεν βρέθηκαν αντίστοιχες γραμμές", + "hi": "कोई मिलान पंक्तियाँ नहीं", + "ar": "لا توجد صفوف مطابقة", + "he": "אין שורות תואמות", + }, + "tbl_columns_btn": { + "en": "Columns", + "fr": "Colonnes", + "de": "Spalten", + "es": "Columnas", + "pt": "Colunas", + "it": "Colonne", + "nl": "Kolommen", + "ja": "列", + "ko": "열", + "zh-Hans": "列", + "zh-Hant": "欄", + "ru": "Столбцы", + "pl": "Kolumny", + "tr": "Sütunlar", + "sv": "Kolumner", + "da": "Kolonner", + "nb": "Kolonner", + "is": "Dálkar", + "fi": "Sarakkeet", + "cs": "Sloupce", + "ro": "Coloane", + "el": "Στήλες", + "hi": "स्तंभ", + "ar": "الأعمدة", + "he": "עמודות", + }, + "tbl_copy_tooltip": { + "en": "Copy", + "fr": "Copier", + "de": "Kopieren", + "es": "Copiar", + "pt": "Copiar", + "it": "Copia", + "nl": "Kopiëren", + "ja": "コピー", + "ko": "복사", + "zh-Hans": "复制", + "zh-Hant": "複製", + "ru": "Копировать", + "pl": "Kopiuj", + "tr": "Kopyala", + "sv": "Kopiera", + "da": "Kopiér", + "nb": "Kopier", + "is": "Afrita", + "fi": "Kopioi", + "cs": "Kopírovat", + "ro": "Copiază", + "el": "Αντιγραφή", + "hi": "कॉपी करें", + "ar": "نسخ", + "he": "העתקה", + }, + "tbl_download_tooltip": { + "en": "Download", + "fr": "Télécharger", + "de": "Herunterladen", + "es": "Descargar", + "pt": "Baixar", + "it": "Scarica", + "nl": "Downloaden", + "ja": "ダウンロード", + "ko": "다운로드", + "zh-Hans": "下载", + "zh-Hant": "下載", + "ru": "Скачать", + "pl": "Pobierz", + "tr": "İndir", + "sv": "Ladda ner", + "da": "Download", + "nb": "Last ned", + "is": "Hlaða niður", + "fi": "Lataa", + "cs": "Stáhnout", + "ro": "Descarcă", + "el": "Λήψη", + "hi": "डाउनलोड करें", + "ar": "تنزيل", + "he": "הורדה", + }, + "tbl_reset_tooltip": { + "en": "Reset", + "fr": "Réinitialiser", + "de": "Zurücksetzen", + "es": "Restablecer", + "pt": "Redefinir", + "it": "Ripristina", + "nl": "Herstellen", + "ja": "リセット", + "ko": "초기화", + "zh-Hans": "重置", + "zh-Hant": "重設", + "ru": "Сбросить", + "pl": "Resetuj", + "tr": "Sıfırla", + "sv": "Återställ", + "da": "Nulstil", + "nb": "Tilbakestill", + "is": "Endurstilla", + "fi": "Nollaa", + "cs": "Obnovit", + "ro": "Resetare", + "el": "Επαναφορά", + "hi": "रीसेट करें", + "ar": "إعادة تعيين", + "he": "איפוס", }, } From 10555a1050e32157d0a856b1a40bf8cc9422da77 Mon Sep 17 00:00:00 2001 From: Richard Iannone Date: Fri, 24 Apr 2026 16:12:22 -0400 Subject: [PATCH 4/8] Add table filter UI translations --- great_docs/_translations.py | 324 ++++++++++++++++++++++++++++++++++++ 1 file changed, 324 insertions(+) diff --git a/great_docs/_translations.py b/great_docs/_translations.py index b6b1d5d..f40fd6f 100644 --- a/great_docs/_translations.py +++ b/great_docs/_translations.py @@ -5204,6 +5204,330 @@ "ar": "إعادة تعيين", "he": "איפוס", }, + "tbl_filter_contains": { + "en": "contains", + "fr": "contient", + "de": "enthält", + "es": "contiene", + "pt": "contém", + "it": "contiene", + "nl": "bevat", + "ja": "を含む", + "ko": "포함", + "zh-Hans": "包含", + "zh-Hant": "包含", + "ru": "содержит", + "pl": "zawiera", + "tr": "içerir", + "sv": "innehåller", + "da": "indeholder", + "nb": "inneholder", + "is": "inniheldur", + "fi": "sisältää", + "cs": "obsahuje", + "ro": "conține", + "el": "περιέχει", + "hi": "शामिल है", + "ar": "يحتوي على", + "he": "מכיל", + }, + "tbl_filter_not_contains": { + "en": "doesn\u2019t contain", + "fr": "ne contient pas", + "de": "enthält nicht", + "es": "no contiene", + "pt": "não contém", + "it": "non contiene", + "nl": "bevat niet", + "ja": "を含まない", + "ko": "포함하지 않음", + "zh-Hans": "不包含", + "zh-Hant": "不包含", + "ru": "не содержит", + "pl": "nie zawiera", + "tr": "içermez", + "sv": "innehåller inte", + "da": "indeholder ikke", + "nb": "inneholder ikke", + "is": "inniheldur ekki", + "fi": "ei sisällä", + "cs": "neobsahuje", + "ro": "nu conține", + "el": "δεν περιέχει", + "hi": "शामिल नहीं है", + "ar": "لا يحتوي على", + "he": "לא מכיל", + }, + "tbl_filter_starts_with": { + "en": "starts with", + "fr": "commence par", + "de": "beginnt mit", + "es": "empieza con", + "pt": "começa com", + "it": "inizia con", + "nl": "begint met", + "ja": "で始まる", + "ko": "로 시작", + "zh-Hans": "开头为", + "zh-Hant": "開頭為", + "ru": "начинается с", + "pl": "zaczyna się od", + "tr": "ile başlar", + "sv": "börjar med", + "da": "begynder med", + "nb": "begynner med", + "is": "byrjar á", + "fi": "alkaa", + "cs": "začíná na", + "ro": "începe cu", + "el": "αρχίζει με", + "hi": "से शुरू होता है", + "ar": "يبدأ بـ", + "he": "מתחיל ב", + }, + "tbl_filter_ends_with": { + "en": "ends with", + "fr": "se termine par", + "de": "endet mit", + "es": "termina con", + "pt": "termina com", + "it": "finisce con", + "nl": "eindigt met", + "ja": "で終わる", + "ko": "로 끝남", + "zh-Hans": "结尾为", + "zh-Hant": "結尾為", + "ru": "заканчивается на", + "pl": "kończy się na", + "tr": "ile biter", + "sv": "slutar med", + "da": "slutter med", + "nb": "slutter med", + "is": "endar á", + "fi": "päättyy", + "cs": "končí na", + "ro": "se termină cu", + "el": "τελειώνει με", + "hi": "से समाप्त होता है", + "ar": "ينتهي بـ", + "he": "מסתיים ב", + }, + "tbl_filter_equals": { + "en": "equals", + "fr": "est égal à", + "de": "gleich", + "es": "es igual a", + "pt": "é igual a", + "it": "uguale a", + "nl": "is gelijk aan", + "ja": "と等しい", + "ko": "같음", + "zh-Hans": "等于", + "zh-Hant": "等於", + "ru": "равно", + "pl": "równa się", + "tr": "eşittir", + "sv": "lika med", + "da": "er lig med", + "nb": "er lik", + "is": "jafnt og", + "fi": "on yhtä kuin", + "cs": "rovná se", + "ro": "este egal cu", + "el": "ίσο με", + "hi": "बराबर है", + "ar": "يساوي", + "he": "שווה ל", + }, + "tbl_filter_is_empty": { + "en": "is empty", + "fr": "est vide", + "de": "ist leer", + "es": "está vacío", + "pt": "está vazio", + "it": "è vuoto", + "nl": "is leeg", + "ja": "空である", + "ko": "비어 있음", + "zh-Hans": "为空", + "zh-Hant": "為空", + "ru": "пусто", + "pl": "jest puste", + "tr": "boş", + "sv": "är tom", + "da": "er tom", + "nb": "er tom", + "is": "er tómt", + "fi": "on tyhjä", + "cs": "je prázdné", + "ro": "este gol", + "el": "είναι κενό", + "hi": "खाली है", + "ar": "فارغ", + "he": "ריק", + }, + "tbl_filter_not_empty": { + "en": "is not empty", + "fr": "n\u2019est pas vide", + "de": "ist nicht leer", + "es": "no está vacío", + "pt": "não está vazio", + "it": "non è vuoto", + "nl": "is niet leeg", + "ja": "空でない", + "ko": "비어 있지 않음", + "zh-Hans": "不为空", + "zh-Hant": "不為空", + "ru": "не пусто", + "pl": "nie jest puste", + "tr": "boş değil", + "sv": "är inte tom", + "da": "er ikke tom", + "nb": "er ikke tom", + "is": "er ekki tómt", + "fi": "ei ole tyhjä", + "cs": "není prázdné", + "ro": "nu este gol", + "el": "δεν είναι κενό", + "hi": "खाली नहीं है", + "ar": "غير فارغ", + "he": "לא ריק", + }, + "tbl_filter_between": { + "en": "between", + "fr": "entre", + "de": "zwischen", + "es": "entre", + "pt": "entre", + "it": "tra", + "nl": "tussen", + "ja": "の間", + "ko": "사이", + "zh-Hans": "介于", + "zh-Hant": "介於", + "ru": "между", + "pl": "między", + "tr": "arasında", + "sv": "mellan", + "da": "mellem", + "nb": "mellom", + "is": "á milli", + "fi": "välillä", + "cs": "mezi", + "ro": "între", + "el": "μεταξύ", + "hi": "के बीच", + "ar": "بين", + "he": "בין", + }, + "tbl_filter_is_true": { + "en": "is true", + "fr": "est vrai", + "de": "ist wahr", + "es": "es verdadero", + "pt": "é verdadeiro", + "it": "è vero", + "nl": "is waar", + "ja": "真である", + "ko": "참", + "zh-Hans": "为真", + "zh-Hant": "為真", + "ru": "истина", + "pl": "jest prawdą", + "tr": "doğru", + "sv": "är sant", + "da": "er sand", + "nb": "er sant", + "is": "er satt", + "fi": "on tosi", + "cs": "je pravda", + "ro": "este adevărat", + "el": "είναι αληθές", + "hi": "सत्य है", + "ar": "صحيح", + "he": "אמת", + }, + "tbl_filter_is_false": { + "en": "is false", + "fr": "est faux", + "de": "ist falsch", + "es": "es falso", + "pt": "é falso", + "it": "è falso", + "nl": "is onwaar", + "ja": "偽である", + "ko": "거짓", + "zh-Hans": "为假", + "zh-Hant": "為假", + "ru": "ложь", + "pl": "jest fałszem", + "tr": "yanlış", + "sv": "är falskt", + "da": "er falsk", + "nb": "er usant", + "is": "er ósatt", + "fi": "on epätosi", + "cs": "je nepravda", + "ro": "este fals", + "el": "είναι ψευδές", + "hi": "असत्य है", + "ar": "خاطئ", + "he": "שקר", + }, + "tbl_filter_is_null": { + "en": "is null", + "fr": "est nul", + "de": "ist null", + "es": "es nulo", + "pt": "é nulo", + "it": "è nullo", + "nl": "is null", + "ja": "null である", + "ko": "null", + "zh-Hans": "为 null", + "zh-Hant": "為 null", + "ru": "null", + "pl": "jest null", + "tr": "null", + "sv": "är null", + "da": "er null", + "nb": "er null", + "is": "er null", + "fi": "on null", + "cs": "je null", + "ro": "este null", + "el": "είναι null", + "hi": "null है", + "ar": "فارغ (null)", + "he": "null", + }, + "tbl_filter_is_not_null": { + "en": "is not null", + "fr": "n\u2019est pas nul", + "de": "ist nicht null", + "es": "no es nulo", + "pt": "não é nulo", + "it": "non è nullo", + "nl": "is niet null", + "ja": "null でない", + "ko": "null 아님", + "zh-Hans": "不为 null", + "zh-Hant": "不為 null", + "ru": "не null", + "pl": "nie jest null", + "tr": "null değil", + "sv": "är inte null", + "da": "er ikke null", + "nb": "er ikke null", + "is": "er ekki null", + "fi": "ei ole null", + "cs": "není null", + "ro": "nu este null", + "el": "δεν είναι null", + "hi": "null नहीं है", + "ar": "غير فارغ (null)", + "he": "לא null", + }, } From 470d6942b02bedb2894c63eca8b15490195835a2 Mon Sep 17 00:00:00 2001 From: Richard Iannone Date: Fri, 24 Apr 2026 16:12:34 -0400 Subject: [PATCH 5/8] Use _gdT for filter operation labels --- great_docs/assets/tbl-explorer.js | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/great_docs/assets/tbl-explorer.js b/great_docs/assets/tbl-explorer.js index 1eacf7c..8200c04 100644 --- a/great_docs/assets/tbl-explorer.js +++ b/great_docs/assets/tbl-explorer.js @@ -97,13 +97,13 @@ // {key, label, needsValue, appliesTo(dtype)} var FILTER_OPS = [ // String ops - {key:"contains", label:"contains", needsValue:true, appliesTo:function(d){return !isNumeric(d) && !isBool(d);}}, - {key:"not_contains",label:"doesn\u2019t contain",needsValue:true,appliesTo:function(d){return !isNumeric(d) && !isBool(d);}}, - {key:"starts_with", label:"starts with", needsValue:true, appliesTo:function(d){return !isNumeric(d) && !isBool(d);}}, - {key:"ends_with", label:"ends with", needsValue:true, appliesTo:function(d){return !isNumeric(d) && !isBool(d);}}, - {key:"eq_str", label:"equals", needsValue:true, appliesTo:function(d){return !isNumeric(d) && !isBool(d);}}, - {key:"is_empty", label:"is empty", needsValue:false, appliesTo:function(d){return !isNumeric(d) && !isBool(d);}}, - {key:"not_empty", label:"is not empty", needsValue:false, appliesTo:function(d){return !isNumeric(d) && !isBool(d);}}, + {key:"contains", label:_gdT("tbl_filter_contains","contains"), needsValue:true, appliesTo:function(d){return !isNumeric(d) && !isBool(d);}}, + {key:"not_contains",label:_gdT("tbl_filter_not_contains","doesn\u2019t contain"),needsValue:true,appliesTo:function(d){return !isNumeric(d) && !isBool(d);}}, + {key:"starts_with", label:_gdT("tbl_filter_starts_with","starts with"), needsValue:true, appliesTo:function(d){return !isNumeric(d) && !isBool(d);}}, + {key:"ends_with", label:_gdT("tbl_filter_ends_with","ends with"), needsValue:true, appliesTo:function(d){return !isNumeric(d) && !isBool(d);}}, + {key:"eq_str", label:_gdT("tbl_filter_equals","equals"), needsValue:true, appliesTo:function(d){return !isNumeric(d) && !isBool(d);}}, + {key:"is_empty", label:_gdT("tbl_filter_is_empty","is empty"), needsValue:false, appliesTo:function(d){return !isNumeric(d) && !isBool(d);}}, + {key:"not_empty", label:_gdT("tbl_filter_not_empty","is not empty"), needsValue:false, appliesTo:function(d){return !isNumeric(d) && !isBool(d);}}, // Numeric ops {key:"eq", label:"\u003D", needsValue:true, appliesTo:isNumeric}, {key:"neq", label:"\u2260", needsValue:true, appliesTo:isNumeric}, @@ -111,13 +111,13 @@ {key:"lte", label:"\u2264", needsValue:true, appliesTo:isNumeric}, {key:"gt", label:"\u003E", needsValue:true, appliesTo:isNumeric}, {key:"gte", label:"\u2265", needsValue:true, appliesTo:isNumeric}, - {key:"between",label:"between",needsValue:"two",appliesTo:isNumeric}, + {key:"between",label:_gdT("tbl_filter_between","between"),needsValue:"two",appliesTo:isNumeric}, // Bool ops - {key:"is_true", label:"is true", needsValue:false, appliesTo:isBool}, - {key:"is_false", label:"is false", needsValue:false, appliesTo:isBool}, + {key:"is_true", label:_gdT("tbl_filter_is_true","is true"), needsValue:false, appliesTo:isBool}, + {key:"is_false", label:_gdT("tbl_filter_is_false","is false"), needsValue:false, appliesTo:isBool}, // Universal ops - {key:"is_null", label:"is null", needsValue:false, appliesTo:function(){return true;}}, - {key:"is_not_null", label:"is not null", needsValue:false, appliesTo:function(){return true;}} + {key:"is_null", label:_gdT("tbl_filter_is_null","is null"), needsValue:false, appliesTo:function(){return true;}}, + {key:"is_not_null", label:_gdT("tbl_filter_is_not_null","is not null"), needsValue:false, appliesTo:function(){return true;}} ]; function getOpsForDtype(dtype) { @@ -391,7 +391,7 @@ var heading = document.createElement("span"); heading.className = "gd-tbl-fw-label"; - heading.textContent = col.name + " between"; + heading.textContent = col.name + " " + _gdT("tbl_filter_between", "between"); wizard.appendChild(heading); var row = document.createElement("span"); From 8b408d481b3945c5f5b8dcf6d6e81db0c2eb7132 Mon Sep 17 00:00:00 2001 From: Richard Iannone Date: Fri, 24 Apr 2026 16:12:50 -0400 Subject: [PATCH 6/8] Add table-explorer guides for i18n packages --- .../synthetic/specs/gdtest_i18n_arabic.py | 22 ++++++++++++++++++ .../synthetic/specs/gdtest_i18n_french.py | 23 +++++++++++++++++++ .../synthetic/specs/gdtest_i18n_japanese.py | 22 ++++++++++++++++++ 3 files changed, 67 insertions(+) diff --git a/test-packages/synthetic/specs/gdtest_i18n_arabic.py b/test-packages/synthetic/specs/gdtest_i18n_arabic.py index ba23d8e..86e1c93 100644 --- a/test-packages/synthetic/specs/gdtest_i18n_arabic.py +++ b/test-packages/synthetic/specs/gdtest_i18n_arabic.py @@ -275,6 +275,27 @@ def escape_html(value: str) -> str: print(safe) ``` """, + "user_guide/03-table-explorer.qmd": """\ + --- + title: "\u0645\u0633\u062a\u0643\u0634\u0641 \u0627\u0644\u062c\u062f\u0648\u0644" + guide-section: "\u0627\u0644\u0623\u0633\u0627\u0633\u064a\u0627\u062a" + --- + + # \u0645\u0633\u062a\u0643\u0634\u0641 \u0627\u0644\u062c\u062f\u0648\u0644 + + \u0627\u0633\u062a\u062e\u062f\u0645 `tbl_explorer()` \u0644\u0627\u0633\u062a\u0643\u0634\u0627\u0641 \u0628\u064a\u0627\u0646\u0627\u062a\u0643 \u0628\u0634\u0643\u0644 \u062a\u0641\u0627\u0639\u0644\u064a. + + ```{python} + #| echo: false + import tempfile + from great_docs import tbl_explorer + rows = "\u0627\u0644\u0627\u0633\u0645,\u0627\u0644\u0639\u0645\u0631,\u0627\u0644\u0645\u062f\u064a\u0646\u0629,\u0627\u0644\u062f\u0631\u062c\u0629\\n\u0623\u062d\u0645\u062f,28,\u0627\u0644\u0642\u0627\u0647\u0631\u0629,92.5\\n\u0641\u0627\u0637\u0645\u0629,35,\u0627\u0644\u0631\u064a\u0627\u0636,87.3\\n\u062e\u0627\u0644\u062f,22,\u062f\u0628\u064a,95.1\\n\u0646\u0648\u0631,41,\u0628\u064a\u0631\u0648\u062a,78.6\\n\u0633\u0627\u0631\u0629,30,\u0627\u0644\u062f\u0627\u0631 \u0627\u0644\u0628\u064a\u0636\u0627\u0621,88.9\\n\u0639\u0645\u0631,27,\u062a\u0648\u0646\u0633,91.2\\n\u0644\u064a\u0644\u0649,33,\u0639\u0645\u0627\u0646,84.7" + tf = tempfile.NamedTemporaryFile(mode="w", suffix=".csv", delete=False) + tf.write(rows) + tf.close() + tbl_explorer(tf.name) + ``` + """, "README.md": """\ # gdtest-i18n-arabic @@ -307,6 +328,7 @@ def escape_html(value: str) -> str: "user_guide_files": [ "01-overview.qmd", "02-templates.qmd", + "03-table-explorer.qmd", ], }, } diff --git a/test-packages/synthetic/specs/gdtest_i18n_french.py b/test-packages/synthetic/specs/gdtest_i18n_french.py index 4bf1014..9576ddd 100644 --- a/test-packages/synthetic/specs/gdtest_i18n_french.py +++ b/test-packages/synthetic/specs/gdtest_i18n_french.py @@ -266,6 +266,28 @@ def resumer(valeurs: list[float]) -> dict: print(stats) ``` """, + "user_guide/03-table-explorer.qmd": """\ + --- + title: "Exploration de tableau" + guide-section: "Fondamentaux" + --- + + # Exploration de tableau + + Utilisez `tbl_explorer()` pour explorer vos donn\u00e9es de + mani\u00e8re interactive. + + ```{python} + #| echo: false + import tempfile + from great_docs import tbl_explorer + rows = "nom,age,ville,score\\nMarie,28,Paris,92.5\\nPierre,35,Lyon,87.3\\nSophie,22,Marseille,95.1\\nJean,41,Toulouse,78.6\\nClaire,30,Nantes,88.9\\nLucas,27,Bordeaux,91.2\\nEmma,33,Lille,84.7" + tf = tempfile.NamedTemporaryFile(mode="w", suffix=".csv", delete=False) + tf.write(rows) + tf.close() + tbl_explorer(tf.name) + ``` + """, "README.md": """\ # gdtest-i18n-french @@ -298,6 +320,7 @@ def resumer(valeurs: list[float]) -> dict: "user_guide_files": [ "01-demarrage-rapide.qmd", "02-configuration.qmd", + "03-table-explorer.qmd", ], }, } diff --git a/test-packages/synthetic/specs/gdtest_i18n_japanese.py b/test-packages/synthetic/specs/gdtest_i18n_japanese.py index 6b1a1ec..ba06941 100644 --- a/test-packages/synthetic/specs/gdtest_i18n_japanese.py +++ b/test-packages/synthetic/specs/gdtest_i18n_japanese.py @@ -261,6 +261,27 @@ def divide(a: float, b: float) -> float: | `multiply` | \u4e8c\u3064\u306e\u6570\u5024\u3092\u4e57\u7b97 | | `divide` | \u4e8c\u3064\u306e\u6570\u5024\u3092\u9664\u7b97 | """, + "user_guide/03-table-explorer.qmd": """\ + --- + title: "\u30c6\u30fc\u30d6\u30eb\u30a8\u30af\u30b9\u30d7\u30ed\u30fc\u30e9\u30fc" + guide-section: "\u306f\u3058\u3081\u306b" + --- + + # \u30c6\u30fc\u30d6\u30eb\u30a8\u30af\u30b9\u30d7\u30ed\u30fc\u30e9\u30fc + + `tbl_explorer()` \u3092\u4f7f\u3063\u3066\u30c7\u30fc\u30bf\u3092\u30a4\u30f3\u30bf\u30e9\u30af\u30c6\u30a3\u30d6\u306b\u63a2\u7d22\u3067\u304d\u307e\u3059\u3002 + + ```{python} + #| echo: false + import tempfile + from great_docs import tbl_explorer + rows = "\u540d\u524d,\u5e74\u9f62,\u90fd\u5e02,\u5f97\u70b9\\n\u592a\u90ce,28,\u6771\u4eac,92.5\\n\u82b1\u5b50,35,\u5927\u962a,87.3\\n\u6b21\u90ce,22,\u4eac\u90fd,95.1\\n\u7f8e\u6708,41,\u6a2a\u6d5c,78.6\\n\u5065,30,\u798f\u5ca1,88.9\\n\u3055\u304f\u3089,27,\u540d\u53e4\u5c4b,91.2\\n\u8aa0,33,\u672d\u5e4c,84.7" + tf = tempfile.NamedTemporaryFile(mode="w", suffix=".csv", delete=False) + tf.write(rows) + tf.close() + tbl_explorer(tf.name) + ``` + """, "README.md": """\ # gdtest-i18n-japanese @@ -288,6 +309,7 @@ def divide(a: float, b: float) -> float: "user_guide_files": [ "01-quickstart.qmd", "02-functions.qmd", + "03-table-explorer.qmd", ], }, } From a0e107aa3e40c8ccf5dc75abc46fb82b5b2f9661 Mon Sep 17 00:00:00 2001 From: Richard Iannone Date: Fri, 24 Apr 2026 16:32:14 -0400 Subject: [PATCH 7/8] Add table filter UI translations --- great_docs/_translations.py | 189 ++++++++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) diff --git a/great_docs/_translations.py b/great_docs/_translations.py index f40fd6f..ed7d1b0 100644 --- a/great_docs/_translations.py +++ b/great_docs/_translations.py @@ -5528,6 +5528,195 @@ "ar": "غير فارغ (null)", "he": "לא null", }, + "tbl_filter_enter_value": { + "en": "Enter value\u2026", + "fr": "Saisir une valeur\u2026", + "de": "Wert eingeben\u2026", + "es": "Introducir valor\u2026", + "pt": "Inserir valor\u2026", + "it": "Inserisci valore\u2026", + "nl": "Waarde invoeren\u2026", + "ja": "値を入力\u2026", + "ko": "값 입력\u2026", + "zh-Hans": "输入值\u2026", + "zh-Hant": "輸入值\u2026", + "ru": "Введите значение\u2026", + "pl": "Wpisz warto\u015b\u0107\u2026", + "tr": "De\u011fer girin\u2026", + "sv": "Ange v\u00e4rde\u2026", + "da": "Indtast v\u00e6rdi\u2026", + "nb": "Skriv inn verdi\u2026", + "is": "Sl\u00e1\u00f0u inn gildi\u2026", + "fi": "Sy\u00f6t\u00e4 arvo\u2026", + "cs": "Zadejte hodnotu\u2026", + "ro": "Introduce\u021bi valoarea\u2026", + "el": "\u0395\u03b9\u03c3\u03b1\u03b3\u03c9\u03b3\u03ae \u03c4\u03b9\u03bc\u03ae\u03c2\u2026", + "hi": "\u092e\u093e\u0928 \u0926\u0930\u094d\u091c \u0915\u0930\u0947\u0902\u2026", + "ar": "\u0623\u062f\u062e\u0644 \u0642\u064a\u0645\u0629\u2026", + "he": "\u05d4\u05d6\u05df \u05e2\u05e8\u05da\u2026", + }, + "tbl_filter_case_insensitive": { + "en": "Case insensitive", + "fr": "Insensible \u00e0 la casse", + "de": "Gro\u00df-/Kleinschreibung ignorieren", + "es": "No distingue may\u00fasculas", + "pt": "Sem distin\u00e7\u00e3o de mai\u00fasculas", + "it": "Senza distinzione maiuscole", + "nl": "Niet hoofdlettergevoelig", + "ja": "\u5927\u6587\u5b57\u5c0f\u6587\u5b57\u3092\u533a\u5225\u3057\u306a\u3044", + "ko": "\ub300\uc18c\ubb38\uc790 \uad6c\ubd84 \uc548 \ud568", + "zh-Hans": "\u4e0d\u533a\u5206\u5927\u5c0f\u5199", + "zh-Hant": "\u4e0d\u5340\u5206\u5927\u5c0f\u5beb", + "ru": "\u0411\u0435\u0437 \u0443\u0447\u0451\u0442\u0430 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430", + "pl": "Bez rozr\u00f3\u017cniania wielko\u015bci liter", + "tr": "B\u00fcy\u00fck/k\u00fc\u00e7\u00fck harf duyars\u0131z", + "sv": "Skiftl\u00e4gesok\u00e4nslig", + "da": "Versaluf\u00f8lsom", + "nb": "Ikke skill mellom store/sm\u00e5 bokstaver", + "is": "H\u00e1stafa\u00f3n\u00e6mt", + "fi": "Ei erota isoja ja pieni\u00e4 kirjaimia", + "cs": "Nerozli\u0161uje velk\u00e1/mal\u00e1 p\u00edsmena", + "ro": "F\u0103r\u0103 diferen\u021biere majuscule", + "el": "\u03a7\u03c9\u03c1\u03af\u03c2 \u03b4\u03b9\u03ac\u03ba\u03c1\u03b9\u03c3\u03b7 \u03c0\u03b5\u03b6\u03ce\u03bd/\u03ba\u03b5\u03c6\u03b1\u03bb\u03b1\u03af\u03c9\u03bd", + "hi": "\u0915\u0947\u0938 \u0905\u0938\u0902\u0935\u0947\u0926\u0928\u0936\u0940\u0932", + "ar": "\u063a\u064a\u0631 \u062d\u0633\u0627\u0633 \u0644\u0644\u0623\u062d\u0631\u0641", + "he": "\u05dc\u05d0 \u05ea\u05dc\u05d5\u05d9 \u05e8\u05d9\u05e9\u05d9\u05d5\u05ea", + }, + "tbl_filter_case_sensitive": { + "en": "Case sensitive", + "fr": "Sensible \u00e0 la casse", + "de": "Gro\u00df-/Kleinschreibung beachten", + "es": "Distingue may\u00fasculas", + "pt": "Com distin\u00e7\u00e3o de mai\u00fasculas", + "it": "Distinzione maiuscole", + "nl": "Hoofdlettergevoelig", + "ja": "\u5927\u6587\u5b57\u5c0f\u6587\u5b57\u3092\u533a\u5225\u3059\u308b", + "ko": "\ub300\uc18c\ubb38\uc790 \uad6c\ubd84", + "zh-Hans": "\u533a\u5206\u5927\u5c0f\u5199", + "zh-Hant": "\u5340\u5206\u5927\u5c0f\u5beb", + "ru": "\u0421 \u0443\u0447\u0451\u0442\u043e\u043c \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430", + "pl": "Rozr\u00f3\u017cnianie wielko\u015bci liter", + "tr": "B\u00fcy\u00fck/k\u00fc\u00e7\u00fck harf duyarl\u0131", + "sv": "Skiftl\u00e4gesk\u00e4nslig", + "da": "Forskelbehandl store/sm\u00e5", + "nb": "Skill mellom store/sm\u00e5 bokstaver", + "is": "H\u00e1stafan\u00e6mt", + "fi": "Erottaa isot ja pienet kirjaimet", + "cs": "Rozli\u0161uje velk\u00e1/mal\u00e1 p\u00edsmena", + "ro": "Cu diferen\u021biere majuscule", + "el": "\u039c\u03b5 \u03b4\u03b9\u03ac\u03ba\u03c1\u03b9\u03c3\u03b7 \u03c0\u03b5\u03b6\u03ce\u03bd/\u03ba\u03b5\u03c6\u03b1\u03bb\u03b1\u03af\u03c9\u03bd", + "hi": "\u0915\u0947\u0938 \u0938\u0902\u0935\u0947\u0926\u0928\u0936\u0940\u0932", + "ar": "\u062d\u0633\u0627\u0633 \u0644\u0644\u0623\u062d\u0631\u0641", + "he": "\u05ea\u05dc\u05d5\u05d9 \u05e8\u05d9\u05e9\u05d9\u05d5\u05ea", + }, + "tbl_filter_apply": { + "en": "Apply", + "fr": "Appliquer", + "de": "Anwenden", + "es": "Aplicar", + "pt": "Aplicar", + "it": "Applica", + "nl": "Toepassen", + "ja": "\u9069\u7528", + "ko": "\uc801\uc6a9", + "zh-Hans": "\u5e94\u7528", + "zh-Hant": "\u5957\u7528", + "ru": "\u041f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c", + "pl": "Zastosuj", + "tr": "Uygula", + "sv": "Till\u00e4mpa", + "da": "Anvend", + "nb": "Bruk", + "is": "Beita", + "fi": "K\u00e4yt\u00e4", + "cs": "Pou\u017e\u00edt", + "ro": "Aplic\u0103", + "el": "\u0395\u03c6\u03b1\u03c1\u03bc\u03bf\u03b3\u03ae", + "hi": "\u0932\u093e\u0917\u0942 \u0915\u0930\u0947\u0902", + "ar": "\u062a\u0637\u0628\u064a\u0642", + "he": "\u05d4\u05d7\u05dc", + }, + "tbl_filter_min": { + "en": "min", + "fr": "min", + "de": "Min", + "es": "m\u00edn", + "pt": "m\u00edn", + "it": "min", + "nl": "min", + "ja": "\u6700\u5c0f", + "ko": "\ucd5c\uc18c", + "zh-Hans": "\u6700\u5c0f", + "zh-Hant": "\u6700\u5c0f", + "ru": "\u043c\u0438\u043d", + "pl": "min", + "tr": "min", + "sv": "min", + "da": "min", + "nb": "min", + "is": "l\u00e1gm", + "fi": "min", + "cs": "min", + "ro": "min", + "el": "\u03b5\u03bb\u03ac\u03c7", + "hi": "\u0928\u094d\u092f\u0942\u0928", + "ar": "\u0623\u062f\u0646\u0649", + "he": "\u05de\u05d9\u05e0\u05d9\u05de\u05d5\u05dd", + }, + "tbl_filter_and": { + "en": "and", + "fr": "et", + "de": "und", + "es": "y", + "pt": "e", + "it": "e", + "nl": "en", + "ja": "\u301c", + "ko": "\u2013", + "zh-Hans": "\u5230", + "zh-Hant": "\u5230", + "ru": "\u0438", + "pl": "i", + "tr": "ve", + "sv": "och", + "da": "og", + "nb": "og", + "is": "og", + "fi": "ja", + "cs": "a", + "ro": "\u0219i", + "el": "\u03ba\u03b1\u03b9", + "hi": "\u0914\u0930", + "ar": "\u0648", + "he": "\u05d5", + }, + "tbl_filter_max": { + "en": "max", + "fr": "max", + "de": "Max", + "es": "m\u00e1x", + "pt": "m\u00e1x", + "it": "max", + "nl": "max", + "ja": "\u6700\u5927", + "ko": "\ucd5c\ub300", + "zh-Hans": "\u6700\u5927", + "zh-Hant": "\u6700\u5927", + "ru": "\u043c\u0430\u043a\u0441", + "pl": "maks", + "tr": "maks", + "sv": "max", + "da": "maks", + "nb": "maks", + "is": "h\u00e1m", + "fi": "maks", + "cs": "max", + "ro": "max", + "el": "\u03bc\u03ad\u03b3", + "hi": "\u0905\u0927\u093f\u0915", + "ar": "\u0623\u0642\u0635\u0649", + "he": "\u05de\u05e7\u05e1\u05d9\u05de\u05d5\u05dd", + }, } From 4439579c9cdf46f25051fcef691dca316c3b3666 Mon Sep 17 00:00:00 2001 From: Richard Iannone Date: Fri, 24 Apr 2026 16:33:06 -0400 Subject: [PATCH 8/8] Localize table filter UI strings --- great_docs/assets/tbl-explorer.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/great_docs/assets/tbl-explorer.js b/great_docs/assets/tbl-explorer.js index 8200c04..0418e01 100644 --- a/great_docs/assets/tbl-explorer.js +++ b/great_docs/assets/tbl-explorer.js @@ -341,7 +341,7 @@ var input = document.createElement("input"); input.type = isNumeric(col.dtype) ? "number" : "text"; input.className = "gd-tbl-fw-input"; - input.placeholder = "Enter value\u2026"; + input.placeholder = _gdT("tbl_filter_enter_value", "Enter value\u2026"); input.setAttribute("aria-label", "Filter value"); inputRow.appendChild(input); @@ -352,11 +352,11 @@ caseBtn.className = "gd-tbl-fw-case"; caseBtn.textContent = "Aa"; caseBtn.setAttribute("aria-label", "Toggle case sensitivity"); - caseBtn.title = "Case insensitive"; + caseBtn.title = _gdT("tbl_filter_case_insensitive", "Case insensitive"); caseBtn.addEventListener("click", function () { caseSensitive = !caseSensitive; caseBtn.classList.toggle("active", caseSensitive); - caseBtn.title = caseSensitive ? "Case sensitive" : "Case insensitive"; + caseBtn.title = caseSensitive ? _gdT("tbl_filter_case_sensitive", "Case sensitive") : _gdT("tbl_filter_case_insensitive", "Case insensitive"); }); inputRow.appendChild(caseBtn); } @@ -364,7 +364,7 @@ var commitBtn = document.createElement("button"); commitBtn.className = "gd-tbl-btn gd-tbl-fw-commit"; - commitBtn.textContent = "Apply"; + commitBtn.textContent = _gdT("tbl_filter_apply", "Apply"); commitBtn.addEventListener("click", function () { var val = input.value.trim(); if (!val) return; @@ -400,26 +400,26 @@ var inputLo = document.createElement("input"); inputLo.type = "number"; inputLo.className = "gd-tbl-fw-input"; - inputLo.placeholder = "min"; + inputLo.placeholder = _gdT("tbl_filter_min", "min"); inputLo.setAttribute("aria-label", "Minimum value"); row.appendChild(inputLo); var sep = document.createElement("span"); - sep.textContent = " and "; + sep.textContent = " " + _gdT("tbl_filter_and", "and") + " "; sep.className = "gd-tbl-fw-sep"; row.appendChild(sep); var inputHi = document.createElement("input"); inputHi.type = "number"; inputHi.className = "gd-tbl-fw-input"; - inputHi.placeholder = "max"; + inputHi.placeholder = _gdT("tbl_filter_max", "max"); inputHi.setAttribute("aria-label", "Maximum value"); row.appendChild(inputHi); wizard.appendChild(row); var commitBtn = document.createElement("button"); commitBtn.className = "gd-tbl-btn gd-tbl-fw-commit"; - commitBtn.textContent = "Apply"; + commitBtn.textContent = _gdT("tbl_filter_apply", "Apply"); commitBtn.addEventListener("click", function () { var lo = inputLo.value.trim(); var hi = inputHi.value.trim();