Skip to content

Commit

Permalink
Live URLS feature
Browse files Browse the repository at this point in the history
  • Loading branch information
AlemTuzlak committed Aug 26, 2024
1 parent f8f9d36 commit 6cdc617
Show file tree
Hide file tree
Showing 9 changed files with 134 additions and 13 deletions.
15 changes: 15 additions & 0 deletions docs/posts/main/configuration/client.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ Before we explain all the possible options here is the client configuration Type
```ts
type RdtClientConfig = {
position: "top-left" | "top-right" | "bottom-left" | "bottom-right" | "middle-left" | "middle-right";
liveUrls: { name: string, url: string }[];
liveUrlsPosition: "top-left" | "top-right" | "bottom-left" | "bottom-right";
defaultOpen: boolean;
expansionLevel: number;
height: number;
Expand All @@ -31,6 +33,19 @@ type RdtClientConfig = {
Let's go through each option and see what it does.
## Live URLs
This option is used to set the live urls that will be displayed in the bottom left corner of the screen. The default value is an empty array.
It allows you to specify multiple live urls that you can use to open the current page in a new tab.
## Live URLs position
This option is used to set the position of the live urls that will be displayed in the bottom left corner of the screen. The possible values are:
- `top-left` - the live urls will be positioned at the top left corner of the screen
- `top-right` - the live urls will be positioned at the top right corner of the screen
- `bottom-left` - the live urls will be positioned at the bottom left corner of the screen
- `bottom-right` - the live urls will be positioned at the bottom right corner of the screen
## Position
This option is used to set the position of the Remix Development Tools trigger (the button that opens the panel). The possible values are:
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "remix-development-tools",
"description": "Remix development tools - a set of tools for developing/debugging Remix.run apps",
"author": "Alem Tuzlak",
"version": "4.3.3",
"version": "4.4.0",
"license": "MIT",
"keywords": [
"remix",
Expand Down
29 changes: 26 additions & 3 deletions src/client/RemixDevTools.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { RDTContextProvider, RdtClientConfig } from "./context/RDTContext.js";
import { Tab } from "./tabs/index.js";
import { useTimelineHandler } from "./hooks/useTimelineHandler.js";
import { useDetachedWindowControls, usePersistOpen, useSettingsContext } from "./context/useRDTContext.js";
import { useLocation } from "@remix-run/react";
import { Link, useLocation } from "@remix-run/react";
import { Trigger } from "./components/Trigger.js";
import { MainPanel } from "./layout/MainPanel.js";
import { Tabs } from "./layout/Tabs.js";
Expand All @@ -26,6 +26,7 @@ import { useDebounce } from "./hooks/useDebounce.js";
import { useListenToRouteChange } from "./hooks/detached/useListenToRouteChange.js";
import { RdtPlugin } from "../index.js";
import { useHotkeys } from "react-hotkeys-hook";
import clsx from "clsx";

const recursivelyChangeTabIndex = (node: Element | HTMLElement, remove = true) => {
if(remove){
Expand All @@ -38,6 +39,27 @@ const recursivelyChangeTabIndex = (node: Element | HTMLElement, remove = true) =
}
};

const LiveUrls = () =>{
const { settings } = useSettingsContext();
const location = useLocation();
const envsPosition = settings.liveUrlsPosition;
const envsClassName = {
"rdt-bottom-0": envsPosition === "bottom-left" || envsPosition === "bottom-right",
"rdt-top-0": envsPosition === "top-left" || envsPosition === "top-right",
"rdt-right-0": envsPosition === "bottom-right" || envsPosition === "top-right",
"rdt-left-0": envsPosition === "bottom-left" || envsPosition === "top-left",
}
if(settings.liveUrls.length === 0) return null;
return <div className={clsx("rdt-flex rdt-fixed rdt-items-center rdt-gap-2 rdt-px-2", envsClassName)}>
{settings.liveUrls.map((env) => {
return <Link key={env.name} referrerPolicy="no-referrer" target="_blank" to={env.url+location.pathname} className="rdt-flex rdt-transition-all hover:rdt-text-black rdt-items-center rdt-gap-2 rdt-text-sm rdt-font-semibold rdt-text-gray-400">
{env.name}
</Link>
})}
</div>

}

const DevTools = ({ plugins: pluginArray }: RemixDevToolsProps) => {
useTimelineHandler();
useResetDetachmentCheck();
Expand Down Expand Up @@ -85,17 +107,18 @@ const DevTools = ({ plugins: pluginArray }: RemixDevToolsProps) => {
}

return (
<>

<div id={REMIX_DEV_TOOLS} className="remix-dev-tools">
<Trigger isOpen={isOpen} setIsOpen={setIsOpen} />
<LiveUrls />
<MainPanel isOpen={isOpen}>
<div className="rdt-flex rdt-h-full">
<Tabs plugins={plugins} setIsOpen={setIsOpen} />
<ContentPanel leftSideOriented={leftSideOriented} plugins={plugins} />
</div>
</MainPanel>
</div>
</>

);
};

Expand Down
15 changes: 11 additions & 4 deletions src/client/components/RouteNode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,45 @@ import clsx from "clsx";
import { RouteWildcards } from "../context/rdtReducer.js";
import { ExtendedRoute, getRouteColor } from "../utils/routing.js";
import { CustomNodeElementProps } from "../../external/react-d3-tree/index.js";
import type { useNavigate } from "@remix-run/react";

export const RouteNode = ({
nodeDatum,
hierarchyPointNode,
toggleNode,
setActiveRoute,
activeRoutes,
navigate
}: CustomNodeElementProps & {
routeWildcards: RouteWildcards;
setActiveRoute: (e: ExtendedRoute) => void;
activeRoutes: string[];
navigate: ReturnType<typeof useNavigate>;
}) => {

const parent = hierarchyPointNode.parent?.data;
const parentName = parent && parent?.name !== "/" ? parent.name : "";
const name = nodeDatum.name.replace(parentName, "") ?? "/";
const route = { ...nodeDatum, ...nodeDatum.attributes } as any as ExtendedRoute;
return (
<g className="rdt-flex">
<g className="rdt-flex">
<circle
x={20}
onClick={toggleNode}
onClick={toggleNode}
className={clsx(
getRouteColor(route),
"rdt-stroke-white",
nodeDatum.__rd3t.collapsed && nodeDatum.children?.length && "rdt-fill-gray-800"
)}
r={12}
></circle>
<g>
<foreignObject y={-15} x={17} width={110} height={140}>
<g >
<foreignObject y={-15} x={17} width={110} height={140}>
<p
onClick={() => setActiveRoute(route)}
onDoubleClickCapture={() => {
navigate(route.url)
}}
style={{ width: 100, fontSize: 14 }}
className={clsx(
"rdt-w-full rdt-break-all rdt-fill-white rdt-stroke-transparent",
Expand Down
8 changes: 4 additions & 4 deletions src/client/context/RDTContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,22 +70,22 @@ export const getExistingStateFromStorage = (config?: RdtClientConfig) => {
const settings = getSettings();
const { detachedWindow, detachedWindowOwner } = detachedModeSetup();
const state: RemixDevToolsState = {
...initialState,

...initialState,
...(existingState ? JSON.parse(existingState) : {}),
settings: {
...initialState.settings,
...config,
...settings,
liveUrls: config?.liveUrls ?? initialState.settings.liveUrls,
},
detachedWindow,
detachedWindowOwner,
};

return state;
};

export type RdtClientConfig = Pick<RemixDevToolsState["settings"], "defaultOpen" | "expansionLevel" | "position" | "height" | "minHeight" | "maxHeight" | "hideUntilHover" | "panelLocation" | "requireUrlFlag" | "urlFlag" | "routeBoundaryGradient">
export type RdtClientConfig = Pick<RemixDevToolsState["settings"], "defaultOpen" | "expansionLevel" | "liveUrls" | "position" | "height" | "minHeight" | "maxHeight" | "hideUntilHover" | "panelLocation" | "requireUrlFlag" | "urlFlag" | "routeBoundaryGradient">


export const RDTContextProvider = ({ children, config }: ContextProps) => {
Expand Down
56 changes: 56 additions & 0 deletions src/client/context/rdtReducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,25 +69,79 @@ export type RemixDevToolsState = {
timeline: TimelineEvent[];
terminals: Terminal[];
settings: {
/**
* The live urls to show in the corner which allow you to open the app in a different environment (eg. staging, production)
* @default []
*/
liveUrls: { url: string, name: string }[];
/**
* The position of the live urls
* @default "bottom-left"
*/
liveUrlsPosition: "bottom-left" | "bottom-right" | "top-left" | "top-right";
/**
* The route boundary gradient color to use
* @default "silver"
*/
routeBoundaryGradient: keyof typeof ROUTE_BOUNDARY_GRADIENTS;
routeWildcards: RouteWildcards;
activeTab: Tabs;
shouldConnectWithForge: boolean;
port: number;
height: number;
/**
* The maximum height of the panel
* @default 800
*/
maxHeight: number;
/**
* The minimum height of the panel
* @default 200
*/
minHeight: number;
/**
* Whether the dev tools should be open by default
* @default false
*/
defaultOpen: boolean;
/**
* Whether the dev tools trigger should be hidden until the user hovers over it
* @default false
*/
hideUntilHover: boolean;
/**
* The position of the trigger button
* @default "bottom-right"
*/
position: TriggerPosition;
/**
* The initial expansion level of the JSON viewer objects
* @default 0
*/
expansionLevel: number;
hoveredRoute: string;
isHoveringRoute: boolean;
routeViewMode: "list" | "tree";
/**
* The location of the panel once it is open
* @default "bottom"
*/
panelLocation: "top" | "bottom";
withServerDevTools: boolean;
/**
* The hotkey to open the dev tools
* @default "shift+a"
*/
openHotkey: string;
/**
* Whether to require the URL flag to open the dev tools
* @default false
*/
requireUrlFlag: boolean;
/**
* The URL flag to open the dev tools, used in conjunction with requireUrlFlag (if set to true)
* @default "rdt"
*/
urlFlag: string;
};
htmlErrors: HTMLError[];
Expand All @@ -102,6 +156,8 @@ export const initialState: RemixDevToolsState = {
terminals: [{ id: 0, locked: false, output: [], history: [] }],
server: undefined,
settings: {
liveUrls: [],
liveUrlsPosition: "bottom-left",
routeBoundaryGradient: "silver",
routeWildcards: {},
activeTab: "page",
Expand Down
1 change: 1 addition & 0 deletions src/client/tabs/RoutesTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ const RoutesTab = () => {
routeWildcards,
setActiveRoute,
activeRoutes,
navigate
})
}
orientation="vertical"
Expand Down
13 changes: 13 additions & 0 deletions src/client/tabs/SettingsTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,19 @@ export const SettingsTab = () => {
]}
hint="This will determine where your trigger position on the screen is when the tools are collapsed."
/>
<SelectWithOptions
label="Environments position"
onSelect={(value) => setSettings({ liveUrlsPosition: value as any })}
value={settings.position}
className="rdt-w-full"
options={[
{ label: "Bottom Right", value: "bottom-right" },
{ label: "Bottom Left", value: "bottom-left" },
{ label: "Top Right", value: "top-right" },
{ label: "Top Left", value: "top-left" },
]}
hint="This will determine where your environments position on the screen is."
/>
<SelectWithOptions
label="Panel position"
onSelect={(value) => setSettings({ panelLocation: value })}
Expand Down
8 changes: 7 additions & 1 deletion src/test-apps/remix-vite/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@ const config = defineRdtConfig({
defaultOpen: false,
panelLocation: "top",
position: "top-right",
requireUrlFlag: false
requireUrlFlag: false,
liveUrls: [
{ url: "https://forge42.dev", name: "Production" },
{
url: "https://forge42.dev/staging",
name: "Staging",
}],
},server: {
silent: true,
},
Expand Down

0 comments on commit 6cdc617

Please sign in to comment.