class Domain { constructor(json) { this.dirty = ko.observable(false); this.id = ko.observable(json.id); this.type = ko.observable(json.type); this.proxied = ko.observable(json.proxied); this.name = ko.observable(json.name); this.content = ko.observable(json.content); this.zone = ko.observable(json.zone); this.ttl = ko.observable(json.ttl); this.ttlAuto = ko.observable(json.ttl == 1); this.ttlAuto.subscribe(function() { if(this.ttlAuto()) { this.ttl(1); } }.bind(this)); this.ttl.subscribe(function() { this.ttlAuto(this.ttl() == 1); }.bind(this)); var initialJSON = this.toJson(); var listenDirty = false; [this.type, this.proxied, this.name, this.content, this.ttl].forEach(function(observable) { observable.subscribe(function() { this.dirty(!this.equals(initialJSON, this.toJson())); }.bind(this)); }.bind(this)); listenDirty = true; } toJson() { var obj = {}; obj.id = this.id(); obj.name = this.name(); obj.proxied = this.proxied(); obj.content = this.content(); obj.ttl = parseInt(this.ttl()); obj.zoneId = this.zone().id(); obj.type = this.type(); return obj; } equals (a, b) { return a.id == b.id && a.name == b.name && a.proxied == b.proxied && a.content == b.content && a.ttl == b.ttl; } deleteButtonClicked() { console.log(this); this.zone().deletePendingDomain(this); $("#delete-modal").modal("show"); } modalDeleteClicked() { var self = this; $.ajax({ url: "./api/delete", data: { data: {zoneId: this.zone().id(), dnsId: this.id()} }, method: "POST" }).done(function() { model.selectedZone().domains.remove(function(item) { return item.id() == self.id(); }); model.makeToastSuccess("Deleted"); $("#delete-modal").modal("hide"); }) .fail(function() { model.makeToastError("Error"); }); } saveButtonClicked() { var self = this; if(this.id() === undefined) { $.ajax({ url: "./api/add", data: { data: JSON.stringify(this.toJson()) }, method: "POST" }).done(function(data) { console.log(data); var data = JSON.parse(data); data.zone = self.zone(); self.zone().domains.unshift(new Domain(data)); self.zone().createPendingDomain(new Domain({type: "A", proxied: false, name: "sub."+self.zone().name(), content: "8.8.8.8", zone: self.zone(), ttl: 1})); model.makeToastSuccess("Saved"); }) .fail(function() { model.makeToastError("Error"); }); } else { $.ajax({ url: "./api/edit", data: { data: JSON.stringify(this.toJson()) }, method: "POST" }).done(function() { self.dirty(false); model.makeToastSuccess("Edited"); }) .fail(function() { model.makeToastError("Error"); }); } } } class Zone { constructor (json) { this.id = ko.observable(json.id); this.name = ko.observable(json.name); this.domains = ko.observableArray(); this.deletePendingDomain = ko.observable(null); this.createPendingDomain = ko.observable(new Domain({type: "A", proxied: false, name: "sub."+this.name(), content: "8.8.8.8", zone: this, ttl: 1})); this.page = ko.observable(1); this.totalPages = ko.observable(1); this.totalPagesArray = ko.computed(function() { var arr = ko.observableArray(); for(var n=1;n<=this.totalPages();n++) { arr.push(""+n); } return arr; }, this); } loadDomains() { this.domains.removeAll(); $.ajax({ url: "./api/listDomains", data: { zoneId: this.id(), page: this.page(), perPage: model.perPage() }, method: "POST" }).done(function(json) { var data = JSON.parse(json); console.log(data); this.totalPages(data.totalPages); data.result.forEach(function(domain) { domain.zone = this; this.domains.push(new Domain(domain)); }.bind(this)); }.bind(this)); } select () { model.setActiveDomain(this); this.loadDomains(); } setPage() { var self = this; return function() { self.page(this); self.loadDomains(); }; } previousPage() { this.page(Math.max(this.page()-1, 1)); this.loadDomains(); } nextPage() { this.page(Math.min(this.page()+1, this.totalPages())); this.loadDomains(); } } class Model { constructor() { this.zones = ko.observableArray(); this.selectedZone = ko.observable(null); this.perPage = ko.observable(20); this.types = ["A", "AAAA", "CNAME", "MX", "SRV", "SPF", "TXT", "NS", "LOC"]; this.ttls = [1, 120, 300, 600, 900, 1800, 3600, 7200, 18000, 43200, 86400]; } setActiveDomain(domain) { this.selectedZone(domain); } makeToast(message, color) { var x = document.getElementById("toast"); x.innerHTML = message; color = color || "#333"; $(x).css("background-color", color); x.className = "show"; setTimeout(function(){ x.className = x.className.replace("show", ""); }, 3000); } makeToastError(message) { this.makeToast(message, "#a00"); } makeToastSuccess(message) { this.makeToast(message, "#090"); } }; var model = new Model(); $(function() { ko.applyBindings(model); $.ajax({ url: "./api/list", dataType: "json" }).done(function(json) { var data = JSON.parse(json); data.result.forEach(function(zone) { // console.log(zone); model.zones.push(new Zone(zone)); }); }); }); /* */