4dae1569cd
* 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
119 lines
3.3 KiB
Vue
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>
|