mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
refactor: add modules/templates and modules/workspaces (#11947)
This commit is contained in:
@@ -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";
|
||||
|
||||
+1
-1
@@ -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: {
|
||||
+1
-1
@@ -13,7 +13,7 @@ const exampleFiles = {
|
||||
};
|
||||
|
||||
const meta: Meta<typeof TemplateFiles> = {
|
||||
title: "components/TemplateFiles",
|
||||
title: "modules/templates/TemplateFiles",
|
||||
parameters: { chromatic },
|
||||
component: TemplateFiles,
|
||||
args: {
|
||||
+1
-1
@@ -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,
|
||||
};
|
||||
+16
-2
@@ -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 };
|
||||
+1
-1
@@ -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";
|
||||
|
||||
Reference in New Issue
Block a user