Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/restyle-history.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@graphiql/plugin-history': patch
---

Restyle to the v6 design. New row layout with status dot, mono name label, and inline variables snippet. Uses `PanelHeader` for the panel chrome.
168 changes: 105 additions & 63 deletions packages/graphiql-plugin-history/src/components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
Button,
Tooltip,
UnStyledButton,
PanelHeader,
} from '@graphiql/react';
import { useHistory, useHistoryActions } from './context';

Expand Down Expand Up @@ -64,24 +65,28 @@ export const History: FC = () => {
const hasFavorites = Boolean(favorites.length);
const hasItems = Boolean(items.length);

const clearButton =
clearStatus || hasItems ? (
<Button
type="button"
state={clearStatus || undefined}
disabled={!items.length}
onClick={handleClearStatus}
>
{{
success: 'Cleared',
error: 'Failed to Clear',
}[clearStatus!] || 'Clear'}
</Button>
) : undefined;

return (
<section aria-label="History" className="graphiql-history">
<div className="graphiql-history-header">
History
{(clearStatus || hasItems) && (
<Button
type="button"
state={clearStatus || undefined}
disabled={!items.length}
onClick={handleClearStatus}
>
{{
success: 'Cleared',
error: 'Failed to Clear',
}[clearStatus!] || 'Clear'}
</Button>
)}
</div>
<PanelHeader
title="History"
subtitle="Last 20 runs."
actions={clearButton}
/>

{hasFavorites && (
<ul className="graphiql-history-items">
Expand Down Expand Up @@ -166,6 +171,10 @@ export const HistoryItem: FC<QueryHistoryItemProps> = props => {
toggleFavorite(props.item);
};

const variablesSnippet = props.item.variables
? formatVariables(props.item.variables)
: null;

return (
<li className={cn('graphiql-history-item', isEditable && 'editable')}>
{isEditable ? (
Expand Down Expand Up @@ -193,54 +202,71 @@ export const HistoryItem: FC<QueryHistoryItemProps> = props => {
</>
) : (
<>
<Tooltip label="Set active">
<UnStyledButton
type="button"
className="graphiql-history-item-label"
onClick={handleHistoryItemClick}
aria-label="Set active"
>
{displayName}
</UnStyledButton>
</Tooltip>
<Tooltip label="Edit label">
<UnStyledButton
type="button"
className="graphiql-history-item-action"
onClick={handleEditLabel}
aria-label="Edit label"
>
<PenIcon aria-hidden="true" />
</UnStyledButton>
</Tooltip>
<Tooltip
label={props.item.favorite ? 'Remove favorite' : 'Add favorite'}
>
<UnStyledButton
type="button"
className="graphiql-history-item-action"
onClick={handleToggleFavorite}
aria-label={
props.item.favorite ? 'Remove favorite' : 'Add favorite'
}
<div className="graphiql-history-item-inner">
<div className="graphiql-history-item-row">
<span
className="graphiql-history-item-status"
aria-hidden="true"
/>
<Tooltip label="Set active">
<UnStyledButton
type="button"
className="graphiql-history-item-label"
onClick={handleHistoryItemClick}
aria-label="Set active"
>
{displayName}
</UnStyledButton>
</Tooltip>
</div>
{variablesSnippet && (
<div className="graphiql-history-item-meta">
<span className="graphiql-history-item-variables">
{variablesSnippet}
</span>
</div>
)}
</div>
<div className="graphiql-history-item-actions">
<Tooltip label="Edit label">
<UnStyledButton
type="button"
className="graphiql-history-item-action"
onClick={handleEditLabel}
aria-label="Edit label"
>
<PenIcon aria-hidden="true" />
</UnStyledButton>
</Tooltip>
<Tooltip
label={props.item.favorite ? 'Remove favorite' : 'Add favorite'}
>
{props.item.favorite ? (
<StarFilledIcon aria-hidden="true" />
) : (
<StarIcon aria-hidden="true" />
)}
</UnStyledButton>
</Tooltip>
<Tooltip label="Delete from history">
<UnStyledButton
type="button"
className="graphiql-history-item-action"
onClick={handleDeleteItemFromHistory}
aria-label="Delete from history"
>
<TrashIcon aria-hidden="true" />
</UnStyledButton>
</Tooltip>
<UnStyledButton
type="button"
className="graphiql-history-item-action"
onClick={handleToggleFavorite}
aria-label={
props.item.favorite ? 'Remove favorite' : 'Add favorite'
}
>
{props.item.favorite ? (
<StarFilledIcon aria-hidden="true" />
) : (
<StarIcon aria-hidden="true" />
)}
</UnStyledButton>
</Tooltip>
<Tooltip label="Delete from history">
<UnStyledButton
type="button"
className="graphiql-history-item-action"
onClick={handleDeleteItemFromHistory}
aria-label="Delete from history"
>
<TrashIcon aria-hidden="true" />
</UnStyledButton>
</Tooltip>
</div>
</>
)}
</li>
Expand All @@ -256,3 +282,19 @@ export function formatQuery(query?: string) {
.replaceAll('}', ' } ')
.replaceAll(/[\s]{2,}/g, ' ');
}

export function formatVariables(variables: string) {
try {
const parsed = JSON.parse(variables) as Record<string, unknown>;
const entries = Object.entries(parsed);
if (!entries.length) {
return null;
}
return entries
.slice(0, 3)
.map(([k, v]) => `${k}: ${JSON.stringify(v)}`)
.join(', ');
} catch {
return variables.slice(0, 60);
}
}
Loading
Loading