globular_admin
Version:
Administration panel for a Globular server.
376 lines (334 loc) • 12.1 kB
text/typescript
import { ConfigurationPanel } from "./configurationPanel";
import { IServiceConfig, IConfig } from "globular-web-client";
import { randomUUID, rgbToHsl } from "./utility";
import { createElement } from "./element";
import {
stopService,
eventHub,
startService,
saveService,
getErrorMessage,
uninstallService,
installService,
globular,
GetServiceDescriptor,
refreshToken,
readFullConfig
} from "./backend";
import { UninstallServiceRequest } from "globular-web-client/lib/admin/admin_pb";
import { ServiceDescriptor } from "globular-web-client/lib/services/services_pb";
/**
* That class is use to display service configuration.
*/
export class ServicePanel extends ConfigurationPanel {
private uninstallBtn: any;
private updateBtn: any;
private stopBtn: any;
private startBtn: any;
public actionBtnGroup: any;
// configuration lines.
private domainConfig: any;
private publisherConfig: any;
private versionConfig: any;
private keepUpdataConfig: any;
private keepAliveConfig: any;
private portConfig: any;
private proxyConfig: any;
private tlsConfig: any;
public stateDiv: any;
private editable: boolean;
private listeners: Map<string, Array<string>>;
constructor(service: IServiceConfig, id: string, name: string) {
super(service, name, randomUUID());
this.listeners = new Map<string, Array<string>>();
// Set the domain propertie.
this.domainConfig = this.appendTextualConfig("Domain");
// Set the id of the publisher
this.publisherConfig = this.appendTextualConfig("PublisherId", "Publisher");
// The version of the service...
this.versionConfig = this.appendTextualConfig("Version");
// TLS todo create boolean configuration values...
this.keepUpdataConfig = this.appendBooleanConfig(
"KeepUpToDate",
["True", "False"],
"Keep up to date"
);
// Restart the service if it stop...
this.keepAliveConfig = this.appendBooleanConfig(
"KeepAlive",
["True", "False"],
"Keep alive"
);
// The port
this.portConfig = this.appendTextualConfig(
"Port",
"Port",
"number",
1,
0,
65535
);
// The proxy
this.proxyConfig = this.appendTextualConfig(
"Proxy",
"Proxy",
"number",
1,
0,
65535
);
// TLS todo create boolean configuration values...
this.tlsConfig = this.appendBooleanConfig(
"TLS",
["True", "False"],
"Use TLS"
);
// Here I will append specific button
this.actionBtnGroup = createElement(null, {
tag: "div",
class: "col s6 right-align",
style: "display: none;"
});
this.actionBtnGroup
.appendElement({
tag: "a",
id: "update_btn",
href: "javascript:void(0)",
class: "waves-effect waves-light btn-flat",
innerHtml: "Update",
style: "margin-right: 2px; display: none"
})
.appendElement({
tag: "a",
id: "uninstall_btn",
href: "javascript:void(0)",
class: "waves-effect waves-light btn-flat",
innerHtml: "Uninstall",
style: "margin-right: 2px;"
})
.appendElement({
tag: "a",
id: "stop_btn",
href: "javascript:void(0)",
class: "waves-effect waves-light btn-flat",
innerHtml: "Stop",
style: "margin-right: 2px;"
})
.appendElement({
tag: "a",
id: "start_btn",
href: "javascript:void(0)",
class: "waves-effect waves-light btn-flat",
innerHtml: "Start",
style: "margin-right: 2px; display: none;"
});
this.uninstallBtn = this.actionBtnGroup.getChildById("uninstall_btn");
this.stopBtn = this.actionBtnGroup.getChildById("stop_btn");
this.startBtn = this.actionBtnGroup.getChildById("start_btn");
this.updateBtn = this.actionBtnGroup.getChildById("update_btn")
// display the start button and hide stop if the service is not running.
if (service.State != "running") {
this.stopBtn.element.style.display = "none";
this.startBtn.element.style.display = "";
}
// Actions..
// Uninstall
this.uninstallBtn.element.onclick = (evt: any) => {
evt.stopPropagation();
uninstallService(this.config, true, () => {
delete globular.config.Services[this.config.Id]
eventHub.publish("uninstall_service_event", this.config.Id, true)
M.toast({ html: "Service " + this.config.Id + " was uninstalled successfully!", displayLength: 3000 });
},
(err: any) => {
M.toast({ html: getErrorMessage(err.message), displayLength: 2000 });
});
};
this.stopBtn.element.onclick = (evt: any) => {
evt.stopPropagation();
stopService(id, () => {
// Here I will set the start button...
eventHub.publish("stop_service_event_" + id, id, false);
},
(err: any) => {
M.toast({ html: getErrorMessage(err.message), displayLength: 2000 });
});
};
/**
* That event will be call when a service will be stopped.
*/
eventHub.subscribe(
"stop_service_event_" + id,
(uuid: string) => {
/** Subscriber id. todo diconnect on logout...*/
if (!this.listeners.has("stop_service_event_" + id)) {
this.listeners.set("stop_service_event_" + id, new Array<string>())
}
this.listeners.get("stop_service_event_" + id).push(uuid)
},
(evt: any) => {
this.stopBtn.element.style.display = "none";
this.startBtn.element.style.display = "";
this.keepAliveConfig.set(); // set the value...
this.stateDiv.element.innerHTML = "stopped";
},
false
);
this.startBtn.element.onclick = (evt: any) => {
evt.stopPropagation();
startService(id, () => {
// Here I will set the start button...
eventHub.publish("start_service_event_" + id, id, false);
},
(err: any) => {
M.toast({ html: getErrorMessage(err.message), displayLength: 2000 });
});
};
eventHub.subscribe(
"start_service_event_" + id,
(uuid: string) => {
//console.log("start_service_event_" + id, uuid);
if (!this.listeners.has("start_service_event_" + id)) {
this.listeners.set("start_service_event_" + id, new Array<string>())
}
this.listeners.get("start_service_event_" + id).push(uuid)
},
(evt: any) => {
this.stopBtn.element.style.display = "";
this.startBtn.element.style.display = "none";
this.stateDiv.element.innerHTML = "running";
},
false
);
// Here I will update the configuration on save event.
eventHub.subscribe(
"save_service_config_event_" + id,
(uuid: string) => {
//console.log("save_service_config_event_" + id, uuid);
if (!this.listeners.has("save_service_config_event_" + id)) {
this.listeners.set("save_service_config_event_" + id, new Array<string>())
}
this.listeners.get("save_service_config_event_" + id).push(uuid)
},
(configStr: string) => {
this.config = JSON.parse(configStr);
this.keepAliveConfig.reset();
this.domainConfig.reset();
this.publisherConfig.reset();
this.versionConfig.reset();
this.keepUpdataConfig.reset();
this.keepAliveConfig.reset();
this.portConfig.reset();
this.proxyConfig.reset();
this.tlsConfig.reset();
this.stateDiv.element.innerHTML = this.config.State;
},
false
);
}
refresh(){
// Set the config.
this.config = globular.config.Services[this.config.Id]
// set field values.
this.keepAliveConfig.reset();
this.domainConfig.reset();
this.publisherConfig.reset();
this.versionConfig.reset();
this.keepUpdataConfig.reset();
this.keepAliveConfig.reset();
this.portConfig.reset();
this.proxyConfig.reset();
this.tlsConfig.reset();
}
setStateDiv(div: any) {
this.stateDiv = div;
if (this.editable) {
this.stateDiv.element.style.display = "none";
} else {
this.stateDiv.element.style.display = "";
}
}
onlogin(data: any) {
super.onlogin(data)
if (this.config != undefined) {
this.actionBtnGroup.element.style.display = "";
this.stateDiv.element.style.display = "none";
this.config = data.Services[this.config.Id];
this.editable = true;
// So here I will get information to see if or not a new service
// version is available and show the update button if it's the case.
GetServiceDescriptor(this.config.Id, this.config.PublisherId,
(descriptors: Array<ServiceDescriptor>) => {
descriptors.sort((a, b) => (a.getVersion() > b.getVersion()) ? 1 : ((b.getVersion() > a.getVersion()) ? -1 : 0))
if (descriptors.length > 0) {
let descriptor = descriptors[descriptors.length - 1]
if (this.config.Version < descriptor.getVersion()) {
// In that case I will dsiplay the update button
this.updateBtn.element.style.display = "inline"
// Update the service to the last version.
this.updateBtn.element.onclick = (evt: any) => {
uninstallService(this.config, false, () => {
installService(
descriptor.getDiscoveriesList()[0],
descriptor.getId(),
descriptor.getPublisherid(),
descriptor.getVersion(),
() => {
// here I will refresh the token and set the full config...
eventHub.publish("install_service_event", descriptor.getId(), true)
M.toast({ html: "Service " + descriptor.getId() + " installed successfully!", displayLength: 3000 });
// refresh the panel again to set the new service to admin mode.
eventHub.publish("onlogin", globular.config, true)
},
(err: any) => {
M.toast({ html: getErrorMessage(err.message), displayLength: 2000 });
}
);
},
(err: any) => {
M.toast({ html: getErrorMessage(err.message), displayLength: 2000 });
});
}
} else {
this.updateBtn.element.style.display = "none"
}
}
},
(err: any) => {
M.toast({ html: getErrorMessage(err.message), displayLength: 2000 });
});
} else {
console.log("service panel have empty configuration! ", this)
}
}
onlogout() {
super.onlogout()
this.actionBtnGroup.element.style.display = "none";
this.stateDiv.element.style.display = "";
this.editable = true;
}
close() {
super.close()
// close the listener.
this.listeners.forEach((listeners: Array<string>, event: string) => {
listeners.forEach((uuid: string) => {
eventHub.unSubscribe(event, uuid);
})
})
}
save() {
super.save();
// Now I will save the configuration.
console.log("save service!");
saveService(this.config, (service: any) => {
// So here I will publish an event to update configuration.
eventHub.publish(
"save_service_config_event_" + service.Id,
JSON.stringify(service),
false
);
}, (err: any) => {
M.toast({ html: getErrorMessage(err.message), displayLength: 2000 });
});
}
}