mirror of https://github.com/coder/coder.git
feat!: move workspace renames behind flag, disable by default (#11189)
This commit is contained in:
parent
e63de9a259
commit
7924bb2a56
|
@ -15,7 +15,7 @@ import (
|
|||
func TestRename(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
|
||||
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true, AllowWorkspaceRenames: true})
|
||||
owner := coderdtest.CreateFirstUser(t, client)
|
||||
member, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, nil)
|
||||
|
|
|
@ -583,6 +583,7 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
|
|||
HostnamePrefix: vals.SSHConfig.DeploymentName.String(),
|
||||
SSHConfigOptions: configSSHOptions,
|
||||
},
|
||||
AllowWorkspaceRenames: vals.AllowWorkspaceRenames.Value(),
|
||||
}
|
||||
if httpServers.TLSConfig != nil {
|
||||
options.TLSCertificates = httpServers.TLSConfig.Certificates
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
"healthy": true,
|
||||
"failing_agents": []
|
||||
},
|
||||
"automatic_updates": "never"
|
||||
"automatic_updates": "never",
|
||||
"allow_renames": false
|
||||
}
|
||||
]
|
||||
|
|
|
@ -14,6 +14,11 @@ SUBCOMMANDS:
|
|||
PostgreSQL deployment.
|
||||
|
||||
OPTIONS:
|
||||
--allow-workspace-renames bool, $CODER_ALLOW_WORKSPACE_RENAMES (default: false)
|
||||
DEPRECATED: Allow users to rename their workspaces. Use only for
|
||||
temporary compatibility reasons, this will be removed in a future
|
||||
release.
|
||||
|
||||
--cache-dir string, $CODER_CACHE_DIRECTORY (default: [cache dir])
|
||||
The directory to cache temporary files. If unspecified and
|
||||
$CACHE_DIRECTORY is set, it will be used for compatibility with
|
||||
|
|
|
@ -462,3 +462,7 @@ userQuietHoursSchedule:
|
|||
# change their quiet hours schedule and the site default is always used.
|
||||
# (default: true, type: bool)
|
||||
allowCustomQuietHours: true
|
||||
# DEPRECATED: Allow users to rename their workspaces. Use only for temporary
|
||||
# compatibility reasons, this will be removed in a future release.
|
||||
# (default: false, type: bool)
|
||||
allowWorkspaceRenames: false
|
||||
|
|
|
@ -8558,6 +8558,9 @@ const docTemplate = `{
|
|||
"agent_stat_refresh_interval": {
|
||||
"type": "integer"
|
||||
},
|
||||
"allow_workspace_renames": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"autobuild_poll_interval": {
|
||||
"type": "integer"
|
||||
},
|
||||
|
@ -11443,6 +11446,9 @@ const docTemplate = `{
|
|||
"codersdk.Workspace": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"allow_renames": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"automatic_updates": {
|
||||
"enum": [
|
||||
"always",
|
||||
|
|
|
@ -7642,6 +7642,9 @@
|
|||
"agent_stat_refresh_interval": {
|
||||
"type": "integer"
|
||||
},
|
||||
"allow_workspace_renames": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"autobuild_poll_interval": {
|
||||
"type": "integer"
|
||||
},
|
||||
|
@ -10372,6 +10375,9 @@
|
|||
"codersdk.Workspace": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"allow_renames": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"automatic_updates": {
|
||||
"enum": ["always", "never"],
|
||||
"allOf": [
|
||||
|
|
|
@ -179,7 +179,8 @@ type Options struct {
|
|||
// This janky function is used in telemetry to parse fields out of the raw
|
||||
// JWT. It needs to be passed through like this because license parsing is
|
||||
// under the enterprise license, and can't be imported into AGPL.
|
||||
ParseLicenseClaims func(rawJWT string) (email string, trial bool, err error)
|
||||
ParseLicenseClaims func(rawJWT string) (email string, trial bool, err error)
|
||||
AllowWorkspaceRenames bool
|
||||
}
|
||||
|
||||
// @title Coder API
|
||||
|
|
|
@ -144,6 +144,7 @@ type Options struct {
|
|||
StatsBatcher *batchstats.Batcher
|
||||
|
||||
WorkspaceAppsStatsCollectorOptions workspaceapps.StatsCollectorOptions
|
||||
AllowWorkspaceRenames bool
|
||||
}
|
||||
|
||||
// New constructs a codersdk client connected to an in-memory API instance.
|
||||
|
@ -449,6 +450,7 @@ func NewOptions(t testing.TB, options *Options) (func(http.Handler), context.Can
|
|||
HealthcheckRefresh: options.HealthcheckRefresh,
|
||||
StatsBatcher: options.StatsBatcher,
|
||||
WorkspaceAppsStatsCollectorOptions: options.WorkspaceAppsStatsCollectorOptions,
|
||||
AllowWorkspaceRenames: options.AllowWorkspaceRenames,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -106,6 +106,7 @@ func (api *API) workspace(rw http.ResponseWriter, r *http.Request) {
|
|||
data.builds[0],
|
||||
data.templates[0],
|
||||
ownerName,
|
||||
api.Options.AllowWorkspaceRenames,
|
||||
))
|
||||
}
|
||||
|
||||
|
@ -277,6 +278,7 @@ func (api *API) workspaceByOwnerAndName(rw http.ResponseWriter, r *http.Request)
|
|||
data.builds[0],
|
||||
data.templates[0],
|
||||
ownerName,
|
||||
api.Options.AllowWorkspaceRenames,
|
||||
))
|
||||
}
|
||||
|
||||
|
@ -585,6 +587,7 @@ func (api *API) postWorkspacesByOrganization(rw http.ResponseWriter, r *http.Req
|
|||
apiBuild,
|
||||
template,
|
||||
member.Username,
|
||||
api.Options.AllowWorkspaceRenames,
|
||||
))
|
||||
}
|
||||
|
||||
|
@ -628,6 +631,12 @@ func (api *API) patchWorkspace(rw http.ResponseWriter, r *http.Request) {
|
|||
// patched in the future, it's enough if one changes.
|
||||
name := workspace.Name
|
||||
if req.Name != "" || req.Name != workspace.Name {
|
||||
if !api.Options.AllowWorkspaceRenames {
|
||||
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
|
||||
Message: "Workspace renames are not allowed.",
|
||||
})
|
||||
return
|
||||
}
|
||||
name = req.Name
|
||||
}
|
||||
|
||||
|
@ -917,6 +926,7 @@ func (api *API) putWorkspaceDormant(rw http.ResponseWriter, r *http.Request) {
|
|||
data.builds[0],
|
||||
data.templates[0],
|
||||
ownerName,
|
||||
api.Options.AllowWorkspaceRenames,
|
||||
))
|
||||
}
|
||||
|
||||
|
@ -1242,6 +1252,7 @@ func (api *API) watchWorkspace(rw http.ResponseWriter, r *http.Request) {
|
|||
data.builds[0],
|
||||
data.templates[0],
|
||||
ownerName,
|
||||
api.Options.AllowWorkspaceRenames,
|
||||
),
|
||||
})
|
||||
}
|
||||
|
@ -1293,9 +1304,10 @@ func (api *API) watchWorkspace(rw http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
type workspaceData struct {
|
||||
templates []database.Template
|
||||
builds []codersdk.WorkspaceBuild
|
||||
users []database.User
|
||||
templates []database.Template
|
||||
builds []codersdk.WorkspaceBuild
|
||||
users []database.User
|
||||
allowRenames bool
|
||||
}
|
||||
|
||||
// workspacesData only returns the data the caller can access. If the caller
|
||||
|
@ -1347,9 +1359,10 @@ func (api *API) workspaceData(ctx context.Context, workspaces []database.Workspa
|
|||
}
|
||||
|
||||
return workspaceData{
|
||||
templates: templates,
|
||||
builds: apiBuilds,
|
||||
users: data.users,
|
||||
templates: templates,
|
||||
builds: apiBuilds,
|
||||
users: data.users,
|
||||
allowRenames: api.Options.AllowWorkspaceRenames,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -1392,6 +1405,7 @@ func convertWorkspaces(workspaces []database.Workspace, data workspaceData) ([]c
|
|||
build,
|
||||
template,
|
||||
owner.Username,
|
||||
data.allowRenames,
|
||||
))
|
||||
}
|
||||
return apiWorkspaces, nil
|
||||
|
@ -1402,6 +1416,7 @@ func convertWorkspace(
|
|||
workspaceBuild codersdk.WorkspaceBuild,
|
||||
template database.Template,
|
||||
ownerName string,
|
||||
allowRenames bool,
|
||||
) codersdk.Workspace {
|
||||
var autostartSchedule *string
|
||||
if workspace.AutostartSchedule.Valid {
|
||||
|
@ -1456,6 +1471,7 @@ func convertWorkspace(
|
|||
FailingAgents: failingAgents,
|
||||
},
|
||||
AutomaticUpdates: codersdk.AutomaticUpdates(workspace.AutomaticUpdates),
|
||||
AllowRenames: allowRenames,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -100,7 +100,10 @@ func TestWorkspace(t *testing.T) {
|
|||
|
||||
t.Run("Rename", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
|
||||
client := coderdtest.New(t, &coderdtest.Options{
|
||||
IncludeProvisionerDaemon: true,
|
||||
AllowWorkspaceRenames: true,
|
||||
})
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
|
||||
|
@ -134,6 +137,29 @@ func TestWorkspace(t *testing.T) {
|
|||
require.Error(t, err, "workspace rename should have failed")
|
||||
})
|
||||
|
||||
t.Run("RenameDisabled", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, &coderdtest.Options{
|
||||
IncludeProvisionerDaemon: true,
|
||||
AllowWorkspaceRenames: false,
|
||||
})
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
ws1 := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID)
|
||||
coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, ws1.LatestBuild.ID)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitMedium)
|
||||
defer cancel()
|
||||
|
||||
want := "new-name"
|
||||
err := client.UpdateWorkspace(ctx, ws1.ID, codersdk.UpdateWorkspaceRequest{
|
||||
Name: want,
|
||||
})
|
||||
require.ErrorContains(t, err, "Workspace renames are not allowed")
|
||||
})
|
||||
|
||||
t.Run("TemplateProperties", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
|
||||
|
@ -2152,7 +2178,10 @@ func TestUpdateWorkspaceAutomaticUpdates_NotFound(t *testing.T) {
|
|||
|
||||
func TestWorkspaceWatcher(t *testing.T) {
|
||||
t.Parallel()
|
||||
client, closeFunc := coderdtest.NewWithProvisionerCloser(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
|
||||
client, closeFunc := coderdtest.NewWithProvisionerCloser(t, &coderdtest.Options{
|
||||
IncludeProvisionerDaemon: true,
|
||||
AllowWorkspaceRenames: true,
|
||||
})
|
||||
defer closeFunc.Close()
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
authToken := uuid.NewString()
|
||||
|
|
|
@ -181,6 +181,7 @@ type DeploymentValues struct {
|
|||
EnableTerraformDebugMode clibase.Bool `json:"enable_terraform_debug_mode,omitempty" typescript:",notnull"`
|
||||
UserQuietHoursSchedule UserQuietHoursScheduleConfig `json:"user_quiet_hours_schedule,omitempty" typescript:",notnull"`
|
||||
WebTerminalRenderer clibase.String `json:"web_terminal_renderer,omitempty" typescript:",notnull"`
|
||||
AllowWorkspaceRenames clibase.Bool `json:"allow_workspace_renames,omitempty" typescript:",notnull"`
|
||||
Healthcheck HealthcheckConfig `json:"healthcheck,omitempty" typescript:",notnull"`
|
||||
|
||||
Config clibase.YAMLConfigPath `json:"config,omitempty" typescript:",notnull"`
|
||||
|
@ -1842,6 +1843,15 @@ Write out the current server config as YAML to stdout.`,
|
|||
Group: &deploymentGroupClient,
|
||||
YAML: "webTerminalRenderer",
|
||||
},
|
||||
{
|
||||
Name: "Allow Workspace Renames",
|
||||
Description: "DEPRECATED: Allow users to rename their workspaces. Use only for temporary compatibility reasons, this will be removed in a future release.",
|
||||
Flag: "allow-workspace-renames",
|
||||
Env: "CODER_ALLOW_WORKSPACE_RENAMES",
|
||||
Default: "false",
|
||||
Value: &c.AllowWorkspaceRenames,
|
||||
YAML: "allowWorkspaceRenames",
|
||||
},
|
||||
// Healthcheck Options
|
||||
{
|
||||
Name: "Health Check Refresh",
|
||||
|
|
|
@ -57,6 +57,7 @@ type Workspace struct {
|
|||
// what is causing an unhealthy status.
|
||||
Health WorkspaceHealth `json:"health"`
|
||||
AutomaticUpdates AutomaticUpdates `json:"automatic_updates" enums:"always,never"`
|
||||
AllowRenames bool `json:"allow_renames"`
|
||||
}
|
||||
|
||||
func (w Workspace) FullName() string {
|
||||
|
|
|
@ -153,6 +153,7 @@ curl -X GET http://coder-server:8080/api/v2/deployment/config \
|
|||
"user": {}
|
||||
},
|
||||
"agent_stat_refresh_interval": 0,
|
||||
"allow_workspace_renames": true,
|
||||
"autobuild_poll_interval": 0,
|
||||
"browser_only": true,
|
||||
"cache_directory": "string",
|
||||
|
|
|
@ -2083,6 +2083,7 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in
|
|||
"user": {}
|
||||
},
|
||||
"agent_stat_refresh_interval": 0,
|
||||
"allow_workspace_renames": true,
|
||||
"autobuild_poll_interval": 0,
|
||||
"browser_only": true,
|
||||
"cache_directory": "string",
|
||||
|
@ -2460,6 +2461,7 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in
|
|||
"user": {}
|
||||
},
|
||||
"agent_stat_refresh_interval": 0,
|
||||
"allow_workspace_renames": true,
|
||||
"autobuild_poll_interval": 0,
|
||||
"browser_only": true,
|
||||
"cache_directory": "string",
|
||||
|
@ -2732,6 +2734,7 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in
|
|||
| `address` | [clibase.HostPort](#clibasehostport) | false | | Address Use HTTPAddress or TLS.Address instead. |
|
||||
| `agent_fallback_troubleshooting_url` | [clibase.URL](#clibaseurl) | false | | |
|
||||
| `agent_stat_refresh_interval` | integer | false | | |
|
||||
| `allow_workspace_renames` | boolean | false | | |
|
||||
| `autobuild_poll_interval` | integer | false | | |
|
||||
| `browser_only` | boolean | false | | |
|
||||
| `cache_directory` | string | false | | |
|
||||
|
@ -5764,6 +5767,7 @@ If the schedule is empty, the user will be updated to use the default schedule.|
|
|||
|
||||
```json
|
||||
{
|
||||
"allow_renames": true,
|
||||
"automatic_updates": "always",
|
||||
"autostart_schedule": "string",
|
||||
"created_at": "2019-08-24T14:15:22Z",
|
||||
|
@ -5943,6 +5947,7 @@ If the schedule is empty, the user will be updated to use the default schedule.|
|
|||
|
||||
| Name | Type | Required | Restrictions | Description |
|
||||
| ------------------------------------------- | ------------------------------------------------------ | -------- | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `allow_renames` | boolean | false | | |
|
||||
| `automatic_updates` | [codersdk.AutomaticUpdates](#codersdkautomaticupdates) | false | | |
|
||||
| `autostart_schedule` | string | false | | |
|
||||
| `created_at` | string | false | | |
|
||||
|
@ -7025,6 +7030,7 @@ If the schedule is empty, the user will be updated to use the default schedule.|
|
|||
"count": 0,
|
||||
"workspaces": [
|
||||
{
|
||||
"allow_renames": true,
|
||||
"automatic_updates": "always",
|
||||
"autostart_schedule": "string",
|
||||
"created_at": "2019-08-24T14:15:22Z",
|
||||
|
|
|
@ -47,6 +47,7 @@ curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/member
|
|||
|
||||
```json
|
||||
{
|
||||
"allow_renames": true,
|
||||
"automatic_updates": "always",
|
||||
"autostart_schedule": "string",
|
||||
"created_at": "2019-08-24T14:15:22Z",
|
||||
|
@ -257,6 +258,7 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/workspace/{workspacenam
|
|||
|
||||
```json
|
||||
{
|
||||
"allow_renames": true,
|
||||
"automatic_updates": "always",
|
||||
"autostart_schedule": "string",
|
||||
"created_at": "2019-08-24T14:15:22Z",
|
||||
|
@ -470,6 +472,7 @@ curl -X GET http://coder-server:8080/api/v2/workspaces \
|
|||
"count": 0,
|
||||
"workspaces": [
|
||||
{
|
||||
"allow_renames": true,
|
||||
"automatic_updates": "always",
|
||||
"autostart_schedule": "string",
|
||||
"created_at": "2019-08-24T14:15:22Z",
|
||||
|
@ -677,6 +680,7 @@ curl -X GET http://coder-server:8080/api/v2/workspaces/{workspace} \
|
|||
|
||||
```json
|
||||
{
|
||||
"allow_renames": true,
|
||||
"automatic_updates": "always",
|
||||
"autostart_schedule": "string",
|
||||
"created_at": "2019-08-24T14:15:22Z",
|
||||
|
@ -1003,6 +1007,7 @@ curl -X PUT http://coder-server:8080/api/v2/workspaces/{workspace}/dormant \
|
|||
|
||||
```json
|
||||
{
|
||||
"allow_renames": true,
|
||||
"automatic_updates": "always",
|
||||
"autostart_schedule": "string",
|
||||
"created_at": "2019-08-24T14:15:22Z",
|
||||
|
|
|
@ -42,6 +42,17 @@ The URL that users will use to access the Coder deployment.
|
|||
|
||||
Allow users to set their own quiet hours schedule for workspaces to stop in (depending on template autostop requirement settings). If false, users can't change their quiet hours schedule and the site default is always used.
|
||||
|
||||
### --allow-workspace-renames
|
||||
|
||||
| | |
|
||||
| ----------- | ------------------------------------------- |
|
||||
| Type | <code>bool</code> |
|
||||
| Environment | <code>$CODER_ALLOW_WORKSPACE_RENAMES</code> |
|
||||
| YAML | <code>allowWorkspaceRenames</code> |
|
||||
| Default | <code>false</code> |
|
||||
|
||||
DEPRECATED: Allow users to rename their workspaces. Use only for temporary compatibility reasons, this will be removed in a future release.
|
||||
|
||||
### --block-direct-connections
|
||||
|
||||
| | |
|
||||
|
|
|
@ -15,6 +15,11 @@ SUBCOMMANDS:
|
|||
PostgreSQL deployment.
|
||||
|
||||
OPTIONS:
|
||||
--allow-workspace-renames bool, $CODER_ALLOW_WORKSPACE_RENAMES (default: false)
|
||||
DEPRECATED: Allow users to rename their workspaces. Use only for
|
||||
temporary compatibility reasons, this will be removed in a future
|
||||
release.
|
||||
|
||||
--cache-dir string, $CODER_CACHE_DIRECTORY (default: [cache dir])
|
||||
The directory to cache temporary files. If unspecified and
|
||||
$CACHE_DIRECTORY is set, it will be used for compatibility with
|
||||
|
|
|
@ -424,6 +424,7 @@ export interface DeploymentValues {
|
|||
readonly enable_terraform_debug_mode?: boolean;
|
||||
readonly user_quiet_hours_schedule?: UserQuietHoursScheduleConfig;
|
||||
readonly web_terminal_renderer?: string;
|
||||
readonly allow_workspace_renames?: boolean;
|
||||
readonly healthcheck?: HealthcheckConfig;
|
||||
readonly config?: string;
|
||||
readonly write_config?: boolean;
|
||||
|
@ -1429,6 +1430,7 @@ export interface Workspace {
|
|||
readonly dormant_at?: string;
|
||||
readonly health: WorkspaceHealth;
|
||||
readonly automatic_updates: AutomaticUpdates;
|
||||
readonly allow_renames: boolean;
|
||||
}
|
||||
|
||||
// From codersdk/workspaceagents.go
|
||||
|
|
|
@ -18,9 +18,9 @@ import {
|
|||
AutomaticUpdateses,
|
||||
Workspace,
|
||||
} from "api/typesGenerated";
|
||||
import { Alert } from "components/Alert/Alert";
|
||||
import MenuItem from "@mui/material/MenuItem";
|
||||
import upperFirst from "lodash/upperFirst";
|
||||
import { type Theme } from "@emotion/react";
|
||||
|
||||
export type WorkspaceSettingsFormValues = {
|
||||
name: string;
|
||||
|
@ -34,6 +34,10 @@ export const WorkspaceSettingsForm: FC<{
|
|||
onCancel: () => void;
|
||||
onSubmit: (values: WorkspaceSettingsFormValues) => Promise<void>;
|
||||
}> = ({ onCancel, onSubmit, workspace, error, templatePoliciesEnabled }) => {
|
||||
const formEnabled =
|
||||
(templatePoliciesEnabled && !workspace.template_require_active_version) ||
|
||||
workspace.allow_renames;
|
||||
|
||||
const form = useFormik<WorkspaceSettingsFormValues>({
|
||||
onSubmit,
|
||||
initialValues: {
|
||||
|
@ -59,18 +63,19 @@ export const WorkspaceSettingsForm: FC<{
|
|||
<FormFields>
|
||||
<TextField
|
||||
{...getFieldHelpers("name")}
|
||||
disabled={form.isSubmitting}
|
||||
disabled={!workspace.allow_renames || form.isSubmitting}
|
||||
onChange={onChangeTrimmed(form)}
|
||||
autoFocus
|
||||
fullWidth
|
||||
label="Name"
|
||||
css={workspace.allow_renames && styles.nameWarning}
|
||||
helperText={
|
||||
workspace.allow_renames
|
||||
? form.values.name !== form.initialValues.name &&
|
||||
"Depending on the template, renaming your workspace may be destructive"
|
||||
: "Renaming your workspace can be destructive and has not been enabled for this deployment."
|
||||
}
|
||||
/>
|
||||
{form.values.name !== form.initialValues.name && (
|
||||
<Alert severity="warning">
|
||||
Depending on the template, renaming your workspace may be
|
||||
destructive
|
||||
</Alert>
|
||||
)}
|
||||
</FormFields>
|
||||
</FormSection>
|
||||
{templatePoliciesEnabled && (
|
||||
|
@ -106,7 +111,17 @@ export const WorkspaceSettingsForm: FC<{
|
|||
</FormFields>
|
||||
</FormSection>
|
||||
)}
|
||||
<FormFooter onCancel={onCancel} isLoading={form.isSubmitting} />
|
||||
{formEnabled && (
|
||||
<FormFooter onCancel={onCancel} isLoading={form.isSubmitting} />
|
||||
)}
|
||||
</HorizontalForm>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = {
|
||||
nameWarning: (theme: Theme) => ({
|
||||
"& .MuiFormHelperText-root": {
|
||||
color: theme.palette.warning.light,
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
|
|
@ -12,7 +12,7 @@ test("Submit the workspace settings page successfully", async () => {
|
|||
// Mock the API calls that loads data
|
||||
jest
|
||||
.spyOn(api, "getWorkspaceByOwnerAndName")
|
||||
.mockResolvedValueOnce(MockWorkspace);
|
||||
.mockResolvedValueOnce({ ...MockWorkspace });
|
||||
// Mock the API calls that submit data
|
||||
const patchWorkspaceSpy = jest
|
||||
.spyOn(api, "patchWorkspace")
|
||||
|
@ -39,3 +39,21 @@ test("Submit the workspace settings page successfully", async () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
test("Name field is disabled if renames are disabled", async () => {
|
||||
// Mock the API calls that loads data
|
||||
jest
|
||||
.spyOn(api, "getWorkspaceByOwnerAndName")
|
||||
.mockResolvedValueOnce({ ...MockWorkspace, allow_renames: false });
|
||||
renderWithWorkspaceSettingsLayout(<WorkspaceSettingsPage />, {
|
||||
route: "/@test-user/test-workspace/settings",
|
||||
path: "/:username/:workspace/settings",
|
||||
// Need this because after submit the user is redirected
|
||||
extraRoutes: [{ path: "/:username/:workspace", element: <div /> }],
|
||||
});
|
||||
await waitForLoaderToBeRemoved();
|
||||
// Fill the form and submit
|
||||
const form = screen.getByTestId("form");
|
||||
const name = within(form).getByLabelText("Name");
|
||||
expect(name).toBeDisabled();
|
||||
});
|
||||
|
|
|
@ -21,3 +21,9 @@ export const AutoUpdates: Story = {
|
|||
templatePoliciesEnabled: true,
|
||||
},
|
||||
};
|
||||
|
||||
export const RenamesDisabled: Story = {
|
||||
args: {
|
||||
workspace: { ...MockWorkspace, allow_renames: false },
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1006,6 +1006,7 @@ export const MockWorkspace: TypesGen.Workspace = {
|
|||
failing_agents: [],
|
||||
},
|
||||
automatic_updates: "never",
|
||||
allow_renames: true,
|
||||
};
|
||||
|
||||
export const MockStoppedWorkspace: TypesGen.Workspace = {
|
||||
|
|
Loading…
Reference in New Issue