WEB-2466 fix(automate): include workspace in function breadcrumb (#3926)
* fix(automate): repair workspace function breadcrumb * fix(automate): use route helper correctly
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
<Component
|
||||
:is="noButtons ? NuxtLink : 'div'"
|
||||
:class="classes"
|
||||
:to="noButtons ? automationFunctionRoute(fn.id) : undefined"
|
||||
:to="noButtons ? automateFunctionRoute(fn.id) : undefined"
|
||||
:external="externalMoreInfo"
|
||||
:target="externalMoreInfo ? '_blank' : undefined"
|
||||
class="rounded-lg border border-outline-3 bg-foundation overflow-hidden"
|
||||
@@ -19,7 +19,7 @@
|
||||
>
|
||||
<Component
|
||||
:is="noButtons ? 'div' : NuxtLink"
|
||||
:to="automationFunctionRoute(fn.id)"
|
||||
:to="automateFunctionRoute(fn.id)"
|
||||
:target="externalMoreInfo ? '_blank' : undefined"
|
||||
class="truncate"
|
||||
>
|
||||
@@ -52,7 +52,7 @@
|
||||
</FormButton>
|
||||
<FormButton
|
||||
color="subtle"
|
||||
:to="automationFunctionRoute(fn.id)"
|
||||
:to="automateFunctionRoute(fn.id)"
|
||||
:external="externalMoreInfo"
|
||||
:target="externalMoreInfo ? '_blank' : undefined"
|
||||
>
|
||||
@@ -80,7 +80,7 @@
|
||||
import { graphql } from '~/lib/common/generated/gql'
|
||||
import type { AutomationsFunctionsCard_AutomateFunctionFragment } from '~/lib/common/generated/gql/graphql'
|
||||
import { CheckIcon } from '@heroicons/vue/24/outline'
|
||||
import { automationFunctionRoute } from '~/lib/common/helpers/route'
|
||||
import { automateFunctionRoute } from '~/lib/common/helpers/route'
|
||||
import { useMarkdown } from '~/lib/common/composables/markdown'
|
||||
|
||||
graphql(`
|
||||
|
||||
@@ -52,7 +52,7 @@ import type {
|
||||
} from '~/lib/automate/helpers/functions'
|
||||
import {
|
||||
automateGithubAppAuthorizationRoute,
|
||||
automationFunctionRoute
|
||||
automateFunctionRoute
|
||||
} from '~/lib/common/helpers/route'
|
||||
import { useEnumSteps, useEnumStepsWidgetSetup } from '~/lib/form/composables/steps'
|
||||
import { useForm } from 'vee-validate'
|
||||
@@ -281,7 +281,7 @@ const buttons = computed((): LayoutDialogButton[] => {
|
||||
iconRight: ArrowRightIcon,
|
||||
fullWidth: true,
|
||||
to: createdFunction.value?.id
|
||||
? automationFunctionRoute(createdFunction.value.id)
|
||||
? automateFunctionRoute(createdFunction.value.id)
|
||||
: undefined
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,26 @@
|
||||
<template>
|
||||
<div class="pt-4 flex gap-4 flex-col sm:flex-row sm:items-center sm:justify-between">
|
||||
<Portal to="navigation">
|
||||
<HeaderNavLink
|
||||
:to="automationFunctionsRoute"
|
||||
:separator="false"
|
||||
name="Automate functions"
|
||||
/>
|
||||
<HeaderNavLink :to="automationFunctionRoute(fn.id)" :name="fn.name" />
|
||||
<template v-if="fnWorkspace">
|
||||
<HeaderNavLink
|
||||
:to="workspaceRoute(fnWorkspace.slug)"
|
||||
:separator="false"
|
||||
:name="fnWorkspace.name"
|
||||
/>
|
||||
<HeaderNavLink
|
||||
:to="workspaceFunctionsRoute(fnWorkspace.slug)"
|
||||
name="Functions"
|
||||
/>
|
||||
<HeaderNavLink :to="automateFunctionRoute(fn.id)" :name="fn.name" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<HeaderNavLink
|
||||
:to="publicAutomateFunctionsRoute"
|
||||
:separator="false"
|
||||
name="Functions"
|
||||
/>
|
||||
<HeaderNavLink :to="automateFunctionRoute(fn.id)" :name="fn.name" />
|
||||
</template>
|
||||
</Portal>
|
||||
<div class="flex items-center gap-4">
|
||||
<AutomateFunctionLogo :logo="fn.logo" />
|
||||
@@ -21,10 +35,15 @@
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { graphql } from '~/lib/common/generated/gql'
|
||||
import type { AutomateFunctionPageHeader_FunctionFragment } from '~/lib/common/generated/gql/graphql'
|
||||
import type {
|
||||
AutomateFunctionPageHeader_FunctionFragment,
|
||||
AutomateFunctionPageHeader_WorkspaceFragment
|
||||
} from '~/lib/common/generated/gql/graphql'
|
||||
import {
|
||||
automationFunctionRoute,
|
||||
automationFunctionsRoute
|
||||
automateFunctionRoute,
|
||||
publicAutomateFunctionsRoute,
|
||||
workspaceFunctionsRoute,
|
||||
workspaceRoute
|
||||
} from '~/lib/common/helpers/route'
|
||||
|
||||
graphql(`
|
||||
@@ -43,10 +62,17 @@ graphql(`
|
||||
}
|
||||
workspaceIds
|
||||
}
|
||||
|
||||
fragment AutomateFunctionPageHeader_Workspace on Workspace {
|
||||
id
|
||||
name
|
||||
slug
|
||||
}
|
||||
`)
|
||||
|
||||
defineProps<{
|
||||
fn: AutomateFunctionPageHeader_FunctionFragment
|
||||
fnWorkspace?: AutomateFunctionPageHeader_WorkspaceFragment
|
||||
isOwner: boolean
|
||||
}>()
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
v-if="revisionFn"
|
||||
text
|
||||
target="_blank"
|
||||
:to="automationFunctionRoute(revisionFn.release.function.id)"
|
||||
:to="automateFunctionRoute(revisionFn.release.function.id)"
|
||||
>
|
||||
View function
|
||||
</FormButton>
|
||||
@@ -75,7 +75,7 @@
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import type { MaybeNullOrUndefined, Optional } from '@speckle/shared'
|
||||
import { automationFunctionRoute } from '~/lib/common/helpers/route'
|
||||
import { automateFunctionRoute } from '~/lib/common/helpers/route'
|
||||
import {
|
||||
useJsonFormsChangeHandler,
|
||||
hasJsonFormErrors as hasFormErrors
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
automationFunctionsRoute,
|
||||
publicAutomateFunctionsRoute,
|
||||
workspaceFunctionsRoute
|
||||
} from '~/lib/common/helpers/route'
|
||||
import type { CreateAutomationSelectableFunction } from '~/lib/automate/helpers/automations'
|
||||
@@ -58,7 +58,7 @@ onMounted(() => {
|
||||
const functionsGalleryRoute = computed(() =>
|
||||
props.workspaceSlug
|
||||
? workspaceFunctionsRoute(props.workspaceSlug)
|
||||
: automationFunctionsRoute
|
||||
: publicAutomateFunctionsRoute
|
||||
)
|
||||
|
||||
const isVisibleAction = (action: LayoutDialogButton): boolean => {
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
<script setup lang="ts">
|
||||
import { useDebouncedTextInput } from '@speckle/ui-components'
|
||||
import {
|
||||
automationFunctionsRoute,
|
||||
publicAutomateFunctionsRoute,
|
||||
workspaceFunctionsRoute
|
||||
} from '~/lib/common/helpers/route'
|
||||
|
||||
@@ -51,7 +51,7 @@ const exploreFunctionsMessage = computed(() =>
|
||||
const exploreFunctionsRoute = computed(() =>
|
||||
props.workspaceSlug
|
||||
? workspaceFunctionsRoute(props.workspaceSlug)
|
||||
: automationFunctionsRoute
|
||||
: publicAutomateFunctionsRoute
|
||||
)
|
||||
|
||||
const search = defineModel<string>('search')
|
||||
|
||||
@@ -31,7 +31,7 @@ const documents = {
|
||||
"\n fragment AutomateFunctionEditDialog_Workspace on Workspace {\n id\n name\n }\n": types.AutomateFunctionEditDialog_WorkspaceFragmentDoc,
|
||||
"\n fragment AutomateFunctionCreateDialogDoneStep_AutomateFunction on AutomateFunction {\n id\n repo {\n id\n url\n owner\n name\n }\n ...AutomationsFunctionsCard_AutomateFunction\n }\n": types.AutomateFunctionCreateDialogDoneStep_AutomateFunctionFragmentDoc,
|
||||
"\n fragment AutomateFunctionCreateDialogTemplateStep_AutomateFunctionTemplate on AutomateFunctionTemplate {\n id\n title\n logo\n url\n }\n": types.AutomateFunctionCreateDialogTemplateStep_AutomateFunctionTemplateFragmentDoc,
|
||||
"\n fragment AutomateFunctionPageHeader_Function on AutomateFunction {\n id\n name\n logo\n repo {\n id\n url\n owner\n name\n }\n releases(limit: 1) {\n totalCount\n }\n workspaceIds\n }\n": types.AutomateFunctionPageHeader_FunctionFragmentDoc,
|
||||
"\n fragment AutomateFunctionPageHeader_Function on AutomateFunction {\n id\n name\n logo\n repo {\n id\n url\n owner\n name\n }\n releases(limit: 1) {\n totalCount\n }\n workspaceIds\n }\n\n fragment AutomateFunctionPageHeader_Workspace on Workspace {\n id\n name\n slug\n }\n": types.AutomateFunctionPageHeader_FunctionFragmentDoc,
|
||||
"\n fragment AutomateFunctionPageInfo_AutomateFunction on AutomateFunction {\n id\n repo {\n id\n url\n owner\n name\n }\n description\n releases(limit: 1) {\n items {\n id\n inputSchema\n createdAt\n commitId\n ...AutomateFunctionPageParametersDialog_AutomateFunctionRelease\n }\n }\n }\n": types.AutomateFunctionPageInfo_AutomateFunctionFragmentDoc,
|
||||
"\n fragment AutomateFunctionPageParametersDialog_AutomateFunctionRelease on AutomateFunctionRelease {\n id\n inputSchema\n }\n": types.AutomateFunctionPageParametersDialog_AutomateFunctionReleaseFragmentDoc,
|
||||
"\n fragment AutomateFunctionsPageHeader_Query on Query {\n activeUser {\n id\n role\n automateInfo {\n hasAutomateGithubApp\n availableGithubOrgs\n }\n }\n serverInfo {\n automate {\n availableFunctionTemplates {\n ...AutomateFunctionCreateDialogTemplateStep_AutomateFunctionTemplate\n }\n }\n }\n }\n": types.AutomateFunctionsPageHeader_QueryFragmentDoc,
|
||||
@@ -381,6 +381,7 @@ const documents = {
|
||||
"\n query ResolveCommentLink($commentId: String!, $projectId: String!) {\n project(id: $projectId) {\n comment(id: $commentId) {\n id\n ...LinkableComment\n }\n }\n }\n": types.ResolveCommentLinkDocument,
|
||||
"\n fragment AutomateFunctionPage_AutomateFunction on AutomateFunction {\n id\n name\n description\n logo\n supportedSourceApps\n tags\n ...AutomateFunctionPageHeader_Function\n ...AutomateFunctionPageInfo_AutomateFunction\n ...AutomateAutomationCreateDialog_AutomateFunction\n creator {\n id\n }\n }\n": types.AutomateFunctionPage_AutomateFunctionFragmentDoc,
|
||||
"\n query AutomateFunctionPage($functionId: ID!) {\n automateFunction(id: $functionId) {\n ...AutomateFunctionPage_AutomateFunction\n }\n activeUser {\n workspaces {\n items {\n ...AutomateFunctionCreateDialog_Workspace\n ...AutomateFunctionEditDialog_Workspace\n }\n }\n }\n }\n": types.AutomateFunctionPageDocument,
|
||||
"\n query AutomateFunctionPageWorkspace($workspaceId: String!) {\n workspace(id: $workspaceId) {\n id\n ...AutomateFunctionPageHeader_Workspace\n }\n }\n": types.AutomateFunctionPageWorkspaceDocument,
|
||||
"\n query AutomateFunctionsPage($search: String, $cursor: String = null) {\n ...AutomateFunctionsPageItems_Query\n ...AutomateFunctionsPageHeader_Query\n }\n": types.AutomateFunctionsPageDocument,
|
||||
"\n fragment ProjectPageProject on Project {\n id\n createdAt\n modelCount: models(limit: 0) {\n totalCount\n }\n commentThreadCount: commentThreads(limit: 0) {\n totalCount\n }\n workspace {\n id\n }\n ...ProjectPageTeamInternals_Project\n ...ProjectPageProjectHeader\n ...ProjectPageTeamDialog\n ...ProjectsMoveToWorkspaceDialog_Project\n }\n": types.ProjectPageProjectFragmentDoc,
|
||||
"\n fragment ProjectPageAutomationPage_Automation on Automation {\n id\n ...ProjectPageAutomationHeader_Automation\n ...ProjectPageAutomationFunctions_Automation\n ...ProjectPageAutomationRuns_Automation\n }\n": types.ProjectPageAutomationPage_AutomationFragmentDoc,
|
||||
@@ -483,7 +484,7 @@ export function graphql(source: "\n fragment AutomateFunctionCreateDialogTempla
|
||||
/**
|
||||
* 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 AutomateFunctionPageHeader_Function on AutomateFunction {\n id\n name\n logo\n repo {\n id\n url\n owner\n name\n }\n releases(limit: 1) {\n totalCount\n }\n workspaceIds\n }\n"): (typeof documents)["\n fragment AutomateFunctionPageHeader_Function on AutomateFunction {\n id\n name\n logo\n repo {\n id\n url\n owner\n name\n }\n releases(limit: 1) {\n totalCount\n }\n workspaceIds\n }\n"];
|
||||
export function graphql(source: "\n fragment AutomateFunctionPageHeader_Function on AutomateFunction {\n id\n name\n logo\n repo {\n id\n url\n owner\n name\n }\n releases(limit: 1) {\n totalCount\n }\n workspaceIds\n }\n\n fragment AutomateFunctionPageHeader_Workspace on Workspace {\n id\n name\n slug\n }\n"): (typeof documents)["\n fragment AutomateFunctionPageHeader_Function on AutomateFunction {\n id\n name\n logo\n repo {\n id\n url\n owner\n name\n }\n releases(limit: 1) {\n totalCount\n }\n workspaceIds\n }\n\n fragment AutomateFunctionPageHeader_Workspace on Workspace {\n id\n name\n slug\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
@@ -1880,6 +1881,10 @@ export function graphql(source: "\n fragment AutomateFunctionPage_AutomateFunct
|
||||
* 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 AutomateFunctionPage($functionId: ID!) {\n automateFunction(id: $functionId) {\n ...AutomateFunctionPage_AutomateFunction\n }\n activeUser {\n workspaces {\n items {\n ...AutomateFunctionCreateDialog_Workspace\n ...AutomateFunctionEditDialog_Workspace\n }\n }\n }\n }\n"): (typeof documents)["\n query AutomateFunctionPage($functionId: ID!) {\n automateFunction(id: $functionId) {\n ...AutomateFunctionPage_AutomateFunction\n }\n activeUser {\n workspaces {\n items {\n ...AutomateFunctionCreateDialog_Workspace\n ...AutomateFunctionEditDialog_Workspace\n }\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 AutomateFunctionPageWorkspace($workspaceId: String!) {\n workspace(id: $workspaceId) {\n id\n ...AutomateFunctionPageHeader_Workspace\n }\n }\n"): (typeof documents)["\n query AutomateFunctionPageWorkspace($workspaceId: String!) {\n workspace(id: $workspaceId) {\n id\n ...AutomateFunctionPageHeader_Workspace\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
@@ -112,10 +112,10 @@ export const automateGithubAppAuthorizationRoute = (workspaceSlug?: string) => {
|
||||
}`
|
||||
}
|
||||
|
||||
export const automationFunctionsRoute = '/functions'
|
||||
export const publicAutomateFunctionsRoute = '/functions'
|
||||
|
||||
export const automationFunctionRoute = (functionId: string) =>
|
||||
`${automationFunctionsRoute}/${functionId}`
|
||||
export const automateFunctionRoute = (functionId: string) =>
|
||||
`${publicAutomateFunctionsRoute}/${functionId}`
|
||||
|
||||
export const workspaceRoute = (slug: string) => `/workspaces/${slug}`
|
||||
export const workspaceSsoRoute = (slug: string) => `/workspaces/${slug}/sso`
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
<template v-if="!loading && fn">
|
||||
<AutomateFunctionPageHeader
|
||||
:fn="fn"
|
||||
:fn-workspace="fnWorkspace"
|
||||
:is-owner="isOwner"
|
||||
class="mb-12"
|
||||
@create-automation="showNewAutomationDialog = true"
|
||||
@@ -70,6 +71,15 @@ const pageQuery = graphql(`
|
||||
}
|
||||
`)
|
||||
|
||||
const functionWorkspaceQuery = graphql(`
|
||||
query AutomateFunctionPageWorkspace($workspaceId: String!) {
|
||||
workspace(id: $workspaceId) {
|
||||
id
|
||||
...AutomateFunctionPageHeader_Workspace
|
||||
}
|
||||
}
|
||||
`)
|
||||
|
||||
definePageMeta({
|
||||
middleware: ['auth', 'require-valid-function']
|
||||
})
|
||||
@@ -95,6 +105,19 @@ const showNewAutomationDialog = ref(false)
|
||||
|
||||
const fn = computed(() => result.value?.automateFunction)
|
||||
const fnWorkspaceId = computed(() => fn.value?.workspaceIds?.at(0))
|
||||
|
||||
const { result: functionWorkspaceResult } = useQuery(
|
||||
functionWorkspaceQuery,
|
||||
() => ({
|
||||
workspaceId: fnWorkspaceId.value as string
|
||||
}),
|
||||
() => ({
|
||||
enabled: !!fnWorkspaceId.value
|
||||
})
|
||||
)
|
||||
|
||||
const fnWorkspace = computed(() => functionWorkspaceResult.value?.workspace)
|
||||
|
||||
const isOwner = computed(
|
||||
() =>
|
||||
!!(
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div>
|
||||
<Portal to="navigation">
|
||||
<HeaderNavLink
|
||||
:to="automationFunctionsRoute"
|
||||
:to="publicAutomateFunctionsRoute"
|
||||
name="Functions"
|
||||
:separator="false"
|
||||
/>
|
||||
@@ -44,7 +44,7 @@ import {
|
||||
usePaginatedQuery
|
||||
} from '~/lib/common/composables/graphql'
|
||||
import { graphql } from '~/lib/common/generated/gql'
|
||||
import { automationFunctionsRoute } from '~/lib/common/helpers/route'
|
||||
import { publicAutomateFunctionsRoute } from '~/lib/common/helpers/route'
|
||||
|
||||
definePageMeta({
|
||||
middleware: ['auth', 'requires-automate-enabled']
|
||||
|
||||
@@ -325,6 +325,9 @@ type CreateFunctionWithoutVersionBody = {
|
||||
speckleServerAuthenticationPayload: AuthCodePayloadWithOrigin
|
||||
functionName: string
|
||||
description: string
|
||||
repositoryUrl: string
|
||||
supportedSourceApps: string[]
|
||||
tags: string[]
|
||||
}
|
||||
|
||||
type CreateFunctionWithoutVersionResponse = {
|
||||
|
||||
@@ -556,7 +556,11 @@ export = (FF_AUTOMATE_MODULE_ENABLED
|
||||
origin: getServerOrigin()
|
||||
},
|
||||
functionName: args.input.name,
|
||||
description: args.input.description
|
||||
description: args.input.description,
|
||||
repositoryUrl:
|
||||
'https://github.com/specklesystems/speckle_automate_python_example',
|
||||
supportedSourceApps: [],
|
||||
tags: []
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user