Skip to content

Commit

Permalink
Merge pull request #31 from dontnod/www/BuildView-lazy-changes
Browse files Browse the repository at this point in the history
www: build view lazy changes
  • Loading branch information
tdesveaux authored Nov 26, 2024
2 parents a416562 + 31c7e10 commit d0150d2
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 21 deletions.
1 change: 1 addition & 0 deletions newsfragments/www-BuildView-changes-load-more.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
BuildView's 'Changes' tab (`builders/:builderid/builds/:buildnumber`) now only load a limited number of changes, with the option to load more.
2 changes: 2 additions & 0 deletions newsfragments/www-BuildView-lazy-changes.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
BuildView (`builders/:builderid/builds/:buildnumber`) now load 'Changes' and 'Responsible Users' on first access to the tab.
This lower unnecessary queries on the master.
85 changes: 64 additions & 21 deletions www/base/src/views/BuildView/BuildView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {FaSpinner} from "react-icons/fa";
import {AlertNotification} from "../../components/AlertNotification/AlertNotification";
import {useEffect, useState} from "react";
import {Link, NavigateFunction, useNavigate, useParams} from "react-router-dom";
import {buildbotSetupPlugin} from "buildbot-plugin-support";
import {buildbotGetSettings, buildbotSetupPlugin} from "buildbot-plugin-support";
import {
Build,
Buildrequest,
Expand Down Expand Up @@ -54,13 +54,15 @@ import {
useFavIcon,
useTopbarItems,
useTopbarActions,
useLoadMoreItemsState,
} from "buildbot-ui";
import {PropertiesTable} from "../../components/PropertiesTable/PropertiesTable";
import {ChangesTable} from "../../components/ChangesTable/ChangesTable";
import {BuildSummary} from "../../components/BuildSummary/BuildSummary";
import {Tab, Table, Tabs} from "react-bootstrap";
import {buildTopbarItemsForBuilder} from "../../util/TopbarUtils";
import {BuildViewDebugTab} from "./BuildViewDebugTab";
import {LoadingSpan} from '../../components/LoadingSpan/LoadingSpan';

const buildTopbarActions = (
build: Build | null,
Expand Down Expand Up @@ -116,7 +118,7 @@ const buildTopbarActions = (
}

const getResponsibleUsers = (propertiesQuery: DataPropertiesCollection,
changesQuery: DataCollection<Change>) => {
changesAuthors: Set<string>) => {
const responsibleUsers: {[name: string]: string | null} = {};
if (getPropertyValueOrDefault(propertiesQuery.properties, "scheduler", "") === "force") {
const owner = getPropertyValueOrDefault(propertiesQuery.properties, "owner", "");
Expand All @@ -130,8 +132,8 @@ const getResponsibleUsers = (propertiesQuery: DataPropertiesCollection,
}
}

for (const change of changesQuery.array) {
const [name, email] = parseChangeAuthorNameAndEmail(change.author);
for (const author of changesAuthors) {
const [name, email] = parseChangeAuthorNameAndEmail(author);
if (email !== null || !(name in responsibleUsers)) {
responsibleUsers[name] = email;
}
Expand All @@ -140,6 +142,62 @@ const getResponsibleUsers = (propertiesQuery: DataPropertiesCollection,
return responsibleUsers;
}

type TabWidgetProps = {
build: Build | null;
}

const ChangesTabWidget = ({build}: TabWidgetProps) => {
const initialChangesFetchLimit = buildbotGetSettings().getIntegerSetting("Changes.changesFetchLimit");
const [changesFetchLimit, onLoadMoreChanges] = useLoadMoreItemsState(
initialChangesFetchLimit, initialChangesFetchLimit
);

const changesQuery = useDataApiSingleElementQuery(
build, [changesFetchLimit],
b => b.getChanges({query: {limit: changesFetchLimit, field: ['changeid']}})
);
if (!changesQuery.isResolved()) {
return <LoadingSpan />
}

return <ChangesTable
changes={changesQuery}
fetchLimit={changesFetchLimit} onLoadMore={onLoadMoreChanges}
/>
}

type ResponsibleUsersTabWidgetProps = {
propertiesQuery: DataPropertiesCollection;
} & TabWidgetProps;

const ResponsibleUsersTabWidget = ({build, propertiesQuery}: ResponsibleUsersTabWidgetProps) => {
const changesQuery = useDataApiSingleElementQuery(
build, [],
b => b.getChanges({subscribe: false, query: {field: 'author'}})
);

if (!propertiesQuery.isResolved() || !changesQuery.isResolved()) {
return <LoadingSpan />
}

const responsibleUsers = computed(() => getResponsibleUsers(
propertiesQuery,
new Set(changesQuery.array.map(c => c.author))
)).get();

return (
<ul className="list-group">
{
Object.entries(responsibleUsers).map(([author, email], index) => (
<li key={index} className="list-group-item">
<ChangeUserAvatar name={author} email={email} showName={true}/>
</li>
))
}
</ul>
);
}

const BuildView = observer(() => {
const builderid = useParams<"builderid">().builderid;
const buildnumber = Number.parseInt(useParams<"buildnumber">().buildnumber ?? "");
Expand Down Expand Up @@ -167,7 +225,6 @@ const BuildView = observer(() => {
const build = findOrNull(buildsArray, b => b.number === buildnumber);
const nextBuild = findOrNull(buildsArray, b => b.number === buildnumber + 1);

const changesQuery = useDataApiSingleElementQuery(build, [], b => b.getChanges());
const buildrequestsQuery = useDataApiSingleElementQuery(build, [],
b => b.buildrequestid === null
? new DataCollection<Buildrequest>()
Expand Down Expand Up @@ -243,7 +300,6 @@ const BuildView = observer(() => {
}
}, [builderid, navigate, shouldNavigateToBuilder]);

const responsibleUsers = computed(() => getResponsibleUsers(propertiesQuery, changesQuery)).get();
/*
$window.document.title = $state.current.data.pageTitle({builder: builder['name'], build: buildnumber});
*/
Expand Down Expand Up @@ -359,14 +415,6 @@ const BuildView = observer(() => {
));
}

const renderResponsibleUsers = () => {
return Object.entries(responsibleUsers).map(([author, email], index) => (
<li key={index} className="list-group-item">
<ChangeUserAvatar name={author} email={email} showName={true}/>
</li>
));
};

return (
<div className="container bb-build-view">
<AlertNotification text={errorMsg}/>
Expand Down Expand Up @@ -396,15 +444,10 @@ const BuildView = observer(() => {
</Table>
</Tab>
<Tab eventKey="responsible" title="Responsible Users">
<ul className="list-group">
{renderResponsibleUsers()}
</ul>
<ResponsibleUsersTabWidget build={build} propertiesQuery={propertiesQuery} />
</Tab>
<Tab eventKey="changes" title="Changes">
{build !== null
? <ChangesTable changes={changesQuery} fetchLimit={0} onLoadMore={null}/>
: <></>
}
<ChangesTabWidget build={build} />
</Tab>
<Tab eventKey="debug" title="Debug">
<BuildViewDebugTab build={build} buildrequest={buildrequest} buildset={buildset}/>
Expand Down

0 comments on commit d0150d2

Please sign in to comment.