diff --git a/tavern/internal/www/package-lock.json b/tavern/internal/www/package-lock.json index e3e148991..be425f0ed 100644 --- a/tavern/internal/www/package-lock.json +++ b/tavern/internal/www/package-lock.json @@ -41,6 +41,7 @@ "react-virtualized": "^9.22.4", "recharts": "^2.11.0", "sort-by": "^1.2.0", + "tailwind-variants": "^0.2.1", "typescript": "^4.9.5", "web-vitals": "^2.1.4", "xterm-addon-attach": "^0.9.0", @@ -1975,16 +1976,21 @@ "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" }, "node_modules/@babel/runtime": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.6.tgz", - "integrity": "sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==", + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.0.tgz", + "integrity": "sha512-Chk32uHMg6TnQdvw2e9IlqPpFX/6NLuK0Ys2PqLb7/gL5uFn9mXvK715FGLlOLQrcO4qIkNHkvPGktzzXexsFw==", "dependencies": { - "regenerator-runtime": "^0.13.11" + "regenerator-runtime": "^0.14.0" }, "engines": { "node": ">=6.9.0" } }, + "node_modules/@babel/runtime/node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, "node_modules/@babel/template": { "version": "7.22.15", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", @@ -18516,6 +18522,33 @@ "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" }, + "node_modules/tailwind-merge": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.2.1.tgz", + "integrity": "sha512-o+2GTLkthfa5YUt4JxPfzMIpQzZ3adD1vLVkvKE1Twl9UAhGsEbIZhHHZVRttyW177S8PDJI3bTQNaebyofK3Q==", + "dependencies": { + "@babel/runtime": "^7.23.7" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, + "node_modules/tailwind-variants": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tailwind-variants/-/tailwind-variants-0.2.1.tgz", + "integrity": "sha512-2xmhAf4UIc3PijOUcJPA1LP4AbxhpcHuHM2C26xM0k81r0maAO6uoUSHl3APmvHZcY5cZCY/bYuJdfFa4eGoaw==", + "dependencies": { + "tailwind-merge": "^2.2.0" + }, + "engines": { + "node": ">=16.x", + "pnpm": ">=7.x" + }, + "peerDependencies": { + "tailwindcss": "*" + } + }, "node_modules/tailwindcss": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.2.7.tgz", diff --git a/tavern/internal/www/package.json b/tavern/internal/www/package.json index 6ceb2f297..ec6f41a36 100644 --- a/tavern/internal/www/package.json +++ b/tavern/internal/www/package.json @@ -36,6 +36,7 @@ "react-virtualized": "^9.22.4", "recharts": "^2.11.0", "sort-by": "^1.2.0", + "tailwind-variants": "^0.2.1", "typescript": "^4.9.5", "web-vitals": "^2.1.4", "xterm-addon-attach": "^0.9.0", diff --git a/tavern/internal/www/src/components/empty-states/EmptyStateNoBeacon.tsx b/tavern/internal/www/src/components/empty-states/EmptyStateNoBeacon.tsx index 0cd2275f4..ad22e3a3d 100644 --- a/tavern/internal/www/src/components/empty-states/EmptyStateNoBeacon.tsx +++ b/tavern/internal/www/src/components/empty-states/EmptyStateNoBeacon.tsx @@ -1,15 +1,15 @@ import { EmptyState, EmptyStateType } from "../tavern-base-ui/EmptyState"; +import Button from "../tavern-base-ui/button/Button"; const EmptyStateNoBeacon = () => { return ( - window.open("https://docs.realm.pub/user-guide/getting-started#start-the-agent", '_blank')} > See imix docs - + ); } diff --git a/tavern/internal/www/src/components/empty-states/EmptyStateNoQuests.tsx b/tavern/internal/www/src/components/empty-states/EmptyStateNoQuests.tsx index ec1817dc4..20e9f96aa 100644 --- a/tavern/internal/www/src/components/empty-states/EmptyStateNoQuests.tsx +++ b/tavern/internal/www/src/components/empty-states/EmptyStateNoQuests.tsx @@ -1,16 +1,16 @@ import { Link } from "react-router-dom"; import { EmptyState, EmptyStateType } from "../tavern-base-ui/EmptyState"; +import Button from "../tavern-base-ui/button/Button"; const EmptyStateNoQuests = () => { return ( - Create new quest - + ) diff --git a/tavern/internal/www/src/components/tavern-base-ui/Modal.tsx b/tavern/internal/www/src/components/tavern-base-ui/Modal.tsx index 6608eccca..3c62ff74b 100644 --- a/tavern/internal/www/src/components/tavern-base-ui/Modal.tsx +++ b/tavern/internal/www/src/components/tavern-base-ui/Modal.tsx @@ -1,6 +1,7 @@ import { XMarkIcon } from "@heroicons/react/24/outline"; import React, { FC, Fragment } from "react"; import { Dialog, Transition } from '@headlessui/react'; +import Button from "./button/Button"; type ModalProps = { isOpen: boolean, @@ -31,15 +32,15 @@ const Modal: FC = ({ isOpen, setOpen, children }) => { - setOpen(false)} + leftIcon={} > - Close panel - - + diff --git a/tavern/internal/www/src/components/tavern-base-ui/TablePagination.tsx b/tavern/internal/www/src/components/tavern-base-ui/TablePagination.tsx index a99762b0a..2e2248967 100644 --- a/tavern/internal/www/src/components/tavern-base-ui/TablePagination.tsx +++ b/tavern/internal/www/src/components/tavern-base-ui/TablePagination.tsx @@ -1,62 +1,66 @@ +import Button from "./button/Button"; + type PageInfo = { - hasNextPage: boolean, - hasPreviousPage: boolean, - startCursor: string, - endCursor: string + hasNextPage: boolean, + hasPreviousPage: boolean, + startCursor: string, + endCursor: string } type Props = { - totalCount: number; - pageInfo: PageInfo; - refetchTable: (endCursor: string | undefined, startCursor: string | undefined) => void; - page: number; - setPage: any; - rowLimit: number; + totalCount: number; + pageInfo: PageInfo; + refetchTable: (endCursor: string | undefined, startCursor: string | undefined) => void; + page: number; + setPage: any; + rowLimit: number; } export default function TablePagination(props: Props) { - const {totalCount, pageInfo, refetchTable, page, setPage, rowLimit} = props; + const { totalCount, pageInfo, refetchTable, page, setPage, rowLimit } = props; - function handlePreviousClick(){ - if(refetchTable && pageInfo.hasPreviousPage){ - setPage((page:number)=> page-1); - refetchTable(undefined, pageInfo.startCursor); - } - } - function handleNextClick(){ - if(refetchTable && pageInfo.hasNextPage){ - setPage((page:number)=> page+1); - refetchTable( pageInfo.endCursor, undefined); - } + function handlePreviousClick() { + if (refetchTable && pageInfo.hasPreviousPage) { + setPage((page: number) => page - 1); + refetchTable(undefined, pageInfo.startCursor); } - const getPageCount = () => { - return Math.ceil(totalCount / rowLimit); + } + function handleNextClick() { + if (refetchTable && pageInfo.hasNextPage) { + setPage((page: number) => page + 1); + refetchTable(pageInfo.endCursor, undefined); } + } + const getPageCount = () => { + return Math.ceil(totalCount / rowLimit); + } - return ( - - - - Page {page} of {getPageCount()} {`(${totalCount} results)`} - - - - handlePreviousClick()} - className="relative inline-flex items-center rounded-md bg-white px-3 py-2 text-sm font-semibold text-gray-900 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus-visible:outline-offset-0 disabled:opacity-50 disabled:cursor-not-allowed" - > - Previous - - handleNextClick()} - className="relative ml-3 inline-flex items-center rounded-md bg-white px-3 py-2 text-sm font-semibold text-gray-900 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus-visible:outline-offset-0 disabled:opacity-50 disabled:cursor-not-allowed" - > - Next - - - - ) -}; \ No newline at end of file + return ( + + + + Page {page} of {getPageCount()} {`(${totalCount} results)`} + + + + handlePreviousClick()} + > + Previous + + handleNextClick()} + > + Next + + + + ) +}; diff --git a/tavern/internal/www/src/components/tavern-base-ui/button/Button.tsx b/tavern/internal/www/src/components/tavern-base-ui/button/Button.tsx new file mode 100644 index 000000000..ecd38b18b --- /dev/null +++ b/tavern/internal/www/src/components/tavern-base-ui/button/Button.tsx @@ -0,0 +1,91 @@ +/* eslint-disable react/jsx-props-no-spreading */ +import { forwardRef, useMemo } from "react"; +import { outlineButton, solidButton, ghostButton } from "./ButtonStyles"; +import { VariantProps } from "tailwind-variants"; +import { Ring } from "@uiball/loaders"; + +// define all the button attributes +type BaseButtonAttributes = React.ComponentPropsWithoutRef<"button">; + +// define the ref type +type Ref = HTMLButtonElement; + +// extend the base button attributes +interface ButtonProps extends BaseButtonAttributes { + isLoading?: boolean; + disabled?: boolean; + leftIcon?: React.ReactElement; + rightIcon?: React.ReactElement; + buttonStyle?: VariantProps; + className?: string, + buttonVariant?: "solid" | "outline" | "ghost"; +} + +const Button = forwardRef((props, ref) => { + // destructure neccesary props + const { type, children, buttonStyle, buttonVariant, disabled, isLoading, leftIcon, rightIcon, className, ...rest } = props; + + // determine icon placement + const { newIcon: icon, iconPlacement } = useMemo(() => { + let newIcon = rightIcon || leftIcon; + + if (isLoading) { + newIcon = ; + } + + return { + newIcon, + iconPlacement: rightIcon ? ("right" as const) : ("left" as const), + }; + }, [isLoading, leftIcon, rightIcon]); + + const renderButtonVariant = () => { + if (buttonVariant === "solid") { + return solidButton({ ...buttonStyle, className }) + } + if (buttonVariant === "outline") { + return outlineButton({ ...buttonStyle, className }) + } + return ghostButton({ ...buttonStyle, className }) + } + + return ( + + {/** render icon before */} + {icon && iconPlacement === "left" ? ( + {icon} + ) : null} + + {/** hide button text during loading state */} + {!isLoading && children} + + {/** render icon after */} + {icon && iconPlacement === "right" ? ( + {icon} + ) : null} + + ); +}); + +// set default props +Button.defaultProps = { + buttonStyle: { color: "purple", size: "md" }, + buttonVariant: "solid", + isLoading: false, + disabled: false, + leftIcon: undefined, + rightIcon: undefined, +}; + +export default Button; diff --git a/tavern/internal/www/src/components/tavern-base-ui/button/ButtonStyles.ts b/tavern/internal/www/src/components/tavern-base-ui/button/ButtonStyles.ts new file mode 100644 index 000000000..5764d23d1 --- /dev/null +++ b/tavern/internal/www/src/components/tavern-base-ui/button/ButtonStyles.ts @@ -0,0 +1,98 @@ +import { tv } from 'tailwind-variants'; + +export const baseButton = tv({ + base: 'text-center relative font-semibold whitespace-nowrap align-middle outline-none inline-flex items-center justify-center select-none rounded-md shadow-sm disabled:opacity-50 disabled:cursor-not-allowed', + variants: { + size: { + xs: 'text-xs py-1 px-2', + md: 'text-sm py-2 px-4', + lg: 'text-base py-3 px-6', + xl: 'text-lg py-4 px-8', + xxl: 'text-xl py-5 px-10', + square_xs: 'text-xs h-4 w-4 p-1', + square_sm: 'text-sm h-6 w-6 p-1', + square_md: 'text-base h-8 w-8 p-1', + square_lg: 'text-lg h-10 w-10 p-1', + square_xl: 'text-xl h-12 w-12 p-1', + }, + xPadding:{ + none: 'px-[0px]', + xs: 'px-[4px]', + sm: 'px-[8px]', + md: 'px-[12px]', + lg: 'px-[16px]', + }, + vPadding: { + none: 'py-[0px]', + xs: 'py-[4px]', + sm: 'py-[8px]', + md: 'py-[12px]', + lg: 'py-[16px]', + }, + vSpace: { + xs: 'my-1', + sm: 'my-2', + md: 'my-4', + lg: 'my-6', + }, + HSpace: { + xs: 'mx-1', + sm: 'mx-2', + md: 'mx-4', + lg: 'mx-6', + }, + align: { + center: 'mx-auto', + right: 'ml-auto', + left: 'mr-auto', + top: 'mb-auto', + bottom: 'mt-auto', + }, + rounded: { + none: 'rounded-none', + xs: 'rounded-[2px]', + sm: 'rounded-[4px]', + normal: 'rounded-[8px]', + lg: 'rounded-[12px]', + full: 'rounded-full', + }, + behavior: { + block: 'w-full', + }, + }, +}); + +// create solid button styles +export const solidButton = tv({ + extend: baseButton, + variants: { + color: { + purple: + 'btn-primary', + gray: 'bg-gray-100 text-gray-900 hover:bg-gray-200', + }, + }, +}); + +//create outline button styles +export const outlineButton = tv({ + extend: baseButton, + base: 'ring-1', + variants: { + color: { + purple: 'text-purple-800 ring-purple-800', + gray: 'text-gray-900 ring-gray-500', + }, + }, +}); + +//create ghost button styles +export const ghostButton = tv({ + extend: baseButton, + variants: { + color: { + purple: 'text-purple-800 hover:bg-purple-100', + gray: 'text-gray-900 hover:bg-gray-100', + }, + }, +}); diff --git a/tavern/internal/www/src/features/create-quest-dropdown/CreateQuestDropdown.tsx b/tavern/internal/www/src/features/create-quest-dropdown/CreateQuestDropdown.tsx index 92a164b93..696d30398 100644 --- a/tavern/internal/www/src/features/create-quest-dropdown/CreateQuestDropdown.tsx +++ b/tavern/internal/www/src/features/create-quest-dropdown/CreateQuestDropdown.tsx @@ -1,10 +1,10 @@ import { Menu, Transition } from '@headlessui/react' import { Fragment } from 'react' import { ChevronDownIcon } from '@heroicons/react/20/solid' -import { Button } from '@chakra-ui/react' import { EllipsisHorizontalIcon } from '@heroicons/react/24/outline' import { Tome } from '../../utils/consts' import { LimitedTaskNode, useCreateQuest } from './useCreateQuest' +import Button from '../../components/tavern-base-ui/button/Button' export const CreateQuestDropdown = ({ @@ -32,17 +32,21 @@ export const CreateQuestDropdown = ({ {showLabel ? - }> + } + > Re-run quest : - } /> + } /> } @@ -58,25 +62,27 @@ export const CreateQuestDropdown = ({ - {({ active }) => ( - ( + handleCreateQuestWithSameTome(name, originalParms, tome, tasks)} - className={`${active ? 'bg-purple-700 text-white' : 'text-gray-900' - } group flex w-full items-center rounded-md px-2 py-2 text-sm`} > Re-run with online beacons - + )} - {({ active }) => ( - ( + handleCreateQuestWithNewTome(name, tasks)} - className={`${active ? 'bg-purple-700 text-white' : 'text-gray-900' - } group flex w-full items-center rounded-md px-2 py-2 text-sm`} + className="w-full" > Re-run with new tome - + )} diff --git a/tavern/internal/www/src/features/task-output/TaskOutput.tsx b/tavern/internal/www/src/features/task-output/TaskOutput.tsx index 303033f55..4d190e779 100644 --- a/tavern/internal/www/src/features/task-output/TaskOutput.tsx +++ b/tavern/internal/www/src/features/task-output/TaskOutput.tsx @@ -2,12 +2,13 @@ import React, { useCallback } from "react"; import TaskStatusBadge from "../../components/TaskStatusBadge"; import BeaconTile from "../../components/BeaconTile"; import TomeAccordion from "../../components/TomeAccordion"; -import { Button, Image } from "@chakra-ui/react"; +import { Image } from "@chakra-ui/react"; import OutputWrapper from "./OutputWrapper"; import ErrorWrapper from "./ErrorWrapper"; import { useNavigate } from "react-router-dom"; import { checkIfBeaconOffline, constructTomeParams } from "../../utils/utils"; import Modal from "../../components/tavern-base-ui/Modal"; +import Button from "../../components/tavern-base-ui/button/Button"; type Props = { isOpen: boolean, @@ -52,7 +53,9 @@ export const TaskOutput = (props: Props) => { {!beaconOffline && - hanldeRerunQuest()} disabled={beaconOffline} title="Beacon must be online to rerun" diff --git a/tavern/internal/www/src/pages/create-quest/components/BeaconStep.tsx b/tavern/internal/www/src/pages/create-quest/components/BeaconStep.tsx index cfefddfcc..cc0a807ff 100644 --- a/tavern/internal/www/src/pages/create-quest/components/BeaconStep.tsx +++ b/tavern/internal/www/src/pages/create-quest/components/BeaconStep.tsx @@ -1,4 +1,4 @@ -import { Heading, Text, Stack, StackItem, Box, Button, FormLabel, Switch } from "@chakra-ui/react"; +import { Heading, Text, Stack, StackItem, Box, FormLabel, Switch } from "@chakra-ui/react"; import { TrashIcon, PlusIcon } from "@heroicons/react/24/outline"; import React, { FC, useCallback } from "react"; import { @@ -13,6 +13,7 @@ import { BeaconFilterBar } from "../../../components/beacon-filter-bar"; import BeaconOption from "../../../components/beacon-option/BeaconOption"; import { BeaconType, HostType, TomeTag } from "../../../utils/consts"; import { useBeaconFilter } from "../hooks/useBeaconFilter"; +import Button from "../../../components/tavern-base-ui/button/Button"; const Grid = _Grid as unknown as FC; const AutoSizer = _AutoSizer as unknown as FC; @@ -119,12 +120,21 @@ const BeaconStep = (props: Props) => { - - } size={"sm"} onClick={() => handleCheckAllFiltered()}>Select all ({filteredBeacons.length}) - - - } size={"sm"} onClick={() => handleUnCheckAllFiltered()}>Clear selected - + + + } + onClick={() => handleCheckAllFiltered()}>Select all ({filteredBeacons.length}) + + + + } + onClick={() => handleUnCheckAllFiltered()}>Clear selected + + {filteredBeacons.length === 0 && ( diff --git a/tavern/internal/www/src/pages/create-quest/components/BeaconStepWrapper.tsx b/tavern/internal/www/src/pages/create-quest/components/BeaconStepWrapper.tsx index 1d7464a26..ff214c786 100644 --- a/tavern/internal/www/src/pages/create-quest/components/BeaconStepWrapper.tsx +++ b/tavern/internal/www/src/pages/create-quest/components/BeaconStepWrapper.tsx @@ -4,6 +4,7 @@ import { TagContext } from "../../../context/TagContext"; import { SelectedBeacons } from "../../../utils/consts"; import { getOnlineBeacons, isBeaconSelected } from "../../../utils/utils"; import BeaconStep from "./BeaconStep"; +import Button from "../../../components/tavern-base-ui/button/Button"; type Props = { setCurrStep: (arg1: number) => void; @@ -44,13 +45,13 @@ export const BeaconStepWrapper = (props: Props) => { )} - handleClickContinue(selectedBeacons)} disabled={!hasBeaconSelected} > Continue - + ); diff --git a/tavern/internal/www/src/pages/create-quest/components/FinalizeStep.tsx b/tavern/internal/www/src/pages/create-quest/components/FinalizeStep.tsx index 5111dc16d..3c3a76ae5 100644 --- a/tavern/internal/www/src/pages/create-quest/components/FinalizeStep.tsx +++ b/tavern/internal/www/src/pages/create-quest/components/FinalizeStep.tsx @@ -7,6 +7,7 @@ import TomeAccordion from "../../../components/TomeAccordion"; import { TagContext } from "../../../context/TagContext"; import { BeaconType } from "../../../utils/consts"; import { convertArrayToObject } from "../../../utils/utils"; +import Button from "../../../components/tavern-base-ui/button/Button"; type Props = { @@ -57,14 +58,13 @@ const FinalizeStep = (props: Props) => { onChange={(event) => handleNameQuest(event?.target?.value)} /> - setCurrStep(1)} > Back - - + { event.preventDefault(); formik.handleSubmit(); @@ -73,7 +73,7 @@ const FinalizeStep = (props: Props) => { type="submit" > Submit - + ); diff --git a/tavern/internal/www/src/pages/create-quest/components/TomeStepWrapper.tsx b/tavern/internal/www/src/pages/create-quest/components/TomeStepWrapper.tsx index 5b184d3dc..07527fd00 100644 --- a/tavern/internal/www/src/pages/create-quest/components/TomeStepWrapper.tsx +++ b/tavern/internal/www/src/pages/create-quest/components/TomeStepWrapper.tsx @@ -2,6 +2,7 @@ import { gql, useQuery } from "@apollo/client"; import { EmptyState, EmptyStateType } from "../../../components/tavern-base-ui/EmptyState"; import { TomeParams } from "../../../utils/consts"; import TomeStep from "./TomeStep"; +import Button from "../../../components/tavern-base-ui/button/Button"; const GET_TOMES = gql` query get_tomes{ @@ -44,19 +45,18 @@ const TomeStepWrapper = ( )} - setCurrStep(0)} + buttonVariant="ghost" > Back - - + setCurrStep(2)} disabled={isContinueDisabled} > Continue - + ); diff --git a/tavern/internal/www/src/pages/dashboard/Dashboard.tsx b/tavern/internal/www/src/pages/dashboard/Dashboard.tsx index 3f3ff5b68..495299318 100644 --- a/tavern/internal/www/src/pages/dashboard/Dashboard.tsx +++ b/tavern/internal/www/src/pages/dashboard/Dashboard.tsx @@ -8,6 +8,7 @@ import { PageNavItem } from "../../utils/enums"; import { GET_HOST_QUERY, GET_TASK_QUERY } from "../../utils/queries"; import OverviewChartWrapper from "./components/OverviewChartWrapper"; +import EmptyStateNoBeacon from "../../components/empty-states/EmptyStateNoBeacon"; export const Dashboard = () => { diff --git a/tavern/internal/www/src/pages/dashboard/components/GroupBarChart.tsx b/tavern/internal/www/src/pages/dashboard/components/GroupBarChart.tsx index eb703c9ca..9800167b8 100644 --- a/tavern/internal/www/src/pages/dashboard/components/GroupBarChart.tsx +++ b/tavern/internal/www/src/pages/dashboard/components/GroupBarChart.tsx @@ -1,4 +1,3 @@ -import { Button } from '@chakra-ui/react'; import React from 'react'; import { useNavigate } from 'react-router-dom'; import { BarChart, Bar, Rectangle, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer, Cell } from 'recharts'; @@ -7,6 +6,7 @@ import { EmptyState, EmptyStateType } from '../../../components/tavern-base-ui/E import { TomeTag } from '../../../utils/consts'; import { TaskChartKeys } from '../../../utils/enums'; import { getOfflineOnlineStatus } from '../../../utils/utils'; +import Button from '../../../components/tavern-base-ui/button/Button'; const GroupBarChart = ({ data, loading, hosts }: { data: Array, loading: boolean, hosts: Array }) => { @@ -111,9 +111,13 @@ const GroupBarChart = ({ data, loading, hosts }: { data: Array, loading: bo Consider targeting the group with fewest tasks {groupWithFewestTasks.name} has {groupWithFewestTasks[TaskChartKeys.taskNoError]} task run and {getTotalActiveBeaconsForGroup()} online beacons - { - handleClickQuestDetails(groupWithFewestTasks) - }}> + { + handleClickQuestDetails(groupWithFewestTasks) + }}> See quest details diff --git a/tavern/internal/www/src/pages/host-details/components/BeaconTable.tsx b/tavern/internal/www/src/pages/host-details/components/BeaconTable.tsx index 18c1ed993..67ee37c28 100644 --- a/tavern/internal/www/src/pages/host-details/components/BeaconTable.tsx +++ b/tavern/internal/www/src/pages/host-details/components/BeaconTable.tsx @@ -1,4 +1,4 @@ -import { Badge, Button } from "@chakra-ui/react"; +import { Badge } from "@chakra-ui/react"; import { ColumnDef } from "@tanstack/react-table"; import { formatDistance } from "date-fns"; import { useNavigate } from 'react-router-dom'; @@ -7,6 +7,7 @@ import Table from "../../../components/tavern-base-ui/Table"; import { BeaconType } from "../../../utils/consts"; import { PrincipalAdminTypes } from "../../../utils/enums"; import { checkIfBeaconOffline } from "../../../utils/utils"; +import Button from "../../../components/tavern-base-ui/button/Button"; type Props = { beacons: Array @@ -100,14 +101,17 @@ const BeaconTable = (props: Props) => { return ( {!isOffline && - - nav("/createQuest", { - state: { - step: 1, - beacons: [id] - } - }) - }> + + nav("/createQuest", { + state: { + step: 1, + beacons: [id] + } + }) + }> New quest } diff --git a/tavern/internal/www/src/pages/host-details/components/EditableHostHeader.tsx b/tavern/internal/www/src/pages/host-details/components/EditableHostHeader.tsx index afb2831e3..6108e828e 100644 --- a/tavern/internal/www/src/pages/host-details/components/EditableHostHeader.tsx +++ b/tavern/internal/www/src/pages/host-details/components/EditableHostHeader.tsx @@ -1,8 +1,8 @@ import { ApolloError } from "@apollo/client"; import { CloseIcon } from "@chakra-ui/icons"; -import { Button } from "@chakra-ui/react"; import { Link } from "react-router-dom"; import { HostType } from "../../../utils/consts"; +import Button from "../../../components/tavern-base-ui/button/Button"; type Props = { hostId?: string; @@ -20,30 +20,27 @@ const EditableHostHeader = (props: Props) => { {hostData && - } colorScheme='purple' variant='outline' size="xs"> + } + buttonVariant="outline" + buttonStyle={{ color: "purple", size: "xs" }} + > {hostData?.name} } {(error || (!hostData && !loading)) && - } colorScheme='purple' variant='outline' size="xs"> + } + buttonVariant="outline" + buttonStyle={{ color: "purple", size: "xs" }} + > Id: {hostId} } - {/* TODO support changing tags - } - colorScheme="gray" - variant="ghost" - verticalAlign="center" - > - - Change host tags - */} - ); } diff --git a/tavern/internal/www/src/pages/host-details/components/HostTasks.tsx b/tavern/internal/www/src/pages/host-details/components/HostTasks.tsx index a065d9b9a..74ebe7e40 100644 --- a/tavern/internal/www/src/pages/host-details/components/HostTasks.tsx +++ b/tavern/internal/www/src/pages/host-details/components/HostTasks.tsx @@ -9,6 +9,7 @@ import TablePagination from "../../../components/tavern-base-ui/TablePagination" import { DEFAULT_QUERY_TYPE, TableRowLimit } from "../../../utils/enums"; import FreeTextSearch from "../../../components/tavern-base-ui/DebouncedFreeTextSearch"; import { useTasks } from "../../../hooks/useTasks"; +import Button from "../../../components/tavern-base-ui/button/Button"; const HostTasks = () => { const { hostId } = useParams(); @@ -60,12 +61,11 @@ const HostTasks = () => { : ( - Create new quest - + )} diff --git a/tavern/internal/www/src/pages/quest-list/components/QuestHeader.tsx b/tavern/internal/www/src/pages/quest-list/components/QuestHeader.tsx index 5494678ac..b890a1fbc 100644 --- a/tavern/internal/www/src/pages/quest-list/components/QuestHeader.tsx +++ b/tavern/internal/www/src/pages/quest-list/components/QuestHeader.tsx @@ -1,6 +1,6 @@ import React from "react"; -import { Button } from "@chakra-ui/react"; import { useNavigate } from "react-router-dom"; +import Button from "../../../components/tavern-base-ui/button/Button"; const QuestHeader = () => { const navigate = useNavigate(); @@ -14,7 +14,8 @@ const QuestHeader = () => { - navigate("/createQuest")} > Create new quest diff --git a/tavern/internal/www/src/pages/tasks/EditablePageHeader.tsx b/tavern/internal/www/src/pages/tasks/EditablePageHeader.tsx index c0d1a8c58..de1e3dd2d 100644 --- a/tavern/internal/www/src/pages/tasks/EditablePageHeader.tsx +++ b/tavern/internal/www/src/pages/tasks/EditablePageHeader.tsx @@ -1,9 +1,9 @@ import { ApolloError } from "@apollo/client"; import { CloseIcon } from "@chakra-ui/icons"; -import { Button } from "@chakra-ui/react"; import { FC } from "react"; import { Link } from "react-router-dom"; import { CreateQuestDropdown } from "../../features/create-quest-dropdown"; +import Button from "../../components/tavern-base-ui/button/Button"; type EditablePageHeaderProps = { questId?: string; @@ -21,14 +21,23 @@ export const EditablePageHeader: FC = ({ questId, data, {data?.quests?.edges[0]?.node?.name && - } colorScheme='purple' variant='outline' size="xs"> + } + + > {data?.quests?.edges[0]?.node?.name} } {(error || (!data?.quests?.edges[0]?.node?.name && !loading)) && - } colorScheme='purple' variant='outline' size="xs"> + } + buttonStyle={{ color: "purple", size: "xs" }} + buttonVariant="outline" + > {questId} diff --git a/tavern/internal/www/src/pages/tasks/Tasks.tsx b/tavern/internal/www/src/pages/tasks/Tasks.tsx index 069087542..23cf17787 100644 --- a/tavern/internal/www/src/pages/tasks/Tasks.tsx +++ b/tavern/internal/www/src/pages/tasks/Tasks.tsx @@ -11,6 +11,7 @@ import { useTasks } from "../../hooks/useTasks"; import { Task } from "../../utils/consts"; import { EditablePageHeader } from "./EditablePageHeader"; import { useQuests } from "../../hooks/useQuests"; +import Button from "../../components/tavern-base-ui/button/Button"; const Tasks = () => { const { questId } = useParams(); @@ -70,12 +71,12 @@ const Tasks = () => { ) : ( - Create new quest - + )} diff --git a/tavern/internal/www/src/pages/tomes/Tomes.tsx b/tavern/internal/www/src/pages/tomes/Tomes.tsx index b2516f535..b41b0676a 100644 --- a/tavern/internal/www/src/pages/tomes/Tomes.tsx +++ b/tavern/internal/www/src/pages/tomes/Tomes.tsx @@ -7,7 +7,7 @@ import { EmptyState, EmptyStateType } from "../../components/tavern-base-ui/Empt import ImportRepositoryModal from "./components/ImportRepositoryModal"; import RepositoryTable from "./components/RepositoryTable"; import { useRepositoryView } from "./hooks/useRepositoryView"; -import { Button } from "@chakra-ui/react"; +import Button from "../../components/tavern-base-ui/button/Button"; export const Tomes = (): ReactElement => { const [isOpen, setOpen] = useState(false); @@ -25,7 +25,11 @@ export const Tomes = (): ReactElement => { - } onClick={() => setOpen(true)}> + } + onClick={() => setOpen(true)} + > Import tome repository diff --git a/tavern/internal/www/src/pages/tomes/components/RepositoryTable.tsx b/tavern/internal/www/src/pages/tomes/components/RepositoryTable.tsx index 96942d7e9..a726e0a20 100644 --- a/tavern/internal/www/src/pages/tomes/components/RepositoryTable.tsx +++ b/tavern/internal/www/src/pages/tomes/components/RepositoryTable.tsx @@ -1,4 +1,4 @@ -import { Badge, Button, Image, Tooltip } from "@chakra-ui/react"; +import { Badge, Image, Tooltip } from "@chakra-ui/react"; import { ArrowPathIcon, ChevronDownIcon, ChevronRightIcon, ClipboardDocumentIcon } from "@heroicons/react/24/outline"; import { ColumnDef, Row } from "@tanstack/react-table"; import { formatDistance } from "date-fns"; @@ -8,6 +8,7 @@ import TomeAccordion from "../../../components/TomeAccordion"; import { RepositoryRow, Tome } from "../../../utils/consts"; import { constructTomeParams } from "../../../utils/utils"; import { useFetchRepositoryTome } from "../hooks/useFetchRepostioryTomes"; +import Button from "../../../components/tavern-base-ui/button/Button"; const RepositoryTable = ({ repositories }: { repositories: Array @@ -127,7 +128,8 @@ const RepositoryTable = ({ repositories }: { } aria-label="Refetch tomes" @@ -138,7 +140,8 @@ const RepositoryTable = ({ repositories }: { } diff --git a/tavern/internal/www/src/pages/tomes/components/StepAddDeploymentKey.tsx b/tavern/internal/www/src/pages/tomes/components/StepAddDeploymentKey.tsx index 49ac9735a..e8ccf0917 100644 --- a/tavern/internal/www/src/pages/tomes/components/StepAddDeploymentKey.tsx +++ b/tavern/internal/www/src/pages/tomes/components/StepAddDeploymentKey.tsx @@ -5,6 +5,7 @@ import { CopyBlock, tomorrow } from "react-code-blocks"; import AlertError from "../../../components/tavern-base-ui/AlertError"; import { RepositoryType } from "../../../utils/consts"; import { useFetchRepositoryTome } from "../hooks/useFetchRepostioryTomes"; +import Button from "../../../components/tavern-base-ui/button/Button"; type StepAddDeploymentKeyProps = { setCurrStep: (step: number) => void; @@ -47,30 +48,26 @@ const StepAddDeploymentKey: FC = ({ setCurrStep, newR - setCurrStep(0)} disabled={loading ? true : false} > Back - - + { event.preventDefault(); importRepositoryTomes(newRepository.id || ""); }} type="submit" disabled={loading ? true : false} + isLoading={loading} > - {loading === true && } {loading === true ? "Importing" : "Import"} tomes - + ); diff --git a/tavern/internal/www/src/pages/tomes/components/StepCreateRepository.tsx b/tavern/internal/www/src/pages/tomes/components/StepCreateRepository.tsx index b19801add..119eff36e 100644 --- a/tavern/internal/www/src/pages/tomes/components/StepCreateRepository.tsx +++ b/tavern/internal/www/src/pages/tomes/components/StepCreateRepository.tsx @@ -4,6 +4,7 @@ import AlertError from "../../../components/tavern-base-ui/AlertError"; import FormTextField from "../../../components/tavern-base-ui/FormTextField"; import { RepositoryType } from "../../../utils/consts"; import { useCreateRepositoryLink } from "../hooks/useCreateRepositoryLink"; +import Button from "../../../components/tavern-base-ui/button/Button"; type StepCreateRepositoryProps = { setCurrStep: (step: number) => void; @@ -39,8 +40,7 @@ const StepCreateRepository: FC = ({ setCurrStep, setN onChange={(event) => formik.setFieldValue('url', event?.target?.value)} /> - { event.preventDefault(); formik.handleSubmit(); @@ -49,7 +49,7 @@ const StepCreateRepository: FC = ({ setCurrStep, setN type="submit" > Save link - + ); diff --git a/tavern/internal/www/src/style.css b/tavern/internal/www/src/style.css index 8a39d7023..61b71434d 100644 --- a/tavern/internal/www/src/style.css +++ b/tavern/internal/www/src/style.css @@ -24,7 +24,7 @@ @layer components { .btn-primary { - @apply inline-flex items-center rounded-md bg-purple-700 px-4 py-3 text-sm font-semibold text-white shadow-sm; + @apply inline-flex items-center rounded-md bg-purple-700 text-white; } .btn-primary:hover {
- Page {page} of {getPageCount()} {`(${totalCount} results)`} -
+ Page {page} of {getPageCount()} {`(${totalCount} results)`} +
{groupWithFewestTasks.name} has {groupWithFewestTasks[TaskChartKeys.taskNoError]} task run and {getTotalActiveBeaconsForGroup()} online beacons