Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix bugs in the infinite scrolling mechanism in logs section #6871

Merged
merged 3 commits into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/eleven-suns-nail.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@wso2is/admin.logs.v1": patch
---

Fix bugs in the infinite scrolling mechanism in logs section
188 changes: 86 additions & 102 deletions features/admin.logs.v1/pages/diagnostic-logs-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ const DiagnosticLogsPage = (props: DiagnosticPagePropsInterface) : ReactElement
["data-componentid"]: componentId
} = props;

const scrollRef: MutableRefObject<HTMLDivElement> = useRef<HTMLDivElement>(null);

const [ isPreviousEmpty, setIsPreviousEmpty ] = useState<boolean>(false);
const [ isNextEmpty, setIsNextEmpty ] = useState<boolean>(false);
const [ searchQuery, setSearchQuery ] = useState<string>("");
Expand All @@ -78,9 +80,31 @@ const DiagnosticLogsPage = (props: DiagnosticPagePropsInterface) : ReactElement
const [ timerRunning, setTimerRunning ] = useState<boolean>(false);
const [ diagnosticLogList, setDiagnosticLogList ] = useState<InterfaceLogEntry[]>([]);

const { t } = useTranslation();
const timeZone: string = "GMT+0000 UTC";

const { t } = useTranslation();

const { error, list, loading, next, previous } = useFetch(requestPayload);

useEffect(() => {
const current: number = getDateTimeWithOffset(timeZone);
const currentEndTime: string = current.toString();
const currentStartTime: string = (current - 3600*1000*timeRange).toString();

setEndTime(currentEndTime);
setStartTime(currentStartTime);
setLastDiagnosticLogRequestTime(currentEndTime);

// Fetch logs automatically during the first render.
setRequestPayload({
endTime: currentEndTime,
filter: "",
limit: LogsConstants.LOG_FETCH_COUNT,
logType: TabIndex.DIAGNOSTIC_LOGS,
startTime: currentStartTime
});
}, []);

useEffect(() => {
// Display a message if the logs are not fetched within 15 seconds of the request.
setTimeout(() => {
Expand All @@ -107,33 +131,9 @@ const DiagnosticLogsPage = (props: DiagnosticPagePropsInterface) : ReactElement
setShowRefreshButton(false);
}, [ endTime, startTime, inputQuery, filterQuery ]);

useEffect(() => {
const current: number = getDateTimeWithOffset(timeZone);
const currentEndTime: string = current.toString();
const currentStartTime: string = (current - 3600*1000*timeRange).toString();

setEndTime(currentEndTime);
setStartTime(currentStartTime);
setLastDiagnosticLogRequestTime(currentEndTime);

// Fetch logs automatically during the first render.
setRequestPayload({
endTime: currentEndTime,
filter: "",
limit: LogsConstants.LOG_FETCH_COUNT,
logType: TabIndex.DIAGNOSTIC_LOGS,
startTime: currentStartTime
});
}, []);

const scrollRef: MutableRefObject<HTMLDivElement> = useRef<HTMLDivElement>(null);

const { error, list, loading, next, previous } = useFetch(requestPayload);


useEffect (() => {
if (!loading && list.length > 0) {
setDiagnosticLogList(list);
setDiagnosticLogList((previousLogs: InterfaceLogEntry[]) => [ ...previousLogs, ...list ]);
}
}, [ list, loading ]);

Expand All @@ -144,24 +144,7 @@ const DiagnosticLogsPage = (props: DiagnosticPagePropsInterface) : ReactElement
const element: any = e.target;

setShowDelayMessage(false);
/**
* When the at the top of the log container
*/
if (element.scrollTop === 0) {

if (previous) {
setRequestPayload({
filter: searchQuery,
limit: LogsConstants.LOG_FETCH_COUNT,
logType: TabIndex.DIAGNOSTIC_LOGS,
previousToken: previous
});
setIsPreviousEmpty(false);
setIsNextEmpty(false);
} else {
setIsPreviousEmpty(true);
}
}
/**
* When at the bottom of the log container
*/
Expand All @@ -181,61 +164,6 @@ const DiagnosticLogsPage = (props: DiagnosticPagePropsInterface) : ReactElement
}
};

const renderDiagnosticLogContent = () : ReactElement => {

return (
<div>
<div className="top-action-bar">
{ advancedSearchFilter() }
<TimeRangeSelector
setFromTime={ (value: string): void => setStartTime(value) }
setToTime={ (value: string): void => setEndTime(value) }
setTimeRange={ (value: number): void => setTimeRange(value) }
data-componentid={ componentId }
/>
{ showRefreshButton
? (
<PrimaryButton
onClick={ () => fetchLatestLogs() }
data-componentid={ `${ componentId }-refresh-button` }
>
<Icon name="refresh" />
{ t("extensions:develop.monitor.filter.refreshButton.label") }
</PrimaryButton>
) : (
<PrimaryButton
onClick={ () => handleSearch() }
data-componentid={ `${ componentId }-search-button` }
>
<Icon name="search" />
{ t("extensions:develop.monitor.filter.queryButton.label") }
</PrimaryButton>
)
}
</div>
<div>
<>
<div className="top-toolbar">
{ renderRefreshTime() }
<Label.Group>
{ filterList && filterList.map(
(value: { key: string, value:string }, index: number) =>
(<Label key={ index } className="filter-pill">
{ getLabelTextForFilterPill(value.key) }
<Label.Detail>{ value.value }</Label.Detail>
<Icon name="delete" onClick={ () => removeFilter(value.key) }></Icon>
</Label>)
) }
{ resolveClearAllFilters() }
</Label.Group>
</div>
{ resolveDiagnosticLogs() }
</>
</div>
</div>
);
};

/**
* Build filter query
*/
Expand All @@ -257,7 +185,9 @@ const DiagnosticLogsPage = (props: DiagnosticPagePropsInterface) : ReactElement
*
* @param query - search query with filters
*/
const handleSearch = () => {
const handleSearch = (overrideQuery?: string) => {
setDiagnosticLogList([]);

let currentQuery: string = "";

if (inputQuery.length === 0) {
Expand All @@ -268,7 +198,7 @@ const DiagnosticLogsPage = (props: DiagnosticPagePropsInterface) : ReactElement
currentQuery = ` and ${currentQuery}`;
}
}
setSearchQuery(currentQuery);
setSearchQuery(overrideQuery === undefined ? currentQuery : overrideQuery);

// If the custom time range is not defined,
// start, end times needs to be updated to account for the time it takes to click the search button.
Expand All @@ -286,7 +216,7 @@ const DiagnosticLogsPage = (props: DiagnosticPagePropsInterface) : ReactElement

setRequestPayload({
endTime: currentEndTime,
filter: `${filterQuery}${currentQuery}`,
filter: `${filterQuery}${overrideQuery === undefined ? currentQuery : overrideQuery}`,
limit: LogsConstants.LOG_FETCH_COUNT,
logType: TabIndex.DIAGNOSTIC_LOGS,
startTime: currentStartTime
Expand All @@ -300,7 +230,7 @@ const DiagnosticLogsPage = (props: DiagnosticPagePropsInterface) : ReactElement
setSearchQuery("");
setInputQuery("");
setShowRefreshButton(false);

handleSearch("");
};

/**
Expand Down Expand Up @@ -354,6 +284,60 @@ const DiagnosticLogsPage = (props: DiagnosticPagePropsInterface) : ReactElement
setFilterList([]);
};

const renderDiagnosticLogContent = () : ReactElement => {
return (
<div>
<div className="top-action-bar">
{ advancedSearchFilter() }
<TimeRangeSelector
setFromTime={ (value: string): void => setStartTime(value) }
setToTime={ (value: string): void => setEndTime(value) }
setTimeRange={ (value: number): void => setTimeRange(value) }
data-componentid={ componentId }
/>
{ showRefreshButton
? (
<PrimaryButton
onClick={ () => fetchLatestLogs() }
data-componentid={ `${ componentId }-refresh-button` }
>
<Icon name="refresh" />
{ t("extensions:develop.monitor.filter.refreshButton.label") }
</PrimaryButton>
) : (
<PrimaryButton
onClick={ () => handleSearch() }
data-componentid={ `${ componentId }-search-button` }
>
<Icon name="search" />
{ t("extensions:develop.monitor.filter.queryButton.label") }
</PrimaryButton>
)
}
</div>
<div>
<>
<div className="top-toolbar">
{ renderRefreshTime() }
<Label.Group>
{ filterList && filterList.map(
(value: { key: string, value:string }, index: number) =>
(<Label key={ index } className="filter-pill">
{ getLabelTextForFilterPill(value.key) }
<Label.Detail>{ value.value }</Label.Detail>
<Icon name="delete" onClick={ () => removeFilter(value.key) }></Icon>
</Label>)
) }
{ resolveClearAllFilters() }
</Label.Group>
</div>
{ resolveDiagnosticLogs() }
</>
</div>
</div>
);
};

/**
* Returns search component
*/
Expand Down
Loading