Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

feat: show workspace name suggestions below the name field#12001

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
aslilac merged 5 commits intomainfromworkspace-name-suggestions
Feb 5, 2024
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletionssite/src/modules/workspaces/generateWorkspaceName.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
import {
NumberDictionary,
animals,
colors,
uniqueNamesGenerator,
} from "unique-names-generator";

export const generateWorkspaceName = () => {
const numberDictionary = NumberDictionary.generate({ min: 0, max: 99 });
return uniqueNamesGenerator({
dictionaries: [colors, animals, numberDictionary],
separator: "-",
length: 3,
style: "lowerCase",
});
};
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -214,7 +214,7 @@ describe("CreateWorkspacePage", () => {
it("Detects when a workspace is being created with the 'duplicate' mode", async () => {
const params = new URLSearchParams({
mode: "duplicate",
name: MockWorkspace.name,
name:`${MockWorkspace.name}-copy`,
version: MockWorkspace.template_active_version_id,
});

Expand Down
50 changes: 13 additions & 37 deletionssite/src/pages/CreateWorkspacePage/CreateWorkspacePage.tsx
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
import { type FC, useCallback, useEffect, useState } from "react";
import { Helmet } from "react-helmet-async";
import { useMutation, useQuery, useQueryClient } from "react-query";
import { useNavigate, useParams, useSearchParams } from "react-router-dom";
import { getUserParameters } from "api/api";
import { checkAuthorization } from "api/queries/authCheck";
import {
Expand All@@ -6,7 +10,7 @@ import {
templateVersionExternalAuth,
} from "api/queries/templates";
import { autoCreateWorkspace, createWorkspace } from "api/queries/workspaces";
import {
importtype{
TemplateVersionParameter,
UserParameter,
Workspace,
Expand All@@ -16,21 +20,12 @@ import { Loader } from "components/Loader/Loader";
import { useMe } from "contexts/auth/useMe";
import { useOrganizationId } from "contexts/auth/useOrganizationId";
import { useEffectEvent } from "hooks/hookPolyfills";
import { useCallback, useEffect, useMemo, useState, type FC } from "react";
import { Helmet } from "react-helmet-async";
import { useMutation, useQuery, useQueryClient } from "react-query";
import { useNavigate, useParams, useSearchParams } from "react-router-dom";
import {
NumberDictionary,
animals,
colors,
uniqueNamesGenerator,
} from "unique-names-generator";
import { pageTitle } from "utils/page";
import { AutofillBuildParameter } from "utils/richParameters";
import { paramsUsedToCreateWorkspace } from "utils/workspace";
import { CreateWorkspacePageView } from "./CreateWorkspacePageView";
import { CreateWSPermissions, createWorkspaceChecks } from "./permissions";
import { generateWorkspaceName } from "modules/workspaces/generateWorkspaceName";

export const createWorkspaceModes = ["form", "auto", "duplicate"] as const;
export type CreateWorkspaceMode = (typeof createWorkspaceModes)[number];
Expand All@@ -46,14 +41,7 @@ const CreateWorkspacePage: FC = () => {
const mode = getWorkspaceMode(searchParams);
const customVersionId = searchParams.get("version") ?? undefined;

const defaultName = useMemo(() => {
const paramsName = searchParams.get("name");
if (mode === "duplicate" && paramsName) {
return `${paramsName}-copy`;
}

return paramsName ?? generateUniqueName();
}, [mode, searchParams]);
const defaultName = searchParams.get("name");

const queryClient = useQueryClient();
const autoCreateWorkspaceMutation = useMutation(
Expand All@@ -63,13 +51,11 @@ const CreateWorkspacePage: FC = () => {

const templateQuery = useQuery(templateByName(organizationId, templateName));

const userParametersQuery = useQuery(
["userParameters"],
() => getUserParameters(templateQuery.data!.id),
{
enabled: templateQuery.isSuccess,
},
);
const userParametersQuery = useQuery({
queryKey: ["userParameters"],
queryFn: () => getUserParameters(templateQuery.data!.id),
enabled: templateQuery.isSuccess,
});

const permissionsQuery = useQuery(
checkAuthorization({
Expand DownExpand Up@@ -122,7 +108,7 @@ const CreateWorkspacePage: FC = () => {
templateName,
organizationId,
defaultBuildParameters: autofillParameters,
defaultName,
defaultName: defaultName ?? generateWorkspaceName(),
versionId: realizedVersionId,
});

Expand DownExpand Up@@ -269,16 +255,6 @@ const getAutofillParameters = (
return buildValues;
};

const generateUniqueName = () => {
const numberDictionary = NumberDictionary.generate({ min: 0, max: 99 });
return uniqueNamesGenerator({
dictionaries: [colors, animals, numberDictionary],
separator: "-",
length: 3,
style: "lowerCase",
});
};

export default CreateWorkspacePage;

function getWorkspaceMode(params: URLSearchParams): CreateWorkspaceMode {
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -48,6 +48,18 @@ export const CreateWorkspaceError: Story = {
},
};

export const SpecificVersion: Story = {
args: {
versionId: "specific-version",
},
};

export const Duplicate: Story = {
args: {
mode: "duplicate",
},
};

export const Parameters: Story = {
args: {
parameters: [
Expand Down
77 changes: 53 additions & 24 deletionssite/src/pages/CreateWorkspacePage/CreateWorkspacePageView.tsx
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
import { type Interpolation, type Theme } from "@emotion/react";
import TextField from "@mui/material/TextField";
importtype * as TypesGenfrom "api/typesGenerated";
import{ UserAutocomplete }from "components/UserAutocomplete/UserAutocomplete";
importButtonfrom "@mui/material/Button";
importFormHelperTextfrom "@mui/material/FormHelperText";
import { FormikContextType, useFormik } from "formik";
import { type FC, useEffect, useState, useMemo } from "react";
import { type FC, useEffect, useState, useMemo, useCallback } from "react";
import { useSearchParams } from "react-router-dom";
import * as Yup from "yup";
import type * as TypesGen from "api/typesGenerated";
import {
getFormHelpers,
nameValidator,
onChangeTrimmed,
} from "utils/formUtils";
import * as Yup from "yup";
import {
FormFields,
FormSection,
FormFooter,
HorizontalForm,
} from "components/Form/Form";
import { UserAutocomplete } from "components/UserAutocomplete/UserAutocomplete";
import {
AutofillBuildParameter,
AutofillSource,
Expand All@@ -24,16 +27,8 @@ import {
} from "utils/richParameters";
import { ErrorAlert } from "components/Alert/ErrorAlert";
import { Stack } from "components/Stack/Stack";
import {
CreateWorkspaceMode,
ExternalAuthPollingState,
} from "./CreateWorkspacePage";
import { useSearchParams } from "react-router-dom";
import { CreateWSPermissions } from "./permissions";
import { Alert } from "components/Alert/Alert";
import { ExternalAuthBanner } from "./ExternalAuthBanner/ExternalAuthBanner";
import { Margins } from "components/Margins/Margins";
import Button from "@mui/material/Button";
import { Avatar } from "components/Avatar/Avatar";
import {
PageHeader,
Expand All@@ -42,6 +37,13 @@ import {
} from "components/PageHeader/PageHeader";
import { Pill } from "components/Pill/Pill";
import { RichParameterInput } from "components/RichParameterInput/RichParameterInput";
import { generateWorkspaceName } from "modules/workspaces/generateWorkspaceName";
import {
CreateWorkspaceMode,
ExternalAuthPollingState,
} from "./CreateWorkspacePage";
import { ExternalAuthBanner } from "./ExternalAuthBanner/ExternalAuthBanner";
import { CreateWSPermissions } from "./permissions";

export const Language = {
duplicationWarning:
Expand All@@ -52,7 +54,7 @@ export interface CreateWorkspacePageViewProps {
mode: CreateWorkspaceMode;
error: unknown;
resetMutation: () => void;
defaultName: string;
defaultName?: string | null;
defaultOwner: TypesGen.User;
template: TypesGen.Template;
versionId?: string;
Expand DownExpand Up@@ -92,11 +94,18 @@ export const CreateWorkspacePageView: FC<CreateWorkspacePageViewProps> = ({
const [searchParams] = useSearchParams();
const disabledParamsList = searchParams?.get("disable_params")?.split(",");
const requiresExternalAuth = externalAuth.some((auth) => !auth.authenticated);
const [suggestedName, setSuggestedName] = useState(() =>
generateWorkspaceName(),
);

const rerollSuggestedName = useCallback(() => {
setSuggestedName(() => generateWorkspaceName());
}, []);

const form: FormikContextType<TypesGen.CreateWorkspaceRequest> =
useFormik<TypesGen.CreateWorkspaceRequest>({
initialValues: {
name: defaultName,
name: defaultName ?? "",
template_id: template.id,
rich_parameter_values: getInitialRichParameterValues(
parameters,
Expand DownExpand Up@@ -205,16 +214,29 @@ export const CreateWorkspacePageView: FC<CreateWorkspacePageViewProps> = ({
</span>
</Stack>
)}

<TextField
{...getFieldHelpers("name")}
disabled={creatingWorkspace}
// resetMutation facilitates the clearing of validation errors
onChange={onChangeTrimmed(form, resetMutation)}
autoFocus
fullWidth
label="Workspace Name"
/>
<div>
<TextField
{...getFieldHelpers("name")}
disabled={creatingWorkspace}
// resetMutation facilitates the clearing of validation errors
onChange={onChangeTrimmed(form, resetMutation)}
fullWidth
label="Workspace Name"
/>
<FormHelperText data-chromatic="ignore">
Need a suggestion?{" "}
<Button
variant="text"
css={styles.nameSuggestion}
onClick={async () => {
await form.setFieldValue("name", suggestedName);
rerollSuggestedName();
}}
>
{suggestedName}
</Button>
</FormHelperText>
</div>

{permissions.createWorkspaceForUser && (
<UserAutocomplete
Expand DownExpand Up@@ -279,6 +301,13 @@ export const CreateWorkspacePageView: FC<CreateWorkspacePageViewProps> = ({
};

const styles = {
nameSuggestion: (theme) => ({
color: theme.roles.info.fill.solid,
padding: "4px 8px",
lineHeight: "inherit",
fontSize: "inherit",
height: "unset",
}),
hasDescription: {
paddingBottom: 16,
},
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -88,7 +88,7 @@ describe(`${useWorkspaceDuplication.name}`, () => {
const parsedParams = new URLSearchParams(router.state.location.search);
const extraMetadataEntries = [
["mode", "duplicate"],
["name", MockWorkspace.name],
["name",`${MockWorkspace.name}-copy`],
["version", MockWorkspace.template_active_version_id],
] as const;

Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
import {useNavigate } from "react-router-dom";
import {useCallback } from "react";
import { useQuery } from "react-query";
import { type CreateWorkspaceMode } from "./CreateWorkspacePage";
import {
type Workspace,
type WorkspaceBuildParameter,
} from "api/typesGenerated";
import { useNavigate } from "react-router-dom";
import type { Workspace, WorkspaceBuildParameter } from "api/typesGenerated";
import { workspaceBuildParameters } from "api/queries/workspaceBuilds";
import {useCallback} from "react";
import {type CreateWorkspaceMode} from "./CreateWorkspacePage";

function getDuplicationUrlParams(
workspaceParams: readonly WorkspaceBuildParameter[],
Expand All@@ -23,7 +20,7 @@ function getDuplicationUrlParams(
return new URLSearchParams({
...consolidatedParams,
mode: "duplicate" satisfies CreateWorkspaceMode,
name: workspace.name,
name:`${workspace.name}-copy`,
version: workspace.template_active_version_id,
});
}
Expand Down
2 changes: 1 addition & 1 deletionsite/src/theme/dark/roles.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -67,7 +67,7 @@ export default {
outline: colors.blue[400],
text: colors.blue[50],
fill: {
solid: colors.blue[600],
solid: colors.blue[500],
outline: colors.blue[600],
text: colors.white,
},
Expand Down
2 changes: 1 addition & 1 deletionsite/src/theme/darkBlue/roles.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -68,7 +68,7 @@ export default {
text: colors.blue[50],
fill: {
solid: colors.blue[500],
outline: colors.blue[500],
outline: colors.blue[600],
text: colors.white,
},
},
Expand Down
2 changes: 1 addition & 1 deletionsite/src/theme/light/roles.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -67,7 +67,7 @@ export default {
outline: colors.blue[400],
text: colors.blue[950],
fill: {
solid: colors.blue[600],
solid: colors.blue[700],
outline: colors.blue[600],
text: colors.white,
},
Expand Down

[8]ページ先頭

©2009-2025 Movatter.jp