import dom import htmlutils.utils import json import streams import tables import strutils import sets from sequtils import map, apply var pkgMap : OrderedTable[string, JsonNode] type DownloadPanel = ref object badge : Node listgroup : Node pkgs : HashSet[string] body : Node proc newDownloadPanel(parent : Node) : DownloadPanel = let dp = DownloadPanel() dp.pkgs = initSet[string]() htmlDocument(document, parent): "div": class ["panel", "panel-default"] "div": class ["panel-heading"] "h3": class ["panel-title"] "a": #attrs {"data-toggle": "collapse", "href": "#dlist"} text "Package list " "span": class ["badge", "pull-right"] style {"display" :"none"} cb: dp.badge = node "ul": class ["list-group"] cb: dp.listgroup = node "div": class ["panel-body"] style { "text-align" : "right", "display" :"none" } "button": class ["btn", "btn-primary"] attrs {"type" : "button"} "span": class ["glyphicon", "glyphicon-download"] cb: node.appendChild(document.createTextNode(" Download")) cb: dp.body = node dp proc updateBadge(dp : DownloadPanel) = let st = if dp.pkgs.len() > 0: "block" else: "none" dp.body.style.display = st dp.badge.style.display = st dp.badge.textContent = $dp.pkgs.len() proc addPkg(dp : DownloadPanel, pkgfile : string) = if not dp.pkgs.contains(pkgfile): dp.pkgs.incl(pkgfile) htmlDocument(document, dp.listgroup): "li": var listElement : Node class ["list-group-item"] text pkgfile "span": class ["glyphicon", "glyphicon-remove", "pull-right"] cb: let fn = proc(e : Event) = dp.pkgs.excl(pkgfile) listElement.remove() dp.updateBadge node.addEventListener("click", fn) cb: listElement = node dp.updateBadge proc createDropdown(parent : Node, data :seq[string], onchange : proc(value : string)) = htmlDocument(document, parent): "div": var button : Node class ["dropdown"] "button": class ["btn", "btn-default", "dropdown-toggle"] attrs {"data-toggle": "dropdown", "type": "button"} cb: for line in data: node.textContent = line break button = node "ul": class ["dropdown-menu"] cb: for line in data: htmlDocument(document, node): "li": "a": text line cb: let fn = proc(e: Event) = button.textContent = node.textContent onchange($node.textContent) node.addEventListener("click", fn) type PkgTable = ref object addButton : Node proc newPkgTable(parent: Node, searchString : string) : PkgTable = var pkgtable = PkgTable() var fragments = newSeq[string]() for fragment in searchString.splitWhitespace(): fragments.add(fragment) var searchResult = newOrderedTable[string,JsonNode]() for key, value in pkgMap: for fragment in fragments: if fragment in key: searchResult.add(key,value) for table in document.querySelectorAll("table.pkgtable"): table.parentNode.removeChild(table) htmlDocument(document, parent): "table": class ["table", "table-striped","pkgtable"] "thead": "tr": "th": "button": class ["btn", "btn-default"] attrs {"type": "button"} "span": class ["glyphicon", "glyphicon-plus"] cb: let txt = document.createTextNode(" Add") node.appendChild(txt) pkgtable.addButton = node "th": text "Name" "th": text "Version" "th": text "Arch" "tbody": cb: var i = 0 for name, versions in searchResult: closureScope: htmlDocument(document, node): "tr": var archCell : Node "td": "div": class ["checkbox"] "label": "input": attrs {"type" : "checkbox"} "td": text $name "td": cb: var data = newSeq[string]() for version, arches in versions: data.add(version) let vs = versions let change_callback = proc(newValue : string) = archCell.removeChildren() var newdata = newSeq[string]() for arch, pkgname in vs[newValue]: newdata.add(arch) createDropdown(archCell, newdata, proc(s : string) = discard) createDropdown(node, data, change_callback) "td": cb: archCell = node var data = newSeq[string]() var arches : JsonNode for v, a in versions: arches = a for arch, pkgname in arches: data.add(arch) createDropdown(node, data, proc(s : string) = discard) pkgtable var dp : DownloadPanel # var pkgTable : PkgTable htmlDocument document, document.body: # "img": # attrs {"src" : "img/background.bpg"} # style { # "width" : "100%", # "position" : "fixed", # "bottom" : "0", # "left" : "0", # "z-index" : "-10" # } "div": var table : Node style {"background-color" : "rgba(255, 255, 255, 0.25)"} class ["container"] "div": style { "margin-top" : "20px", "background-color" : "rgba(224, 224, 224, 0.5)" } class ["jumbotron"] "h1": text "Jpacrepo" "p": text "Personal archlinux package repository" "div": "form": class ["form-horizontal"] "div": class ["form-group"] "label": class ["control-label", "col-sm-2"] text " Search package" "div": class ["col-sm-10"] "input": class ["form-control"] attrs {"type" : "text"} cb : proc add2DownloadList(e : Event) = let rows = table.querySelectorAll("tbody tr") for row in rows: let cbox = row.querySelector("td:first-child input") if cbox.checked: let pkgname = $row.querySelector("td:nth-child(2)").textContent let version = $row.querySelector("td:nth-child(3) button").textContent let arch = $row.querySelector("td:nth-child(4) button").textContent dp.addPkg(pkgMap[pkgname][version][arch].getStr) proc oninput(e : Event) = if pkgMap.len == 0 or node.value.len < 2: return let pkgtable = newPkgTable(table, $node.value) pkgtable.addButton.addEventListener("click", add2DownloadList) node.addEventListener("input", oninput) "div": class ["row"] "div": class ["col-sm-3"] cb: dp = newDownloadPanel(node) "div": class ["col-sm-9"] cb: table = node let r = newXMLHTTPRequest() let load_cb = proc(e : Event) = let response = parseJson($r.responseText) pkgMap = response.getFields() # var keys = newSeq[string]() # for key in response.getFields().keys(): # keys.add(key) # echo keys r.addEventListener("load", load_cb) r.open("get", "http://oggio88.soon.it/jpacrepo/rest/pkg/map") r.setRequestHeader("Accept", "application/json") r.send()