Skip to content

Commit

Permalink
Packages follow ups (#392)
Browse files Browse the repository at this point in the history
* Rename note -> toast and touch ups to simplify code

* Clean up the packages panel and install deps
  • Loading branch information
nichochar authored Oct 20, 2024
1 parent 0ba7559 commit 32d0901
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 163 deletions.
126 changes: 0 additions & 126 deletions packages/web/src/components/apps/package-install-note.tsx

This file was deleted.

112 changes: 112 additions & 0 deletions packages/web/src/components/apps/package-install-toast.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import { useEffect, useState } from 'react';
import { CircleAlertIcon, InfoIcon, Loader2Icon, XIcon } from 'lucide-react';

import { usePackageJson } from './use-package-json';
import { useLogs } from './use-logs';
import { Button } from '@srcbook/components/src/components/ui/button';
import { cn } from '@/lib/utils';

const ToastWrapper: React.FC<{ showToast: boolean; children: React.ReactNode }> = ({
showToast,
children,
}) => (
<div
className={cn(
'absolute bottom-4 left-4 z-20 bg-muted border flex items-center gap-4 p-4',
'rounded-lg transition-all duration-150 ease-in-out',
{
'opacity-0 -bottom-8': !showToast,
},
)}
>
{children}
</div>
);

const PackageInstallToast: React.FunctionComponent = () => {
const { togglePane } = useLogs();
const { status, npmInstall, nodeModulesExists } = usePackageJson();
const [showToast, setShowToast] = useState(false);

useEffect(() => {
if (nodeModulesExists === false && (status === 'idle' || status === 'complete')) {
setShowToast(true);
}
}, [nodeModulesExists, status]);

switch (status) {
case 'installing':
return (
<ToastWrapper showToast={showToast}>
<Loader2Icon size={18} className="animate-spin" />
<span className="select-none">Installing Packages...</span>

<Button
className="active:translate-y-0"
onClick={() => {
alert('todo');
setShowToast(false);
}}
>
Cancel
</Button>
</ToastWrapper>
);

case 'failed':
return (
<ToastWrapper showToast={showToast}>
<CircleAlertIcon size={18} />
<span className="font-medium select-none">Packages failed to install</span>

<Button
className="active:translate-y-0"
onClick={() => {
togglePane();
setShowToast(false);
}}
>
More info
</Button>

<Button
variant="secondary"
size="icon"
onClick={() => setShowToast(false)}
className="active:translate-y-0"
>
<XIcon size={18} />
</Button>
</ToastWrapper>
);

case 'idle':
case 'complete':
return (
<ToastWrapper showToast={showToast}>
<InfoIcon size={18} />
<span className="select-none">Packages need to be installed</span>

<div className="flex items-center gap-2">
<Button
className="active:translate-y-0"
onClick={() => npmInstall().then(() => setShowToast(false))}
>
Install
</Button>

<Button
variant="secondary"
size="icon"
onClick={() => setShowToast(false)}
className="active:translate-y-0"
>
<XIcon size={18} />
</Button>
</div>
</ToastWrapper>
);
}
};

export default PackageInstallToast;
58 changes: 34 additions & 24 deletions packages/web/src/components/apps/panels/settings.tsx
Original file line number Diff line number Diff line change
@@ -1,47 +1,57 @@
import { Button } from '@srcbook/components/src/components/ui/button';
import { usePackageJson } from '../use-package-json';

export default function SettingsPanel() {
export default function PackagesPanel() {
const { status, output, npmInstall, clearNodeModules, nodeModulesExists } = usePackageJson();

return (
<div className="flex flex-col gap-4 px-5 w-[360px]">
<p className="text-sm text-tertiary-foreground">
Clear your node_modules, re-install packages and inspect the output logs from{' '}
<pre>npm install</pre>
</p>
<div>
<Button onClick={() => npmInstall()} disabled={status === 'installing'}>
Run npm install
</Button>
</div>
<div>
<Button
onClick={() => npmInstall(['uuid'])}
variant="secondary"
disabled={status === 'installing'}
>
Run npm install uuid
</Button>
</div>
<div>
exists={JSON.stringify(nodeModulesExists)}
<Button
onClick={() => clearNodeModules()}
variant="secondary"
disabled={nodeModulesExists !== true}
>
Clear node_modules
</Button>
</div>

{status !== 'idle' ? (
<>
<span>
Status: <code>{status}</code>
</span>
<pre className="font-mono text-sm bg-tertiary p-2 overflow-auto rounded-md border">
<h3 className="text-sm font-medium">Logs</h3>
<pre className="font-mono text-xs bg-tertiary p-2 overflow-auto rounded-md border">
{/* FIXME: disambiguate between stdout and stderr in here using n.type! */}
{output.map((n) => n.data).join('\n')}
</pre>
</>
) : null}

{process.env.NODE_ENV !== 'production' && (
<>
<span>
Status: <code>{status}</code>
</span>
<div>
<Button
onClick={() => npmInstall(['uuid'])}
variant="secondary"
disabled={status === 'installing'}
>
Run npm install uuid
</Button>
</div>
<div>
exists={JSON.stringify(nodeModulesExists)}
<Button
onClick={() => clearNodeModules()}
variant="secondary"
disabled={nodeModulesExists !== true}
>
Clear node_modules
</Button>
</div>
</>
)}
</div>
);
}
22 changes: 13 additions & 9 deletions packages/web/src/components/apps/sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
FolderTreeIcon,
KeyboardIcon,
MoonIcon,
SettingsIcon,
PackageIcon,
SunIcon,
} from 'lucide-react';
import { Button } from '@srcbook/components/src/components/ui/button';
Expand All @@ -21,16 +21,17 @@ import KeyboardShortcutsDialog from '../keyboard-shortcuts-dialog';
import FeedbackDialog from '../feedback-dialog';
import { cn } from '@/lib/utils';
import ExplorerPanel from './panels/explorer';
import SettingsPanel from './panels/settings';
import PackagesPanel from './panels/settings';
import { usePackageJson } from './use-package-json';

export type PanelType = 'explorer' | 'settings';
export type PanelType = 'explorer' | 'packages';

function getTitleForPanel(panel: PanelType | null): string | null {
switch (panel) {
case 'explorer':
return 'Files';
case 'settings':
return 'Settings';
case 'packages':
return 'Manage Packages';
default:
return null;
}
Expand All @@ -46,6 +47,7 @@ export default function Sidebar({ panel, onChangePanel }: SidebarProps) {

const [showShortcuts, setShowShortcuts] = useState(false);
const [showFeedback, setShowFeedback] = useState(false);
const { status } = usePackageJson();

function setPanel(nextPanel: PanelType) {
onChangePanel(nextPanel === panel ? null : nextPanel);
Expand All @@ -70,14 +72,16 @@ export default function Sidebar({ panel, onChangePanel }: SidebarProps) {
)}
/>
</NavItemWithTooltip>
<NavItemWithTooltip tooltipContent="Settings" onClick={() => setPanel('settings')}>
<SettingsIcon
<NavItemWithTooltip tooltipContent="Packages" onClick={() => setPanel('packages')}>
<PackageIcon
size={18}
className={cn(
'transition-colors',
panel === 'settings'
panel === 'packages'
? 'text-secondary-foreground'
: 'text-tertiary-foreground hover:text-secondary-foreground',
status === 'installing' && 'text-run',
status === 'failed' && 'text-error',
)}
/>
</NavItemWithTooltip>
Expand Down Expand Up @@ -129,7 +133,7 @@ export default function Sidebar({ panel, onChangePanel }: SidebarProps) {
}}
>
{panel === 'explorer' && <ExplorerPanel />}
{panel === 'settings' && <SettingsPanel />}
{panel === 'packages' && <PackagesPanel />}
</Panel>
</div>
</>
Expand Down
Loading

0 comments on commit 32d0901

Please sign in to comment.