634 lines
24 KiB
JavaScript
634 lines
24 KiB
JavaScript
(() => {
|
||
function create(dependencies) {
|
||
const {
|
||
appState,
|
||
escapeHtml,
|
||
cleanString,
|
||
normalizeString,
|
||
formatDateInputDisplay,
|
||
getDateInputValue,
|
||
formatHours,
|
||
getWeekStartDate,
|
||
getLocalDateKey,
|
||
getTimeManagementDayKey,
|
||
isTimeManagementSaveEnabled,
|
||
getTimeManagementRows,
|
||
getTimeManagementActivityOptions,
|
||
findTimeManagementServiceRequestByNumber,
|
||
formatTimeManagementServiceRequestLabel,
|
||
isNonServiceRequestSrNumber,
|
||
findOptionValue,
|
||
findOptionLabel,
|
||
getTimeManagementTaskTypeOptions,
|
||
formatTimeManagementHourPayloadValue,
|
||
} = dependencies;
|
||
|
||
function renderTimeManagementModal() {
|
||
const modal = appState.timeManagementModal;
|
||
|
||
if (!modal) {
|
||
return "";
|
||
}
|
||
|
||
const selectedDate = modal.selectedDate || getDateInputValue(new Date());
|
||
const selectedDateLabel = formatDateInputDisplay(selectedDate);
|
||
const canSaveTimeManagement = isTimeManagementSaveEnabled(modal);
|
||
const isSavingTimeManagement = Boolean(modal.isSaving);
|
||
|
||
return `
|
||
<div class="arch-panel-extension-detail-overlay">
|
||
<div class="arch-panel-extension-time-management-dialog" role="document">
|
||
<header class="arch-panel-extension-detail-head">
|
||
<div>
|
||
<p class="arch-panel-extension-panel-label">Horas apontadas</p>
|
||
<h3 class="arch-panel-extension-panel-title">Manage time</h3>
|
||
</div>
|
||
</header>
|
||
|
||
<div class="arch-panel-extension-time-management-toolbar">
|
||
<label class="arch-panel-extension-form-field">
|
||
<span>Selected date</span>
|
||
<span class="arch-panel-extension-date-picker">
|
||
<button
|
||
type="button"
|
||
class="arch-panel-extension-date-step-button"
|
||
data-action="time-management-date-week-prev"
|
||
aria-label="Previous week"
|
||
>
|
||
<svg viewBox="0 0 20 20" aria-hidden="true" focusable="false">
|
||
<path d="M12.78 4.22a.75.75 0 0 1 0 1.06L8.06 10l4.72 4.72a.75.75 0 1 1-1.06 1.06l-5.25-5.25a.75.75 0 0 1 0-1.06l5.25-5.25a.75.75 0 0 1 1.06 0Z"></path>
|
||
</svg>
|
||
</button>
|
||
<span class="arch-panel-extension-date-input-shell">
|
||
<button
|
||
type="button"
|
||
class="arch-panel-extension-date-picker-button"
|
||
data-action="open-time-management-date-picker"
|
||
aria-label="Open calendar"
|
||
>
|
||
<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
|
||
<path d="M7 2a1 1 0 0 1 1 1v1h8V3a1 1 0 1 1 2 0v1h1.25A2.75 2.75 0 0 1 22 6.75v11.5A2.75 2.75 0 0 1 19.25 21H4.75A2.75 2.75 0 0 1 2 18.25V6.75A2.75 2.75 0 0 1 4.75 4H6V3a1 1 0 0 1 1-1ZM4.5 9.5v8.75c0 .69.56 1.25 1.25 1.25h12.5c.69 0 1.25-.56 1.25-1.25V9.5h-15Zm1.25-4c-.69 0-1.25.56-1.25 1.25V8h15V6.75c0-.69-.56-1.25-1.25-1.25H17v.5a1 1 0 1 1-2 0v-.5H9v.5a1 1 0 0 1-2 0v-.5H5.75Z"></path>
|
||
</svg>
|
||
</button>
|
||
<input
|
||
type="text"
|
||
value="${escapeHtml(selectedDateLabel)}"
|
||
aria-label="Selected date"
|
||
readonly
|
||
>
|
||
${renderTimeManagementDatePicker(selectedDate)}
|
||
</span>
|
||
<button
|
||
type="button"
|
||
class="arch-panel-extension-date-step-button"
|
||
data-action="time-management-date-week-next"
|
||
aria-label="Next week"
|
||
>
|
||
<svg viewBox="0 0 20 20" aria-hidden="true" focusable="false">
|
||
<path d="M7.22 15.78a.75.75 0 0 1 0-1.06L11.94 10 7.22 5.28a.75.75 0 0 1 1.06-1.06l5.25 5.25a.75.75 0 0 1 0 1.06l-5.25 5.25a.75.75 0 0 1-1.06 0Z"></path>
|
||
</svg>
|
||
</button>
|
||
</span>
|
||
</label>
|
||
${renderTimeManagementHourIndicators(modal)}
|
||
</div>
|
||
|
||
${renderTimeManagementBody(modal)}
|
||
|
||
<div class="arch-panel-extension-detail-actions">
|
||
<div class="arch-panel-extension-time-management-footer-actions">
|
||
<button
|
||
type="button"
|
||
class="arch-panel-extension-utility-button"
|
||
data-action="time-management-add-sr"
|
||
>
|
||
Add SR
|
||
</button>
|
||
<button
|
||
type="button"
|
||
class="arch-panel-extension-utility-button"
|
||
data-action="time-management-add-non-service"
|
||
>
|
||
Add (Non-service)
|
||
</button>
|
||
<button
|
||
type="button"
|
||
class="arch-panel-extension-utility-button is-outline"
|
||
data-action="time-management-save"
|
||
${canSaveTimeManagement && !isSavingTimeManagement ? "" : "disabled"}
|
||
>
|
||
${isSavingTimeManagement ? "Gravando..." : "Gravar"}
|
||
</button>
|
||
</div>
|
||
${
|
||
modal.saveErrorMessage
|
||
? `<p class="arch-panel-extension-time-management-save-error">${escapeHtml(modal.saveErrorMessage)}</p>`
|
||
: ""
|
||
}
|
||
<button
|
||
type="button"
|
||
class="arch-panel-extension-close"
|
||
data-action="close-time-management"
|
||
aria-label="Fechar apontamento de horas"
|
||
>
|
||
Fechar
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
`;
|
||
}
|
||
|
||
function renderTimeManagementBody(modal) {
|
||
if (modal.status === "loading") {
|
||
return renderTimeManagementSkeleton();
|
||
}
|
||
|
||
if (modal.status === "error") {
|
||
return `
|
||
<div class="arch-panel-extension-time-management-card is-error">
|
||
<p class="arch-panel-extension-summary-label">Erro na requisição</p>
|
||
<p class="arch-panel-extension-detail-subtitle">${escapeHtml(
|
||
modal.errorMessage || "Não foi possÃvel carregar o apontamento."
|
||
)}</p>
|
||
</div>
|
||
`;
|
||
}
|
||
|
||
const rows = getTimeManagementRows(modal);
|
||
|
||
return `
|
||
<div class="arch-panel-extension-time-management-card">
|
||
${renderTimeManagementHeaderRow(modal.weekDays || [])}
|
||
<div class="arch-panel-extension-time-management-rows">
|
||
${
|
||
rows.length
|
||
? rows.map((row, index) => renderTimeManagementEntryRow(modal, row, index)).join("")
|
||
: `<div class="arch-panel-extension-empty-state arch-panel-extension-time-management-empty">
|
||
Nenhum apontamento de hora neste período
|
||
</div>`
|
||
}
|
||
</div>
|
||
</div>
|
||
`;
|
||
}
|
||
|
||
function renderTimeManagementHeaderRow(weekDays) {
|
||
return `
|
||
<div class="arch-panel-extension-time-management-header-row" aria-hidden="true">
|
||
<span class="arch-panel-extension-time-management-column-label">Service Request</span>
|
||
<span class="arch-panel-extension-time-management-column-label">Activity</span>
|
||
<span class="arch-panel-extension-time-management-column-label">Task Type</span>
|
||
${(weekDays || []).map((day) => renderTimeManagementDayHeader(day)).join("")}
|
||
<span class="arch-panel-extension-time-management-column-label" aria-label="Actions"></span>
|
||
</div>
|
||
`;
|
||
}
|
||
|
||
function renderTimeManagementDayHeader(day) {
|
||
return `
|
||
<span class="arch-panel-extension-time-management-day-head">
|
||
<strong>${escapeHtml(day.dayLabel || "-")}</strong>
|
||
<span>${escapeHtml(day.monthLabel || day.date || "-")}</span>
|
||
</span>
|
||
`;
|
||
}
|
||
|
||
function renderTimeManagementEntryRow(modal, row, index) {
|
||
const rowId = cleanString(row?.id) || `row-${index}`;
|
||
const isHighlighted =
|
||
cleanString(modal?.highlightRowId) &&
|
||
cleanString(modal?.highlightRowId) === rowId;
|
||
const selectedSr = cleanString(row?.selectedSrNumber);
|
||
const activityOptions = getTimeManagementActivityOptions(modal, selectedSr);
|
||
const selectedSrOption = findTimeManagementServiceRequestByNumber(
|
||
modal,
|
||
selectedSr
|
||
);
|
||
const isNonServiceRequest = isNonServiceRequestSrNumber(selectedSr);
|
||
const selectedSrLabel =
|
||
selectedSrOption?.label ||
|
||
formatTimeManagementServiceRequestLabel(selectedSrOption) ||
|
||
selectedSr;
|
||
const selectedActivityValue =
|
||
findOptionValue(activityOptions, row?.selectedActivityValue) ||
|
||
cleanString(row?.selectedActivityValue) ||
|
||
"";
|
||
const selectedActivityLabel =
|
||
findOptionLabel(activityOptions, selectedActivityValue) || selectedActivityValue;
|
||
const taskTypeOptions = getTimeManagementTaskTypeOptions(modal, selectedSr);
|
||
const selectedTaskTypeValue =
|
||
findOptionValue(taskTypeOptions, row?.selectedTaskTypeValue) ||
|
||
cleanString(row?.selectedTaskTypeValue) ||
|
||
"";
|
||
const selectedTaskTypeLabel =
|
||
findOptionLabel(taskTypeOptions, selectedTaskTypeValue) || selectedTaskTypeValue;
|
||
|
||
return `
|
||
<div class="arch-panel-extension-time-management-entry-row is-compact${isHighlighted ? " is-duplicate-highlight" : ""}" data-row-id="${escapeHtml(rowId)}">
|
||
<input type="hidden" name="timeEntryId" value="${escapeHtml(row?.timeEntryId || "")}">
|
||
<label class="arch-panel-extension-form-field">
|
||
${renderSearchableCombobox({
|
||
field: "sr",
|
||
rowId,
|
||
selectedValue: selectedSr,
|
||
value: selectedSrLabel,
|
||
placeholder: "Search SR",
|
||
options: modal.serviceRequests || [],
|
||
valueKey: "srNumber",
|
||
labelKey: "label",
|
||
fallbackLabelKey: "srTitle",
|
||
disabled: isNonServiceRequest,
|
||
})}
|
||
</label>
|
||
<label class="arch-panel-extension-form-field">
|
||
${renderSearchableCombobox({
|
||
field: "activity",
|
||
rowId,
|
||
selectedValue: selectedActivityValue,
|
||
value: selectedActivityLabel,
|
||
placeholder: "Search activity",
|
||
options: activityOptions,
|
||
valueKey: "value",
|
||
labelKey: "label",
|
||
metaKey: "value",
|
||
disabled: isNonServiceRequest,
|
||
})}
|
||
</label>
|
||
<label class="arch-panel-extension-form-field">
|
||
${renderSearchableCombobox({
|
||
field: "taskType",
|
||
rowId,
|
||
selectedValue: selectedTaskTypeValue,
|
||
value: selectedTaskTypeLabel,
|
||
placeholder: "Search task type",
|
||
options: taskTypeOptions,
|
||
valueKey: "value",
|
||
labelKey: "label",
|
||
})}
|
||
</label>
|
||
${(modal.weekDays || [])
|
||
.map((day) =>
|
||
renderTimeManagementDayInput(day, rowId, row?.dayHours)
|
||
)
|
||
.join("")}
|
||
<button
|
||
type="button"
|
||
class="arch-panel-extension-time-management-delete"
|
||
data-action="time-management-remove-row"
|
||
data-row-id="${escapeHtml(rowId)}"
|
||
aria-label="Remover linha de apontamento"
|
||
title="Remover linha"
|
||
>
|
||
<svg viewBox="0 0 20 20" aria-hidden="true" focusable="false">
|
||
<path d="M7.5 2.5A1.5 1.5 0 0 1 9 1h2a1.5 1.5 0 0 1 1.5 1.5V3H16a.75.75 0 0 1 0 1.5h-.72l-.67 11.33A2.25 2.25 0 0 1 12.36 18H7.64a2.25 2.25 0 0 1-2.25-2.17L4.72 4.5H4A.75.75 0 0 1 4 3h3.5v-.5ZM9 3h2v-.5H9V3Zm-2.78 1.5.66 11.24c.02.42.36.76.76.76h4.72c.4 0 .74-.34.76-.76l.66-11.24H6.22Zm2.53 2.25c.41 0 .75.34.75.75v6a.75.75 0 0 1-1.5 0v-6c0-.41.34-.75.75-.75Zm3.25.75a.75.75 0 0 0-1.5 0v6a.75.75 0 0 0 1.5 0v-6Z"></path>
|
||
</svg>
|
||
</button>
|
||
</div>
|
||
`;
|
||
}
|
||
|
||
function renderTimeManagementSkeleton() {
|
||
return `
|
||
<div class="arch-panel-extension-time-management-card" aria-busy="true">
|
||
<div class="arch-panel-extension-time-management-header-row">
|
||
${["Service Request", "Activity", "Task Type"]
|
||
.map(
|
||
(label) =>
|
||
`<span class="arch-panel-extension-time-management-column-label">${label}</span>`
|
||
)
|
||
.join("")}
|
||
${Array.from({ length: 7 }, () => `
|
||
<span class="arch-panel-extension-time-management-day-head">
|
||
<span class="arch-panel-extension-skeleton arch-panel-extension-skeleton-title"></span>
|
||
<span class="arch-panel-extension-skeleton arch-panel-extension-skeleton-text"></span>
|
||
</span>
|
||
`).join("")}
|
||
<span></span>
|
||
</div>
|
||
<div class="arch-panel-extension-time-management-entry-row">
|
||
${Array.from({ length: 3 }, () => `
|
||
<div class="arch-panel-extension-form-field">
|
||
<span class="arch-panel-extension-skeleton arch-panel-extension-skeleton-control"></span>
|
||
</div>
|
||
`).join("")}
|
||
${Array.from({ length: 7 }, () => `
|
||
<div class="arch-panel-extension-time-management-day">
|
||
<span class="arch-panel-extension-skeleton arch-panel-extension-skeleton-input"></span>
|
||
</div>
|
||
`).join("")}
|
||
<span></span>
|
||
</div>
|
||
</div>
|
||
`;
|
||
}
|
||
|
||
function renderSearchableCombobox({
|
||
field,
|
||
rowId,
|
||
selectedValue,
|
||
value,
|
||
placeholder,
|
||
options,
|
||
valueKey,
|
||
labelKey,
|
||
fallbackLabelKey,
|
||
metaKey,
|
||
disabled = false,
|
||
}) {
|
||
const safeField = escapeHtml(field);
|
||
const safeRowId = escapeHtml(rowId || "");
|
||
const isDisabled = Boolean(disabled);
|
||
const normalizedSelectedValue = normalizeString(selectedValue);
|
||
const normalizedOptions = (options || [])
|
||
.map((item) => ({
|
||
value: cleanString(item?.[valueKey]),
|
||
label:
|
||
cleanString(item?.[labelKey]) ||
|
||
cleanString(item?.[fallbackLabelKey]) ||
|
||
cleanString(item?.[valueKey]),
|
||
meta: cleanString(item?.[metaKey]),
|
||
}))
|
||
.filter((item) => item.value || item.label);
|
||
|
||
return `
|
||
<span class="arch-panel-extension-combobox${isDisabled ? " is-disabled" : ""}" data-combobox-field="${safeField}" data-row-id="${safeRowId}">
|
||
<span class="arch-panel-extension-combobox-value" title="${escapeHtml(value || "")}">
|
||
${escapeHtml(value || placeholder || "")}
|
||
</span>
|
||
<input
|
||
type="search"
|
||
value=""
|
||
placeholder="${escapeHtml(placeholder || "")}"
|
||
data-combobox-field="${safeField}"
|
||
data-row-id="${safeRowId}"
|
||
autocomplete="off"
|
||
spellcheck="false"
|
||
role="combobox"
|
||
aria-autocomplete="list"
|
||
aria-expanded="false"
|
||
${isDisabled ? "disabled" : ""}
|
||
>
|
||
<span class="arch-panel-extension-combobox-arrow" aria-hidden="true">
|
||
<svg viewBox="0 0 20 20" focusable="false">
|
||
<path d="M5.23 7.21a.75.75 0 0 1 1.06.02L10 11.16l3.71-3.93a.75.75 0 1 1 1.08 1.04l-4.25 4.5a.75.75 0 0 1-1.08 0l-4.25-4.5a.75.75 0 0 1 .02-1.06Z"></path>
|
||
</svg>
|
||
</span>
|
||
<span class="arch-panel-extension-combobox-menu" role="listbox">
|
||
${
|
||
normalizedOptions.length
|
||
? normalizedOptions
|
||
.map(
|
||
(item, index) => {
|
||
const isSelected =
|
||
normalizedSelectedValue &&
|
||
normalizeString(item.value) === normalizedSelectedValue;
|
||
const meta =
|
||
item.meta && normalizeString(item.meta) !== normalizeString(item.label)
|
||
? item.meta
|
||
: "";
|
||
const optionId = `arch-panel-extension-combobox-${safeField}-${index}`;
|
||
|
||
return `
|
||
<button
|
||
id="${optionId}"
|
||
type="button"
|
||
class="arch-panel-extension-combobox-option${isSelected ? " is-selected" : ""}"
|
||
data-action="time-management-combobox-option"
|
||
data-field="${safeField}"
|
||
data-row-id="${safeRowId}"
|
||
data-value="${escapeHtml(item.value)}"
|
||
data-search="${escapeHtml(`${item.label} ${item.value}`.toLowerCase())}"
|
||
role="option"
|
||
aria-selected="${isSelected ? "true" : "false"}"
|
||
>
|
||
<span class="arch-panel-extension-combobox-option-main">
|
||
${escapeHtml(item.label || item.value)}
|
||
</span>
|
||
${
|
||
meta
|
||
? `<span class="arch-panel-extension-combobox-option-meta">${escapeHtml(meta)}</span>`
|
||
: ""
|
||
}
|
||
</button>
|
||
`;
|
||
}
|
||
)
|
||
.join("")
|
||
: `<span class="arch-panel-extension-combobox-empty">No options</span>`
|
||
}
|
||
</span>
|
||
</span>
|
||
`;
|
||
}
|
||
|
||
function renderTimeManagementDatePicker(selectedDate) {
|
||
const picker = appState.timeManagementDatePicker;
|
||
|
||
if (!picker.isOpen) {
|
||
return "";
|
||
}
|
||
|
||
const monthStart = new Date(picker.year, picker.month, 1);
|
||
const calendarStart = getWeekStartDate(monthStart);
|
||
const selectedDateKey = getLocalDateKey(selectedDate);
|
||
const todayKey = getLocalDateKey(new Date());
|
||
const monthLabel = new Intl.DateTimeFormat("en-US", {
|
||
month: "long",
|
||
year: "numeric",
|
||
}).format(monthStart);
|
||
const days = Array.from({ length: 42 }, (_, index) => {
|
||
const date = new Date(calendarStart);
|
||
date.setDate(calendarStart.getDate() + index);
|
||
const dateKey = getLocalDateKey(date);
|
||
const className = [
|
||
"arch-panel-extension-date-picker-day",
|
||
date.getMonth() === picker.month ? "" : "is-muted",
|
||
dateKey === todayKey ? "is-today" : "",
|
||
dateKey === selectedDateKey ? "is-selected" : "",
|
||
]
|
||
.filter(Boolean)
|
||
.join(" ");
|
||
|
||
return `
|
||
<button
|
||
type="button"
|
||
class="${className}"
|
||
data-action="time-management-date-picker-select"
|
||
data-date-value="${escapeHtml(dateKey)}"
|
||
>
|
||
${date.getDate()}
|
||
</button>
|
||
`;
|
||
});
|
||
|
||
return `
|
||
<div class="arch-panel-extension-date-picker-popover">
|
||
<div class="arch-panel-extension-date-picker-head">
|
||
<button
|
||
type="button"
|
||
class="arch-panel-extension-calendar-nav"
|
||
data-action="time-management-date-picker-prev"
|
||
aria-label="Previous month"
|
||
>
|
||
‹
|
||
</button>
|
||
<strong>${escapeHtml(monthLabel)}</strong>
|
||
<button
|
||
type="button"
|
||
class="arch-panel-extension-calendar-nav"
|
||
data-action="time-management-date-picker-next"
|
||
aria-label="Next month"
|
||
>
|
||
›
|
||
</button>
|
||
</div>
|
||
<div class="arch-panel-extension-date-picker-weekdays">
|
||
${["S", "M", "T", "W", "T", "F", "S"].map((day) => `<span>${day}</span>`).join("")}
|
||
</div>
|
||
<div class="arch-panel-extension-date-picker-grid">
|
||
${days.join("")}
|
||
</div>
|
||
</div>
|
||
`;
|
||
}
|
||
|
||
function renderTimeManagementHourIndicators(modal) {
|
||
if (modal?.status === "loading") {
|
||
return `
|
||
<div class="arch-panel-extension-time-management-hour-indicators" aria-label="Resumo de horas apontadas" aria-busy="true">
|
||
${Array.from({ length: 4 }, () => `
|
||
<span class="arch-panel-extension-time-management-hour-indicator">
|
||
<span class="arch-panel-extension-skeleton arch-panel-extension-skeleton-text"></span>
|
||
<strong class="arch-panel-extension-skeleton arch-panel-extension-skeleton-title"></strong>
|
||
</span>
|
||
`).join("")}
|
||
</div>
|
||
`;
|
||
}
|
||
|
||
return `
|
||
<div class="arch-panel-extension-time-management-hour-indicators" aria-label="Resumo de horas apontadas">
|
||
${buildTimeManagementHourIndicators(modal)
|
||
.map(
|
||
(indicator) => `
|
||
<span class="arch-panel-extension-time-management-hour-indicator">
|
||
<span>${escapeHtml(indicator.label)}</span>
|
||
<strong>${escapeHtml(formatHours(indicator.value))}</strong>
|
||
</span>
|
||
`
|
||
)
|
||
.join("")}
|
||
</div>
|
||
`;
|
||
}
|
||
|
||
function buildTimeManagementHourIndicators(modal) {
|
||
const totals = getTimeManagementRows(modal).reduce(
|
||
(accumulator, row) => {
|
||
const rowTotal = getTimeManagementRowTotalHours(row);
|
||
const category = getTimeManagementHourCategory(modal, row);
|
||
|
||
accumulator[category] += rowTotal;
|
||
accumulator.total += rowTotal;
|
||
|
||
return accumulator;
|
||
},
|
||
{
|
||
service: 0,
|
||
nonService: 0,
|
||
timeOff: 0,
|
||
total: 0,
|
||
}
|
||
);
|
||
|
||
return [
|
||
{ label: "Service", value: totals.service },
|
||
{ label: "Non Service", value: totals.nonService },
|
||
{ label: "Time Off", value: totals.timeOff },
|
||
{ label: "Total hours", value: totals.total },
|
||
];
|
||
}
|
||
|
||
function getTimeManagementRowTotalHours(row) {
|
||
return Object.values(row?.dayHours || {}).reduce(
|
||
(sum, value) => sum + formatTimeManagementHourPayloadValue(value),
|
||
0
|
||
);
|
||
}
|
||
|
||
function getTimeManagementHourCategory(modal, row) {
|
||
if (isTimeManagementTimeOffRow(modal, row)) {
|
||
return "timeOff";
|
||
}
|
||
|
||
return isNonServiceRequestSrNumber(row?.selectedSrNumber)
|
||
? "nonService"
|
||
: "service";
|
||
}
|
||
|
||
function isTimeManagementTimeOffRow(modal, row) {
|
||
const taskTypeValue = cleanString(row?.selectedTaskTypeValue);
|
||
const taskType = findTimeManagementTaskTypeByValue(modal, taskTypeValue);
|
||
const candidates = [
|
||
taskTypeValue,
|
||
taskType?.label,
|
||
taskType?.tags,
|
||
].map((value) => normalizeString(value));
|
||
|
||
return candidates.some(
|
||
(value) =>
|
||
value === "TIME_OFF" ||
|
||
value === "TIMEOFF" ||
|
||
value.includes("TIME_OFF") ||
|
||
value.includes("TIME OFF")
|
||
);
|
||
}
|
||
|
||
function findTimeManagementTaskTypeByValue(modal, value) {
|
||
const normalizedValue = normalizeString(value);
|
||
|
||
if (!normalizedValue) {
|
||
return null;
|
||
}
|
||
|
||
return (modal?.taskTypes || []).find(
|
||
(item) => normalizeString(item?.value) === normalizedValue
|
||
) || null;
|
||
}
|
||
|
||
function renderTimeManagementDayInput(
|
||
day,
|
||
rowId = "",
|
||
dayHours = {}
|
||
) {
|
||
const dateKey = getTimeManagementDayKey(day);
|
||
const value = cleanString(dayHours?.[dateKey]);
|
||
|
||
return `
|
||
<label class="arch-panel-extension-time-management-day">
|
||
<input
|
||
type="number"
|
||
min="0"
|
||
step="1"
|
||
value="${escapeHtml(value)}"
|
||
placeholder="0"
|
||
data-action="time-management-hours-change"
|
||
data-row-id="${escapeHtml(rowId || "")}"
|
||
data-date-key="${escapeHtml(dateKey)}"
|
||
aria-label="Horas apontadas em ${escapeHtml(day.date || "")}"
|
||
>
|
||
</label>
|
||
`;
|
||
}
|
||
|
||
return {
|
||
renderTimeManagementModal,
|
||
};
|
||
}
|
||
|
||
globalThis.ArchPanelManageTimeView = Object.freeze({
|
||
create,
|
||
});
|
||
})();
|