diff --git a/packages/app/src/front/components/grid/LogCell.tsx b/packages/app/src/front/components/grid/LogCell.tsx
index 42e8872..5fb8087 100644
--- a/packages/app/src/front/components/grid/LogCell.tsx
+++ b/packages/app/src/front/components/grid/LogCell.tsx
@@ -1,9 +1,11 @@
import { FsdtLogMessageContent } from '@fullstack-devtool/core'
import styled from '@emotion/styled'
import { ObjectView } from '../ObjectView'
+import { StoredMessage } from '../../stores/messageStore'
type LogCellProps = {
value: FsdtLogMessageContent
+ data: StoredMessage
}
const StyledLogCell = styled.div`
@@ -13,8 +15,24 @@ const StyledLogCell = styled.div`
* {
font-family: ${(props) => props.theme.fontFamily.secondary};
}
+ display: flex;
+ align-items: center;
`
-export const LogCell = ({ value }: LogCellProps) => {
- return {typeof value === 'object' ? : value}
+const Quantity = styled.span`
+ margin-left: 8px;
+ background-color: ${(props) => props.theme.colors.primary};
+ color: white;
+ padding: 2px 4px;
+ border-radius: 400px;
+ font-size: 12px;
+`
+
+export const LogCell = ({ value, data }: LogCellProps) => {
+ return (
+
+ {typeof value === 'object' ? : value}
+ {data.quantity > 1 && {data.quantity}}
+
+ )
}
diff --git a/packages/app/src/front/stores/messageStore.ts b/packages/app/src/front/stores/messageStore.ts
index 306ba62..91708ce 100644
--- a/packages/app/src/front/stores/messageStore.ts
+++ b/packages/app/src/front/stores/messageStore.ts
@@ -1,8 +1,13 @@
import { FsdtLogMessageContent, FsdtServerMessage } from '@fullstack-devtool/core'
import { create } from 'zustand'
+import { groupMessagesWithTheSameContent } from '../utils/message'
+
+export type StoredMessage = FsdtServerMessage & {
+ quantity: number
+}
interface MessageState {
- messages: FsdtServerMessage[]
+ messages: StoredMessage[]
sources: string[]
tags: string[]
addMessage: (message: FsdtServerMessage) => void
@@ -16,6 +21,18 @@ export const useMessageStore = create((set) => ({
tags: [],
addMessage: (message) =>
set((state) => {
+ // Group messages with the same content
+ const lastMessage = state.messages[state.messages.length - 1]
+ if (
+ lastMessage &&
+ lastMessage.source === message.source &&
+ lastMessage.data.content === message.data.content &&
+ lastMessage.data.tag === message.data.tag
+ ) {
+ lastMessage.quantity++
+ return { messages: [...state.messages] }
+ }
+ // Add new message
const newSources = [...state.sources]
const newTags = [...state.tags]
if (!newSources.includes(message.source)) {
@@ -24,7 +41,7 @@ export const useMessageStore = create((set) => ({
if (!newTags.includes(message.data.tag) && message.data.tag) {
newTags.push(message.data.tag)
}
- return { messages: [...state.messages, message], sources: newSources, tags: newTags }
+ return { messages: [...state.messages, { ...message, quantity: 1 }], sources: newSources, tags: newTags }
}),
addMessages: (messages) =>
set((state) => {
@@ -38,7 +55,14 @@ export const useMessageStore = create((set) => ({
newTags.push(message.data.tag)
}
})
- return { messages: [...state.messages, ...messages], sources: newSources, tags: newTags }
+ return {
+ messages: groupMessagesWithTheSameContent([
+ ...state.messages,
+ ...messages.map((mess) => ({ ...mess, quantity: 1 })),
+ ]),
+ sources: newSources,
+ tags: newTags,
+ }
}),
clearMessages: () => set({ messages: [] }),
}))
diff --git a/packages/app/src/front/utils/message.spec.ts b/packages/app/src/front/utils/message.spec.ts
new file mode 100644
index 0000000..34c131b
--- /dev/null
+++ b/packages/app/src/front/utils/message.spec.ts
@@ -0,0 +1,88 @@
+import { EventType, LogLevel } from '@fullstack-devtool/core'
+import { StoredMessage } from '../stores/messageStore'
+import { groupMessagesWithTheSameContent } from './message'
+
+describe('message', () => {
+ describe('groupMessagesWithTheSameContent', () => {
+ it('should group messages with the same content', () => {
+ const allMessages: StoredMessage[] = [
+ {
+ id: 1,
+ source: 'source1',
+ type: EventType.LOG,
+ data: {
+ content: 'content1',
+ tag: 'tag1',
+ timestamp: '1',
+ level: LogLevel.LOG,
+ },
+ quantity: 1,
+ },
+ {
+ id: 2,
+ source: 'source1',
+ type: EventType.LOG,
+ data: {
+ content: 'content1',
+ tag: 'tag1',
+ timestamp: '2',
+ level: LogLevel.LOG,
+ },
+ quantity: 1,
+ },
+ {
+ id: 3,
+ source: 'source1',
+ type: EventType.LOG,
+ data: {
+ content: 'content2',
+ tag: 'tag1',
+ timestamp: '3',
+ level: LogLevel.LOG,
+ },
+ quantity: 1,
+ },
+ {
+ id: 4,
+ source: 'source1',
+ type: EventType.LOG,
+ data: {
+ content: 'content2',
+ tag: 'tag1',
+ timestamp: '4',
+ level: LogLevel.LOG,
+ },
+ quantity: 1,
+ },
+ ]
+ const groupedMessages: StoredMessage[] = [
+ {
+ id: 1,
+ source: 'source1',
+ type: EventType.LOG,
+ data: {
+ content: 'content1',
+ tag: 'tag1',
+ timestamp: '1',
+ level: LogLevel.LOG,
+ },
+ quantity: 2,
+ },
+ {
+ id: 3,
+ source: 'source1',
+ type: EventType.LOG,
+ data: {
+ content: 'content2',
+ tag: 'tag1',
+ timestamp: '3',
+ level: LogLevel.LOG,
+ },
+ quantity: 2,
+ },
+ ]
+
+ expect(groupMessagesWithTheSameContent(allMessages)).toEqual(groupedMessages)
+ })
+ })
+})
diff --git a/packages/app/src/front/utils/message.ts b/packages/app/src/front/utils/message.ts
new file mode 100644
index 0000000..34335bb
--- /dev/null
+++ b/packages/app/src/front/utils/message.ts
@@ -0,0 +1,19 @@
+import { StoredMessage } from '../stores/messageStore'
+
+export const groupMessagesWithTheSameContent = (messages: StoredMessage[]) => {
+ const groupedMessages: StoredMessage[] = []
+ messages.forEach((message) => {
+ const lastMessage = groupedMessages[groupedMessages.length - 1]
+ if (
+ lastMessage &&
+ lastMessage.source === message.source &&
+ lastMessage.data.content === message.data.content &&
+ lastMessage.data.tag === message.data.tag
+ ) {
+ lastMessage.quantity++
+ } else {
+ groupedMessages.push({ ...message, quantity: 1 })
+ }
+ })
+ return groupedMessages
+}