diff --git a/packages/frontend-2/components/settings/Dialog.vue b/packages/frontend-2/components/settings/Dialog.vue index d816d9f53..34afc376e 100644 --- a/packages/frontend-2/components/settings/Dialog.vue +++ b/packages/frontend-2/components/settings/Dialog.vue @@ -23,8 +23,7 @@ :key="key" :label="sidebarMenuItem.title" :class="{ - 'bg-highlight-2 hover:!bg-highlight-2': - selectedMenuItem?.title === sidebarMenuItem.title + 'bg-highlight-2 hover:!bg-highlight-2': targetMenuItem === key }" @click="targetMenuItem = `${key}`" /> @@ -38,12 +37,36 @@ :key="key" :label="sidebarMenuItem.title" :class="{ - 'bg-highlight-2 hover:!bg-highlight-2': - selectedMenuItem?.title === sidebarMenuItem.title + 'bg-highlight-2 hover:!bg-highlight-2': targetMenuItem === key }" @click="targetMenuItem = `${key}`" /> + + + + + + (null) const menuItemConfig = shallowRef<{ [key: string]: { [key: string]: MenuItem } }>({ user: { @@ -121,15 +152,28 @@ const menuItemConfig = shallowRef<{ [key: string]: { [key: string]: MenuItem } } title: 'Pending invitations', component: SettingsServerPendingInvitations } + }, + workspace: { + // Workspace menu items will be added here, general, members and projects } }) const isOpen = defineModel('open', { required: true }) const targetMenuItem = defineModel('targetMenuItem', { required: true }) +const workspaceItems = computed(() => + workspaceResult.value?.activeUser + ? workspaceResult.value.activeUser.workspaces.items + : [] +) +const hasWorkspaceItems = computed(() => workspaceItems.value.length > 0) const isAdmin = computed(() => user.value?.role === Roles.Server.Admin) const selectedMenuItem = computed((): MenuItem | null => { - const categories = [menuItemConfig.value.user, menuItemConfig.value.server] + const categories = [ + menuItemConfig.value.user, + menuItemConfig.value.server, + menuItemConfig.value.workspace + ] for (const category of categories) { if (targetMenuItem.value && targetMenuItem.value in category) { return category[targetMenuItem.value] @@ -146,6 +190,12 @@ const selectedMenuItem = computed((): MenuItem | null => { return null }) +// Keep track of the selected workspace ID, to open the page for the correct workspace +const onWorkspaceMenuItemClick = (id: string, target: string) => { + targetWorkspaceId.value = id + targetMenuItem.value = target +} + watch( () => user.value, (newVal) => { diff --git a/packages/frontend-2/composables/globals.ts b/packages/frontend-2/composables/globals.ts index d51c2b28b..f5c398176 100644 --- a/packages/frontend-2/composables/globals.ts +++ b/packages/frontend-2/composables/globals.ts @@ -10,6 +10,14 @@ export const useIsAutomateModuleEnabled = () => { return ref(FF_AUTOMATE_MODULE_ENABLED) } +export const useIsWorkspacesEnabled = () => { + const { + public: { FF_WORKSPACES_MODULE_ENABLED } + } = useRuntimeConfig() + + return ref(FF_WORKSPACES_MODULE_ENABLED) +} + export const useIsGendoModuleEnabled = () => { const { public: { FF_GENDOAI_MODULE_ENABLED } diff --git a/packages/frontend-2/lib/common/generated/gql/gql.ts b/packages/frontend-2/lib/common/generated/gql/gql.ts index e675f85b5..538d9f23a 100644 --- a/packages/frontend-2/lib/common/generated/gql/gql.ts +++ b/packages/frontend-2/lib/common/generated/gql/gql.ts @@ -206,6 +206,7 @@ const documents = { "\n query AdminPanelProjectsList(\n $query: String\n $orderBy: String\n $limit: Int!\n $visibility: String\n $cursor: String\n ) {\n admin {\n projectList(\n query: $query\n orderBy: $orderBy\n limit: $limit\n visibility: $visibility\n cursor: $cursor\n ) {\n cursor\n items {\n id\n name\n visibility\n createdAt\n updatedAt\n models {\n totalCount\n }\n versions {\n totalCount\n }\n team {\n id\n user {\n name\n id\n avatar\n }\n }\n }\n totalCount\n cursor\n }\n }\n }\n": types.AdminPanelProjectsListDocument, "\n query AdminPanelInvitesList($limit: Int!, $cursor: String, $query: String) {\n admin {\n inviteList(limit: $limit, cursor: $cursor, query: $query) {\n cursor\n items {\n email\n id\n invitedBy {\n id\n name\n }\n }\n totalCount\n }\n }\n }\n": types.AdminPanelInvitesListDocument, "\n mutation InviteServerUser($input: [ServerInviteCreateInput!]!) {\n serverInviteBatchCreate(input: $input)\n }\n": types.InviteServerUserDocument, + "\n query SettingsSidebarWorkspaces {\n activeUser {\n workspaces {\n items {\n id\n name\n }\n }\n }\n }\n": types.SettingsSidebarWorkspacesDocument, "\n fragment AppAuthorAvatar on AppAuthor {\n id\n name\n avatar\n }\n": types.AppAuthorAvatarFragmentDoc, "\n fragment LimitedUserAvatar on LimitedUser {\n id\n name\n avatar\n }\n": types.LimitedUserAvatarFragmentDoc, "\n fragment ActiveUserAvatar on User {\n id\n name\n avatar\n }\n": types.ActiveUserAvatarFragmentDoc, @@ -1029,6 +1030,10 @@ export function graphql(source: "\n query AdminPanelInvitesList($limit: Int!, $ * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ export function graphql(source: "\n mutation InviteServerUser($input: [ServerInviteCreateInput!]!) {\n serverInviteBatchCreate(input: $input)\n }\n"): (typeof documents)["\n mutation InviteServerUser($input: [ServerInviteCreateInput!]!) {\n serverInviteBatchCreate(input: $input)\n }\n"]; +/** + * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. + */ +export function graphql(source: "\n query SettingsSidebarWorkspaces {\n activeUser {\n workspaces {\n items {\n id\n name\n }\n }\n }\n }\n"): (typeof documents)["\n query SettingsSidebarWorkspaces {\n activeUser {\n workspaces {\n items {\n id\n name\n }\n }\n }\n }\n"]; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ diff --git a/packages/frontend-2/lib/common/generated/gql/graphql.ts b/packages/frontend-2/lib/common/generated/gql/graphql.ts index 3c9bea0d8..e1649911d 100644 --- a/packages/frontend-2/lib/common/generated/gql/graphql.ts +++ b/packages/frontend-2/lib/common/generated/gql/graphql.ts @@ -2930,7 +2930,6 @@ export type StreamCreateInput = { name?: InputMaybe; /** Optionally specify user IDs of users that you want to invite to be contributors to this stream */ withContributors?: InputMaybe>; - workspaceId?: InputMaybe; }; export type StreamInviteCreateInput = { @@ -3730,6 +3729,8 @@ export type Workspace = { id: Scalars['ID']['output']; /** Only available to workspace owners */ invitedTeam?: Maybe>; + /** Optional url for workspace logo image */ + logoUrl?: Maybe; name: Scalars['String']['output']; projects: ProjectCollection; /** Active user's role for this workspace. `null` if request is not authenticated, or the workspace is not explicitly shared with you. */ @@ -3741,7 +3742,7 @@ export type Workspace = { export type WorkspaceProjectsArgs = { cursor?: InputMaybe; - filter?: InputMaybe; + filter?: InputMaybe; limit?: Scalars['Int']['input']; }; @@ -3761,7 +3762,6 @@ export type WorkspaceCollection = { export type WorkspaceCreateInput = { description?: InputMaybe; - logoUrl?: InputMaybe; name: Scalars['String']['input']; }; @@ -3846,6 +3846,11 @@ export type WorkspaceMutationsUpdateRoleArgs = { input: WorkspaceRoleUpdateInput; }; +export type WorkspaceProjectsFilter = { + /** Filter out projects by name */ + search?: InputMaybe; +}; + export enum WorkspaceRole { Admin = 'ADMIN', Guest = 'GUEST', @@ -4812,6 +4817,11 @@ export type InviteServerUserMutationVariables = Exact<{ export type InviteServerUserMutation = { __typename?: 'Mutation', serverInviteBatchCreate: boolean }; +export type SettingsSidebarWorkspacesQueryVariables = Exact<{ [key: string]: never; }>; + + +export type SettingsSidebarWorkspacesQuery = { __typename?: 'Query', activeUser?: { __typename?: 'User', workspaces: { __typename?: 'WorkspaceCollection', items: Array<{ __typename?: 'Workspace', id: string, name: string }> } } | null }; + export type AppAuthorAvatarFragment = { __typename?: 'AppAuthor', id: string, name: string, avatar?: string | null }; export type LimitedUserAvatarFragment = { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null }; @@ -5220,6 +5230,7 @@ export const AdminPanelUsersListDocument = {"kind":"Document","definitions":[{"k export const AdminPanelProjectsListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"AdminPanelProjectsList"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"query"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"orderBy"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"limit"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"visibility"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"cursor"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"admin"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"projectList"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"query"},"value":{"kind":"Variable","name":{"kind":"Name","value":"query"}}},{"kind":"Argument","name":{"kind":"Name","value":"orderBy"},"value":{"kind":"Variable","name":{"kind":"Name","value":"orderBy"}}},{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"Variable","name":{"kind":"Name","value":"limit"}}},{"kind":"Argument","name":{"kind":"Name","value":"visibility"},"value":{"kind":"Variable","name":{"kind":"Name","value":"visibility"}}},{"kind":"Argument","name":{"kind":"Name","value":"cursor"},"value":{"kind":"Variable","name":{"kind":"Name","value":"cursor"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"cursor"}},{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"visibility"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"models"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}},{"kind":"Field","name":{"kind":"Name","value":"versions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}},{"kind":"Field","name":{"kind":"Name","value":"team"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"avatar"}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"totalCount"}},{"kind":"Field","name":{"kind":"Name","value":"cursor"}}]}}]}}]}}]} as unknown as DocumentNode; export const AdminPanelInvitesListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"AdminPanelInvitesList"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"limit"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"cursor"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"query"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"admin"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"inviteList"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"Variable","name":{"kind":"Name","value":"limit"}}},{"kind":"Argument","name":{"kind":"Name","value":"cursor"},"value":{"kind":"Variable","name":{"kind":"Name","value":"cursor"}}},{"kind":"Argument","name":{"kind":"Name","value":"query"},"value":{"kind":"Variable","name":{"kind":"Name","value":"query"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"cursor"}},{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"invitedBy"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}}]}}]}}]} as unknown as DocumentNode; export const InviteServerUserDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"InviteServerUser"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ServerInviteCreateInput"}}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"serverInviteBatchCreate"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}]}]}}]} as unknown as DocumentNode; +export const SettingsSidebarWorkspacesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"SettingsSidebarWorkspaces"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"activeUser"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"workspaces"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const UpdateUserDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateUser"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UserUpdateInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"activeUserMutations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"update"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"user"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"bio"}},{"kind":"Field","name":{"kind":"Name","value":"company"}},{"kind":"Field","name":{"kind":"Name","value":"avatar"}}]}}]}}]}}]} as unknown as DocumentNode; export const UpdateNotificationPreferencesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateNotificationPreferences"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"JSONObject"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userNotificationPreferencesUpdate"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"preferences"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}]}]}}]} as unknown as DocumentNode; export const DeleteAccountDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DeleteAccount"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UserDeleteInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userDelete"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"userConfirmation"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}]}]}}]} as unknown as DocumentNode; diff --git a/packages/frontend-2/lib/settings/graphql/queries.ts b/packages/frontend-2/lib/settings/graphql/queries.ts new file mode 100644 index 000000000..efdcecdd4 --- /dev/null +++ b/packages/frontend-2/lib/settings/graphql/queries.ts @@ -0,0 +1,14 @@ +import { graphql } from '~~/lib/common/generated/gql' + +export const settingsSidebarWorkspacesQuery = graphql(` + query SettingsSidebarWorkspaces { + activeUser { + workspaces { + items { + id + name + } + } + } + } +`)