diff --git a/src/ui/builder/advanced_mode.py b/src/ui/builder/advanced_mode.py new file mode 100644 index 000000000..8835785f5 --- /dev/null +++ b/src/ui/builder/advanced_mode.py @@ -0,0 +1,40 @@ +import base64 +import json + +from .utils.form import get_forms, get_service_settings + + +def advanced_mode_builder(templates: list[dict], plugins: list, global_config: dict, total_config: dict, service_name: str) -> str: + """Render forms with global config data. + ATM we don't need templates but we need to pass at least one to the function (it will simply not override anything). + """ + + # We need + settings = get_service_settings(service_name, global_config, total_config) + builder = [ + { + "type": "card", + "containerColumns": {"pc": 12, "tablet": 12, "mobile": 12}, + "widgets": [ + { + "type": "Title", + "data": { + "title": service_name, + "type": "container", + "lowercase": True, + }, + }, + { + "type": "Subtitle", + "data": {"subtitle": "services_manage_subtitle", "type": "container", "subtitleClass": "mb-4"}, + }, + { + "type": "Templates", + "data": { + "templates": get_forms(templates, plugins, settings, ("advanced",)), + }, + }, + ], + } + ] + return base64.b64encode(bytes(json.dumps(builder), "utf-8")).decode("ascii") diff --git a/src/ui/builder/easy_mode.py b/src/ui/builder/easy_mode.py new file mode 100644 index 000000000..377f85b33 --- /dev/null +++ b/src/ui/builder/easy_mode.py @@ -0,0 +1,40 @@ +import base64 +import json + +from .utils.form import get_forms, get_service_settings + + +def easy_mode_builder(templates: list[dict], plugins: list, global_config: dict, total_config: dict, service_name: str) -> str: + """Render forms with global config data. + ATM we don't need templates but we need to pass at least one to the function (it will simply not override anything). + """ + + # We need + settings = get_service_settings(service_name, global_config, total_config) + builder = [ + { + "type": "card", + "containerColumns": {"pc": 12, "tablet": 12, "mobile": 12}, + "widgets": [ + { + "type": "Title", + "data": { + "title": service_name, + "type": "container", + "lowercase": True, + }, + }, + { + "type": "Subtitle", + "data": {"subtitle": "services_manage_subtitle", "type": "container", "subtitleClass": "mb-4"}, + }, + { + "type": "Templates", + "data": { + "templates": get_forms(templates, plugins, settings, ("easy",)), + }, + }, + ], + } + ] + return base64.b64encode(bytes(json.dumps(builder), "utf-8")).decode("ascii") diff --git a/src/ui/builder/raw_mode.py b/src/ui/builder/raw_mode.py index 555afc4b8..e53ef01b6 100644 --- a/src/ui/builder/raw_mode.py +++ b/src/ui/builder/raw_mode.py @@ -18,11 +18,24 @@ def raw_mode_builder(templates: list[dict], plugins: list, global_config: dict, # We need settings = get_service_settings(service_name, global_config, total_config) + builder = [ { "type": "card", "containerColumns": {"pc": 12, "tablet": 12, "mobile": 12}, "widgets": [ + { + "type": "Title", + "data": { + "title": service_name, + "type": "container", + "lowercase": True, + }, + }, + { + "type": "Subtitle", + "data": {"subtitle": "services_manage_subtitle", "type": "container", "subtitleClass": "mb-4"}, + }, { "type": "Templates", "data": { diff --git a/src/ui/builder/services.py b/src/ui/builder/services.py index d25726aaf..bc9dd9885 100644 --- a/src/ui/builder/services.py +++ b/src/ui/builder/services.py @@ -271,7 +271,7 @@ def services_action( "size": "normal", "attrs": { "role": "link", - "data-link": f"services/{mode}/{server_name}", + "data-link": f"modes?service_name={server_name}&mode={mode}" if mode != "create" else f"modes?mode={mode}", }, }, ) diff --git a/src/ui/builder/utils/form.py b/src/ui/builder/utils/form.py index 5317b2b55..11033d27e 100644 --- a/src/ui/builder/utils/form.py +++ b/src/ui/builder/utils/form.py @@ -106,9 +106,11 @@ def set_raw(template: list, plugins_base: list, settings: dict) -> dict: for plugin in plugins: for setting, value in plugin.get("settings").items(): - # avoid some methods from services_settings - if setting in settings and settings[setting].get("method", "ui") not in ("ui", "default", "manual"): - continue + # we want to show none default value even if this is a disabled method + + # if setting in settings and settings[setting].get("method", "ui") not in ("ui", "default", "manual") and : + # continue + raw_value = None # Start by setting template value if exists @@ -130,6 +132,7 @@ def set_raw(template: list, plugins_base: list, settings: dict) -> dict: if raw_value: raw_settings[setting] = raw_value + print("raw_settings", raw_settings, flush=True) return raw_settings diff --git a/src/ui/client/dashboard/components/Builder/RawMode.vue b/src/ui/client/dashboard/components/Builder/Modes.vue similarity index 96% rename from src/ui/client/dashboard/components/Builder/RawMode.vue rename to src/ui/client/dashboard/components/Builder/Modes.vue index 9f36186aa..a6edc1190 100644 --- a/src/ui/client/dashboard/components/Builder/RawMode.vue +++ b/src/ui/client/dashboard/components/Builder/Modes.vue @@ -9,8 +9,8 @@ import ButtonGroup from "@components/Widget/ButtonGroup.vue"; import { useEqualStr } from "@utils/global.js"; /** - * @name Builder/RawMode.vue - * @description This component is lightweight builder containing only the necessary components to create the raw page. + * @name Builder/Modes.vue + * @description This component is lightweight builder containing only the necessary components to create a service mode page. * @example * [ * { diff --git a/src/ui/client/dashboard/components/Form/Raw.vue b/src/ui/client/dashboard/components/Form/Raw.vue index 0253c3bfc..f212b3126 100644 --- a/src/ui/client/dashboard/components/Form/Raw.vue +++ b/src/ui/client/dashboard/components/Form/Raw.vue @@ -103,6 +103,9 @@ function updateRaw(v) { * @returns {string} - The raw string */ function json2raw(json) { + // return nothing case json is empty object + if (Object.keys(json).length === 0) return ""; + let dataStr = JSON.stringify(json); // Remove first and last curly brackets dataStr = dataStr.slice(1, -1); diff --git a/src/ui/client/dashboard/pages/raw/Raw.vue b/src/ui/client/dashboard/pages/modes/Modes.vue similarity index 75% rename from src/ui/client/dashboard/pages/raw/Raw.vue rename to src/ui/client/dashboard/pages/modes/Modes.vue index 3d2de77a9..ab8a15333 100644 --- a/src/ui/client/dashboard/pages/raw/Raw.vue +++ b/src/ui/client/dashboard/pages/modes/Modes.vue @@ -1,16 +1,16 @@ + + diff --git a/src/ui/client/dashboard/pages/raw/raw.js b/src/ui/client/dashboard/pages/modes/modes.js similarity index 83% rename from src/ui/client/dashboard/pages/raw/raw.js rename to src/ui/client/dashboard/pages/modes/modes.js index 0ff759963..9d7a70134 100644 --- a/src/ui/client/dashboard/pages/raw/raw.js +++ b/src/ui/client/dashboard/pages/modes/modes.js @@ -1,11 +1,11 @@ import { createApp } from "vue"; import { createPinia } from "pinia"; import { getI18n } from "@utils/lang.js"; -import Raw from "./Raw.vue"; +import Modes from "./Modes.vue"; const pinia = createPinia(); -createApp(Raw) +createApp(Modes) .use(pinia) .use(getI18n(["dashboard", "action", "inp", "icons", "services", "raw"])) .mount("#app"); diff --git a/src/ui/client/dashboard/pages/raw/index.html b/src/ui/client/dashboard/pages/raw/index.html deleted file mode 100644 index a29b932f9..000000000 --- a/src/ui/client/dashboard/pages/raw/index.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - BunkerWeb | Raw mode - - - - - -
- - - diff --git a/src/ui/client/tests/builder/advanced_mode.py b/src/ui/client/tests/builder/advanced_mode.py new file mode 100644 index 000000000..7f5d97e1e --- /dev/null +++ b/src/ui/client/tests/builder/advanced_mode.py @@ -0,0 +1,40 @@ +import base64 +import json + +from .utils.form import get_forms, get_service_settings + + +def advanced_mode_builder(templates: list[dict], plugins: list, global_config: dict, total_config: dict, service_name: str) -> str: + """Render forms with global config data. + ATM we don't need templates but we need to pass at least one to the function (it will simply not override anything). + """ + + # We need + settings = get_service_settings(service_name, global_config, total_config) + builder = [ + { + "type": "card", + "containerColumns": {"pc": 12, "tablet": 12, "mobile": 12}, + "widgets": [ + { + "type": "Title", + "data": { + "title": service_name, + "type": "container", + "lowercase": True, + }, + }, + { + "type": "Subtitle", + "data": {"subtitle": "services_manage_subtitle", "type": "container", "subtitleClass": "mb-4"}, + }, + { + "type": "Templates", + "data": { + "templates": get_forms(templates, plugins, settings, ("advanced",)), + }, + }, + ], + } + ] + return builder diff --git a/src/ui/client/tests/builder/easy_mode.py b/src/ui/client/tests/builder/easy_mode.py new file mode 100644 index 000000000..cf9832f70 --- /dev/null +++ b/src/ui/client/tests/builder/easy_mode.py @@ -0,0 +1,40 @@ +import base64 +import json + +from .utils.form import get_forms, get_service_settings + + +def easy_mode_builder(templates: list[dict], plugins: list, global_config: dict, total_config: dict, service_name: str) -> str: + """Render forms with global config data. + ATM we don't need templates but we need to pass at least one to the function (it will simply not override anything). + """ + + # We need + settings = get_service_settings(service_name, global_config, total_config) + builder = [ + { + "type": "card", + "containerColumns": {"pc": 12, "tablet": 12, "mobile": 12}, + "widgets": [ + { + "type": "Title", + "data": { + "title": service_name, + "type": "container", + "lowercase": True, + }, + }, + { + "type": "Subtitle", + "data": {"subtitle": "services_manage_subtitle", "type": "container", "subtitleClass": "mb-4"}, + }, + { + "type": "Templates", + "data": { + "templates": get_forms(templates, plugins, settings, ("easy",)), + }, + }, + ], + } + ] + return builder diff --git a/src/ui/client/tests/builder/services.py b/src/ui/client/tests/builder/services.py index 213aefffe..5b1c080a6 100644 --- a/src/ui/client/tests/builder/services.py +++ b/src/ui/client/tests/builder/services.py @@ -263,7 +263,7 @@ def services_action( "size": "normal", "attrs": { "role": "link", - "data-link": f"services/{mode}/{server_name}", + "data-link": f"modes?service_name={server_name}&mode={mode}" if mode != "create" else f"modes?mode={mode}", }, }, ) diff --git a/src/ui/client/tests/builder/utils/form.py b/src/ui/client/tests/builder/utils/form.py index 5317b2b55..11033d27e 100644 --- a/src/ui/client/tests/builder/utils/form.py +++ b/src/ui/client/tests/builder/utils/form.py @@ -106,9 +106,11 @@ def set_raw(template: list, plugins_base: list, settings: dict) -> dict: for plugin in plugins: for setting, value in plugin.get("settings").items(): - # avoid some methods from services_settings - if setting in settings and settings[setting].get("method", "ui") not in ("ui", "default", "manual"): - continue + # we want to show none default value even if this is a disabled method + + # if setting in settings and settings[setting].get("method", "ui") not in ("ui", "default", "manual") and : + # continue + raw_value = None # Start by setting template value if exists @@ -130,6 +132,7 @@ def set_raw(template: list, plugins_base: list, settings: dict) -> dict: if raw_value: raw_settings[setting] = raw_value + print("raw_settings", raw_settings, flush=True) return raw_settings diff --git a/src/ui/client/vite.config.dashboard.js b/src/ui/client/vite.config.dashboard.js index f14fd2745..abac3c0ee 100644 --- a/src/ui/client/vite.config.dashboard.js +++ b/src/ui/client/vite.config.dashboard.js @@ -51,7 +51,7 @@ export default defineConfig({ ), jobs: resolve(__dirname, "./dashboard/pages/jobs/index.html"), services: resolve(__dirname, "./dashboard/pages/services/index.html"), - raw: resolve(__dirname, "./dashboard/pages/raw/index.html"), + modes: resolve(__dirname, "./dashboard/pages/modes/index.html"), }, }, }, diff --git a/src/ui/main.py b/src/ui/main.py index c61437bd9..3b3ac56dd 100644 --- a/src/ui/main.py +++ b/src/ui/main.py @@ -58,6 +58,8 @@ from builder.global_config import global_config_builder from builder.jobs import jobs_builder from builder.services import services_builder from builder.raw_mode import raw_mode_builder +from builder.advanced_mode import advanced_mode_builder +from builder.easy_mode import easy_mode_builder from common_utils import get_version # type: ignore from logger import setup_logger # type: ignore @@ -1278,40 +1280,51 @@ def update_service(config, variables, format_configs, server_name, old_server_na return redirect(url_for("loading", next=url_for(redirect_name, service_name=[server_name]), message=message)) -@app.route("/raw-mode", methods=["GET", "POST"]) +@app.route("/modes", methods=["GET", "POST"]) @login_required -def services_raw(): +def services_modes(): if request.method == "POST": if DB.readonly: return handle_error("Database is in read-only mode", "services") verify_data_in_form( data={"operation": ("edit", "new", "delete")}, - err_message="Invalid operation parameter on /services.", + err_message="Invalid operation parameter on /easy-mode.", redirect_url="services", ) config, variables, format_configs, server_name, old_server_name, operation, is_draft, was_draft, is_draft_unchanged = get_service_data() update_service(config, variables, format_configs, server_name, old_server_name, operation, is_draft, was_draft, is_draft_unchanged, "raw-mode") - if not request.args.get("service_name"): - return handle_error("Service name missing to access raw mode.", "services") + if not request.args.get("mode"): + return handle_error("Mode type is missing to access /modes.", "services") service_name = request.args.get("service_name") + mode = request.args.get("mode") total_config = DB.get_config(methods=True, with_drafts=True) service_names = total_config["SERVER_NAME"]["value"].split(" ") - # Case new service - service_names.append("new") - if service_name not in service_names: - return handle_error("Service name not found to access raw mode.", "services") + if service_name and service_name not in service_names: + return handle_error("Service name not found to access advanced mode.", "services") + + # Case new service + if service_name is None: + service_name = "new" global_config = app.bw_config.get_config(global_only=True, methods=True) plugins = app.bw_config.get_plugins() - data_server_builder = raw_mode_builder(TEMPLATE_PLACEHOLDER, plugins, global_config, total_config, service_name) + data_server_builder = None + if mode == "raw": + data_server_builder = raw_mode_builder(TEMPLATE_PLACEHOLDER, plugins, global_config, total_config, service_name) - return render_template("raw.html", data_server_builder=data_server_builder) + if mode == "advanced": + data_server_builder = advanced_mode_builder(TEMPLATE_PLACEHOLDER, plugins, global_config, total_config, service_name) + + if mode == "easy": + data_server_builder = easy_mode_builder(TEMPLATE_PLACEHOLDER, plugins, global_config, total_config, service_name) + + return render_template("modes.html", data_server_builder=data_server_builder) @app.route("/services", methods=["GET", "POST"]) diff --git a/src/ui/templates/global-config.html b/src/ui/templates/global-config.html index a7782e881..70eb5b8f5 100644 --- a/src/ui/templates/global-config.html +++ b/src/ui/templates/global-config.html @@ -7,10 +7,10 @@ BunkerWeb | Global config - - - - + + + + diff --git a/src/ui/templates/home.html b/src/ui/templates/home.html index 8460748be..c77627aa6 100644 --- a/src/ui/templates/home.html +++ b/src/ui/templates/home.html @@ -7,8 +7,8 @@ BunkerWeb | Home - - + + diff --git a/src/ui/templates/instances.html b/src/ui/templates/instances.html index 68bf306ad..d97854b1f 100644 --- a/src/ui/templates/instances.html +++ b/src/ui/templates/instances.html @@ -7,9 +7,9 @@ BunkerWeb | Instances - - - + + + diff --git a/src/ui/templates/jobs.html b/src/ui/templates/jobs.html index f0bb2bb18..1b0a6d811 100644 --- a/src/ui/templates/jobs.html +++ b/src/ui/templates/jobs.html @@ -7,9 +7,9 @@ BunkerWeb | Jobs - - - + + + diff --git a/src/ui/templates/modes.html b/src/ui/templates/modes.html new file mode 100644 index 000000000..2bac37db9 --- /dev/null +++ b/src/ui/templates/modes.html @@ -0,0 +1,30 @@ + + + + + + + + + BunkerWeb | Raw mode + + + + + + + + + {% set data_server_flash = [] %} + {% with messages = get_flashed_messages(with_categories=true) %} + {% for category, message in messages %} + {% if data_server_flash.append({"type": "error" if category == "error" else "success", "title": "dashboard_error" if category == "error" else "dashboard_success", "message": message}) %}{% endif %} + {% endfor %} + {% endwith %} + + + + +
+ + \ No newline at end of file diff --git a/src/ui/templates/raw.html b/src/ui/templates/raw.html index 84936a1a3..609c31a27 100644 --- a/src/ui/templates/raw.html +++ b/src/ui/templates/raw.html @@ -7,10 +7,10 @@ BunkerWeb | Raw mode - - - - + + + + diff --git a/src/ui/templates/services.html b/src/ui/templates/services.html index 68398cebe..6b037d687 100644 --- a/src/ui/templates/services.html +++ b/src/ui/templates/services.html @@ -7,9 +7,9 @@ BunkerWeb | Services - - - + + +