Skip to content

Commit

Permalink
Merge pull request #423 from duyet/chore/ui-update
Browse files Browse the repository at this point in the history
feat: add column Markdown format
  • Loading branch information
duyet authored Nov 21, 2024
2 parents ec82462 + dec896d commit 245ca28
Show file tree
Hide file tree
Showing 14 changed files with 782 additions and 97 deletions.
1 change: 1 addition & 0 deletions app/[host]/[query]/more/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export const settingsConfig: QueryConfig = {
changed: ColumnFormat.Boolean,
value: ColumnFormat.Code,
default: ColumnFormat.Code,
description: ColumnFormat.Markdown,
},
defaultParams: {
changed: '',
Expand Down
2 changes: 1 addition & 1 deletion components/charts/backup-size.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { type ChartProps } from '@/components/charts/chart-props'
import { CardMetric } from '@/components/generic-charts/card-metric'
import { ChartCard } from '@/components/generic-charts/chart-card'
import { CardMetric } from '@/components/tremor/card-metric'
import { fetchData } from '@/lib/clickhouse'

export async function ChartBackupSize({
Expand Down
2 changes: 1 addition & 1 deletion components/charts/disk-size.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { type ChartProps } from '@/components/charts/chart-props'
import { CardMetric } from '@/components/generic-charts/card-metric'
import { ChartCard } from '@/components/generic-charts/chart-card'
import { CardMetric } from '@/components/tremor/card-metric'
import { fetchData } from '@/lib/clickhouse'

export async function ChartDiskSize({
Expand Down
2 changes: 1 addition & 1 deletion components/charts/query-cache.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { type ChartProps } from '@/components/charts/chart-props'
import { CardMetric } from '@/components/generic-charts/card-metric'
import { ChartCard } from '@/components/generic-charts/chart-card'
import { CardMetric } from '@/components/tremor/card-metric'
import { fetchData } from '@/lib/clickhouse'

export async function ChartQueryCache({
Expand Down
41 changes: 41 additions & 0 deletions components/data-table/cells/markdown-format.cy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { MarkdownFormat } from './markdown-format'

describe('<MarkdownFormat />', () => {
it('renders basic markdown text', () => {
cy.mount(<MarkdownFormat value="Hello **World**" />)
cy.get('strong').should('contain', 'World')
})

it('renders empty string when value is null or undefined', () => {
cy.mount(<MarkdownFormat value={null} />)
cy.get('span').should('have.text', '')

cy.mount(<MarkdownFormat value={undefined} />)
cy.get('span').should('have.text', '')
})

it('applies default classes', () => {
cy.mount(<MarkdownFormat value="Test" />)
cy.get('span')
.should('have.class', 'truncate')
.and('have.class', 'text-wrap')
})

it('applies custom className from options', () => {
cy.mount(
<MarkdownFormat value="Test" options={{ className: 'text-red-500' }} />
)
cy.get('span')
.should('have.class', 'text-red-500')
.and('have.class', 'truncate')
.and('have.class', 'text-wrap')
})

it('handles non-string values by converting to string', () => {
cy.mount(<MarkdownFormat value={123} />)
cy.get('span').should('contain', '123')

cy.mount(<MarkdownFormat value={true} />)
cy.get('span').should('contain', 'true')
})
})
19 changes: 19 additions & 0 deletions components/data-table/cells/markdown-format.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { cn } from '@/lib/utils'
import Markdown from 'react-markdown'

export interface MarkdownFormatOptions {
className?: string
}

interface MarkdownFormatProps {
value: any
options?: MarkdownFormatOptions
}

export function MarkdownFormat({ value, options }: MarkdownFormatProps) {
return (
<span className={cn('truncate text-wrap', options?.className)}>
<Markdown>{`${!!value ? value : ''}`}</Markdown>
</span>
)
}
12 changes: 12 additions & 0 deletions components/data-table/format-cell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ import {
type HoverCardOptions,
} from './cells/hover-card-format'
import { LinkFormat } from './cells/link-format'
import {
MarkdownFormat,
type MarkdownFormatOptions,
} from './cells/markdown-format'
import { RelatedTimeFormat } from './cells/related-time-format'
import { TextFormat, type TextFormatOptions } from './cells/text-format'

Expand Down Expand Up @@ -134,6 +138,14 @@ export const formatCell = <
/>
)

case ColumnFormat.Markdown:
return (
<MarkdownFormat
value={value}
options={columnFormatOptions as MarkdownFormatOptions}
/>
)

case ColumnFormat.HoverCard:
return (
<HoverCardFormat
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,8 @@ describe('<CardMetric />', () => {
cy.get('div').contains('0')
cy.get('div').contains('10')

// Tremor bar should be 0% filled
cy.get('.tremor-ProgressBar-progressBar')
.should('have.attr', 'style')
.and('include', '0%')
// should be 0% filled
cy.get('span').should('have.attr', 'title').and('include', '0%')
})

it('renders 10% bar', () => {
Expand All @@ -21,10 +19,8 @@ describe('<CardMetric />', () => {
cy.get('div').contains('1')
cy.get('div').contains('10')

// Tremor bar should be 10% filled
cy.get('.tremor-ProgressBar-progressBar')
.should('have.attr', 'style')
.and('include', '10%')
// should be 10% filled
cy.get('span').should('have.attr', 'title').and('include', '10%')
})

it('renders 100% bar', () => {
Expand All @@ -34,10 +30,8 @@ describe('<CardMetric />', () => {
cy.get('div').contains('10')
cy.get('div').contains('10')

// Tremor bar should be 100% filled
cy.get('.tremor-ProgressBar-progressBar')
.should('have.attr', 'style')
.and('include', '100%')
// should be 100% filled
cy.get('span').should('have.attr', 'title').and('include', '100%')
})

it('renders 1000% bar when current > target', () => {
Expand All @@ -47,10 +41,8 @@ describe('<CardMetric />', () => {
cy.get('div').contains('100')
cy.get('div').contains('10')

// Tremor bar should be 1000% filled
cy.get('.tremor-ProgressBar-progressBar')
.should('have.attr', 'style')
.and('include', '1000%')
// should be 1000% filled
cy.get('span').should('have.attr', 'title').and('include', '1000%')
})

it('renders 10% bar with currentReadable and targetReadable', () => {
Expand All @@ -67,10 +59,8 @@ describe('<CardMetric />', () => {
cy.get('div').contains('xx 1 xx')
cy.get('div').contains('xx 10 xx')

// Tremor bar should be 10% filled
cy.get('.tremor-ProgressBar-progressBar')
.should('have.attr', 'style')
.and('include', '10%')
// should be 10% filled
cy.get('span').should('have.attr', 'title').and('include', '10%')
})

it('renders with custom className', () => {
Expand All @@ -82,7 +72,6 @@ describe('<CardMetric />', () => {
/>
)

// Tremor bar should be 10% filled
cy.get('.bg-cyan-400.custom-classname').should('exist')
})
})
40 changes: 40 additions & 0 deletions components/generic-charts/card-metric.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
'use client'

import { cn } from '@/lib/utils'

export interface CardMetricProps {
current: number
target: number
currentReadable?: string
targetReadable?: string
className?: string
}

export function CardMetric({
current,
target,
currentReadable,
targetReadable,
className,
}: CardMetricProps) {
const percent = (current / target) * 100

return (
<div className={cn('flex flex-col gap-4', className)}>
<div className="text-xl md:text-3xl">{currentReadable || current}</div>

<div>
<div className="mt-2 flex flex-row items-center justify-between gap-2">
<span
className="truncate text-muted-foreground"
title={`${percent}%`}
>
{currentReadable || current}
</span>
<hr className="shrink grow border-dotted" />
<span className="text-nowrap">{targetReadable || target}</span>
</div>
</div>
</div>
)
}
7 changes: 5 additions & 2 deletions components/generic-charts/card-multi-metrics.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,15 @@ export function CardMultiMetrics({
) : null}

{items.map((item, i) => {
const _percent = (item.current / item.target) * 100
const percent = (item.current / item.target) * 100

return (
<div key={i}>
<div className="mt-2 flex flex-row items-center justify-between gap-2">
<span className="truncate text-muted-foreground">
<span
className="truncate text-muted-foreground"
title={`${percent}%`}
>
{item.currentReadable}
</span>
<hr className="shrink grow border-dotted" />
Expand Down
35 changes: 0 additions & 35 deletions components/tremor/card-metric.tsx

This file was deleted.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
"react-dom": "^19.0.0-rc-0bc30748-20241028",
"react-error-boundary": "^4.1.2",
"react-hook-form": "^7.53.1",
"react-markdown": "^9.0.1",
"react-resizable-panels": "^2.1.6",
"recharts": "^2.13.1",
"server-only-context": "^0.1.0",
Expand Down
3 changes: 3 additions & 0 deletions types/column-format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { type CodeDialogOptions } from '@/components/data-table/cells/code-dialo
import { type CodeToggleOptions } from '@/components/data-table/cells/code-toggle-format'
import { type ColoredBadgeOptions } from '@/components/data-table/cells/colored-badge-format'
import { type HoverCardOptions } from '@/components/data-table/cells/hover-card-format'
import { MarkdownFormatOptions } from '@/components/data-table/cells/markdown-format'
import { type TextFormatOptions } from '@/components/data-table/cells/text-format'

export enum ColumnFormat {
Expand All @@ -17,6 +18,7 @@ export enum ColumnFormat {
CodeDialog = 'code-dialog',
HoverCard = 'hover-card',
Duration = 'duration',
Markdown = 'markdown',
Boolean = 'boolean',
Action = 'action',
Number = 'number',
Expand All @@ -31,6 +33,7 @@ export type ColumnFormatWithArgs =
| [ColumnFormat.Action, Action[]]
| [ColumnFormat.Link, LinkProps & { className?: string }]
| [ColumnFormat.Text, TextFormatOptions]
| [ColumnFormat.Markdown, MarkdownFormatOptions]
| [ColumnFormat.ColoredBadge, ColoredBadgeOptions]
| [ColumnFormat.HoverCard, HoverCardOptions]
| [ColumnFormat.CodeDialog, CodeDialogOptions]
Expand Down
Loading

1 comment on commit 245ca28

@vercel
Copy link

@vercel vercel bot commented on 245ca28 Nov 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.