From 3403ef5bf9656f3f762c9949d5153178287e3c16 Mon Sep 17 00:00:00 2001 From: Taylor Bantle Date: Fri, 15 Mar 2024 15:05:49 -0700 Subject: [PATCH 1/6] web: RC FormSelect.Group --- .../BranchSelector/BranchSelectorQuery.tsx | 45 --- .../BranchSelectorWithTableQuery.tsx | 61 ---- .../CustomFormSelect/BranchSelector/Inner.tsx | 37 -- .../CustomFormSelect/BranchSelector/index.tsx | 46 --- .../CustomFormSelect/BranchSelector/types.ts | 22 -- .../CustomFormSelect/CommitSelector.tsx | 65 ---- .../ForBranchesAndCommits.tsx | 72 ---- .../CustomFormSelect/ForBranchesAndTags.tsx | 86 ----- .../CustomFormSelect/SelectTabs.tsx | 28 -- .../CustomFormSelect/TabWrapper.tsx | 18 - .../CustomFormSelect/TagSelector.tsx | 53 --- web/components/CustomFormSelect/component.tsx | 47 --- .../CustomFormSelect/index.module.css | 103 ------ web/components/CustomFormSelect/index.tsx | 10 - .../CustomFormSelect/selectorComponents.tsx | 96 ------ .../tests/BranchSelector.test.tsx | 89 ----- .../tests/CommitSelector.test.tsx | 82 ----- web/components/CustomFormSelect/types.ts | 37 -- web/components/CustomFormSelect/utils.ts | 14 - web/components/DatabaseTableNav/index.tsx | 22 +- .../DiffTable/DiffTableStats/mocks.ts | 2 +- .../DiffTableNav/CommitInfo/mocks.ts | 2 +- .../BranchAndCommitSelector.tsx | 45 +++ .../BranchAndTagSelector.tsx | 80 +++++ .../DoltDisabledSelector.tsx | 0 .../NotDoltSelectWrapper.tsx | 29 ++ .../FormSelectForRefs/getGroupOption.tsx | 17 + .../FormSelectForRefs/index.module.css | 23 ++ .../mocks.ts | 0 .../queries.ts | 13 + .../useGetBranchOptionsForSelect.ts | 27 ++ .../useGetCommitOptionsForSelect.tsx | 51 +++ .../useGetTagOptionsForSelect.ts | 23 ++ web/components/SchemaDiagram/queries.ts | 2 +- .../NewBranchForm/index.module.css | 4 - .../NewBranchPage/NewBranchForm/index.tsx | 7 +- .../NewBranchPage/NewBranchForm/mocks.ts | 2 +- .../NewReleaseForm/index.module.css | 4 - .../NewReleasePage/NewReleaseForm/index.tsx | 7 +- .../NewReleasePage/NewReleaseForm/mocks.ts | 2 +- .../Steps/Branch/index.module.css | 6 +- .../FileUploadPage/Steps/Branch/index.tsx | 26 +- web/gen/graphql-types.tsx | 316 ++++++++++-------- 43 files changed, 535 insertions(+), 1186 deletions(-) delete mode 100644 web/components/CustomFormSelect/BranchSelector/BranchSelectorQuery.tsx delete mode 100644 web/components/CustomFormSelect/BranchSelector/BranchSelectorWithTableQuery.tsx delete mode 100644 web/components/CustomFormSelect/BranchSelector/Inner.tsx delete mode 100644 web/components/CustomFormSelect/BranchSelector/index.tsx delete mode 100644 web/components/CustomFormSelect/BranchSelector/types.ts delete mode 100644 web/components/CustomFormSelect/CommitSelector.tsx delete mode 100644 web/components/CustomFormSelect/ForBranchesAndCommits.tsx delete mode 100644 web/components/CustomFormSelect/ForBranchesAndTags.tsx delete mode 100644 web/components/CustomFormSelect/SelectTabs.tsx delete mode 100644 web/components/CustomFormSelect/TabWrapper.tsx delete mode 100644 web/components/CustomFormSelect/TagSelector.tsx delete mode 100644 web/components/CustomFormSelect/component.tsx delete mode 100644 web/components/CustomFormSelect/index.module.css delete mode 100644 web/components/CustomFormSelect/index.tsx delete mode 100644 web/components/CustomFormSelect/selectorComponents.tsx delete mode 100644 web/components/CustomFormSelect/tests/BranchSelector.test.tsx delete mode 100644 web/components/CustomFormSelect/tests/CommitSelector.test.tsx delete mode 100644 web/components/CustomFormSelect/types.ts delete mode 100644 web/components/CustomFormSelect/utils.ts create mode 100644 web/components/FormSelectForRefs/BranchAndCommitSelector.tsx create mode 100644 web/components/FormSelectForRefs/BranchAndTagSelector.tsx rename web/components/{CustomFormSelect => FormSelectForRefs}/DoltDisabledSelector.tsx (100%) create mode 100644 web/components/FormSelectForRefs/NotDoltSelectWrapper.tsx create mode 100644 web/components/FormSelectForRefs/getGroupOption.tsx create mode 100644 web/components/FormSelectForRefs/index.module.css rename web/components/{CustomFormSelect => FormSelectForRefs}/mocks.ts (100%) rename web/components/{CustomFormSelect => FormSelectForRefs}/queries.ts (72%) create mode 100644 web/components/FormSelectForRefs/useGetBranchOptionsForSelect.ts create mode 100644 web/components/FormSelectForRefs/useGetCommitOptionsForSelect.tsx create mode 100644 web/components/FormSelectForRefs/useGetTagOptionsForSelect.ts diff --git a/web/components/CustomFormSelect/BranchSelector/BranchSelectorQuery.tsx b/web/components/CustomFormSelect/BranchSelector/BranchSelectorQuery.tsx deleted file mode 100644 index cdae33f6..00000000 --- a/web/components/CustomFormSelect/BranchSelector/BranchSelectorQuery.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import QueryHandler from "@components/util/QueryHandler"; -import { Maybe } from "@dolthub/web-utils"; -import { useBranchesForSelectorQuery } from "@gen/graphql-types"; -import useDefaultBranch from "@hooks/useDefaultBranch"; -import { database } from "@lib/urls"; -import { useRouter } from "next/router"; -import Inner from "./Inner"; -import { BranchSelectorForRepoProps } from "./types"; - -export default function BranchSelectorQuery(props: BranchSelectorForRepoProps) { - const { defaultBranchName } = useDefaultBranch(props.params); - - const res = useBranchesForSelectorQuery({ - variables: { - databaseName: props.params.databaseName, - }, - }); - const router = useRouter(); - - const handleChangeBranch = async (branchName: Maybe) => { - if (!branchName) return; - const { href, as } = props.routeRefChangeTo - ? props.routeRefChangeTo({ - ...props.params, - refName: branchName, - }) - : database(props.params); - - router.push(href, as).catch(console.error); - }; - - return ( - ( - - )} - /> - ); -} diff --git a/web/components/CustomFormSelect/BranchSelector/BranchSelectorWithTableQuery.tsx b/web/components/CustomFormSelect/BranchSelector/BranchSelectorWithTableQuery.tsx deleted file mode 100644 index 0a36fb88..00000000 --- a/web/components/CustomFormSelect/BranchSelector/BranchSelectorWithTableQuery.tsx +++ /dev/null @@ -1,61 +0,0 @@ -import QueryHandler from "@components/util/QueryHandler"; -import { Maybe } from "@dolthub/web-utils"; -import { - useBranchesForSelectorQuery, - useTableNamesLazyQuery, -} from "@gen/graphql-types"; -import useDefaultBranch from "@hooks/useDefaultBranch"; -import { ref } from "@lib/urls"; -import { useRouter } from "next/router"; -import Inner from "./Inner"; -import { BranchSelectorWithTableQueryProps } from "./types"; - -export default function BranchSelectorWithTableQuery( - props: BranchSelectorWithTableQueryProps, -) { - const { defaultBranchName } = useDefaultBranch(props.params); - const [getTableNames] = useTableNamesLazyQuery(); - - const res = useBranchesForSelectorQuery({ - variables: { - databaseName: props.params.databaseName, - }, - fetchPolicy: "network-only", - }); - const router = useRouter(); - - const handleChangeBranch = async (branchName: Maybe) => { - if (!branchName) return; - const variables = { - databaseName: props.params.databaseName, - refName: branchName, - }; - const tableRes = await getTableNames({ variables }); - const tableExists = tableRes.data?.tableNames.list.some( - t => t === props.params.tableName, - ); - const { href, as } = - tableExists && props.routeRefChangeTo - ? props.routeRefChangeTo({ - ...props.params, - refName: branchName, - }) - : ref({ ...props.params, refName: branchName }); - - router.push(href, as).catch(console.error); - }; - - return ( - ( - - )} - /> - ); -} diff --git a/web/components/CustomFormSelect/BranchSelector/Inner.tsx b/web/components/CustomFormSelect/BranchSelector/Inner.tsx deleted file mode 100644 index d9321790..00000000 --- a/web/components/CustomFormSelect/BranchSelector/Inner.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { excerpt } from "@dolthub/web-utils"; -import { BranchForBranchSelectorFragment } from "@gen/graphql-types"; -import { branches } from "@lib/urls"; -import Selector from "../component"; -import { BranchSelectorProps } from "./types"; - -const excerptLength = 35; - -export default function Inner( - props: BranchSelectorProps, -) { - return ( -
- { - return { - value: b.branchName, - label: excerpt(b.branchName, excerptLength), - }; - })} - footerLink={{ - urlString: "View all branches", - urlParams: branches({ - ...props.params, - refName: props.selectedValue, - }), - }} - placeholder="select a branch..." - /> -
- ); -} diff --git a/web/components/CustomFormSelect/BranchSelector/index.tsx b/web/components/CustomFormSelect/BranchSelector/index.tsx deleted file mode 100644 index 686fd6cf..00000000 --- a/web/components/CustomFormSelect/BranchSelector/index.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import QueryHandler from "@components/util/QueryHandler"; -import { Maybe } from "@dolthub/web-utils"; -import { useBranchesForSelectorQuery } from "@gen/graphql-types"; -import useDefaultBranch from "@hooks/useDefaultBranch"; -import { RefUrl } from "@lib/urls"; -import BranchSelectorQuery from "./BranchSelectorQuery"; -import BranchSelectorWithTableQuery from "./BranchSelectorWithTableQuery"; -import Inner from "./Inner"; -import { BranchSelectorForRepoProps } from "./types"; - -export function BranchSelector(props: BranchSelectorForRepoProps) { - const { refName, tableName } = props.params; - - if (refName && tableName) { - const params = { ...props.params, refName, tableName }; - return ; - } - return ; -} - -type CustomProps = BranchSelectorForRepoProps & { - onChangeValue: (e: Maybe) => void; - routeRefChangeTo?: RefUrl; -}; - -export default function CustomBranchSelector(props: CustomProps): JSX.Element { - const { defaultBranchName } = useDefaultBranch(props.params); - - const res = useBranchesForSelectorQuery({ - variables: props.params, - fetchPolicy: "cache-and-network", - }); - - return ( - ( - - )} - /> - ); -} diff --git a/web/components/CustomFormSelect/BranchSelector/types.ts b/web/components/CustomFormSelect/BranchSelector/types.ts deleted file mode 100644 index 9e7e4fb1..00000000 --- a/web/components/CustomFormSelect/BranchSelector/types.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Maybe } from "@dolthub/web-utils"; -import { BranchForBranchSelectorFragment } from "@gen/graphql-types"; -import { OptionalRefParams, TableParams } from "@lib/params"; -import { RefUrl } from "@lib/urls"; -import { BaseFormSelectorProps } from "../types"; - -export type BranchSelectorForRepoProps = BaseFormSelectorProps & { - params: OptionalRefParams & { tableName?: string }; - defaultName?: string; - dataCyPrefix?: string; - routeRefChangeTo?: RefUrl; -}; - -export type BranchSelectorProps = - BranchSelectorForRepoProps & { - onChangeValue: (e: Maybe) => void; - branches: B[]; - }; - -export type BranchSelectorWithTableQueryProps = BranchSelectorForRepoProps & { - params: TableParams; -}; diff --git a/web/components/CustomFormSelect/CommitSelector.tsx b/web/components/CustomFormSelect/CommitSelector.tsx deleted file mode 100644 index 264e3119..00000000 --- a/web/components/CustomFormSelect/CommitSelector.tsx +++ /dev/null @@ -1,65 +0,0 @@ -import QueryHandler from "@components/util/QueryHandler"; -import { Maybe } from "@dolthub/web-utils"; -import { CommitForHistoryFragment } from "@gen/graphql-types"; -import { useCommitListForBranch } from "@hooks/useCommitListForBranch"; -import { RefParams } from "@lib/params"; -import { commitLog } from "@lib/urls"; -import Selector from "./component"; -import { BaseFormSelectorProps, Tab } from "./types"; -import { getCommitLabel } from "./utils"; - -type Props = BaseFormSelectorProps & { - params: RefParams; - tabs: Tab[]; - onChangeValue: (e: Maybe) => void; -}; - -type InnerProps = { - commits: CommitForHistoryFragment[]; - loadMore: () => void; - hasMore: boolean; -} & Props; - -function Inner({ commits, ...props }: InnerProps) { - return ( -
- { - return { - value: c.commitId, - label: getCommitLabel(c), - }; - })} - footerLink={{ - urlString: "View all commits", - urlParams: commitLog(props.params), - }} - /> -
- ); -} - -export default function CommitSelector(props: Props) { - const res = useCommitListForBranch(props.params, true); - - return ( - ( - - )} - /> - ); -} diff --git a/web/components/CustomFormSelect/ForBranchesAndCommits.tsx b/web/components/CustomFormSelect/ForBranchesAndCommits.tsx deleted file mode 100644 index 9cfc9051..00000000 --- a/web/components/CustomFormSelect/ForBranchesAndCommits.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import { useEffectOnMount } from "@dolthub/react-hooks"; -import { Maybe } from "@dolthub/web-utils"; -import useDefaultBranch from "@hooks/useDefaultBranch"; -import { OptionalRefParams } from "@lib/params"; -import { useEffect, useState } from "react"; -import CustomBranchSelector from "./BranchSelector"; -import CommitSelector from "./CommitSelector"; -import TabWrapper from "./TabWrapper"; - -type Props = { - params: OptionalRefParams; - selectedValue: Maybe; - onChangeValue: (s: Maybe) => void; -}; - -export default function ForBranchesAndCommits(props: Props) { - const [showFirstTab, setShowFirstTab] = useState(true); - const [shouldAutoFocus, setShouldAutoFocus] = useState(false); - const { defaultBranchName } = useDefaultBranch(props.params); - - useEffectOnMount(() => { - if (props.params.refName) { - props.onChangeValue(props.params.refName); - } - }); - - useEffect(() => { - if (!showFirstTab) { - setShouldAutoFocus(true); - } - }, [showFirstTab]); - - const formSelectProps = { - tabs: [ - { - label: "Branches", - active: showFirstTab, - onClick: () => setShowFirstTab(true), - }, - { - label: "Commits", - active: !showFirstTab, - onClick: () => setShowFirstTab(false), - }, - ], - selectedValue: props.selectedValue, - onChangeValue: props.onChangeValue, - customDropdown: true, - useValueAsSingleValue: true, - }; - - return ( - - - - - ); -} diff --git a/web/components/CustomFormSelect/ForBranchesAndTags.tsx b/web/components/CustomFormSelect/ForBranchesAndTags.tsx deleted file mode 100644 index 385683b5..00000000 --- a/web/components/CustomFormSelect/ForBranchesAndTags.tsx +++ /dev/null @@ -1,86 +0,0 @@ -import QueryHandler from "@components/util/QueryHandler"; -import { useTagListQuery } from "@gen/graphql-types"; -import { OptionalRefParams } from "@lib/params"; -import { RefUrl } from "@lib/urls"; -import { useEffect, useState } from "react"; -import { BranchSelector } from "./BranchSelector"; -import TabWrapper from "./TabWrapper"; -import TagSelector from "./TagSelector"; - -type Props = { - params: OptionalRefParams; - selectedValue?: string; - routeRefChangeTo: RefUrl; - className?: string; - doltDisabled?: boolean; -}; - -function Inner(props: Props) { - // We need to fetch tags in this outer component to determine the active tab. - const tagRes = useTagListQuery({ - variables: props.params, - }); - const [showFirstTab, setShowFirstTab] = useState(true); - const [autoFocusFirst, setAutoFocusFirst] = useState(false); - const [autoFocusSecond, setAutoFocusSecond] = useState(false); - - useEffect(() => { - if (!tagRes.data?.tags.list.length || !props.selectedValue) return; - if (tagRes.data.tags.list.find(t => t.tagName === props.selectedValue)) { - setShowFirstTab(false); - } - }, [tagRes.data?.tags, props.selectedValue, setShowFirstTab]); - - const formSelectProps = { - tabs: [ - { - label: "Branches", - active: showFirstTab, - onClick: () => { - setShowFirstTab(true); - setAutoFocusFirst(true); - }, - }, - { - label: "Tags", - active: !showFirstTab, - onClick: () => { - setShowFirstTab(false); - setAutoFocusSecond(true); - }, - }, - ], - selectedValue: props.selectedValue, - routeRefChangeTo: props.routeRefChangeTo, - useValueAsSingleValue: true, - doltDisabled: props.doltDisabled, - }; - - return ( - - - ( - - )} - /> - - ); -} - -export default function ForBranchesAndTags(props: Props) { - if (props.doltDisabled) { - return ; - } - return ; -} diff --git a/web/components/CustomFormSelect/SelectTabs.tsx b/web/components/CustomFormSelect/SelectTabs.tsx deleted file mode 100644 index 3e0fa4e8..00000000 --- a/web/components/CustomFormSelect/SelectTabs.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { Btn } from "@dolthub/react-components"; -import cx from "classnames"; -import css from "./index.module.css"; -import { Tab } from "./types"; - -type Props = { - tabs: Tab[]; -}; - -export default function SelectTabs({ tabs }: Props) { - return ( -
- {tabs.map(tab => ( - - {tab.label} - - ))} -
- ); -} diff --git a/web/components/CustomFormSelect/TabWrapper.tsx b/web/components/CustomFormSelect/TabWrapper.tsx deleted file mode 100644 index dbc7e52e..00000000 --- a/web/components/CustomFormSelect/TabWrapper.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { ReactNode } from "react"; -import css from "./index.module.css"; - -type Props = { - label?: string; - showFirstTab: boolean; - children: [ReactNode, ReactNode]; - className?: string; -}; - -export default function TabWrapper(props: Props) { - return ( -
- {props.label &&
{props.label}
} - {props.showFirstTab ? props.children[0] : props.children[1]} -
- ); -} diff --git a/web/components/CustomFormSelect/TagSelector.tsx b/web/components/CustomFormSelect/TagSelector.tsx deleted file mode 100644 index 6daa48c1..00000000 --- a/web/components/CustomFormSelect/TagSelector.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import { Maybe } from "@dolthub/web-utils"; -import { TagForListFragment } from "@gen/graphql-types"; -import { DatabaseParams } from "@lib/params"; -import { RefUrl, database, releases } from "@lib/urls"; -import { useRouter } from "next/router"; -import Selector from "./component"; -import { BaseFormSelectorProps, Tab } from "./types"; - -type Props = BaseFormSelectorProps & { - params: DatabaseParams; - tabs: Tab[]; - routeRefChangeTo?: RefUrl; - tags: TagForListFragment[]; -}; - -export default function TagSelector(props: Props) { - const router = useRouter(); - - const handleChangeRef = async (refName: Maybe) => { - if (!refName) return; - const { href, as } = props.routeRefChangeTo - ? props.routeRefChangeTo({ - ...props.params, - refName, - }) - : database(props.params); - - router.push(href, as).catch(console.error); - }; - - return ( -
- { - return { - value: t.tagName, - label: t.tagName, - }; - })} - footerLink={{ - urlString: "View all tags", - urlParams: releases(props.params), - }} - /> -
- ); -} diff --git a/web/components/CustomFormSelect/component.tsx b/web/components/CustomFormSelect/component.tsx deleted file mode 100644 index b8965718..00000000 --- a/web/components/CustomFormSelect/component.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import { FormSelect } from "@dolthub/react-components"; -import cx from "classnames"; -import DoltDisabledSelector from "./DoltDisabledSelector"; -import css from "./index.module.css"; -import { getComponents } from "./selectorComponents"; -import { FormSelectorProps } from "./types"; - -export default function Selector(props: FormSelectorProps) { - const dataCy = props.dataCySuffix ?? ""; - return ( -
- {props.showLabel && {props.label}} -
-
- {props.doltDisabled ? ( - - ) : ( - - )} -
-
-
- ); -} - -function getNoOptions(dataCy: string, noneFoundMsg?: string) { - // eslint-disable-next-line react/display-name - return function () { - return ( -

- {noneFoundMsg ?? "No options found"} -

- ); - }; -} diff --git a/web/components/CustomFormSelect/index.module.css b/web/components/CustomFormSelect/index.module.css deleted file mode 100644 index b8852a0c..00000000 --- a/web/components/CustomFormSelect/index.module.css +++ /dev/null @@ -1,103 +0,0 @@ -.container { - @apply flex whitespace-pre-line; -} - -.linkContainer { - @apply hidden; - @screen md { - @apply border-t flex justify-center; - } -} - -.input { - @apply mt-4 mb-2 px-0 font-semibold; -} - -.link { - @apply text-sm py-2; -} - -.singleValue { - @apply mx-0.5 max-w-full box-border z-1 overflow-hidden text-ellipsis whitespace-nowrap select-all; - grid-area: 1 / 1 / 2 / 3; -} - -.optionBorder { - @apply border-t; -} - -.optionClear { - @apply border-t-white; -} - -.option { - grid-area: 1 / 3; -} - -.splitByWhiteSpace { - @apply max-w-full whitespace-pre-line mr-5; -} - -.splitByWord { - @apply break-words; -} - -.check { - @apply mr-2 max-w-[20px] min-w-[20px] text-green-500; -} - -.checkInvisible { - @apply invisible; -} - -.buttonContainer { - @apply flex border-b; -} - -.button { - @apply border-b-3 ml-4 font-semibold px-2 mt-1; -} - -.buttonDisabled { - @apply text-acc-hoverlinkblue border-transparent; -} - -.buttonDisabled:hover, -.activeButton { - @apply border-ld-orange text-ld-orange; -} - -.label { - @apply font-normal text-sm mt-2 mr-3; -} - -.optionLabel { - @apply w-[85%]; -} - -.openItem { - @apply opacity-100 transition-opacity duration-75; -} - -.dropdown { - @apply min-w-[250px] max-w-[250px] w-full; -} - -.customDropdown { - @apply min-w-[350px] max-w-[350px] w-full; - - @screen md { - @apply w-auto block; - } -} - -.selector { - @apply w-[80%]; - @screen md { - @apply w-auto; - } -} - -.doltDisabled { - @apply bg-ld-lightblue border border-ld-darkgrey px-2.5 py-2 rounded text-sm; -} diff --git a/web/components/CustomFormSelect/index.tsx b/web/components/CustomFormSelect/index.tsx deleted file mode 100644 index e66d79f9..00000000 --- a/web/components/CustomFormSelect/index.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import ForBranches from "./BranchSelector"; -import Selector from "./component"; -import ForBranchesAndCommits from "./ForBranchesAndCommits"; -import ForBranchesAndTags from "./ForBranchesAndTags"; - -export default Object.assign(Selector, { - ForBranches, - ForBranchesAndCommits, - ForBranchesAndTags, -}); diff --git a/web/components/CustomFormSelect/selectorComponents.tsx b/web/components/CustomFormSelect/selectorComponents.tsx deleted file mode 100644 index d177a62f..00000000 --- a/web/components/CustomFormSelect/selectorComponents.tsx +++ /dev/null @@ -1,96 +0,0 @@ -import Link from "@components/links/Link"; -import { - FormSelectTypes, - MenuProps, - OptionProps, - SingleValueProps, - components, -} from "@dolthub/react-components"; -import { FiCheck } from "@react-icons/all-files/fi/FiCheck"; -import cx from "classnames"; -import SelectTabs from "./SelectTabs"; -import css from "./index.module.css"; -import { FooterProps, FormSelectorProps } from "./types"; - -type Option = FormSelectTypes.Option; - -function SingleValueComponent( - props: SingleValueProps, -): JSX.Element { - return
{props.data.label}
; -} - -function OptionComponent(props: OptionProps): JSX.Element { - return ( - - -
- {props.label} -
-
- ); -} - -function FooterLink( - props: FooterProps & { dataCySuffix?: string }, -): JSX.Element { - return ( -
- - {props.urlString} - -
- ); -} - -function menuComponent( - header?: JSX.Element, - footer?: JSX.Element, -): (props: MenuProps) => JSX.Element { - const menu = ({ children, ...props }: MenuProps) => ( - - { -
- {header} - {children} - {footer} -
- } -
- ); - return menu; -} - -export function getComponents(props: FormSelectorProps) { - const res = { - SingleValue: SingleValueComponent, - Option: OptionComponent, - }; - return { - ...res, - Menu: menuComponent( - props.tabs && , - props.footerLink && , - ), - }; -} diff --git a/web/components/CustomFormSelect/tests/BranchSelector.test.tsx b/web/components/CustomFormSelect/tests/BranchSelector.test.tsx deleted file mode 100644 index 12e98977..00000000 --- a/web/components/CustomFormSelect/tests/BranchSelector.test.tsx +++ /dev/null @@ -1,89 +0,0 @@ -import { MockedProvider } from "@apollo/client/testing"; -import useMockRouter from "@hooks/useMockRouter"; -import { setup } from "@lib/testUtils.test"; -import { database } from "@lib/urls"; -import { screen, waitFor } from "@testing-library/react"; -import CustomFormSelect from ".."; -import * as mocks from "../mocks"; - -const jestRouter = jest.spyOn(require("next/router"), "useRouter"); - -jest.mock("next/router", () => { - return { - useRouter: () => { - return { route: "", pathname: "", query: "", asPath: "" }; - }, - }; -}); - -describe("test CustomFormSelect.ForBranches", () => { - mocks.branchTests.forEach(test => { - it(`render Selector ${test.title}`, async () => { - const onChangeValue = jest.fn(); - - const propsToFormSelect = { - tabs: [ - { - label: "Branches", - active: true, - onClick: jest.fn(), - }, - { - label: "Commits", - active: false, - onClick: jest.fn(), - }, - ], - selectedValue: test.selected, - onChangeValue, - customDropdown: true, - }; - - const url = database(mocks.fakeParams); - useMockRouter(jestRouter, { - asPath: url.asPathname(), - pathname: url.hrefPathname(), - }); - - const { user } = setup( - - - , - ); - - if (test.error) { - await waitFor(() => - expect(screen.getByText(mocks.branchError)).toBeVisible(), - ); - } else if (test.empty) { - await waitFor(() => - expect(screen.getByText("No branches found")).toBeVisible(), - ); - } else { - await waitFor(() => - expect(screen.getByRole("button", { name: "Commits" })).toBeVisible(), - ); - expect(screen.getByRole("button", { name: "Branches" })).toBeVisible(); - const selected = - test.selected === "" ? "select a branch..." : test.selected; - expect(screen.getByText(selected)).toBeVisible(); - - expect(user.click(screen.getByLabelText("main"))); - await waitFor(() => expect(onChangeValue).toBeCalled()); - } - }); - }); -}); diff --git a/web/components/CustomFormSelect/tests/CommitSelector.test.tsx b/web/components/CustomFormSelect/tests/CommitSelector.test.tsx deleted file mode 100644 index 733746cc..00000000 --- a/web/components/CustomFormSelect/tests/CommitSelector.test.tsx +++ /dev/null @@ -1,82 +0,0 @@ -import { MockedProvider } from "@apollo/client/testing"; -import { setup } from "@lib/testUtils.test"; -import { screen, waitFor } from "@testing-library/react"; -import CommitSelector from "../CommitSelector"; -import * as mocks from "../mocks"; - -describe("test CustomFormSelect.ForCommits", () => { - mocks.commitTests.forEach(test => { - it(`render Selector ${test.title}`, async () => { - const onChangeValue = jest.fn(); - - const propsToFormSelect = { - tabs: [ - { - label: "Branches", - active: true, - onClick: jest.fn(), - }, - { - label: "Commits", - active: false, - onClick: jest.fn(), - }, - ], - selectedValue: test.selected, - onChangeValue, - customDropdown: true, - }; - - const { user } = setup( - - - , - ); - - if (test.error) { - await waitFor(() => - expect(screen.getByText(mocks.commitError)).toBeVisible(), - ); - } else if (test.empty) { - await waitFor(() => - expect(screen.getByText("No commits found")).toBeVisible(), - ); - } else { - const selected = test.selected === "" ? "Select..." : test.selected; - - await waitFor(() => expect(screen.getByText(selected)).toBeVisible()); - await waitFor(() => - expect( - screen.getByLabelText(mocks.commitPicked.commitId), - ).toBeVisible(), - ); - - expect(screen.getByRole("button", { name: "Branches" })).toBeVisible(); - expect(screen.getByRole("button", { name: "Commits" })).toBeVisible(); - - expect(user.click(screen.getByLabelText(mocks.commitPicked.commitId))); - - await waitFor(() => - expect(onChangeValue).toHaveBeenLastCalledWith( - mocks.commitPicked.commitId, - ), - ); - } - }); - }); -}); diff --git a/web/components/CustomFormSelect/types.ts b/web/components/CustomFormSelect/types.ts deleted file mode 100644 index 03879b69..00000000 --- a/web/components/CustomFormSelect/types.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { FormSelectTypes } from "@dolthub/react-components"; -import { Maybe, Route } from "@dolthub/web-utils"; - -export type Tab = { - label: string; - active: boolean; - onClick: () => void; -}; - -export type BaseFormSelectorProps = { - selectedValue?: Maybe; - className?: string; - mono?: boolean; - tabs?: Tab[]; - autoFocus?: boolean; - customDropdown?: boolean; - showLabel?: boolean; - placeholder?: string; - useValueAsSingleValue?: boolean; - loading?: boolean; - doltDisabled?: boolean; -}; - -export type FooterProps = { - urlParams: Route; - urlString: string; -}; - -export type FormSelectorProps = BaseFormSelectorProps & { - onChangeValue: (e: Maybe) => void; - val: Maybe; - options: Array>; - label: string; - dataCySuffix?: string; - noneFoundMsg?: string; - footerLink?: FooterProps; // Shows 'View all' link in footer if present -}; diff --git a/web/components/CustomFormSelect/utils.ts b/web/components/CustomFormSelect/utils.ts deleted file mode 100644 index d2dade6d..00000000 --- a/web/components/CustomFormSelect/utils.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { excerpt, getTimeAgoString } from "@dolthub/web-utils"; -import { CommitForHistoryFragment } from "@gen/graphql-types"; - -const maxCommitMsgChars = 78; - -export function limitTwoLines(s: string, maxChars: number): string { - return excerpt(s.replace(/(\r\n|\n|\r)/g, " "), maxChars); -} - -export function getCommitLabel(c: CommitForHistoryFragment): string { - return `${c.commitId} -${limitTwoLines(c.message, maxCommitMsgChars)} -${getTimeAgoString(c.committedAt)}`; -} diff --git a/web/components/DatabaseTableNav/index.tsx b/web/components/DatabaseTableNav/index.tsx index 0de23d98..3df5b1e2 100644 --- a/web/components/DatabaseTableNav/index.tsx +++ b/web/components/DatabaseTableNav/index.tsx @@ -1,4 +1,5 @@ -import CustomFormSelect from "@components/CustomFormSelect"; +import BranchAndTagSelector from "@components/FormSelectForRefs/BranchAndTagSelector"; +import NotDoltSelectWrapper from "@components/FormSelectForRefs/NotDoltSelectWrapper"; import Tooltip from "@components/Tooltip"; import Link from "@components/links/Link"; import HideForNoWritesWrapper from "@components/util/HideForNoWritesWrapper"; @@ -51,14 +52,17 @@ function Nav({ )} >
- - - +
+ + + +
diff --git a/web/components/DiffTable/DiffTableStats/mocks.ts b/web/components/DiffTable/DiffTableStats/mocks.ts index 8fa0f9a4..93083867 100644 --- a/web/components/DiffTable/DiffTableStats/mocks.ts +++ b/web/components/DiffTable/DiffTableStats/mocks.ts @@ -1,4 +1,4 @@ -import { fakeCommitId } from "@components/CustomFormSelect/mocks"; +import { fakeCommitId } from "@components/FormSelectForRefs/mocks"; import { ColumnForDataTableFragment } from "@gen/graphql-types"; import { RequiredRefsParams, TableParams } from "@lib/params"; diff --git a/web/components/DiffTableNav/CommitInfo/mocks.ts b/web/components/DiffTableNav/CommitInfo/mocks.ts index e035057d..9077afaf 100644 --- a/web/components/DiffTableNav/CommitInfo/mocks.ts +++ b/web/components/DiffTableNav/CommitInfo/mocks.ts @@ -1,5 +1,5 @@ import { MockedResponse } from "@apollo/client/testing"; -import { fakeCommitId } from "@components/CustomFormSelect/mocks"; +import { fakeCommitId } from "@components/FormSelectForRefs/mocks"; import { CommitForAfterCommitHistoryFragment, HistoryForCommitDocument, diff --git a/web/components/FormSelectForRefs/BranchAndCommitSelector.tsx b/web/components/FormSelectForRefs/BranchAndCommitSelector.tsx new file mode 100644 index 00000000..40a26050 --- /dev/null +++ b/web/components/FormSelectForRefs/BranchAndCommitSelector.tsx @@ -0,0 +1,45 @@ +import { FormSelect } from "@dolthub/react-components"; +import { Maybe } from "@dolthub/web-utils"; +import { OptionalRefParams } from "@lib/params"; +import { branches, commitLog } from "@lib/urls"; +import getGroupOption from "./getGroupOption"; +import css from "./index.module.css"; +import useGetBranchOptionsForSelect from "./useGetBranchOptionsForSelect"; +import useGetCommitOptionsForSelect from "./useGetCommitOptionsForSelect"; + +type Props = { + params: OptionalRefParams; + selectedValue: Maybe; + onChangeValue: (s: Maybe) => void; +}; + +export default function BranchAndCommitSelector(props: Props) { + const { branchOptions } = useGetBranchOptionsForSelect(props.params); + const { commitOptions, refParams } = useGetCommitOptionsForSelect( + props.params, + ); + + const handleChangeRef = async (refName: Maybe) => { + if (!refName) return; + props.onChangeValue(refName); + }; + + const options = [ + getGroupOption(branchOptions, "Branches", branches(refParams)), + getGroupOption(commitOptions, "Commits", commitLog(refParams)), + ]; + + return ( + t.value === props.selectedValue, + )} + label="Pick a branch or recent commit" + onChange={async e => handleChangeRef(e?.value)} + options={options} + placeholder="select a branch or commit..." + className={css.branchAndCommitSelect} + selectedOptionFirst + /> + ); +} diff --git a/web/components/FormSelectForRefs/BranchAndTagSelector.tsx b/web/components/FormSelectForRefs/BranchAndTagSelector.tsx new file mode 100644 index 00000000..710e71b7 --- /dev/null +++ b/web/components/FormSelectForRefs/BranchAndTagSelector.tsx @@ -0,0 +1,80 @@ +import { FormSelect } from "@dolthub/react-components"; +import { Maybe } from "@dolthub/web-utils"; +import { useTableListForBranchLazyQuery } from "@gen/graphql-types"; +import { DatabasePageParams } from "@lib/params"; +import { RefUrl, branches, database, ref, releases } from "@lib/urls"; +import { useRouter } from "next/router"; +import getGroupOption from "./getGroupOption"; +import css from "./index.module.css"; +import useGetBranchOptionsForSelect from "./useGetBranchOptionsForSelect"; +import useGetTagOptionsForSelect from "./useGetTagOptionsForSelect"; + +type Props = { + params: DatabasePageParams; + selectedValue?: string; + routeRefChangeTo: RefUrl; + className?: string; +}; + +export default function BranchAndTagSelector(props: Props) { + const router = useRouter(); + + const [getTableList] = useTableListForBranchLazyQuery(); + + const { tagOptions } = useGetTagOptionsForSelect(props.params); + const { branchOptions } = useGetBranchOptionsForSelect(props.params); + + const handleChangeRef = async (refName: Maybe) => { + if (!refName) return; + const variables = { + ...props.params, + refName, + }; + + // If on a table page, check if the table exists on the new branch. If not, route to ref. + if (props.params.tableName) { + const tableRes = await getTableList({ variables }); + const tableExists = tableRes.data?.tables.some( + v => v.tableName === props.params.tableName, + ); + if (!tableExists) { + const { href, as } = ref({ ...props.params, refName }); + router.push(href, as).catch(console.error); + return; + } + } + + const { href, as } = props.routeRefChangeTo + ? props.routeRefChangeTo({ + ...props.params, + refName, + }) + : database(props.params); + + router.push(href, as).catch(console.error); + }; + + const options = [ + getGroupOption( + branchOptions, + "Branches", + branches({ ...props.params, refName: props.selectedValue }), + ), + getGroupOption(tagOptions, "Tags", releases(props.params)), + ]; + + return ( + t.value === props.selectedValue, + )} + onChange={async e => handleChangeRef(e?.value)} + options={options} + placeholder="select a branch or tag..." + outerClassName={props.className} + className={css.branchAndTagSelect} + selectedOptionFirst + /> + ); +} diff --git a/web/components/CustomFormSelect/DoltDisabledSelector.tsx b/web/components/FormSelectForRefs/DoltDisabledSelector.tsx similarity index 100% rename from web/components/CustomFormSelect/DoltDisabledSelector.tsx rename to web/components/FormSelectForRefs/DoltDisabledSelector.tsx diff --git a/web/components/FormSelectForRefs/NotDoltSelectWrapper.tsx b/web/components/FormSelectForRefs/NotDoltSelectWrapper.tsx new file mode 100644 index 00000000..c0c823d8 --- /dev/null +++ b/web/components/FormSelectForRefs/NotDoltSelectWrapper.tsx @@ -0,0 +1,29 @@ +import NotDoltWrapper from "@components/util/NotDoltWrapper"; +import { Maybe } from "@dolthub/web-utils"; +import { ReactNode } from "react"; +import DoltDisabledSelector from "./DoltDisabledSelector"; + +type Props = { + children: ReactNode; + val: Maybe; +}; + +type InnerProps = Props & { + doltDisabled?: boolean; +}; + +function Inner(props: InnerProps) { + return props.doltDisabled ? ( + + ) : ( + props.children + ); +} + +export default function NotDoltSelectWrapper(props: Props) { + return ( + + {props.children} + + ); +} diff --git a/web/components/FormSelectForRefs/getGroupOption.tsx b/web/components/FormSelectForRefs/getGroupOption.tsx new file mode 100644 index 00000000..a7933f42 --- /dev/null +++ b/web/components/FormSelectForRefs/getGroupOption.tsx @@ -0,0 +1,17 @@ +import Link from "@components/links/Link"; +import { FormSelectTypes } from "@dolthub/react-components"; +import { Route } from "@dolthub/web-utils"; + +export default function getGroupOption( + options: Array>, + label: string, + footerRoute: Route, +): FormSelectTypes.CustomGroupBase> { + const lowerLabel = label.toLowerCase(); + return { + label, + options, + noOptionsMsg: `No ${lowerLabel} found`, + footer: View all {lowerLabel}, + }; +} diff --git a/web/components/FormSelectForRefs/index.module.css b/web/components/FormSelectForRefs/index.module.css new file mode 100644 index 00000000..843e34c4 --- /dev/null +++ b/web/components/FormSelectForRefs/index.module.css @@ -0,0 +1,23 @@ +.branchAndTagSelect { + @apply min-w-[275px] max-w-[275px] w-full; +} + +.branchAndCommitSelect { + @apply max-w-md; + + @screen md { + @apply w-auto; + } +} + +.commitDetails { + @apply text-acc-darkgrey text-xs mt-1; +} + +.commitTimeAgo { + @apply mt-0.5; +} + +.doltDisabled { + @apply bg-ld-lightblue border border-ld-darkgrey px-2.5 py-2 rounded text-sm; +} diff --git a/web/components/CustomFormSelect/mocks.ts b/web/components/FormSelectForRefs/mocks.ts similarity index 100% rename from web/components/CustomFormSelect/mocks.ts rename to web/components/FormSelectForRefs/mocks.ts diff --git a/web/components/CustomFormSelect/queries.ts b/web/components/FormSelectForRefs/queries.ts similarity index 72% rename from web/components/CustomFormSelect/queries.ts rename to web/components/FormSelectForRefs/queries.ts index 319886ca..f76bdd49 100644 --- a/web/components/CustomFormSelect/queries.ts +++ b/web/components/FormSelectForRefs/queries.ts @@ -34,3 +34,16 @@ export const TAG_LIST_QUERY = gql` } } `; + +export const TABLE_LIST_FOR_BRANCH_QUERY = gql` + query TableListForBranch($databaseName: String!, $refName: String!) { + tables( + databaseName: $databaseName + refName: $refName + filterSystemTables: true + ) { + _id + tableName + } + } +`; diff --git a/web/components/FormSelectForRefs/useGetBranchOptionsForSelect.ts b/web/components/FormSelectForRefs/useGetBranchOptionsForSelect.ts new file mode 100644 index 00000000..6f9e5cee --- /dev/null +++ b/web/components/FormSelectForRefs/useGetBranchOptionsForSelect.ts @@ -0,0 +1,27 @@ +import { FormSelectTypes } from "@dolthub/react-components"; +import { excerpt } from "@dolthub/web-utils"; +import { useBranchesForSelectorQuery } from "@gen/graphql-types"; +import { DatabaseParams } from "@lib/params"; + +type ReturnType = { + branchOptions: Array>; +}; + +export default function useGetBranchOptionsForSelect( + params: DatabaseParams, +): ReturnType { + const branchRes = useBranchesForSelectorQuery({ + variables: params, + fetchPolicy: "cache-and-network", + }); + + const branchOptions = + branchRes.data?.allBranches.map(b => { + return { + value: b.branchName, + label: excerpt(b.branchName, 45), + }; + }) ?? []; + + return { branchOptions }; +} diff --git a/web/components/FormSelectForRefs/useGetCommitOptionsForSelect.tsx b/web/components/FormSelectForRefs/useGetCommitOptionsForSelect.tsx new file mode 100644 index 00000000..8b864557 --- /dev/null +++ b/web/components/FormSelectForRefs/useGetCommitOptionsForSelect.tsx @@ -0,0 +1,51 @@ +import { FormSelectTypes } from "@dolthub/react-components"; +import { excerpt, getTimeAgoString } from "@dolthub/web-utils"; +import { CommitForHistoryFragment } from "@gen/graphql-types"; +import { useCommitListForBranch } from "@hooks/useCommitListForBranch"; +import useDefaultBranch from "@hooks/useDefaultBranch"; +import { OptionalRefParams, RefParams } from "@lib/params"; +import css from "./index.module.css"; + +type ReturnType = { + commitOptions: Array>; + refParams: RefParams; +}; + +export default function useGetCommitOptionsForSelect( + params: OptionalRefParams, +): ReturnType { + const { defaultBranchName } = useDefaultBranch(params); + const refParams = { + ...params, + refName: params.refName ?? defaultBranchName, + }; + const commitRes = useCommitListForBranch(refParams, true); + + const commitOptions = + commitRes.commits?.map(c => { + return { + value: c.commitId, + label: c.commitId, + details: , + }; + }) ?? []; + + return { commitOptions, refParams }; +} + +function limitTwoLines(s: string, maxChars: number): string { + return excerpt(s.replace(/(\r\n|\n|\r)/g, " "), maxChars); +} + +const maxCommitMsgChars = 90; + +function CommitDetails(props: { commit: CommitForHistoryFragment }) { + return ( +
+
{limitTwoLines(props.commit.message, maxCommitMsgChars)}
+
+ {getTimeAgoString(props.commit.committedAt)} +
+
+ ); +} diff --git a/web/components/FormSelectForRefs/useGetTagOptionsForSelect.ts b/web/components/FormSelectForRefs/useGetTagOptionsForSelect.ts new file mode 100644 index 00000000..e735e5a8 --- /dev/null +++ b/web/components/FormSelectForRefs/useGetTagOptionsForSelect.ts @@ -0,0 +1,23 @@ +import { FormSelectTypes } from "@dolthub/react-components"; +import { useTagListQuery } from "@gen/graphql-types"; +import { DatabaseParams } from "@lib/params"; + +type ReturnType = { + tagOptions: Array>; +}; + +export default function useGetTagOptionsForSelect( + params: DatabaseParams, +): ReturnType { + const tagRes = useTagListQuery({ variables: params }); + + const tagOptions = + tagRes.data?.tags.list.map(t => { + return { + value: t.tagName, + label: t.tagName, + }; + }) ?? []; + + return { tagOptions }; +} diff --git a/web/components/SchemaDiagram/queries.ts b/web/components/SchemaDiagram/queries.ts index 8cb68ac5..a6372868 100644 --- a/web/components/SchemaDiagram/queries.ts +++ b/web/components/SchemaDiagram/queries.ts @@ -1,6 +1,6 @@ import { gql } from "@apollo/client"; -export const TABLE_LIST_FOR_BRANCH_QUERY = gql` +export const TABLE_LIST_FOR_SCHEMAS_QUERY = gql` fragment ColumnsListForTableList on IndexColumn { name sqlType diff --git a/web/components/pageComponents/DatabasePage/ForBranches/NewBranchPage/NewBranchForm/index.module.css b/web/components/pageComponents/DatabasePage/ForBranches/NewBranchPage/NewBranchForm/index.module.css index 382c0341..48e50faf 100644 --- a/web/components/pageComponents/DatabasePage/ForBranches/NewBranchPage/NewBranchForm/index.module.css +++ b/web/components/pageComponents/DatabasePage/ForBranches/NewBranchPage/NewBranchForm/index.module.css @@ -16,7 +16,3 @@ } } } - -.error { - @apply text-center max-w-xs; -} diff --git a/web/components/pageComponents/DatabasePage/ForBranches/NewBranchPage/NewBranchForm/index.tsx b/web/components/pageComponents/DatabasePage/ForBranches/NewBranchPage/NewBranchForm/index.tsx index 5904059f..a2bbf0d0 100644 --- a/web/components/pageComponents/DatabasePage/ForBranches/NewBranchPage/NewBranchForm/index.tsx +++ b/web/components/pageComponents/DatabasePage/ForBranches/NewBranchPage/NewBranchForm/index.tsx @@ -1,6 +1,5 @@ import ButtonsWithError from "@components/ButtonsWithError"; -import CustomFormSelect from "@components/CustomFormSelect"; -import ErrorMsg from "@components/ErrorMsg"; +import BranchAndCommitSelector from "@components/FormSelectForRefs/BranchAndCommitSelector"; import { Button, FormInput, Loader } from "@dolthub/react-components"; import { useReactiveWidth } from "@dolthub/react-hooks"; import { Maybe } from "@dolthub/web-utils"; @@ -55,7 +54,7 @@ export default function NewBranchForm(props: Props): JSX.Element {
-
-
); diff --git a/web/components/pageComponents/DatabasePage/ForBranches/NewBranchPage/NewBranchForm/mocks.ts b/web/components/pageComponents/DatabasePage/ForBranches/NewBranchPage/NewBranchForm/mocks.ts index 327a6579..94378ad8 100644 --- a/web/components/pageComponents/DatabasePage/ForBranches/NewBranchPage/NewBranchForm/mocks.ts +++ b/web/components/pageComponents/DatabasePage/ForBranches/NewBranchPage/NewBranchForm/mocks.ts @@ -2,7 +2,7 @@ import { MockedResponse } from "@apollo/client/testing"; import { branchSelectorMock, mainBranch, -} from "@components/CustomFormSelect/mocks"; +} from "@components/FormSelectForRefs/mocks"; import { CreateBranchDocument } from "@gen/graphql-types"; import { loremer } from "@lib/loremer"; import { DatabaseParams } from "@lib/params"; diff --git a/web/components/pageComponents/DatabasePage/ForReleases/NewReleasePage/NewReleaseForm/index.module.css b/web/components/pageComponents/DatabasePage/ForReleases/NewReleasePage/NewReleaseForm/index.module.css index 29a0e8a2..e9b57eae 100644 --- a/web/components/pageComponents/DatabasePage/ForReleases/NewReleasePage/NewReleaseForm/index.module.css +++ b/web/components/pageComponents/DatabasePage/ForReleases/NewReleasePage/NewReleaseForm/index.module.css @@ -11,10 +11,6 @@ @apply max-w-md; } -.error { - @apply text-center max-w-xs; -} - .textarea { @apply max-w-none; } diff --git a/web/components/pageComponents/DatabasePage/ForReleases/NewReleasePage/NewReleaseForm/index.tsx b/web/components/pageComponents/DatabasePage/ForReleases/NewReleasePage/NewReleaseForm/index.tsx index fb632586..f4853722 100644 --- a/web/components/pageComponents/DatabasePage/ForReleases/NewReleasePage/NewReleaseForm/index.tsx +++ b/web/components/pageComponents/DatabasePage/ForReleases/NewReleasePage/NewReleaseForm/index.tsx @@ -1,6 +1,5 @@ import ButtonsWithError from "@components/ButtonsWithError"; -import CustomFormSelect from "@components/CustomFormSelect"; -import ErrorMsg from "@components/ErrorMsg"; +import BranchAndCommitSelector from "@components/FormSelectForRefs/BranchAndCommitSelector"; import { Button, FormInput, Loader, Textarea } from "@dolthub/react-components"; import { OptionalRefParams } from "@lib/params"; import { releases } from "@lib/urls"; @@ -36,7 +35,7 @@ export default function NewTagForm(props: Props): JSX.Element {
- createTagRes.setFormData({ fromRefName: s })} @@ -72,6 +71,7 @@ export default function NewTagForm(props: Props): JSX.Element {
-
); diff --git a/web/components/pageComponents/DatabasePage/ForReleases/NewReleasePage/NewReleaseForm/mocks.ts b/web/components/pageComponents/DatabasePage/ForReleases/NewReleasePage/NewReleaseForm/mocks.ts index 049eab4d..9fb4a942 100644 --- a/web/components/pageComponents/DatabasePage/ForReleases/NewReleasePage/NewReleaseForm/mocks.ts +++ b/web/components/pageComponents/DatabasePage/ForReleases/NewReleasePage/NewReleaseForm/mocks.ts @@ -2,7 +2,7 @@ import { MockedResponse } from "@apollo/client/testing"; import { branchSelectorMock, mainBranch, -} from "@components/CustomFormSelect/mocks"; +} from "@components/FormSelectForRefs/mocks"; import { CreateTagDocument } from "@gen/graphql-types"; import { loremer } from "@lib/loremer"; import { defaultBranchMock } from "../../../ForDefaultBranch/mocks"; diff --git a/web/components/pageComponents/FileUploadPage/Steps/Branch/index.module.css b/web/components/pageComponents/FileUploadPage/Steps/Branch/index.module.css index dfb9d23c..e81862a8 100644 --- a/web/components/pageComponents/FileUploadPage/Steps/Branch/index.module.css +++ b/web/components/pageComponents/FileUploadPage/Steps/Branch/index.module.css @@ -1,3 +1,7 @@ -.selector { +.outerSelector { @apply text-left mx-auto w-72 my-8; } + +.selector { + @apply min-w-64; +} diff --git a/web/components/pageComponents/FileUploadPage/Steps/Branch/index.tsx b/web/components/pageComponents/FileUploadPage/Steps/Branch/index.tsx index d42ef65e..92b1d1bb 100644 --- a/web/components/pageComponents/FileUploadPage/Steps/Branch/index.tsx +++ b/web/components/pageComponents/FileUploadPage/Steps/Branch/index.tsx @@ -1,7 +1,7 @@ -import CustomFormSelect from "@components/CustomFormSelect"; import ErrorMsg from "@components/ErrorMsg"; +import useGetBranchOptionsForSelect from "@components/FormSelectForRefs/useGetBranchOptionsForSelect"; import DatabaseLink from "@components/links/DatabaseLink"; -import { Loader } from "@dolthub/react-components"; +import { FormSelect, Loader } from "@dolthub/react-components"; import StepLayout from "../../StepLayout"; import { useFileUploadContext } from "../../contexts/fileUploadLocalForage"; import { UploadStage } from "../../enums"; @@ -17,6 +17,7 @@ export default function Branch() { function Inner() { const { state, error, updateLoad, setItem, dbParams, getUploadUrl } = useFileUploadContext(); + const { branchOptions } = useGetBranchOptionsForSelect(dbParams); return ( {" "} to base your changes on.

-
- setItem("branchName", b)} - showLabel - mono - /> -
+ setItem("branchName", b)} + label="Branch" + selectedOptionFirst + horizontal + mono + />
diff --git a/web/gen/graphql-types.tsx b/web/gen/graphql-types.tsx index 72a69b89..c1f0d381 100644 --- a/web/gen/graphql-types.tsx +++ b/web/gen/graphql-types.tsx @@ -690,26 +690,6 @@ export type CreateSchemaMutationVariables = Exact<{ export type CreateSchemaMutation = { __typename?: 'Mutation', createSchema: boolean }; -export type BranchForBranchSelectorFragment = { __typename?: 'Branch', branchName: string, databaseName: string }; - -export type BranchesForSelectorQueryVariables = Exact<{ - databaseName: Scalars['String']['input']; -}>; - - -export type BranchesForSelectorQuery = { __typename?: 'Query', allBranches: Array<{ __typename?: 'Branch', branchName: string, databaseName: string }> }; - -export type TagForListFragment = { __typename?: 'Tag', _id: string, tagName: string, message: string, taggedAt: any, commitId: string, tagger: { __typename?: 'DoltWriter', _id: string, username?: string | null, displayName: string, emailAddress: string } }; - -export type TagListForTagListFragment = { __typename?: 'TagList', list: Array<{ __typename?: 'Tag', _id: string, tagName: string, message: string, taggedAt: any, commitId: string, tagger: { __typename?: 'DoltWriter', _id: string, username?: string | null, displayName: string, emailAddress: string } }> }; - -export type TagListQueryVariables = Exact<{ - databaseName: Scalars['String']['input']; -}>; - - -export type TagListQuery = { __typename?: 'Query', tags: { __typename?: 'TagList', list: Array<{ __typename?: 'Tag', _id: string, tagName: string, message: string, taggedAt: any, commitId: string, tagger: { __typename?: 'DoltWriter', _id: string, username?: string | null, displayName: string, emailAddress: string } }> } }; - export type CurrentDatabaseQueryVariables = Exact<{ [key: string]: never; }>; @@ -816,6 +796,34 @@ export type SchemaDiffQueryVariables = Exact<{ export type SchemaDiffQuery = { __typename?: 'Query', schemaDiff?: { __typename?: 'SchemaDiff', schemaPatch?: Array | null, schemaDiff?: { __typename?: 'TextDiff', leftLines: string, rightLines: string } | null } | null }; +export type BranchForBranchSelectorFragment = { __typename?: 'Branch', branchName: string, databaseName: string }; + +export type BranchesForSelectorQueryVariables = Exact<{ + databaseName: Scalars['String']['input']; +}>; + + +export type BranchesForSelectorQuery = { __typename?: 'Query', allBranches: Array<{ __typename?: 'Branch', branchName: string, databaseName: string }> }; + +export type TagForListFragment = { __typename?: 'Tag', _id: string, tagName: string, message: string, taggedAt: any, commitId: string, tagger: { __typename?: 'DoltWriter', _id: string, username?: string | null, displayName: string, emailAddress: string } }; + +export type TagListForTagListFragment = { __typename?: 'TagList', list: Array<{ __typename?: 'Tag', _id: string, tagName: string, message: string, taggedAt: any, commitId: string, tagger: { __typename?: 'DoltWriter', _id: string, username?: string | null, displayName: string, emailAddress: string } }> }; + +export type TagListQueryVariables = Exact<{ + databaseName: Scalars['String']['input']; +}>; + + +export type TagListQuery = { __typename?: 'Query', tags: { __typename?: 'TagList', list: Array<{ __typename?: 'Tag', _id: string, tagName: string, message: string, taggedAt: any, commitId: string, tagger: { __typename?: 'DoltWriter', _id: string, username?: string | null, displayName: string, emailAddress: string } }> } }; + +export type TableListForBranchQueryVariables = Exact<{ + databaseName: Scalars['String']['input']; + refName: Scalars['String']['input']; +}>; + + +export type TableListForBranchQuery = { __typename?: 'Query', tables: Array<{ __typename?: 'Table', _id: string, tableName: string }> }; + export type ColumnsListForTableListFragment = { __typename?: 'IndexColumn', name: string, sqlType?: string | null }; export type IndexForTableListFragment = { __typename?: 'Index', name: string, type: string, comment: string, columns: Array<{ __typename?: 'IndexColumn', name: string, sqlType?: string | null }> }; @@ -1160,39 +1168,6 @@ export type TableNamesQueryVariables = Exact<{ export type TableNamesQuery = { __typename?: 'Query', tableNames: { __typename?: 'TableNames', list: Array } }; -export const BranchForBranchSelectorFragmentDoc = gql` - fragment BranchForBranchSelector on Branch { - branchName - databaseName -} - `; -export const DoltWriterForHistoryFragmentDoc = gql` - fragment DoltWriterForHistory on DoltWriter { - _id - username - displayName - emailAddress -} - `; -export const TagForListFragmentDoc = gql` - fragment TagForList on Tag { - _id - tagName - message - taggedAt - tagger { - ...DoltWriterForHistory - } - commitId -} - ${DoltWriterForHistoryFragmentDoc}`; -export const TagListForTagListFragmentDoc = gql` - fragment TagListForTagList on TagList { - list { - ...TagForList - } -} - ${TagForListFragmentDoc}`; export const CommitForDiffSelectorFragmentDoc = gql` fragment CommitForDiffSelector on Commit { _id @@ -1283,6 +1258,39 @@ export const SchemaDiffFragmentDoc = gql` schemaPatch } ${SchemaDiffForTableListFragmentDoc}`; +export const BranchForBranchSelectorFragmentDoc = gql` + fragment BranchForBranchSelector on Branch { + branchName + databaseName +} + `; +export const DoltWriterForHistoryFragmentDoc = gql` + fragment DoltWriterForHistory on DoltWriter { + _id + username + displayName + emailAddress +} + `; +export const TagForListFragmentDoc = gql` + fragment TagForList on Tag { + _id + tagName + message + taggedAt + tagger { + ...DoltWriterForHistory + } + commitId +} + ${DoltWriterForHistoryFragmentDoc}`; +export const TagListForTagListFragmentDoc = gql` + fragment TagListForTagList on TagList { + list { + ...TagForList + } +} + ${TagForListFragmentDoc}`; export const ForeignKeyColumnForDataTableFragmentDoc = gql` fragment ForeignKeyColumnForDataTable on ForeignKeyColumn { referencedColumnName @@ -1605,86 +1613,6 @@ export function useCreateSchemaMutation(baseOptions?: Apollo.MutationHookOptions export type CreateSchemaMutationHookResult = ReturnType; export type CreateSchemaMutationResult = Apollo.MutationResult; export type CreateSchemaMutationOptions = Apollo.BaseMutationOptions; -export const BranchesForSelectorDocument = gql` - query BranchesForSelector($databaseName: String!) { - allBranches(databaseName: $databaseName) { - ...BranchForBranchSelector - } -} - ${BranchForBranchSelectorFragmentDoc}`; - -/** - * __useBranchesForSelectorQuery__ - * - * To run a query within a React component, call `useBranchesForSelectorQuery` and pass it any options that fit your needs. - * When your component renders, `useBranchesForSelectorQuery` returns an object from Apollo Client that contains loading, error, and data properties - * you can use to render your UI. - * - * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; - * - * @example - * const { data, loading, error } = useBranchesForSelectorQuery({ - * variables: { - * databaseName: // value for 'databaseName' - * }, - * }); - */ -export function useBranchesForSelectorQuery(baseOptions: Apollo.QueryHookOptions & ({ variables: BranchesForSelectorQueryVariables; skip?: boolean; } | { skip: boolean; }) ) { - const options = {...defaultOptions, ...baseOptions} - return Apollo.useQuery(BranchesForSelectorDocument, options); - } -export function useBranchesForSelectorLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { - const options = {...defaultOptions, ...baseOptions} - return Apollo.useLazyQuery(BranchesForSelectorDocument, options); - } -export function useBranchesForSelectorSuspenseQuery(baseOptions?: Apollo.SuspenseQueryHookOptions) { - const options = {...defaultOptions, ...baseOptions} - return Apollo.useSuspenseQuery(BranchesForSelectorDocument, options); - } -export type BranchesForSelectorQueryHookResult = ReturnType; -export type BranchesForSelectorLazyQueryHookResult = ReturnType; -export type BranchesForSelectorSuspenseQueryHookResult = ReturnType; -export type BranchesForSelectorQueryResult = Apollo.QueryResult; -export const TagListDocument = gql` - query TagList($databaseName: String!) { - tags(databaseName: $databaseName) { - ...TagListForTagList - } -} - ${TagListForTagListFragmentDoc}`; - -/** - * __useTagListQuery__ - * - * To run a query within a React component, call `useTagListQuery` and pass it any options that fit your needs. - * When your component renders, `useTagListQuery` returns an object from Apollo Client that contains loading, error, and data properties - * you can use to render your UI. - * - * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; - * - * @example - * const { data, loading, error } = useTagListQuery({ - * variables: { - * databaseName: // value for 'databaseName' - * }, - * }); - */ -export function useTagListQuery(baseOptions: Apollo.QueryHookOptions & ({ variables: TagListQueryVariables; skip?: boolean; } | { skip: boolean; }) ) { - const options = {...defaultOptions, ...baseOptions} - return Apollo.useQuery(TagListDocument, options); - } -export function useTagListLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { - const options = {...defaultOptions, ...baseOptions} - return Apollo.useLazyQuery(TagListDocument, options); - } -export function useTagListSuspenseQuery(baseOptions?: Apollo.SuspenseQueryHookOptions) { - const options = {...defaultOptions, ...baseOptions} - return Apollo.useSuspenseQuery(TagListDocument, options); - } -export type TagListQueryHookResult = ReturnType; -export type TagListLazyQueryHookResult = ReturnType; -export type TagListSuspenseQueryHookResult = ReturnType; -export type TagListQueryResult = Apollo.QueryResult; export const CurrentDatabaseDocument = gql` query CurrentDatabase { currentDatabase @@ -2116,6 +2044,128 @@ export type SchemaDiffQueryHookResult = ReturnType; export type SchemaDiffLazyQueryHookResult = ReturnType; export type SchemaDiffSuspenseQueryHookResult = ReturnType; export type SchemaDiffQueryResult = Apollo.QueryResult; +export const BranchesForSelectorDocument = gql` + query BranchesForSelector($databaseName: String!) { + allBranches(databaseName: $databaseName) { + ...BranchForBranchSelector + } +} + ${BranchForBranchSelectorFragmentDoc}`; + +/** + * __useBranchesForSelectorQuery__ + * + * To run a query within a React component, call `useBranchesForSelectorQuery` and pass it any options that fit your needs. + * When your component renders, `useBranchesForSelectorQuery` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useBranchesForSelectorQuery({ + * variables: { + * databaseName: // value for 'databaseName' + * }, + * }); + */ +export function useBranchesForSelectorQuery(baseOptions: Apollo.QueryHookOptions & ({ variables: BranchesForSelectorQueryVariables; skip?: boolean; } | { skip: boolean; }) ) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useQuery(BranchesForSelectorDocument, options); + } +export function useBranchesForSelectorLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useLazyQuery(BranchesForSelectorDocument, options); + } +export function useBranchesForSelectorSuspenseQuery(baseOptions?: Apollo.SuspenseQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useSuspenseQuery(BranchesForSelectorDocument, options); + } +export type BranchesForSelectorQueryHookResult = ReturnType; +export type BranchesForSelectorLazyQueryHookResult = ReturnType; +export type BranchesForSelectorSuspenseQueryHookResult = ReturnType; +export type BranchesForSelectorQueryResult = Apollo.QueryResult; +export const TagListDocument = gql` + query TagList($databaseName: String!) { + tags(databaseName: $databaseName) { + ...TagListForTagList + } +} + ${TagListForTagListFragmentDoc}`; + +/** + * __useTagListQuery__ + * + * To run a query within a React component, call `useTagListQuery` and pass it any options that fit your needs. + * When your component renders, `useTagListQuery` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useTagListQuery({ + * variables: { + * databaseName: // value for 'databaseName' + * }, + * }); + */ +export function useTagListQuery(baseOptions: Apollo.QueryHookOptions & ({ variables: TagListQueryVariables; skip?: boolean; } | { skip: boolean; }) ) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useQuery(TagListDocument, options); + } +export function useTagListLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useLazyQuery(TagListDocument, options); + } +export function useTagListSuspenseQuery(baseOptions?: Apollo.SuspenseQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useSuspenseQuery(TagListDocument, options); + } +export type TagListQueryHookResult = ReturnType; +export type TagListLazyQueryHookResult = ReturnType; +export type TagListSuspenseQueryHookResult = ReturnType; +export type TagListQueryResult = Apollo.QueryResult; +export const TableListForBranchDocument = gql` + query TableListForBranch($databaseName: String!, $refName: String!) { + tables(databaseName: $databaseName, refName: $refName, filterSystemTables: true) { + _id + tableName + } +} + `; + +/** + * __useTableListForBranchQuery__ + * + * To run a query within a React component, call `useTableListForBranchQuery` and pass it any options that fit your needs. + * When your component renders, `useTableListForBranchQuery` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useTableListForBranchQuery({ + * variables: { + * databaseName: // value for 'databaseName' + * refName: // value for 'refName' + * }, + * }); + */ +export function useTableListForBranchQuery(baseOptions: Apollo.QueryHookOptions & ({ variables: TableListForBranchQueryVariables; skip?: boolean; } | { skip: boolean; }) ) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useQuery(TableListForBranchDocument, options); + } +export function useTableListForBranchLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useLazyQuery(TableListForBranchDocument, options); + } +export function useTableListForBranchSuspenseQuery(baseOptions?: Apollo.SuspenseQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useSuspenseQuery(TableListForBranchDocument, options); + } +export type TableListForBranchQueryHookResult = ReturnType; +export type TableListForBranchLazyQueryHookResult = ReturnType; +export type TableListForBranchSuspenseQueryHookResult = ReturnType; +export type TableListForBranchQueryResult = Apollo.QueryResult; export const TableListForSchemasDocument = gql` query TableListForSchemas($databaseName: String!, $refName: String!) { tables(databaseName: $databaseName, refName: $refName, filterSystemTables: true) { From 86c7ce6980044ab7e2ec61ebbcac08a8249cd1b9 Mon Sep 17 00:00:00 2001 From: Taylor Bantle Date: Mon, 18 Mar 2024 10:12:26 -0700 Subject: [PATCH 2/6] web: Fixes --- web/components/DatabaseHeaderAndNav/Full.tsx | 4 +++- .../DatabaseHeaderAndNav/MobileHeaderSelector.tsx | 2 -- .../FormSelectForRefs/BranchAndTagSelector.tsx | 12 +++++------- web/components/FormSelectForRefs/index.module.css | 6 +----- .../useGetCommitOptionsForSelect.tsx | 2 +- .../NewBranchPage/NewBranchForm/index.tsx | 2 +- 6 files changed, 11 insertions(+), 17 deletions(-) diff --git a/web/components/DatabaseHeaderAndNav/Full.tsx b/web/components/DatabaseHeaderAndNav/Full.tsx index 1f45482b..12ad8d9e 100644 --- a/web/components/DatabaseHeaderAndNav/Full.tsx +++ b/web/components/DatabaseHeaderAndNav/Full.tsx @@ -34,7 +34,9 @@ export default function Full(props: Props) { {...props} onMenuClick={() => props.setShowSmall(true)} /> - +
+ +
diff --git a/web/components/DatabaseHeaderAndNav/MobileHeaderSelector.tsx b/web/components/DatabaseHeaderAndNav/MobileHeaderSelector.tsx index 92c40205..5bd46772 100644 --- a/web/components/DatabaseHeaderAndNav/MobileHeaderSelector.tsx +++ b/web/components/DatabaseHeaderAndNav/MobileHeaderSelector.tsx @@ -7,7 +7,6 @@ import { } from "@lib/mobileUtils"; import { OptionalRefParams } from "@lib/params"; import { useRouter } from "next/router"; -import css from "./index.module.css"; type Props = { params: OptionalRefParams; @@ -45,7 +44,6 @@ export default function MobileHeaderSelector(props: Props) { options={getTabOptions(res.isDolt, res.hideDoltFeature)} val={pageName} hideSelectedOptions - outerClassName={css.mobileSelector} forMobile /> ); diff --git a/web/components/FormSelectForRefs/BranchAndTagSelector.tsx b/web/components/FormSelectForRefs/BranchAndTagSelector.tsx index 710e71b7..d57670cf 100644 --- a/web/components/FormSelectForRefs/BranchAndTagSelector.tsx +++ b/web/components/FormSelectForRefs/BranchAndTagSelector.tsx @@ -2,7 +2,7 @@ import { FormSelect } from "@dolthub/react-components"; import { Maybe } from "@dolthub/web-utils"; import { useTableListForBranchLazyQuery } from "@gen/graphql-types"; import { DatabasePageParams } from "@lib/params"; -import { RefUrl, branches, database, ref, releases } from "@lib/urls"; +import { RefUrl, branches, ref, releases } from "@lib/urls"; import { useRouter } from "next/router"; import getGroupOption from "./getGroupOption"; import css from "./index.module.css"; @@ -44,12 +44,10 @@ export default function BranchAndTagSelector(props: Props) { } } - const { href, as } = props.routeRefChangeTo - ? props.routeRefChangeTo({ - ...props.params, - refName, - }) - : database(props.params); + const { href, as } = props.routeRefChangeTo({ + ...props.params, + refName, + }); router.push(href, as).catch(console.error); }; diff --git a/web/components/FormSelectForRefs/index.module.css b/web/components/FormSelectForRefs/index.module.css index 843e34c4..5f07e8fc 100644 --- a/web/components/FormSelectForRefs/index.module.css +++ b/web/components/FormSelectForRefs/index.module.css @@ -1,5 +1,5 @@ .branchAndTagSelect { - @apply min-w-[275px] max-w-[275px] w-full; + @apply min-w-[270px] max-w-[270px] w-full; } .branchAndCommitSelect { @@ -10,10 +10,6 @@ } } -.commitDetails { - @apply text-acc-darkgrey text-xs mt-1; -} - .commitTimeAgo { @apply mt-0.5; } diff --git a/web/components/FormSelectForRefs/useGetCommitOptionsForSelect.tsx b/web/components/FormSelectForRefs/useGetCommitOptionsForSelect.tsx index 8b864557..5907b8e4 100644 --- a/web/components/FormSelectForRefs/useGetCommitOptionsForSelect.tsx +++ b/web/components/FormSelectForRefs/useGetCommitOptionsForSelect.tsx @@ -41,7 +41,7 @@ const maxCommitMsgChars = 90; function CommitDetails(props: { commit: CommitForHistoryFragment }) { return ( -
+
{limitTwoLines(props.commit.message, maxCommitMsgChars)}
{getTimeAgoString(props.commit.committedAt)} diff --git a/web/components/pageComponents/DatabasePage/ForBranches/NewBranchPage/NewBranchForm/index.tsx b/web/components/pageComponents/DatabasePage/ForBranches/NewBranchPage/NewBranchForm/index.tsx index a2bbf0d0..dffba01c 100644 --- a/web/components/pageComponents/DatabasePage/ForBranches/NewBranchPage/NewBranchForm/index.tsx +++ b/web/components/pageComponents/DatabasePage/ForBranches/NewBranchPage/NewBranchForm/index.tsx @@ -63,7 +63,7 @@ export default function NewBranchForm(props: Props): JSX.Element { value={newBranchName} onChangeString={setNewBranchName} label="New branch name" - placeholder="" + placeholder="i.e. feature-branch" className={css.input} /> Date: Mon, 18 Mar 2024 16:10:29 -0700 Subject: [PATCH 3/6] web: Add unit tests --- .../DiffTable/DiffTableStats/mocks.ts | 2 +- .../DiffTableNav/CommitInfo/mocks.ts | 2 +- .../BranchAndCommitSelector.tsx | 12 +- .../BranchAndTagSelector.tsx | 12 +- .../FormSelectForRefs/getGroupOption.tsx | 6 +- web/components/FormSelectForRefs/mocks.ts | 221 ------------------ .../tests/BranchAndCommitSelector.test.tsx | 39 ++++ .../tests/BranchAndTagSelector.test.tsx | 130 +++++++++++ .../FormSelectForRefs/tests/mocks.ts | 211 +++++++++++++++++ .../FormSelectForRefs/tests/utils.test.ts | 95 ++++++++ .../useGetBranchOptionsForSelect.ts | 4 +- .../useGetCommitOptionsForSelect.tsx | 4 +- .../useGetTagOptionsForSelect.ts | 4 +- .../NewBranchPage/NewBranchForm/mocks.ts | 2 +- .../NewReleasePage/NewReleaseForm/mocks.ts | 7 +- .../ForReleases/ReleaseList/mocks.ts | 47 ++-- web/hooks/useCommitListForBranch/mocks.ts | 68 ++++++ 17 files changed, 610 insertions(+), 256 deletions(-) delete mode 100644 web/components/FormSelectForRefs/mocks.ts create mode 100644 web/components/FormSelectForRefs/tests/BranchAndCommitSelector.test.tsx create mode 100644 web/components/FormSelectForRefs/tests/BranchAndTagSelector.test.tsx create mode 100644 web/components/FormSelectForRefs/tests/mocks.ts create mode 100644 web/components/FormSelectForRefs/tests/utils.test.ts create mode 100644 web/hooks/useCommitListForBranch/mocks.ts diff --git a/web/components/DiffTable/DiffTableStats/mocks.ts b/web/components/DiffTable/DiffTableStats/mocks.ts index 93083867..0ac5a79a 100644 --- a/web/components/DiffTable/DiffTableStats/mocks.ts +++ b/web/components/DiffTable/DiffTableStats/mocks.ts @@ -1,5 +1,5 @@ -import { fakeCommitId } from "@components/FormSelectForRefs/mocks"; import { ColumnForDataTableFragment } from "@gen/graphql-types"; +import { fakeCommitId } from "@hooks/useCommitListForBranch/mocks"; import { RequiredRefsParams, TableParams } from "@lib/params"; type Params = RequiredRefsParams & { tableName: string; refName: string }; diff --git a/web/components/DiffTableNav/CommitInfo/mocks.ts b/web/components/DiffTableNav/CommitInfo/mocks.ts index 9077afaf..82f846fc 100644 --- a/web/components/DiffTableNav/CommitInfo/mocks.ts +++ b/web/components/DiffTableNav/CommitInfo/mocks.ts @@ -1,9 +1,9 @@ import { MockedResponse } from "@apollo/client/testing"; -import { fakeCommitId } from "@components/FormSelectForRefs/mocks"; import { CommitForAfterCommitHistoryFragment, HistoryForCommitDocument, } from "@gen/graphql-types"; +import { fakeCommitId } from "@hooks/useCommitListForBranch/mocks"; import chance from "@lib/chance"; import { RefParams } from "@lib/params"; diff --git a/web/components/FormSelectForRefs/BranchAndCommitSelector.tsx b/web/components/FormSelectForRefs/BranchAndCommitSelector.tsx index 40a26050..edebb06b 100644 --- a/web/components/FormSelectForRefs/BranchAndCommitSelector.tsx +++ b/web/components/FormSelectForRefs/BranchAndCommitSelector.tsx @@ -14,10 +14,14 @@ type Props = { }; export default function BranchAndCommitSelector(props: Props) { - const { branchOptions } = useGetBranchOptionsForSelect(props.params); - const { commitOptions, refParams } = useGetCommitOptionsForSelect( + const { branchOptions, error: branchErr } = useGetBranchOptionsForSelect( props.params, ); + const { + commitOptions, + refParams, + error: commitErr, + } = useGetCommitOptionsForSelect(props.params); const handleChangeRef = async (refName: Maybe) => { if (!refName) return; @@ -25,8 +29,8 @@ export default function BranchAndCommitSelector(props: Props) { }; const options = [ - getGroupOption(branchOptions, "Branches", branches(refParams)), - getGroupOption(commitOptions, "Commits", commitLog(refParams)), + getGroupOption(branchOptions, "Branches", branches(refParams), branchErr), + getGroupOption(commitOptions, "Commits", commitLog(refParams), commitErr), ]; return ( diff --git a/web/components/FormSelectForRefs/BranchAndTagSelector.tsx b/web/components/FormSelectForRefs/BranchAndTagSelector.tsx index d57670cf..b664a250 100644 --- a/web/components/FormSelectForRefs/BranchAndTagSelector.tsx +++ b/web/components/FormSelectForRefs/BranchAndTagSelector.tsx @@ -21,8 +21,10 @@ export default function BranchAndTagSelector(props: Props) { const [getTableList] = useTableListForBranchLazyQuery(); - const { tagOptions } = useGetTagOptionsForSelect(props.params); - const { branchOptions } = useGetBranchOptionsForSelect(props.params); + const { tagOptions, error: tagErr } = useGetTagOptionsForSelect(props.params); + const { branchOptions, error: branchErr } = useGetBranchOptionsForSelect( + props.params, + ); const handleChangeRef = async (refName: Maybe) => { if (!refName) return; @@ -31,7 +33,8 @@ export default function BranchAndTagSelector(props: Props) { refName, }; - // If on a table page, check if the table exists on the new branch. If not, route to ref. + // If on a table page, check if the table exists on the new branch. If not, + // route to ref. if (props.params.tableName) { const tableRes = await getTableList({ variables }); const tableExists = tableRes.data?.tables.some( @@ -57,8 +60,9 @@ export default function BranchAndTagSelector(props: Props) { branchOptions, "Branches", branches({ ...props.params, refName: props.selectedValue }), + branchErr, ), - getGroupOption(tagOptions, "Tags", releases(props.params)), + getGroupOption(tagOptions, "Tags", releases(props.params), tagErr), ]; return ( diff --git a/web/components/FormSelectForRefs/getGroupOption.tsx b/web/components/FormSelectForRefs/getGroupOption.tsx index a7933f42..d0d2825f 100644 --- a/web/components/FormSelectForRefs/getGroupOption.tsx +++ b/web/components/FormSelectForRefs/getGroupOption.tsx @@ -1,17 +1,21 @@ import Link from "@components/links/Link"; import { FormSelectTypes } from "@dolthub/react-components"; import { Route } from "@dolthub/web-utils"; +import { ApolloErrorType } from "@lib/errors/types"; export default function getGroupOption( options: Array>, label: string, footerRoute: Route, + error?: ApolloErrorType, ): FormSelectTypes.CustomGroupBase> { const lowerLabel = label.toLowerCase(); return { label, options, - noOptionsMsg: `No ${lowerLabel} found`, + noOptionsMsg: error + ? `Error getting ${lowerLabel}: ${error.message}` + : `No ${lowerLabel} found`, footer: View all {lowerLabel}, }; } diff --git a/web/components/FormSelectForRefs/mocks.ts b/web/components/FormSelectForRefs/mocks.ts deleted file mode 100644 index 839316df..00000000 --- a/web/components/FormSelectForRefs/mocks.ts +++ /dev/null @@ -1,221 +0,0 @@ -import { MockedResponse } from "@apollo/client/testing"; -import { - BranchesForSelectorDocument, - BranchForBranchSelectorFragment, - CommitForHistoryFragment, - HistoryForBranchDocument, -} from "@gen/graphql-types"; -import chance from "@lib/chance"; -import { DatabaseParams } from "@lib/params"; -import { defaultBranchMock } from "@pageComponents/DatabasePage/ForDefaultBranch/mocks"; - -export const fakeParams: DatabaseParams = { - databaseName: "dbname", -}; - -export const randomSelect = chance.name(); -export const fakeBranchName = "test-branch"; -export const defaultBranchQuery = defaultBranchMock({ - ...fakeParams, - branchName: fakeBranchName, -}); - -export const mainBranch = ( - params: DatabaseParams, -): BranchForBranchSelectorFragment => { - return { - __typename: "Branch", - ...params, - branchName: "main", - }; -}; - -const testBranch = ( - params: DatabaseParams, -): BranchForBranchSelectorFragment => { - return { - __typename: "Branch", - ...params, - branchName: "test", - }; -}; - -export const branchTests = [ - { - title: "test: no selected value with branches", - empty: false, - selected: "", - error: false, - }, - { - title: "test: selected value as random value with branches", - empty: false, - selected: randomSelect, - error: false, - }, - { - title: "test: empty", - empty: true, - selected: "", - error: false, - }, - { - title: "test: error", - empty: true, - selected: "", - error: true, - }, -]; - -export const branchSelectorMock = ( - params: DatabaseParams, - empty?: boolean, -): MockedResponse => { - return { - request: { - query: BranchesForSelectorDocument, - variables: params, - }, - result: { - data: { - allBranches: empty ? [] : [testBranch(params), mainBranch(params)], - }, - }, - }; -}; - -export const noBranchMock = (params: DatabaseParams): MockedResponse => { - return { - request: { - query: BranchesForSelectorDocument, - variables: params, - }, - result: { - data: { - allBranches: [], - }, - }, - }; -}; - -export const oneBranchMock = (params: DatabaseParams): MockedResponse => { - return { - request: { - query: BranchesForSelectorDocument, - variables: params, - }, - result: { - data: { - allBranches: [mainBranch(params)], - }, - }, - }; -}; - -export const branchError = "branch error"; -export const errorMock = (params: DatabaseParams): MockedResponse => { - return { - request: { - query: BranchesForSelectorDocument, - variables: params, - }, - error: new Error(branchError), - }; -}; - -export function fakeCommitId() { - return chance.hash().slice(0, 32); -} - -const commitMock = (): CommitForHistoryFragment => { - const commitId = fakeCommitId(); - const email = chance.email(); - return { - __typename: "Commit", - _id: `databases/${fakeParams.databaseName}/commits/${commitId}`, - commitId, - message: chance.sentence(), - committedAt: Date.now(), - parents: [], - committer: { - __typename: "DoltWriter", - _id: email, - displayName: chance.name(), - username: chance.word(), - emailAddress: email, - }, - }; -}; - -export const commitPicked = commitMock(); -export const commitNotPicked = commitMock(); - -export const commitTests = [ - { - title: "test: no selected value with commits", - empty: false, - selected: "", - error: false, - }, - { - title: "test: selected value as commitId with commits", - empty: false, - selected: commitPicked.commitId, - error: false, - }, - { - title: "test: selected value as random value with commits", - empty: false, - selected: randomSelect, - error: false, - }, - { - title: "test: empty", - empty: true, - selected: "", - error: false, - }, - { - title: "test: error", - empty: true, - selected: "", - error: true, - }, -]; - -export const commitsListMock = (empty: boolean): MockedResponse[] => [ - { - request: { - query: HistoryForBranchDocument, - variables: { - databaseName: fakeParams.databaseName, - refName: fakeBranchName, - }, - }, - result: { - data: { - __typename: "Query", - commits: { - __typename: "CommitList", - nextOffset: "", - list: empty ? [] : [commitPicked, commitNotPicked], - }, - }, - }, - }, -]; - -export const commitError = "Commit Error"; - -export const mockCommitError = (): MockedResponse[] => [ - { - request: { - query: HistoryForBranchDocument, - variables: { - databaseName: fakeParams.databaseName, - refName: fakeBranchName, - }, - }, - error: new Error(commitError), - }, -]; diff --git a/web/components/FormSelectForRefs/tests/BranchAndCommitSelector.test.tsx b/web/components/FormSelectForRefs/tests/BranchAndCommitSelector.test.tsx new file mode 100644 index 00000000..a969f111 --- /dev/null +++ b/web/components/FormSelectForRefs/tests/BranchAndCommitSelector.test.tsx @@ -0,0 +1,39 @@ +import { MockedProvider } from "@apollo/client/testing"; +import { commitError } from "@hooks/useCommitListForBranch/mocks"; +import { setup } from "@lib/testUtils.test"; +import { screen } from "@testing-library/react"; +import BranchAndCommitSelector from "../BranchAndCommitSelector"; +import * as mocks from "./mocks"; +import { testRenderComponent } from "./utils.test"; + +describe("test BranchAndCommitSelector", () => { + mocks.branchAndCommitTests.forEach(test => { + it(`renders for ${test.desc}`, async () => { + const onChangeValue = jest.fn(); + + const { user } = setup( + + + , + ); + + expect( + screen.getByText("Pick a branch or recent commit"), + ).toBeInTheDocument(); + + await testRenderComponent(test, user, "Commit", commitError, async v => { + expect(onChangeValue).toHaveBeenLastCalledWith(v); + }); + }); + }); +}); diff --git a/web/components/FormSelectForRefs/tests/BranchAndTagSelector.test.tsx b/web/components/FormSelectForRefs/tests/BranchAndTagSelector.test.tsx new file mode 100644 index 00000000..387ab5c0 --- /dev/null +++ b/web/components/FormSelectForRefs/tests/BranchAndTagSelector.test.tsx @@ -0,0 +1,130 @@ +import { MockedProvider } from "@apollo/client/testing"; +import { tagError } from "@components/pageComponents/DatabasePage/ForReleases/ReleaseList/mocks"; +import useMockRouter, { actions } from "@hooks/useMockRouter"; +import { setup } from "@lib/testUtils.test"; +import { ref, table } from "@lib/urls"; +import BranchAndTagSelector from "../BranchAndTagSelector"; +import * as mocks from "./mocks"; +import { + testRenderComponent, + testValueToSelect, + waitForVisibleValueToClick, +} from "./utils.test"; + +const jestRouter = jest.spyOn(require("next/router"), "useRouter"); + +jest.mock("next/router", () => { + return { + useRouter: () => { + return { route: "", pathname: "", query: "", asPath: "" }; + }, + }; +}); + +describe("test BranchAndTagSelector", () => { + mocks.branchAndTagTests.forEach(test => { + it(`renders for ${test.desc}`, async () => { + useMockRouter(jestRouter, {}); + + const { user } = setup( + + ref(p)} + selectedValue={test.value} + params={mocks.fakeRefParams} + /> + , + ); + + await testRenderComponent(test, user, "Tag", tagError, async v => { + const { href, as } = ref({ + ...mocks.fakeParams, + refName: v, + }); + expect(actions.push).toHaveBeenCalledWith(href, as); + }); + }); + }); + + it("handles table not existing on new branch", async () => { + useMockRouter(jestRouter, {}); + const refName = "main"; + const refToSelect = "test"; + const tableName = "testtable"; + const tableParams = { ...mocks.fakeParams, refName, tableName }; + + const { user } = setup( + + table({ ...p, tableName })} + selectedValue={refName} + params={tableParams} + /> + , + ); + + await waitForVisibleValueToClick(user, refName, "tag"); + + await testValueToSelect(refToSelect, user, async v => { + const { href, as } = ref({ + ...mocks.fakeParams, + refName: v, + }); + + expect(actions.push).toHaveBeenCalledWith(href, as); + }); + }); + + it("handles table existing on new branch", async () => { + useMockRouter(jestRouter, {}); + const refName = "main"; + const refToSelect = "test"; + const tableName = "testtable"; + const tableParams = { ...mocks.fakeParams, refName, tableName }; + + const { user } = setup( + + table({ ...p, tableName })} + selectedValue={refName} + params={tableParams} + /> + , + ); + + await waitForVisibleValueToClick(user, refName, "tag"); + + await testValueToSelect(refToSelect, user, async v => { + const { href, as } = table({ + ...mocks.fakeParams, + refName: v, + tableName, + }); + + expect(actions.push).toHaveBeenCalledWith(href, as); + }); + }); +}); diff --git a/web/components/FormSelectForRefs/tests/mocks.ts b/web/components/FormSelectForRefs/tests/mocks.ts new file mode 100644 index 00000000..9175d4ac --- /dev/null +++ b/web/components/FormSelectForRefs/tests/mocks.ts @@ -0,0 +1,211 @@ +import { MockedResponse } from "@apollo/client/testing"; +import { + generateFakeTag, + getTagsListQueryMock, + tagsListErrorMock, +} from "@components/pageComponents/DatabasePage/ForReleases/ReleaseList/mocks"; +import { + BranchForBranchSelectorFragment, + BranchesForSelectorDocument, + TableListForBranchDocument, +} from "@gen/graphql-types"; +import { + commitMock, + commitsListMock, + mockCommitError, +} from "@hooks/useCommitListForBranch/mocks"; +import chance from "@lib/chance"; +import { DatabaseParams, RefParams, TableParams } from "@lib/params"; +import { defaultBranchMock } from "@pageComponents/DatabasePage/ForDefaultBranch/mocks"; + +export const fakeParams = { databaseName: "dbname" }; +export const fakeBranchName = { name: "test-branch" }; +export const defaultBranchQuery = defaultBranchMock({ + ...fakeParams, + branchName: fakeBranchName.name, +}); +export const fakeRefParams = { ...fakeParams, refName: fakeBranchName.name }; +export const randomSelect = chance.name(); + +const testBranch = ( + params: DatabaseParams, +): BranchForBranchSelectorFragment => { + return { + __typename: "Branch", + ...params, + branchName: "test", + }; +}; + +export const mainBranch = ( + params: DatabaseParams, +): BranchForBranchSelectorFragment => { + return { + __typename: "Branch", + ...params, + branchName: "main", + }; +}; + +export const branchSelectorMock = ( + params: DatabaseParams, + empty = false, +): MockedResponse => { + return { + request: { + query: BranchesForSelectorDocument, + variables: params, + }, + result: { + data: { + allBranches: empty ? [] : [testBranch(params), mainBranch(params)], + }, + }, + }; +}; + +export const branchError = "branch error"; + +export const mockBranchError = (params: DatabaseParams): MockedResponse => { + return { + request: { + query: BranchesForSelectorDocument, + variables: params, + }, + error: new Error(branchError), + }; +}; + +const commit1 = commitMock(fakeParams); +const commit2 = commitMock(fakeParams); + +export const getBranchAndCommitMocks = ( + params: RefParams, + error = false, + empty = false, +): MockedResponse[] => { + if (error) { + return [mockBranchError(params), ...mockCommitError(params)]; + } + if (empty) { + return [branchSelectorMock(params, true), ...commitsListMock(params, [])]; + } + return [ + branchSelectorMock(params), + ...commitsListMock(params, [commit1, commit2]), + ]; +}; + +const tag1 = generateFakeTag({ ...fakeParams, tagName: "v1" }); +const tag2 = generateFakeTag({ ...fakeParams, tagName: "v2" }); + +export const getBranchAndTagMocks = ( + params: RefParams, + error = false, + empty = false, +): MockedResponse[] => { + if (error) { + return [mockBranchError(params), tagsListErrorMock(params)]; + } + if (empty) { + return [branchSelectorMock(params, true), getTagsListQueryMock(params, [])]; + } + return [ + branchSelectorMock(params), + getTagsListQueryMock(params, [tag1, tag2]), + ]; +}; + +export const tableListEmptyMock = (params: RefParams): MockedResponse => { + return { + request: { + query: TableListForBranchDocument, + variables: params, + }, + result: { + data: { + tables: [], + }, + }, + }; +}; + +const tableMock = (params: TableParams) => { + return { + __typename: "Table", + tableName: params.tableName, + _id: `databases/${params.databaseName}/refs/${params.refName}/tables/${params.tableName}`, + }; +}; + +export const tableListMock = (params: TableParams): MockedResponse => { + return { + request: { + query: TableListForBranchDocument, + variables: params, + }, + result: { + data: { + tables: [tableMock(params)], + }, + }, + }; +}; + +export type Test = { + desc: string; + value: string | undefined; + error: boolean; + empty: boolean; + valueToSelect?: string; +}; + +const commonTests: Test[] = [ + { + desc: "no options", + value: undefined, + error: false, + empty: true, + }, + { + desc: "errors", + value: undefined, + error: true, + empty: true, + }, + { + desc: "no selected value with options", + value: undefined, + empty: false, + error: false, + }, + { + desc: "selected branchName value", + value: "test", + empty: false, + error: false, + valueToSelect: "main", + }, +]; + +export const branchAndCommitTests: Test[] = [ + ...commonTests, + { + desc: "selected commitId value", + value: commit1.commitId, + empty: false, + error: false, + valueToSelect: commit2.commitId, + }, +]; + +export const branchAndTagTests: Test[] = [ + ...commonTests, + { + desc: "selected tagName value", + value: tag1.tagName, + empty: false, + error: false, + valueToSelect: tag2.tagName, + }, +]; diff --git a/web/components/FormSelectForRefs/tests/utils.test.ts b/web/components/FormSelectForRefs/tests/utils.test.ts new file mode 100644 index 00000000..1653b486 --- /dev/null +++ b/web/components/FormSelectForRefs/tests/utils.test.ts @@ -0,0 +1,95 @@ +import { pluralize } from "@dolthub/web-utils"; +import { screen, waitFor } from "@testing-library/react"; +import { UserEvent } from "@testing-library/user-event"; +import { Test, branchError } from "./mocks"; + +export async function testRenderComponent( + test: Test, + user: UserEvent, + label2: string, + error2: string, + testOnChange: (v: string) => Promise, +) { + const lowerLabel = label2.toLowerCase(); + const pluralLabel = pluralize(2, label2); + const lowerPluralLabel = pluralLabel.toLowerCase(); + + const selected = test.value; + if (!selected) { + const placeholder = screen.getByText(`select a branch or ${lowerLabel}...`); + expect(placeholder).toBeVisible(); + await user.click(placeholder); + + expect(screen.getByRole("button", { name: "Branches" })).toBeVisible(); + expect(screen.getByRole("button", { name: pluralLabel })).toBeVisible(); + + if (test.error) { + expect(screen.getByText(new RegExp(branchError))).toBeVisible(); + } else if (test.empty) { + expect(screen.getByText("No branches found")).toBeVisible(); + } else { + expect(screen.queryByText("No branches found")).not.toBeInTheDocument(); + } + + expect(screen.getByText("View all branches")).toBeVisible(); + + await user.click(screen.getByRole("button", { name: pluralLabel })); + + if (test.error) { + expect(screen.getByText(new RegExp(error2))).toBeVisible(); + } else if (test.empty) { + expect(screen.getByText(`No ${lowerPluralLabel} found`)).toBeVisible(); + } else { + expect( + screen.queryByText(`No ${lowerPluralLabel} found`), + ).not.toBeInTheDocument(); + } + + expect(screen.getByText(`View all ${lowerPluralLabel}`)).toBeVisible(); + + return; + } + + await waitForVisibleValueToClick(user, selected, lowerLabel); + + expect(screen.getByRole("button", { name: "Branches" })).toBeVisible(); + expect(screen.getByRole("button", { name: pluralLabel })).toBeVisible(); + + if (test.valueToSelect) { + await testValueToSelect(test.valueToSelect, user, testOnChange); + } +} + +export async function waitForVisibleValueToClick( + user: UserEvent, + selected: string, + lowerLabel: string, +) { + await waitFor(() => + expect( + screen.queryByText(`select a branch or ${lowerLabel}...`), + ).not.toBeInTheDocument(), + ); + + expect( + await screen.findByLabelText(`single-value-${selected}`), + ).toBeVisible(); + + await user.click(screen.getByText(selected)); +} + +export async function testValueToSelect( + v: string, + user: UserEvent, + testOnChange: (v: string) => Promise, +) { + expect(await screen.findByText(v)).toBeVisible(); + await user.click(screen.getByLabelText(`select-option-${v}`)); + + await waitFor(async () => testOnChange(v)); +} + +// Need to place the above functions in a .test.tsx file, so there needs to be at least one test in the file +describe("utils test", () => { + it("works", () => {}); +}); diff --git a/web/components/FormSelectForRefs/useGetBranchOptionsForSelect.ts b/web/components/FormSelectForRefs/useGetBranchOptionsForSelect.ts index 6f9e5cee..73b0782d 100644 --- a/web/components/FormSelectForRefs/useGetBranchOptionsForSelect.ts +++ b/web/components/FormSelectForRefs/useGetBranchOptionsForSelect.ts @@ -1,10 +1,12 @@ import { FormSelectTypes } from "@dolthub/react-components"; import { excerpt } from "@dolthub/web-utils"; import { useBranchesForSelectorQuery } from "@gen/graphql-types"; +import { ApolloErrorType } from "@lib/errors/types"; import { DatabaseParams } from "@lib/params"; type ReturnType = { branchOptions: Array>; + error?: ApolloErrorType; }; export default function useGetBranchOptionsForSelect( @@ -23,5 +25,5 @@ export default function useGetBranchOptionsForSelect( }; }) ?? []; - return { branchOptions }; + return { branchOptions, error: branchRes.error }; } diff --git a/web/components/FormSelectForRefs/useGetCommitOptionsForSelect.tsx b/web/components/FormSelectForRefs/useGetCommitOptionsForSelect.tsx index 5907b8e4..6e02aaf5 100644 --- a/web/components/FormSelectForRefs/useGetCommitOptionsForSelect.tsx +++ b/web/components/FormSelectForRefs/useGetCommitOptionsForSelect.tsx @@ -3,12 +3,14 @@ import { excerpt, getTimeAgoString } from "@dolthub/web-utils"; import { CommitForHistoryFragment } from "@gen/graphql-types"; import { useCommitListForBranch } from "@hooks/useCommitListForBranch"; import useDefaultBranch from "@hooks/useDefaultBranch"; +import { ApolloErrorType } from "@lib/errors/types"; import { OptionalRefParams, RefParams } from "@lib/params"; import css from "./index.module.css"; type ReturnType = { commitOptions: Array>; refParams: RefParams; + error?: ApolloErrorType; }; export default function useGetCommitOptionsForSelect( @@ -30,7 +32,7 @@ export default function useGetCommitOptionsForSelect( }; }) ?? []; - return { commitOptions, refParams }; + return { commitOptions, refParams, error: commitRes.error }; } function limitTwoLines(s: string, maxChars: number): string { diff --git a/web/components/FormSelectForRefs/useGetTagOptionsForSelect.ts b/web/components/FormSelectForRefs/useGetTagOptionsForSelect.ts index e735e5a8..762c2412 100644 --- a/web/components/FormSelectForRefs/useGetTagOptionsForSelect.ts +++ b/web/components/FormSelectForRefs/useGetTagOptionsForSelect.ts @@ -1,9 +1,11 @@ import { FormSelectTypes } from "@dolthub/react-components"; import { useTagListQuery } from "@gen/graphql-types"; +import { ApolloErrorType } from "@lib/errors/types"; import { DatabaseParams } from "@lib/params"; type ReturnType = { tagOptions: Array>; + error?: ApolloErrorType; }; export default function useGetTagOptionsForSelect( @@ -19,5 +21,5 @@ export default function useGetTagOptionsForSelect( }; }) ?? []; - return { tagOptions }; + return { tagOptions, error: tagRes.error }; } diff --git a/web/components/pageComponents/DatabasePage/ForBranches/NewBranchPage/NewBranchForm/mocks.ts b/web/components/pageComponents/DatabasePage/ForBranches/NewBranchPage/NewBranchForm/mocks.ts index 94378ad8..460aaab8 100644 --- a/web/components/pageComponents/DatabasePage/ForBranches/NewBranchPage/NewBranchForm/mocks.ts +++ b/web/components/pageComponents/DatabasePage/ForBranches/NewBranchPage/NewBranchForm/mocks.ts @@ -2,7 +2,7 @@ import { MockedResponse } from "@apollo/client/testing"; import { branchSelectorMock, mainBranch, -} from "@components/FormSelectForRefs/mocks"; +} from "@components/FormSelectForRefs/tests/mocks"; import { CreateBranchDocument } from "@gen/graphql-types"; import { loremer } from "@lib/loremer"; import { DatabaseParams } from "@lib/params"; diff --git a/web/components/pageComponents/DatabasePage/ForReleases/NewReleasePage/NewReleaseForm/mocks.ts b/web/components/pageComponents/DatabasePage/ForReleases/NewReleasePage/NewReleaseForm/mocks.ts index 9fb4a942..1a295181 100644 --- a/web/components/pageComponents/DatabasePage/ForReleases/NewReleasePage/NewReleaseForm/mocks.ts +++ b/web/components/pageComponents/DatabasePage/ForReleases/NewReleasePage/NewReleaseForm/mocks.ts @@ -2,9 +2,8 @@ import { MockedResponse } from "@apollo/client/testing"; import { branchSelectorMock, mainBranch, -} from "@components/FormSelectForRefs/mocks"; +} from "@components/FormSelectForRefs/tests/mocks"; import { CreateTagDocument } from "@gen/graphql-types"; -import { loremer } from "@lib/loremer"; import { defaultBranchMock } from "../../../ForDefaultBranch/mocks"; import { generateFakeTag } from "../../ReleaseList/mocks"; @@ -13,9 +12,9 @@ export const fromBranch = mainBranch(dbParams); export const fromRefName: string = fromBranch.branchName; export const tagParams = { ...dbParams, tagName: "v1" }; -export const message = loremer.sentence(); export const { tagName } = tagParams; -export const returnedTag = generateFakeTag(tagParams, message); +export const returnedTag = generateFakeTag(tagParams); +export const { message } = returnedTag; // QUERY MOCKS diff --git a/web/components/pageComponents/DatabasePage/ForReleases/ReleaseList/mocks.ts b/web/components/pageComponents/DatabasePage/ForReleases/ReleaseList/mocks.ts index 8d1e27bb..8f441fa1 100644 --- a/web/components/pageComponents/DatabasePage/ForReleases/ReleaseList/mocks.ts +++ b/web/components/pageComponents/DatabasePage/ForReleases/ReleaseList/mocks.ts @@ -10,8 +10,8 @@ import { DatabaseParams } from "@lib/params"; export function generateFakeTag( params: DatabaseParams & { tagName: string }, - message: string, ): TagForListFragment { + const message = chance.sentence(); const email = chance.email(); const doltWriter: DoltWriterForHistoryFragment = { __typename: "DoltWriter", @@ -54,25 +54,40 @@ export const databaseParams = { // RepoRole.Unspecified, // ); -const request = { - query: TagListDocument, - variables: databaseParams, +const getRequest = (params: DatabaseParams) => { + return { + query: TagListDocument, + variables: params, + }; }; -export const tag1 = generateFakeTag( - { ...databaseParams, tagName: "v1" }, - chance.sentence(), -); -export const tag2 = generateFakeTag( - { ...databaseParams, tagName: "v2" }, - chance.sentence(), +export const tag1 = generateFakeTag({ ...databaseParams, tagName: "v1" }); +export const tag2 = generateFakeTag({ ...databaseParams, tagName: "v2" }); + +export const getTagsListQueryMock = ( + params: DatabaseParams, + list: TagForListFragment[], +): MockedResponse => { + return { + request: getRequest(params), + result: { + data: buildFakeData(list), + }, + }; +}; + +export const tagsListQueryMock: MockedResponse = getTagsListQueryMock( + databaseParams, + [tag1, tag2], ); -export const tagsListQueryMock: MockedResponse = { - request, - result: { - data: buildFakeData([tag1, tag2]), - }, +export const tagError = "Tag Error"; + +export const tagsListErrorMock = (params: DatabaseParams): MockedResponse => { + return { + request: getRequest(params), + error: new Error(tagError), + }; }; // // MUTATION MOCKS diff --git a/web/hooks/useCommitListForBranch/mocks.ts b/web/hooks/useCommitListForBranch/mocks.ts new file mode 100644 index 00000000..02555835 --- /dev/null +++ b/web/hooks/useCommitListForBranch/mocks.ts @@ -0,0 +1,68 @@ +import { MockedResponse } from "@apollo/client/testing"; +import { + CommitForHistoryFragment, + HistoryForBranchDocument, +} from "@gen/graphql-types"; +import chance from "@lib/chance"; +import { DatabaseParams, RefParams } from "@lib/params"; + +const date = new Date(); + +export function fakeCommitId() { + return chance.hash().slice(0, 32); +} + +export const commitMock = ( + params: DatabaseParams, +): CommitForHistoryFragment => { + const commitId = fakeCommitId(); + return { + __typename: "Commit", + _id: `databases/${params.databaseName}/commits/${commitId}`, + commitId, + message: chance.sentence(), + committedAt: date.valueOf(), + committer: { + __typename: "DoltWriter", + _id: chance.email(), + displayName: chance.name(), + username: chance.word(), + emailAddress: chance.email(), + }, + parents: [], + }; +}; + +export const commitsListMock = ( + params: RefParams, + commits: CommitForHistoryFragment[], +): MockedResponse[] => [ + { + request: { + query: HistoryForBranchDocument, + variables: params, + }, + result: { + data: { + __typename: "Query", + commits: { + __typename: "CommitList", + nextPageToken: "", + list: commits, + }, + }, + }, + }, +]; + +export const commitError = "Commit Error"; + +export const mockCommitError = (params: RefParams): MockedResponse[] => [ + { + request: { + query: HistoryForBranchDocument, + variables: params, + }, + error: new Error(commitError), + }, +]; From 57e7cebef35fa3dcbc449176ec98fa153c2c265f Mon Sep 17 00:00:00 2001 From: Taylor Bantle Date: Mon, 18 Mar 2024 16:51:21 -0700 Subject: [PATCH 4/6] web: Use table names for selector --- .../BranchAndTagSelector.tsx | 10 ++--- web/components/FormSelectForRefs/queries.ts | 7 ++- .../FormSelectForRefs/tests/mocks.ts | 18 +++----- web/gen/graphql-types.tsx | 45 ++++++++++--------- 4 files changed, 37 insertions(+), 43 deletions(-) diff --git a/web/components/FormSelectForRefs/BranchAndTagSelector.tsx b/web/components/FormSelectForRefs/BranchAndTagSelector.tsx index b664a250..3b5ebefc 100644 --- a/web/components/FormSelectForRefs/BranchAndTagSelector.tsx +++ b/web/components/FormSelectForRefs/BranchAndTagSelector.tsx @@ -1,6 +1,6 @@ import { FormSelect } from "@dolthub/react-components"; import { Maybe } from "@dolthub/web-utils"; -import { useTableListForBranchLazyQuery } from "@gen/graphql-types"; +import { useTableNamesForBranchLazyQuery } from "@gen/graphql-types"; import { DatabasePageParams } from "@lib/params"; import { RefUrl, branches, ref, releases } from "@lib/urls"; import { useRouter } from "next/router"; @@ -19,7 +19,7 @@ type Props = { export default function BranchAndTagSelector(props: Props) { const router = useRouter(); - const [getTableList] = useTableListForBranchLazyQuery(); + const [getTableNames] = useTableNamesForBranchLazyQuery(); const { tagOptions, error: tagErr } = useGetTagOptionsForSelect(props.params); const { branchOptions, error: branchErr } = useGetBranchOptionsForSelect( @@ -36,9 +36,9 @@ export default function BranchAndTagSelector(props: Props) { // If on a table page, check if the table exists on the new branch. If not, // route to ref. if (props.params.tableName) { - const tableRes = await getTableList({ variables }); - const tableExists = tableRes.data?.tables.some( - v => v.tableName === props.params.tableName, + const tableRes = await getTableNames({ variables }); + const tableExists = tableRes.data?.tableNames.list.some( + t => t === props.params.tableName, ); if (!tableExists) { const { href, as } = ref({ ...props.params, refName }); diff --git a/web/components/FormSelectForRefs/queries.ts b/web/components/FormSelectForRefs/queries.ts index f76bdd49..9fa87798 100644 --- a/web/components/FormSelectForRefs/queries.ts +++ b/web/components/FormSelectForRefs/queries.ts @@ -36,14 +36,13 @@ export const TAG_LIST_QUERY = gql` `; export const TABLE_LIST_FOR_BRANCH_QUERY = gql` - query TableListForBranch($databaseName: String!, $refName: String!) { - tables( + query TableNamesForBranch($databaseName: String!, $refName: String!) { + tableNames( databaseName: $databaseName refName: $refName filterSystemTables: true ) { - _id - tableName + list } } `; diff --git a/web/components/FormSelectForRefs/tests/mocks.ts b/web/components/FormSelectForRefs/tests/mocks.ts index 9175d4ac..e7632018 100644 --- a/web/components/FormSelectForRefs/tests/mocks.ts +++ b/web/components/FormSelectForRefs/tests/mocks.ts @@ -7,7 +7,7 @@ import { import { BranchForBranchSelectorFragment, BranchesForSelectorDocument, - TableListForBranchDocument, + TableNamesForBranchDocument, } from "@gen/graphql-types"; import { commitMock, @@ -119,34 +119,26 @@ export const getBranchAndTagMocks = ( export const tableListEmptyMock = (params: RefParams): MockedResponse => { return { request: { - query: TableListForBranchDocument, + query: TableNamesForBranchDocument, variables: params, }, result: { data: { - tables: [], + tableNames: { list: [] }, }, }, }; }; -const tableMock = (params: TableParams) => { - return { - __typename: "Table", - tableName: params.tableName, - _id: `databases/${params.databaseName}/refs/${params.refName}/tables/${params.tableName}`, - }; -}; - export const tableListMock = (params: TableParams): MockedResponse => { return { request: { - query: TableListForBranchDocument, + query: TableNamesForBranchDocument, variables: params, }, result: { data: { - tables: [tableMock(params)], + tableNames: { list: [params.tableName] }, }, }, }; diff --git a/web/gen/graphql-types.tsx b/web/gen/graphql-types.tsx index c1f0d381..81167822 100644 --- a/web/gen/graphql-types.tsx +++ b/web/gen/graphql-types.tsx @@ -816,13 +816,13 @@ export type TagListQueryVariables = Exact<{ export type TagListQuery = { __typename?: 'Query', tags: { __typename?: 'TagList', list: Array<{ __typename?: 'Tag', _id: string, tagName: string, message: string, taggedAt: any, commitId: string, tagger: { __typename?: 'DoltWriter', _id: string, username?: string | null, displayName: string, emailAddress: string } }> } }; -export type TableListForBranchQueryVariables = Exact<{ +export type TableNamesForBranchQueryVariables = Exact<{ databaseName: Scalars['String']['input']; refName: Scalars['String']['input']; }>; -export type TableListForBranchQuery = { __typename?: 'Query', tables: Array<{ __typename?: 'Table', _id: string, tableName: string }> }; +export type TableNamesForBranchQuery = { __typename?: 'Query', tableNames: { __typename?: 'TableNames', list: Array } }; export type ColumnsListForTableListFragment = { __typename?: 'IndexColumn', name: string, sqlType?: string | null }; @@ -2124,48 +2124,51 @@ export type TagListQueryHookResult = ReturnType; export type TagListLazyQueryHookResult = ReturnType; export type TagListSuspenseQueryHookResult = ReturnType; export type TagListQueryResult = Apollo.QueryResult; -export const TableListForBranchDocument = gql` - query TableListForBranch($databaseName: String!, $refName: String!) { - tables(databaseName: $databaseName, refName: $refName, filterSystemTables: true) { - _id - tableName +export const TableNamesForBranchDocument = gql` + query TableNamesForBranch($databaseName: String!, $refName: String!) { + tableNames( + databaseName: $databaseName + refName: $refName + filterSystemTables: true + ) { + list } } `; /** - * __useTableListForBranchQuery__ + * __useTableNamesForBranchQuery__ * - * To run a query within a React component, call `useTableListForBranchQuery` and pass it any options that fit your needs. - * When your component renders, `useTableListForBranchQuery` returns an object from Apollo Client that contains loading, error, and data properties + * To run a query within a React component, call `useTableNamesForBranchQuery` and pass it any options that fit your needs. + * When your component renders, `useTableNamesForBranchQuery` returns an object from Apollo Client that contains loading, error, and data properties * you can use to render your UI. * * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; * * @example - * const { data, loading, error } = useTableListForBranchQuery({ + * const { data, loading, error } = useTableNamesForBranchQuery({ * variables: { * databaseName: // value for 'databaseName' * refName: // value for 'refName' * }, * }); */ -export function useTableListForBranchQuery(baseOptions: Apollo.QueryHookOptions & ({ variables: TableListForBranchQueryVariables; skip?: boolean; } | { skip: boolean; }) ) { +export function useTableNamesForBranchQuery(baseOptions: Apollo.QueryHookOptions & ({ variables: TableNamesForBranchQueryVariables; skip?: boolean; } | { skip: boolean; }) ) { const options = {...defaultOptions, ...baseOptions} - return Apollo.useQuery(TableListForBranchDocument, options); + return Apollo.useQuery(TableNamesForBranchDocument, options); } -export function useTableListForBranchLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { +export function useTableNamesForBranchLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { const options = {...defaultOptions, ...baseOptions} - return Apollo.useLazyQuery(TableListForBranchDocument, options); + return Apollo.useLazyQuery(TableNamesForBranchDocument, options); } -export function useTableListForBranchSuspenseQuery(baseOptions?: Apollo.SuspenseQueryHookOptions) { +export function useTableNamesForBranchSuspenseQuery(baseOptions?: Apollo.SuspenseQueryHookOptions) { const options = {...defaultOptions, ...baseOptions} - return Apollo.useSuspenseQuery(TableListForBranchDocument, options); + return Apollo.useSuspenseQuery(TableNamesForBranchDocument, options); } -export type TableListForBranchQueryHookResult = ReturnType; -export type TableListForBranchLazyQueryHookResult = ReturnType; -export type TableListForBranchSuspenseQueryHookResult = ReturnType; -export type TableListForBranchQueryResult = Apollo.QueryResult; +export type TableNamesForBranchQueryHookResult = ReturnType; +export type TableNamesForBranchLazyQueryHookResult = ReturnType; +export type TableNamesForBranchSuspenseQueryHookResult = ReturnType; +export type TableNamesForBranchQueryResult = Apollo.QueryResult; export const TableListForSchemasDocument = gql` query TableListForSchemas($databaseName: String!, $refName: String!) { tables(databaseName: $databaseName, refName: $refName, filterSystemTables: true) { From 21a82933109e23eda34958adaf73bf09520f9047 Mon Sep 17 00:00:00 2001 From: Taylor Bantle Date: Tue, 19 Mar 2024 09:38:19 -0700 Subject: [PATCH 5/6] web: Add loading state --- .../FormSelectForRefs/BranchAndCommitSelector.tsx | 10 +++++++--- .../FormSelectForRefs/BranchAndTagSelector.tsx | 15 +++++++++++---- .../useGetBranchOptionsForSelect.ts | 3 ++- .../useGetCommitOptionsForSelect.tsx | 8 +++++++- .../useGetTagOptionsForSelect.ts | 3 ++- 5 files changed, 29 insertions(+), 10 deletions(-) diff --git a/web/components/FormSelectForRefs/BranchAndCommitSelector.tsx b/web/components/FormSelectForRefs/BranchAndCommitSelector.tsx index edebb06b..a3bbe54c 100644 --- a/web/components/FormSelectForRefs/BranchAndCommitSelector.tsx +++ b/web/components/FormSelectForRefs/BranchAndCommitSelector.tsx @@ -14,13 +14,16 @@ type Props = { }; export default function BranchAndCommitSelector(props: Props) { - const { branchOptions, error: branchErr } = useGetBranchOptionsForSelect( - props.params, - ); + const { + branchOptions, + error: branchErr, + loading: branchLoading, + } = useGetBranchOptionsForSelect(props.params); const { commitOptions, refParams, error: commitErr, + loading: commitLoading, } = useGetCommitOptionsForSelect(props.params); const handleChangeRef = async (refName: Maybe) => { @@ -35,6 +38,7 @@ export default function BranchAndCommitSelector(props: Props) { return ( t.value === props.selectedValue, )} diff --git a/web/components/FormSelectForRefs/BranchAndTagSelector.tsx b/web/components/FormSelectForRefs/BranchAndTagSelector.tsx index 3b5ebefc..a6660611 100644 --- a/web/components/FormSelectForRefs/BranchAndTagSelector.tsx +++ b/web/components/FormSelectForRefs/BranchAndTagSelector.tsx @@ -21,10 +21,16 @@ export default function BranchAndTagSelector(props: Props) { const [getTableNames] = useTableNamesForBranchLazyQuery(); - const { tagOptions, error: tagErr } = useGetTagOptionsForSelect(props.params); - const { branchOptions, error: branchErr } = useGetBranchOptionsForSelect( - props.params, - ); + const { + tagOptions, + error: tagErr, + loading: tagLoading, + } = useGetTagOptionsForSelect(props.params); + const { + branchOptions, + error: branchErr, + loading: branchLoading, + } = useGetBranchOptionsForSelect(props.params); const handleChangeRef = async (refName: Maybe) => { if (!refName) return; @@ -67,6 +73,7 @@ export default function BranchAndTagSelector(props: Props) { return ( t.value === props.selectedValue, diff --git a/web/components/FormSelectForRefs/useGetBranchOptionsForSelect.ts b/web/components/FormSelectForRefs/useGetBranchOptionsForSelect.ts index 73b0782d..559cb337 100644 --- a/web/components/FormSelectForRefs/useGetBranchOptionsForSelect.ts +++ b/web/components/FormSelectForRefs/useGetBranchOptionsForSelect.ts @@ -7,6 +7,7 @@ import { DatabaseParams } from "@lib/params"; type ReturnType = { branchOptions: Array>; error?: ApolloErrorType; + loading: boolean; }; export default function useGetBranchOptionsForSelect( @@ -25,5 +26,5 @@ export default function useGetBranchOptionsForSelect( }; }) ?? []; - return { branchOptions, error: branchRes.error }; + return { branchOptions, error: branchRes.error, loading: branchRes.loading }; } diff --git a/web/components/FormSelectForRefs/useGetCommitOptionsForSelect.tsx b/web/components/FormSelectForRefs/useGetCommitOptionsForSelect.tsx index 6e02aaf5..305e190a 100644 --- a/web/components/FormSelectForRefs/useGetCommitOptionsForSelect.tsx +++ b/web/components/FormSelectForRefs/useGetCommitOptionsForSelect.tsx @@ -11,6 +11,7 @@ type ReturnType = { commitOptions: Array>; refParams: RefParams; error?: ApolloErrorType; + loading: boolean; }; export default function useGetCommitOptionsForSelect( @@ -32,7 +33,12 @@ export default function useGetCommitOptionsForSelect( }; }) ?? []; - return { commitOptions, refParams, error: commitRes.error }; + return { + commitOptions, + refParams, + error: commitRes.error, + loading: commitRes.loading, + }; } function limitTwoLines(s: string, maxChars: number): string { diff --git a/web/components/FormSelectForRefs/useGetTagOptionsForSelect.ts b/web/components/FormSelectForRefs/useGetTagOptionsForSelect.ts index 762c2412..8011940f 100644 --- a/web/components/FormSelectForRefs/useGetTagOptionsForSelect.ts +++ b/web/components/FormSelectForRefs/useGetTagOptionsForSelect.ts @@ -6,6 +6,7 @@ import { DatabaseParams } from "@lib/params"; type ReturnType = { tagOptions: Array>; error?: ApolloErrorType; + loading: boolean; }; export default function useGetTagOptionsForSelect( @@ -21,5 +22,5 @@ export default function useGetTagOptionsForSelect( }; }) ?? []; - return { tagOptions, error: tagRes.error }; + return { tagOptions, error: tagRes.error, loading: tagRes.loading }; } From 8d42de7aa4c4c46b4ff8673874b9925ea98fa524 Mon Sep 17 00:00:00 2001 From: Taylor Bantle Date: Tue, 19 Mar 2024 09:50:56 -0700 Subject: [PATCH 6/6] web: Up RC --- web/package.json | 2 +- web/yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/web/package.json b/web/package.json index 879c602d..cd93a28a 100644 --- a/web/package.json +++ b/web/package.json @@ -26,7 +26,7 @@ }, "dependencies": { "@apollo/client": "^3.7.0", - "@dolthub/react-components": "^0.1.9", + "@dolthub/react-components": "^0.1.10", "@dolthub/react-contexts": "^0.1.0", "@dolthub/react-hooks": "^0.1.6", "@dolthub/web-utils": "^0.1.2", diff --git a/web/yarn.lock b/web/yarn.lock index 747b4cfd..308e5f39 100644 --- a/web/yarn.lock +++ b/web/yarn.lock @@ -1353,7 +1353,7 @@ __metadata: resolution: "@dolt-sql-workbench/web@workspace:." dependencies: "@apollo/client": "npm:^3.7.0" - "@dolthub/react-components": "npm:^0.1.9" + "@dolthub/react-components": "npm:^0.1.10" "@dolthub/react-contexts": "npm:^0.1.0" "@dolthub/react-hooks": "npm:^0.1.6" "@dolthub/web-utils": "npm:^0.1.2" @@ -1438,9 +1438,9 @@ __metadata: languageName: unknown linkType: soft -"@dolthub/react-components@npm:^0.1.9": - version: 0.1.9 - resolution: "@dolthub/react-components@npm:0.1.9" +"@dolthub/react-components@npm:^0.1.10": + version: 0.1.10 + resolution: "@dolthub/react-components@npm:0.1.10" dependencies: "@dolthub/react-hooks": "npm:^0.1.7" "@dolthub/web-utils": "npm:^0.1.3" @@ -1458,7 +1458,7 @@ __metadata: peerDependencies: react: ^18 react-dom: ^18 - checksum: 2b734b91e689c8d84f709bbe9d2697f6360d2bbb09897ccc95cb279590f7a26ce4514e273184f46510ef58ac381dc80451bd17e17113f31396065d39efe240e4 + checksum: e1ba35a01b1d8f6bb7af3a2e1f8863f8708411b20ec3e99921f1c06c55200afe3b3822989df3d4df01af7ac4c21812787ff78e437efe1ad7b20cfe562d1c5727 languageName: node linkType: hard