mirror of
https://github.com/bunkerity/bunkerweb
synced 2026-05-24 09:28:37 +00:00
add home format for Vue.js vuilder
This commit is contained in:
parent
72916d2b60
commit
58b9ff2351
3 changed files with 198 additions and 36 deletions
164
src/ui/main.py
164
src/ui/main.py
|
|
@ -614,6 +614,139 @@ def totp():
|
|||
return render_template("totp.html")
|
||||
|
||||
|
||||
def home_builder(data):
|
||||
"""
|
||||
It returns the home page in JSON format for the Vue.js builder
|
||||
"""
|
||||
|
||||
version_card = {
|
||||
"type": "card",
|
||||
"link": "https://panel.bunkerweb.io/?utm_campaign=self&utm_source=ui#pro",
|
||||
"containerColumns": {"pc": 4, "tablet": 6, "mobile": 12},
|
||||
"widgets": [
|
||||
{
|
||||
"type": "Stat",
|
||||
"data": {
|
||||
"title": "home_version",
|
||||
"subtitle": (
|
||||
"home_all_features_available"
|
||||
if data.get("is_pro_version")
|
||||
else (
|
||||
"home_awaiting_compliance"
|
||||
if data.get("pro_status") == "active" and data.get("pro_overlapped")
|
||||
else (
|
||||
"home_renew_license"
|
||||
if data.get("pro_status") == "expired"
|
||||
else "home_talk_to_team" if data.get("pro_status") == "suspended" else "home_upgrade_to_pro"
|
||||
)
|
||||
)
|
||||
),
|
||||
"subtitleColor": "success" if data.get("is_pro_version") else "warning",
|
||||
"stat": (
|
||||
"home_pro"
|
||||
if data.get("is_pro_version")
|
||||
else (
|
||||
"home_pro_locked"
|
||||
if data.get("pro_status") == "active" and data.get("pro_overlapped")
|
||||
else (
|
||||
"home_expired"
|
||||
if data.get("pro_status") == "expired"
|
||||
else "home_suspended" if data.get("pro_status") == "suspended" else "home_free"
|
||||
)
|
||||
)
|
||||
),
|
||||
"iconName": "crown" if data.get("is_pro_version") else "key",
|
||||
"iconColor": "amber" if data.get("is_pro_version") else "green",
|
||||
},
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
version_num_card = {
|
||||
"type": "card",
|
||||
"link": "https://github.com/bunkerity/bunkerweb",
|
||||
"containerColumns": {"pc": 4, "tablet": 6, "mobile": 12},
|
||||
"widgets": [
|
||||
{
|
||||
"type": "Stat",
|
||||
"data": {
|
||||
"title": "home_version_number",
|
||||
"subtitle": (
|
||||
"home_couldnt_find_remote"
|
||||
if not data.get("remote_version")
|
||||
else "home_latest_version" if data.get("remote_version") and data.get("check_version") else "home_update_available"
|
||||
),
|
||||
"subtitleColor": (
|
||||
"error" if not data.get("remote_version") else "success" if data.get("remote_version") and data.get("check_version") else "warning"
|
||||
),
|
||||
"stat": data.get("version"),
|
||||
"iconName": "wire",
|
||||
"iconColor": "teal",
|
||||
},
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
instances_card = {
|
||||
"type": "card",
|
||||
"link": "/instances",
|
||||
"containerColumns": {"pc": 4, "tablet": 6, "mobile": 12},
|
||||
"widgets": [
|
||||
{
|
||||
"type": "Stat",
|
||||
"data": {
|
||||
"title": "home_instances",
|
||||
"subtitle": "home_total_number",
|
||||
"subtitleColor": "info",
|
||||
"stat": data.get("instances_number"),
|
||||
"iconName": "box",
|
||||
"iconColor": "dark",
|
||||
},
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
services_card = {
|
||||
"type": "card",
|
||||
"link": "/services",
|
||||
"containerColumns": {"pc": 4, "tablet": 6, "mobile": 12},
|
||||
"widgets": [
|
||||
{
|
||||
"type": "Stat",
|
||||
"data": {
|
||||
"title": "home_services",
|
||||
"subtitle": "home_all_methods_included",
|
||||
"subtitleColor": "info",
|
||||
"stat": data.get("services_number"),
|
||||
"iconName": "disk",
|
||||
"iconColor": "orange",
|
||||
},
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
plugins_card = {
|
||||
"type": "card",
|
||||
"link": "/plugins",
|
||||
"containerColumns": {"pc": 4, "tablet": 6, "mobile": 12},
|
||||
"widgets": [
|
||||
{
|
||||
"type": "Stat",
|
||||
"data": {
|
||||
"title": "home_plugins",
|
||||
"subtitle": "home_errors_found" if data.get("plugins_errors") > 0 else "home_no_error",
|
||||
"subtitleColor": "error" if data.get("plugins_errors") > 0 else "success",
|
||||
"stat": "42",
|
||||
"iconName": "puzzle",
|
||||
"iconColor": "yellow",
|
||||
},
|
||||
}
|
||||
],
|
||||
}
|
||||
builder = [version_card, version_num_card, instances_card, services_card, plugins_card]
|
||||
return builder
|
||||
|
||||
|
||||
@app.route("/home")
|
||||
@login_required
|
||||
def home():
|
||||
|
|
@ -638,7 +771,8 @@ def home():
|
|||
remote_version = basename(r.url).strip().replace("v", "")
|
||||
|
||||
config = app.config["CONFIG"].get_config(with_drafts=True)
|
||||
instances = app.config["INSTANCES"].get_instances()
|
||||
override_instances = config["OVERRIDE_INSTANCES"]["value"] != ""
|
||||
instances = app.config["INSTANCES"].get_instances(override_instances=override_instances)
|
||||
|
||||
instance_health_count = 0
|
||||
|
||||
|
|
@ -662,6 +796,34 @@ def home():
|
|||
services_autoconf_count += 1
|
||||
services += 1
|
||||
|
||||
metadata = app.config["DB"].get_metadata()
|
||||
|
||||
is_pro_version = metadata["is_pro"]
|
||||
pro_status = metadata["pro_status"]
|
||||
pro_services = metadata["pro_services"]
|
||||
pro_overlapped = metadata["pro_overlapped"]
|
||||
bw_version = metadata["version"]
|
||||
|
||||
data = {
|
||||
"check_version": not remote_version or bw_version == remote_version,
|
||||
"remote_version": remote_version,
|
||||
"version": bw_version,
|
||||
"instances_number": len(instances),
|
||||
"services_number": services,
|
||||
"instance_health_count": instance_health_count,
|
||||
"services_scheduler_count": services_scheduler_count,
|
||||
"services_ui_count": services_ui_count,
|
||||
"services_autoconf_count": services_autoconf_count,
|
||||
"is_pro_version": is_pro_version,
|
||||
"pro_status": pro_status,
|
||||
"pro_services": pro_services,
|
||||
"pro_overlapped": pro_overlapped,
|
||||
"plugins_number": len(app.config["CONFIG"].get_plugins()),
|
||||
"plugins_errors": app.config["DB"].get_plugins_errors(),
|
||||
}
|
||||
|
||||
data_server_builder = home_builder(data)
|
||||
|
||||
return render_template(
|
||||
"home.html",
|
||||
check_version=not remote_version or bw_version == remote_version,
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ class News {
|
|||
) {
|
||||
sessionStorage.setItem(
|
||||
"lastRefetch",
|
||||
Math.round(new Date().getTime() / 1000) + 3600
|
||||
Math.round(new Date().getTime() / 1000) + 3600,
|
||||
);
|
||||
sessionStorage.setItem("lastNews", JSON.stringify(lastNews));
|
||||
}
|
||||
|
|
@ -102,7 +102,7 @@ class News {
|
|||
news.photo.url,
|
||||
news.excerpt,
|
||||
news.tags,
|
||||
news.date
|
||||
news.date,
|
||||
);
|
||||
const BASE_URL = this.BASE_URL;
|
||||
let cleanHTML = DOMPurify.sanitize(cardHTML);
|
||||
|
|
@ -114,7 +114,7 @@ class News {
|
|||
slug.addEventListener("click", function () {
|
||||
window.open(
|
||||
`${BASE_URL}blog/post/${news.slug}?utm_campaign=self&utm_source=ui`,
|
||||
"_blank"
|
||||
"_blank",
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
@ -268,7 +268,7 @@ class FlashMsg {
|
|||
if (Number(this.flashCount.textContent) > 0) this.animeBtn();
|
||||
// display only one fixed flash message
|
||||
const flashFixedEls = document.querySelectorAll(
|
||||
"[data-flash-message-fixed]"
|
||||
"[data-flash-message-fixed]",
|
||||
);
|
||||
if (flashFixedEls.length > 1) {
|
||||
flashFixedEls.forEach((el, i) => {
|
||||
|
|
@ -298,7 +298,7 @@ class FlashMsg {
|
|||
flashEl.remove();
|
||||
//update count
|
||||
this.flashCount.textContent = document.querySelectorAll(
|
||||
"[data-flash-message]"
|
||||
"[data-flash-message]",
|
||||
).length;
|
||||
}
|
||||
} catch (err) {}
|
||||
|
|
@ -401,7 +401,7 @@ class Banner {
|
|||
// Try to get data from api
|
||||
if (sessionStorage.getItem("bannerNews") !== null) {
|
||||
return this.updateBanner(
|
||||
JSON.parse(sessionStorage.getItem("bannerNews"))
|
||||
JSON.parse(sessionStorage.getItem("bannerNews")),
|
||||
);
|
||||
}
|
||||
fetch("https://www.bunkerweb.io/api/bw-ui-news")
|
||||
|
|
@ -413,7 +413,7 @@ class Banner {
|
|||
// Refetch after one hour
|
||||
sessionStorage.setItem(
|
||||
"bannerRefetch",
|
||||
Math.round(new Date().getTime() / 1000) + 3600
|
||||
Math.round(new Date().getTime() / 1000) + 3600,
|
||||
);
|
||||
return this.updateBanner(res.data[0].data);
|
||||
})
|
||||
|
|
@ -446,7 +446,7 @@ class Banner {
|
|||
this.bannerEl.querySelector(
|
||||
`[role="listitem"][data-id="${
|
||||
+visibleEl.getAttribute("data-id") + 1
|
||||
}"]`
|
||||
}"]`,
|
||||
) || this.bannerEl.querySelector(`[role="listitem"][data-id="0"]`);
|
||||
|
||||
// Hide current one
|
||||
|
|
@ -538,7 +538,7 @@ class Clipboard {
|
|||
if (result.state === "granted" || result.state === "prompt") {
|
||||
/* write to the clipboard now */
|
||||
const copyEl = document.querySelector(
|
||||
e.target.getAttribute("data-clipboard-target")
|
||||
e.target.getAttribute("data-clipboard-target"),
|
||||
);
|
||||
|
||||
copyEl.select();
|
||||
|
|
@ -560,7 +560,7 @@ class Clipboard {
|
|||
if (!this.isCopy) {
|
||||
/* write to the clipboard now */
|
||||
const copyEl = document.querySelector(
|
||||
e.target.getAttribute("data-clipboard-target")
|
||||
e.target.getAttribute("data-clipboard-target"),
|
||||
);
|
||||
|
||||
copyEl.select();
|
||||
|
|
@ -579,7 +579,7 @@ class Clipboard {
|
|||
if (!this.isCopy) {
|
||||
/* write to the clipboard now */
|
||||
const copyEl = document.querySelector(
|
||||
e.target.getAttribute("data-clipboard-target")
|
||||
e.target.getAttribute("data-clipboard-target"),
|
||||
);
|
||||
|
||||
copyEl.select();
|
||||
|
|
@ -611,7 +611,7 @@ class Clipboard {
|
|||
"opacity-0",
|
||||
"transition-opacity",
|
||||
"duration-300",
|
||||
this.isCopy ? "bg-green-500" : "bg-red-500"
|
||||
this.isCopy ? "bg-green-500" : "bg-red-500",
|
||||
);
|
||||
feedbackEl.textContent = this.isCopy ? "Copied!" : "Error!";
|
||||
btn.appendChild(feedbackEl);
|
||||
|
|
@ -642,13 +642,13 @@ const setMenu = new Menu();
|
|||
const setNewsSidebar = new Sidebar(
|
||||
"[data-sidebar-info]",
|
||||
"[data-sidebar-info-open]",
|
||||
"[data-sidebar-info-close]"
|
||||
"[data-sidebar-info-close]",
|
||||
);
|
||||
|
||||
const setFlashSidebar = new Sidebar(
|
||||
"[data-flash-sidebar]",
|
||||
"[data-flash-sidebar-open]",
|
||||
"[data-flash-sidebar-close]"
|
||||
"[data-flash-sidebar-close]",
|
||||
);
|
||||
|
||||
const setClipboard = new Clipboard();
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ class FolderNav {
|
|||
constructor(prefix) {
|
||||
this.prefix = prefix;
|
||||
this.breadContainer = document.querySelector(
|
||||
`[data-${this.prefix}-breadcrumb]`
|
||||
`[data-${this.prefix}-breadcrumb]`,
|
||||
);
|
||||
this.container = document.querySelector(`[data-${this.prefix}-container]`);
|
||||
this.isReadonly =
|
||||
|
|
@ -12,11 +12,11 @@ class FolderNav {
|
|||
? true
|
||||
: false;
|
||||
this.listContainer = document.querySelector(
|
||||
`[data-${this.prefix}-folders]`
|
||||
`[data-${this.prefix}-folders]`,
|
||||
);
|
||||
this.els = document.querySelectorAll(`div[data-${this.prefix}-element]`);
|
||||
this.files = document.querySelectorAll(
|
||||
`div[data-${this.prefix}-element][data-_type='file']`
|
||||
`div[data-${this.prefix}-element][data-_type='file']`,
|
||||
);
|
||||
this.addFileEl = document.querySelector(`[data-${this.prefix}-add-file]`);
|
||||
this.initSorted();
|
||||
|
|
@ -91,8 +91,8 @@ class FolderNav {
|
|||
this.removeBreadElByLvl(+prevLvl);
|
||||
const folder = document.querySelector(
|
||||
`div[data-${this.prefix}-element][data-path='${item.getAttribute(
|
||||
"data-path"
|
||||
)}']`
|
||||
"data-path",
|
||||
)}']`,
|
||||
);
|
||||
this.updateActions(folder);
|
||||
}
|
||||
|
|
@ -113,7 +113,7 @@ class FolderNav {
|
|||
|
||||
showCurrentFolderEls(path, lvl) {
|
||||
const nestedEl = document.querySelectorAll(
|
||||
`div[data-path^="${path}/"][data-level="${+lvl + 1}"]`
|
||||
`div[data-path^="${path}/"][data-level="${+lvl + 1}"]`,
|
||||
);
|
||||
for (let i = 0; i < nestedEl.length; i++) {
|
||||
const el = nestedEl[i];
|
||||
|
|
@ -157,7 +157,7 @@ class FolderNav {
|
|||
//the clicked bread item
|
||||
removeBreadElByLvl(lvl) {
|
||||
const breadcrumbItem = this.breadContainer.querySelectorAll(
|
||||
`[data-${this.prefix}-breadcrumb-item]`
|
||||
`[data-${this.prefix}-breadcrumb-item]`,
|
||||
);
|
||||
breadcrumbItem.forEach((item) => {
|
||||
if (
|
||||
|
|
@ -216,7 +216,7 @@ class FolderDropdown {
|
|||
this.prefix = prefix;
|
||||
this.container = document.querySelector(`[data-${this.prefix}-container]`);
|
||||
this.dropEls = document.querySelectorAll(
|
||||
`[data-${this.prefix}-action-dropdown]`
|
||||
`[data-${this.prefix}-action-dropdown]`,
|
||||
);
|
||||
this.init();
|
||||
}
|
||||
|
|
@ -262,7 +262,7 @@ class FolderDropdown {
|
|||
.closest("button")
|
||||
.getAttribute(`data-${this.prefix}-action-dropdown-btn`);
|
||||
const dropEl = document.querySelector(
|
||||
`[data-${this.prefix}-action-dropdown="${att}"]`
|
||||
`[data-${this.prefix}-action-dropdown="${att}"]`,
|
||||
);
|
||||
this.hideDrop(dropEl);
|
||||
}
|
||||
|
|
@ -346,33 +346,33 @@ class FolderModal {
|
|||
: false;
|
||||
//add service/file elements
|
||||
this.breadContainer = document.querySelector(
|
||||
`[data-${this.prefix}-breadcrumb]`
|
||||
`[data-${this.prefix}-breadcrumb]`,
|
||||
);
|
||||
this.addConfContainer = document.querySelector(
|
||||
`[data-${this.prefix}-add-container]`
|
||||
`[data-${this.prefix}-add-container]`,
|
||||
);
|
||||
//modal DOM elements
|
||||
this.form = document.querySelector(`[data-${this.prefix}-modal-form]`);
|
||||
this.modalEl = document.querySelector(`[data-${this.prefix}-modal]`);
|
||||
this.modalTitle = this.modalEl.querySelector(
|
||||
`[data-${this.prefix}-modal-title]`
|
||||
`[data-${this.prefix}-modal-title]`,
|
||||
);
|
||||
this.modalPath = this.modalEl.querySelector(
|
||||
`[data-${this.prefix}-modal-path]`
|
||||
`[data-${this.prefix}-modal-path]`,
|
||||
);
|
||||
this.modalEditor = this.modalEl.querySelector(
|
||||
`[data-${this.prefix}-modal-editor]`
|
||||
`[data-${this.prefix}-modal-editor]`,
|
||||
);
|
||||
this.modalPathPrev = this.modalPath.querySelector(
|
||||
`p[data-${this.prefix}-modal-path-prefix]`
|
||||
`p[data-${this.prefix}-modal-path-prefix]`,
|
||||
);
|
||||
this.modalPathName = this.modalPath.querySelector("input");
|
||||
this.modalPathSuffix = this.modalPath.querySelector(
|
||||
`p[data-${this.prefix}-modal-path-suffix]`
|
||||
`p[data-${this.prefix}-modal-path-suffix]`,
|
||||
);
|
||||
|
||||
this.modalSubmit = this.modalEl.querySelector(
|
||||
`[data-${this.prefix}-modal-submit]`
|
||||
`[data-${this.prefix}-modal-submit]`,
|
||||
);
|
||||
//hidden input for backend
|
||||
this.modalInpPath = this.modalEl.querySelector("#path");
|
||||
|
|
@ -381,7 +381,7 @@ class FolderModal {
|
|||
this.modalInpOldName = this.modalEl.querySelector("#old_name");
|
||||
this.modalTxtarea = this.modalEl.querySelector("#content");
|
||||
this.modalDelMsg = this.modalEl.querySelector(
|
||||
`[data-${this.prefix}-modal-delete]`
|
||||
`[data-${this.prefix}-modal-delete]`,
|
||||
);
|
||||
//HANDLERS
|
||||
//modal and values logic after clicking add file/folder button
|
||||
|
|
@ -411,7 +411,7 @@ class FolderModal {
|
|||
"file",
|
||||
"",
|
||||
"",
|
||||
this.getLevelFromBread()
|
||||
this.getLevelFromBread(),
|
||||
);
|
||||
}
|
||||
} catch (err) {}
|
||||
|
|
@ -481,7 +481,7 @@ class FolderModal {
|
|||
var element = document.createElement("a");
|
||||
element.setAttribute(
|
||||
"href",
|
||||
"data:text/plain;charset=utf-8," + encodeURIComponent(text)
|
||||
"data:text/plain;charset=utf-8," + encodeURIComponent(text),
|
||||
);
|
||||
element.setAttribute("download", filename);
|
||||
|
||||
|
|
@ -652,7 +652,7 @@ class FolderModal {
|
|||
"delete-btn",
|
||||
"valid-btn",
|
||||
"edit-btn",
|
||||
"info-btn"
|
||||
"info-btn",
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue