feat(acc): Omnibus ACC PR 2: The Sequel (#5659)

* fix(acc): disable button on acc item create

* chore(acc): revert temp cors change

* fix(acc): project integrations tab edits

* feat(acc): revise model card

* fix(acc): improve table

* fix(acc): move sync actions to existig menu

* fix(acc): add model button on different size and learn more

* fix(acc): actions that aren't lies

* fix(acc): fix logged out state on sync from ACC button

* chore(acc): bump fct

* fix(acc): re-open dialog

* fix(acc): folder tree overflow

* fix(acc): sticky headers for folders and files

* fix(acc): bump function

---------

Co-authored-by: oguzhankoral <oguzhankoral@gmail.com>
This commit is contained in:
Chuck Driesler
2025-10-07 08:37:46 +01:00
committed by GitHub
parent 1c257b68d3
commit b83dae3867
22 changed files with 879 additions and 389 deletions
@@ -41,7 +41,7 @@
</div>
</div>
<div v-else>
<FormButton size="sm" @click="$emit('upgrade')">Upgrade</FormButton>
<FormButton size="sm" @click="openLearnMore">Learn more</FormButton>
</div>
</div>
</div>
@@ -80,6 +80,10 @@ const statusText = () => {
}
}
const openLearnMore = () => {
window.open('https://docs.speckle.systems/beta/acc/overview', '_blank')
}
const handleCTA = async () => {
if (
integration.value.status === 'notConnected' ||
@@ -1,9 +1,12 @@
<template>
<div class="flex flex-row h-full overflow-hidden border rounded-lg bg-foundation">
<!-- Left Pane for tree -->
<div class="w-1/4 p-2 overflow-y-auto border-r">
<h3 class="font-semibold text-lg text-center">Folders</h3>
<hr class="mb-1" />
<div class="w-1/4 p-2 pt-0 h-80 overflow-y-auto border-r">
<div class="z-10 sticky top-0 bg-foundation pb-1">
<h3 class="font-semibold pt-2 text-lg text-center">Folders</h3>
<hr />
</div>
<div v-if="!rootFolder"></div>
<ul
v-else-if="rootFolder && rootFolder.children?.items.length"
@@ -21,9 +24,12 @@
</ul>
</div>
<!-- Right Pane for content -->
<div class="w-3/4 p-2 overflow-y-auto">
<h3 class="font-semibold text-lg text-center">Files</h3>
<hr class="mb-1" />
<div class="w-3/4 h-80 p-2 pt-0 overflow-y-auto">
<div class="z-10 sticky top-0 bg-foundation pb-1">
<h3 class="pt-2 font-semibold text-lg text-center">Files</h3>
<hr />
</div>
<IntegrationsAccFolderContents
v-if="!!selectedFolderId"
:key="`contents-${selectedFolderId}`"
@@ -1,13 +1,13 @@
<template>
<div v-tippy="statusLabel">
<CommonBadge
:color-classes="
[runStatusClasses(status), 'shrink-0 grow-0 text-foreground'].join(' ')
"
>
ACC
</CommonBadge>
</div>
<CommonBadge
v-tippy="statusTooltip"
class="bg-"
:color-classes="
[runStatusClasses(status), 'shrink-0 grow-0 text-foreground'].join(' ')
"
>
ACC
</CommonBadge>
</template>
<script setup lang="ts">
@@ -21,6 +21,8 @@ graphql(`
fragment SyncStatusModelItem_AccSyncItem on AccSyncItem {
id
status
updatedAt
accFileVersionIndex
}
`)
@@ -28,21 +30,41 @@ const props = defineProps<{
item: SyncStatusModelItem_AccSyncItemFragment
}>()
const { formattedRelativeDate } = useDateFormatters()
const status = computed(() => props.item.status)
const statusLabel = computed(
() => status.value.charAt(0).toUpperCase() + status.value.slice(1)
const statusTooltip = computed(
() =>
`V${props.item.accFileVersionIndex} ${getStatusDescription(
props.item.status
)} ${formattedRelativeDate(props.item.updatedAt)}`
)
const getStatusDescription = (status: AccSyncItemStatus): string => {
switch (status) {
case 'failed':
return 'failed to sync'
case 'pending':
return 'scheduled for sync'
case 'paused':
return 'sync paused'
case 'succeeded':
return 'updated'
case 'syncing':
return 'processing since'
default:
return ''
}
}
const runStatusClasses = (run: AccSyncItemStatus) => {
const classParts = ['w-24 justify-center']
const classParts = ['w-12 justify-center']
switch (run) {
case 'syncing':
classParts.push('bg-info-lighter')
break
case 'pending':
classParts.push('bg-warning-lighter')
break
case 'paused':
classParts.push('bg-warning-lighter')
break
@@ -50,7 +72,7 @@ const runStatusClasses = (run: AccSyncItemStatus) => {
classParts.push('bg-danger-lighter')
break
case 'succeeded':
classParts.push('bg-success-lighter')
classParts.push('bg-foundation-2')
break
}
@@ -1,53 +1,52 @@
<template>
<div class="flex flex-col space-y-2">
<div class="flex text-body-xs text-foreground font-medium">Sync models</div>
<LayoutTable
class="bg-foundation"
class="mt-6 bg-foundation"
:columns="[
{ id: 'status', header: 'Status', classes: 'col-span-2' },
{ id: 'accFileName', header: 'File name', classes: 'col-span-2' },
{ id: 'accFileViewName', header: 'View name', classes: 'col-span-2' },
{ id: 'modelId', header: 'Model id', classes: 'col-span-2' },
{ id: 'createdBy', header: 'Created by', classes: 'col-span-2' },
{ id: 'actions', header: 'Actions', classes: 'col-span-2' }
{ id: 'file', header: 'File', classes: 'col-span-4' },
{ id: 'status', header: 'Status', classes: 'col-span-4' },
{ id: 'createdBy', header: 'Created by', classes: 'col-span-3' },
{
id: 'actions',
header: '',
classes: 'col-span-1 flex items-center justify-end'
}
]"
:items="accSyncItems"
>
<template #file="{ item }">
<div class="flex flex-col items-start overflow-hidden">
<NuxtLink
class="text-foreground-1 hover:text-blue-500 underline"
:to="`/projects/${projectId}/models/${item.model?.id}`"
>
{{ item.accFileName }}
</NuxtLink>
<p
v-if="item.accFileViewName"
v-tippy="getViewNameLabel(item.accFileViewName)"
class="text-ellipsis w-full whitespace-nowrap text-foreground-2 overflow-hidden"
>
{{ item.accFileViewName }}
</p>
</div>
</template>
<template #status="{ item }">
<IntegrationsAccSyncStatus :status="item.status" />
</template>
<template #accFileName="{ item }">
{{ item.accFileName }}
</template>
<template #accFileViewName="{ item }">
{{ item.accFileViewName || '-' }}
</template>
<template #modelId="{ item }">
<NuxtLink
class="text-foreground-1 hover:text-blue-500 underline"
:to="`/projects/${projectId}/models/${item.model?.id}`"
>
{{ item.model?.id }}
</NuxtLink>
<div class="flex items-center space-x-1">
<CommonBadge
v-tippy="formattedFullDate(item.updatedAt)"
color-classes="w-12 bg-info-lighter justify-center"
>
{{ getVersionLabel(item.accFileVersionIndex) }}
</CommonBadge>
<IntegrationsAccSyncStatus :status="item.status" />
</div>
</template>
<template #createdBy="{ item }">
{{ item.author?.name }}
</template>
<template #actions="{ item }">
<div class="space-x-2">
<FormButton
hide-text
color="outline"
:icon-left="item.status === 'paused' ? PlayIcon : PauseIcon"
@click="handleStatusSyncItem(item.id, item.status === 'paused')"
/>
<FormButton
hide-text
color="outline"
:icon-left="TrashIcon"
@click="handleDeleteSyncItem(item.id)"
/>
</div>
<IntegrationsAccActionsMenu :target-sync-item="item" />
</template>
</LayoutTable>
</div>
@@ -55,15 +54,9 @@
<script setup lang="ts">
import type { AccTokens } from '@speckle/shared/acc'
import { useMutation, useQuery, useSubscription } from '@vue/apollo-composable'
import {
accSyncItemDeleteMutation,
accSyncItemUpdateMutation
} from '~/lib/acc/graphql/mutations'
import { useQuery, useSubscription } from '@vue/apollo-composable'
import { projectAccSyncItemsQuery } from '~/lib/acc/graphql/queries'
import { onProjectAccSyncItemUpdatedSubscription } from '~/lib/acc/graphql/subscriptions'
import { PauseIcon } from '@heroicons/vue/24/solid'
import { TrashIcon, PlayIcon } from '@heroicons/vue/24/outline'
const props = defineProps<{
projectId: string
@@ -72,6 +65,7 @@ const props = defineProps<{
}>()
const { triggerNotification } = useGlobalToast()
const { formattedFullDate } = useDateFormatters()
const { result: accSyncItemsResult, refetch: refetchAccSyncItems } = useQuery(
projectAccSyncItemsQuery,
@@ -91,6 +85,14 @@ const { onResult: onProjectAccSyncItemsUpdated } = useSubscription(
})
)
const getVersionLabel = (versionNumber: number): string => {
return `V${versionNumber}`
}
const getViewNameLabel = (viewName: string): string => {
return `Revit View: ${viewName}`
}
onProjectAccSyncItemsUpdated((res) => {
// TODO ACC: Mutate local cache instead of refetch
refetchAccSyncItems()
@@ -100,43 +102,4 @@ onProjectAccSyncItemsUpdated((res) => {
description: res.data?.projectAccSyncItemsUpdated.accSyncItem?.accFileName
})
})
const { mutate: deleteAccSyncItem } = useMutation(accSyncItemDeleteMutation)
const handleDeleteSyncItem = async (id: string) => {
try {
await deleteAccSyncItem({
input: {
projectId: props.projectId,
id
}
})
} catch (error) {
triggerNotification({
type: ToastNotificationType.Danger,
title: 'Delete sync item failed',
description: error instanceof Error ? error.message : 'Unexpected error'
})
}
}
const { mutate: updateAccSyncItem } = useMutation(accSyncItemUpdateMutation)
const handleStatusSyncItem = async (id: string, isPaused: boolean) => {
try {
await updateAccSyncItem({
input: {
projectId: props.projectId,
id,
status: isPaused ? 'pending' : 'paused'
}
})
} catch (error) {
triggerNotification({
type: ToastNotificationType.Danger,
title: 'Update sync item failed',
description: error instanceof Error ? error.message : 'Unexpected error'
})
}
}
</script>
@@ -0,0 +1,90 @@
<template>
<div>
<LayoutMenu
v-model:open="showMenu"
:items="actionItems"
size="lg"
mount-menu-on-body
:menu-position="HorizontalDirection.Left"
:menu-id="`acc-sync-items-${targetSyncItem.id}`"
@chosen="({ item }) => onActionChosen(item.id)"
>
<FormButton
:color="showMenu ? 'outline' : 'subtle'"
hide-text
:icon-right="showMenu ? XMarkIcon : EllipsisHorizontalIcon"
@click="toggleMenu"
/>
</LayoutMenu>
</div>
</template>
<script setup lang="ts">
import { HorizontalDirection, type LayoutMenuItem } from '@speckle/ui-components'
import { EllipsisHorizontalIcon, XMarkIcon } from '@heroicons/vue/24/outline'
import { graphql } from '~/lib/common/generated/gql'
import type { SettingsProjectIntegrationsActionsMenu_AccSyncItemFragment } from '~/lib/common/generated/gql/graphql'
import { useDeleteAccSyncItem } from '~/lib/acc/composables/useDeleteAccSyncItem'
import { useUpdateAccSyncItem } from '~/lib/acc/composables/useUpdateAccSyncItem'
graphql(`
fragment SettingsProjectIntegrationsActionsMenu_AccSyncItem on AccSyncItem {
id
status
project {
id
}
}
`)
const props = defineProps<{
targetSyncItem: SettingsProjectIntegrationsActionsMenu_AccSyncItemFragment
}>()
const showMenu = ref(false)
const projectId = computed(() => props.targetSyncItem.project.id)
const isPaused = computed(() => props.targetSyncItem.status === 'paused')
const actionItems = computed<LayoutMenuItem[][]>(() => [
[
{
title: isPaused.value ? 'Trigger sync...' : 'Pause sync...',
id: 'trigger'
},
{
title: 'Delete sync...',
id: 'delete'
}
]
])
const deleteAccSyncItem = useDeleteAccSyncItem()
const handleDeleteSyncItem = async (id: string) => {
await deleteAccSyncItem(projectId.value, id)
}
const updateAccSyncItem = useUpdateAccSyncItem()
const handleStatusSyncItem = async (id: string) => {
await updateAccSyncItem(projectId.value, id, isPaused.value ? 'pending' : 'paused')
}
const onActionChosen = (actionItem: string) => {
switch (actionItem) {
case 'trigger': {
handleStatusSyncItem(props.targetSyncItem.id)
break
}
case 'delete': {
handleDeleteSyncItem(props.targetSyncItem.id)
break
}
}
}
const toggleMenu = () => {
showMenu.value = !showMenu.value
}
</script>
@@ -45,7 +45,6 @@
<script setup lang="ts">
import type { AccHub } from '@speckle/shared/acc'
import type { LayoutDialogButton } from '@speckle/ui-components'
import { useMutation } from '@vue/apollo-composable'
import { useForm } from 'vee-validate'
import { useAccAuthManager } from '~/lib/acc/composables/useAccAuthManager'
import {
@@ -53,8 +52,7 @@ import {
type AccFolder,
type AccItemVersion
} from '~/lib/acc/composables/useAccFiles'
import { accSyncItemCreateMutation } from '~/lib/acc/graphql/mutations'
import { useCreateNewModel } from '~/lib/projects/composables/modelManagement'
import { useCreateAccSyncItem } from '~/lib/acc/composables/useCreateAccSyncItem'
type FormValues = { feedback: string }
@@ -68,21 +66,26 @@ const props = defineProps<{
const isOpen = defineModel<boolean>('open', { required: true })
const isCreatingSyncItem = ref(false)
const disableCreateButton = computed(() => !!isCreatingSyncItem.value)
const { handleSubmit } = useForm<FormValues>()
const dialogButtons = computed((): LayoutDialogButton[] => [
{
text: 'Create',
props: { color: 'primary' },
props: { color: 'primary', loading: isCreatingSyncItem.value },
onClick: () => {
onSubmit()
},
disabled: disableCreateButton.value,
disabledMessage: 'Creating ACC sync...',
id: 'createAccSync'
}
])
const { triggerNotification } = useGlobalToast()
const createModel = useCreateNewModel()
const createAccSyncItem = useCreateAccSyncItem()
const dialogTitle = computed(() => props.title || 'Create sync from ACC')
@@ -132,39 +135,28 @@ const onFileSelected = (fileId: string, fileVersion: AccItemVersion) => {
selectedFileVersion.value = fileVersion
}
const { mutate: createAccSyncItem } = useMutation(accSyncItemCreateMutation)
const addSync = async () => {
try {
if (!selectedFileVersion.value || !selectedFileVersion.value.fileType) {
return
}
isCreatingSyncItem.value = true
const fileVersion = selectedFileVersion.value.versionNumber
const accFileViewName = revitViewName.value === '' ? undefined : revitViewName.value
const res = await createModel({
name: selectedFileVersion.value.name,
description: '',
projectId: props.projectId as string
})
await createAccSyncItem({
input: {
projectId: props.projectId as string,
modelId: res?.id as string,
accRegion: selectedHub.value?.attributes?.region as string,
accFileExtension: selectedFileVersion.value.fileType,
accHubId: selectedHubId.value!,
accProjectId: selectedProjectId.value as string,
accRootProjectFolderUrn: rootProjectFolderId.value!,
accFileLineageUrn: selectedFileId.value as string,
accFileName: selectedFileVersion.value.name,
accFileVersionIndex: fileVersion,
accFileVersionUrn: selectedFileVersion.value.id,
accFileViewName
}
projectId: props.projectId as string,
accRegion: selectedHub.value?.attributes?.region as string,
accFileExtension: selectedFileVersion.value.fileType,
accHubId: selectedHubId.value!,
accProjectId: selectedProjectId.value as string,
accRootProjectFolderUrn: rootProjectFolderId.value!,
accFileLineageUrn: selectedFileId.value as string,
accFileName: selectedFileVersion.value.name,
accFileVersionIndex: fileVersion,
accFileVersionUrn: selectedFileVersion.value.id,
accFileViewName
})
} catch (error) {
triggerNotification({
@@ -173,6 +165,7 @@ const addSync = async () => {
description: error instanceof Error ? error.message : 'Unexpected error'
})
} finally {
isCreatingSyncItem.value = false
revitViewName.value = undefined
}
}
@@ -40,6 +40,12 @@
:project-id="project.id"
:model-id="model.id"
/>
<ProjectPageModelsCardRemoveSyncDialog
v-if="accSyncItem"
v-model:open="isRemoveSyncDialogOpen"
:project-id="project.id"
:sync-item="accSyncItem"
/>
</div>
</template>
<script setup lang="ts">
@@ -57,6 +63,7 @@ import { HorizontalDirection } from '~~/lib/common/composables/window'
import { useActiveUser } from '~~/lib/auth/composables/activeUser'
import { modelVersionsRoute } from '~/lib/common/helpers/route'
import { useWorkspacePlan } from '~/lib/workspaces/composables/plan'
import { useUpdateAccSyncItem } from '~/lib/acc/composables/useUpdateAccSyncItem'
graphql(`
fragment ProjectPageModelsActions on Model {
@@ -73,6 +80,10 @@ graphql(`
...FullPermissionCheckResult
}
}
accSyncItem {
id
...ProjectPageModelsActions_AccSyncItem
}
...UseCopyModelLink_Model
}
`)
@@ -84,16 +95,31 @@ graphql(`
id
slug
}
permissions {
canReadAccIntegrationSettings {
...FullPermissionCheckResult
}
}
...ProjectsModelPageEmbed_Project
}
`)
graphql(`
fragment ProjectPageModelsActions_AccSyncItem on AccSyncItem {
id
accFileName
status
}
`)
enum ActionTypes {
Rename = 'rename',
Delete = 'delete',
Share = 'share',
ViewVersions = 'view-versions',
UploadVersion = 'upload-version',
ToggleSyncPause = 'toggle-sync-pause',
DeleteSync = 'delete-sync',
CopyId = 'copy-id',
Embed = 'embed',
ViewUploads = 'view-uploads'
@@ -125,9 +151,15 @@ const { statusIsCanceled } = useWorkspacePlan(props.project.workspace?.slug || '
const showActionsMenu = ref(false)
const openDialog = ref(null as Nullable<ActionTypes>)
const accSyncItem = computed(() => props.model.accSyncItem)
const updateAccSyncItem = useUpdateAccSyncItem()
const canEdit = computed(() => props.model.permissions.canUpdate)
const canDelete = computed(() => props.model.permissions.canDelete)
const canCreateVersion = computed(() => props.model.permissions.canCreateVersion)
const canEditAccSync = computed(
() => props.project.permissions.canReadAccIntegrationSettings
)
const uploadVersionDisabled = computed(() => {
if (canCreateVersion.value.code === 'WORKSPACES_NOT_AUTHORIZED_ERROR') {
@@ -169,26 +201,42 @@ const actionsItems = computed<LayoutMenuItem[][]>(() => [
]
]
: []),
[
{
title: 'View versions',
id: ActionTypes.ViewVersions
},
{
title: 'View uploads',
id: ActionTypes.ViewUploads
},
...(isLoggedIn.value
? [
{
title: 'Upload new version...',
id: ActionTypes.UploadVersion,
disabled: uploadVersionDisabled.value.disabled,
disabledTooltip: uploadVersionDisabled.value.tooltip
}
]
: [])
],
accSyncItem.value
? [
{
title:
accSyncItem.value?.status === 'paused' ? 'Resume sync...' : 'Pause sync...',
id: ActionTypes.ToggleSyncPause,
disabled: !canEditAccSync.value.authorized,
disabledTooltip: canEditAccSync.value.message
},
{
title: 'Remove sync...',
id: ActionTypes.DeleteSync,
disabled: !canEditAccSync.value.authorized,
disabledTooltip: canEditAccSync.value.message
}
]
: [
{
title: 'View versions',
id: ActionTypes.ViewVersions
},
{
title: 'View uploads',
id: ActionTypes.ViewUploads
},
...(isLoggedIn.value
? [
{
title: 'Upload new version...',
id: ActionTypes.UploadVersion,
disabled: uploadVersionDisabled.value.disabled,
disabledTooltip: uploadVersionDisabled.value.tooltip
}
]
: [])
],
[
{ title: 'Copy link', id: ActionTypes.Share },
{ title: 'Copy ID', id: ActionTypes.CopyId },
@@ -225,6 +273,10 @@ const isUploadsDialogOpen = computed({
get: () => openDialog.value === ActionTypes.ViewUploads,
set: (isOpen) => (openDialog.value = isOpen ? ActionTypes.ViewUploads : null)
})
const isRemoveSyncDialogOpen = computed({
get: () => openDialog.value === ActionTypes.DeleteSync,
set: (isOpen) => (openDialog.value = isOpen ? ActionTypes.DeleteSync : null)
})
const onActionChosen = (params: { item: LayoutMenuItem; event: MouseEvent }) => {
const { item } = params
@@ -234,8 +286,17 @@ const onActionChosen = (params: { item: LayoutMenuItem; event: MouseEvent }) =>
case ActionTypes.Delete:
case ActionTypes.Embed:
case ActionTypes.ViewUploads:
case ActionTypes.DeleteSync:
openDialog.value = item.id
break
case ActionTypes.ToggleSyncPause:
if (!accSyncItem.value) return
updateAccSyncItem(
props.project.id,
accSyncItem.value?.id,
accSyncItem.value.status === 'paused' ? 'pending' : 'paused'
)
break
case ActionTypes.Share:
mp.track('Branch Action', { type: 'action', name: 'share' })
void copyModelLink({ model: props.model })
@@ -19,24 +19,30 @@
v-tippy="canCreateModel.cantClickCreateReason.value"
class="grow inline-flex sm:grow-0 lg:hidden"
>
<FormButton
:disabled="!canCreateModel.canClickCreate.value"
@click="handleCreateModelClick"
<LayoutMenu
v-if="showAccIntegration"
v-model:open="showMenu"
:items="menuItems"
:menu-position="HorizontalDirection.Left"
:menu-id="menuId"
@click.stop.prevent
@chosen="onActionChosen"
>
New model
</FormButton>
</div>
<!-- I believe for now sync limits corralate with model limit since new sync creates new model, once we have limits for syncs, this should change -->
<div
v-tippy="canCreateModel.cantClickCreateReason.value"
class="grow inline-flex sm:grow-0 lg:hidden"
>
<FormButton
:disabled="!canCreateModel.canClickCreate.value"
@click="showNewAccSync = true"
>
New sync
</FormButton>
<FormButton color="primary" @click="showMenu = !showMenu">
<div class="flex items-center gap-1">
Add model
<ChevronDownIcon class="h-3 w-3" />
</div>
</FormButton>
</LayoutMenu>
<div v-else v-tippy="canCreateModel.cantClickCreateReason.value">
<FormButton
:disabled="!canCreateModel.canClickCreate.value"
@click="handleCreateModelClick"
>
New model
</FormButton>
</div>
</div>
</div>
</div>
@@ -90,36 +96,40 @@
>
View all in 3D
</FormButton>
<LayoutMenu
v-if="showAccIntegration"
v-model:open="showMenu"
:items="menuItems"
:menu-position="HorizontalDirection.Left"
:menu-id="menuId"
@click.stop.prevent
@chosen="onActionChosen"
>
<FormButton color="primary" @click="showMenu = !showMenu">
<div class="flex items-center gap-1">
Add model
<ChevronDownIcon class="h-3 w-3" />
</div>
</FormButton>
</LayoutMenu>
<div v-else v-tippy="canCreateModel.cantClickCreateReason.value">
<FormButton
:disabled="!canCreateModel.canClickCreate.value"
class="hidden lg:inline-flex shrink-0"
@click="handleCreateModelClick"
<div class="hidden lg:inline-flex shrink-0">
<LayoutMenu
v-if="showAccIntegration"
v-model:open="showMenu"
:items="menuItems"
:menu-position="HorizontalDirection.Left"
:menu-id="menuId"
@click.stop.prevent
@chosen="onActionChosen"
>
New model
</FormButton>
<FormButton color="primary" @click="showMenu = !showMenu">
<div class="flex items-center gap-1">
Add model
<ChevronDownIcon class="h-3 w-3" />
</div>
</FormButton>
</LayoutMenu>
<div v-else v-tippy="canCreateModel.cantClickCreateReason.value">
<FormButton
:disabled="!canCreateModel.canClickCreate.value"
@click="handleCreateModelClick"
>
New model
</FormButton>
</div>
</div>
</div>
</div>
</div>
<ProjectModelsAdd v-model:open="showNewDialog" :project="project" />
<IntegrationsAccDialogCreateSync :open="showNewAccSync" :project-id="project?.id" />
<IntegrationsAccDialogCreateSync
v-model:open="showNewAccSync"
:project-id="project?.id"
/>
</div>
</template>
<script setup lang="ts">
@@ -132,7 +142,10 @@ import type {
FormUsersSelectItemFragment,
ProjectModelsPageHeader_ProjectFragment
} from '~~/lib/common/generated/gql/graphql'
import { modelRoute } from '~~/lib/common/helpers/route'
import {
modelRoute,
workspaceIntegrationSettingsRoute
} from '~~/lib/common/helpers/route'
import type {
GridListToggleValue,
LayoutMenuItem
@@ -140,6 +153,7 @@ import type {
import { useMixpanel } from '~~/lib/core/composables/mp'
import { useCanCreateModel } from '~/lib/projects/composables/permissions'
import { HorizontalDirection } from '@speckle/ui-components'
import { useAccIntegration } from '~/lib/integrations/composables/useAccIntegration'
const emit = defineEmits<{
(e: 'update:selected-members', val: FormUsersSelectItemFragment[]): void
@@ -268,6 +282,8 @@ enum AddNewModelActionTypes {
NewAccSyncItem = 'new-acc-sync-item'
}
const { integration, checkConnection } = useAccIntegration()
const menuItems = computed<LayoutMenuItem[][]>(() => [
[
{
@@ -288,7 +304,7 @@ const menuItems = computed<LayoutMenuItem[][]>(() => [
]
])
const onActionChosen = (params: { item: LayoutMenuItem; event: MouseEvent }) => {
const onActionChosen = async (params: { item: LayoutMenuItem; event: MouseEvent }) => {
const { item } = params
switch (item.id) {
@@ -296,7 +312,17 @@ const onActionChosen = (params: { item: LayoutMenuItem; event: MouseEvent }) =>
handleCreateModelClick()
break
case AddNewModelActionTypes.NewAccSyncItem:
showNewAccSync.value = true
// need to check connection before meaningful action. it will refresh the crediantials
await checkConnection(
props.project?.workspace?.slug as string,
props.project?.workspace?.id as string
)
if (integration.value.status === 'connected') {
showNewAccSync.value = true
} else {
router.push(workspaceIntegrationSettingsRoute(props.project?.workspace?.slug))
}
break
}
}
@@ -24,6 +24,11 @@
>
<ExclamationCircleIcon class="w-4 h-4" />
</NuxtLink>
<IntegrationsAccSyncStatusModelItem
v-if="accSyncItem"
v-tippy=""
:item="accSyncItem"
/>
<ProjectPageModelsActions
ref="actions"
v-model:open="showActionsMenu"
@@ -55,9 +60,6 @@
submodel
</FormButton>
</div>
<div v-if="accSyncItem" class="flex items-center ml-2">
<IntegrationsAccSyncStatusModelItem :item="accSyncItem" />
</div>
<!-- Spacer -->
<div class="flex-grow"></div>
@@ -78,7 +80,7 @@
/>
<!-- Import area must exist even if hidden, so that we can trigger uploads from actions -->
<ProjectCardImportFileArea
v-show="!pendingVersion"
v-show="!pendingVersion && !accSyncItem"
ref="importArea"
empty-state-variant="modelList"
:project="project"
@@ -313,6 +315,7 @@ graphql(`
...ProjectCardImportFileArea_Model
...ProjectPageModelsCard_Model
accSyncItem {
id
...SyncStatusModelItem_AccSyncItem
}
}
@@ -321,10 +324,6 @@ graphql(`
}
`)
const isPendingFileUpload = (
i: SingleLevelModelTreeItemFragment | PendingFileUploadFragment
): i is PendingFileUploadFragment => has(i, 'uploadDate')
const emit = defineEmits<{
(e: 'model-updated'): void
(e: 'create-submodel', parentModelName: string): void
@@ -343,6 +342,10 @@ const accSyncItem = computed(() =>
props.item.__typename === 'ModelsTreeItem' ? props.item.model?.accSyncItem : undefined
)
const isPendingFileUpload = (
i: SingleLevelModelTreeItemFragment | PendingFileUploadFragment
): i is PendingFileUploadFragment => has(i, 'uploadDate')
const importArea = ref(
null as Nullable<{
triggerPicker: () => void
@@ -0,0 +1,49 @@
<template>
<LayoutDialog
v-model:open="open"
max-width="sm"
hide-closer
:buttons="[
{
text: 'Cancel',
props: { color: 'outline' },
onClick: () => {
open = false
}
},
{
text: 'Remove',
props: { color: 'danger' },
onClick: onConfirm
}
]"
>
<template #header>Remove sync</template>
</LayoutDialog>
</template>
<script setup lang="ts">
import { useDeleteAccSyncItem } from '~/lib/acc/composables/useDeleteAccSyncItem'
import type { ProjectPageModelRemoveSyncDialog_AccSyncItemFragment } from '~/lib/common/generated/gql/graphql'
import { graphql } from '~~/lib/common/generated/gql'
graphql(`
fragment ProjectPageModelRemoveSyncDialog_AccSyncItem on AccSyncItem {
id
accFileName
}
`)
const props = defineProps<{
projectId: string
syncItem: ProjectPageModelRemoveSyncDialog_AccSyncItemFragment
}>()
const open = defineModel<boolean>('open', { required: true })
const deleteAccSyncItem = useDeleteAccSyncItem()
const onConfirm = async () => {
await deleteAccSyncItem(props.projectId, props.syncItem.id)
}
</script>
@@ -1,64 +1,57 @@
<template>
<div class="flex flex-col text-xs space-y-2">
<ProjectPageSettingsBlock :auth-check="canUpdate" title="ACC">
<template #top-buttons>
<FormButton
color="outline"
to="https://docs.speckle.systems/beta/acc/overview"
external
target="_blank"
>
Docs
</FormButton>
<FormButton :disabled="!canUpdate?.authorized">New</FormButton>
</template>
<IntegrationsAccSyncs
:project-id="projectId"
:is-logged-in="hasTokens"
:tokens="tokens"
/>
<ClientOnly>
<div v-if="!hasTokens">
<CommonLoadingBar v-if="loadingTokens" :loading="true" class="my-2" />
<div v-else>
<hr class="mb-2" />
<FormButton size="sm" @click="authAcc(`/projects/${projectId}/acc`)">
Connect to ACC
</FormButton>
</div>
</div>
<!-- USER INFO -->
<div v-if="userInfo" class="flex flex-col space-y-2">
<hr class="my-2" />
<div class="flex flex-col text ml-1 space-y-2 mb-2">
<span>
<strong>Name:</strong>
{{ userInfo.firstName }} {{ userInfo.lastName }}
</span>
<span>
<strong>Email:</strong>
{{ userInfo.emailId }}
</span>
<span>
<strong>User ID:</strong>
{{ userInfo.userId }}
</span>
</div>
</div>
</ClientOnly>
</div>
</ProjectPageSettingsBlock>
</template>
<script setup lang="ts">
import { useQuery } from '@vue/apollo-composable'
import { useAccAuthManager } from '~/lib/acc/composables/useAccAuthManager'
import { useAccUser } from '~/lib/acc/composables/useAccUser'
import { graphql } from '~/lib/common/generated/gql'
import { projectIntegrationsQuery } from '~/lib/projects/graphql/queries'
defineProps<{ projectId: string }>()
graphql(`
fragment ProjectPageSettingsIntegrations_Project on Project {
id
permissions {
canReadAccIntegrationSettings {
...FullPermissionCheckResult
}
}
}
`)
const route = useRoute()
const projectId = computed(() => route.params.id as string)
const hasTokens = computed(() => !!tokens.value?.access_token)
const { tokens, loadingTokens, authAcc, tryGetTokensFromCookies } = useAccAuthManager()
const { userInfo, fetchUserInfo } = useAccUser()
const { tokens, tryGetTokensFromCookies } = useAccAuthManager()
watch(tokens, async (newTokens) => {
if (newTokens?.access_token) {
await fetchUserInfo(newTokens?.access_token)
}
})
const { result } = useQuery(projectIntegrationsQuery, () => ({
projectId: projectId.value
}))
const canUpdate = computed(
() => result.value?.project?.permissions?.canReadAccIntegrationSettings
)
onMounted(async () => {
await tryGetTokensFromCookies()
if (tokens.value) {
await fetchUserInfo(tokens.value?.access_token)
}
})
</script>
@@ -0,0 +1,80 @@
import { useApolloClient } from '@vue/apollo-composable'
import { accSyncItemCreateMutation } from '~/lib/acc/graphql/mutations'
import { useCreateNewModel } from '~/lib/projects/composables/modelManagement'
export const useCreateAccSyncItem = () => {
const apollo = useApolloClient().client
const { triggerNotification } = useGlobalToast()
const createModel = useCreateNewModel()
return async (args: {
projectId: string
accRegion: string
accFileExtension: string
accHubId: string
accProjectId: string
accRootProjectFolderUrn: string
accFileLineageUrn: string
accFileName: string
accFileVersionIndex: number
accFileVersionUrn: string
accFileViewName?: string
}) => {
try {
const model = await createModel({
name: args.accFileName,
description: '',
projectId: args.projectId
})
if (!model) {
throw new Error('Failed to create model')
}
await apollo.mutate({
mutation: accSyncItemCreateMutation,
variables: {
input: {
projectId: args.projectId,
modelId: model.id,
accHubId: args.accHubId,
accRegion: args.accRegion,
accProjectId: args.accProjectId,
accRootProjectFolderUrn: args.accRootProjectFolderUrn,
accFileLineageUrn: args.accFileLineageUrn,
accFileVersionUrn: args.accFileVersionUrn,
accFileName: args.accFileName,
accFileExtension: args.accFileExtension,
accFileVersionIndex: args.accFileVersionIndex,
accFileViewName: args.accFileViewName
}
},
update: (cache, { data }) => {
if (!data?.accSyncItemMutations.create) return
const newSyncItem = data.accSyncItemMutations.create
cache.modify({
id: getCacheId('Model', model.id),
fields: {
accSyncItem: () => newSyncItem
}
})
cache.modify({
id: getCacheId('Project', args.projectId),
fields: {
accSyncItems: (value) => {
const syncItems = value ?? []
return [newSyncItem, ...syncItems]
}
}
})
}
})
} catch (e) {
triggerNotification({
type: ToastNotificationType.Danger,
title: 'Failed to sync with ACC',
description: e instanceof Error ? e.message : 'Unexpected error'
})
}
}
}
@@ -0,0 +1,52 @@
import { useApolloClient } from '@vue/apollo-composable'
import { accSyncItemDeleteMutation } from '~/lib/acc/graphql/mutations'
import type { AccSyncItem } from '~/lib/acc/types'
import { getCacheKey } from '~/lib/common/helpers/graphql'
export const useDeleteAccSyncItem = () => {
const apollo = useApolloClient()
const { triggerNotification } = useGlobalToast()
return async (projectId: string, accSyncItemId: string) => {
const result = await apollo.client
.mutate({
mutation: accSyncItemDeleteMutation,
variables: {
input: {
id: accSyncItemId,
projectId
}
},
update: (cache) => {
cache.evict({
id: getCacheKey('AccSyncItem', accSyncItemId)
})
cache.modify({
id: getCacheKey('Project', accSyncItemId),
fields: {
accSyncItems: (existingRefs = [], { readField }) => {
return existingRefs.filter(
(ref: AccSyncItem) => readField('id', ref) !== accSyncItemId
)
}
}
})
}
})
.catch(convertThrowIntoFetchResult)
if (result.data) {
triggerNotification({
type: ToastNotificationType.Success,
title: 'ACC sync deleted',
description: `Your model is no longer linked with an ACC file.`
})
} else {
const errMsg = getFirstGqlErrorMessage(result?.errors)
triggerNotification({
type: ToastNotificationType.Danger,
title: errMsg
})
}
}
}
@@ -0,0 +1,50 @@
import { useApolloClient } from '@vue/apollo-composable'
import { accSyncItemUpdateMutation } from '~/lib/acc/graphql/mutations'
import type { AccSyncItemStatus } from '~/lib/acc/types'
import { getCacheKey } from '~/lib/common/helpers/graphql'
export const useUpdateAccSyncItem = () => {
const apollo = useApolloClient()
const { triggerNotification } = useGlobalToast()
return async (
projectId: string,
accSyncItemId: string,
status: AccSyncItemStatus
) => {
const result = await apollo.client
.mutate({
mutation: accSyncItemUpdateMutation,
variables: {
input: {
id: accSyncItemId,
projectId,
status
}
},
update: (cache) => {
cache.modify({
id: getCacheKey('AccSyncItem', accSyncItemId),
fields: {
status: () => status
}
})
}
})
.catch(convertThrowIntoFetchResult)
if (result.data) {
triggerNotification({
type: ToastNotificationType.Success,
title: 'ACC sync updated',
description: 'Successfully updated ACC sync'
})
} else {
const errMsg = getFirstGqlErrorMessage(result?.errors)
triggerNotification({
type: ToastNotificationType.Danger,
title: errMsg
})
}
}
}
@@ -5,9 +5,11 @@ export const projectAccSyncItemFragment = graphql(`
id
project {
id
name
}
model {
id
name
}
accRegion
accHubId
@@ -5,7 +5,17 @@ export const accSyncItemCreateMutation = graphql(`
accSyncItemMutations {
create(input: $input) {
id
model {
id
name
}
author {
id
name
}
accFileName
accFileLineageUrn
accFileViewName
status
}
}
@@ -64,7 +64,8 @@ type Documents = {
"\n fragment HeaderNavNotificationsProjectInvite_PendingStreamCollaborator on PendingStreamCollaborator {\n id\n invitedBy {\n ...LimitedUserAvatar\n }\n projectId\n projectName\n token\n workspaceSlug\n user {\n id\n }\n }\n": typeof types.HeaderNavNotificationsProjectInvite_PendingStreamCollaboratorFragmentDoc,
"\n fragment HeaderNavNotificationsWorkspaceInvite_PendingWorkspaceCollaborator on PendingWorkspaceCollaborator {\n id\n invitedBy {\n id\n ...LimitedUserAvatar\n }\n workspace {\n id\n name\n }\n token\n user {\n id\n }\n ...UseWorkspaceInviteManager_PendingWorkspaceCollaborator\n }\n": typeof types.HeaderNavNotificationsWorkspaceInvite_PendingWorkspaceCollaboratorFragmentDoc,
"\n fragment AccIntegrationFolderNode_AccFolder on AccFolder {\n id\n name\n contents {\n items {\n id\n name\n latestVersion {\n id\n name\n versionNumber\n fileType\n }\n }\n }\n children {\n items {\n id\n name\n children {\n items {\n id\n name\n }\n }\n contents {\n items {\n id\n name\n }\n }\n }\n }\n }\n": typeof types.AccIntegrationFolderNode_AccFolderFragmentDoc,
"\n fragment SyncStatusModelItem_AccSyncItem on AccSyncItem {\n id\n status\n }\n": typeof types.SyncStatusModelItem_AccSyncItemFragmentDoc,
"\n fragment SyncStatusModelItem_AccSyncItem on AccSyncItem {\n id\n status\n updatedAt\n accFileVersionIndex\n }\n": typeof types.SyncStatusModelItem_AccSyncItemFragmentDoc,
"\n fragment SettingsProjectIntegrationsActionsMenu_AccSyncItem on AccSyncItem {\n id\n status\n project {\n id\n }\n }\n": typeof types.SettingsProjectIntegrationsActionsMenu_AccSyncItemFragmentDoc,
"\n fragment InviteDialogWorkspace_Workspace on Workspace {\n id\n name\n slug\n domainBasedMembershipProtectionEnabled\n defaultSeatType\n domains {\n domain\n id\n }\n seats {\n editors {\n available\n }\n }\n ...InviteDialogSharedSelectUsers_Workspace\n ...WorkspacesPlan_Workspace\n }\n": typeof types.InviteDialogWorkspace_WorkspaceFragmentDoc,
"\n fragment InviteDialogProject_Project on Project {\n id\n name\n workspaceId\n workspace {\n id\n name\n role\n domainBasedMembershipProtectionEnabled\n domains {\n domain\n id\n }\n ...WorkspacesPlan_Workspace\n }\n ...InviteDialogProjectRow_Project\n }\n": typeof types.InviteDialogProject_ProjectFragmentDoc,
"\n fragment InviteDialogProjectRow_Project on Project {\n id\n workspaceId\n workspace {\n id\n role\n }\n }\n": typeof types.InviteDialogProjectRow_ProjectFragmentDoc,
@@ -113,18 +114,21 @@ type Documents = {
"\n query InvitableCollaborators(\n $projectId: String!\n $filter: InvitableCollaboratorsFilter\n $limit: Int!\n $workspaceId: String\n ) {\n project(id: $projectId) {\n invitableCollaborators(filter: $filter, limit: $limit) {\n totalCount\n items {\n user {\n id\n avatar\n name\n workspaceRole(workspaceId: $workspaceId)\n }\n }\n }\n }\n }\n": typeof types.InvitableCollaboratorsDocument,
"\n fragment ProjectDiscussionsPageHeader_Project on Project {\n id\n name\n }\n": typeof types.ProjectDiscussionsPageHeader_ProjectFragmentDoc,
"\n fragment ProjectDiscussionsPageResults_Project on Project {\n id\n }\n": typeof types.ProjectDiscussionsPageResults_ProjectFragmentDoc,
"\n fragment ProjectPageModelsActions on Model {\n id\n name\n permissions {\n canUpdate {\n ...FullPermissionCheckResult\n }\n canDelete {\n ...FullPermissionCheckResult\n }\n canCreateVersion {\n ...FullPermissionCheckResult\n }\n }\n ...UseCopyModelLink_Model\n }\n": typeof types.ProjectPageModelsActionsFragmentDoc,
"\n fragment ProjectPageModelsActions_Project on Project {\n id\n workspace {\n id\n slug\n }\n ...ProjectsModelPageEmbed_Project\n }\n": typeof types.ProjectPageModelsActions_ProjectFragmentDoc,
"\n fragment ProjectPageModelsActions on Model {\n id\n name\n permissions {\n canUpdate {\n ...FullPermissionCheckResult\n }\n canDelete {\n ...FullPermissionCheckResult\n }\n canCreateVersion {\n ...FullPermissionCheckResult\n }\n }\n accSyncItem {\n id\n ...ProjectPageModelsActions_AccSyncItem\n }\n ...UseCopyModelLink_Model\n }\n": typeof types.ProjectPageModelsActionsFragmentDoc,
"\n fragment ProjectPageModelsActions_Project on Project {\n id\n workspace {\n id\n slug\n }\n permissions {\n canReadAccIntegrationSettings {\n ...FullPermissionCheckResult\n }\n }\n ...ProjectsModelPageEmbed_Project\n }\n": typeof types.ProjectPageModelsActions_ProjectFragmentDoc,
"\n fragment ProjectPageModelsActions_AccSyncItem on AccSyncItem {\n id\n accFileName\n status\n }\n": typeof types.ProjectPageModelsActions_AccSyncItemFragmentDoc,
"\n fragment ProjectPageModelsCardProject on Project {\n id\n role\n visibility\n ...ProjectPageModelsActions_Project\n ...ProjectCardImportFileArea_Project\n permissions {\n canCreateModel {\n ...FullPermissionCheckResult\n }\n }\n }\n": typeof types.ProjectPageModelsCardProjectFragmentDoc,
"\n fragment ProjectPageModelsCard_Model on Model {\n id\n homeView {\n id\n resourceIds\n }\n lastUpload: uploads(input: { limit: 1, cursor: null }) {\n items {\n id\n updatedAt\n convertedStatus\n }\n }\n lastVersion: versions(limit: 1, cursor: null) {\n items {\n id\n createdAt\n }\n }\n }\n": typeof types.ProjectPageModelsCard_ModelFragmentDoc,
"\n fragment ProjectModelsPageHeader_Project on Project {\n id\n name\n sourceApps\n role\n models {\n totalCount\n }\n team {\n id\n user {\n ...FormUsersSelectItem\n }\n }\n workspace {\n id\n role\n slug\n name\n readOnly\n plan {\n name\n }\n }\n permissions {\n canCreateModel {\n ...FullPermissionCheckResult\n }\n canReadAccIntegrationSettings {\n ...FullPermissionCheckResult\n }\n }\n ...ProjectModelsAdd_Project\n }\n": typeof types.ProjectModelsPageHeader_ProjectFragmentDoc,
"\n fragment ProjectModelsPageResults_Project on Project {\n ...ProjectPageLatestItemsModels\n }\n": typeof types.ProjectModelsPageResults_ProjectFragmentDoc,
"\n fragment ProjectPageModelsStructureItem_Project on Project {\n id\n ...ProjectPageModelsActions_Project\n ...ProjectCardImportFileArea_Project\n ...UseCanCreateModel_Project\n permissions {\n canCreateModel {\n ...FullPermissionCheckResult\n }\n }\n }\n": typeof types.ProjectPageModelsStructureItem_ProjectFragmentDoc,
"\n fragment SingleLevelModelTreeItem on ModelsTreeItem {\n id\n name\n fullName\n model {\n ...ProjectPageLatestItemsModelItem\n ...ProjectCardImportFileArea_Model\n ...ProjectPageModelsCard_Model\n accSyncItem {\n ...SyncStatusModelItem_AccSyncItem\n }\n }\n hasChildren\n updatedAt\n }\n": typeof types.SingleLevelModelTreeItemFragmentDoc,
"\n fragment SingleLevelModelTreeItem on ModelsTreeItem {\n id\n name\n fullName\n model {\n ...ProjectPageLatestItemsModelItem\n ...ProjectCardImportFileArea_Model\n ...ProjectPageModelsCard_Model\n accSyncItem {\n id\n ...SyncStatusModelItem_AccSyncItem\n }\n }\n hasChildren\n updatedAt\n }\n": typeof types.SingleLevelModelTreeItemFragmentDoc,
"\n fragment ProjectPageModelsUploadsDialog_FileUpload on FileUpload {\n id\n convertedStatus\n convertedMessage\n fileName\n fileSize\n convertedLastUpdate\n convertedVersionId\n uploadDate\n uploadComplete\n branchName\n ...UseFailedFileImportJobUtils_FileUpload\n }\n": typeof types.ProjectPageModelsUploadsDialog_FileUploadFragmentDoc,
"\n query GetModelUploads(\n $projectId: String!\n $modelId: String!\n $input: GetModelUploadsInput!\n ) {\n project(id: $projectId) {\n id\n model(id: $modelId) {\n id\n uploads(input: $input) {\n totalCount\n cursor\n items {\n id\n ...ProjectPageModelsUploadsDialog_FileUpload\n }\n }\n }\n }\n }\n": typeof types.GetModelUploadsDocument,
"\n fragment ProjectPageModelsCardDeleteDialog on Model {\n id\n name\n }\n": typeof types.ProjectPageModelsCardDeleteDialogFragmentDoc,
"\n fragment ProjectPageModelsCardRenameDialog on Model {\n id\n name\n description\n }\n": typeof types.ProjectPageModelsCardRenameDialogFragmentDoc,
"\n fragment ProjectPageModelRemoveSyncDialog_AccSyncItem on AccSyncItem {\n id\n accFileName\n }\n": typeof types.ProjectPageModelRemoveSyncDialog_AccSyncItemFragmentDoc,
"\n fragment ProjectPageSettingsIntegrations_Project on Project {\n id\n permissions {\n canReadAccIntegrationSettings {\n ...FullPermissionCheckResult\n }\n }\n }\n": typeof types.ProjectPageSettingsIntegrations_ProjectFragmentDoc,
"\n query ProjectPageSettingsGeneral($projectId: String!) {\n project(id: $projectId) {\n id\n ...ProjectPageSettingsGeneralBlockProjectInfo_Project\n ...ProjectPageSettingsGeneralBlockAccess_Project\n ...ProjectPageSettingsGeneralBlockDiscussions_Project\n ...ProjectPageSettingsGeneralBlockLeave_Project\n ...ProjectPageSettingsGeneralBlockDelete_Project\n ...ProjectPageTeamInternals_Project\n }\n }\n": typeof types.ProjectPageSettingsGeneralDocument,
"\n fragment ProjectPageSettingsGeneralBlockAccess_Project on Project {\n id\n visibility\n workspaceId\n permissions {\n canUpdate {\n ...FullPermissionCheckResult\n }\n }\n }\n": typeof types.ProjectPageSettingsGeneralBlockAccess_ProjectFragmentDoc,
"\n fragment ProjectPageSettingsGeneralBlockDelete_Project on Project {\n ...ProjectsDeleteDialog_Project\n permissions {\n canUpdate {\n ...FullPermissionCheckResult\n }\n }\n }\n": typeof types.ProjectPageSettingsGeneralBlockDelete_ProjectFragmentDoc,
@@ -227,8 +231,8 @@ type Documents = {
"\n fragment WorkspaceWizard_Workspace on Workspace {\n creationState {\n completed\n state\n }\n name\n slug\n }\n": typeof types.WorkspaceWizard_WorkspaceFragmentDoc,
"\n fragment WorkspaceWizardStepRegion_ServerInfo on ServerInfo {\n multiRegion {\n regions {\n id\n ...SettingsWorkspacesRegionsSelect_ServerRegionItem\n }\n }\n }\n": typeof types.WorkspaceWizardStepRegion_ServerInfoFragmentDoc,
"\n fragment AccFolderContents on AccFolder {\n id\n name\n contents {\n items {\n id\n name\n latestVersion {\n id\n name\n versionNumber\n fileType\n }\n }\n }\n children {\n items {\n id\n name\n }\n }\n }\n ": typeof types.AccFolderContentsFragmentDoc,
"\n fragment ProjectAccSyncItem on AccSyncItem {\n id\n project {\n id\n }\n model {\n id\n }\n accRegion\n accHubId\n accProjectId\n accRootProjectFolderUrn\n accFileLineageUrn\n accFileName\n accFileExtension\n accFileVersionIndex\n accFileViewName\n updatedAt\n status\n author {\n name\n avatar\n }\n }\n": typeof types.ProjectAccSyncItemFragmentDoc,
"\n mutation CreateAccSyncItem($input: CreateAccSyncItemInput!) {\n accSyncItemMutations {\n create(input: $input) {\n id\n accFileLineageUrn\n status\n }\n }\n }\n": typeof types.CreateAccSyncItemDocument,
"\n fragment ProjectAccSyncItem on AccSyncItem {\n id\n project {\n id\n name\n }\n model {\n id\n name\n }\n accRegion\n accHubId\n accProjectId\n accRootProjectFolderUrn\n accFileLineageUrn\n accFileName\n accFileExtension\n accFileVersionIndex\n accFileViewName\n updatedAt\n status\n author {\n name\n avatar\n }\n }\n": typeof types.ProjectAccSyncItemFragmentDoc,
"\n mutation CreateAccSyncItem($input: CreateAccSyncItemInput!) {\n accSyncItemMutations {\n create(input: $input) {\n id\n model {\n id\n name\n }\n author {\n id\n name\n }\n accFileName\n accFileLineageUrn\n accFileViewName\n status\n }\n }\n }\n": typeof types.CreateAccSyncItemDocument,
"\n mutation DeleteAccSyncItem($input: DeleteAccSyncItemInput!) {\n accSyncItemMutations {\n delete(input: $input)\n }\n }\n": typeof types.DeleteAccSyncItemDocument,
"\n mutation UpdateAccSyncItem($input: UpdateAccSyncItemInput!) {\n accSyncItemMutations {\n update(input: $input) {\n id\n status\n }\n }\n }\n": typeof types.UpdateAccSyncItemDocument,
"\n query ProjectAccSyncItems($id: String!) {\n project(id: $id) {\n accSyncItems {\n items {\n ...ProjectAccSyncItem\n }\n }\n }\n }\n": typeof types.ProjectAccSyncItemsDocument,
@@ -373,6 +377,7 @@ type Documents = {
"\n query ProjectAutomationPagePaginatedRuns(\n $projectId: String!\n $automationId: String!\n $cursor: String = null\n ) {\n project(id: $projectId) {\n id\n automation(id: $automationId) {\n id\n runs(cursor: $cursor, limit: 10) {\n totalCount\n cursor\n items {\n id\n ...AutomationRunDetails\n }\n }\n }\n }\n }\n": typeof types.ProjectAutomationPagePaginatedRunsDocument,
"\n query ProjectAutomationAccessCheck($projectId: String!) {\n project(id: $projectId) {\n id\n automations(limit: 0) {\n totalCount\n }\n }\n }\n": typeof types.ProjectAutomationAccessCheckDocument,
"\n query ProjectWebhooks($projectId: String!) {\n project(id: $projectId) {\n id\n name\n ...ProjectPageSettingsWebhooks_Project\n webhooks {\n items {\n streamId\n triggers\n enabled\n url\n id\n description\n history(limit: 5) {\n items {\n status\n statusInfo\n }\n }\n }\n totalCount\n }\n }\n }\n": typeof types.ProjectWebhooksDocument,
"\n query ProjectIntegrations($projectId: String!) {\n project(id: $projectId) {\n id\n name\n ...ProjectPageSettingsIntegrations_Project\n accSyncItems {\n items {\n id\n }\n totalCount\n }\n }\n }\n": typeof types.ProjectIntegrationsDocument,
"\n query ProjectEmbedTokens($projectId: String!, $cursor: String = null) {\n project(id: $projectId) {\n id\n ...ProjectPageSettingsTokens_Project\n }\n }\n": typeof types.ProjectEmbedTokensDocument,
"\n query ProjectBlobInfo($blobId: String!, $projectId: String!) {\n project(id: $projectId) {\n id\n blob(id: $blobId) {\n id\n fileName\n fileType\n fileSize\n createdAt\n }\n }\n }\n": typeof types.ProjectBlobInfoDocument,
"\n query MoveToWorkspaceDryRun($workspaceId: String!, $projectId: String!, $limit: Int) {\n project(id: $projectId) {\n id\n moveToWorkspaceDryRun(workspaceId: $workspaceId) {\n addedToWorkspaceTotalCount\n addedToWorkspace(limit: $limit) {\n avatar\n id\n name\n }\n }\n }\n }\n": typeof types.MoveToWorkspaceDryRunDocument,
@@ -612,7 +617,8 @@ const documents: Documents = {
"\n fragment HeaderNavNotificationsProjectInvite_PendingStreamCollaborator on PendingStreamCollaborator {\n id\n invitedBy {\n ...LimitedUserAvatar\n }\n projectId\n projectName\n token\n workspaceSlug\n user {\n id\n }\n }\n": types.HeaderNavNotificationsProjectInvite_PendingStreamCollaboratorFragmentDoc,
"\n fragment HeaderNavNotificationsWorkspaceInvite_PendingWorkspaceCollaborator on PendingWorkspaceCollaborator {\n id\n invitedBy {\n id\n ...LimitedUserAvatar\n }\n workspace {\n id\n name\n }\n token\n user {\n id\n }\n ...UseWorkspaceInviteManager_PendingWorkspaceCollaborator\n }\n": types.HeaderNavNotificationsWorkspaceInvite_PendingWorkspaceCollaboratorFragmentDoc,
"\n fragment AccIntegrationFolderNode_AccFolder on AccFolder {\n id\n name\n contents {\n items {\n id\n name\n latestVersion {\n id\n name\n versionNumber\n fileType\n }\n }\n }\n children {\n items {\n id\n name\n children {\n items {\n id\n name\n }\n }\n contents {\n items {\n id\n name\n }\n }\n }\n }\n }\n": types.AccIntegrationFolderNode_AccFolderFragmentDoc,
"\n fragment SyncStatusModelItem_AccSyncItem on AccSyncItem {\n id\n status\n }\n": types.SyncStatusModelItem_AccSyncItemFragmentDoc,
"\n fragment SyncStatusModelItem_AccSyncItem on AccSyncItem {\n id\n status\n updatedAt\n accFileVersionIndex\n }\n": types.SyncStatusModelItem_AccSyncItemFragmentDoc,
"\n fragment SettingsProjectIntegrationsActionsMenu_AccSyncItem on AccSyncItem {\n id\n status\n project {\n id\n }\n }\n": types.SettingsProjectIntegrationsActionsMenu_AccSyncItemFragmentDoc,
"\n fragment InviteDialogWorkspace_Workspace on Workspace {\n id\n name\n slug\n domainBasedMembershipProtectionEnabled\n defaultSeatType\n domains {\n domain\n id\n }\n seats {\n editors {\n available\n }\n }\n ...InviteDialogSharedSelectUsers_Workspace\n ...WorkspacesPlan_Workspace\n }\n": types.InviteDialogWorkspace_WorkspaceFragmentDoc,
"\n fragment InviteDialogProject_Project on Project {\n id\n name\n workspaceId\n workspace {\n id\n name\n role\n domainBasedMembershipProtectionEnabled\n domains {\n domain\n id\n }\n ...WorkspacesPlan_Workspace\n }\n ...InviteDialogProjectRow_Project\n }\n": types.InviteDialogProject_ProjectFragmentDoc,
"\n fragment InviteDialogProjectRow_Project on Project {\n id\n workspaceId\n workspace {\n id\n role\n }\n }\n": types.InviteDialogProjectRow_ProjectFragmentDoc,
@@ -661,18 +667,21 @@ const documents: Documents = {
"\n query InvitableCollaborators(\n $projectId: String!\n $filter: InvitableCollaboratorsFilter\n $limit: Int!\n $workspaceId: String\n ) {\n project(id: $projectId) {\n invitableCollaborators(filter: $filter, limit: $limit) {\n totalCount\n items {\n user {\n id\n avatar\n name\n workspaceRole(workspaceId: $workspaceId)\n }\n }\n }\n }\n }\n": types.InvitableCollaboratorsDocument,
"\n fragment ProjectDiscussionsPageHeader_Project on Project {\n id\n name\n }\n": types.ProjectDiscussionsPageHeader_ProjectFragmentDoc,
"\n fragment ProjectDiscussionsPageResults_Project on Project {\n id\n }\n": types.ProjectDiscussionsPageResults_ProjectFragmentDoc,
"\n fragment ProjectPageModelsActions on Model {\n id\n name\n permissions {\n canUpdate {\n ...FullPermissionCheckResult\n }\n canDelete {\n ...FullPermissionCheckResult\n }\n canCreateVersion {\n ...FullPermissionCheckResult\n }\n }\n ...UseCopyModelLink_Model\n }\n": types.ProjectPageModelsActionsFragmentDoc,
"\n fragment ProjectPageModelsActions_Project on Project {\n id\n workspace {\n id\n slug\n }\n ...ProjectsModelPageEmbed_Project\n }\n": types.ProjectPageModelsActions_ProjectFragmentDoc,
"\n fragment ProjectPageModelsActions on Model {\n id\n name\n permissions {\n canUpdate {\n ...FullPermissionCheckResult\n }\n canDelete {\n ...FullPermissionCheckResult\n }\n canCreateVersion {\n ...FullPermissionCheckResult\n }\n }\n accSyncItem {\n id\n ...ProjectPageModelsActions_AccSyncItem\n }\n ...UseCopyModelLink_Model\n }\n": types.ProjectPageModelsActionsFragmentDoc,
"\n fragment ProjectPageModelsActions_Project on Project {\n id\n workspace {\n id\n slug\n }\n permissions {\n canReadAccIntegrationSettings {\n ...FullPermissionCheckResult\n }\n }\n ...ProjectsModelPageEmbed_Project\n }\n": types.ProjectPageModelsActions_ProjectFragmentDoc,
"\n fragment ProjectPageModelsActions_AccSyncItem on AccSyncItem {\n id\n accFileName\n status\n }\n": types.ProjectPageModelsActions_AccSyncItemFragmentDoc,
"\n fragment ProjectPageModelsCardProject on Project {\n id\n role\n visibility\n ...ProjectPageModelsActions_Project\n ...ProjectCardImportFileArea_Project\n permissions {\n canCreateModel {\n ...FullPermissionCheckResult\n }\n }\n }\n": types.ProjectPageModelsCardProjectFragmentDoc,
"\n fragment ProjectPageModelsCard_Model on Model {\n id\n homeView {\n id\n resourceIds\n }\n lastUpload: uploads(input: { limit: 1, cursor: null }) {\n items {\n id\n updatedAt\n convertedStatus\n }\n }\n lastVersion: versions(limit: 1, cursor: null) {\n items {\n id\n createdAt\n }\n }\n }\n": types.ProjectPageModelsCard_ModelFragmentDoc,
"\n fragment ProjectModelsPageHeader_Project on Project {\n id\n name\n sourceApps\n role\n models {\n totalCount\n }\n team {\n id\n user {\n ...FormUsersSelectItem\n }\n }\n workspace {\n id\n role\n slug\n name\n readOnly\n plan {\n name\n }\n }\n permissions {\n canCreateModel {\n ...FullPermissionCheckResult\n }\n canReadAccIntegrationSettings {\n ...FullPermissionCheckResult\n }\n }\n ...ProjectModelsAdd_Project\n }\n": types.ProjectModelsPageHeader_ProjectFragmentDoc,
"\n fragment ProjectModelsPageResults_Project on Project {\n ...ProjectPageLatestItemsModels\n }\n": types.ProjectModelsPageResults_ProjectFragmentDoc,
"\n fragment ProjectPageModelsStructureItem_Project on Project {\n id\n ...ProjectPageModelsActions_Project\n ...ProjectCardImportFileArea_Project\n ...UseCanCreateModel_Project\n permissions {\n canCreateModel {\n ...FullPermissionCheckResult\n }\n }\n }\n": types.ProjectPageModelsStructureItem_ProjectFragmentDoc,
"\n fragment SingleLevelModelTreeItem on ModelsTreeItem {\n id\n name\n fullName\n model {\n ...ProjectPageLatestItemsModelItem\n ...ProjectCardImportFileArea_Model\n ...ProjectPageModelsCard_Model\n accSyncItem {\n ...SyncStatusModelItem_AccSyncItem\n }\n }\n hasChildren\n updatedAt\n }\n": types.SingleLevelModelTreeItemFragmentDoc,
"\n fragment SingleLevelModelTreeItem on ModelsTreeItem {\n id\n name\n fullName\n model {\n ...ProjectPageLatestItemsModelItem\n ...ProjectCardImportFileArea_Model\n ...ProjectPageModelsCard_Model\n accSyncItem {\n id\n ...SyncStatusModelItem_AccSyncItem\n }\n }\n hasChildren\n updatedAt\n }\n": types.SingleLevelModelTreeItemFragmentDoc,
"\n fragment ProjectPageModelsUploadsDialog_FileUpload on FileUpload {\n id\n convertedStatus\n convertedMessage\n fileName\n fileSize\n convertedLastUpdate\n convertedVersionId\n uploadDate\n uploadComplete\n branchName\n ...UseFailedFileImportJobUtils_FileUpload\n }\n": types.ProjectPageModelsUploadsDialog_FileUploadFragmentDoc,
"\n query GetModelUploads(\n $projectId: String!\n $modelId: String!\n $input: GetModelUploadsInput!\n ) {\n project(id: $projectId) {\n id\n model(id: $modelId) {\n id\n uploads(input: $input) {\n totalCount\n cursor\n items {\n id\n ...ProjectPageModelsUploadsDialog_FileUpload\n }\n }\n }\n }\n }\n": types.GetModelUploadsDocument,
"\n fragment ProjectPageModelsCardDeleteDialog on Model {\n id\n name\n }\n": types.ProjectPageModelsCardDeleteDialogFragmentDoc,
"\n fragment ProjectPageModelsCardRenameDialog on Model {\n id\n name\n description\n }\n": types.ProjectPageModelsCardRenameDialogFragmentDoc,
"\n fragment ProjectPageModelRemoveSyncDialog_AccSyncItem on AccSyncItem {\n id\n accFileName\n }\n": types.ProjectPageModelRemoveSyncDialog_AccSyncItemFragmentDoc,
"\n fragment ProjectPageSettingsIntegrations_Project on Project {\n id\n permissions {\n canReadAccIntegrationSettings {\n ...FullPermissionCheckResult\n }\n }\n }\n": types.ProjectPageSettingsIntegrations_ProjectFragmentDoc,
"\n query ProjectPageSettingsGeneral($projectId: String!) {\n project(id: $projectId) {\n id\n ...ProjectPageSettingsGeneralBlockProjectInfo_Project\n ...ProjectPageSettingsGeneralBlockAccess_Project\n ...ProjectPageSettingsGeneralBlockDiscussions_Project\n ...ProjectPageSettingsGeneralBlockLeave_Project\n ...ProjectPageSettingsGeneralBlockDelete_Project\n ...ProjectPageTeamInternals_Project\n }\n }\n": types.ProjectPageSettingsGeneralDocument,
"\n fragment ProjectPageSettingsGeneralBlockAccess_Project on Project {\n id\n visibility\n workspaceId\n permissions {\n canUpdate {\n ...FullPermissionCheckResult\n }\n }\n }\n": types.ProjectPageSettingsGeneralBlockAccess_ProjectFragmentDoc,
"\n fragment ProjectPageSettingsGeneralBlockDelete_Project on Project {\n ...ProjectsDeleteDialog_Project\n permissions {\n canUpdate {\n ...FullPermissionCheckResult\n }\n }\n }\n": types.ProjectPageSettingsGeneralBlockDelete_ProjectFragmentDoc,
@@ -775,8 +784,8 @@ const documents: Documents = {
"\n fragment WorkspaceWizard_Workspace on Workspace {\n creationState {\n completed\n state\n }\n name\n slug\n }\n": types.WorkspaceWizard_WorkspaceFragmentDoc,
"\n fragment WorkspaceWizardStepRegion_ServerInfo on ServerInfo {\n multiRegion {\n regions {\n id\n ...SettingsWorkspacesRegionsSelect_ServerRegionItem\n }\n }\n }\n": types.WorkspaceWizardStepRegion_ServerInfoFragmentDoc,
"\n fragment AccFolderContents on AccFolder {\n id\n name\n contents {\n items {\n id\n name\n latestVersion {\n id\n name\n versionNumber\n fileType\n }\n }\n }\n children {\n items {\n id\n name\n }\n }\n }\n ": types.AccFolderContentsFragmentDoc,
"\n fragment ProjectAccSyncItem on AccSyncItem {\n id\n project {\n id\n }\n model {\n id\n }\n accRegion\n accHubId\n accProjectId\n accRootProjectFolderUrn\n accFileLineageUrn\n accFileName\n accFileExtension\n accFileVersionIndex\n accFileViewName\n updatedAt\n status\n author {\n name\n avatar\n }\n }\n": types.ProjectAccSyncItemFragmentDoc,
"\n mutation CreateAccSyncItem($input: CreateAccSyncItemInput!) {\n accSyncItemMutations {\n create(input: $input) {\n id\n accFileLineageUrn\n status\n }\n }\n }\n": types.CreateAccSyncItemDocument,
"\n fragment ProjectAccSyncItem on AccSyncItem {\n id\n project {\n id\n name\n }\n model {\n id\n name\n }\n accRegion\n accHubId\n accProjectId\n accRootProjectFolderUrn\n accFileLineageUrn\n accFileName\n accFileExtension\n accFileVersionIndex\n accFileViewName\n updatedAt\n status\n author {\n name\n avatar\n }\n }\n": types.ProjectAccSyncItemFragmentDoc,
"\n mutation CreateAccSyncItem($input: CreateAccSyncItemInput!) {\n accSyncItemMutations {\n create(input: $input) {\n id\n model {\n id\n name\n }\n author {\n id\n name\n }\n accFileName\n accFileLineageUrn\n accFileViewName\n status\n }\n }\n }\n": types.CreateAccSyncItemDocument,
"\n mutation DeleteAccSyncItem($input: DeleteAccSyncItemInput!) {\n accSyncItemMutations {\n delete(input: $input)\n }\n }\n": types.DeleteAccSyncItemDocument,
"\n mutation UpdateAccSyncItem($input: UpdateAccSyncItemInput!) {\n accSyncItemMutations {\n update(input: $input) {\n id\n status\n }\n }\n }\n": types.UpdateAccSyncItemDocument,
"\n query ProjectAccSyncItems($id: String!) {\n project(id: $id) {\n accSyncItems {\n items {\n ...ProjectAccSyncItem\n }\n }\n }\n }\n": types.ProjectAccSyncItemsDocument,
@@ -921,6 +930,7 @@ const documents: Documents = {
"\n query ProjectAutomationPagePaginatedRuns(\n $projectId: String!\n $automationId: String!\n $cursor: String = null\n ) {\n project(id: $projectId) {\n id\n automation(id: $automationId) {\n id\n runs(cursor: $cursor, limit: 10) {\n totalCount\n cursor\n items {\n id\n ...AutomationRunDetails\n }\n }\n }\n }\n }\n": types.ProjectAutomationPagePaginatedRunsDocument,
"\n query ProjectAutomationAccessCheck($projectId: String!) {\n project(id: $projectId) {\n id\n automations(limit: 0) {\n totalCount\n }\n }\n }\n": types.ProjectAutomationAccessCheckDocument,
"\n query ProjectWebhooks($projectId: String!) {\n project(id: $projectId) {\n id\n name\n ...ProjectPageSettingsWebhooks_Project\n webhooks {\n items {\n streamId\n triggers\n enabled\n url\n id\n description\n history(limit: 5) {\n items {\n status\n statusInfo\n }\n }\n }\n totalCount\n }\n }\n }\n": types.ProjectWebhooksDocument,
"\n query ProjectIntegrations($projectId: String!) {\n project(id: $projectId) {\n id\n name\n ...ProjectPageSettingsIntegrations_Project\n accSyncItems {\n items {\n id\n }\n totalCount\n }\n }\n }\n": types.ProjectIntegrationsDocument,
"\n query ProjectEmbedTokens($projectId: String!, $cursor: String = null) {\n project(id: $projectId) {\n id\n ...ProjectPageSettingsTokens_Project\n }\n }\n": types.ProjectEmbedTokensDocument,
"\n query ProjectBlobInfo($blobId: String!, $projectId: String!) {\n project(id: $projectId) {\n id\n blob(id: $blobId) {\n id\n fileName\n fileType\n fileSize\n createdAt\n }\n }\n }\n": types.ProjectBlobInfoDocument,
"\n query MoveToWorkspaceDryRun($workspaceId: String!, $projectId: String!, $limit: Int) {\n project(id: $projectId) {\n id\n moveToWorkspaceDryRun(workspaceId: $workspaceId) {\n addedToWorkspaceTotalCount\n addedToWorkspace(limit: $limit) {\n avatar\n id\n name\n }\n }\n }\n }\n": types.MoveToWorkspaceDryRunDocument,
@@ -1327,7 +1337,11 @@ export function graphql(source: "\n fragment AccIntegrationFolderNode_AccFolder
/**
* 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 SyncStatusModelItem_AccSyncItem on AccSyncItem {\n id\n status\n }\n"): (typeof documents)["\n fragment SyncStatusModelItem_AccSyncItem on AccSyncItem {\n id\n status\n }\n"];
export function graphql(source: "\n fragment SyncStatusModelItem_AccSyncItem on AccSyncItem {\n id\n status\n updatedAt\n accFileVersionIndex\n }\n"): (typeof documents)["\n fragment SyncStatusModelItem_AccSyncItem on AccSyncItem {\n id\n status\n updatedAt\n accFileVersionIndex\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 fragment SettingsProjectIntegrationsActionsMenu_AccSyncItem on AccSyncItem {\n id\n status\n project {\n id\n }\n }\n"): (typeof documents)["\n fragment SettingsProjectIntegrationsActionsMenu_AccSyncItem on AccSyncItem {\n id\n status\n project {\n id\n }\n }\n"];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
@@ -1523,11 +1537,15 @@ export function graphql(source: "\n fragment ProjectDiscussionsPageResults_Proj
/**
* 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 ProjectPageModelsActions on Model {\n id\n name\n permissions {\n canUpdate {\n ...FullPermissionCheckResult\n }\n canDelete {\n ...FullPermissionCheckResult\n }\n canCreateVersion {\n ...FullPermissionCheckResult\n }\n }\n ...UseCopyModelLink_Model\n }\n"): (typeof documents)["\n fragment ProjectPageModelsActions on Model {\n id\n name\n permissions {\n canUpdate {\n ...FullPermissionCheckResult\n }\n canDelete {\n ...FullPermissionCheckResult\n }\n canCreateVersion {\n ...FullPermissionCheckResult\n }\n }\n ...UseCopyModelLink_Model\n }\n"];
export function graphql(source: "\n fragment ProjectPageModelsActions on Model {\n id\n name\n permissions {\n canUpdate {\n ...FullPermissionCheckResult\n }\n canDelete {\n ...FullPermissionCheckResult\n }\n canCreateVersion {\n ...FullPermissionCheckResult\n }\n }\n accSyncItem {\n id\n ...ProjectPageModelsActions_AccSyncItem\n }\n ...UseCopyModelLink_Model\n }\n"): (typeof documents)["\n fragment ProjectPageModelsActions on Model {\n id\n name\n permissions {\n canUpdate {\n ...FullPermissionCheckResult\n }\n canDelete {\n ...FullPermissionCheckResult\n }\n canCreateVersion {\n ...FullPermissionCheckResult\n }\n }\n accSyncItem {\n id\n ...ProjectPageModelsActions_AccSyncItem\n }\n ...UseCopyModelLink_Model\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 fragment ProjectPageModelsActions_Project on Project {\n id\n workspace {\n id\n slug\n }\n ...ProjectsModelPageEmbed_Project\n }\n"): (typeof documents)["\n fragment ProjectPageModelsActions_Project on Project {\n id\n workspace {\n id\n slug\n }\n ...ProjectsModelPageEmbed_Project\n }\n"];
export function graphql(source: "\n fragment ProjectPageModelsActions_Project on Project {\n id\n workspace {\n id\n slug\n }\n permissions {\n canReadAccIntegrationSettings {\n ...FullPermissionCheckResult\n }\n }\n ...ProjectsModelPageEmbed_Project\n }\n"): (typeof documents)["\n fragment ProjectPageModelsActions_Project on Project {\n id\n workspace {\n id\n slug\n }\n permissions {\n canReadAccIntegrationSettings {\n ...FullPermissionCheckResult\n }\n }\n ...ProjectsModelPageEmbed_Project\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 fragment ProjectPageModelsActions_AccSyncItem on AccSyncItem {\n id\n accFileName\n status\n }\n"): (typeof documents)["\n fragment ProjectPageModelsActions_AccSyncItem on AccSyncItem {\n id\n accFileName\n status\n }\n"];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
@@ -1551,7 +1569,7 @@ export function graphql(source: "\n fragment ProjectPageModelsStructureItem_Pro
/**
* 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 SingleLevelModelTreeItem on ModelsTreeItem {\n id\n name\n fullName\n model {\n ...ProjectPageLatestItemsModelItem\n ...ProjectCardImportFileArea_Model\n ...ProjectPageModelsCard_Model\n accSyncItem {\n ...SyncStatusModelItem_AccSyncItem\n }\n }\n hasChildren\n updatedAt\n }\n"): (typeof documents)["\n fragment SingleLevelModelTreeItem on ModelsTreeItem {\n id\n name\n fullName\n model {\n ...ProjectPageLatestItemsModelItem\n ...ProjectCardImportFileArea_Model\n ...ProjectPageModelsCard_Model\n accSyncItem {\n ...SyncStatusModelItem_AccSyncItem\n }\n }\n hasChildren\n updatedAt\n }\n"];
export function graphql(source: "\n fragment SingleLevelModelTreeItem on ModelsTreeItem {\n id\n name\n fullName\n model {\n ...ProjectPageLatestItemsModelItem\n ...ProjectCardImportFileArea_Model\n ...ProjectPageModelsCard_Model\n accSyncItem {\n id\n ...SyncStatusModelItem_AccSyncItem\n }\n }\n hasChildren\n updatedAt\n }\n"): (typeof documents)["\n fragment SingleLevelModelTreeItem on ModelsTreeItem {\n id\n name\n fullName\n model {\n ...ProjectPageLatestItemsModelItem\n ...ProjectCardImportFileArea_Model\n ...ProjectPageModelsCard_Model\n accSyncItem {\n id\n ...SyncStatusModelItem_AccSyncItem\n }\n }\n hasChildren\n updatedAt\n }\n"];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
@@ -1568,6 +1586,14 @@ export function graphql(source: "\n fragment ProjectPageModelsCardDeleteDialog
* 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 ProjectPageModelsCardRenameDialog on Model {\n id\n name\n description\n }\n"): (typeof documents)["\n fragment ProjectPageModelsCardRenameDialog on Model {\n id\n name\n description\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 fragment ProjectPageModelRemoveSyncDialog_AccSyncItem on AccSyncItem {\n id\n accFileName\n }\n"): (typeof documents)["\n fragment ProjectPageModelRemoveSyncDialog_AccSyncItem on AccSyncItem {\n id\n accFileName\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 fragment ProjectPageSettingsIntegrations_Project on Project {\n id\n permissions {\n canReadAccIntegrationSettings {\n ...FullPermissionCheckResult\n }\n }\n }\n"): (typeof documents)["\n fragment ProjectPageSettingsIntegrations_Project on Project {\n id\n permissions {\n canReadAccIntegrationSettings {\n ...FullPermissionCheckResult\n }\n }\n }\n"];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
@@ -1979,11 +2005,11 @@ export function graphql(source: "\n fragment AccFolderContents on AccFo
/**
* 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 ProjectAccSyncItem on AccSyncItem {\n id\n project {\n id\n }\n model {\n id\n }\n accRegion\n accHubId\n accProjectId\n accRootProjectFolderUrn\n accFileLineageUrn\n accFileName\n accFileExtension\n accFileVersionIndex\n accFileViewName\n updatedAt\n status\n author {\n name\n avatar\n }\n }\n"): (typeof documents)["\n fragment ProjectAccSyncItem on AccSyncItem {\n id\n project {\n id\n }\n model {\n id\n }\n accRegion\n accHubId\n accProjectId\n accRootProjectFolderUrn\n accFileLineageUrn\n accFileName\n accFileExtension\n accFileVersionIndex\n accFileViewName\n updatedAt\n status\n author {\n name\n avatar\n }\n }\n"];
export function graphql(source: "\n fragment ProjectAccSyncItem on AccSyncItem {\n id\n project {\n id\n name\n }\n model {\n id\n name\n }\n accRegion\n accHubId\n accProjectId\n accRootProjectFolderUrn\n accFileLineageUrn\n accFileName\n accFileExtension\n accFileVersionIndex\n accFileViewName\n updatedAt\n status\n author {\n name\n avatar\n }\n }\n"): (typeof documents)["\n fragment ProjectAccSyncItem on AccSyncItem {\n id\n project {\n id\n name\n }\n model {\n id\n name\n }\n accRegion\n accHubId\n accProjectId\n accRootProjectFolderUrn\n accFileLineageUrn\n accFileName\n accFileExtension\n accFileVersionIndex\n accFileViewName\n updatedAt\n status\n author {\n name\n avatar\n }\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 mutation CreateAccSyncItem($input: CreateAccSyncItemInput!) {\n accSyncItemMutations {\n create(input: $input) {\n id\n accFileLineageUrn\n status\n }\n }\n }\n"): (typeof documents)["\n mutation CreateAccSyncItem($input: CreateAccSyncItemInput!) {\n accSyncItemMutations {\n create(input: $input) {\n id\n accFileLineageUrn\n status\n }\n }\n }\n"];
export function graphql(source: "\n mutation CreateAccSyncItem($input: CreateAccSyncItemInput!) {\n accSyncItemMutations {\n create(input: $input) {\n id\n model {\n id\n name\n }\n author {\n id\n name\n }\n accFileName\n accFileLineageUrn\n accFileViewName\n status\n }\n }\n }\n"): (typeof documents)["\n mutation CreateAccSyncItem($input: CreateAccSyncItemInput!) {\n accSyncItemMutations {\n create(input: $input) {\n id\n model {\n id\n name\n }\n author {\n id\n name\n }\n accFileName\n accFileLineageUrn\n accFileViewName\n status\n }\n }\n }\n"];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
@@ -2560,6 +2586,10 @@ export function graphql(source: "\n query ProjectAutomationAccessCheck($project
* 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 ProjectWebhooks($projectId: String!) {\n project(id: $projectId) {\n id\n name\n ...ProjectPageSettingsWebhooks_Project\n webhooks {\n items {\n streamId\n triggers\n enabled\n url\n id\n description\n history(limit: 5) {\n items {\n status\n statusInfo\n }\n }\n }\n totalCount\n }\n }\n }\n"): (typeof documents)["\n query ProjectWebhooks($projectId: String!) {\n project(id: $projectId) {\n id\n name\n ...ProjectPageSettingsWebhooks_Project\n webhooks {\n items {\n streamId\n triggers\n enabled\n url\n id\n description\n history(limit: 5) {\n items {\n status\n statusInfo\n }\n }\n }\n totalCount\n }\n }\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 ProjectIntegrations($projectId: String!) {\n project(id: $projectId) {\n id\n name\n ...ProjectPageSettingsIntegrations_Project\n accSyncItems {\n items {\n id\n }\n totalCount\n }\n }\n }\n"): (typeof documents)["\n query ProjectIntegrations($projectId: String!) {\n project(id: $projectId) {\n id\n name\n ...ProjectPageSettingsIntegrations_Project\n accSyncItems {\n items {\n id\n }\n totalCount\n }\n }\n }\n"];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
File diff suppressed because one or more lines are too long
@@ -173,6 +173,9 @@ export const workspaceJoinRoute = '/workspaces/actions/join'
export const workspaceFunctionsRoute = (slug?: string) =>
`/workspaces/${slug}/functions`
export const workspaceIntegrationSettingsRoute = (slug?: string) =>
`/settings/workspaces/${slug}/integrations`
export const presentationRoute = (projectId?: string, presentationId?: string) =>
`/projects/${projectId}/presentations/${presentationId}`
@@ -355,6 +355,22 @@ export const projectWebhooksQuery = graphql(`
}
`)
export const projectIntegrationsQuery = graphql(`
query ProjectIntegrations($projectId: String!) {
project(id: $projectId) {
id
name
...ProjectPageSettingsIntegrations_Project
accSyncItems {
items {
id
}
totalCount
}
}
}
`)
export const projectEmbedTokensQuery = graphql(`
query ProjectEmbedTokens($projectId: String!, $cursor: String = null) {
project(id: $projectId) {
@@ -5,6 +5,6 @@ export const ImporterAutomateFunctions = {
},
rvt: {
functionId: '0725cb0ac6',
functionReleaseId: 'b5c16a1606'
functionReleaseId: '576643b561'
}
}
@@ -0,0 +1,49 @@
/* eslint-disable @typescript-eslint/no-unsafe-return */
/* eslint-disable @typescript-eslint/no-explicit-any */
import { getFeatureFlags } from '@/modules/shared/helpers/envHelper'
import type { SpeckleModuleMocksConfig } from '@/modules/shared/helpers/mocks'
import { faker } from '@faker-js/faker'
import { times } from 'lodash-es'
const { FF_ACC_INTEGRATION_ENABLED } = getFeatureFlags()
const mocks: SpeckleModuleMocksConfig = {
resolvers: ({ store }) => ({
Project: {
accSyncItems: () => {
const count = faker.number.int({ min: 1, max: 10 })
return {
cursor: null,
totalCount: count,
items: times(count, () => store.get('AccSyncItem'))
} as any
}
},
Model: {
accSyncItem: () => store.get('AccSyncItem') as any
},
AccSyncItem: {
project: () => store.get('Project') as any,
model: () => store.get('Model') as any,
author: () => store.get('LimitedUser') as any
}
}),
mocks: {
AccSyncItem: {
status: () =>
faker.helpers.arrayElement([
'pending',
'syncing',
'failed',
'succeeded',
'paused'
]),
accFileVersionIndex: () => faker.number.int({ min: 1, max: 999 }),
accFileViewName: () =>
faker.helpers.arrayElement([null, faker.lorem.slug({ min: 1, max: 6 })])
}
}
}
export default FF_ACC_INTEGRATION_ENABLED ? mocks : {}