Skip to content

Commit

Permalink
DEVPROD-7658: Create event log tables on Event Log page (#304)
Browse files Browse the repository at this point in the history
  • Loading branch information
sophiabarness authored Aug 20, 2024
1 parent 7b4c56c commit 89f6165
Show file tree
Hide file tree
Showing 19 changed files with 986 additions and 8 deletions.
24 changes: 24 additions & 0 deletions apps/spruce/cypress/integration/image/event_log.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
describe("event log page", () => {
const IMAGE_EVENT_LIMIT = 5;
it("load more button should return twice as many events", () => {
cy.visit("/image/ubuntu2204/event-log");
cy.dataCy("image-event-log-card").should("have.length", IMAGE_EVENT_LIMIT);
cy.dataCy("load-more-button").click();
cy.dataCy("image-event-log-card").should(
"have.length",
2 * IMAGE_EVENT_LIMIT,
);
});

it("should show no events when filtering for a nonexistent item", () => {
cy.visit("/image/ubuntu2204/event-log");
cy.dataCy("image-event-log-card").should("have.length", IMAGE_EVENT_LIMIT);
cy.dataCy("image-event-log-name-filter").first().click();
cy.get('input[placeholder="Search name"]').type("bogus{enter}");
cy.dataCy("image-event-log-card")
.first()
.within(() => {
cy.dataCy("image-event-log-table-row").should("have.length", 0);
});
});
});
2 changes: 1 addition & 1 deletion apps/spruce/src/components/Settings/EventLog/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export { EventDiffTable } from "./EventDiffTable";
export { EventLog } from "./EventLog";
export { EVENT_LIMIT, useEvents } from "./useEvents";
export { useEvents } from "hooks/useEvents";
export type { Event } from "./types";
5 changes: 5 additions & 0 deletions apps/spruce/src/constants/externalResources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,8 @@ export const getHoneycombSystemMetricsUrl = (
};

export const adminSettingsURL = `${getUiUrl()}/admin`;

export const buildHostConfigurationRepoURL =
"https://github.com/10gen/buildhost-configuration";
export const buildHostPostConfigRepoURL =
"https://github.com/10gen/buildhost-post-config";
26 changes: 26 additions & 0 deletions apps/spruce/src/gql/client/cache.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { InMemoryCache } from "@apollo/client";
import { IMAGE_EVENT_LIMIT } from "pages/image/tabs/EventLogTab/useImageEvents";

export const cache = new InMemoryCache({
typePolicies: {
Expand Down Expand Up @@ -35,6 +36,31 @@ export const cache = new InMemoryCache({
},
},
},
Image: {
fields: {
events: {
keyArgs: ["$imageId"],
merge(existing, incoming, { args }) {
const {
count: existingCount = 0,
eventLogEntries: existingEntries = [],
} = existing || {};
const { count: incomingCount, eventLogEntries: incomingEntries } =
incoming;
const count = existingCount + incomingCount;
const page = args?.page ?? 0;
const merged = existingEntries ? existingEntries.slice(0) : [];
for (let i = 0; i < incomingEntries.length; ++i) {
merged[page * IMAGE_EVENT_LIMIT + i] = incomingEntries[i];
}
return {
count,
eventLogEntries: merged,
};
},
},
},
},
ProjectEvents: {
fields: {
count: {
Expand Down
32 changes: 32 additions & 0 deletions apps/spruce/src/gql/generated/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6254,6 +6254,38 @@ export type ImageDistrosQuery = {
} | null;
};

export type ImageEventsQueryVariables = Exact<{
imageId: Scalars["String"]["input"];
limit: Scalars["Int"]["input"];
page: Scalars["Int"]["input"];
}>;

export type ImageEventsQuery = {
__typename?: "Query";
image?: {
__typename?: "Image";
id: string;
events: {
__typename?: "ImageEventsPayload";
count: number;
eventLogEntries: Array<{
__typename?: "ImageEvent";
amiAfter: string;
amiBefore?: string | null;
timestamp: Date;
entries: Array<{
__typename?: "ImageEventEntry";
action: ImageEventEntryAction;
after: string;
before: string;
name: string;
type: ImageEventType;
}>;
}>;
};
} | null;
};

export type ImagePackagesQueryVariables = Exact<{
imageId: Scalars["String"]["input"];
opts: PackageOpts;
Expand Down
20 changes: 20 additions & 0 deletions apps/spruce/src/gql/queries/image-events.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
query ImageEvents($imageId: String!, $limit: Int!, $page: Int!) {
image(imageId: $imageId) {
events(limit: $limit, page: $page) {
count
eventLogEntries {
amiAfter
amiBefore
entries {
action
after
before
name
type
}
timestamp
}
}
id
}
}
2 changes: 2 additions & 0 deletions apps/spruce/src/gql/queries/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import HOST_EVENTS from "./host-events.graphql";
import HOST from "./host.graphql";
import HOSTS from "./hosts.graphql";
import IMAGE_DISTROS from "./image-distros.graphql";
import IMAGE_EVENTS from "./image-events.graphql";
import IMAGE_PACKAGES from "./image-packages.graphql";
import IMAGES from "./images.graphql";
import INSTANCE_TYPES from "./instance-types.graphql";
Expand Down Expand Up @@ -111,6 +112,7 @@ export {
HOST,
HOSTS,
IMAGE_DISTROS,
IMAGE_EVENTS,
IMAGE_PACKAGES,
IMAGES,
INSTANCE_TYPES,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { useState } from "react";

export const EVENT_LIMIT = 15;

export const useEvents = (limit: number) => {
const [allEventsFetched, setAllEventsFetched] = useState(false);
const [prevCount, setPrevCount] = useState(0);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import { useEffect } from "react";
import { useQuery } from "@apollo/client";
import { EVENT_LIMIT, useEvents } from "components/Settings/EventLog";
import { useEvents } from "components/Settings/EventLog";
import { useToastContext } from "context/toast";
import {
DistroEventsQuery,
DistroEventsQueryVariables,
} from "gql/generated/types";
import { DISTRO_EVENTS } from "gql/queries";

const DISTRO_EVENT_LIMIT = 15;

export const useDistroEvents = (
distroId: string,
limit: number = EVENT_LIMIT,
limit: number = DISTRO_EVENT_LIMIT,
) => {
const dispatchToast = useToastContext();

Expand Down
36 changes: 36 additions & 0 deletions apps/spruce/src/pages/image/ImageEventLog/Header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import styled from "@emotion/styled";
import { Disclaimer, Subtitle } from "@leafygreen-ui/typography";
import { size } from "constants/tokens";
import { useDateFormat } from "hooks";

interface HeaderProps {
amiBefore: string;
amiAfter: string;
timestamp: Date;
}

export const Header: React.FC<HeaderProps> = ({
amiAfter,
amiBefore,
timestamp,
}) => {
const getDateCopy = useDateFormat();

return (
<StyledHeader>
<Subtitle data-cy="event-log-timestamp">
{getDateCopy(timestamp)}
</Subtitle>
<Disclaimer data-cy="event-log-ami">
AMI changed from {amiBefore} to {amiAfter}
</Disclaimer>
</StyledHeader>
);
};

const StyledHeader = styled.div`
display: flex;
flex-direction: column;
gap: ${size.xxs};
padding-bottom: ${size.s};
`;
69 changes: 69 additions & 0 deletions apps/spruce/src/pages/image/ImageEventLog/ImageEventLog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import styled from "@emotion/styled";
import Card from "@leafygreen-ui/card";
import { Subtitle } from "@leafygreen-ui/typography";
import { LoadingButton } from "components/Buttons";
import { size } from "constants/tokens";
import { ImageEvent } from "gql/generated/types";
import { Header } from "./Header";
import { ImageEventLogTable } from "./ImageEventLogTable";

type ImageEventLogProps = {
allEventsFetched: boolean;
events: ImageEvent[];
handleFetchMore: () => void;
loading?: boolean;
};

export const ImageEventLog: React.FC<ImageEventLogProps> = ({
allEventsFetched,
events,
handleFetchMore,
loading,
}) => {
const allEventsFetchedCopy =
events.length > 0 ? "No more events to show." : "No events to show.";

return (
<Container>
{events.map((event) => {
const { amiAfter, amiBefore, entries, timestamp } = event;
return (
<ImageEventLogCard
key={`event_log_${timestamp}`}
data-cy="image-event-log-card"
>
<Header
amiAfter={amiAfter}
amiBefore={amiBefore ?? ""}
timestamp={timestamp}
/>
<ImageEventLogTable entries={entries} />
</ImageEventLogCard>
);
})}
{!allEventsFetched && events.length > 0 && (
<LoadingButton
data-cy="load-more-button"
loading={loading}
onClick={handleFetchMore}
variant="primary"
>
Load more events
</LoadingButton>
)}
{allEventsFetched && <Subtitle>{allEventsFetchedCopy}</Subtitle>}
</Container>
);
};

const Container = styled.div`
display: flex;
flex-direction: column;
align-items: center;
gap: ${size.l};
`;

const ImageEventLogCard = styled(Card)`
width: 100%;
padding: ${size.m};
`;
Loading

0 comments on commit 89f6165

Please sign in to comment.