Redact tool: rich UI, multilingual, engine choice, output formats
- Custom inline form (EN/NO/UK/PL lang switcher) replacing generic stub - Engine selector: Azure gpt-4o-mini (default), gpt-4o, GPU cuttlefish, regex-only - Entity type toggles: names, organisations, places, dates of birth - Output formats: contextual role tags, generic [PERSON], Norwegian pseudonyms - Keep officials mode: judges/experts kept as [JUDGE: Andersen] format - Exempt names list: specific names excluded from redaction - Hint paragraphs explaining each option in all four languages - Backend: engine routing, callGpuLlm(), applyGenericTags(), applyPseudonymization() - AzureOpenAiGateway: withDeployment() clone pattern for per-call model override Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1415,3 +1415,58 @@ p {
|
||||
}
|
||||
|
||||
.control-hint { font-size: 0.74rem; color: var(--muted); font-weight: 400; }
|
||||
|
||||
/* ─── Exempt names section (Redact tool) ──────────────────────────────────── */
|
||||
|
||||
.exempt-section {
|
||||
margin-top: 0.75rem;
|
||||
padding-top: 0.75rem;
|
||||
border-top: 1px solid var(--line);
|
||||
}
|
||||
|
||||
.exempt-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
margin-bottom: 0.4rem;
|
||||
}
|
||||
|
||||
.exempt-name-input {
|
||||
flex: 1;
|
||||
padding: 0.3rem 0.55rem;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 6px;
|
||||
font-size: 0.875rem;
|
||||
background: var(--panel);
|
||||
color: var(--ink);
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.exempt-name-input:focus {
|
||||
outline: 3px solid rgba(15, 118, 110, 0.28);
|
||||
outline-offset: 1px;
|
||||
border-color: var(--teal);
|
||||
}
|
||||
|
||||
/* ─── Entity type toggles (Redact tool) ───────────────────────────────────── */
|
||||
|
||||
.entity-toggles {
|
||||
flex-wrap: wrap;
|
||||
gap: 0.4rem 1.1rem;
|
||||
}
|
||||
|
||||
.entity-toggles label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.3rem;
|
||||
font-size: 0.875rem;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.entity-toggles input[type="checkbox"] {
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
accent-color: var(--teal);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
+304
-8
@@ -3,6 +3,205 @@ const state = {
|
||||
authenticated: Boolean(window.DBN_TOOLS_AUTHENTICATED),
|
||||
};
|
||||
|
||||
const REDACT_I18N = {
|
||||
en: {
|
||||
redactEngine: 'Engine',
|
||||
redactEngineAzureMini: 'Azure gpt-4o-mini',
|
||||
redactEngineAzureFull: 'Azure gpt-4o',
|
||||
redactEngineGpu: 'GPU (cuttlefish)',
|
||||
redactEngineRegex: 'Regex only',
|
||||
redactEngineHint: 'Azure engines use your BNL Azure credits. GPU runs the local LiteLLM proxy. Regex-only is instant and free but finds no names or organisations.',
|
||||
redactMode: 'Mode',
|
||||
redactModeStandard: 'Standard',
|
||||
redactModeStrict: 'Strict',
|
||||
redactModeHint: 'Standard: regex patterns + LLM scan for names/orgs/places. Strict: also replaces any capitalised two-word phrase as a potential name — more aggressive, may produce false positives.',
|
||||
redactRegion: 'Region',
|
||||
redactRegionNordic: 'Nordic',
|
||||
redactRegionEuropean: 'European',
|
||||
redactRegionEchr: 'ECHR',
|
||||
redactRegionGlobal: 'Global',
|
||||
redactRegionHint: 'Nordic: Norwegian fødselsnummer, phone, email, addresses. European: adds IBAN, SE personnummer, UK NI. ECHR: adds application numbers, DOB phrases. Global: adds US SSN, document numbers.',
|
||||
redactEntities: 'Redact',
|
||||
redactEntityNames: 'Names',
|
||||
redactEntityOrgs: 'Organisations',
|
||||
redactEntityPlaces: 'Places',
|
||||
redactEntityDob: 'Dates of birth',
|
||||
redactOfficials: 'Officials',
|
||||
redactKeepOfficials: 'Keep official names (judges, experts)',
|
||||
redactOfficialsHint: 'When checked, judges, expert witnesses and caseworkers keep their names in a labelled tag: [JUDGE: Andersen]. Uncheck to replace all names with generic role tags.',
|
||||
redactOutput: 'Output',
|
||||
redactOutputContextual: 'Contextual tags',
|
||||
redactOutputGeneric: 'Generic tags',
|
||||
redactOutputPseudo: 'Pseudonyms',
|
||||
redactOutputHint: 'Contextual: each person gets a role tag so their identity is traceable within the document. Generic: all names become [PERSON]. Pseudonyms: replaced with plausible fake Norwegian values.',
|
||||
redactExempt: 'Exempt names',
|
||||
redactExemptAdd: 'Add',
|
||||
redactExemptHint: 'Names listed here will never be redacted, even if the AI would otherwise remove them — e.g. a judge or expert who must remain identifiable.',
|
||||
redactExemptPlaceholder: 'Name to keep (e.g. Judge Andersen)',
|
||||
redactAliases: 'Name aliases',
|
||||
redactAliasAdd: 'Add',
|
||||
redactAliasHint: 'Replace a specific name with a custom bracketed label, e.g. "David Jr" → [Junior].',
|
||||
redactUploadAria: 'File upload',
|
||||
redactUploadDrop: 'Drop up to 5 files here, or',
|
||||
redactUploadBrowse: 'browse',
|
||||
redactUploadHint: 'text extracted in memory, never stored',
|
||||
redactUploadClear: '× Clear',
|
||||
redactInputLabel: 'Pasted text',
|
||||
redactInputPlaceholder: 'Paste text containing names, phone numbers, emails, addresses, or national ID numbers.',
|
||||
redactRun: 'Run',
|
||||
redactRunning: 'Redacting…',
|
||||
redactReadyTitle: 'Ready',
|
||||
redactReadyDesc: 'Paste text or upload a file, configure redaction options, then run.',
|
||||
},
|
||||
no: {
|
||||
redactEngine: 'Motor',
|
||||
redactEngineAzureMini: 'Azure gpt-4o-mini',
|
||||
redactEngineAzureFull: 'Azure gpt-4o',
|
||||
redactEngineGpu: 'GPU (cuttlefish)',
|
||||
redactEngineRegex: 'Kun regex',
|
||||
redactEngineHint: 'Azure-motorer bruker BNL Azure-kreditter. GPU kjører lokal LiteLLM-proxy. Kun regex er øyeblikkelig og gratis, men finner ingen navn eller organisasjoner.',
|
||||
redactMode: 'Modus',
|
||||
redactModeStandard: 'Standard',
|
||||
redactModeStrict: 'Strikt',
|
||||
redactModeHint: 'Standard: regex-mønstre + LLM-skanning for navn/org/steder. Strikt: erstatter også enhver stor-stav-kombinasjon som potensielt navn — mer aggressivt, kan gi falske positiver.',
|
||||
redactRegion: 'Region',
|
||||
redactRegionNordic: 'Nordisk',
|
||||
redactRegionEuropean: 'Europeisk',
|
||||
redactRegionEchr: 'EMD',
|
||||
redactRegionGlobal: 'Global',
|
||||
redactRegionHint: 'Nordisk: norsk fødselsnummer, telefon, e-post, adresser. Europeisk: legger til IBAN, SE personnummer, UK NI. EMD: legger til saksnummer, fødselsdatofraser. Global: legger til US SSN, dokumentnummer.',
|
||||
redactEntities: 'Rediger',
|
||||
redactEntityNames: 'Navn',
|
||||
redactEntityOrgs: 'Organisasjoner',
|
||||
redactEntityPlaces: 'Steder',
|
||||
redactEntityDob: 'Fødselsdatoer',
|
||||
redactOfficials: 'Offisielle',
|
||||
redactKeepOfficials: 'Behold offisielle navn (dommere, sakkyndige)',
|
||||
redactOfficialsHint: 'Når avkrysset beholder dommere, sakkyndige og saksbehandlere sine navn i en merket tagg: [DOMMER: Andersen]. Fjern haken for å erstatte alle navn med generiske rolletaggar.',
|
||||
redactOutput: 'Utdata',
|
||||
redactOutputContextual: 'Kontekstuelle taggar',
|
||||
redactOutputGeneric: 'Generiske taggar',
|
||||
redactOutputPseudo: 'Pseudonymer',
|
||||
redactOutputHint: 'Kontekstuell: hver person får en rolletagg slik at identiteten kan spores i dokumentet. Generisk: alle navn blir [PERSON]. Pseudonymer: erstattes med troverdige falske norske verdier.',
|
||||
redactExempt: 'Unntak',
|
||||
redactExemptAdd: 'Legg til',
|
||||
redactExemptHint: 'Navn oppført her vil aldri bli redigert, selv om AI ellers ville fjernet dem — f.eks. en dommer eller sakkyndig som må forbli identifiserbar.',
|
||||
redactExemptPlaceholder: 'Navn som skal beholdes (f.eks. Dommer Andersen)',
|
||||
redactAliases: 'Navnealiaser',
|
||||
redactAliasAdd: 'Legg til',
|
||||
redactAliasHint: 'Erstatt et spesifikt navn med en egendefinert merkelapp, f.eks. «David Jr» → [Junior].',
|
||||
redactUploadAria: 'Filopplasting',
|
||||
redactUploadDrop: 'Slipp opptil 5 filer her, eller',
|
||||
redactUploadBrowse: 'bla',
|
||||
redactUploadHint: 'tekst hentes i minnet, lagres aldri',
|
||||
redactUploadClear: '× Tøm',
|
||||
redactInputLabel: 'Limt inn tekst',
|
||||
redactInputPlaceholder: 'Lim inn tekst med navn, telefonnummer, e-poster, adresser eller personnummer.',
|
||||
redactRun: 'Kjør',
|
||||
redactRunning: 'Redigerer…',
|
||||
redactReadyTitle: 'Klar',
|
||||
redactReadyDesc: 'Lim inn tekst eller last opp en fil, konfigurer redigeringsalternativene, og kjør.',
|
||||
},
|
||||
uk: {
|
||||
redactEngine: 'Рушій',
|
||||
redactEngineAzureMini: 'Azure gpt-4o-mini',
|
||||
redactEngineAzureFull: 'Azure gpt-4o',
|
||||
redactEngineGpu: 'GPU (cuttlefish)',
|
||||
redactEngineRegex: 'Лише регулярні вирази',
|
||||
redactEngineHint: 'Рушії Azure використовують кредити BNL Azure. GPU запускає локальний проксі LiteLLM. Лише regex — миттєво і безкоштовно, але не знаходить імен або організацій.',
|
||||
redactMode: 'Режим',
|
||||
redactModeStandard: 'Стандартний',
|
||||
redactModeStrict: 'Суворий',
|
||||
redactModeHint: 'Стандарт: шаблони regex + LLM-сканування для імен/орг/місць. Суворий: також замінює будь-яку комбінацію слів з великої літери як потенційне ім\'я.',
|
||||
redactRegion: 'Регіон',
|
||||
redactRegionNordic: 'Nordisk',
|
||||
redactRegionEuropean: 'Європейський',
|
||||
redactRegionEchr: 'ЄСПЛ',
|
||||
redactRegionGlobal: 'Глобальний',
|
||||
redactRegionHint: 'Nordisk: норвезький фødselsnummer, телефон, email, адреси. Європейський: додає IBAN, SE personnummer, UK NI. ЄСПЛ: додає номери справ, фрази дати народження. Глобальний: додає US SSN.',
|
||||
redactEntities: 'Редагувати',
|
||||
redactEntityNames: 'Імена',
|
||||
redactEntityOrgs: 'Організації',
|
||||
redactEntityPlaces: 'Місця',
|
||||
redactEntityDob: 'Дати народження',
|
||||
redactOfficials: 'Офіційні особи',
|
||||
redactKeepOfficials: 'Зберігати офіційні імена (судді, експерти)',
|
||||
redactOfficialsHint: 'Якщо позначено, судді, експерти та соціальні працівники зберігають свої імена у позначеному тезі: [СУДДЯ: Andersen].',
|
||||
redactOutput: 'Вивід',
|
||||
redactOutputContextual: 'Контекстні теги',
|
||||
redactOutputGeneric: 'Загальні теги',
|
||||
redactOutputPseudo: 'Псевдоніми',
|
||||
redactOutputHint: 'Контекстний: кожна особа отримує тег ролі. Загальний: всі імена стають [PERSON]. Псевдоніми: замінюються правдоподібними норвезькими значеннями.',
|
||||
redactExempt: 'Виключені імена',
|
||||
redactExemptAdd: 'Додати',
|
||||
redactExemptHint: 'Імена, перелічені тут, ніколи не будуть відредаговані.',
|
||||
redactExemptPlaceholder: 'Ім\'я для збереження (напр. суддя Andersen)',
|
||||
redactAliases: 'Псевдоніми імен',
|
||||
redactAliasAdd: 'Додати',
|
||||
redactAliasHint: 'Замініть конкретне ім\'я на власну мітку, напр. «David Jr» → [Junior].',
|
||||
redactUploadAria: 'Завантаження файлів',
|
||||
redactUploadDrop: 'Перетягніть до 5 файлів сюди, або',
|
||||
redactUploadBrowse: 'огляд',
|
||||
redactUploadHint: 'текст обробляється в пам\'яті, ніколи не зберігається',
|
||||
redactUploadClear: '× Очистити',
|
||||
redactInputLabel: 'Вставлений текст',
|
||||
redactInputPlaceholder: 'Вставте текст з іменами, телефонами, адресами або ідентифікаційними номерами.',
|
||||
redactRun: 'Запустити',
|
||||
redactRunning: 'Редагування…',
|
||||
redactReadyTitle: 'Готово',
|
||||
redactReadyDesc: 'Вставте текст або завантажте файл, налаштуйте параметри, запустіть.',
|
||||
},
|
||||
pl: {
|
||||
redactEngine: 'Silnik',
|
||||
redactEngineAzureMini: 'Azure gpt-4o-mini',
|
||||
redactEngineAzureFull: 'Azure gpt-4o',
|
||||
redactEngineGpu: 'GPU (cuttlefish)',
|
||||
redactEngineRegex: 'Tylko regex',
|
||||
redactEngineHint: 'Silniki Azure używają kredytów Azure BNL. GPU korzysta z lokalnego proxy LiteLLM. Tylko regex jest natychmiastowy i bezpłatny, ale nie znajdzie imion ani organizacji.',
|
||||
redactMode: 'Tryb',
|
||||
redactModeStandard: 'Standardowy',
|
||||
redactModeStrict: 'Ścisły',
|
||||
redactModeHint: 'Standardowy: wzorce regex + skanowanie LLM dla imion/org/miejsc. Ścisły: zastępuje też każdą kombinację słów pisanych wielką literą jako potencjalne imię.',
|
||||
redactRegion: 'Region',
|
||||
redactRegionNordic: 'Nordycki',
|
||||
redactRegionEuropean: 'Europejski',
|
||||
redactRegionEchr: 'ETPC',
|
||||
redactRegionGlobal: 'Globalny',
|
||||
redactRegionHint: 'Nordycki: norweski fødselsnummer, telefon, email, adresy. Europejski: dodaje IBAN, SE personnummer, UK NI. ETPC: dodaje numery spraw, frazy daty urodzenia. Globalny: dodaje US SSN.',
|
||||
redactEntities: 'Redaguj',
|
||||
redactEntityNames: 'Imiona',
|
||||
redactEntityOrgs: 'Organizacje',
|
||||
redactEntityPlaces: 'Miejsca',
|
||||
redactEntityDob: 'Daty urodzenia',
|
||||
redactOfficials: 'Urzędnicy',
|
||||
redactKeepOfficials: 'Zachowaj oficjalne nazwy (sędziowie, eksperci)',
|
||||
redactOfficialsHint: 'Gdy zaznaczone, sędziowie, biegli i pracownicy socjalni zachowują swoje nazwiska w oznaczonym tagu: [SĘDZIA: Andersen].',
|
||||
redactOutput: 'Wyjście',
|
||||
redactOutputContextual: 'Tagi kontekstowe',
|
||||
redactOutputGeneric: 'Tagi ogólne',
|
||||
redactOutputPseudo: 'Pseudonimy',
|
||||
redactOutputHint: 'Kontekstowe: każda osoba otrzymuje tag roli. Ogólne: wszystkie imiona stają się [PERSON]. Pseudonimy: zastąpione wiarygodnymi fałszywymi wartościami norweskimi.',
|
||||
redactExempt: 'Zwolnione nazwy',
|
||||
redactExemptAdd: 'Dodaj',
|
||||
redactExemptHint: 'Nazwy tu wpisane nigdy nie zostaną zredagowane.',
|
||||
redactExemptPlaceholder: 'Nazwa do zachowania (np. Sędzia Andersen)',
|
||||
redactAliases: 'Aliasy nazw',
|
||||
redactAliasAdd: 'Dodaj',
|
||||
redactAliasHint: 'Zastąp konkretną nazwę własną etykietą, np. «David Jr» → [Junior].',
|
||||
redactUploadAria: 'Przesyłanie pliku',
|
||||
redactUploadDrop: 'Upuść do 5 plików tutaj lub',
|
||||
redactUploadBrowse: 'przeglądaj',
|
||||
redactUploadHint: 'tekst wyodrębniany w pamięci, nigdy nie przechowywany',
|
||||
redactUploadClear: '× Wyczyść',
|
||||
redactInputLabel: 'Wklejony tekst',
|
||||
redactInputPlaceholder: 'Wklej tekst zawierający imiona, numery telefonów, adresy lub numery identyfikacyjne.',
|
||||
redactRun: 'Uruchom',
|
||||
redactRunning: 'Redagowanie…',
|
||||
redactReadyTitle: 'Gotowe',
|
||||
redactReadyDesc: 'Wklej tekst lub wgraj plik, skonfiguruj opcje redakcji, uruchom.',
|
||||
},
|
||||
};
|
||||
|
||||
let lastTimelineEvents = [];
|
||||
let audioQueue = []; // [{file, status: 'pending'|'processing'|'done'|'error', result}]
|
||||
let lastTranscriptData = null;
|
||||
@@ -310,6 +509,89 @@ function applyTranscribeI18n(lang) {
|
||||
});
|
||||
}
|
||||
|
||||
function currentRedactT(key) {
|
||||
const t = REDACT_I18N[uiLang] || REDACT_I18N.en;
|
||||
return (key in t) ? t[key] : (REDACT_I18N.en[key] ?? key);
|
||||
}
|
||||
|
||||
function applyRedactI18n(lang) {
|
||||
uiLang = lang;
|
||||
localStorage.setItem('dbn-ui-lang', lang);
|
||||
document.querySelectorAll('[data-i18n]').forEach((el) => {
|
||||
const text = currentRedactT(el.dataset.i18n);
|
||||
if (text != null) el.textContent = text;
|
||||
});
|
||||
document.querySelectorAll('[data-i18n-placeholder]').forEach((el) => {
|
||||
const text = currentRedactT(el.dataset.i18nPlaceholder);
|
||||
if (text != null) el.placeholder = text;
|
||||
});
|
||||
document.querySelectorAll('[data-i18n-aria]').forEach((el) => {
|
||||
const text = currentRedactT(el.dataset.i18nAria);
|
||||
if (text != null) el.setAttribute('aria-label', text);
|
||||
});
|
||||
document.querySelectorAll('#redactLangSwitcher .lang-btn').forEach((btn) => {
|
||||
btn.classList.toggle('is-active', btn.dataset.lang === lang);
|
||||
});
|
||||
}
|
||||
|
||||
function currentRedactEngine() {
|
||||
return document.querySelector('input[name="redactEngine"]:checked')?.value || 'azure_mini';
|
||||
}
|
||||
|
||||
function currentOutputFormat() {
|
||||
return document.querySelector('input[name="outputFormat"]:checked')?.value || 'contextual';
|
||||
}
|
||||
|
||||
function currentKeepOfficials() {
|
||||
return document.getElementById('keepOfficialsCheck')?.checked ?? false;
|
||||
}
|
||||
|
||||
function currentRedactTypes() {
|
||||
return {
|
||||
names: document.getElementById('redactNames')?.checked ?? true,
|
||||
orgs: document.getElementById('redactOrgs')?.checked ?? true,
|
||||
places: document.getElementById('redactPlaces')?.checked ?? true,
|
||||
dob: document.getElementById('redactDob')?.checked ?? true,
|
||||
};
|
||||
}
|
||||
|
||||
function setupRedactControls() {
|
||||
const switcher = document.getElementById('redactLangSwitcher');
|
||||
if (!switcher) return;
|
||||
switcher.querySelectorAll('.lang-btn').forEach((btn) => {
|
||||
btn.addEventListener('click', () => applyRedactI18n(btn.dataset.lang));
|
||||
});
|
||||
applyRedactI18n(uiLang);
|
||||
}
|
||||
|
||||
function setupExemptNames() {
|
||||
const addBtn = document.getElementById('addExemptRow');
|
||||
const rows = document.getElementById('exemptRows');
|
||||
if (!addBtn || !rows) return;
|
||||
|
||||
addBtn.addEventListener('click', () => {
|
||||
const row = document.createElement('div');
|
||||
row.className = 'exempt-row';
|
||||
row.innerHTML = [
|
||||
`<input type="text" class="exempt-name-input" placeholder="${escapeHtml(currentRedactT('redactExemptPlaceholder'))}" maxlength="100">`,
|
||||
'<button type="button" class="alias-remove" aria-label="Remove exempt name">×</button>',
|
||||
].join('');
|
||||
rows.appendChild(row);
|
||||
row.querySelector('.exempt-name-input').focus();
|
||||
});
|
||||
|
||||
rows.addEventListener('click', (e) => {
|
||||
const btn = e.target.closest('.alias-remove');
|
||||
if (btn) btn.closest('.exempt-row').remove();
|
||||
});
|
||||
}
|
||||
|
||||
function getExemptNames() {
|
||||
return Array.from(document.querySelectorAll('#exemptRows .exempt-name-input'))
|
||||
.map((el) => el.value.trim())
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
const tools = {
|
||||
ask: {
|
||||
kind: 'Source-grounded Legal Ask',
|
||||
@@ -433,10 +715,15 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
setupAudio();
|
||||
setupTranscribeControls();
|
||||
setupVocabPresets();
|
||||
document.querySelectorAll('.lang-btn').forEach((btn) => {
|
||||
setupRedactControls();
|
||||
setupExemptNames();
|
||||
// Wire transcribe lang switcher (only present on transcribe page)
|
||||
document.querySelectorAll('#uiLangSwitcher .lang-btn').forEach((btn) => {
|
||||
btn.addEventListener('click', () => applyTranscribeI18n(btn.dataset.lang));
|
||||
});
|
||||
applyTranscribeI18n(uiLang);
|
||||
if (document.getElementById('uiLangSwitcher')) {
|
||||
applyTranscribeI18n(uiLang);
|
||||
}
|
||||
els.results.addEventListener('click', (e) => {
|
||||
if (e.target.closest('#exportCsvBtn')) exportTimelineCSV(lastTimelineEvents);
|
||||
if (e.target.closest('#dlTxt')) downloadTranscriptTxt();
|
||||
@@ -532,9 +819,14 @@ async function runTool(event) {
|
||||
payload.limit = 7;
|
||||
}
|
||||
if (state.activeTool === 'redact') {
|
||||
payload.mode = currentRedactionMode();
|
||||
payload.region = currentRedactionRegion();
|
||||
payload.aliases = getAliases();
|
||||
payload.mode = currentRedactionMode();
|
||||
payload.region = currentRedactionRegion();
|
||||
payload.aliases = getAliases();
|
||||
payload.engine = currentRedactEngine();
|
||||
payload.output_format = currentOutputFormat();
|
||||
payload.keep_officials = currentKeepOfficials();
|
||||
payload.exempt_names = getExemptNames();
|
||||
payload.redact_types = currentRedactTypes();
|
||||
}
|
||||
|
||||
setBusy(true);
|
||||
@@ -742,9 +1034,13 @@ async function postJson(url, payload) {
|
||||
function setBusy(isBusy) {
|
||||
const button = document.querySelector('#runButton');
|
||||
button.disabled = isBusy;
|
||||
button.textContent = isBusy
|
||||
? (state.activeTool === 'transcribe' ? currentUiT('running') : currentUiT('runningOther'))
|
||||
: currentUiT('run');
|
||||
if (state.activeTool === 'transcribe') {
|
||||
button.textContent = isBusy ? currentUiT('running') : currentUiT('run');
|
||||
} else if (state.activeTool === 'redact') {
|
||||
button.textContent = isBusy ? currentRedactT('redactRunning') : currentRedactT('redactRun');
|
||||
} else {
|
||||
button.textContent = isBusy ? currentUiT('runningOther') : currentUiT('run');
|
||||
}
|
||||
}
|
||||
|
||||
function currentLanguage() {
|
||||
|
||||
Reference in New Issue
Block a user