feat: 'Block DocTypes' editor button — block any doctype, incl. not on /desk
Adds an edit-mode menu action + dialog to manage a global blocked_doctypes list (Link picker + remove), persisted in the working config and validated server-side. Lets you block doctypes that have no link on the desk. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
17893b06ae
commit
b41d517249
|
|
@ -219,7 +219,16 @@ def _validate_config(cfg: dict) -> dict:
|
|||
if order:
|
||||
entry["order"] = order
|
||||
out_ws[ws_name] = entry
|
||||
return {"version": 1, "workspaces": out_ws}
|
||||
|
||||
out = {"version": 1, "workspaces": out_ws}
|
||||
# Global block list: doctypes blocked anywhere (incl. ones not on /desk).
|
||||
blocked_doctypes = []
|
||||
for dt in cfg.get("blocked_doctypes") or []:
|
||||
if isinstance(dt, str) and dt and dt not in blocked_doctypes:
|
||||
blocked_doctypes.append(dt)
|
||||
if blocked_doctypes:
|
||||
out["blocked_doctypes"] = blocked_doctypes
|
||||
return out
|
||||
|
||||
|
||||
def _write(path: str, cfg: dict):
|
||||
|
|
|
|||
|
|
@ -204,3 +204,31 @@ body.jey-edit .links-widget-box {
|
|||
outline: 1px dashed var(--border-color);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
/* Block DocTypes dialog */
|
||||
.jey-blocked-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 5px 8px;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 6px;
|
||||
margin-bottom: 6px;
|
||||
font-size: 13px;
|
||||
}
|
||||
.jey-blocked-row .dt {
|
||||
flex: 1;
|
||||
font-weight: 500;
|
||||
}
|
||||
.jey-blocked-x {
|
||||
border: none;
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
color: var(--red-500, #e24c4c);
|
||||
font-size: 12px;
|
||||
padding: 2px 6px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.jey-blocked-x:hover {
|
||||
background: var(--red-100, #fce4e4);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@
|
|||
const $fab = $(`
|
||||
<div id="jey-fab">
|
||||
<div class="jey-fab-menu">
|
||||
<button data-act="block">🔒 ${__("Block DocTypes")}</button>
|
||||
<button data-act="export">${__("Export to jey_theme")}</button>
|
||||
<button data-act="reset">${__("Reset to default")}</button>
|
||||
</div>
|
||||
|
|
@ -91,10 +92,64 @@
|
|||
`).appendTo("body");
|
||||
|
||||
$fab.find(".jey-fab-btn").on("click", toggle_edit);
|
||||
$fab.find('[data-act="block"]').on("click", open_block_doctypes_dialog);
|
||||
$fab.find('[data-act="export"]').on("click", do_export);
|
||||
$fab.find('[data-act="reset"]').on("click", do_reset);
|
||||
}
|
||||
|
||||
// Global block list — block any doctype, including ones not present on /desk.
|
||||
function open_block_doctypes_dialog() {
|
||||
let list = (config.blocked_doctypes || []).slice();
|
||||
const d = new frappe.ui.Dialog({
|
||||
title: __("Block DocTypes (anywhere, incl. not on the desk)"),
|
||||
fields: [
|
||||
{ fieldname: "add", label: __("Add a DocType to block"), fieldtype: "Link", options: "DocType" },
|
||||
{ fieldname: "list_html", fieldtype: "HTML" },
|
||||
],
|
||||
primary_action_label: __("Save"),
|
||||
primary_action: async () => {
|
||||
if (list.length) config.blocked_doctypes = list;
|
||||
else delete config.blocked_doctypes;
|
||||
await save_now();
|
||||
d.hide();
|
||||
frappe.show_alert(
|
||||
{ message: __("Saved — “✓ Done editing” to apply the block"), indicator: "green" },
|
||||
5
|
||||
);
|
||||
},
|
||||
});
|
||||
const render = () => {
|
||||
const $w = d.fields_dict.list_html.$wrapper;
|
||||
$w.empty();
|
||||
if (!list.length) {
|
||||
$w.html(`<div class="text-muted" style="padding:6px 0">${__("No blocked doctypes yet.")}</div>`);
|
||||
return;
|
||||
}
|
||||
list.forEach((dt, i) => {
|
||||
const $row = $(
|
||||
`<div class="jey-blocked-row">🔒 <span class="dt"></span>` +
|
||||
`<button type="button" class="jey-blocked-x" title="${__("Remove")}">✕</button></div>`
|
||||
);
|
||||
$row.find(".dt").text(dt);
|
||||
$row.find(".jey-blocked-x").on("click", () => {
|
||||
list.splice(i, 1);
|
||||
render();
|
||||
});
|
||||
$w.append($row);
|
||||
});
|
||||
};
|
||||
d.fields_dict.add.df.onchange = () => {
|
||||
const v = d.get_value("add");
|
||||
if (v) {
|
||||
if (!list.includes(v)) list.push(v);
|
||||
d.set_value("add", "");
|
||||
render();
|
||||
}
|
||||
};
|
||||
render();
|
||||
d.show();
|
||||
}
|
||||
|
||||
function update_fab() {
|
||||
const $fab = $("#jey-fab");
|
||||
$fab.toggleClass("on", editing);
|
||||
|
|
|
|||
Loading…
Reference in New Issue