Skip to content

Commit 7d25479

Browse files
committed
[Dashboard] Add Insight blueprint playground (#5631)
DASH-554 <!-- start pr-codex --> --- ## PR-Codex overview This PR primarily focuses on the removal of certain components related to `BlueprintsPage`, updates to the `useHeightObserver` function, and enhancements to the `BlueprintPlayground` functionality, including new utility functions for fetching blueprint data. ### Detailed summary - Deleted components: `BlueprintsPage`, `BlueprintsExplorer`, `BlueprintsPageHeader`. - Updated `useHeightObserver` to be an exported function. - Changed height from `40px` to `32px` in CSS. - Added new props (`scrollableContainerClassName`, `shadowColor`) to several components. - Implemented a new utility for fetching blueprints and their specifications. - Enhanced `BlueprintPlayground` to handle fetching and displaying blueprints. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` <!-- end pr-codex -->
1 parent bc368c5 commit 7d25479

17 files changed

+1315
-152
lines changed

apps/dashboard/src/@/components/blocks/NetworkSelectors.tsx

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,17 +85,29 @@ export function MultiNetworkSelector(props: {
8585
export function SingleNetworkSelector(props: {
8686
chainId: number | undefined;
8787
onChange: (chainId: number) => void;
88+
className?: string;
89+
popoverContentClassName?: string;
90+
// if specified - only these chains will be shown
91+
chainIds?: number[];
8892
}) {
8993
const { allChains, idToChain } = useAllChainsData();
9094

95+
const chainsToShow = useMemo(() => {
96+
if (!props.chainIds) {
97+
return allChains;
98+
}
99+
const chainIdSet = new Set(props.chainIds);
100+
return allChains.filter((chain) => chainIdSet.has(chain.chainId));
101+
}, [allChains, props.chainIds]);
102+
91103
const options = useMemo(() => {
92-
return allChains.map((chain) => {
104+
return chainsToShow.map((chain) => {
93105
return {
94106
label: chain.name,
95107
value: String(chain.chainId),
96108
};
97109
});
98-
}, [allChains]);
110+
}, [chainsToShow]);
99111

100112
const searchFn = useCallback(
101113
(option: Option, searchValue: string) => {
@@ -132,17 +144,22 @@ export function SingleNetworkSelector(props: {
132144
[idToChain],
133145
);
134146

147+
const isLoadingChains = allChains.length === 0;
148+
135149
return (
136150
<SelectWithSearch
137-
searchPlaceholder="Search by Name or Chain Id"
151+
searchPlaceholder="Search by Name or Chain ID"
138152
value={String(props.chainId)}
139153
options={options}
140154
onValueChange={(chainId) => {
141155
props.onChange(Number(chainId));
142156
}}
143-
placeholder="Select Chain"
157+
placeholder={isLoadingChains ? "Loading Chains..." : "Select Chain"}
144158
overrideSearchFn={searchFn}
145159
renderOption={renderOption}
160+
className={props.className}
161+
popoverContentClassName={props.popoverContentClassName}
162+
disabled={isLoadingChains}
146163
/>
147164
);
148165
}

apps/dashboard/src/@/components/blocks/select-with-search.tsx

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,26 @@ interface SelectWithSearchProps
3030
searchTerm: string,
3131
) => boolean;
3232
renderOption?: (option: { value: string; label: string }) => React.ReactNode;
33+
popoverContentClassName?: string;
3334
}
3435

3536
export const SelectWithSearch = React.forwardRef<
3637
HTMLButtonElement,
3738
SelectWithSearchProps
3839
>(
3940
(
40-
{ options, onValueChange, placeholder, className, value, ...props },
41+
{
42+
options,
43+
onValueChange,
44+
placeholder,
45+
className,
46+
value,
47+
renderOption,
48+
overrideSearchFn,
49+
popoverContentClassName,
50+
searchPlaceholder,
51+
...props
52+
},
4153
ref,
4254
) => {
4355
const [isPopoverOpen, setIsPopoverOpen] = React.useState(false);
@@ -49,7 +61,6 @@ export const SelectWithSearch = React.forwardRef<
4961

5062
// show 50 initially and then 20 more when reaching the end
5163
const { itemsToShow, lastItemRef } = useShowMore<HTMLButtonElement>(50, 20);
52-
const { overrideSearchFn } = props;
5364

5465
const optionsToShow = useMemo(() => {
5566
const filteredOptions: {
@@ -122,7 +133,7 @@ export const SelectWithSearch = React.forwardRef<
122133
</PopoverTrigger>
123134

124135
<PopoverContent
125-
className="z-[10001] p-0"
136+
className={cn("z-[10001] p-0", popoverContentClassName)}
126137
align="center"
127138
sideOffset={10}
128139
onEscapeKeyDown={() => setIsPopoverOpen(false)}
@@ -136,7 +147,7 @@ export const SelectWithSearch = React.forwardRef<
136147
{/* Search */}
137148
<div className="relative">
138149
<Input
139-
placeholder={props.searchPlaceholder || "Search"}
150+
placeholder={searchPlaceholder || "Search"}
140151
value={searchValue}
141152
onChange={(e) => setSearchValue(e.target.value)}
142153
className="!h-auto rounded-b-none border-0 border-border border-b py-3 pl-10 focus-visible:ring-0 focus-visible:ring-offset-0"
@@ -175,9 +186,7 @@ export const SelectWithSearch = React.forwardRef<
175186
</div>
176187

177188
<div className="min-w-0 grow">
178-
{props.renderOption
179-
? props.renderOption(option)
180-
: option.label}
189+
{renderOption ? renderOption(option) : option.label}
181190
</div>
182191
</Button>
183192
);

apps/dashboard/src/@/components/ui/DynamicHeight.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export function DynamicHeight(props: {
3434
);
3535
}
3636

37-
function useHeightObserver() {
37+
export function useHeightObserver() {
3838
const elementRef = useRef<HTMLDivElement>(null);
3939
const [height, setHeight] = useState<number | undefined>();
4040

apps/dashboard/src/@/components/ui/ScrollShadow/ScrollShadow.module.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22
position: absolute;
33
left: 0;
44
width: 100%;
5-
height: 40px;
5+
height: 32px;
66
pointer-events: none;
77
}
88

99
.scrollShadowX {
1010
position: absolute;
1111
top: 0;
12-
width: 40px;
12+
width: 32px;
1313
height: 100%;
1414
pointer-events: none;
1515
}

apps/dashboard/src/@/components/ui/code/CodeBlockContainer.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ export function CodeBlockContainer(props: {
1111
children: React.ReactNode;
1212
className?: string;
1313
scrollableClassName?: string;
14+
scrollableContainerClassName?: string;
1415
copyButtonClassName?: string;
16+
shadowColor?: string;
1517
}) {
1618
const { hasCopied, onCopy } = useClipboard(props.codeToCopy);
1719

@@ -24,8 +26,11 @@ export function CodeBlockContainer(props: {
2426
>
2527
<ScrollShadow
2628
scrollableClassName={cn("p-4", props.scrollableClassName)}
27-
className="text-xs md:text-sm [&_*]:leading-relaxed"
28-
shadowColor="hsl(var(--muted))"
29+
className={cn(
30+
"text-xs md:text-sm [&_*]:leading-relaxed",
31+
props.scrollableContainerClassName,
32+
)}
33+
shadowColor={props.shadowColor || "hsl(var(--muted))"}
2934
>
3035
{props.children}
3136
</ScrollShadow>

apps/dashboard/src/@/components/ui/code/RenderCode.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,17 @@ export function RenderCode(props: {
66
className?: string;
77
scrollableClassName?: string;
88
copyButtonClassName?: string;
9+
scrollableContainerClassName?: string;
10+
shadowColor?: string;
911
}) {
1012
return (
1113
<CodeBlockContainer
1214
codeToCopy={props.code}
1315
className={props.className}
1416
copyButtonClassName={props.copyButtonClassName}
1517
scrollableClassName={props.scrollableClassName}
18+
scrollableContainerClassName={props.scrollableContainerClassName}
19+
shadowColor={props.shadowColor}
1620
>
1721
<div
1822
// biome-ignore lint/security/noDangerouslySetInnerHtml: we know what we're doing here

apps/dashboard/src/@/components/ui/code/code.client.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ export type CodeProps = {
1212
scrollableClassName?: string;
1313
keepPreviousDataOnCodeChange?: boolean;
1414
copyButtonClassName?: string;
15+
scrollableContainerClassName?: string;
16+
shadowColor?: string;
1517
ignoreFormattingErrors?: boolean;
1618
};
1719

@@ -23,6 +25,8 @@ export const CodeClient: React.FC<CodeProps> = ({
2325
keepPreviousDataOnCodeChange = false,
2426
copyButtonClassName,
2527
ignoreFormattingErrors,
28+
scrollableContainerClassName,
29+
shadowColor,
2630
}) => {
2731
const codeQuery = useQuery({
2832
queryKey: ["html", code],
@@ -43,6 +47,8 @@ export const CodeClient: React.FC<CodeProps> = ({
4347
className={className}
4448
scrollableClassName={scrollableClassName}
4549
copyButtonClassName={copyButtonClassName}
50+
scrollableContainerClassName={scrollableContainerClassName}
51+
shadowColor={shadowColor}
4652
/>
4753
);
4854
}
@@ -54,6 +60,8 @@ export const CodeClient: React.FC<CodeProps> = ({
5460
className={className}
5561
scrollableClassName={scrollableClassName}
5662
copyButtonClassName={copyButtonClassName}
63+
scrollableContainerClassName={scrollableContainerClassName}
64+
shadowColor={shadowColor}
5765
/>
5866
);
5967
};

apps/dashboard/src/@/components/ui/code/getCodeHtml.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,7 @@ function isPrettierSupportedLang(lang: BundledLanguage) {
1010
lang === "ts" ||
1111
lang === "tsx" ||
1212
lang === "javascript" ||
13-
lang === "typescript" ||
14-
lang === "css" ||
15-
lang === "json"
13+
lang === "typescript"
1614
);
1715
}
1816

apps/dashboard/src/@/components/ui/code/plaintext-code.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,17 @@ export function PlainTextCodeBlock(props: {
77
className?: string;
88
scrollableClassName?: string;
99
codeClassName?: string;
10+
scrollableContainerClassName?: string;
11+
shadowColor?: string;
1012
}) {
1113
return (
1214
<CodeBlockContainer
1315
codeToCopy={props.code}
1416
className={props.className}
1517
copyButtonClassName={props.copyButtonClassName}
1618
scrollableClassName={props.scrollableClassName}
19+
scrollableContainerClassName={props.scrollableContainerClassName}
20+
shadowColor={props.shadowColor}
1721
>
1822
<code className={cn("block whitespace-pre", props.codeClassName)}>
1923
{props.code}

0 commit comments

Comments
 (0)