Phase 3: embed web UI with go:embed, pinned TypeScript toolchain, drop i18n, add /healthz
continuous-integration/drone/push Build encountered an error

- html/embed.go embeds html/ (pages, css, img, js, video); src/assets.go
  serves it, with os.DirFS("html") under -dev. Static assets get an ETag
  and Cache-Control: no-cache; HTML pages are still templated (only the
  login error message is substituted now).
- Delete the generated src/webUI.go (783 KB base64), src/html-build.go and
  cmd/webui-gen; Dockerfile no longer runs a generator.
- Language layer removed: 254 {{.x}} placeholders inlined as English
  strings in ts/*.ts and the two auth pages; html/lang/en.json, the
  LanguageUI struct and the 'language' setting are gone.
- ts/tsconfig.json + package.json pin typescript 5.9.3; the seven sources
  compile (ES2020, global scripts) into one committed html/js/app.js.
  Ten unreferenced legacy scripts under html/js/ deleted; all pages load
  js/app.js.
- Fix the six type errors that blocked a clean compile, including a real
  bug: a missing semicolon in the search shortcut handler made the code
  call the result of preventDefault(), so the shortcut threw instead of
  focusing the search box.
- /healthz liveness endpoint; Dockerfile healthcheck and README use it.
- Drone: go vet, and a webui-check step that rebuilds the bundle and fails
  if the committed app.js is stale.
- README-DEV.md documents build, UI toolchain, -dev, versioning, CI.
This commit is contained in:
2026-09-26 12:46:45 +10:00
parent 51c7830067
commit ddc70e170a
47 changed files with 2208 additions and 7373 deletions
+123 -123
View File
@@ -49,23 +49,23 @@ class MainMenuItem extends MainMenu {
switch(this.menuKey) {
case "playlist":
this.tableHeader = ["{{.playlist.table.playlist}}", "{{.playlist.table.tuner}}", "{{.playlist.table.lastUpdate}}", "{{.playlist.table.availability}} %", "{{.playlist.table.type}}", "{{.playlist.table.streams}}", "{{.playlist.table.groupTitle}} %", "{{.playlist.table.tvgID}} %", "{{.playlist.table.uniqueID}} %"]
this.tableHeader = ["Playlist", "Tuner", "Last Update", "Availability %", "Type", "Streams", "group-title %", "tvg-id %", "Unique ID %"]
break
case "xmltv":
this.tableHeader = ["{{.xmltv.table.guide}}", "{{.xmltv.table.lastUpdate}}", "{{.xmltv.table.availability}} %", "{{.xmltv.table.channels}}", "{{.xmltv.table.programs}}"]
this.tableHeader = ["Guide", "Last Update", "Availability %", "Channels", "Programs"]
break
case "filter":
this.tableHeader = ["{{.filter.table.name}}", "{{.filter.table.type}}", "{{.filter.table.filter}}"]
this.tableHeader = ["Filter Name", "Filter Type", "Filter"]
break
case "users":
this.tableHeader = ["{{.users.table.username}}", "{{.users.table.password}}", "{{.users.table.web}}", "{{.users.table.pms}}", "{{.users.table.m3u}}", "{{.users.table.xml}}", "{{.users.table.api}}"]
this.tableHeader = ["Username", "Password", "WEB", "PMS", "M3U", "XML", "API"]
break
case "mapping":
this.tableHeader = ["BULK", "{{.mapping.table.chNo}}", "{{.mapping.table.logo}}", "{{.mapping.table.channelName}}", "{{.mapping.table.playlist}}", "{{.mapping.table.groupTitle}}", "{{.mapping.table.xmltvFile}}", "{{.mapping.table.xmltvID}}", "{{.mapping.table.edit}}"]
this.tableHeader = ["BULK", "Ch. No.", "Logo", "Channel Name", "Playlist", "Group Title", "XMLTV File", "XMLTV ID", "Edit"]
break
}
@@ -225,11 +225,11 @@ class Content {
cell.childType = "P"
switch (data[key]["type"]) {
case "custom-filter":
cell.value = "{{.filter.custom}}"
cell.value = "Custom"
break;
case "group-title":
cell.value = "{{.filter.group}}"
cell.value = "Group"
break;
default:
@@ -480,7 +480,7 @@ class Content {
var cell:Cell = new Cell()
cell.child = true
cell.childType = "EDIT"
cell.value = "{{.button.edit}}"
cell.value = "Edit"
var editTd = cell.createCell()
var editButton = (editTd.firstChild as HTMLInputElement)
editButton.setAttribute('onclick', 'javascript: openPopUp("mapping", this)')
@@ -644,14 +644,14 @@ class ShowContent extends Content {
var interaction = document.getElementById(this.interactionID)
switch (menuKey) {
case "playlist":
var input = this.createInput("button", menuKey, "{{.button.new}}")
var input = this.createInput("button", menuKey, "New")
input.setAttribute("id", "-")
input.setAttribute("onclick", 'javascript: openPopUp("playlist")')
interaction.appendChild(input)
break;
case "filter":
var input = this.createInput("button", menuKey, "{{.button.new}}")
var input = this.createInput("button", menuKey, "New")
input.setAttribute("id", -1)
input.setAttribute("onclick", 'javascript: openPopUp("filter", this)')
interaction.appendChild(input)
@@ -659,14 +659,14 @@ class ShowContent extends Content {
case "xmltv":
var input = this.createInput("button", menuKey, "{{.button.new}}")
var input = this.createInput("button", menuKey, "New")
input.setAttribute("id", "xmltv")
input.setAttribute("onclick", 'javascript: openPopUp("xmltv")')
interaction.appendChild(input)
break;
case "users":
var input = this.createInput("button", menuKey, "{{.button.new}}")
var input = this.createInput("button", menuKey, "New")
input.setAttribute("id", "users")
input.setAttribute("onclick", 'javascript: openPopUp("users")')
interaction.appendChild(input)
@@ -674,32 +674,32 @@ class ShowContent extends Content {
case "mapping":
showElement("loading", true)
var input = this.createInput("button", menuKey, "{{.button.save}}")
var input = this.createInput("button", menuKey, "Save")
input.setAttribute("onclick", 'javascript: savePopupData("mapping", "", "")')
interaction.appendChild(input)
var input = this.createInput("button", menuKey, "{{.button.bulkEdit}}")
var input = this.createInput("button", menuKey, "Bulk Edit")
input.setAttribute("onclick", 'javascript: bulkEdit()')
interaction.appendChild(input)
var input = this.createInput("search", "search", "")
input.setAttribute("id", "searchMapping")
input.setAttribute("placeholder", "{{.button.search}}")
input.setAttribute("placeholder", "Search")
input.className = "search"
input.setAttribute("oninput", 'javascript: searchInMapping()')
interaction.appendChild(input)
break;
case "settings":
var input = this.createInput("button", menuKey, "{{.button.save}}")
var input = this.createInput("button", menuKey, "Save")
input.setAttribute("onclick", 'javascript: saveSettings();')
interaction.appendChild(input)
var input = this.createInput("button", menuKey, "{{.button.backup}}")
var input = this.createInput("button", menuKey, "Backup")
input.setAttribute("onclick", 'javascript: backup();')
interaction.appendChild(input)
var input = this.createInput("button", menuKey, "{{.button.restore}}")
var input = this.createInput("button", menuKey, "Restore")
input.setAttribute("onclick", 'javascript: restore();')
interaction.appendChild(input)
@@ -717,7 +717,7 @@ class ShowContent extends Content {
break
case "log":
var input = this.createInput("button", menuKey, "{{.button.resetLogs}}")
var input = this.createInput("button", menuKey, "Reset Logs")
input.setAttribute("onclick", 'javascript: resetLogs();')
interaction.appendChild(input)
@@ -770,23 +770,23 @@ class ShowContent extends Content {
if (menuKey == "mapping") {
if (element == "{{.mapping.table.chNo}}") {
if (element == "Ch. No.") {
cell.onclick = true
cell.onclickFunktion = "javascript: sortTable(1);"
cell.tdClassName = "sortThis"
}
if (element == "{{.mapping.table.channelName}}") {
if (element == "Channel Name") {
cell.onclick = true
cell.onclickFunktion = "javascript: sortTable(3);"
}
if (element == "{{.mapping.table.playlist}}") {
if (element == "Playlist") {
cell.onclick = true
cell.onclickFunktion = "javascript: sortTable(4);"
}
if (element == "{{.mapping.table.groupTitle}}") {
if (element == "Group Title") {
cell.onclick = true
cell.onclickFunktion = "javascript: sortTable(5);"
}
@@ -975,7 +975,7 @@ function initShellLayout() {
var search = document.getElementById("searchMapping")
if (search != null) {
event.preventDefault()
event.preventDefault();
(search as HTMLInputElement).focus()
}
}
@@ -1072,7 +1072,7 @@ function setClientInfoValue(key:string, value:any) {
if ((key == "m3u-url" || key == "xepg-url") && isClientInfoHttpURL(textValue)) {
element.innerHTML = ""
var anchor = document.createElement("A")
var anchor = document.createElement("a")
anchor.href = textValue
anchor.target = "_blank"
anchor.rel = "noopener noreferrer"
@@ -1140,7 +1140,7 @@ function createLayout() {
if (ACTIVE_MENU_ID.length == 0 && content != null && menu != null) {
if (content.innerHTML.replace(/\\s/g, "").length == 0) {
var firstItem = menu.getElementsByTagName("LI")[0]
var firstItem = menu.getElementsByTagName("LI")[0] as HTMLElement
if (firstItem != undefined) {
firstItem.click()
}
@@ -1330,24 +1330,24 @@ function openPopUp(dataType, element) {
switch (dataType) {
case "playlist":
content.createHeadline("{{.playlist.playlistType.title}}")
content.createHeadline("Playlist type")
// Type
var text:string[] = ["M3U", "HDHomeRun"]
var values:string[] = ["javascript: openPopUp('m3u')", "javascript: openPopUp('hdhr')"]
var select = content.createSelect(text, values, "", "type")
select.setAttribute("id", "type")
select.setAttribute("onchange", 'javascript: changeButtonAction(this, "next", "onclick")') // changeButtonAction
content.appendRow("{{.playlist.type.title}}", select)
content.appendRow("Type", select)
// Interaktion
content.createInteraction()
// Abbrechen
var input = content.createInput("button", "cancel", "{{.button.cancel}}")
var input = content.createInput("button", "cancel", "Cancel")
input.setAttribute("onclick", 'javascript: showElement("popup", false);')
content.addInteraction(input)
// Weiter
var input = content.createInput("button", "next", "{{.button.next}}")
var input = content.createInput("button", "next", "Next")
input.setAttribute("onclick", 'javascript: openPopUp("m3u")')
input.setAttribute("id", 'next')
content.addInteraction(input)
@@ -1358,20 +1358,20 @@ function openPopUp(dataType, element) {
// Name
var dbKey:string = "name"
var input = content.createInput("text", dbKey, data[dbKey])
input.setAttribute("placeholder", "{{.playlist.name.placeholder}}")
content.appendRow("{{.playlist.name.title}}", input)
input.setAttribute("placeholder", "Playlist name")
content.appendRow("Name", input)
// Beschreibung
var dbKey:string = "description"
var input = content.createInput("text", dbKey, data[dbKey])
input.setAttribute("placeholder", "{{.playlist.description.placeholder}}")
content.appendRow("{{.playlist.description.title}}", input)
input.setAttribute("placeholder", "Description")
content.appendRow("Description", input)
// URL
var dbKey:string = "file.source"
var input = content.createInput("text", dbKey, data[dbKey])
input.setAttribute("placeholder", "{{.playlist.fileM3U.placeholder}}")
content.appendRow("{{.playlist.fileM3U.title}}", input)
input.setAttribute("placeholder", "File path or URL of the M3U")
content.appendRow("M3U File", input)
// Tuner
if (SERVER["settings"]["buffer"] != "-") {
@@ -1386,7 +1386,7 @@ function openPopUp(dataType, element) {
var dbKey:string = "tuner"
var select = content.createSelect(text, values, data[dbKey], dbKey)
select.setAttribute("onfocus", "javascript: return;")
content.appendRow("{{.playlist.tuner.title}}", select)
content.appendRow("Tuner / Streams", select)
} else {
var dbKey:string = "tuner"
if (data[dbKey] == undefined) {
@@ -1395,39 +1395,39 @@ function openPopUp(dataType, element) {
var input = content.createInput("text", dbKey, data[dbKey])
input.setAttribute("readonly", "true")
input.className = "notAvailable"
content.appendRow("{{.playlist.tuner.title}}", input)
content.appendRow("Tuner / Streams", input)
}
content.description("{{.playlist.tuner.description}}")
content.description("Number of parallel connections that can be established to the provider. <br>Only available with activated buffer.<br>New settings will only be applied after quitting all streams.")
// Interaktion
content.createInteraction()
// Löschen
if (data["id.provider"]!= "-") {
var input = content.createInput("button", "delete", "{{.button.delete}}")
var input = content.createInput("button", "delete", "Delete")
input.className = "delete"
input.setAttribute('onclick', 'javascript: savePopupData("m3u", "' + id + '", true, 0)')
content.addInteraction(input)
} else {
var input = content.createInput("button", "back", "{{.button.back}}")
var input = content.createInput("button", "back", "Back")
input.setAttribute("onclick", 'javascript: openPopUp("playlist")')
content.addInteraction(input)
}
// Abbrechen
var input = content.createInput("button", "cancel", "{{.button.cancel}}")
var input = content.createInput("button", "cancel", "Cancel")
input.setAttribute("onclick", 'javascript: showElement("popup", false);')
content.addInteraction(input)
// Aktualisieren
if (data["id.provider"]!= "-") {
var input = content.createInput("button", "update", "{{.button.update}}")
var input = content.createInput("button", "update", "Update")
input.setAttribute('onclick', 'javascript: savePopupData("m3u", "' + id + '", false, 1)')
content.addInteraction(input)
}
// Speichern
var input = content.createInput("button", "save", "{{.button.save}}")
var input = content.createInput("button", "save", "Save")
input.setAttribute('onclick', 'javascript: savePopupData("m3u", "' + id + '", false, 0)')
content.addInteraction(input)
break
@@ -1437,20 +1437,20 @@ function openPopUp(dataType, element) {
// Name
var dbKey:string = "name"
var input = content.createInput("text", dbKey, data[dbKey])
input.setAttribute("placeholder", "{{.playlist.name.placeholder}}")
content.appendRow("{{.playlist.name.title}}", input)
input.setAttribute("placeholder", "Playlist name")
content.appendRow("Name", input)
// Beschreibung
var dbKey:string = "description"
var input = content.createInput("text", dbKey, data[dbKey])
input.setAttribute("placeholder", "{{.playlist.description.placeholder}}")
content.appendRow("{{.playlist.description.placeholder}}", input)
input.setAttribute("placeholder", "Description")
content.appendRow("Description", input)
// URL
var dbKey:string = "file.source"
var input = content.createInput("text", dbKey, data[dbKey])
input.setAttribute("placeholder", "{{.playlist.fileHDHR.placeholder}}")
content.appendRow("{{.playlist.fileHDHR.title}}", input)
input.setAttribute("placeholder", "IP address and port (192.168.1.10:5004)")
content.appendRow("HDHomeRun IP", input)
// Tuner
if (SERVER["settings"]["buffer"] != "-") {
@@ -1465,7 +1465,7 @@ function openPopUp(dataType, element) {
var dbKey:string = "tuner"
var select = content.createSelect(text, values, data[dbKey], dbKey)
select.setAttribute("onfocus", "javascript: return;")
content.appendRow("{{.playlist.tuner.title}}", select)
content.appendRow("Tuner / Streams", select)
} else {
var dbKey:string = "tuner"
if (data[dbKey] == undefined) {
@@ -1474,39 +1474,39 @@ function openPopUp(dataType, element) {
var input = content.createInput("text", dbKey, data[dbKey])
input.setAttribute("readonly", "true")
input.className = "notAvailable"
content.appendRow("{{.playlist.tuner.title}}", input)
content.appendRow("Tuner / Streams", input)
}
content.description("{{.playlist.tuner.description}}")
content.description("Number of parallel connections that can be established to the provider. <br>Only available with activated buffer.<br>New settings will only be applied after quitting all streams.")
// Interaktion
content.createInteraction()
// Löschen
if (data["id.provider"]!= "-") {
var input = content.createInput("button", "delete", "{{.button.delete}}")
var input = content.createInput("button", "delete", "Delete")
input.setAttribute('onclick', 'javascript: savePopupData("hdhr", "' + id + '", true, 0)')
input.className = "delete"
content.addInteraction(input)
} else {
var input = content.createInput("button", "back", "{{.button.back}}")
var input = content.createInput("button", "back", "Back")
input.setAttribute("onclick", 'javascript: openPopUp("playlist")')
content.addInteraction(input)
}
// Abbrechen
var input = content.createInput("button", "cancel", "{{.button.cancel}}")
var input = content.createInput("button", "cancel", "Cancel")
input.setAttribute("onclick", 'javascript: showElement("popup", false);')
content.addInteraction(input)
// Aktualisieren
if (data["id.provider"]!= "-") {
var input = content.createInput("button", "update", "{{.button.update}}")
var input = content.createInput("button", "update", "Update")
input.setAttribute('onclick', 'javascript: savePopupData("hdhr", "' + id + '", false, 1)')
content.addInteraction(input)
}
// Speichern
var input = content.createInput("button", "save", "{{.button.save}}")
var input = content.createInput("button", "save", "Save")
input.setAttribute('onclick', 'javascript: savePopupData("hdhr", "' + id + '", false, 0)')
content.addInteraction(input)
break
@@ -1516,22 +1516,22 @@ function openPopUp(dataType, element) {
// Type
var dbKey:string = "type"
var text:string[] = ["M3U: " + "{{.filter.type.groupTitle}}", "xTeVe: " + "{{.filter.type.customFilter}}"]
var text:string[] = ["M3U: " + "Group Title", "xTeVe: " + "Custom Filter"]
var values:string[] = ["javascript: openPopUp('group-title')", "javascript: openPopUp('custom-filter')"]
var select = content.createSelect(text, values, "javascript: openPopUp('group-title')", dbKey)
select.setAttribute("id", id)
select.setAttribute("onchange", 'javascript: changeButtonAction(this, "next", "onclick");') // changeButtonAction
content.appendRow("{{.filter.type.title}}", select)
content.appendRow("Type", select)
// Interaktion
content.createInteraction()
// Abbrechen
var input = content.createInput("button", "cancel", "{{.button.cancel}}")
var input = content.createInput("button", "cancel", "Cancel")
input.setAttribute("onclick", 'javascript: showElement("popup", false);')
content.addInteraction(input)
// Weiter
var input = content.createInput("button", "next", "{{.button.next}}")
var input = content.createInput("button", "next", "Next")
input.setAttribute("onclick", 'javascript: openPopUp("group-title")')
input.setAttribute("id", 'next')
content.addInteraction(input)
@@ -1542,25 +1542,25 @@ function openPopUp(dataType, element) {
switch (dataType) {
case "custom-filter":
content.createHeadline("{{.filter.custom}}")
content.createHeadline("Custom")
break;
case "group-title":
content.createHeadline("{{.filter.group}}")
content.createHeadline("Group")
break;
}
// Name
var dbKey:string = "name"
var input = content.createInput("text", dbKey, data[dbKey])
input.setAttribute("placeholder", "{{.filter.name.placeholder}}")
content.appendRow("{{.filter.name.title}}", input)
input.setAttribute("placeholder", "Filter name")
content.appendRow("Filter Name", input)
// Beschreibung
var dbKey:string = "description"
var input = content.createInput("text", dbKey, data[dbKey])
input.setAttribute("placeholder", "{{.filter.description.placeholder}}")
content.appendRow("{{.filter.description.title}}", input)
input.setAttribute("placeholder", "Description")
content.appendRow("Description", input)
// Typ
var dbKey:string = "type"
@@ -1576,13 +1576,13 @@ function openPopUp(dataType, element) {
var dbKey:string = "caseSensitive"
var input = content.createCheckbox(dbKey)
input.checked = data[dbKey]
content.appendRow("{{.filter.caseSensitive.title}}", input)
content.appendRow("Case Sensitive", input)
// Filterregel (Benutzerdefiniert)
var dbKey:string = "filter"
var input = content.createInput("text", dbKey, data[dbKey])
input.setAttribute("placeholder", "{{.filter.filterRule.placeholder}}")
content.appendRow("{{.filter.filterRule.title}}", input)
input.setAttribute("placeholder", "Sport {HD} !{ES,IT}")
content.appendRow("Filter Rule", input)
break;
@@ -1596,28 +1596,28 @@ function openPopUp(dataType, element) {
var select = content.createSelect(text, values, data[dbKey], dbKey)
select.setAttribute("onchange", "javascript: this.className = 'changed'")
content.appendRow("{{.filter.filterGroup.title}}", select)
content.description("{{.filter.filterGroup.description}}")
content.appendRow("Group Title", select)
content.description("Select a M3U group. (Counter)<br>Changing the group title in the M3U invalidates the filter.")
// Groß- Kleinschreibung beachten
var dbKey:string = "caseSensitive"
var input = content.createCheckbox(dbKey)
input.checked = data[dbKey]
content.appendRow("{{.filter.caseSensitive.title}}", input)
content.appendRow("Case Sensitive", input)
var dbKey:string = "include"
var input = content.createInput("text", dbKey, data[dbKey])
input.setAttribute("placeholder", "{{.filter.include.placeholder}}")
input.setAttribute("placeholder", "FHD,UHD")
content.appendRow("{{.filter.include.title}}", input)
content.description("{{.filter.include.description}}")
content.appendRow("Include", input)
content.description("Channel name must include.<br>(Comma separated) Comma means or")
var dbKey:string = "exclude"
var input = content.createInput("text", dbKey, data[dbKey])
input.setAttribute("placeholder", "{{.filter.exclude.placeholder}}")
content.appendRow("{{.filter.exclude.title}}", input)
content.description("{{.filter.exclude.description}}")
input.setAttribute("placeholder", "ES,IT")
content.appendRow("Exclude", input)
content.description("Channel name must not contain.<br>(Comma separated) Comma means or")
break
@@ -1629,18 +1629,18 @@ function openPopUp(dataType, element) {
content.createInteraction()
// Löschen
var input = content.createInput("button", "delete", "{{.button.delete}}")
var input = content.createInput("button", "delete", "Delete")
input.setAttribute('onclick', 'javascript: savePopupData("filter", "' + id + '", true, 0)')
input.className = "delete"
content.addInteraction(input)
// Abbrechen
var input = content.createInput("button", "cancel", "{{.button.cancel}}")
var input = content.createInput("button", "cancel", "Cancel")
input.setAttribute("onclick", 'javascript: showElement("popup", false);')
content.addInteraction(input)
// Speichern
var input = content.createInput("button", "save", "{{.button.save}}")
var input = content.createInput("button", "save", "Save")
input.setAttribute('onclick', 'javascript: savePopupData("filter", "' + id + '", false, 0)')
content.addInteraction(input)
@@ -1651,68 +1651,68 @@ function openPopUp(dataType, element) {
// Name
var dbKey:string = "name"
var input = content.createInput("text", dbKey, data[dbKey])
input.setAttribute("placeholder", "{{.xmltv.name.placeholder}}")
content.appendRow("{{.xmltv.name.title}}", input)
input.setAttribute("placeholder", "Guide name")
content.appendRow("Name", input)
// Beschreibung
var dbKey:string = "description"
var input = content.createInput("text", dbKey, data[dbKey])
input.setAttribute("placeholder", "{{.xmltv.description.placeholder}}")
content.appendRow("{{.xmltv.description.title}}", input)
input.setAttribute("placeholder", "Description")
content.appendRow("Description", input)
// URL
var dbKey:string = "file.source"
var input = content.createInput("text", dbKey, data[dbKey])
input.setAttribute("placeholder", "{{.xmltv.fileXMLTV.placeholder}}")
content.appendRow("{{.xmltv.fileXMLTV.title}}", input)
input.setAttribute("placeholder", "File path or URL of the XMLTV")
content.appendRow("XMLTV File", input)
// Interaktion
content.createInteraction()
// Löschen
if (data["id.provider"]!= "-") {
var input = content.createInput("button", "delete", "{{.button.delete}}")
var input = content.createInput("button", "delete", "Delete")
input.setAttribute('onclick', 'javascript: savePopupData("xmltv", "' + id + '", true, 0)')
input.className = "delete"
content.addInteraction(input)
}
// Abbrechen
var input = content.createInput("button", "cancel", "{{.button.cancel}}")
var input = content.createInput("button", "cancel", "Cancel")
input.setAttribute("onclick", 'javascript: showElement("popup", false);')
content.addInteraction(input)
// Aktualisieren
if (data["id.provider"]!= "-") {
var input = content.createInput("button", "update", "{{.button.update}}")
var input = content.createInput("button", "update", "Update")
input.setAttribute('onclick', 'javascript: savePopupData("xmltv", "' + id + '", false, 1)')
content.addInteraction(input)
}
// Speichern
var input = content.createInput("button", "save", "{{.button.save}}")
var input = content.createInput("button", "save", "Save")
input.setAttribute('onclick', 'javascript: savePopupData("xmltv", "' + id + '", false, 0)')
content.addInteraction(input)
break
case "users":
content.createHeadline("{{.mainMenu.item.users}}")
content.createHeadline("Users")
// Benutzername
var dbKey:string = "username"
var input = content.createInput("text", dbKey, data[dbKey])
input.setAttribute("placeholder", "{{.users.username.placeholder}}")
content.appendRow("{{.users.username.title}}", input)
input.setAttribute("placeholder", "Username")
content.appendRow("Username", input)
// Neues Passwort
var dbKey:string = "password"
var input = content.createInput("password", dbKey, "")
input.setAttribute("placeholder", "{{.users.password.placeholder}}")
content.appendRow("{{.users.password.title}}", input)
input.setAttribute("placeholder", "Password")
content.appendRow("Password", input)
// Bestätigung
var dbKey:string = "confirm"
var input = content.createInput("password", dbKey, "")
input.setAttribute("placeholder", "{{.users.confirm.placeholder}}")
content.appendRow("{{.users.confirm.title}}", input)
input.setAttribute("placeholder", "Password confirm")
content.appendRow("Confirm", input)
// Berechtigung WEB
var dbKey:string = "authentication.web"
@@ -1721,57 +1721,57 @@ function openPopUp(dataType, element) {
if (data["defaultUser"] == true) {
input.setAttribute("onclick", "javascript: return false")
}
content.appendRow("{{.users.web.title}}", input)
content.appendRow("Web Access", input)
// Berechtigung PMS
var dbKey:string = "authentication.pms"
var input = content.createCheckbox(dbKey)
input.checked = data[dbKey]
content.appendRow("{{.users.pms.title}}", input)
content.appendRow("PMS Access", input)
// Berechtigung M3U
var dbKey:string = "authentication.m3u"
var input = content.createCheckbox(dbKey)
input.checked = data[dbKey]
content.appendRow("{{.users.m3u.title}}", input)
content.appendRow("M3U Access", input)
// Berechtigung XML
var dbKey:string = "authentication.xml"
var input = content.createCheckbox(dbKey)
input.checked = data[dbKey]
content.appendRow("{{.users.xml.title}}", input)
content.appendRow("XML Access", input)
// Berechtigung API
var dbKey:string = "authentication.api"
var input = content.createCheckbox(dbKey)
input.checked = data[dbKey]
content.appendRow("{{.users.api.title}}", input)
content.appendRow("API Access", input)
// Interaktion
content.createInteraction()
// Löschen
if (data["defaultUser"]!= true && id != "-") {
var input = content.createInput("button", "delete", "{{.button.delete}}")
var input = content.createInput("button", "delete", "Delete")
input.className = "delete"
input.setAttribute('onclick', 'javascript: savePopupData("' + dataType + '", "' + id + '", true, 0)')
content.addInteraction(input)
}
// Abbrechen
var input = content.createInput("button", "cancel", "{{.button.cancel}}")
var input = content.createInput("button", "cancel", "Cancel")
input.setAttribute("onclick", 'javascript: showElement("popup", false);')
content.addInteraction(input)
// Speichern
var input = content.createInput("button", "save", "{{.button.save}}")
var input = content.createInput("button", "save", "Save")
input.setAttribute("onclick", 'javascript: savePopupData("' + dataType + '", "' + id + '", "false");')
content.addInteraction(input)
break
case "mapping":
content.createHeadline("{{.mainMenu.item.mapping}}")
content.createHeadline("Mapping")
// Aktiv
var dbKey:string = "x-active"
var input = content.createCheckbox(dbKey)
@@ -1779,7 +1779,7 @@ function openPopUp(dataType, element) {
input.id = "active"
//input.setAttribute("onchange", "javascript: this.className = 'changed'")
input.setAttribute("onchange", "javascript: toggleChannelStatus('" + id + "', this)")
content.appendRow("{{.mapping.active.title}}", input)
content.appendRow("Active", input)
// Kanalname
var dbKey:string = "x-name"
@@ -1789,16 +1789,16 @@ function openPopUp(dataType, element) {
input.style.border = "solid 1px red"
input.setAttribute("readonly", "true")
}
content.appendRow("{{.mapping.channelName.title}}", input)
content.appendRow("Channel Name", input)
content.description(data["name"])
// Beschreibung
var dbKey:string = "x-description"
var input = content.createInput("text", dbKey, data[dbKey])
input.setAttribute("placeholder", "{{.mapping.description.placeholder}}")
input.setAttribute("placeholder", "Used by the Dummy as an XML description")
input.setAttribute("onchange", "javascript: this.className = 'changed'")
content.appendRow("{{.mapping.description.title}}", input)
content.appendRow("Channel Description", input)
// Aktualisierung des Kanalnamens
if (data.hasOwnProperty("_uuid.key")) {
@@ -1807,7 +1807,7 @@ function openPopUp(dataType, element) {
var input = content.createCheckbox(dbKey)
input.setAttribute("onchange", "javascript: this.className = 'changed'")
input.checked = data[dbKey]
content.appendRow("{{.mapping.updateChannelName.title}}", input)
content.appendRow("Update Channel Name", input)
}
}
@@ -1816,7 +1816,7 @@ function openPopUp(dataType, element) {
var input = content.createInput("text", dbKey, data[dbKey])
input.setAttribute("onchange", "javascript: this.className = 'changed'")
input.setAttribute("id", "channel-icon")
content.appendRow("{{.mapping.channelLogo.title}}", input)
content.appendRow("Logo URL", input)
// Aktualisierung des Kanallogos
var dbKey:string = "x-update-channel-icon"
@@ -1824,7 +1824,7 @@ function openPopUp(dataType, element) {
input.checked = data[dbKey]
input.setAttribute("id", "update-icon")
input.setAttribute("onchange", "javascript: this.className = 'changed'; changeChannelLogo('" + id + "');")
content.appendRow("{{.mapping.updateChannelLogo.title}}", input)
content.appendRow("Update Channel Logo", input)
// Erweitern der EPG Kategorie
var dbKey:string = "x-category"
@@ -1832,13 +1832,13 @@ function openPopUp(dataType, element) {
var values:string[] = ["", "Kids", "News", "Movie", "Series", "Sports"]
var select = content.createSelect(text, values, data[dbKey], dbKey)
select.setAttribute("onchange", "javascript: this.className = 'changed'")
content.appendRow("{{.mapping.epgCategory.title}}", select)
content.appendRow("EPG Category", select)
// M3U Gruppentitel
var dbKey:string = "x-group-title"
var input = content.createInput("text", dbKey, data[dbKey])
input.setAttribute("onchange", "javascript: this.className = 'changed'")
content.appendRow("{{.mapping.m3uGroupTitle.title}}", input)
content.appendRow("Group Title (xteve.m3u)", input)
if (data["group-title"] != undefined) {
content.description(data["group-title"])
@@ -1852,7 +1852,7 @@ function openPopUp(dataType, element) {
select.setAttribute("name", dbKey)
select.setAttribute("id", "popup-xmltv")
select.setAttribute("onchange", "javascript: this.className = 'changed'; setXmltvChannel('" + id + "',this);")
content.appendRow("{{.mapping.xmltvFile.title}}", select)
content.appendRow("XMLTV File", select)
var file = data[dbKey]
// XMLTV Mapping
@@ -1864,18 +1864,18 @@ function openPopUp(dataType, element) {
select.setAttribute("onchange", "javascript: this.className = 'changed'; checkXmltvChannel('" + id + "',this,'" + xmlFile + "');")
sortSelect(select)
content.appendRow("{{.mapping.xmltvChannel.title}}", select)
content.appendRow("XMLTV Channel", select)
// Interaktion
content.createInteraction()
// Logo hochladen
var input = content.createInput("button", "cancel", "{{.button.uploadLogo}}")
var input = content.createInput("button", "cancel", "Upload Logo")
input.setAttribute("onclick", 'javascript: uploadLogo();')
content.addInteraction(input)
// Abbrechen
var input = content.createInput("button", "cancel", "{{.button.cancel}}")
var input = content.createInput("button", "cancel", "Cancel")
input.setAttribute("onclick", 'javascript: showElement("popup", false);')
content.addInteraction(input)
@@ -1886,7 +1886,7 @@ function openPopUp(dataType, element) {
ids.push(id)
}
var input = content.createInput("button", "save", "{{.button.done}}")
var input = content.createInput("button", "save", "Done")
input.setAttribute("onclick", 'javascript: donePopupData("' + dataType + '", "' + ids + '", "false");')
content.addInteraction(input)
break