refactor: add modules/templates and modules/workspaces (#11947)

This commit is contained in:
Kayla Washburn-Love
2024-01-31 12:09:36 -07:00
committed by GitHub
parent 4604db072a
commit 76e73287a5
32 changed files with 86 additions and 66 deletions
+1 -1
View File
@@ -25,7 +25,7 @@ import {
Line,
LogLine,
logLineHeight,
} from "components/WorkspaceBuildLogs/Logs";
} from "modules/workspaces/WorkspaceBuildLogs/Logs";
import { useProxy } from "contexts/ProxyContext";
import { Stack } from "components/Stack/Stack";
import { AgentLatency } from "./AgentLatency";
@@ -7,7 +7,7 @@ import {
import { TemplateExampleCard } from "./TemplateExampleCard";
const meta: Meta<typeof TemplateExampleCard> = {
title: "components/TemplateExampleCard",
title: "modules/templates/TemplateExampleCard",
parameters: { chromatic },
component: TemplateExampleCard,
args: {
@@ -13,7 +13,7 @@ const exampleFiles = {
};
const meta: Meta<typeof TemplateFiles> = {
title: "components/TemplateFiles",
title: "modules/templates/TemplateFiles",
parameters: { chromatic },
component: TemplateFiles,
args: {
@@ -4,7 +4,7 @@ import { MockWorkspaceBuildLogs } from "testHelpers/entities";
import { WorkspaceBuildLogs } from "./WorkspaceBuildLogs";
const meta: Meta<typeof WorkspaceBuildLogs> = {
title: "components/WorkspaceBuildLogs",
title: "modules/workspaces/WorkspaceBuildLogs",
parameters: { chromatic },
component: WorkspaceBuildLogs,
};
@@ -1,10 +1,11 @@
import { action } from "@storybook/addon-actions";
import type { Meta, StoryObj } from "@storybook/react";
import { expect, userEvent, waitFor, within } from "@storybook/test";
import { MockTemplateVersion, MockTemplate } from "testHelpers/entities";
import { WorkspaceOutdatedTooltip } from "./WorkspaceOutdatedTooltip";
const meta: Meta<typeof WorkspaceOutdatedTooltip> = {
title: "components/WorkspaceOutdatedTooltip",
title: "modules/workspaces/WorkspaceOutdatedTooltip",
component: WorkspaceOutdatedTooltip,
parameters: {
queries: [
@@ -24,6 +25,19 @@ const meta: Meta<typeof WorkspaceOutdatedTooltip> = {
export default meta;
type Story = StoryObj<typeof WorkspaceOutdatedTooltip>;
const Example: Story = {};
const Example: Story = {
play: async ({ canvasElement, step }) => {
const screen = within(canvasElement);
await step("activate hover trigger", async () => {
await userEvent.hover(screen.getByRole("button"));
await waitFor(() =>
expect(
screen.getByText(MockTemplateVersion.message),
).toBeInTheDocument(),
);
});
},
};
export { Example as WorkspaceOutdatedTooltip };
@@ -25,7 +25,7 @@ const MockedAppearance = {
};
const meta: Meta<typeof WorkspaceStatusBadge> = {
title: "components/WorkspaceStatusBadge",
title: "modules/workspaces/WorkspaceStatusBadge",
component: WorkspaceStatusBadge,
decorators: [
(Story) => (
@@ -1,5 +1,10 @@
import { type Interpolation, type Theme } from "@emotion/react";
import TextField from "@mui/material/TextField";
import { useFormik } from "formik";
import { type FC, useEffect } from "react";
import camelCase from "lodash/camelCase";
import capitalize from "lodash/capitalize";
import * as Yup from "yup";
import type {
ProvisionerJobLog,
Template,
@@ -8,18 +13,19 @@ import type {
VariableValue,
} from "api/typesGenerated";
import { Stack } from "components/Stack/Stack";
import { TemplateUpload, type TemplateUploadProps } from "./TemplateUpload";
import { useFormik } from "formik";
import { SelectedTemplate } from "pages/CreateWorkspacePage/SelectedTemplate";
import { type FC, useEffect } from "react";
import {
nameValidator,
getFormHelpers,
onChangeTrimmed,
templateDisplayNameValidator,
} from "utils/formUtils";
import * as Yup from "yup";
import { WorkspaceBuildLogs } from "components/WorkspaceBuildLogs/WorkspaceBuildLogs";
import {
type TemplateAutostartRequirementDaysValue,
type TemplateAutostopRequirementDaysValue,
} from "utils/schedule";
import { sortedDays } from "modules/templates/TemplateScheduleAutostart/TemplateScheduleAutostart";
import { WorkspaceBuildLogs } from "modules/workspaces/WorkspaceBuildLogs/WorkspaceBuildLogs";
import { IconField } from "components/IconField/IconField";
import {
HorizontalForm,
@@ -27,14 +33,8 @@ import {
FormFields,
FormFooter,
} from "components/Form/Form";
import camelCase from "lodash/camelCase";
import capitalize from "lodash/capitalize";
import { TemplateUpload, type TemplateUploadProps } from "./TemplateUpload";
import { VariableInput } from "./VariableInput";
import {
type TemplateAutostartRequirementDaysValue,
type TemplateAutostopRequirementDaysValue,
} from "utils/schedule";
import { sortedDays } from "components/TemplateScheduleAutostart/TemplateScheduleAutostart";
const MAX_DESCRIPTION_CHAR_LIMIT = 128;
@@ -1,4 +1,6 @@
import { type Interpolation, type Theme } from "@emotion/react";
import { type FC } from "react";
import { Link, useSearchParams } from "react-router-dom";
import { ErrorAlert } from "components/Alert/ErrorAlert";
import { Loader } from "components/Loader/Loader";
import { Margins } from "components/Margins/Margins";
@@ -8,9 +10,7 @@ import {
PageHeaderTitle,
} from "components/PageHeader/PageHeader";
import { Stack } from "components/Stack/Stack";
import { TemplateExampleCard } from "components/TemplateExampleCard/TemplateExampleCard";
import { type FC } from "react";
import { Link, useSearchParams } from "react-router-dom";
import { TemplateExampleCard } from "modules/templates/TemplateExampleCard/TemplateExampleCard";
import type { StarterTemplatesByTag } from "utils/starterTemplates";
const getTagLabel = (tag: string) => {
@@ -6,7 +6,7 @@ import { Loader } from "components/Loader/Loader";
import {
TemplateFiles,
useFileTab,
} from "components/TemplateFiles/TemplateFiles";
} from "modules/templates/TemplateFiles/TemplateFiles";
import { useTemplateLayoutContext } from "pages/TemplatePage/TemplateLayout";
import { useOrganizationId } from "contexts/auth/useOrganizationId";
import { getTemplatePageTitle } from "../utils";
@@ -7,7 +7,7 @@ import type {
} from "api/typesGenerated";
import { Loader } from "components/Loader/Loader";
import { Stack } from "components/Stack/Stack";
import { TemplateResourcesTable } from "components/TemplateResourcesTable/TemplateResourcesTable";
import { TemplateResourcesTable } from "modules/templates/TemplateResourcesTable/TemplateResourcesTable";
import { TemplateStats } from "./TemplateStats";
export interface TemplateSummaryPageViewProps {
@@ -5,8 +5,9 @@ import Checkbox from "@mui/material/Checkbox";
import FormControlLabel from "@mui/material/FormControlLabel";
import Switch from "@mui/material/Switch";
import { FormikTouched, useFormik } from "formik";
import { FC, ChangeEvent, useState, useEffect } from "react";
import { Template, UpdateTemplateMeta } from "api/typesGenerated";
import { type FC, ChangeEvent, useState, useEffect } from "react";
import { useTheme } from "@emotion/react";
import type { Template, UpdateTemplateMeta } from "api/typesGenerated";
import { getFormHelpers } from "utils/formUtils";
import { docs } from "utils/docs";
import {
@@ -20,6 +21,7 @@ import {
FormFields,
} from "components/Form/Form";
import { Stack } from "components/Stack/Stack";
import { TemplateScheduleAutostart } from "modules/templates/TemplateScheduleAutostart/TemplateScheduleAutostart";
import {
useWorkspacesToGoDormant,
useWorkspacesToBeDeleted,
@@ -38,8 +40,6 @@ import {
AutostopRequirementWeeksHelperText,
convertAutostopRequirementDaysValue,
} from "./AutostopRequirementHelperText";
import { useTheme } from "@emotion/react";
import { TemplateScheduleAutostart } from "components/TemplateScheduleAutostart/TemplateScheduleAutostart";
const MS_HOUR_CONVERSION = 3600000;
const MS_DAY_CONVERSION = 86400000;
@@ -2,6 +2,14 @@ import Button from "@mui/material/Button";
import IconButton from "@mui/material/IconButton";
import Tooltip from "@mui/material/Tooltip";
import CreateIcon from "@mui/icons-material/AddOutlined";
import { Link as RouterLink } from "react-router-dom";
import { type Interpolation, type Theme, useTheme } from "@emotion/react";
import { type FC, useCallback, useEffect, useRef, useState } from "react";
import AlertTitle from "@mui/material/AlertTitle";
import ButtonGroup from "@mui/material/ButtonGroup";
import ArrowBackOutlined from "@mui/icons-material/ArrowBackOutlined";
import CloseOutlined from "@mui/icons-material/CloseOutlined";
import PlayArrowOutlined from "@mui/icons-material/PlayArrowOutlined";
import type {
ProvisionerJobLog,
Template,
@@ -10,13 +18,10 @@ import type {
VariableValue,
WorkspaceResource,
} from "api/typesGenerated";
import { Link as RouterLink } from "react-router-dom";
import { Alert, AlertDetail } from "components/Alert/Alert";
import { TemplateResourcesTable } from "components/TemplateResourcesTable/TemplateResourcesTable";
import { WorkspaceBuildLogs } from "components/WorkspaceBuildLogs/WorkspaceBuildLogs";
import { TemplateResourcesTable } from "modules/templates/TemplateResourcesTable/TemplateResourcesTable";
import { WorkspaceBuildLogs } from "modules/workspaces/WorkspaceBuildLogs/WorkspaceBuildLogs";
import { PublishVersionData } from "pages/TemplateVersionEditorPage/types";
import { type FC, useCallback, useEffect, useRef, useState } from "react";
import PlayArrowOutlined from "@mui/icons-material/PlayArrowOutlined";
import {
createFile,
existsFile,
@@ -38,10 +43,6 @@ import { MissingTemplateVariablesDialog } from "./MissingTemplateVariablesDialog
import { MonacoEditor } from "./MonacoEditor";
import { PublishTemplateVersionDialog } from "./PublishTemplateVersionDialog";
import { TemplateVersionStatusBadge } from "./TemplateVersionStatusBadge";
import AlertTitle from "@mui/material/AlertTitle";
import { type Interpolation, type Theme, useTheme } from "@emotion/react";
import ArrowBackOutlined from "@mui/icons-material/ArrowBackOutlined";
import CloseOutlined from "@mui/icons-material/CloseOutlined";
import { MONOSPACE_FONT_FAMILY } from "theme/constants";
import { Loader } from "components/Loader/Loader";
import {
@@ -53,7 +54,6 @@ import {
TopbarIconButton,
} from "components/FullPageLayout/Topbar";
import { Sidebar } from "components/FullPageLayout/Sidebar";
import ButtonGroup from "@mui/material/ButtonGroup";
import { ProvisionerTagsPopover } from "./ProvisionerTagsPopover";
type Tab = "logs" | "resources" | undefined; // Undefined is to hide the tab
@@ -24,11 +24,12 @@ import { AppProviders } from "App";
// For some reason this component in Jest is throwing a MUI style warning so,
// since we don't need it for this test, we can mock it out
jest.mock("components/TemplateResourcesTable/TemplateResourcesTable", () => {
return {
TemplateResourcesTable: () => <div />,
};
});
jest.mock(
"modules/templates/TemplateResourcesTable/TemplateResourcesTable",
() => ({
TemplateResourcesTable: () => <div></div>,
}),
);
const renderTemplateEditorPage = () => {
renderWithAuth(<TemplateVersionEditorPage />, {
@@ -37,7 +38,7 @@ const renderTemplateEditorPage = () => {
extraRoutes: [
{
path: "/templates/:templateId",
element: <div />,
element: <div></div>,
},
],
});
@@ -5,7 +5,7 @@ import { useParams } from "react-router-dom";
import { usePermissions } from "contexts/auth/usePermissions";
import { useOrganizationId } from "contexts/auth/useOrganizationId";
import { pageTitle } from "utils/page";
import { useFileTab } from "components/TemplateFiles/TemplateFiles";
import { useFileTab } from "modules/templates/TemplateFiles/TemplateFiles";
import TemplateVersionPageView from "./TemplateVersionPageView";
import {
templateByName,
@@ -1,6 +1,8 @@
import Button from "@mui/material/Button";
import AddIcon from "@mui/icons-material/Add";
import EditIcon from "@mui/icons-material/Edit";
import { type FC } from "react";
import { Link as RouterLink } from "react-router-dom";
import { Loader } from "components/Loader/Loader";
import { Margins } from "components/Margins/Margins";
import {
@@ -11,14 +13,12 @@ import {
} from "components/PageHeader/PageHeader";
import { Stack } from "components/Stack/Stack";
import { Stats, StatsItem } from "components/Stats/Stats";
import { TemplateFiles } from "components/TemplateFiles/TemplateFiles";
import { TemplateFiles } from "modules/templates/TemplateFiles/TemplateFiles";
import { UseTabResult } from "hooks/useTab";
import { type FC } from "react";
import { Link as RouterLink } from "react-router-dom";
import type { TemplateVersion } from "api/typesGenerated";
import { createDayString } from "utils/createDayString";
import { ErrorAlert } from "components/Alert/ErrorAlert";
import { TemplateVersion } from "api/typesGenerated";
import { TemplateVersionFiles } from "utils/templateVersion";
import { ErrorAlert } from "components/Alert/ErrorAlert";
export interface TemplateVersionPageViewProps {
versionName: string;
@@ -7,7 +7,7 @@ import type { TemplateExample } from "api/typesGenerated";
import { CodeExample } from "components/CodeExample/CodeExample";
import { Stack } from "components/Stack/Stack";
import { TableEmpty } from "components/TableEmpty/TableEmpty";
import { TemplateExampleCard } from "components/TemplateExampleCard/TemplateExampleCard";
import { TemplateExampleCard } from "modules/templates/TemplateExampleCard/TemplateExampleCard";
import { docs } from "utils/docs";
// Those are from https://github.com/coder/coder/tree/main/examples/templates
@@ -7,7 +7,7 @@ import { DashboardFullPage } from "modules/dashboard/DashboardLayout";
import { BuildAvatar } from "components/BuildAvatar/BuildAvatar";
import { Loader } from "components/Loader/Loader";
import { Stack } from "components/Stack/Stack";
import { WorkspaceBuildLogs } from "components/WorkspaceBuildLogs/WorkspaceBuildLogs";
import { WorkspaceBuildLogs } from "modules/workspaces/WorkspaceBuildLogs/WorkspaceBuildLogs";
import {
FullWidthPageHeader,
PageHeaderTitle,
@@ -18,7 +18,7 @@ import { Alert } from "components/Alert/Alert";
import {
WorkspaceBuildData,
WorkspaceBuildDataSkeleton,
} from "components/WorkspaceBuild/WorkspaceBuildData";
} from "modules/workspaces/WorkspaceBuild/WorkspaceBuildData";
import { Sidebar, SidebarCaption, SidebarItem } from "./Sidebar";
const sortLogsByCreatedAt = (logs: ProvisionerJobLog[]) => {
@@ -1,7 +1,9 @@
import ArrowDownwardOutlined from "@mui/icons-material/ArrowDownwardOutlined";
import LoadingButton from "@mui/lab/LoadingButton";
import { type FC } from "react";
import { useInfiniteQuery } from "react-query";
import { infiniteWorkspaceBuilds } from "api/queries/workspaceBuilds";
import { Workspace } from "api/typesGenerated";
import type { Workspace } from "api/typesGenerated";
import {
Sidebar,
SidebarCaption,
@@ -11,10 +13,13 @@ import {
import {
WorkspaceBuildData,
WorkspaceBuildDataSkeleton,
} from "components/WorkspaceBuild/WorkspaceBuildData";
import { useInfiniteQuery } from "react-query";
} from "modules/workspaces/WorkspaceBuild/WorkspaceBuildData";
export const HistorySidebar = ({ workspace }: { workspace: Workspace }) => {
interface HistorySidebarProps {
workspace: Workspace;
}
export const HistorySidebar: FC<HistorySidebarProps> = ({ workspace }) => {
const buildsQuery = useInfiniteQuery({
...infiniteWorkspaceBuilds(workspace?.id ?? ""),
enabled: workspace !== undefined,
@@ -2,7 +2,7 @@ import { useTheme } from "@emotion/react";
import { type FC, useRef, useEffect } from "react";
import type { ProvisionerJobLog } from "api/typesGenerated";
import { Loader } from "components/Loader/Loader";
import { WorkspaceBuildLogs } from "components/WorkspaceBuildLogs/WorkspaceBuildLogs";
import { WorkspaceBuildLogs } from "modules/workspaces/WorkspaceBuildLogs/WorkspaceBuildLogs";
interface WorkspaceBuildLogsSectionProps {
logs?: ProvisionerJobLog[];
@@ -17,11 +17,7 @@ import {
TopbarIcon,
TopbarIconButton,
} from "components/FullPageLayout/Topbar";
import { WorkspaceStatusBadge } from "components/WorkspaceStatusBadge/WorkspaceStatusBadge";
import {
WorkspaceScheduleControls,
shouldDisplayScheduleControls,
} from "./WorkspaceScheduleControls";
import { WorkspaceStatusBadge } from "modules/workspaces/WorkspaceStatusBadge/WorkspaceStatusBadge";
import { workspaceQuota } from "api/queries/workspaceQuota";
import { useDashboard } from "modules/dashboard/useDashboard";
import { displayDormantDeletion } from "utils/dormant";
@@ -29,10 +25,14 @@ import { Popover, PopoverTrigger } from "components/Popover/Popover";
import { HelpTooltipContent } from "components/HelpTooltip/HelpTooltip";
import { AvatarData } from "components/AvatarData/AvatarData";
import { ExternalAvatar } from "components/Avatar/Avatar";
import { UserAvatar } from "components/UserAvatar/UserAvatar";
import { WorkspaceActions } from "./WorkspaceActions/WorkspaceActions";
import { WorkspaceNotifications } from "./WorkspaceNotifications/WorkspaceNotifications";
import {
WorkspaceScheduleControls,
shouldDisplayScheduleControls,
} from "./WorkspaceScheduleControls";
import { WorkspacePermissions } from "./permissions";
import { UserAvatar } from "components/UserAvatar/UserAvatar";
export type WorkspaceError =
| "getBuildsError"
@@ -21,11 +21,11 @@ import { AvatarData } from "components/AvatarData/AvatarData";
import { ExternalAvatar } from "components/Avatar/Avatar";
import { Stack } from "components/Stack/Stack";
import { LastUsed } from "pages/WorkspacesPage/LastUsed";
import { WorkspaceOutdatedTooltip } from "components/WorkspaceOutdatedTooltip/WorkspaceOutdatedTooltip";
import { WorkspaceOutdatedTooltip } from "modules/workspaces/WorkspaceOutdatedTooltip/WorkspaceOutdatedTooltip";
import {
DormantStatusBadge,
WorkspaceStatusBadge,
} from "components/WorkspaceStatusBadge/WorkspaceStatusBadge";
} from "modules/workspaces/WorkspaceStatusBadge/WorkspaceStatusBadge";
import { getDisplayWorkspaceTemplateName } from "utils/workspace";
import { AvatarDataSkeleton } from "components/AvatarData/AvatarDataSkeleton";
import { InfoTooltip } from "components/InfoTooltip/InfoTooltip";