Files
ha-dashboard-studio/dashboard_studio/web/i18n.js
T
veenm 9e7e7beaa0 Dashboard Studio 1.5.0: conditional widgets, appliance card, multi-player media
- Visibility conditions on every widget (is / is not / above / below,
  all or any); rows that only held hidden widgets close up in view mode
- Appliance card for washer, dryer and dishwasher: status or power
  based, time left, ready time, progress and program; hides when off
- Media card controls several players with a switcher and album art
- Dutch translations and docs for the new features

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 22:24:22 +01:00

287 lines
20 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* Translations. English text is the key; a missing translation falls back to English.
* Language: the device setting in Dashboard Studio, else Home Assistant's own language
* (same origin, so its localStorage is readable), else the browser's. */
(function () {
const NL = {
// --- toolbar, menus, dialogs
"Dashboard": "Dashboard",
"New dashboard": "Nieuw dashboard",
"Undo": "Ongedaan maken",
"Redo": "Opnieuw",
"More actions": "Meer acties",
"Kiosk": "Kiosk",
"Kiosk mode": "Kioskmodus",
"Edit": "Bewerken",
"Done": "Gereed",
"Offline": "Offline",
"Connected": "Verbonden",
"Saving…": "Opslaan…",
"Saved": "Opgeslagen",
"Not saved": "Niet opgeslagen",
"Rename…": "Wijzig naam…",
"Duplicate": "Dupliceer",
"New dashboard from my devices": "Nieuw dashboard met mijn apparaten",
"Created “{0}” from your devices.": "“{0}” gemaakt met je apparaten.",
"Dashboard Studio has no access to Home Assistant (SUPERVISOR_TOKEN is missing). Restart the app; if this stays, reinstall it.": "Dashboard Studio heeft geen toegang tot Home Assistant (SUPERVISOR_TOKEN ontbreekt). Herstart de app; als dit blijft, installeer de app opnieuw.",
"Export as JSON": "Exporteer als JSON",
"Import JSON…": "Importeer JSON…",
"Delete dashboard…": "Verwijder dashboard…",
"Widgets": "Widgets",
"Inspector": "Inspector",
"Add widget": "Widget toevoegen",
"Click to add. Drag to move, drag the corner to resize. Arrow keys move the selected widget, Shift+arrows resize, ⌘D duplicates, Delete removes.":
"Klik om toe te voegen. Sleep om te verplaatsen, sleep de hoek om het formaat te wijzigen. Pijltjestoetsen verplaatsen de geselecteerde widget, Shift+pijltjes wijzigen het formaat, ⌘D dupliceert, Delete verwijdert.",
"Cancel": "Annuleer",
"Create": "Maak aan",
"Rename": "Wijzig naam",
"Rename dashboard": "Wijzig naam van dashboard",
"Delete": "Verwijder",
"Close": "Sluit",
"Run": "Voer uit",
"Turn on": "Zet aan",
"Turn off": "Zet uit",
"Lock": "Vergrendel",
"Unlock": "Ontgrendel",
"Changed {0}": "Gewijzigd {0}",
"Delete “{0}”?": "“{0}” verwijderen?",
"The dashboard and its widgets will be removed. This can’t be undone.": "Het dashboard en de widgets worden verwijderd. Dit kan niet ongedaan worden gemaakt.",
"This is your only dashboard. Create another one before deleting it.": "Dit is je enige dashboard. Maak eerst een ander dashboard aan voordat je dit verwijdert.",
"Imported “{0}”.": "“{0}” geïmporteerd.",
"Couldn’t import: {0}.": "Importeren mislukt: {0}.",
"the file has no widgets list": "het bestand bevat geen widgets",
"Widget deleted. Press ⌘Z to undo.": "Widget verwijderd. Druk op ⌘Z om dit ongedaan te maken.",
"Couldn’t save. Your changes are kept here and will save on the next edit.": "Opslaan mislukt. Je wijzigingen blijven hier bewaard en worden bij de volgende wijziging opgeslagen.",
"Couldn’t load your dashboards. Check that the app is running.": "Je dashboards konden niet worden geladen. Controleer of de app draait.",
"Not connected to Home Assistant. Retrying…": "Niet verbonden met Home Assistant. Opnieuw proberen…",
"{0} failed: {1}": "{0} mislukt: {1}",
"The button’s action data isn’t valid JSON. Fix it in the inspector.": "De actiegegevens van de knop zijn geen geldige JSON. Pas dit aan in de inspector.",
"This button has no action yet. Set one in the inspector.": "Deze knop heeft nog geen actie. Stel er een in via de inspector.",
"Unknown widget “{0}”.": "Onbekende widget “{0}”.",
"This widget couldn’t be drawn.": "Deze widget kon niet worden getekend.",
"Home": "Thuis",
"Everything at a glance": "Alles in één oogopslag",
"Quick controls": "Snelle bediening",
"Temperature, last 24 hours": "Temperatuur, afgelopen 24 uur",
"copy": "kopie",
// --- kiosk
"Kiosk mode is on. To leave, tap the {0} corner {1} times.": "Kioskmodus staat aan. Tik {1} keer op de hoek {0} om te stoppen.",
"top right": "rechtsboven", "top left": "linksboven", "bottom right": "rechtsonder", "bottom left": "linksonder",
"top-right": "Rechtsboven", "top-left": "Linksboven", "bottom-right": "Rechtsonder", "bottom-left": "Linksonder",
"Leave kiosk mode?": "Kioskmodus verlaten?",
"This closes by itself in a few seconds.": "Dit venster sluit vanzelf over een paar seconden.",
"Full screen": "Volledig scherm",
"Exit full screen": "Volledig scherm uit",
"Stay": "Blijf",
"Leave kiosk": "Verlaat kiosk",
"Full screen isn’t available in this browser.": "Volledig scherm is niet beschikbaar in deze browser.",
"Home Assistant’s frame blocks full screen. Use “New tab” in the kiosk settings instead.": "Home Assistant blokkeert volledig scherm in zijn venster. Gebruik “Nieuw tabblad” bij de kioskinstellingen.",
// --- inspector
"Name": "Naam",
"Appearance": "Weergave",
"Theme": "Thema",
"System follows your device’s light or dark appearance.": "Systeem volgt de lichte of donkere weergave van je apparaat.",
"System": "Systeem", "Light": "Licht", "Dark": "Donker", "Nord": "Nord", "Dusk": "Schemer", "Forest": "Bos", "Custom": "Aangepast",
"Tile style": "Tegelstijl",
"Cards": "Kaarten", "Outline": "Omlijnd", "Plain": "Zonder kaart",
"Corner radius (px)": "Hoekafronding (px)",
"Colors": "Kleuren",
"editing switches to Custom": "aanpassen schakelt naar Aangepast",
"Background (color or CSS gradient)": "Achtergrond (kleur of CSS-verloop)",
"Tile color": "Tegelkleur",
"Text color": "Tekstkleur",
"Secondary text color": "Kleur van secundaire tekst",
"Accent color": "Accentkleur",
"Background image URL": "URL van achtergrondafbeelding",
"Blur behind tiles (px)": "Vervaging achter tegels (px)",
"For photo backgrounds": "Voor fotoachtergronden",
"Grid": "Raster",
"Columns": "Kolommen",
"Row height (px)": "Rijhoogte (px)",
"Spacing (px)": "Tussenruimte (px)",
"Maximum width (px)": "Maximale breedte (px)",
"0 = full width": "0 = volledige breedte",
"Screen saver after (minutes)": "Schermbeveiliging na (minuten)",
"0 = off": "0 = uit",
"Exit corner (tap it 5 times to leave)": "Uitgangshoek (tik 5 keer om te stoppen)",
"Hide the pointer when idle": "Verberg de aanwijzer bij inactiviteit",
"Start kiosk": "Start kiosk",
"New tab": "Nieuw tabblad",
"On a wall tablet, open kiosk in a new tab to hide the Home Assistant sidebar too.": "Open de kiosk op een wandtablet in een nieuw tabblad om ook de zijbalk van Home Assistant te verbergen.",
"Select a widget to edit it.": "Selecteer een widget om deze te bewerken.",
"Language": "Taal",
"Language on this device": "Taal op dit apparaat",
"Automatic": "Automatisch",
"Size and position": "Formaat en positie",
"Column": "Kolom", "Row": "Rij", "Width": "Breedte", "Height": "Hoogte",
"Style": "Stijl",
"No background": "Geen achtergrond",
"Background": "Achtergrond",
"Default": "Standaard",
"Add an entity…": "Voeg een entiteit toe…",
"Remove {0}": "Verwijder {0}",
"No entity with this ID": "Geen entiteit met deze ID",
"Loading albums…": "Albums laden…",
"No albums found in Immich.": "Geen albums gevonden in Immich.",
// --- widget names and fields
"Heading": "Kop", "Entity tile": "Entiteitstegel", "Big value": "Grote waarde", "Gauge": "Meter",
"Thermostat": "Thermostaat", "History graph": "Geschiedenisgrafiek", "Clock": "Klok", "Weather": "Weer",
"Entity list": "Entiteitenlijst", "Button": "Knop", "Media player": "Mediaspeler", "Camera": "Camera",
"Car": "Auto", "Text": "Tekst", "Photos": "Foto’s", "Calendar": "Agenda", "Web page": "Webpagina",
"Subtitle": "Ondertitel", "Font size (px)": "Lettergrootte (px)", "Alignment": "Uitlijning",
"left": "Links", "center": "Midden", "right": "Rechts",
"Welcome home": "Welkom thuis",
"Entity": "Entiteit", "Entity name": "Naam van entiteit", "Icon": "Pictogram", "Tap action": "Tikactie",
"auto": "Auto", "toggle": "Schakel", "more-info": "Info", "none": "Geen",
"Show when it last changed": "Toon wanneer het laatst gewijzigd is",
"Unit": "Eenheid", "From entity": "Van entiteit", "Decimals": "Decimalen",
"Warn above": "Waarschuwing boven", "Critical above": "Kritiek boven",
"Minimum": "Minimum", "Maximum": "Maximum", "Green from": "Groen vanaf", "Yellow from": "Geel vanaf", "Red from": "Rood vanaf",
"Step": "Stap", "Title": "Titel", "Sensors": "Sensoren", "Hours to show": "Aantal uren",
"Fill under the line": "Vul onder de lijn",
"24-hour time": "24-uursnotatie", "Show seconds": "Toon seconden", "Show date": "Toon datum",
"Devices": "Apparaten", "Entities": "Entiteiten",
"Label": "Label", "Target entity (optional)": "Doelentiteit (optioneel)",
"Action (e.g. scene.turn_on)": "Actie (bijv. scene.turn_on)", "Action data (JSON)": "Actiegegevens (JSON)",
"Refresh every (seconds)": "Vernieuw elke (seconden)", "Show name": "Toon naam",
"My car": "Mijn auto", "Car image URL (optional)": "URL van autoafbeelding (optioneel)",
"Drivetrain": "Aandrijving", "electric": "Elektrisch", "fuel": "Brandstof",
"Battery or fuel level (%)": "Accu- of brandstofniveau (%)", "Range": "Actieradius",
"Charging power": "Laadvermogen", "Charge limit (%)": "Laadlimiet (%)", "Doors": "Portieren",
"Climate": "Klimaat", "Location": "Locatie", "Odometer": "Kilometerstand",
"Text — use {{ sensor.x }} for live values": "Tekst — gebruik {{ sensor.x }} voor live waarden",
"Inside it’s {{ sensor.living_room_temperature }}.": "Binnen is het {{ sensor.living_room_temperature }}.",
"Source": "Bron", "links": "Links", "immich": "Immich",
"Image URLs, one per line": "Afbeeldings-URL’s, één per regel",
"Immich albums": "Immich-albums",
"Change photo every (seconds)": "Wissel foto elke (seconden)",
"Shuffle": "Willekeurige volgorde",
"Fit": "Passend", "cover": "Vullen", "contain": "Volledig",
"Show when the photo was taken": "Toon wanneer de foto is gemaakt",
"Description (for screen readers)": "Beschrijving (voor schermlezers)",
"Upcoming": "Binnenkort", "Calendars": "Agenda’s", "Days ahead": "Aantal dagen vooruit",
"Most events to show": "Maximaal aantal afspraken", "Show which calendar": "Toon welke agenda",
// --- widget content
"Unavailable": "Niet beschikbaar", "Unknown": "Onbekend",
"On": "Aan", "Off": "Uit", "Open": "Open", "Closed": "Dicht", "Clear": "Vrij", "Motion": "Beweging",
"Occupied": "Bezet", "Dry": "Droog", "Wet": "Nat", "Smoke": "Rook", "Away": "Afwezig",
"Unplugged": "Niet aangesloten", "Plugged in": "Aangesloten", "Not charging": "Laadt niet", "Charging": "Laden",
"Scene": "Scène", "Running": "Actief", "Script": "Script",
"just now": "zojuist", "{0} min ago": "{0} min geleden", "{0} h ago": "{0} uur geleden", "{0} d ago": "{0} d geleden",
"Can’t find {0}.": "{0} niet gevonden.",
"Check the entity ID in the inspector.": "Controleer de entiteit-ID in de inspector.",
"Choose {0} in the inspector.": "Kies {0} in de inspector.",
"an entity": "een entiteit", "a light": "een lamp", "a thermostat": "een thermostaat",
"a weather entity": "een weerentiteit", "a media player": "een mediaspeler", "a camera": "een camera",
"Critical": "Kritiek", "High": "Hoog",
"Now": "Nu", "Lower to {0}°": "Verlaag naar {0}°", "Raise to {0}°": "Verhoog naar {0}°", "Mode": "Modus",
"Add one or more sensors in the inspector.": "Voeg in de inspector een of meer sensoren toe.",
"Loading history…": "Geschiedenis laden…",
"No numeric history for this period.": "Geen numerieke geschiedenis voor deze periode.",
"History for the last {0} hours": "Geschiedenis van de afgelopen {0} uur",
"−{0} h": "−{0} u",
"Humidity": "Luchtvochtigheid", "Wind": "Wind",
"Add entities in the inspector.": "Voeg entiteiten toe in de inspector.",
"Previous track": "Vorige track", "Play": "Afspelen", "Pause": "Pauzeer", "Next track": "Volgende track", "Volume": "Volume",
"{0} camera": "Camera {0}",
"Set the car’s level, range or lock entity in the inspector.": "Stel in de inspector het niveau, de actieradius of het slot van de auto in.",
"Parked at home": "Thuis geparkeerd", "Locked": "Vergrendeld", "Unlocked": "Ontgrendeld",
"Battery level": "Accuniveau", "Fuel level": "Brandstofniveau", "Charge limit {0}%": "Laadlimiet {0}%",
"Climate on": "Klimaat aan", "range": "actieradius", "Low": "Laag",
"Choose one or more Immich albums in the inspector.": "Kies in de inspector een of meer Immich-albums.",
"Add image URLs in the inspector.": "Voeg in de inspector afbeeldings-URL’s toe.",
"Photo slideshow": "Diavoorstelling",
"Loading photos…": "Foto’s laden…",
"Couldn’t load photos. {0}": "Foto’s laden mislukt. {0}",
"These albums have no photos yet.": "Deze albums bevatten nog geen foto’s.",
"Add one or more calendars in the inspector.": "Voeg in de inspector een of meer agenda’s toe.",
"Loading events…": "Afspraken laden…",
"Couldn’t load events. {0}": "Afspraken laden mislukt. {0}",
"Nothing planned for the next {0} days.": "Niets gepland voor de komende {0} dagen.",
"Embedded page": "Ingesloten pagina", "Add a URL in the inspector.": "Voeg in de inspector een URL toe.",
// tabs
"Overview": "Overzicht", "Add tab": "Tabblad toevoegen", "Tab {0}": "Tabblad {0}", "Tabs": "Tabbladen", "Tab": "Tabblad",
"A dashboard needs at least one tab.": "Een dashboard heeft minstens één tabblad nodig.",
"Delete tab “{0}”?": "Tabblad “{0}” verwijderen?",
"Its {0} widgets will be deleted too. You can undo this with ⌘Z.": "De {0} widgets erop worden ook verwijderd. Je kunt dit ongedaan maken met ⌘Z.",
"Show tabs in a side menu": "Toon tabbladen in een zijmenu", "Tab name": "Naam van tabblad",
"Move up": "Omhoog", "Move down": "Omlaag", "Moved to “{0}”.": "Verplaatst naar “{0}”.",
// waste
"Waste collection": "Afvalkalender", "Layout": "Indeling", "next": "Volgende", "list": "Lijst",
"Waste sensors (leave empty to find them automatically)": "Afvalsensoren (leeg laten om ze automatisch te vinden)",
"Most pickups to show": "Maximaal aantal ophaalmomenten", "Only pickups within (days)": "Alleen ophaalmomenten binnen (dagen)",
"No pickups in the next {0} days.": "Geen ophaalmomenten in de komende {0} dagen.",
"No Afvalwijzer sensors found. Install the Afvalwijzer integration, or pick the sensors in the inspector.": "Geen Afvalwijzer-sensoren gevonden. Installeer de Afvalwijzer-integratie of kies de sensoren in de inspector.",
"Next pickup": "Volgende ophaalmoment", "Put the bin out tonight": "Zet de container vanavond buiten",
"Day after tomorrow": "Overmorgen", "In {0} days": "Over {0} dagen",
"Organic": "GFT", "Paper": "Papier", "Residual waste": "Restafval", "Residual waste bags": "Restafvalzakken",
"Textile": "Textiel", "Bulky waste": "Grofvuil", "Hazardous waste": "KCA", "Nappies": "Luiers", "Glass": "Glas",
"Pruning waste": "Snoeiafval", "Garden waste": "Tuinafval", "Christmas trees": "Kerstbomen", "BEST bag": "BEST-tas",
"Hazardous waste van": "Milieubus",
// visibility
"Hidden now": "Nu verborgen", "Visibility": "Zichtbaarheid",
"Show this widget only when the conditions below are met. Leave empty to always show it.": "Toon deze widget alleen als aan de voorwaarden hieronder is voldaan. Laat leeg om hem altijd te tonen.",
"Show when": "Toon als", "all": "Alle voorwaarden", "any": "Eén voorwaarde", "Add condition": "Voorwaarde toevoegen",
"Remove condition": "Verwijder voorwaarde", "Condition": "Voorwaarde", "Value": "Waarde",
"is": "Is", "is not": "Is niet", "above": "Hoger dan", "below": "Lager dan",
"Visible right now": "Nu zichtbaar", "Hidden right now": "Nu verborgen",
// media
"Media players": "Mediaspelers", "Show album art": "Toon albumhoes", "Hide players that are off from the switcher": "Verberg uitgeschakelde spelers in de keuzelijst",
// appliance
"Appliance": "Apparaat", "Washing machine": "Wasmachine", "Dryer": "Droger", "Dishwasher": "Vaatwasser",
"washer": "Wasmachine", "dryer": "Droger", "dishwasher": "Vaatwasser", "other": "Anders",
"Status": "Status", "Power (W), if there is no status": "Vermogen (W), als er geen status is", "Running above (W)": "Aan boven (W)",
"Time remaining or end time": "Resterende tijd of eindtijd", "Progress (%)": "Voortgang (%)", "Program": "Programma",
"Only show while running or finished": "Alleen tonen als hij draait of klaar is",
"Choose the appliance’s status, power or remaining-time entity in the inspector.": "Kies in de inspector de status-, vermogens- of resterende-tijdentiteit van het apparaat.",
"In progress": "Bezig", "Finished": "Klaar", "Paused": "Gepauzeerd", "Ready to unload": "Klaar om uit te ruimen",
"{0} h {1} min": "{0} u {1} min", "{0} min": "{0} min", "left · ready at {0}": "te gaan · klaar om {0}", "Progress": "Voortgang",
"Today": "Vandaag", "Tomorrow": "Morgen", "All day": "Hele dag", "Busy": "Bezet",
};
// Home Assistant states, translated when shown as text.
const STATES_NL = {
on: "Aan", off: "Uit", unavailable: "Niet beschikbaar", unknown: "Onbekend", home: "Thuis", not_home: "Afwezig",
open: "Open", opening: "Gaat open", closed: "Dicht", closing: "Gaat dicht", locked: "Vergrendeld", unlocked: "Ontgrendeld",
locking: "Vergrendelen", unlocking: "Ontgrendelen", jammed: "Vastgelopen", playing: "Speelt", paused: "Gepauzeerd",
idle: "Inactief", standby: "Stand-by", buffering: "Bufferen", heat: "Verwarmen", cool: "Koelen", auto: "Automatisch",
heat_cool: "Verwarmen/koelen", dry: "Drogen", fan_only: "Alleen ventilator", cleaning: "Reinigen", docked: "Gedockt",
returning: "Keert terug", charging: "Laden", above_horizon: "Boven de horizon", below_horizon: "Onder de horizon",
"clear-night": "Helder", cloudy: "Bewolkt", exceptional: "Uitzonderlijk", fog: "Mist", hail: "Hagel", lightning: "Onweer",
"lightning-rainy": "Onweer en regen", partlycloudy: "Halfbewolkt", pouring: "Stortregen", rainy: "Regen", snowy: "Sneeuw",
"snowy-rainy": "Natte sneeuw", sunny: "Zonnig", windy: "Winderig", "windy-variant": "Winderig", armed_away: "Ingeschakeld (afwezig)",
armed_home: "Ingeschakeld (thuis)", armed_night: "Ingeschakeld (nacht)", disarmed: "Uitgeschakeld", triggered: "Geactiveerd",
};
const read = (k) => { try { return localStorage.getItem(k); } catch { return null; } };
function detect() {
const pref = read("ds.lang");
if (pref && pref !== "auto") return pref;
let ha = read("selectedLanguage"); // Home Assistant stores it as a JSON string
try { ha = ha && JSON.parse(ha); } catch { /* plain string */ }
return String(ha || navigator.language || "en").toLowerCase().startsWith("nl") ? "nl" : "en";
}
const lang = detect();
const dict = lang === "nl" ? NL : {};
const cap = (s) => (s ? String(s).charAt(0).toUpperCase() + String(s).slice(1) : "").replace(/_/g, " ");
window.I18n = {
lang,
locale: lang === "nl" ? "nl-NL" : undefined,
languages: { auto: "Automatic", en: "English", nl: "Nederlands" },
preference: () => read("ds.lang") || "auto",
/** t("Hello {0}", name) */
t(text, ...args) {
const s = dict[text] ?? text;
return args.length ? s.replace(/\{(\d)\}/g, (_, i) => args[i] ?? "") : s;
},
/** A Home Assistant state as readable text. */
state: (st) => (lang === "nl" && STATES_NL[st]) || cap(st),
};
document.documentElement.lang = lang;
})();