Files
speckle-server/packages/frontend-2/components/automate/automation/create-dialog/SelectFunctionStep.vue
T
Kristaps Fabians Geikins 4dae1569cd feat(fe2): invite + list workspace invites (#2629)
* list invites table

* invites list works

* update last reminded date on resend

* fix FE

* WIP invitedialog + updated debounced utility

* invite create works

* exclude users correctly

* more adjustments

* minor cleanup

* using workspace invite server role

* test fix

* fixed multiple root eslint issues

* minor adjustments
2024-08-12 11:30:01 +03:00

119 lines
3.3 KiB
Vue

<template>
<div>
<FormTextInput
label="Select function"
:show-label="showLabel"
:show-required="showRequired"
name="search"
color="foundation"
placeholder="Search Functions..."
show-clear
full-width
v-bind="bind"
v-on="on"
/>
<div class="mt-4">
<template v-if="queryItems?.length || loading">
<AutomateFunctionCardView small-view>
<AutomateFunctionCard
v-for="fn in items"
:key="fn.id"
:fn="fn"
external-more-info
:selected="selectedFunction && selectedFunction?.id === fn.id"
@use="
() =>
(selectedFunction =
selectedFunction && selectedFunction.id === fn.id ? undefined : fn)
"
/>
</AutomateFunctionCardView>
<InfiniteLoading :settings="{ identifier }" @infinite="onInfiniteLoad" />
</template>
<CommonGenericEmptyState v-else :search="!!search" @clear-search="search = ''" />
</div>
</div>
</template>
<script setup lang="ts">
import { useDebouncedTextInput } from '@speckle/ui-components'
import { useQueryLoading } from '@vue/apollo-composable'
import { graphql } from '~/lib/common/generated/gql'
import type { CreateAutomationSelectableFunction } from '~/lib/automate/helpers/automations'
import type { Optional } from '@speckle/shared'
import { usePaginatedQuery } from '~/lib/common/composables/graphql'
const searchQuery = graphql(`
query AutomationCreateDialogFunctionsSearch($search: String, $cursor: String = null) {
automateFunctions(limit: 20, filter: { search: $search }, cursor: $cursor) {
cursor
totalCount
items {
id
...AutomateAutomationCreateDialog_AutomateFunction
}
}
}
`)
const props = withDefaults(
defineProps<{
preselectedFunction: Optional<CreateAutomationSelectableFunction>
pageSize?: Optional<number>
showLabel?: Optional<boolean>
showRequired?: Optional<boolean>
}>(),
{
showLabel: true,
showRequired: true
}
)
const selectedFunction = defineModel<Optional<CreateAutomationSelectableFunction>>(
'selectedFunction',
{
required: true
}
)
const { on, bind, value: search } = useDebouncedTextInput()
const loading = useQueryLoading()
const {
identifier,
onInfiniteLoad,
query: { result }
} = usePaginatedQuery({
query: searchQuery,
baseVariables: computed(() => ({
search: search.value?.length ? search.value : null
})),
resolveKey: (vars) => [vars.search || ''],
resolveCurrentResult: (res) => res?.automateFunctions,
resolveNextPageVariables: (baseVars, cursor) => ({
...baseVars,
cursor
}),
resolveCursorFromVariables: (vars) => vars.cursor
})
const queryItems = computed(() => result.value?.automateFunctions.items)
const items = computed(() => {
const baseItems = (queryItems.value || []).slice(0, props.pageSize)
const preselectedFn = props.preselectedFunction
if (!preselectedFn || baseItems.find((fn) => fn.id === preselectedFn.id)) {
return baseItems
}
return [preselectedFn, ...baseItems]
})
watch(
() => props.preselectedFunction,
(newVal) => {
if (newVal && !selectedFunction.value) {
selectedFunction.value = newVal
}
},
{ immediate: true }
)
</script>