Loading states
This commit is contained in:
@@ -11,36 +11,41 @@
|
||||
class="mb-2"
|
||||
v-on="on"
|
||||
/>
|
||||
<div
|
||||
v-if="hasMoveableProjects"
|
||||
class="flex flex-col mt-2 border rounded-md border-outline-3"
|
||||
>
|
||||
<div
|
||||
v-for="project in moveableProjects"
|
||||
:key="project.id"
|
||||
class="flex px-4 py-3 items-center space-x-2 justify-between border-b last:border-0 border-outline-3"
|
||||
>
|
||||
<div class="flex flex-col flex-1 truncate text-body-xs">
|
||||
<span class="font-medium text-foreground truncate">
|
||||
{{ project.name }}
|
||||
</span>
|
||||
<div class="flex items-center gap-x-1">
|
||||
<span class="text-foreground-3 truncate">
|
||||
{{ project.modelCount.totalCount }} model{{
|
||||
project.modelCount.totalCount !== 1 ? 's' : ''
|
||||
}}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<FormButton size="sm" color="outline" @click="onMoveClick(project)">
|
||||
Move...
|
||||
</FormButton>
|
||||
</div>
|
||||
<div v-if="loading" class="py-4 flex items-center justify-center w-full h-32">
|
||||
<CommonLoadingIcon size="sm" />
|
||||
</div>
|
||||
<p v-else class="py-4 text-body-xs text-foreground-2">
|
||||
You don't have any projects that can be moved into this workspace. Only projects
|
||||
you own and that aren't in another workspace can be moved.
|
||||
</p>
|
||||
<template v-else>
|
||||
<div
|
||||
v-if="hasMoveableProjects"
|
||||
class="flex flex-col mt-2 border rounded-md border-outline-3"
|
||||
>
|
||||
<div
|
||||
v-for="project in moveableProjects"
|
||||
:key="project.id"
|
||||
class="flex px-4 py-3 items-center space-x-2 justify-between border-b last:border-0 border-outline-3"
|
||||
>
|
||||
<div class="flex flex-col flex-1 truncate text-body-xs">
|
||||
<span class="font-medium text-foreground truncate">
|
||||
{{ project.name }}
|
||||
</span>
|
||||
<div class="flex items-center gap-x-1">
|
||||
<span class="text-foreground-3 truncate">
|
||||
{{ project.modelCount.totalCount }} model{{
|
||||
project.modelCount.totalCount !== 1 ? 's' : ''
|
||||
}}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<FormButton size="sm" color="outline" @click="onMoveClick(project)">
|
||||
Move...
|
||||
</FormButton>
|
||||
</div>
|
||||
</div>
|
||||
<p v-else class="py-4 text-body-xs text-foreground-2">
|
||||
You don't have any projects that can be moved into this workspace. Only projects
|
||||
you own and that aren't in another workspace can be moved.
|
||||
</p>
|
||||
</template>
|
||||
<InfiniteLoading
|
||||
v-if="moveableProjects?.length && !search?.length"
|
||||
:settings="{ identifier }"
|
||||
@@ -52,7 +57,11 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { graphql } from '~~/lib/common/generated/gql'
|
||||
import { FormTextInput, useDebouncedTextInput } from '@speckle/ui-components'
|
||||
import {
|
||||
CommonLoadingIcon,
|
||||
FormTextInput,
|
||||
useDebouncedTextInput
|
||||
} from '@speckle/ui-components'
|
||||
import type { WorkspaceMoveProjectSelectProject_ProjectFragment } from '~~/lib/common/generated/gql/graphql'
|
||||
import { usePaginatedQuery } from '~/lib/common/composables/graphql'
|
||||
import { workspaceMoveProjectManagerUserQuery } from '~/lib/workspaces/graphql/queries'
|
||||
@@ -81,7 +90,7 @@ const emit = defineEmits<{
|
||||
}>()
|
||||
|
||||
const {
|
||||
query: { result },
|
||||
query: { result, loading },
|
||||
identifier,
|
||||
onInfiniteLoad
|
||||
} = usePaginatedQuery({
|
||||
|
||||
@@ -1,65 +1,70 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="flex flex-col space-y-4">
|
||||
<div v-if="hasWorkspaces">
|
||||
<p class="mb-4">Select an existing workspaces or create a new one.</p>
|
||||
<div class="flex flex-col gap-2">
|
||||
<div
|
||||
v-for="ws in workspaces"
|
||||
:key="`${ws.id}-${ws.permissions?.canMoveProjectToWorkspace?.code}`"
|
||||
v-tippy="disabledTooltipText(ws)"
|
||||
>
|
||||
<button
|
||||
class="w-full"
|
||||
:class="
|
||||
!canMoveToWorkspace(ws) && !isLimitReached(ws)
|
||||
? 'cursor-not-allowed'
|
||||
: ''
|
||||
"
|
||||
:disabled="!canMoveToWorkspace(ws) && !isLimitReached(ws)"
|
||||
@click="handleWorkspaceClick(ws)"
|
||||
<div v-if="loading" class="py-4 flex items-center justify-center w-full h-32">
|
||||
<CommonLoadingIcon size="sm" />
|
||||
</div>
|
||||
<template v-else>
|
||||
<div v-if="hasWorkspaces">
|
||||
<p class="mb-4">Select an existing workspaces or create a new one.</p>
|
||||
<div class="flex flex-col gap-2">
|
||||
<div
|
||||
v-for="ws in workspaces"
|
||||
:key="`${ws.id}-${ws.permissions?.canMoveProjectToWorkspace?.code}`"
|
||||
v-tippy="disabledTooltipText(ws)"
|
||||
>
|
||||
<WorkspaceCard
|
||||
:logo="ws.logo ?? ''"
|
||||
:name="ws.name"
|
||||
:clickable="canMoveToWorkspace(ws) || isLimitReached(ws)"
|
||||
<button
|
||||
class="w-full"
|
||||
:class="
|
||||
!canMoveToWorkspace(ws) && !isLimitReached(ws)
|
||||
? 'cursor-not-allowed'
|
||||
: ''
|
||||
"
|
||||
:disabled="!canMoveToWorkspace(ws) && !isLimitReached(ws)"
|
||||
@click="handleWorkspaceClick(ws)"
|
||||
>
|
||||
<template #text>
|
||||
<div class="flex flex-col gap-2 items-start">
|
||||
<CommonBadge
|
||||
v-if="isSsoRequired(ws)"
|
||||
color="secondary"
|
||||
class="capitalize"
|
||||
rounded
|
||||
>
|
||||
SSO login required
|
||||
<WorkspaceCard
|
||||
:logo="ws.logo ?? ''"
|
||||
:name="ws.name"
|
||||
:clickable="canMoveToWorkspace(ws) || isLimitReached(ws)"
|
||||
>
|
||||
<template #text>
|
||||
<div class="flex flex-col gap-2 items-start">
|
||||
<CommonBadge
|
||||
v-if="isSsoRequired(ws)"
|
||||
color="secondary"
|
||||
class="capitalize"
|
||||
rounded
|
||||
>
|
||||
SSO login required
|
||||
</CommonBadge>
|
||||
<p>
|
||||
{{ ws.projects.totalCount }} projects,
|
||||
{{ ws.projects.totalCount }} models
|
||||
</p>
|
||||
<UserAvatarGroup
|
||||
:users="ws.team.items.map((t) => t.user)"
|
||||
:max-count="6"
|
||||
size="sm"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #actions>
|
||||
<CommonBadge color="secondary" rounded>
|
||||
{{ formatName(ws.plan?.name) }}
|
||||
</CommonBadge>
|
||||
<p>
|
||||
{{ ws.projects.totalCount }} projects,
|
||||
{{ ws.projects.totalCount }} models
|
||||
</p>
|
||||
<UserAvatarGroup
|
||||
:users="ws.team.items.map((t) => t.user)"
|
||||
:max-count="6"
|
||||
size="sm"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #actions>
|
||||
<CommonBadge color="secondary" class="capitalize" rounded>
|
||||
{{ ws.plan?.name }}
|
||||
</CommonBadge>
|
||||
</template>
|
||||
</WorkspaceCard>
|
||||
</button>
|
||||
</template>
|
||||
</WorkspaceCard>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p v-else class="text-body-xs text-foreground">
|
||||
Looks like you haven't created any workspaces yet. Workspaces help you easily
|
||||
organise and control your digital projects. Create one to move your project
|
||||
into.
|
||||
</p>
|
||||
<p v-else class="text-body-xs text-foreground">
|
||||
Looks like you haven't created any workspaces yet. Workspaces help you easily
|
||||
organise and control your digital projects. Create one to move your project
|
||||
into.
|
||||
</p>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<WorkspacePlanLimitReachedDialog
|
||||
@@ -83,6 +88,7 @@ import type {
|
||||
import { useQuery } from '@vue/apollo-composable'
|
||||
import { UserAvatarGroup } from '@speckle/ui-components'
|
||||
import { workspaceMoveProjectManagerUserQuery } from '~/lib/workspaces/graphql/queries'
|
||||
import { formatName } from '~/lib/billing/helpers/plan'
|
||||
|
||||
graphql(`
|
||||
fragment WorkspaceMoveProjectSelectWorkspace_User on User {
|
||||
@@ -144,7 +150,7 @@ const emit = defineEmits<{
|
||||
): void
|
||||
}>()
|
||||
|
||||
const { result } = useQuery(workspaceMoveProjectManagerUserQuery, () => ({
|
||||
const { result, loading } = useQuery(workspaceMoveProjectManagerUserQuery, () => ({
|
||||
cursor: null,
|
||||
filter: {},
|
||||
projectId: props.project.id
|
||||
|
||||
Reference in New Issue
Block a user