-
Notifications
You must be signed in to change notification settings - Fork 21
Dedicated serial console page #1384
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
520e816
2b89b73
699ade0
bea8fb3
fd16b6d
736fffe
093c599
e2f495e
c89633d
8f51ecf
43936c6
53eb3a4
3edef70
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,107 @@ | ||
| import { Suspense, lazy } from 'react' | ||
| import { Link } from 'react-router-dom' | ||
|
|
||
| import { useApiQuery } from '@oxide/api' | ||
| import { Button } from '@oxide/ui' | ||
| import { DirectionLeftIcon, Spinner } from '@oxide/ui' | ||
| import { MiB } from '@oxide/util' | ||
|
|
||
| import { SerialConsoleStatusBadge } from 'app/components/StatusBadge' | ||
| import { useInstanceSelector } from 'app/hooks' | ||
| import { pb } from 'app/util/path-builder' | ||
|
|
||
| const Terminal = lazy(() => import('app/components/Terminal')) | ||
|
|
||
| export function SerialConsolePage() { | ||
| const { organization, project, instance } = useInstanceSelector() | ||
|
|
||
| const { isRefetching, data, refetch } = useApiQuery( | ||
| 'instanceSerialConsoleV1', | ||
| { | ||
| path: { instance }, | ||
| // holding off on using toPathQuery for now because it doesn't like numbers | ||
| query: { organization, project, maxBytes: 10 * MiB, fromStart: 0 }, | ||
| }, | ||
| { refetchOnWindowFocus: false } | ||
| ) | ||
|
|
||
| return ( | ||
| <div className="!mx-0 flex h-full max-h-[calc(100vh-60px)] !w-full flex-col"> | ||
| <Link | ||
| to={pb.instance({ organization, project, instance })} | ||
| className="mx-3 mt-3 mb-6 flex h-10 flex-shrink-0 items-center rounded px-3 bg-accent-secondary" | ||
| > | ||
| <DirectionLeftIcon className="text-accent-tertiary" /> | ||
| <div className="ml-2 text-mono-sm text-accent"> | ||
| <span className="text-accent-tertiary">Back to</span> instance | ||
| </div> | ||
| </Link> | ||
|
|
||
| <div className="gutter relative w-full flex-shrink flex-grow overflow-hidden"> | ||
| {!data && <SerialSkeleton />} | ||
| <Suspense fallback={null}> | ||
| <Terminal data={data?.data} /> | ||
| </Suspense> | ||
| </div> | ||
| <div className="flex-shrink-0 justify-between overflow-hidden border-t bg-default border-secondary empty:border-t-0"> | ||
| <div className="gutter flex h-20 items-center justify-between"> | ||
| <div> | ||
| <Button | ||
| loading={isRefetching} | ||
| size="sm" | ||
| onClick={() => refetch()} | ||
| disabled={!data} | ||
| > | ||
| Refresh | ||
| </Button> | ||
|
|
||
| <Button variant="ghost" size="sm" disabled={!data} className="ml-2"> | ||
| Equivalent CLI Command | ||
| </Button> | ||
| </div> | ||
|
|
||
| <SerialConsoleStatusBadge status={data ? 'connected' : 'connecting'} /> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| ) | ||
| } | ||
|
|
||
| function SerialSkeleton() { | ||
| const instanceSelector = useInstanceSelector() | ||
|
|
||
| return ( | ||
| <div className="relative h-full flex-shrink flex-grow overflow-hidden"> | ||
| <div className="h-full space-y-2 overflow-hidden"> | ||
| {[...Array(200)].map((_e, i) => ( | ||
| <div | ||
| key={i} | ||
| className="h-4 rounded bg-tertiary motion-safe:animate-pulse" | ||
| style={{ | ||
| width: `${Math.sin(Math.sin(i)) * 20 + 40}%`, | ||
| }} /* this is silly deterministic way to get random looking lengths */ | ||
|
Comment on lines
+81
to
+82
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wanted the text-like line lengths. If we use
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this produces a great result. If you want random that doesn't change on every render, you could do this at top level in the file so it runs only once per pageload. const rands = new Array(200).fill(0).map(() => Math.random())then this will produce a similar range to what you had. width: `${rands[i] * 40 + 20}%`But I don't think it looks better. It looks messy. RandomSine formula
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well all generative code is sine waves, why break the mould. |
||
| /> | ||
| ))} | ||
| </div> | ||
|
|
||
| <div | ||
| className="absolute bottom-0 h-full w-full" | ||
| style={{ | ||
| background: 'linear-gradient(180deg, rgba(8, 15, 17, 0) 0%, #080F11 100%)', | ||
| }} | ||
| /> | ||
| <div className="absolute top-1/2 left-1/2 flex w-96 -translate-x-1/2 -translate-y-1/2 flex-col items-center justify-center space-y-4 rounded-lg border p-12 !bg-raise border-secondary elevation-3"> | ||
| <Spinner size="lg" /> | ||
|
|
||
| <div className="space-y-2"> | ||
| <p className="text-center text-sans-xl text-default"> | ||
| Connecting to{' '} | ||
| <Link to={pb.instance(instanceSelector)} className="text-accent-secondary"> | ||
| {instanceSelector.instance} | ||
| </Link> | ||
| </p> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| ) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| import { SettingsGroup } from '@oxide/ui' | ||
|
|
||
| import { useInstanceSelector } from 'app/hooks' | ||
| import { pb } from 'app/util/path-builder' | ||
|
|
||
| export function ConnectTab() { | ||
| const { organization, project, instance } = useInstanceSelector() | ||
|
|
||
| return ( | ||
| <SettingsGroup | ||
| title="Serial Console" | ||
| docs={{ text: 'Serial Console', link: '/' }} | ||
| cta={pb.serialConsole({ organization, project, instance })} | ||
| ctaText="Connect" | ||
| > | ||
| Connect to your instance’s serial console | ||
| </SettingsGroup> | ||
| ) | ||
| } |
This file was deleted.


There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Temporary — not sure how web sockets will work with the API, so I took a stab at some potential states