diff --git a/invokeai/frontend/web/public/locales/en.json b/invokeai/frontend/web/public/locales/en.json index aa6a3af1b5..a5c4f820c0 100644 --- a/invokeai/frontend/web/public/locales/en.json +++ b/invokeai/frontend/web/public/locales/en.json @@ -1004,6 +1004,7 @@ "unknownOutput": "Unknown output: {{name}}", "updateNode": "Update Node", "updateApp": "Update App", + "loadingTemplates": "Loading {{name}}", "updateAllNodes": "Update Nodes", "allNodesUpdated": "All Nodes Updated", "unableToUpdateNodes_one": "Unable to update {{count}} node", diff --git a/invokeai/frontend/web/src/features/nodes/components/sidePanel/builder/WorkflowBuilder.tsx b/invokeai/frontend/web/src/features/nodes/components/sidePanel/builder/WorkflowBuilder.tsx index f71337f0ae..b31399b72f 100644 --- a/invokeai/frontend/web/src/features/nodes/components/sidePanel/builder/WorkflowBuilder.tsx +++ b/invokeai/frontend/web/src/features/nodes/components/sidePanel/builder/WorkflowBuilder.tsx @@ -2,12 +2,15 @@ import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine'; import { draggable } from '@atlaskit/pragmatic-drag-and-drop/element/adapter'; import type { SystemStyleObject } from '@invoke-ai/ui-library'; import { Button, Flex, Spacer } from '@invoke-ai/ui-library'; +import { useStore } from '@nanostores/react'; import { useAppSelector } from 'app/store/storeHooks'; +import { IAINoContentFallback } from 'common/components/IAIImageFallback'; import ScrollableContent from 'common/components/OverlayScrollbars/ScrollableContent'; import { firefoxDndFix } from 'features/dnd/util'; import { FormElementComponent } from 'features/nodes/components/sidePanel/builder/ContainerElementComponent'; import { buildFormElementDndData, useBuilderDndMonitor } from 'features/nodes/components/sidePanel/builder/dnd-hooks'; import { WorkflowBuilderEditMenu } from 'features/nodes/components/sidePanel/builder/WorkflowBuilderMenu'; +import { $hasTemplates } from 'features/nodes/store/nodesSlice'; import { selectFormRootElementId, selectIsFormEmpty } from 'features/nodes/store/workflowSlice'; import type { FormElement } from 'features/nodes/types/workflow'; import { buildContainer, buildDivider, buildHeading, buildText } from 'features/nodes/types/workflow'; @@ -15,6 +18,7 @@ import { startCase } from 'lodash-es'; import type { RefObject } from 'react'; import { memo, useEffect, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; +import { useGetOpenAPISchemaQuery } from 'services/api/endpoints/appInfo'; import { assert } from 'tsafe'; const sx: SystemStyleObject = { @@ -28,8 +32,7 @@ const sx: SystemStyleObject = { export const WorkflowBuilder = memo(() => { const { t } = useTranslation(); - const rootElementId = useAppSelector(selectFormRootElementId); - const isFormEmpty = useAppSelector(selectIsFormEmpty); + useBuilderDndMonitor(); return ( @@ -47,9 +50,7 @@ export const WorkflowBuilder = memo(() => { - - - + @@ -57,6 +58,25 @@ export const WorkflowBuilder = memo(() => { }); WorkflowBuilder.displayName = 'WorkflowBuilder'; +const WorkflowBuilderContent = memo(() => { + const { t } = useTranslation(); + const rootElementId = useAppSelector(selectFormRootElementId); + const isFormEmpty = useAppSelector(selectIsFormEmpty); + const openApiSchemaQuery = useGetOpenAPISchemaQuery(); + const loadedTemplates = useStore($hasTemplates); + + if (openApiSchemaQuery.isLoading || !loadedTemplates) { + return ; + } + + return ( + + + + ); +}); +WorkflowBuilderContent.displayName = 'WorkflowBuilderContent'; + const useAddFormElementDnd = ( type: Exclude, draggableRef: RefObject diff --git a/invokeai/frontend/web/src/features/nodes/components/sidePanel/viewMode/EmptyState.tsx b/invokeai/frontend/web/src/features/nodes/components/sidePanel/viewMode/EmptyState.tsx index 8c03c6dc31..b23803ef22 100644 --- a/invokeai/frontend/web/src/features/nodes/components/sidePanel/viewMode/EmptyState.tsx +++ b/invokeai/frontend/web/src/features/nodes/components/sidePanel/viewMode/EmptyState.tsx @@ -10,7 +10,7 @@ export const EmptyState = () => { const isCleanEditor = useAppSelector(selectCleanEditor); return ( - + { return ( - - - + ); @@ -24,10 +24,11 @@ ViewModeLeftPanelContent.displayName = 'ViewModeLeftPanelContent'; const ViewModeLeftPanelContentInner = memo(() => { const { isLoading } = useGetOpenAPISchemaQuery(); + const loadedTemplates = useStore($hasTemplates); const rootElementId = useAppSelector(selectFormRootElementId); const isFormEmpty = useAppSelector(selectIsFormEmpty); - if (isLoading) { + if (isLoading || !loadedTemplates) { return ; } @@ -35,6 +36,10 @@ const ViewModeLeftPanelContentInner = memo(() => { return ; } - return ; + return ( + + + + ); }); ViewModeLeftPanelContentInner.displayName = ' ViewModeLeftPanelContentInner';