mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
chore: move Shared Workspaces from experiments to beta (#22206)
* Removed the shared-workspaces experiment and cleaned up related middleware * Added beta tagging to the UI for shared workspaces
This commit is contained in:
+1
-5
@@ -106,11 +106,7 @@ func TestList(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var (
|
||||
client, db = coderdtest.NewWithDatabase(t, &coderdtest.Options{
|
||||
DeploymentValues: coderdtest.DeploymentValues(t, func(dv *codersdk.DeploymentValues) {
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
}),
|
||||
})
|
||||
client, db = coderdtest.NewWithDatabase(t, nil)
|
||||
orgOwner = coderdtest.CreateFirstUser(t, client)
|
||||
memberClient, member = coderdtest.CreateAnotherUser(t, client, orgOwner.OrganizationID, rbac.ScopedRoleOrgAuditor(orgOwner.OrganizationID))
|
||||
sharedWorkspace = dbfake.WorkspaceBuild(t, db, database.WorkspaceTable{
|
||||
|
||||
+7
-31
@@ -25,11 +25,7 @@ func TestSharingShare(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var (
|
||||
client, db = coderdtest.NewWithDatabase(t, &coderdtest.Options{
|
||||
DeploymentValues: coderdtest.DeploymentValues(t, func(dv *codersdk.DeploymentValues) {
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
}),
|
||||
})
|
||||
client, db = coderdtest.NewWithDatabase(t, nil)
|
||||
orgOwner = coderdtest.CreateFirstUser(t, client)
|
||||
workspaceOwnerClient, workspaceOwner = coderdtest.CreateAnotherUser(t, client, orgOwner.OrganizationID, rbac.ScopedRoleOrgAuditor(orgOwner.OrganizationID))
|
||||
workspace = dbfake.WorkspaceBuild(t, db, database.WorkspaceTable{
|
||||
@@ -68,12 +64,8 @@ func TestSharingShare(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var (
|
||||
client, db = coderdtest.NewWithDatabase(t, &coderdtest.Options{
|
||||
DeploymentValues: coderdtest.DeploymentValues(t, func(dv *codersdk.DeploymentValues) {
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
}),
|
||||
})
|
||||
orgOwner = coderdtest.CreateFirstUser(t, client)
|
||||
client, db = coderdtest.NewWithDatabase(t, nil)
|
||||
orgOwner = coderdtest.CreateFirstUser(t, client)
|
||||
|
||||
workspaceOwnerClient, workspaceOwner = coderdtest.CreateAnotherUser(t, client, orgOwner.OrganizationID, rbac.ScopedRoleOrgAuditor(orgOwner.OrganizationID))
|
||||
workspace = dbfake.WorkspaceBuild(t, db, database.WorkspaceTable{
|
||||
@@ -127,11 +119,7 @@ func TestSharingShare(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var (
|
||||
client, db = coderdtest.NewWithDatabase(t, &coderdtest.Options{
|
||||
DeploymentValues: coderdtest.DeploymentValues(t, func(dv *codersdk.DeploymentValues) {
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
}),
|
||||
})
|
||||
client, db = coderdtest.NewWithDatabase(t, nil)
|
||||
orgOwner = coderdtest.CreateFirstUser(t, client)
|
||||
workspaceOwnerClient, workspaceOwner = coderdtest.CreateAnotherUser(t, client, orgOwner.OrganizationID, rbac.ScopedRoleOrgAuditor(orgOwner.OrganizationID))
|
||||
workspace = dbfake.WorkspaceBuild(t, db, database.WorkspaceTable{
|
||||
@@ -182,11 +170,7 @@ func TestSharingStatus(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var (
|
||||
client, db = coderdtest.NewWithDatabase(t, &coderdtest.Options{
|
||||
DeploymentValues: coderdtest.DeploymentValues(t, func(dv *codersdk.DeploymentValues) {
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
}),
|
||||
})
|
||||
client, db = coderdtest.NewWithDatabase(t, nil)
|
||||
orgOwner = coderdtest.CreateFirstUser(t, client)
|
||||
workspaceOwnerClient, workspaceOwner = coderdtest.CreateAnotherUser(t, client, orgOwner.OrganizationID, rbac.ScopedRoleOrgAuditor(orgOwner.OrganizationID))
|
||||
workspace = dbfake.WorkspaceBuild(t, db, database.WorkspaceTable{
|
||||
@@ -230,11 +214,7 @@ func TestSharingRemove(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var (
|
||||
client, db = coderdtest.NewWithDatabase(t, &coderdtest.Options{
|
||||
DeploymentValues: coderdtest.DeploymentValues(t, func(dv *codersdk.DeploymentValues) {
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
}),
|
||||
})
|
||||
client, db = coderdtest.NewWithDatabase(t, nil)
|
||||
orgOwner = coderdtest.CreateFirstUser(t, client)
|
||||
workspaceOwnerClient, workspaceOwner = coderdtest.CreateAnotherUser(t, client, orgOwner.OrganizationID, rbac.ScopedRoleOrgAuditor(orgOwner.OrganizationID))
|
||||
workspace = dbfake.WorkspaceBuild(t, db, database.WorkspaceTable{
|
||||
@@ -291,11 +271,7 @@ func TestSharingRemove(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var (
|
||||
client, db = coderdtest.NewWithDatabase(t, &coderdtest.Options{
|
||||
DeploymentValues: coderdtest.DeploymentValues(t, func(dv *codersdk.DeploymentValues) {
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
}),
|
||||
})
|
||||
client, db = coderdtest.NewWithDatabase(t, nil)
|
||||
orgOwner = coderdtest.CreateFirstUser(t, client)
|
||||
workspaceOwnerClient, workspaceOwner = coderdtest.CreateAnotherUser(t, client, orgOwner.OrganizationID, rbac.ScopedRoleOrgAuditor(orgOwner.OrganizationID))
|
||||
workspace = dbfake.WorkspaceBuild(t, db, database.WorkspaceTable{
|
||||
|
||||
+3
-4
@@ -49,10 +49,9 @@ OPTIONS:
|
||||
security purposes if a --wildcard-access-url is configured.
|
||||
|
||||
--disable-workspace-sharing bool, $CODER_DISABLE_WORKSPACE_SHARING
|
||||
Disable workspace sharing (requires the "workspace-sharing" experiment
|
||||
to be enabled). Workspace ACL checking is disabled and only owners can
|
||||
have ssh, apps and terminal access to workspaces. Access based on the
|
||||
'owner' role is also allowed unless disabled via
|
||||
Disable workspace sharing. Workspace ACL checking is disabled and only
|
||||
owners can have ssh, apps and terminal access to workspaces. Access
|
||||
based on the 'owner' role is also allowed unless disabled via
|
||||
--disable-owner-workspace-access.
|
||||
|
||||
--swagger-enable bool, $CODER_SWAGGER_ENABLE
|
||||
|
||||
+4
-4
@@ -523,10 +523,10 @@ disablePathApps: false
|
||||
# workspaces.
|
||||
# (default: <unset>, type: bool)
|
||||
disableOwnerWorkspaceAccess: false
|
||||
# Disable workspace sharing (requires the "workspace-sharing" experiment to be
|
||||
# enabled). Workspace ACL checking is disabled and only owners can have ssh, apps
|
||||
# and terminal access to workspaces. Access based on the 'owner' role is also
|
||||
# allowed unless disabled via --disable-owner-workspace-access.
|
||||
# Disable workspace sharing. Workspace ACL checking is disabled and only owners
|
||||
# can have ssh, apps and terminal access to workspaces. Access based on the
|
||||
# 'owner' role is also allowed unless disabled via
|
||||
# --disable-owner-workspace-access.
|
||||
# (default: <unset>, type: bool)
|
||||
disableWorkspaceSharing: false
|
||||
# These options change the behavior of how clients interact with the Coder.
|
||||
|
||||
@@ -466,7 +466,6 @@ func (api *API) convertTasks(ctx context.Context, requesterID uuid.UUID, dbTasks
|
||||
|
||||
apiWorkspaces, err := convertWorkspaces(
|
||||
ctx,
|
||||
api.Experiments,
|
||||
api.Logger,
|
||||
requesterID,
|
||||
workspaces,
|
||||
@@ -546,7 +545,6 @@ func (api *API) taskGet(rw http.ResponseWriter, r *http.Request) {
|
||||
|
||||
ws, err := convertWorkspace(
|
||||
ctx,
|
||||
api.Experiments,
|
||||
api.Logger,
|
||||
apiKey.UserID,
|
||||
workspace,
|
||||
|
||||
Generated
+3
-7
@@ -15097,8 +15097,7 @@ const docTemplate = `{
|
||||
"workspace-usage",
|
||||
"web-push",
|
||||
"oauth2",
|
||||
"mcp-server-http",
|
||||
"workspace-sharing"
|
||||
"mcp-server-http"
|
||||
],
|
||||
"x-enum-comments": {
|
||||
"ExperimentAutoFillParameters": "This should not be taken out of experiments until we have redesigned the feature.",
|
||||
@@ -15107,7 +15106,6 @@ const docTemplate = `{
|
||||
"ExperimentNotifications": "Sends notifications via SMTP and webhooks following certain events.",
|
||||
"ExperimentOAuth2": "Enables OAuth2 provider functionality.",
|
||||
"ExperimentWebPush": "Enables web push notifications through the browser.",
|
||||
"ExperimentWorkspaceSharing": "Enables updating workspace ACLs for sharing with users and groups.",
|
||||
"ExperimentWorkspaceUsage": "Enables the new workspace usage tracking."
|
||||
},
|
||||
"x-enum-descriptions": [
|
||||
@@ -15117,8 +15115,7 @@ const docTemplate = `{
|
||||
"Enables the new workspace usage tracking.",
|
||||
"Enables web push notifications through the browser.",
|
||||
"Enables OAuth2 provider functionality.",
|
||||
"Enables the MCP HTTP server functionality.",
|
||||
"Enables updating workspace ACLs for sharing with users and groups."
|
||||
"Enables the MCP HTTP server functionality."
|
||||
],
|
||||
"x-enum-varnames": [
|
||||
"ExperimentExample",
|
||||
@@ -15127,8 +15124,7 @@ const docTemplate = `{
|
||||
"ExperimentWorkspaceUsage",
|
||||
"ExperimentWebPush",
|
||||
"ExperimentOAuth2",
|
||||
"ExperimentMCPServerHTTP",
|
||||
"ExperimentWorkspaceSharing"
|
||||
"ExperimentMCPServerHTTP"
|
||||
]
|
||||
},
|
||||
"codersdk.ExternalAPIKeyScopes": {
|
||||
|
||||
Generated
+3
-7
@@ -13624,8 +13624,7 @@
|
||||
"workspace-usage",
|
||||
"web-push",
|
||||
"oauth2",
|
||||
"mcp-server-http",
|
||||
"workspace-sharing"
|
||||
"mcp-server-http"
|
||||
],
|
||||
"x-enum-comments": {
|
||||
"ExperimentAutoFillParameters": "This should not be taken out of experiments until we have redesigned the feature.",
|
||||
@@ -13634,7 +13633,6 @@
|
||||
"ExperimentNotifications": "Sends notifications via SMTP and webhooks following certain events.",
|
||||
"ExperimentOAuth2": "Enables OAuth2 provider functionality.",
|
||||
"ExperimentWebPush": "Enables web push notifications through the browser.",
|
||||
"ExperimentWorkspaceSharing": "Enables updating workspace ACLs for sharing with users and groups.",
|
||||
"ExperimentWorkspaceUsage": "Enables the new workspace usage tracking."
|
||||
},
|
||||
"x-enum-descriptions": [
|
||||
@@ -13644,8 +13642,7 @@
|
||||
"Enables the new workspace usage tracking.",
|
||||
"Enables web push notifications through the browser.",
|
||||
"Enables OAuth2 provider functionality.",
|
||||
"Enables the MCP HTTP server functionality.",
|
||||
"Enables updating workspace ACLs for sharing with users and groups."
|
||||
"Enables the MCP HTTP server functionality."
|
||||
],
|
||||
"x-enum-varnames": [
|
||||
"ExperimentExample",
|
||||
@@ -13654,8 +13651,7 @@
|
||||
"ExperimentWorkspaceUsage",
|
||||
"ExperimentWebPush",
|
||||
"ExperimentOAuth2",
|
||||
"ExperimentMCPServerHTTP",
|
||||
"ExperimentWorkspaceSharing"
|
||||
"ExperimentMCPServerHTTP"
|
||||
]
|
||||
},
|
||||
"codersdk.ExternalAPIKeyScopes": {
|
||||
|
||||
@@ -1526,10 +1526,6 @@ func New(options *Options) *API {
|
||||
})
|
||||
r.Get("/timings", api.workspaceTimings)
|
||||
r.Route("/acl", func(r chi.Router) {
|
||||
r.Use(
|
||||
httpmw.RequireExperiment(api.Experiments, codersdk.ExperimentWorkspaceSharing),
|
||||
)
|
||||
|
||||
r.Get("/", api.workspaceACL)
|
||||
r.Patch("/", api.patchWorkspaceACL)
|
||||
r.Delete("/", api.deleteWorkspaceACL)
|
||||
|
||||
+2
-17
@@ -114,7 +114,6 @@ func (api *API) workspace(rw http.ResponseWriter, r *http.Request) {
|
||||
|
||||
w, err := convertWorkspace(
|
||||
ctx,
|
||||
api.Experiments,
|
||||
api.Logger,
|
||||
apiKey.UserID,
|
||||
workspace,
|
||||
@@ -240,7 +239,6 @@ func (api *API) workspaces(rw http.ResponseWriter, r *http.Request) {
|
||||
|
||||
wss, err := convertWorkspaces(
|
||||
ctx,
|
||||
api.Experiments,
|
||||
api.Logger,
|
||||
apiKey.UserID,
|
||||
workspaces,
|
||||
@@ -336,7 +334,6 @@ func (api *API) workspaceByOwnerAndName(rw http.ResponseWriter, r *http.Request)
|
||||
|
||||
w, err := convertWorkspace(
|
||||
ctx,
|
||||
api.Experiments,
|
||||
api.Logger,
|
||||
apiKey.UserID,
|
||||
workspace,
|
||||
@@ -868,7 +865,6 @@ func createWorkspace(
|
||||
|
||||
w, err := convertWorkspace(
|
||||
ctx,
|
||||
api.Experiments,
|
||||
api.Logger,
|
||||
initiatorID,
|
||||
workspace,
|
||||
@@ -1514,7 +1510,6 @@ func (api *API) putWorkspaceDormant(rw http.ResponseWriter, r *http.Request) {
|
||||
|
||||
w, err := convertWorkspace(
|
||||
ctx,
|
||||
api.Experiments,
|
||||
api.Logger,
|
||||
apiKey.UserID,
|
||||
workspace,
|
||||
@@ -2094,7 +2089,6 @@ func (api *API) watchWorkspace(
|
||||
}
|
||||
w, err := convertWorkspace(
|
||||
ctx,
|
||||
api.Experiments,
|
||||
api.Logger,
|
||||
apiKey.UserID,
|
||||
workspace,
|
||||
@@ -2236,8 +2230,7 @@ func (api *API) workspaceACL(rw http.ResponseWriter, r *http.Request) {
|
||||
// the case here. This data goes directly to an unauthorized user. We are
|
||||
// just straight up breaking security promises.
|
||||
//
|
||||
// Fine for now while behind the shared-workspaces experiment, but needs to
|
||||
// be fixed before GA.
|
||||
// TODO: This needs to be fixed before GA. Currently in beta.
|
||||
|
||||
// Fetch all of the users and their organization memberships
|
||||
userIDs := make([]uuid.UUID, 0, len(workspaceACL.Users))
|
||||
@@ -2595,7 +2588,6 @@ func (api *API) workspaceData(ctx context.Context, workspaces []database.Workspa
|
||||
|
||||
func convertWorkspaces(
|
||||
ctx context.Context,
|
||||
experiments codersdk.Experiments,
|
||||
logger slog.Logger,
|
||||
requesterID uuid.UUID,
|
||||
workspaces []database.Workspace,
|
||||
@@ -2633,7 +2625,6 @@ func convertWorkspaces(
|
||||
|
||||
w, err := convertWorkspace(
|
||||
ctx,
|
||||
experiments,
|
||||
logger,
|
||||
requesterID,
|
||||
workspace,
|
||||
@@ -2653,7 +2644,6 @@ func convertWorkspaces(
|
||||
|
||||
func convertWorkspace(
|
||||
ctx context.Context,
|
||||
experiments codersdk.Experiments,
|
||||
logger slog.Logger,
|
||||
requesterID uuid.UUID,
|
||||
workspace database.Workspace,
|
||||
@@ -2752,20 +2742,15 @@ func convertWorkspace(
|
||||
NextStartAt: nextStartAt,
|
||||
IsPrebuild: workspace.IsPrebuild(),
|
||||
TaskID: workspace.TaskID,
|
||||
SharedWith: sharedWorkspaceActors(ctx, experiments, logger, workspace),
|
||||
SharedWith: sharedWorkspaceActors(ctx, logger, workspace),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func sharedWorkspaceActors(
|
||||
ctx context.Context,
|
||||
experiments codersdk.Experiments,
|
||||
logger slog.Logger,
|
||||
workspace database.Workspace,
|
||||
) []codersdk.SharedWorkspaceActor {
|
||||
if !experiments.Enabled(codersdk.ExperimentWorkspaceSharing) {
|
||||
return nil
|
||||
}
|
||||
|
||||
out := make([]codersdk.SharedWorkspaceActor, 0, len(workspace.UserACL)+len(workspace.GroupACL))
|
||||
|
||||
// Users
|
||||
|
||||
@@ -1899,7 +1899,6 @@ func TestWorkspaceFilter(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
dv := coderdtest.DeploymentValues(t)
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
|
||||
var (
|
||||
client, db = coderdtest.NewWithDatabase(t, &coderdtest.Options{
|
||||
@@ -1937,7 +1936,6 @@ func TestWorkspaceFilter(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
dv := coderdtest.DeploymentValues(t)
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
|
||||
var (
|
||||
client, db = coderdtest.NewWithDatabase(t, &coderdtest.Options{
|
||||
@@ -1975,7 +1973,6 @@ func TestWorkspaceFilter(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
dv := coderdtest.DeploymentValues(t)
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
|
||||
var (
|
||||
client, db = coderdtest.NewWithDatabase(t, &coderdtest.Options{
|
||||
@@ -2013,7 +2010,6 @@ func TestWorkspaceFilter(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
dv := coderdtest.DeploymentValues(t)
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
|
||||
var (
|
||||
client, db = coderdtest.NewWithDatabase(t, &coderdtest.Options{
|
||||
@@ -5249,7 +5245,7 @@ func TestUpdateWorkspaceACL(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
dv := coderdtest.DeploymentValues(t)
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
|
||||
adminClient := coderdtest.New(t, &coderdtest.Options{
|
||||
IncludeProvisionerDaemon: true,
|
||||
DeploymentValues: dv,
|
||||
@@ -5285,7 +5281,7 @@ func TestUpdateWorkspaceACL(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
dv := coderdtest.DeploymentValues(t)
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
|
||||
adminClient := coderdtest.New(t, &coderdtest.Options{
|
||||
IncludeProvisionerDaemon: true,
|
||||
DeploymentValues: dv,
|
||||
@@ -5318,7 +5314,7 @@ func TestUpdateWorkspaceACL(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
dv := coderdtest.DeploymentValues(t)
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
|
||||
adminClient := coderdtest.New(t, &coderdtest.Options{
|
||||
IncludeProvisionerDaemon: true,
|
||||
DeploymentValues: dv,
|
||||
@@ -5358,7 +5354,7 @@ func TestUpdateWorkspaceACL(t *testing.T) {
|
||||
t.Cleanup(func() { rbac.SetWorkspaceACLDisabled(prevWorkspaceACLDisabled) })
|
||||
|
||||
dv := coderdtest.DeploymentValues(t)
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
|
||||
adminClient := coderdtest.New(t, &coderdtest.Options{
|
||||
IncludeProvisionerDaemon: true,
|
||||
DeploymentValues: dv,
|
||||
@@ -5426,11 +5422,7 @@ func TestDeleteWorkspaceACL(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var (
|
||||
client, db = coderdtest.NewWithDatabase(t, &coderdtest.Options{
|
||||
DeploymentValues: coderdtest.DeploymentValues(t, func(dv *codersdk.DeploymentValues) {
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
}),
|
||||
})
|
||||
client, db = coderdtest.NewWithDatabase(t, nil)
|
||||
admin = coderdtest.CreateFirstUser(t, client)
|
||||
workspaceOwnerClient, workspaceOwner = coderdtest.CreateAnotherUser(t, client, admin.OrganizationID)
|
||||
_, toShareWithUser = coderdtest.CreateAnotherUser(t, client, admin.OrganizationID)
|
||||
@@ -5461,11 +5453,7 @@ func TestDeleteWorkspaceACL(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var (
|
||||
client, db = coderdtest.NewWithDatabase(t, &coderdtest.Options{
|
||||
DeploymentValues: coderdtest.DeploymentValues(t, func(dv *codersdk.DeploymentValues) {
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
}),
|
||||
})
|
||||
client, db = coderdtest.NewWithDatabase(t, nil)
|
||||
admin = coderdtest.CreateFirstUser(t, client)
|
||||
workspaceOwnerClient, workspaceOwner = coderdtest.CreateAnotherUser(t, client, admin.OrganizationID)
|
||||
sharedUseClient, toShareWithUser = coderdtest.CreateAnotherUser(t, client, admin.OrganizationID)
|
||||
@@ -5504,11 +5492,7 @@ func TestWorkspaceReadCanListACL(t *testing.T) {
|
||||
t.Cleanup(func() { rbac.SetWorkspaceACLDisabled(prevWorkspaceACLDisabled) })
|
||||
|
||||
var (
|
||||
client, db = coderdtest.NewWithDatabase(t, &coderdtest.Options{
|
||||
DeploymentValues: coderdtest.DeploymentValues(t, func(dv *codersdk.DeploymentValues) {
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
}),
|
||||
})
|
||||
client, db = coderdtest.NewWithDatabase(t, nil)
|
||||
admin = coderdtest.CreateFirstUser(t, client)
|
||||
workspaceOwnerClient, workspaceOwner = coderdtest.CreateAnotherUser(t, client, admin.OrganizationID)
|
||||
sharedUserClientA, sharedUserA = coderdtest.CreateAnotherUser(t, client, admin.OrganizationID)
|
||||
@@ -5558,7 +5542,6 @@ func TestWorkspaceSharingDisabled(t *testing.T) {
|
||||
var (
|
||||
client, db = coderdtest.NewWithDatabase(t, &coderdtest.Options{
|
||||
DeploymentValues: coderdtest.DeploymentValues(t, func(dv *codersdk.DeploymentValues) {
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
// DisableWorkspaceSharing is false (default)
|
||||
}),
|
||||
})
|
||||
@@ -5592,7 +5575,6 @@ func TestWorkspaceSharingDisabled(t *testing.T) {
|
||||
var (
|
||||
client, db = coderdtest.NewWithDatabase(t, &coderdtest.Options{
|
||||
DeploymentValues: coderdtest.DeploymentValues(t, func(dv *codersdk.DeploymentValues) {
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
dv.DisableWorkspaceSharing = true
|
||||
}),
|
||||
})
|
||||
|
||||
@@ -3042,7 +3042,7 @@ func (c *DeploymentValues) Options() serpent.OptionSet {
|
||||
},
|
||||
{
|
||||
Name: "Disable Workspace Sharing",
|
||||
Description: `Disable workspace sharing (requires the "workspace-sharing" experiment to be enabled). Workspace ACL checking is disabled and only owners can have ssh, apps and terminal access to workspaces. Access based on the 'owner' role is also allowed unless disabled via --disable-owner-workspace-access.`,
|
||||
Description: `Disable workspace sharing. Workspace ACL checking is disabled and only owners can have ssh, apps and terminal access to workspaces. Access based on the 'owner' role is also allowed unless disabled via --disable-owner-workspace-access.`,
|
||||
Flag: "disable-workspace-sharing",
|
||||
Env: "CODER_DISABLE_WORKSPACE_SHARING",
|
||||
|
||||
@@ -4265,7 +4265,6 @@ const (
|
||||
ExperimentWebPush Experiment = "web-push" // Enables web push notifications through the browser.
|
||||
ExperimentOAuth2 Experiment = "oauth2" // Enables OAuth2 provider functionality.
|
||||
ExperimentMCPServerHTTP Experiment = "mcp-server-http" // Enables the MCP HTTP server functionality.
|
||||
ExperimentWorkspaceSharing Experiment = "workspace-sharing" // Enables updating workspace ACLs for sharing with users and groups.
|
||||
)
|
||||
|
||||
func (e Experiment) DisplayName() string {
|
||||
@@ -4284,8 +4283,6 @@ func (e Experiment) DisplayName() string {
|
||||
return "OAuth2 Provider Functionality"
|
||||
case ExperimentMCPServerHTTP:
|
||||
return "MCP HTTP Server Functionality"
|
||||
case ExperimentWorkspaceSharing:
|
||||
return "Workspace Sharing"
|
||||
default:
|
||||
// Split on hyphen and convert to title case
|
||||
// e.g. "web-push" -> "Web Push", "mcp-server-http" -> "Mcp Server Http"
|
||||
@@ -4303,7 +4300,6 @@ var ExperimentsKnown = Experiments{
|
||||
ExperimentWebPush,
|
||||
ExperimentOAuth2,
|
||||
ExperimentMCPServerHTTP,
|
||||
ExperimentWorkspaceSharing,
|
||||
}
|
||||
|
||||
// ExperimentsSafe should include all experiments that are safe for
|
||||
|
||||
+1
-1
@@ -325,7 +325,7 @@
|
||||
"description": "Sharing workspaces",
|
||||
"path": "./user-guides/shared-workspaces.md",
|
||||
"icon_path": "./images/icons/generic.svg",
|
||||
"state": ["early access"]
|
||||
"state": ["beta"]
|
||||
},
|
||||
{
|
||||
"title": "Workspace Scheduling",
|
||||
|
||||
Generated
+3
-3
@@ -3981,9 +3981,9 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o
|
||||
|
||||
#### Enumerated Values
|
||||
|
||||
| Value(s) |
|
||||
|-------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `auto-fill-parameters`, `example`, `mcp-server-http`, `notifications`, `oauth2`, `web-push`, `workspace-sharing`, `workspace-usage` |
|
||||
| Value(s) |
|
||||
|----------------------------------------------------------------------------------------------------------------|
|
||||
| `auto-fill-parameters`, `example`, `mcp-server-http`, `notifications`, `oauth2`, `web-push`, `workspace-usage` |
|
||||
|
||||
## codersdk.ExternalAPIKeyScopes
|
||||
|
||||
|
||||
Generated
+1
-1
@@ -1167,7 +1167,7 @@ Remove the permission for the 'owner' role to have workspace execution on all wo
|
||||
| Environment | <code>$CODER_DISABLE_WORKSPACE_SHARING</code> |
|
||||
| YAML | <code>disableWorkspaceSharing</code> |
|
||||
|
||||
Disable workspace sharing (requires the "workspace-sharing" experiment to be enabled). Workspace ACL checking is disabled and only owners can have ssh, apps and terminal access to workspaces. Access based on the 'owner' role is also allowed unless disabled via --disable-owner-workspace-access.
|
||||
Disable workspace sharing. Workspace ACL checking is disabled and only owners can have ssh, apps and terminal access to workspaces. Access based on the 'owner' role is also allowed unless disabled via --disable-owner-workspace-access.
|
||||
|
||||
### --session-duration
|
||||
|
||||
|
||||
@@ -31,11 +31,6 @@ func TestSharingShare(t *testing.T) {
|
||||
|
||||
var (
|
||||
client, db, orgOwner = coderdenttest.NewWithDatabase(t, &coderdenttest.Options{
|
||||
Options: &coderdtest.Options{
|
||||
DeploymentValues: coderdtest.DeploymentValues(t, func(dv *codersdk.DeploymentValues) {
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
}),
|
||||
},
|
||||
LicenseOptions: &coderdenttest.LicenseOptions{
|
||||
Features: license.Features{
|
||||
codersdk.FeatureTemplateRBAC: 1,
|
||||
@@ -84,11 +79,6 @@ func TestSharingShare(t *testing.T) {
|
||||
|
||||
var (
|
||||
client, db, orgOwner = coderdenttest.NewWithDatabase(t, &coderdenttest.Options{
|
||||
Options: &coderdtest.Options{
|
||||
DeploymentValues: coderdtest.DeploymentValues(t, func(dv *codersdk.DeploymentValues) {
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
}),
|
||||
},
|
||||
LicenseOptions: &coderdenttest.LicenseOptions{
|
||||
Features: license.Features{
|
||||
codersdk.FeatureTemplateRBAC: 1,
|
||||
@@ -140,11 +130,6 @@ func TestSharingShare(t *testing.T) {
|
||||
|
||||
var (
|
||||
client, db, orgOwner = coderdenttest.NewWithDatabase(t, &coderdenttest.Options{
|
||||
Options: &coderdtest.Options{
|
||||
DeploymentValues: coderdtest.DeploymentValues(t, func(dv *codersdk.DeploymentValues) {
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
}),
|
||||
},
|
||||
LicenseOptions: &coderdenttest.LicenseOptions{
|
||||
Features: license.Features{
|
||||
codersdk.FeatureTemplateRBAC: 1,
|
||||
@@ -198,11 +183,6 @@ func TestSharingStatus(t *testing.T) {
|
||||
|
||||
var (
|
||||
client, db, orgOwner = coderdenttest.NewWithDatabase(t, &coderdenttest.Options{
|
||||
Options: &coderdtest.Options{
|
||||
DeploymentValues: coderdtest.DeploymentValues(t, func(dv *codersdk.DeploymentValues) {
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
}),
|
||||
},
|
||||
LicenseOptions: &coderdenttest.LicenseOptions{
|
||||
Features: license.Features{
|
||||
codersdk.FeatureTemplateRBAC: 1,
|
||||
@@ -255,11 +235,6 @@ func TestSharingRemove(t *testing.T) {
|
||||
|
||||
var (
|
||||
client, db, orgOwner = coderdenttest.NewWithDatabase(t, &coderdenttest.Options{
|
||||
Options: &coderdtest.Options{
|
||||
DeploymentValues: coderdtest.DeploymentValues(t, func(dv *codersdk.DeploymentValues) {
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
}),
|
||||
},
|
||||
LicenseOptions: &coderdenttest.LicenseOptions{
|
||||
Features: license.Features{
|
||||
codersdk.FeatureTemplateRBAC: 1,
|
||||
@@ -328,11 +303,6 @@ func TestSharingRemove(t *testing.T) {
|
||||
|
||||
var (
|
||||
client, db, orgOwner = coderdenttest.NewWithDatabase(t, &coderdenttest.Options{
|
||||
Options: &coderdtest.Options{
|
||||
DeploymentValues: coderdtest.DeploymentValues(t, func(dv *codersdk.DeploymentValues) {
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
}),
|
||||
},
|
||||
LicenseOptions: &coderdenttest.LicenseOptions{
|
||||
Features: license.Features{
|
||||
codersdk.FeatureTemplateRBAC: 1,
|
||||
|
||||
+3
-4
@@ -50,10 +50,9 @@ OPTIONS:
|
||||
security purposes if a --wildcard-access-url is configured.
|
||||
|
||||
--disable-workspace-sharing bool, $CODER_DISABLE_WORKSPACE_SHARING
|
||||
Disable workspace sharing (requires the "workspace-sharing" experiment
|
||||
to be enabled). Workspace ACL checking is disabled and only owners can
|
||||
have ssh, apps and terminal access to workspaces. Access based on the
|
||||
'owner' role is also allowed unless disabled via
|
||||
Disable workspace sharing. Workspace ACL checking is disabled and only
|
||||
owners can have ssh, apps and terminal access to workspaces. Access
|
||||
based on the 'owner' role is also allowed unless disabled via
|
||||
--disable-owner-workspace-access.
|
||||
|
||||
--swagger-enable bool, $CODER_SWAGGER_ENABLE
|
||||
|
||||
@@ -364,9 +364,6 @@ func New(ctx context.Context, options *Options) (_ *API, err error) {
|
||||
r.Get("/idpsync/field-values", api.organizationIDPSyncClaimFieldValues)
|
||||
|
||||
r.Route("/workspace-sharing", func(r chi.Router) {
|
||||
r.Use(
|
||||
httpmw.RequireExperiment(api.AGPL.Experiments, codersdk.ExperimentWorkspaceSharing),
|
||||
)
|
||||
r.Get("/", api.workspaceSharingSettings)
|
||||
r.Patch("/", api.patchWorkspaceSharingSettings)
|
||||
})
|
||||
|
||||
@@ -3651,7 +3651,6 @@ func TestWorkspacesFiltering(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
dv := coderdtest.DeploymentValues(t)
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
|
||||
ownerClient, db, owner := coderdenttest.NewWithDatabase(t, &coderdenttest.Options{
|
||||
Options: &coderdtest.Options{
|
||||
@@ -3703,7 +3702,6 @@ func TestWorkspacesFiltering(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
dv := coderdtest.DeploymentValues(t)
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
|
||||
var (
|
||||
ownerClient, db, owner = coderdenttest.NewWithDatabase(t, &coderdenttest.Options{
|
||||
@@ -3757,7 +3755,6 @@ func TestWorkspacesFiltering(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
dv := coderdtest.DeploymentValues(t)
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
|
||||
var (
|
||||
ownerClient, db, owner = coderdenttest.NewWithDatabase(t, &coderdenttest.Options{
|
||||
@@ -3806,7 +3803,6 @@ func TestWorkspacesFiltering(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
dv := coderdtest.DeploymentValues(t)
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
|
||||
var (
|
||||
ownerClient, db, owner = coderdenttest.NewWithDatabase(t, &coderdenttest.Options{
|
||||
@@ -3854,7 +3850,6 @@ func TestWorkspacesFiltering(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
dv := coderdtest.DeploymentValues(t)
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
|
||||
var (
|
||||
ownerClient, db, owner = coderdenttest.NewWithDatabase(t, &coderdenttest.Options{
|
||||
@@ -4356,7 +4351,7 @@ func TestUpdateWorkspaceACL(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
dv := coderdtest.DeploymentValues(t)
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
|
||||
adminClient, adminUser := coderdenttest.New(t, &coderdenttest.Options{
|
||||
Options: &coderdtest.Options{
|
||||
IncludeProvisionerDaemon: true,
|
||||
@@ -4405,7 +4400,7 @@ func TestUpdateWorkspaceACL(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
dv := coderdtest.DeploymentValues(t)
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
|
||||
adminClient := coderdtest.New(t, &coderdtest.Options{
|
||||
IncludeProvisionerDaemon: true,
|
||||
DeploymentValues: dv,
|
||||
@@ -4449,7 +4444,6 @@ func TestDeleteWorkspaceACL(t *testing.T) {
|
||||
client, db, admin = coderdenttest.NewWithDatabase(t, &coderdenttest.Options{
|
||||
Options: &coderdtest.Options{
|
||||
DeploymentValues: coderdtest.DeploymentValues(t, func(dv *codersdk.DeploymentValues) {
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
}),
|
||||
},
|
||||
LicenseOptions: &coderdenttest.LicenseOptions{
|
||||
@@ -4493,7 +4487,6 @@ func TestDeleteWorkspaceACL(t *testing.T) {
|
||||
client, db, admin = coderdenttest.NewWithDatabase(t, &coderdenttest.Options{
|
||||
Options: &coderdtest.Options{
|
||||
DeploymentValues: coderdtest.DeploymentValues(t, func(dv *codersdk.DeploymentValues) {
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
}),
|
||||
},
|
||||
LicenseOptions: &coderdenttest.LicenseOptions{
|
||||
@@ -4543,7 +4536,6 @@ func TestWorkspacesSharedWith(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
dv := coderdtest.DeploymentValues(t)
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
|
||||
client, db, user := coderdenttest.NewWithDatabase(t, &coderdenttest.Options{
|
||||
Options: &coderdtest.Options{
|
||||
@@ -4631,7 +4623,6 @@ func TestWorkspacesSharedWith(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
dv := coderdtest.DeploymentValues(t)
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
|
||||
client, db, user := coderdenttest.NewWithDatabase(t, &coderdenttest.Options{
|
||||
Options: &coderdtest.Options{
|
||||
|
||||
@@ -25,7 +25,6 @@ func TestWorkspaceSharingSettings(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
dv := coderdtest.DeploymentValues(t)
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
|
||||
client, first := coderdenttest.New(t, &coderdenttest.Options{
|
||||
Options: &coderdtest.Options{
|
||||
@@ -45,7 +44,6 @@ func TestWorkspaceSharingSettings(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
dv := coderdtest.DeploymentValues(t)
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
|
||||
client, first := coderdenttest.New(t, &coderdenttest.Options{
|
||||
Options: &coderdtest.Options{
|
||||
@@ -77,7 +75,6 @@ func TestWorkspaceSharingSettings(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
dv := coderdtest.DeploymentValues(t)
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
|
||||
client, first := coderdenttest.New(t, &coderdenttest.Options{
|
||||
Options: &coderdtest.Options{
|
||||
@@ -101,7 +98,6 @@ func TestWorkspaceSharingSettings(t *testing.T) {
|
||||
|
||||
auditor := audit.NewMock()
|
||||
dv := coderdtest.DeploymentValues(t)
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
|
||||
client, first := coderdenttest.New(t, &coderdenttest.Options{
|
||||
AuditLogging: true,
|
||||
@@ -131,23 +127,6 @@ func TestWorkspaceSharingSettings(t *testing.T) {
|
||||
require.Equal(t, database.ResourceTypeOrganization, alog.ResourceType)
|
||||
require.Equal(t, first.OrganizationID, alog.ResourceID)
|
||||
})
|
||||
|
||||
t.Run("ExperimentDisabled", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Note: NOT setting the experiment flag.
|
||||
client, first := coderdenttest.New(t, &coderdenttest.Options{})
|
||||
|
||||
ctx := testutil.Context(t, testutil.WaitMedium)
|
||||
|
||||
memberClient, _ := coderdtest.CreateAnotherUser(t, client, first.OrganizationID)
|
||||
_, err := memberClient.WorkspaceSharingSettings(ctx, first.OrganizationID.String())
|
||||
var apiErr *codersdk.Error
|
||||
require.ErrorAs(t, err, &apiErr)
|
||||
require.Equal(t, http.StatusForbidden, apiErr.StatusCode())
|
||||
require.Contains(t, apiErr.Message, "requires enabling")
|
||||
require.Contains(t, apiErr.Message, "workspace-sharing")
|
||||
})
|
||||
}
|
||||
|
||||
func TestWorkspaceSharingDisabled(t *testing.T) {
|
||||
@@ -157,7 +136,6 @@ func TestWorkspaceSharingDisabled(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
dv := coderdtest.DeploymentValues(t)
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
|
||||
client, db, owner := coderdenttest.NewWithDatabase(t, &coderdenttest.Options{
|
||||
Options: &coderdtest.Options{
|
||||
@@ -211,7 +189,6 @@ func TestWorkspaceSharingDisabled(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
dv := coderdtest.DeploymentValues(t)
|
||||
dv.Experiments = []string{string(codersdk.ExperimentWorkspaceSharing)}
|
||||
|
||||
client, db, owner := coderdenttest.NewWithDatabase(t, &coderdenttest.Options{
|
||||
Options: &coderdtest.Options{
|
||||
|
||||
Generated
-2
@@ -1939,7 +1939,6 @@ export type Experiment =
|
||||
| "notifications"
|
||||
| "oauth2"
|
||||
| "web-push"
|
||||
| "workspace-sharing"
|
||||
| "workspace-usage";
|
||||
|
||||
export const Experiments: Experiment[] = [
|
||||
@@ -1949,7 +1948,6 @@ export const Experiments: Experiment[] = [
|
||||
"notifications",
|
||||
"oauth2",
|
||||
"web-push",
|
||||
"workspace-sharing",
|
||||
"workspace-usage",
|
||||
];
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import { ErrorAlert } from "components/Alert/ErrorAlert";
|
||||
import { Button } from "components/Button/Button";
|
||||
import { Checkbox } from "components/Checkbox/Checkbox";
|
||||
import { DeleteDialog } from "components/Dialogs/DeleteDialog/DeleteDialog";
|
||||
import { FeatureStageBadge } from "components/FeatureStageBadge/FeatureStageBadge";
|
||||
import {
|
||||
FormFields,
|
||||
FormFooter,
|
||||
@@ -147,7 +148,12 @@ export const OrganizationSettingsPageView: FC<
|
||||
{onToggleWorkspaceSharing && (
|
||||
<HorizontalContainer className="mt-12">
|
||||
<HorizontalSection
|
||||
title="Workspace Sharing"
|
||||
title={
|
||||
<div className="flex items-center gap-2">
|
||||
Workspace Sharing
|
||||
<FeatureStageBadge contentType="beta" size="sm" />
|
||||
</div>
|
||||
}
|
||||
description="Control whether workspace owners can share their workspaces."
|
||||
>
|
||||
<div className="flex items-start gap-3">
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { Workspace } from "api/typesGenerated";
|
||||
import { FeatureStageBadge } from "components/FeatureStageBadge/FeatureStageBadge";
|
||||
import { TopbarButton } from "components/FullPageLayout/Topbar";
|
||||
import {
|
||||
Popover,
|
||||
@@ -32,6 +33,10 @@ export const ShareButton: FC<ShareButtonProps> = ({
|
||||
</TopbarButton>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent align="end" className="w-[580px] p-4">
|
||||
<div className="flex items-center gap-2 mb-4">
|
||||
<h3 className="text-lg font-semibold m-0">Workspace Sharing</h3>
|
||||
<FeatureStageBadge contentType="beta" size="sm" />
|
||||
</div>
|
||||
<WorkspaceSharingForm
|
||||
workspaceACL={sharing.workspaceACL}
|
||||
canUpdatePermissions={canUpdatePermissions}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { Workspace } from "api/typesGenerated";
|
||||
import { Avatar } from "components/Avatar/Avatar";
|
||||
import { FeatureStageBadge } from "components/FeatureStageBadge/FeatureStageBadge";
|
||||
import {
|
||||
Sidebar as BaseSidebar,
|
||||
SidebarHeader,
|
||||
@@ -11,7 +12,6 @@ import {
|
||||
TimerIcon as ScheduleIcon,
|
||||
Users as SharingIcon,
|
||||
} from "lucide-react";
|
||||
import { useDashboard } from "modules/dashboard/useDashboard";
|
||||
import type { FC } from "react";
|
||||
|
||||
interface SidebarProps {
|
||||
@@ -25,8 +25,6 @@ export const Sidebar: FC<SidebarProps> = ({
|
||||
workspace,
|
||||
sharingDisabled,
|
||||
}) => {
|
||||
const { experiments } = useDashboard();
|
||||
|
||||
return (
|
||||
<BaseSidebar>
|
||||
<SidebarHeader
|
||||
@@ -51,9 +49,10 @@ export const Sidebar: FC<SidebarProps> = ({
|
||||
<SidebarNavItem href="schedule" icon={ScheduleIcon}>
|
||||
Schedule
|
||||
</SidebarNavItem>
|
||||
{experiments.includes("workspace-sharing") && !sharingDisabled && (
|
||||
{!sharingDisabled && (
|
||||
<SidebarNavItem href="sharing" icon={SharingIcon}>
|
||||
Sharing
|
||||
<FeatureStageBadge contentType="beta" size="sm" />
|
||||
</SidebarNavItem>
|
||||
)}
|
||||
</BaseSidebar>
|
||||
|
||||
Reference in New Issue
Block a user