'use client' import type { Getter } from 'jotai/vanilla' import type { WorkflowSourceApp } from './types' import { keepPreviousData, queryOptions } from '@tanstack/react-query' import { atom } from 'jotai' import { atomWithInfiniteQuery, atomWithQuery } from 'jotai-tanstack-query' import { selectAtom } from 'jotai/utils' import { dslAppName, isWorkflowDsl } from '@/features/deployments/shared/domain/dsl' import { consoleQuery } from '@/service/client' import { normalizeAppPagination } from '@/service/use-apps' import { AppModeEnum } from '@/types/app' import { dslFileAtom, dslFileReadVersionAtom, effectiveMethodAtom, selectedAppAtom, sourceSearchTextAtom, } from './primitives' import { SOURCE_APPS_PAGE_SIZE } from './utils' const dslFileContentQueryAtom = atomWithQuery((get) => { const file = get(dslFileAtom) const fileReadVersion = get(dslFileReadVersionAtom) return queryOptions({ queryKey: [ 'createGuideDslFileContent', fileReadVersion, file, file?.name ?? '', file?.size ?? 0, file?.lastModified ?? 0, ], queryFn: async () => (file ? await file.text() : ''), enabled: Boolean(file), retry: false, }) }) export const dslContentAtom = atom((get) => { return get(dslFileContentQueryAtom).data ?? '' }) export const isReadingDslAtom = atom((get) => { const file = get(dslFileAtom) const dslFileContentQuery = get(dslFileContentQueryAtom) return Boolean(file && (dslFileContentQuery.isLoading || dslFileContentQuery.isFetching)) }) export const dslReadErrorAtom = atom((get) => { return Boolean(get(dslFileAtom) && get(dslFileContentQueryAtom).isError) }) export const dslDefaultAppNameAtom = atom((get) => { const dslContent = get(dslContentAtom) return dslContent ? dslAppName(dslContent) : '' }) export const dslUnsupportedModeAtom = atom((get) => { const dslContent = get(dslContentAtom) return ( get(effectiveMethodAtom) === 'importDsl' && Boolean(dslContent.trim()) && !get(isReadingDslAtom) && !get(dslReadErrorAtom) && !isWorkflowDsl(dslContent) ) }) export const importDslReadyAtom = atom((get) => { return ( Boolean(get(dslContentAtom).trim()) && !get(isReadingDslAtom) && !get(dslReadErrorAtom) && !get(dslUnsupportedModeAtom) ) }) export const sourceAppsQueryAtom = atomWithInfiniteQuery((get) => { const sourceSearchText = get(sourceSearchTextAtom) return consoleQuery.apps.get.infiniteOptions({ input: (pageParam) => ({ query: { page: Number(pageParam), limit: SOURCE_APPS_PAGE_SIZE, name: sourceSearchText, mode: AppModeEnum.WORKFLOW, }, }), getNextPageParam: (lastPage) => (lastPage.has_more ? lastPage.page + 1 : undefined), initialPageParam: 1, placeholderData: keepPreviousData, select: (data) => ({ ...data, pages: data.pages.map(normalizeAppPagination), }), enabled: get(effectiveMethodAtom) === 'bindApp', }) }) const sourceAppsDataAtom = selectAtom(sourceAppsQueryAtom, (query) => query.data) export const sourceAppsErrorAtom = selectAtom(sourceAppsQueryAtom, (query) => query.error) export const sourceAppsFetchNextPageAtom = selectAtom( sourceAppsQueryAtom, (query) => query.fetchNextPage, ) export const sourceAppsHasNextPageAtom = selectAtom( sourceAppsQueryAtom, (query) => query.hasNextPage, ) export const sourceAppsIsFetchingAtom = selectAtom(sourceAppsQueryAtom, (query) => query.isFetching) export const sourceAppsIsFetchingNextPageAtom = selectAtom( sourceAppsQueryAtom, (query) => query.isFetchingNextPage, ) export const sourceAppsIsLoadingAtom = selectAtom(sourceAppsQueryAtom, (query) => query.isLoading) export const sourceAppsIsPlaceholderDataAtom = selectAtom( sourceAppsQueryAtom, (query) => query.isPlaceholderData, ) export const sourceAppsAtom = atom((get) => { return (get(sourceAppsDataAtom)?.pages.flatMap((page) => page.data) ?? []) as WorkflowSourceApp[] }) export const effectiveSelectedAppAtom = atom((get) => { const selectedApp = get(selectedAppAtom) if (selectedApp) return selectedApp if (get(sourceAppsIsPlaceholderDataAtom)) return undefined return get(sourceAppsAtom)[0] }) export function sourceReady(get: Getter) { const method = get(effectiveMethodAtom) return method === 'importDsl' ? get(importDslReadyAtom) : Boolean(get(effectiveSelectedAppAtom)?.id) }