Skip to content

Commit

Permalink
♻️ Create Preformatted component to render JSON (#505)
Browse files Browse the repository at this point in the history
* fix close handler for email device modal

* create and reuse preformatted component

* optional title

* use component in another place
xendke authored Nov 18, 2024
1 parent 304f6a2 commit d744f66
Showing 8 changed files with 53 additions and 26 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Accordion, Text } from '@stump/components'
import { Accordion, Preformatted, Text } from '@stump/components'
import { useMemo } from 'react'
import { useFormContext, useWatch } from 'react-hook-form'

@@ -19,7 +19,6 @@ export default function FilterConfigJSON() {
}),
[groups, joiner],
)
const formattedFilters = useMemo(() => JSON.stringify(apiFilters, null, 2), [apiFilters])

return (
<Accordion type="single" collapsible>
@@ -32,8 +31,8 @@ export default function FilterConfigJSON() {
</Text>
</div>
</Accordion.Trigger>
<Accordion.Content className="rounded-md bg-background-surface p-4">
<pre className="text-xs text-foreground-subtle">{formattedFilters}</pre>
<Accordion.Content>
<Preformatted content={apiFilters} />
</Accordion.Content>
</Accordion.Item>
</Accordion>
Original file line number Diff line number Diff line change
@@ -66,7 +66,7 @@ export default function CreateOrUpdateDeviceModal({ isOpen, updatingDevice, onCl
await invalidateQueries({ keys: [sdk.emailer.keys.getDevices] })
}

const onOpenChange = (nowOpen: boolean) => (nowOpen ? onClose() : null)
const onOpenChange = (nowOpen: boolean) => (!nowOpen ? onClose() : null)

return (
<Dialog open={isOpen} onOpenChange={onOpenChange}>
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Sheet, Text, usePrevious } from '@stump/components'
import { Preformatted, Sheet, usePrevious } from '@stump/components'
import { CoreJobOutput } from '@stump/sdk'

type Props = {
@@ -17,18 +17,7 @@ export default function JobDataInspector({ data, onClose }: Props) {
title="Job data"
description="The final output of the job after it had completed"
>
<div className="flex flex-col pb-0">
<div className="flex h-10 items-center bg-background-surface px-4">
<Text size="sm" className="font-medium">
Raw JSON
</Text>
</div>
<div className="rounded-sm bg-background-surface p-4">
<pre className="text-xs text-foreground-subtle">
{JSON.stringify(displayedData, null, 2)}
</pre>
</div>
</div>
<Preformatted title="Raw JSON" content={displayedData} />
</Sheet>
)
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Sheet } from '@stump/components'
import { Preformatted } from '@stump/components'
import { User } from '@stump/sdk'

type Props = {
@@ -15,9 +16,7 @@ export default function InspectUserSlideOver({ user, onClose }: Props) {
title="Inspect user"
description="Inspect a user's information and configuration"
>
<div className="px-6 py-2">
<pre>{JSON.stringify(user, null, 2)}</pre>
</div>
<Preformatted title="Raw JSON" content={user} />
</Sheet>
)
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
import { Accordion, Alert, Button, Drawer, IconButton, Text, ToolTip } from '@stump/components'
import {
Accordion,
Alert,
Button,
Drawer,
IconButton,
Preformatted,
Text,
ToolTip,
} from '@stump/components'
import { useLocaleContext } from '@stump/i18n'
import { Construction, Filter } from 'lucide-react'

@@ -42,10 +51,8 @@ export default function FilterBottomDrawer() {
<Text size="sm" variant="muted">
{t(withLocaleKey('rawData.description'))}
</Text>
<div className="mt-1.5 rounded-sm bg-background-surface p-4">
<pre className="text-xs text-foreground-subtle">
{JSON.stringify(filters, null, 2)}
</pre>
<div className="mt-1.5">
<Preformatted content={filters} />
</div>
</Accordion.Content>
</Accordion.Item>
1 change: 1 addition & 0 deletions packages/components/src/index.ts
Original file line number Diff line number Diff line change
@@ -41,6 +41,7 @@ export {
export { Link } from './link'
export { NavigationMenu, navigationMenuTriggerStyle } from './navigation'
export { Popover } from './popover'
export { Preformatted, type PreformattedProps } from './preformatted'
export { FullScreenLoader, ProgressBar, type ProgressBarProps, ProgressSpinner } from './progress'
export { RadioGroup } from './radio'
export { ScrollArea, ScrollBar } from './scroll-area'
31 changes: 31 additions & 0 deletions packages/components/src/preformatted/Preformatted.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { useMemo } from 'react'

import { Any } from '..'
import { Text } from '../text'

export type PreformattedProps = { title?: string; content: Any }

export function Preformatted({ title, content }: PreformattedProps) {
const memoContent = useMemo(() => JSON.stringify(content, null, 2), [content])

const formatted = (
<div className="rounded-sm bg-background-surface p-4">
<pre className="text-xs text-foreground-subtle">{memoContent}</pre>
</div>
)

if (!title) {
return formatted
}

return (
<div className="flex flex-col pb-0">
<div className="flex h-10 items-center bg-background-surface px-4">
<Text size="sm" className="font-medium">
{title}
</Text>
</div>
{formatted}
</div>
)
}
1 change: 1 addition & 0 deletions packages/components/src/preformatted/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { Preformatted, type PreformattedProps } from './Preformatted'

0 comments on commit d744f66

Please sign in to comment.