Replaced labels with icons in the SR and Action badges
This commit is contained in:
111
src/features/opportunities/workload-action-form.js
Normal file
111
src/features/opportunities/workload-action-form.js
Normal file
@@ -0,0 +1,111 @@
|
||||
function createWorkloadActionForm({ MODAL_ID, allowsCrmActivities, isMissingAction, getOpportunity, formatDate, createCloseIcon, environment }) {
|
||||
const { document } = environment;
|
||||
let active = null;
|
||||
function element(tag, className, text) {
|
||||
const node = document.createElement(tag);
|
||||
if (className) node.className = className;
|
||||
if (text !== undefined) node.textContent = text;
|
||||
return node;
|
||||
}
|
||||
function close(restoreFocus = true) {
|
||||
if (!active) return false;
|
||||
const previous = active;
|
||||
active = null;
|
||||
previous.modal.remove();
|
||||
if (restoreFocus && previous.trigger?.isConnected) previous.trigger.focus();
|
||||
return true;
|
||||
}
|
||||
function createButton(optyNumber) {
|
||||
const button = element("button", "opportunities-extension-add-action", "+");
|
||||
button.type = "button";
|
||||
button.title = "Add Action";
|
||||
button.setAttribute("aria-label", `Add Action for ${optyNumber}`);
|
||||
button.setAttribute("aria-haspopup", "dialog");
|
||||
button.addEventListener("click", event => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
open(optyNumber, button);
|
||||
});
|
||||
return button;
|
||||
}
|
||||
function open(optyNumber, trigger) {
|
||||
if (!allowsCrmActivities() || !isMissingAction(optyNumber)) return;
|
||||
const host = document.getElementById(MODAL_ID);
|
||||
if (!host || host.hidden) return;
|
||||
close(false);
|
||||
const modal = element("section", "opportunities-extension-action-form-modal");
|
||||
modal.setAttribute("role", "dialog");
|
||||
modal.setAttribute("aria-modal", "true");
|
||||
modal.setAttribute("aria-labelledby", "opportunities-extension-action-form-title");
|
||||
const dialog = element("div", "opportunities-extension-action-form-dialog");
|
||||
const header = element("header", "opportunities-extension-account-plans-header");
|
||||
const heading = element("div", "opportunities-extension-action-form-heading");
|
||||
const title = element("h2", "", "Add Action");
|
||||
title.id = "opportunities-extension-action-form-title";
|
||||
heading.append(title, element("p", "", String(optyNumber)));
|
||||
const opportunity = getOpportunity(optyNumber);
|
||||
const details = element("dl", "opportunities-extension-action-form-context");
|
||||
for (const [label, value] of [
|
||||
["Customer", opportunity?.CustomerAccount?.PartyUniqueName],
|
||||
["Name", opportunity?.Name],
|
||||
["Close Date", formatDate(opportunity?.EffectiveDate)]
|
||||
]) {
|
||||
details.append(element("dt", "", label), element("dd", "", value == null || value === "" ? "-" : String(value)));
|
||||
}
|
||||
heading.append(details);
|
||||
const dismiss = element("button", "opportunities-extension-icon-button");
|
||||
dismiss.type = "button";
|
||||
dismiss.title = "Close";
|
||||
dismiss.setAttribute("aria-label", "Close Action form");
|
||||
dismiss.append(createCloseIcon());
|
||||
dismiss.addEventListener("click", () => close());
|
||||
header.append(heading, dismiss);
|
||||
const form = element("form", "opportunities-extension-action-form");
|
||||
// Form-only version: never submit or navigate until the API contract is provided.
|
||||
form.addEventListener("submit", event => event.preventDefault());
|
||||
const fields = [];
|
||||
for (const [name, label, type] of [
|
||||
["team", "Team", "text"], ["startDate", "Start date", "date"],
|
||||
["endDate", "End Date", "date"], ["status", "Status", "text"],
|
||||
["complexity", "Complexity", "text"], ["notes", "Notes", "textarea"]
|
||||
]) {
|
||||
const field = element("label", "opportunities-extension-action-form-field");
|
||||
const input = element(type === "textarea" ? "textarea" : "input");
|
||||
if (type !== "textarea") input.type = type;
|
||||
else input.rows = 5;
|
||||
input.name = name;
|
||||
input.id = `opportunities-extension-action-form-${name}`;
|
||||
field.htmlFor = input.id;
|
||||
if (name === "notes" || name === "team") field.className += " opportunities-extension-action-form-wide";
|
||||
field.append(element("span", "", label), input);
|
||||
form.append(field);
|
||||
fields.push(input);
|
||||
}
|
||||
const footer = element("footer", "opportunities-extension-action-form-footer");
|
||||
const save = element("button", "opportunities-extension-action-form-save", "Save");
|
||||
save.type = "submit";
|
||||
save.disabled = true;
|
||||
save.title = "Gravacao ainda nao disponivel";
|
||||
const cancel = element("button", "", "Cancel");
|
||||
cancel.type = "button";
|
||||
cancel.addEventListener("click", () => close());
|
||||
footer.append(save, cancel);
|
||||
form.append(footer);
|
||||
dialog.append(header, form);
|
||||
modal.append(dialog);
|
||||
host.append(modal);
|
||||
active = { modal, trigger };
|
||||
modal.addEventListener("click", event => { if (event.target === modal) close(); });
|
||||
modal.addEventListener("keydown", event => {
|
||||
if (event.key !== "Tab") return;
|
||||
const controls = [dismiss, ...fields, cancel];
|
||||
const index = controls.indexOf(document.activeElement);
|
||||
if (index === -1 || (!event.shiftKey && index === controls.length - 1) || (event.shiftKey && index === 0)) {
|
||||
event.preventDefault();
|
||||
controls[event.shiftKey ? controls.length - 1 : 0].focus();
|
||||
}
|
||||
});
|
||||
fields[0].focus();
|
||||
}
|
||||
return { createButton, open, close };
|
||||
}
|
||||
Reference in New Issue
Block a user