Skip to content

Commit

Permalink
Feat(dui3): readonly workspaces (#3789)
Browse files Browse the repository at this point in the history
* Handle readonly workspaces

* Handle existing projects for readonly workspaces

* better conditions for is workspace readonly

* decrease size of the alert to xs

---------

Co-authored-by: oguzhankoral <[email protected]>
  • Loading branch information
oguzhankoral and oguzhankoral authored Jan 9, 2025
1 parent b25e8b0 commit af33991
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 31 deletions.
30 changes: 29 additions & 1 deletion packages/dui3/components/common/ProjectModelGroup.vue
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,28 @@
</button>

<div v-show="showModels" class="space-y-2 mt-2 pb-1">
<CommonAlert
v-if="isWorkspaceReadOnly"
size="xs"
:color="'warning'"
:actions="[
{
title: 'Subscribe',
onClick: () => $openUrl(workspaceUrl)
}
]"
>
<template #description>
The workspace is in a read-only locked state until there's an active
subscription. Subscribe to a plan to regain full access.
</template>
</CommonAlert>
<ModelSender
v-for="model in project.senders"
:key="model.modelCardId"
:model-card="model"
:project="project"
:readonly="isProjectReadOnly"
:readonly="isProjectReadOnly || isWorkspaceReadOnly"
/>
<ModelReceiver
v-for="model in project.receivers"
Expand Down Expand Up @@ -193,6 +209,11 @@ const isProjectReadOnly = computed(() => {
return false
})
const isWorkspaceReadOnly = computed(() => {
if (!projectDetails.value?.workspace) return false // project is not even in a workspace
return projectDetails.value?.workspace?.readOnly
})
// Enable later when FE2 is ready for accepting/denying requested accesses
// const hasServerMatch = computed(() =>
// accountStore.isAccountExistsByServer(props.project.serverUrl)
Expand Down Expand Up @@ -247,6 +268,13 @@ const projectUrl = computed(() => {
}`
})
const workspaceUrl = computed(() => {
const acc = accountStore.accounts.find((acc) => acc.accountInfo.id === clientId)
return `${acc?.accountInfo.serverInfo.url as string}/workspaces/${
projectDetails.value?.workspace?.slug
}`
})
// Subscribe to version created events at a project level, and filter to any receivers (if any)
const { onResult } = useSubscription(
versionCreatedSubscription,
Expand Down
15 changes: 12 additions & 3 deletions packages/dui3/components/wizard/ProjectSelector.vue
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,23 @@
show-label
:items="workspaces"
:disabled-item-predicate="userCantCreateWorkspace"
:disabled-item-tooltip="'You do not have write access on this workspace.'"
mount-menu-on-body
>
<template #something-selected="{ value }">
<span>{{ value.name }}</span>
</template>
<template #option="{ item }">
<div class="flex items-center">
<div
v-tippy="{
content: item.readOnly
? 'This workspace is read-only.'
: item.role === 'workspace:guest'
? 'You do not have write access on this workspace.'
: undefined,
disabled: !(item.readOnly || item.role === 'workspace:guest')
}"
class="flex items-center"
>
<span class="truncate">{{ item.name }}</span>
</div>
</template>
Expand Down Expand Up @@ -251,7 +260,7 @@ const createNewProjectInWorkspace = async (name: string) => {
}
const userCantCreateWorkspace = (item: WorkspaceListWorkspaceItemFragment) =>
!!item?.role && item.role === 'workspace:guest'
(!!item?.role && item.role === 'workspace:guest') || !!item.readOnly
const {
result: projectsResult,
Expand Down
8 changes: 4 additions & 4 deletions packages/dui3/lib/common/generated/gql/gql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const documents = {
"\n mutation CreateProject($input: ProjectCreateInput) {\n projectMutations {\n create(input: $input) {\n ...ProjectListProjectItem\n }\n }\n }\n": types.CreateProjectDocument,
"\n mutation CreateProjectInWorkspace($input: WorkspaceProjectCreateInput!) {\n workspaceMutations {\n projects {\n create(input: $input) {\n ...ProjectListProjectItem\n }\n }\n }\n }\n": types.CreateProjectInWorkspaceDocument,
"\n mutation StreamAccessRequestCreate($input: String!) {\n streamAccessRequestCreate(streamId: $input) {\n id\n }\n }\n": types.StreamAccessRequestCreateDocument,
"\n fragment WorkspaceListWorkspaceItem on Workspace {\n id\n name\n description\n createdAt\n updatedAt\n logo\n role\n }\n": types.WorkspaceListWorkspaceItemFragmentDoc,
"\n fragment WorkspaceListWorkspaceItem on Workspace {\n id\n name\n description\n createdAt\n updatedAt\n logo\n role\n readOnly\n }\n": types.WorkspaceListWorkspaceItemFragmentDoc,
"\n fragment AutomateFunctionItem on AutomateFunction {\n name\n isFeatured\n id\n creator {\n name\n }\n releases {\n items {\n inputSchema\n }\n }\n }\n": types.AutomateFunctionItemFragmentDoc,
"\n mutation CreateAutomation($projectId: ID!, $input: ProjectAutomationCreateInput!) {\n projectMutations {\n automationMutations(projectId: $projectId) {\n create(input: $input) {\n id\n name\n }\n }\n }\n }\n": types.CreateAutomationDocument,
"\n fragment AutomateFunctionRunItem on AutomateFunctionRun {\n id\n status\n statusMessage\n results\n contextView\n function {\n id\n name\n logo\n }\n }\n": types.AutomateFunctionRunItemFragmentDoc,
Expand All @@ -35,7 +35,7 @@ const documents = {
"\n query ObjectQuery($projectId: String!, $objectId: String!) {\n project(id: $projectId) {\n object(id: $objectId) {\n id\n data\n }\n }\n }\n": types.ObjectQueryDocument,
"\n query ProjectAddByUrlQueryWithVersion(\n $projectId: String!\n $modelId: String!\n $versionId: String!\n ) {\n project(id: $projectId) {\n ...ProjectListProjectItem\n model(id: $modelId) {\n ...ModelListModelItem\n version(id: $versionId) {\n ...VersionListItem\n }\n }\n }\n }\n": types.ProjectAddByUrlQueryWithVersionDocument,
"\n query ProjectAddByUrlQueryWithoutVersion($projectId: String!, $modelId: String!) {\n project(id: $projectId) {\n ...ProjectListProjectItem\n model(id: $modelId) {\n ...ModelListModelItem\n }\n }\n }\n": types.ProjectAddByUrlQueryWithoutVersionDocument,
"\n query ProjectDetails($projectId: String!) {\n project(id: $projectId) {\n id\n role\n name\n team {\n user {\n avatar\n id\n name\n }\n }\n visibility\n }\n }\n": types.ProjectDetailsDocument,
"\n query ProjectDetails($projectId: String!) {\n project(id: $projectId) {\n id\n role\n name\n workspace {\n slug\n readOnly\n }\n team {\n user {\n avatar\n id\n name\n }\n }\n visibility\n }\n }\n": types.ProjectDetailsDocument,
"\n query AutomateFunctions {\n automateFunctions {\n items {\n ...AutomateFunctionItem\n }\n }\n }\n": types.AutomateFunctionsDocument,
"\n query ModelDetails($modelId: String!, $projectId: String!) {\n project(id: $projectId) {\n id\n name\n model(id: $modelId) {\n id\n displayName\n name\n versions {\n totalCount\n items {\n id\n }\n }\n author {\n id\n name\n avatar\n }\n }\n }\n }\n": types.ModelDetailsDocument,
"\n query VersionDetails($projectId: String!, $versionId: String!, $modelId: String!) {\n project(id: $projectId) {\n id\n name\n model(id: $modelId) {\n id\n name\n versions(limit: 1) {\n items {\n id\n createdAt\n sourceApplication\n authorUser {\n id\n }\n }\n }\n version(id: $versionId) {\n id\n referencedObject\n message\n sourceApplication\n createdAt\n previewUrl\n }\n }\n }\n }\n": types.VersionDetailsDocument,
Expand Down Expand Up @@ -88,7 +88,7 @@ export function graphql(source: "\n mutation StreamAccessRequestCreate($input:
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function graphql(source: "\n fragment WorkspaceListWorkspaceItem on Workspace {\n id\n name\n description\n createdAt\n updatedAt\n logo\n role\n }\n"): (typeof documents)["\n fragment WorkspaceListWorkspaceItem on Workspace {\n id\n name\n description\n createdAt\n updatedAt\n logo\n role\n }\n"];
export function graphql(source: "\n fragment WorkspaceListWorkspaceItem on Workspace {\n id\n name\n description\n createdAt\n updatedAt\n logo\n role\n readOnly\n }\n"): (typeof documents)["\n fragment WorkspaceListWorkspaceItem on Workspace {\n id\n name\n description\n createdAt\n updatedAt\n logo\n role\n readOnly\n }\n"];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
Expand Down Expand Up @@ -152,7 +152,7 @@ export function graphql(source: "\n query ProjectAddByUrlQueryWithoutVersion($p
/**
* 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 ProjectDetails($projectId: String!) {\n project(id: $projectId) {\n id\n role\n name\n team {\n user {\n avatar\n id\n name\n }\n }\n visibility\n }\n }\n"): (typeof documents)["\n query ProjectDetails($projectId: String!) {\n project(id: $projectId) {\n id\n role\n name\n team {\n user {\n avatar\n id\n name\n }\n }\n visibility\n }\n }\n"];
export function graphql(source: "\n query ProjectDetails($projectId: String!) {\n project(id: $projectId) {\n id\n role\n name\n workspace {\n slug\n readOnly\n }\n team {\n user {\n avatar\n id\n name\n }\n }\n visibility\n }\n }\n"): (typeof documents)["\n query ProjectDetails($projectId: String!) {\n project(id: $projectId) {\n id\n role\n name\n workspace {\n slug\n readOnly\n }\n team {\n user {\n avatar\n id\n name\n }\n }\n visibility\n }\n }\n"];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
Expand Down
Loading

0 comments on commit af33991

Please sign in to comment.