From ad31e1fe9e30c942ea730dd4d5e0d4600c916b0b Mon Sep 17 00:00:00 2001 From: Jordan Phillips Date: Tue, 7 May 2024 18:35:01 +1000 Subject: [PATCH] feat: add sidebar and split components into separate files --- .../interfaces/dashboard/EncodeDialog.tsx | 105 ----------------- .../dashboard/encode-dialog/EncodeDialog.tsx | 107 ++++++++++++++++++ .../encode-dialog/EncodeDialogCommand.tsx | 23 ++++ .../encode-dialog/EncodeDialogLog.tsx | 49 ++++++++ .../encode-dialog/EncodeDialogScript.tsx | 44 +++++++ .../encode-dialog/EncodeDialogSidebar.tsx | 31 +++++ .../encode-dialog/use-encode-dialog.hook.ts | 30 +++++ .../components/interfaces/dashboard/index.ts | 1 + .../tables/encoded/EncodedTable.tsx | 2 +- .../tables/encoding/EncodingTable.tsx | 2 +- .../components/ui/code-block/CodeBlock.tsx | 4 +- 11 files changed, 289 insertions(+), 109 deletions(-) delete mode 100644 app/src/components/interfaces/dashboard/EncodeDialog.tsx create mode 100644 app/src/components/interfaces/dashboard/encode-dialog/EncodeDialog.tsx create mode 100644 app/src/components/interfaces/dashboard/encode-dialog/EncodeDialogCommand.tsx create mode 100644 app/src/components/interfaces/dashboard/encode-dialog/EncodeDialogLog.tsx create mode 100644 app/src/components/interfaces/dashboard/encode-dialog/EncodeDialogScript.tsx create mode 100644 app/src/components/interfaces/dashboard/encode-dialog/EncodeDialogSidebar.tsx create mode 100644 app/src/components/interfaces/dashboard/encode-dialog/use-encode-dialog.hook.ts create mode 100644 app/src/components/interfaces/dashboard/index.ts diff --git a/app/src/components/interfaces/dashboard/EncodeDialog.tsx b/app/src/components/interfaces/dashboard/EncodeDialog.tsx deleted file mode 100644 index 8d40a65e..00000000 --- a/app/src/components/interfaces/dashboard/EncodeDialog.tsx +++ /dev/null @@ -1,105 +0,0 @@ -import type { EncodeDialogFragment$key } from '@/__generated__/EncodeDialogFragment.graphql' - -import { Button, Card, Chip, Dialog, Typography } from '@giantnodes/react' -import { IconX } from '@tabler/icons-react' -import React from 'react' -import { graphql, useFragment, useSubscription } from 'react-relay' - -import CodeBlock from '@/components/ui/code-block/CodeBlock' -import EncodeStatusBadge from '@/components/ui/encode-badges/EncodeStatusBadge' -import ScrollAnchor from '@/components/ui/ScrollAnchor' - -const FRAGMENT = graphql` - fragment EncodeDialogFragment on Encode { - command - output - recipe { - name - } - file { - path_info { - name - } - } - ...EncodeStatusBadgeFragment - } -` - -const OUTPUTTED_SUBSCRIPTION = graphql` - subscription EncodeDialogOutputtedSubscription { - encode_outputted { - output - } - } -` - -type EncodeDialogProps = React.PropsWithChildren & { - $key: EncodeDialogFragment$key -} - -const EncodeDialog: React.FC = ({ children, $key }) => { - const data = useFragment(FRAGMENT, $key) - - useSubscription({ - subscription: OUTPUTTED_SUBSCRIPTION, - variables: {}, - }) - - return ( - - {children} - - - {({ close }) => ( - - -
-
- {data.file.path_info.name} - - - - {data.recipe.name} -
- -
- -
-
-
- - -
- {data.command && ( - - Command - - - {data.command} - - - )} - - {data.output && ( - - Logs - - - - {data.output} - - - - )} -
-
-
- )} -
-
- ) -} - -export default EncodeDialog diff --git a/app/src/components/interfaces/dashboard/encode-dialog/EncodeDialog.tsx b/app/src/components/interfaces/dashboard/encode-dialog/EncodeDialog.tsx new file mode 100644 index 00000000..8fdf68a6 --- /dev/null +++ b/app/src/components/interfaces/dashboard/encode-dialog/EncodeDialog.tsx @@ -0,0 +1,107 @@ +import type { EncodeDialogFragment$key } from '@/__generated__/EncodeDialogFragment.graphql' + +import { Button, Card, Chip, Dialog, Typography } from '@giantnodes/react' +import { IconX } from '@tabler/icons-react' +import React from 'react' +import { graphql, useFragment, useSubscription } from 'react-relay' + +import EncodeDialogScript from '@/components/interfaces/dashboard/encode-dialog/EncodeDialogScript' +import EncodeDialogSidebar from '@/components/interfaces/dashboard/encode-dialog/EncodeDialogSidebar' +import { + EncodeDialogContext, + EncodeDialogPage, + useEncodeDialog, +} from '@/components/interfaces/dashboard/encode-dialog/use-encode-dialog.hook' +import EncodeStatusBadge from '@/components/ui/encode-badges/EncodeStatusBadge' + +const FRAGMENT = graphql` + fragment EncodeDialogFragment on Encode { + recipe { + name + } + file { + path_info { + name + } + } + ...EncodeStatusBadgeFragment + ...EncodeDialogScriptFragment + } +` + +const OUTPUTTED_SUBSCRIPTION = graphql` + subscription EncodeDialogOutputtedSubscription { + encode_outputted { + output + } + } +` + +type EncodeDialogProps = React.PropsWithChildren & { + $key: EncodeDialogFragment$key +} + +const EncodeDialog: React.FC = ({ children, $key }) => { + const data = useFragment(FRAGMENT, $key) + const context = useEncodeDialog({ page: EncodeDialogPage.SCRIPT }) + + useSubscription({ + subscription: OUTPUTTED_SUBSCRIPTION, + variables: {}, + }) + + const content = React.useCallback(() => { + switch (context.page) { + case EncodeDialogPage.SCRIPT: + return + + case EncodeDialogPage.ANALYTICS: + return + + default: + throw new Error(`unexpected value ${context.page} was provided.`) + } + }, [context.page, data]) + + return ( + + {children} + + + {({ close }) => ( + + + + + + +
+
+ {data.file.path_info.name} + + + + {data.recipe.name} +
+ +
+ +
+
+
+ + +
{content()}
+
+
+
+
+ )} +
+
+ ) +} + +export default EncodeDialog diff --git a/app/src/components/interfaces/dashboard/encode-dialog/EncodeDialogCommand.tsx b/app/src/components/interfaces/dashboard/encode-dialog/EncodeDialogCommand.tsx new file mode 100644 index 00000000..5ad577e6 --- /dev/null +++ b/app/src/components/interfaces/dashboard/encode-dialog/EncodeDialogCommand.tsx @@ -0,0 +1,23 @@ +import type { EncodeDialogCommandFragment$key } from '@/__generated__/EncodeDialogCommandFragment.graphql' + +import { graphql, useFragment } from 'react-relay' + +import CodeBlock from '@/components/ui/code-block/CodeBlock' + +const FRAGMENT = graphql` + fragment EncodeDialogCommandFragment on Encode { + command + } +` + +type EncodeDialogCommandProps = { + $key: EncodeDialogCommandFragment$key +} + +const EncodeDialogCommand: React.FC = ({ $key }) => { + const data = useFragment(FRAGMENT, $key) + + return {data.command} +} + +export default EncodeDialogCommand diff --git a/app/src/components/interfaces/dashboard/encode-dialog/EncodeDialogLog.tsx b/app/src/components/interfaces/dashboard/encode-dialog/EncodeDialogLog.tsx new file mode 100644 index 00000000..397aad5e --- /dev/null +++ b/app/src/components/interfaces/dashboard/encode-dialog/EncodeDialogLog.tsx @@ -0,0 +1,49 @@ +import type { EncodeDialogLogFragment$key } from '@/__generated__/EncodeDialogLogFragment.graphql' +import type { EncodeDialogLogSubscription } from '@/__generated__/EncodeDialogLogSubscription.graphql' + +import { graphql, useFragment, useSubscription } from 'react-relay' + +import CodeBlock from '@/components/ui/code-block/CodeBlock' +import ScrollAnchor from '@/components/ui/ScrollAnchor' + +const FRAGMENT = graphql` + fragment EncodeDialogLogFragment on Encode { + id + output + } +` + +const SUBSCRIPTION = graphql` + subscription EncodeDialogLogSubscription($where: EncodeFilterInput) { + encode_outputted(where: $where) { + ...EncodeDialogLogFragment + } + } +` + +type EncodeDialogLogProps = { + $key: EncodeDialogLogFragment$key +} + +const EncodeDialogLog: React.FC = ({ $key }) => { + const data = useFragment(FRAGMENT, $key) + + useSubscription({ + subscription: SUBSCRIPTION, + variables: { + where: { + id: { + eq: data.id, + }, + }, + }, + }) + + return ( + + {data.output} + + ) +} + +export default EncodeDialogLog diff --git a/app/src/components/interfaces/dashboard/encode-dialog/EncodeDialogScript.tsx b/app/src/components/interfaces/dashboard/encode-dialog/EncodeDialogScript.tsx new file mode 100644 index 00000000..3717e0f4 --- /dev/null +++ b/app/src/components/interfaces/dashboard/encode-dialog/EncodeDialogScript.tsx @@ -0,0 +1,44 @@ +import type { EncodeDialogScriptFragment$key } from '@/__generated__/EncodeDialogScriptFragment.graphql' + +import { Card } from '@giantnodes/react' +import { graphql, useFragment } from 'react-relay' + +import EncodeDialogCommand from '@/components/interfaces/dashboard/encode-dialog/EncodeDialogCommand' +import EncodeDialogLog from '@/components/interfaces/dashboard/encode-dialog/EncodeDialogLog' + +const FRAGMENT = graphql` + fragment EncodeDialogScriptFragment on Encode { + ...EncodeDialogCommandFragment + ...EncodeDialogLogFragment + } +` + +type EncodeDialogScriptProps = { + $key: EncodeDialogScriptFragment$key +} + +const EncodeDialogScript: React.FC = ({ $key }) => { + const data = useFragment(FRAGMENT, $key) + + return ( + <> + + Command + + + + + + + + Logs + + + + + + + ) +} + +export default EncodeDialogScript diff --git a/app/src/components/interfaces/dashboard/encode-dialog/EncodeDialogSidebar.tsx b/app/src/components/interfaces/dashboard/encode-dialog/EncodeDialogSidebar.tsx new file mode 100644 index 00000000..157f7cf6 --- /dev/null +++ b/app/src/components/interfaces/dashboard/encode-dialog/EncodeDialogSidebar.tsx @@ -0,0 +1,31 @@ +import { Navigation } from '@giantnodes/react' +import { IconReportAnalytics, IconScript } from '@tabler/icons-react' + +import { + EncodeDialogPage, + useEncodeDialogContext, +} from '@/components/interfaces/dashboard/encode-dialog/use-encode-dialog.hook' + +const EncodeDialogSidebar = () => { + const { page, setPage } = useEncodeDialogContext() + + return ( + + + setPage(EncodeDialogPage.SCRIPT)}> + + + + + + setPage(EncodeDialogPage.ANALYTICS)}> + + + + + + + ) +} + +export default EncodeDialogSidebar diff --git a/app/src/components/interfaces/dashboard/encode-dialog/use-encode-dialog.hook.ts b/app/src/components/interfaces/dashboard/encode-dialog/use-encode-dialog.hook.ts new file mode 100644 index 00000000..85bdabaa --- /dev/null +++ b/app/src/components/interfaces/dashboard/encode-dialog/use-encode-dialog.hook.ts @@ -0,0 +1,30 @@ +import React from 'react' + +import { createContext } from '@/utilities/context' + +export enum EncodeDialogPage { + SCRIPT, + ANALYTICS, +} + +type UseEncodeDialogReturn = ReturnType + +type UseEncodeDialogProps = { + page: EncodeDialogPage +} + +export const useEncodeDialog = (props: UseEncodeDialogProps) => { + const [page, setPage] = React.useState(props.page) + + return { + page, + setPage, + } +} + +export const [EncodeDialogContext, useEncodeDialogContext] = createContext({ + name: 'EncodeDialogContext', + strict: true, + errorMessage: + 'useEncodeDialogContext: `context` is undefined. Seems you forgot to wrap component within ', +}) diff --git a/app/src/components/interfaces/dashboard/index.ts b/app/src/components/interfaces/dashboard/index.ts new file mode 100644 index 00000000..86dccc03 --- /dev/null +++ b/app/src/components/interfaces/dashboard/index.ts @@ -0,0 +1 @@ +export { default as EncodeDialog } from '@/components/interfaces/dashboard/encode-dialog/EncodeDialog' diff --git a/app/src/components/tables/encoded/EncodedTable.tsx b/app/src/components/tables/encoded/EncodedTable.tsx index 593a62a1..5cd8ad6a 100644 --- a/app/src/components/tables/encoded/EncodedTable.tsx +++ b/app/src/components/tables/encoded/EncodedTable.tsx @@ -5,7 +5,7 @@ import { Button, Link, Table } from '@giantnodes/react' import React from 'react' import { graphql, usePaginationFragment } from 'react-relay' -import EncodeDialog from '@/components/interfaces/dashboard/EncodeDialog' +import { EncodeDialog } from '@/components/interfaces/dashboard' import { EncodeBadges } from '@/components/ui' const FRAGMENT = graphql` diff --git a/app/src/components/tables/encoding/EncodingTable.tsx b/app/src/components/tables/encoding/EncodingTable.tsx index e181fe13..952b34d2 100644 --- a/app/src/components/tables/encoding/EncodingTable.tsx +++ b/app/src/components/tables/encoding/EncodingTable.tsx @@ -10,7 +10,7 @@ import { IconProgressX } from '@tabler/icons-react' import React from 'react' import { graphql, useMutation, usePaginationFragment, useSubscription } from 'react-relay' -import EncodeDialog from '@/components/interfaces/dashboard/EncodeDialog' +import { EncodeDialog } from '@/components/interfaces/dashboard' import { EncodeBadges } from '@/components/ui' const FRAGMENT = graphql` diff --git a/app/src/components/ui/code-block/CodeBlock.tsx b/app/src/components/ui/code-block/CodeBlock.tsx index d7f5e694..ec6c4c81 100644 --- a/app/src/components/ui/code-block/CodeBlock.tsx +++ b/app/src/components/ui/code-block/CodeBlock.tsx @@ -4,7 +4,7 @@ import SyntaxHighlighter from 'react-syntax-highlighter' import { atomOneDark } from 'react-syntax-highlighter/dist/esm/styles/hljs' type CodeBlockProps = Pick & { - children: string | string[] + children?: string | string[] | null } const CodeBlock: React.FC = ({ children, ...rest }) => ( @@ -15,7 +15,7 @@ const CodeBlock: React.FC = ({ children, ...rest }) => ( style={atomOneDark} {...rest} > - {children} + {children ?? ''} )