Implementação de cache para melhoria de performance na navegação Manage time
This commit is contained in:
@@ -169,6 +169,7 @@
|
|||||||
promise: null,
|
promise: null,
|
||||||
},
|
},
|
||||||
timeManagementActivityCache: new Map(),
|
timeManagementActivityCache: new Map(),
|
||||||
|
timeManagementWeekCache: new Map(),
|
||||||
pendingTimeManagementHighlightRowId: "",
|
pendingTimeManagementHighlightRowId: "",
|
||||||
timeManagementDatePicker: {
|
timeManagementDatePicker: {
|
||||||
isOpen: false,
|
isOpen: false,
|
||||||
|
|||||||
@@ -125,6 +125,35 @@
|
|||||||
throw new Error("resourceCurrentUser.resourcePartyId nao esta disponivel.");
|
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(
|
const weekInfoPayload = await comcipRepository.fetchInfoWeekRequest(
|
||||||
normalizedDate
|
normalizedDate
|
||||||
);
|
);
|
||||||
@@ -152,11 +181,15 @@
|
|||||||
normalizeTimeManagementServiceRequests(srPayload),
|
normalizeTimeManagementServiceRequests(srPayload),
|
||||||
timeEntryRows
|
timeEntryRows
|
||||||
);
|
);
|
||||||
const activitySrNumbers = getActivityRequestSrNumbers(
|
const initialActivitySrNumbers = getInitialActivityRequestSrNumbers(
|
||||||
|
timeEntryRows,
|
||||||
|
serviceRequests
|
||||||
|
);
|
||||||
|
const fullActivitySrNumbers = getActivityRequestSrNumbers(
|
||||||
srPayload,
|
srPayload,
|
||||||
serviceRequests
|
serviceRequests
|
||||||
);
|
);
|
||||||
const activityRequest = await fetchCachedActivityRequest(activitySrNumbers);
|
const activityRequest = await fetchCachedActivityRequest(initialActivitySrNumbers);
|
||||||
const activityRequestUrl = activityRequest.url;
|
const activityRequestUrl = activityRequest.url;
|
||||||
const activityPayload = activityRequest.payload;
|
const activityPayload = activityRequest.payload;
|
||||||
const activityOptionsBySr = normalizeActivityRequest(
|
const activityOptionsBySr = normalizeActivityRequest(
|
||||||
@@ -205,7 +238,18 @@
|
|||||||
isSaving: false,
|
isSaving: false,
|
||||||
saveErrorMessage: "",
|
saveErrorMessage: "",
|
||||||
};
|
};
|
||||||
|
writeCachedTimeManagementWeekState(
|
||||||
|
cacheKey,
|
||||||
|
appState.timeManagementModal
|
||||||
|
);
|
||||||
renderModal();
|
renderModal();
|
||||||
|
hydrateTimeManagementActivityData({
|
||||||
|
cacheKey,
|
||||||
|
requestId,
|
||||||
|
selectedDate: normalizedDate,
|
||||||
|
serviceRequests,
|
||||||
|
srNumbers: fullActivitySrNumbers,
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (appState.timeManagementModal?.requestId !== requestId) {
|
if (appState.timeManagementModal?.requestId !== requestId) {
|
||||||
return;
|
return;
|
||||||
@@ -435,6 +479,7 @@
|
|||||||
saveErrorMessage: "",
|
saveErrorMessage: "",
|
||||||
};
|
};
|
||||||
renderModal();
|
renderModal();
|
||||||
|
hydrateMissingActivityDataForSr(selectedSrNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateTimeManagementField(fieldName, inputValue, rowId = "") {
|
function updateTimeManagementField(fieldName, inputValue, rowId = "") {
|
||||||
@@ -679,6 +724,7 @@
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
appState.timeManagementWeekCache?.clear?.();
|
||||||
await loadTimeManagementData(
|
await loadTimeManagementData(
|
||||||
modal.selectedDate || getDateInputValue(new Date())
|
modal.selectedDate || getDateInputValue(new Date())
|
||||||
);
|
);
|
||||||
@@ -821,6 +867,154 @@
|
|||||||
?.removeAttribute("aria-activedescendant");
|
?.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) {
|
async function fetchCachedActivityRequest(srNumbers) {
|
||||||
const cacheKey = getActivityRequestCacheKey(srNumbers);
|
const cacheKey = getActivityRequestCacheKey(srNumbers);
|
||||||
|
|
||||||
|
|||||||
@@ -254,7 +254,9 @@
|
|||||||
function getActivityRequestSrNumbers(srPayload, serviceRequests) {
|
function getActivityRequestSrNumbers(srPayload, serviceRequests) {
|
||||||
const normalizedSrNumbers = [
|
const normalizedSrNumbers = [
|
||||||
...(serviceRequests || []).map((item) => item.srNumber),
|
...(serviceRequests || []).map((item) => item.srNumber),
|
||||||
...collectSrNumbers(srPayload),
|
...extractArray(srPayload, ["items", "data", "results", "content"]).map(
|
||||||
|
(item) => getFieldValue(item, ["SrNumber", "srNumber"])
|
||||||
|
),
|
||||||
];
|
];
|
||||||
const seen = new Set();
|
const seen = new Set();
|
||||||
|
|
||||||
@@ -384,11 +386,8 @@
|
|||||||
const preferredRows = ACTIVITY_REQUEST_DETAIL_FIELDS.map((fieldName) =>
|
const preferredRows = ACTIVITY_REQUEST_DETAIL_FIELDS.map((fieldName) =>
|
||||||
createActivityRequestDetailRow(fieldName, getActivityRequestDetailValue(item, fieldName))
|
createActivityRequestDetailRow(fieldName, getActivityRequestDetailValue(item, fieldName))
|
||||||
).filter(Boolean);
|
).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);
|
const key = normalizeActivityRequestDetailKey(row.key);
|
||||||
|
|
||||||
if (!key || seen.has(key)) {
|
if (!key || seen.has(key)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user