Skip to content

Commit

Permalink
Pass only needed props to Table component to optimize page size (#1115)
Browse files Browse the repository at this point in the history
* refactor: pass only needed props to Table component to optimize page size

* Create dirty-sloths-crash.md

---------

Co-authored-by: David Boyne <boyneyy123@gmail.com>
  • Loading branch information
carlosallexandre and boyney123 authored Jan 29, 2025
1 parent 6774b51 commit 3211cad
Show file tree
Hide file tree
Showing 9 changed files with 152 additions and 50 deletions.
5 changes: 5 additions & 0 deletions .changeset/dirty-sloths-crash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@eventcatalog/core": patch
---

refactor(core): reduced amount of data the discover table needs
105 changes: 81 additions & 24 deletions eventcatalog/src/components/Tables/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,34 +9,100 @@ import {
useReactTable,
type Column,
type ColumnFiltersState,
type Row,
} from '@tanstack/react-table';
import type { CollectionEntry } from 'astro:content';
import DebouncedInput from './DebouncedInput';

import { getColumnsByCollection } from './columns';
import { useEffect, useMemo, useState, type EventHandler } from 'react';
import type { CollectionTypes } from '@types';
import { useEffect, useMemo, useState } from 'react';
import type { CollectionMessageTypes } from '@types';
import { isSameVersion } from '@utils/collections/util';

declare module '@tanstack/react-table' {
// @ts-ignore
interface ColumnMeta<TData extends RowData, TValue> {
filterVariant?: 'collection' | 'name' | 'badges';
collectionFilterKey?: string;
collectionFilterKey?: 'producers' | 'consumers' | 'sends' | 'receives' | 'services';
showFilter?: boolean;
className?: string;
}
}

export const Table = ({
export type TCollectionTypes = 'domains' | 'services' | CollectionMessageTypes | 'flows';

export type TData<T extends TCollectionTypes> = {
collection: T;
data: {
id: string;
name: string;
summary: string;
version: string;
latestVersion?: string; // Defined on getter collection utility
badges?: Array<{
id: string; // Where is it defined?
content: string;
backgroundColor: string;
textColor: string;
icon: any; // Where is it defined?
}>;
// ---------------------------------------------------------------------------
// Domains
services?: Array<{
collection: string; // Be more specific;
data: {
id: string;
name: string;
version: string;
};
}>;
// ---------------------------------------------------------------------------
// Services
receives?: Array<{
collection: string; // Be more specific;
data: {
id: string;
name: string;
version: string;
};
}>;
sends?: Array<{
collection: string; // Be more specific;
data: {
id: string;
name: string;
version: string;
};
}>;
// ---------------------------------------------------------------------------
// Messages
producers?: Array<{
collection: string; // Specify only 'services'?
data: {
id: string;
name: string;
version: string;
};
}>;
// Only for messages
consumers?: Array<{
collection: string; // Specify only 'services'?
data: {
id: string;
name: string;
version: string;
};
}>;
// ---------------------------------------------------------------------------
};
};

export const Table = <T extends TCollectionTypes>({
data: initialData,
collection,
mode = 'simple',
checkboxLatestId,
}: {
data: CollectionEntry<'events'>[];
collection: string;
data: TData<T>[];
collection: T;
checkboxLatestId: string;
mode?: 'simple' | 'full';
}) => {
Expand Down Expand Up @@ -68,7 +134,6 @@ export const Table = ({
const columns = useMemo(() => getColumnsByCollection(collection), [collection]);

const table = useReactTable({
// @ts-ignore
data,
columns,
onColumnFiltersChange: setColumnFilters,
Expand Down Expand Up @@ -106,7 +171,6 @@ export const Table = ({
<div className="text-md">
{header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}
</div>
{/* @ts-ignore */}
<div className="">
{header.column.columnDef.meta?.showFilter !== false && <Filter column={header.column} />}
{header.column.columnDef.meta?.showFilter == false && <div className="h-10" />}
Expand Down Expand Up @@ -201,34 +265,27 @@ export const Table = ({
);
};

function Filter({ column }: { column: Column<any, unknown> }) {
const { filterVariant, collectionFilterKey = '' } = column.columnDef.meta ?? {};
function Filter<T extends TCollectionTypes>({ column }: { column: Column<TData<T>, unknown> }) {
const { filterVariant, collectionFilterKey } = column.columnDef.meta ?? {};

const columnFilterValue = column.getFilterValue();

const sortedUniqueValues = useMemo(() => {
if (filterVariant === 'collection') {
if (filterVariant === 'collection' && collectionFilterKey) {
const rows = column.getFacetedRowModel().rows;
const data = rows
.map((row: Row<CollectionEntry<CollectionTypes>>) => {
// @ts-ignore
const items = row.original.data[collectionFilterKey];
return items as CollectionEntry<CollectionTypes>[];
})
.flat();
const data = rows.map((row) => row.original.data?.[collectionFilterKey] ?? []).flat();

const allItems = data.map((item) => `${item.data.name} (v${item.data.version})`);
const allItems = data.map((item) => `${item?.data.name} (v${item?.data.version})`);
const uniqueItemsInList = Array.from(new Set(allItems));

return uniqueItemsInList.sort().slice(0, 2000);
}
if (filterVariant === 'name') {
const rows = column.getFacetedRowModel().rows;
const data = rows
.map((row: Row<CollectionEntry<CollectionTypes>>) => {
// @ts-ignore
.map((row) => {
const data = row.original;
return data as CollectionEntry<CollectionTypes>;
return data;
})
.flat();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { ServerIcon } from '@heroicons/react/20/solid';
import { RectangleGroupIcon } from '@heroicons/react/20/solid';
import { createColumnHelper } from '@tanstack/react-table';
import type { CollectionEntry } from 'astro:content';
import { filterByBadge, filterByName, filterCollectionByName } from '../filters/custom-filters';
import { filterByName, filterCollectionByName } from '../filters/custom-filters';
import { buildUrl } from '@utils/url-builder';
import { Tag } from 'lucide-react';
import { createBadgesColumn } from './SharedColumns';
import type { TData } from '../Table';

const columnHelper = createColumnHelper<CollectionEntry<'domains'>>();
const columnHelper = createColumnHelper<TData<'domains'>>();

export const columns = () => [
columnHelper.accessor('data.name', {
Expand Down Expand Up @@ -65,7 +64,7 @@ export const columns = () => [

return (
<ul>
{services.map((consumer: any) => {
{services.map((consumer) => {
const color = 'pink';
return (
<li key={consumer.data.id} className="py-1 group ">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { createColumnHelper } from '@tanstack/react-table';
import type { CollectionEntry } from 'astro:content';
import { filterByName } from '../filters/custom-filters';
import { buildUrl } from '@utils/url-builder';
import { QueueListIcon } from '@heroicons/react/24/solid';
import { createBadgesColumn } from './SharedColumns';
import type { TData } from '../Table';

const columnHelper = createColumnHelper<CollectionEntry<'flows'>>();
const columnHelper = createColumnHelper<TData<'flows'>>();

export const columns = () => [
columnHelper.accessor('data.name', {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { ServerIcon, BoltIcon, ChatBubbleLeftIcon, MagnifyingGlassIcon } from '@heroicons/react/24/solid';
import { createColumnHelper } from '@tanstack/react-table';
import type { CollectionMessageTypes } from '@types';
import type { CollectionEntry } from 'astro:content';
import { useMemo } from 'react';
import { filterByName, filterCollectionByName, filterByBadge } from '../filters/custom-filters';
import { filterByName, filterCollectionByName } from '../filters/custom-filters';
import { buildUrl } from '@utils/url-builder';
import { createBadgesColumn } from './SharedColumns';
import type { TData } from '../Table';
import type { CollectionMessageTypes } from '@types';

const columnHelper = createColumnHelper<CollectionEntry<CollectionMessageTypes>>();
const columnHelper = createColumnHelper<TData<CollectionMessageTypes>>();

export const getColorAndIconForMessageType = (type: string) => {
switch (type) {
Expand Down Expand Up @@ -80,7 +80,7 @@ export const columns = () => [
return <div className="font-light text-sm text-gray-400/60 text-left italic">No producers documented</div>;
return (
<ul className="">
{producers.map((producer: any, index: number) => {
{producers.map((producer, index) => {
return (
<li className="py-2 group flex items-center space-x-2" key={`${producer.data.id}-${index}`}>
<a
Expand Down Expand Up @@ -120,7 +120,7 @@ export const columns = () => [

return (
<ul>
{consumers.map((consumer: any, index: number) => {
{consumers.map((consumer, index) => {
return (
<li key={`${consumer.data.id}-${index}`} className="py-1 group font-light ">
<a
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { ServerIcon, BoltIcon, ChatBubbleLeftIcon } from '@heroicons/react/24/solid';
import { createColumnHelper } from '@tanstack/react-table';
import type { CollectionEntry } from 'astro:content';
import { useMemo, useState } from 'react';
import { filterByName, filterCollectionByName } from '../filters/custom-filters';
import { buildUrl } from '@utils/url-builder';
import { getColorAndIconForMessageType } from './MessageTableColumns';
import { createBadgesColumn } from './SharedColumns';
import type { TData } from '../Table';

const columnHelper = createColumnHelper<CollectionEntry<'services'>>();
const columnHelper = createColumnHelper<TData<'services'>>();

export const columns = () => [
columnHelper.accessor('data.name', {
Expand Down Expand Up @@ -65,7 +65,7 @@ export const columns = () => [

const receiversWithIcons = useMemo(
() =>
receives?.map((consumer: any) => {
receives?.map((consumer) => {
const type = consumer.collection.slice(0, -1);
return {
...consumer,
Expand All @@ -87,7 +87,7 @@ export const columns = () => [
)}
{isExpanded && (
<ul>
{receiversWithIcons.map((consumer: any, index: number) => (
{receiversWithIcons.map((consumer, index: number) => (
<li key={`${consumer.data.id}-${index}`} className="py-1 group font-light ">
<a
href={buildUrl(`/docs/${consumer.collection}/${consumer.data.id}/${consumer.data.version}`)}
Expand Down Expand Up @@ -137,7 +137,7 @@ export const columns = () => [
)}
{isExpanded && (
<ul>
{sends.map((consumer: any, index: number) => {
{sends.map((consumer, index) => {
const type = consumer.collection.slice(0, -1);
const color = type === 'event' ? 'orange' : 'blue';
const Icon = type === 'event' ? BoltIcon : ChatBubbleLeftIcon;
Expand Down
6 changes: 4 additions & 2 deletions eventcatalog/src/components/Tables/columns/SharedColumns.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { createColumnHelper } from '@tanstack/react-table';
import { Tag } from 'lucide-react';
import { filterByBadge } from '../filters/custom-filters';
export const createBadgesColumn = <T extends { data: { badges?: any[] } }>(
import type { TCollectionTypes, TData } from '../Table';

export const createBadgesColumn = <T extends { data: Pick<TData<U>['data'], 'badges'> }, U extends TCollectionTypes>(
columnHelper: ReturnType<typeof createColumnHelper<T>>
) => {
return columnHelper.accessor((row) => row.data.badges, {
Expand All @@ -16,7 +18,7 @@ export const createBadgesColumn = <T extends { data: { badges?: any[] } }>(

return (
<ul>
{badges.map((badge: any, index: number) => {
{badges.map((badge, index) => {
return (
<li key={`${badge.id}-${index}`} className="py-1 group font-light ">
<div className="group-hover:text-primary flex space-x-1 items-center ">
Expand Down
9 changes: 8 additions & 1 deletion eventcatalog/src/layouts/DiscoverLayout.astro
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
import { Table } from '@components/Tables/Table';
import { Table, type TData, type TCollectionTypes } from '@components/Tables/Table';
import { QueueListIcon, RectangleGroupIcon, BoltIcon, ChatBubbleLeftIcon } from '@heroicons/react/24/outline';
import ServerIcon from '@heroicons/react/24/outline/ServerIcon';
import { getCommands } from '@utils/commands';
Expand All @@ -20,6 +20,13 @@ const services = await getServices();
const domains = await getDomains();
const flows = await getFlows();
export interface Props<T extends TCollectionTypes> {
title: string;
subtitle: string;
data: TData<T>[];
type: T;
}
const { title, subtitle, data, type } = Astro.props;
const currentPath = Astro.url.pathname;
Expand Down
Loading

0 comments on commit 3211cad

Please sign in to comment.