Implementação de cache para melhoria de performance na navegação Manage time
This commit is contained in:
@@ -169,6 +169,7 @@
|
||||
promise: null,
|
||||
},
|
||||
timeManagementActivityCache: new Map(),
|
||||
timeManagementWeekCache: new Map(),
|
||||
pendingTimeManagementHighlightRowId: "",
|
||||
timeManagementDatePicker: {
|
||||
isOpen: false,
|
||||
|
||||
@@ -125,6 +125,35 @@
|
||||
throw new Error("resourceCurrentUser.resourcePartyId nao esta disponivel.");
|
||||
}
|
||||
|
||||
const cacheKey = getTimeManagementWeekCacheKey(
|
||||
resourcePartyId,
|
||||
normalizedDate
|
||||
);
|
||||
const cachedState = getCachedTimeManagementWeekState(cacheKey);
|
||||
|
||||
if (cachedState) {
|
||||
appState.timeManagementModal = {
|
||||
...cachedState,
|
||||
requestId,
|
||||
selectedDate: normalizedDate,
|
||||
status: "ready",
|
||||
isSaving: false,
|
||||
saveErrorMessage: "",
|
||||
};
|
||||
renderModal();
|
||||
hydrateTimeManagementActivityData({
|
||||
cacheKey,
|
||||
requestId,
|
||||
selectedDate: normalizedDate,
|
||||
serviceRequests: cachedState.serviceRequests || [],
|
||||
srNumbers: getActivityRequestSrNumbers(
|
||||
null,
|
||||
cachedState.serviceRequests || []
|
||||
),
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const weekInfoPayload = await comcipRepository.fetchInfoWeekRequest(
|
||||
normalizedDate
|
||||
);
|
||||
@@ -152,11 +181,15 @@
|
||||
normalizeTimeManagementServiceRequests(srPayload),
|
||||
timeEntryRows
|
||||
);
|
||||
const activitySrNumbers = getActivityRequestSrNumbers(
|
||||
const initialActivitySrNumbers = getInitialActivityRequestSrNumbers(
|
||||
timeEntryRows,
|
||||
serviceRequests
|
||||
);
|
||||
const fullActivitySrNumbers = getActivityRequestSrNumbers(
|
||||
srPayload,
|
||||
serviceRequests
|
||||
);
|
||||
const activityRequest = await fetchCachedActivityRequest(activitySrNumbers);
|
||||
const activityRequest = await fetchCachedActivityRequest(initialActivitySrNumbers);
|
||||
const activityRequestUrl = activityRequest.url;
|
||||
const activityPayload = activityRequest.payload;
|
||||
const activityOptionsBySr = normalizeActivityRequest(
|
||||
@@ -205,7 +238,18 @@
|
||||
isSaving: false,
|
||||
saveErrorMessage: "",
|
||||
};
|
||||
writeCachedTimeManagementWeekState(
|
||||
cacheKey,
|
||||
appState.timeManagementModal
|
||||
);
|
||||
renderModal();
|
||||
hydrateTimeManagementActivityData({
|
||||
cacheKey,
|
||||
requestId,
|
||||
selectedDate: normalizedDate,
|
||||
serviceRequests,
|
||||
srNumbers: fullActivitySrNumbers,
|
||||
});
|
||||
} catch (error) {
|
||||
if (appState.timeManagementModal?.requestId !== requestId) {
|
||||
return;
|
||||
@@ -435,6 +479,7 @@
|
||||
saveErrorMessage: "",
|
||||
};
|
||||
renderModal();
|
||||
hydrateMissingActivityDataForSr(selectedSrNumber);
|
||||
}
|
||||
|
||||
function updateTimeManagementField(fieldName, inputValue, rowId = "") {
|
||||
@@ -679,6 +724,7 @@
|
||||
);
|
||||
}
|
||||
|
||||
appState.timeManagementWeekCache?.clear?.();
|
||||
await loadTimeManagementData(
|
||||
modal.selectedDate || getDateInputValue(new Date())
|
||||
);
|
||||
@@ -821,6 +867,154 @@
|
||||
?.removeAttribute("aria-activedescendant");
|
||||
}
|
||||
|
||||
function getInitialActivityRequestSrNumbers(timeEntryRows, serviceRequests) {
|
||||
const rowSrNumbers = (timeEntryRows || [])
|
||||
.map((row) => cleanString(row?.selectedSrNumber))
|
||||
.filter((srNumber) => /^SR\d+$/i.test(srNumber));
|
||||
|
||||
return rowSrNumbers.length
|
||||
? dedupeSrNumbers(rowSrNumbers)
|
||||
: dedupeSrNumbers((serviceRequests || []).slice(0, 1).map((item) => item.srNumber));
|
||||
}
|
||||
|
||||
function dedupeSrNumbers(srNumbers) {
|
||||
const seen = new Set();
|
||||
|
||||
return (srNumbers || [])
|
||||
.map((srNumber) => cleanString(srNumber).toUpperCase())
|
||||
.filter((srNumber) => /^SR\d+$/i.test(srNumber))
|
||||
.filter((srNumber) => {
|
||||
const key = normalizeString(srNumber);
|
||||
|
||||
if (seen.has(key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
seen.add(key);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
function getTimeManagementWeekCacheKey(resourceId, selectedDate) {
|
||||
return `${cleanString(resourceId)}|${cleanString(selectedDate)}`;
|
||||
}
|
||||
|
||||
function getCachedTimeManagementWeekState(cacheKey) {
|
||||
const cachedState = appState.timeManagementWeekCache?.get?.(cacheKey);
|
||||
|
||||
return cachedState ? cloneTimeManagementState(cachedState) : null;
|
||||
}
|
||||
|
||||
function writeCachedTimeManagementWeekState(cacheKey, state) {
|
||||
if (!cacheKey || !appState.timeManagementWeekCache?.set) {
|
||||
return;
|
||||
}
|
||||
|
||||
appState.timeManagementWeekCache.set(
|
||||
cacheKey,
|
||||
cloneTimeManagementState({
|
||||
...state,
|
||||
requestId: "",
|
||||
isSaving: false,
|
||||
saveErrorMessage: "",
|
||||
highlightRowId: "",
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function cloneTimeManagementState(state) {
|
||||
if (!state) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (typeof structuredClone === "function") {
|
||||
return structuredClone(state);
|
||||
}
|
||||
|
||||
return JSON.parse(JSON.stringify(state));
|
||||
}
|
||||
|
||||
async function hydrateTimeManagementActivityData({
|
||||
cacheKey,
|
||||
requestId,
|
||||
selectedDate,
|
||||
serviceRequests,
|
||||
srNumbers,
|
||||
}) {
|
||||
const fullCacheKey = getActivityRequestCacheKey(srNumbers);
|
||||
|
||||
if (!fullCacheKey) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const activityRequest = await fetchCachedActivityRequest(srNumbers);
|
||||
const activityPayload = activityRequest.payload;
|
||||
const activityOptionsBySr = normalizeActivityRequest(
|
||||
activityPayload,
|
||||
serviceRequests
|
||||
);
|
||||
const activityRequestDetailsBySr = normalizeActivityRequestDetails(
|
||||
activityPayload,
|
||||
serviceRequests
|
||||
);
|
||||
|
||||
if (
|
||||
appState.timeManagementModal?.requestId !== requestId ||
|
||||
cleanString(appState.timeManagementModal?.selectedDate) !== cleanString(selectedDate)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
appState.timeManagementModal = {
|
||||
...appState.timeManagementModal,
|
||||
activityOptionsBySr: {
|
||||
...(appState.timeManagementModal.activityOptionsBySr || {}),
|
||||
...activityOptionsBySr,
|
||||
},
|
||||
activityRequestDetailsBySr: {
|
||||
...(appState.timeManagementModal.activityRequestDetailsBySr || {}),
|
||||
...activityRequestDetailsBySr,
|
||||
},
|
||||
activityRequestUrl: activityRequest.url || appState.timeManagementModal.activityRequestUrl,
|
||||
activityRequestPayload: activityPayload || appState.timeManagementModal.activityRequestPayload,
|
||||
};
|
||||
writeCachedTimeManagementWeekState(cacheKey, appState.timeManagementModal);
|
||||
renderModal();
|
||||
} catch {
|
||||
// Background activity enrichment should not block Manage time usage.
|
||||
}
|
||||
}
|
||||
|
||||
function hydrateMissingActivityDataForSr(srNumber) {
|
||||
const modal = appState.timeManagementModal;
|
||||
const normalizedSrNumber = cleanString(srNumber).toUpperCase();
|
||||
|
||||
if (
|
||||
!modal ||
|
||||
!/^SR\d+$/i.test(normalizedSrNumber) ||
|
||||
getTimeManagementActivityOptions(modal, normalizedSrNumber).some(
|
||||
(option) => cleanString(option?.value)
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
const resourceId = getCurrentUserResourcePartyId();
|
||||
const cacheKey = getTimeManagementWeekCacheKey(
|
||||
resourceId,
|
||||
modal.selectedDate
|
||||
);
|
||||
|
||||
hydrateTimeManagementActivityData({
|
||||
cacheKey,
|
||||
requestId: modal.requestId,
|
||||
selectedDate: modal.selectedDate,
|
||||
serviceRequests: modal.serviceRequests || [],
|
||||
srNumbers: [normalizedSrNumber],
|
||||
});
|
||||
}
|
||||
|
||||
async function fetchCachedActivityRequest(srNumbers) {
|
||||
const cacheKey = getActivityRequestCacheKey(srNumbers);
|
||||
|
||||
|
||||
@@ -254,7 +254,9 @@
|
||||
function getActivityRequestSrNumbers(srPayload, serviceRequests) {
|
||||
const normalizedSrNumbers = [
|
||||
...(serviceRequests || []).map((item) => item.srNumber),
|
||||
...collectSrNumbers(srPayload),
|
||||
...extractArray(srPayload, ["items", "data", "results", "content"]).map(
|
||||
(item) => getFieldValue(item, ["SrNumber", "srNumber"])
|
||||
),
|
||||
];
|
||||
const seen = new Set();
|
||||
|
||||
@@ -384,11 +386,8 @@
|
||||
const preferredRows = ACTIVITY_REQUEST_DETAIL_FIELDS.map((fieldName) =>
|
||||
createActivityRequestDetailRow(fieldName, getActivityRequestDetailValue(item, fieldName))
|
||||
).filter(Boolean);
|
||||
const extraRows = flattenDisplayRecord(item)
|
||||
.map(([fieldName, value]) => createActivityRequestDetailRow(fieldName, value))
|
||||
.filter(Boolean);
|
||||
|
||||
return [...preferredRows, ...extraRows].filter((row) => {
|
||||
return preferredRows.filter((row) => {
|
||||
const key = normalizeActivityRequestDetailKey(row.key);
|
||||
|
||||
if (!key || seen.has(key)) {
|
||||
|
||||
Reference in New Issue
Block a user