mirror of
https://github.com/invoke-ai/InvokeAI.git
synced 2026-04-23 03:00:31 -04:00
refactor(ui): standardize more workflow editor hooks to use Safe and OrThrow suffixes for clarity
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { Handle, Position } from '@xyflow/react';
|
||||
import { useNodeTemplate } from 'features/nodes/hooks/useNodeTemplate';
|
||||
import { useNodeTemplateOrThrow } from 'features/nodes/hooks/useNodeTemplateOrThrow';
|
||||
import { map } from 'lodash-es';
|
||||
import type { CSSProperties } from 'react';
|
||||
import { memo } from 'react';
|
||||
@@ -19,7 +19,7 @@ const collapsedHandleStyles: CSSProperties = {
|
||||
};
|
||||
|
||||
const InvocationNodeCollapsedHandles = ({ nodeId }: Props) => {
|
||||
const template = useNodeTemplate(nodeId);
|
||||
const template = useNodeTemplateOrThrow(nodeId);
|
||||
|
||||
if (!template) {
|
||||
return null;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Flex, Icon, Text, Tooltip } from '@invoke-ai/ui-library';
|
||||
import { compare } from 'compare-versions';
|
||||
import { useNodeUserTitleSafe } from 'features/nodes/hooks/useNodeUserTitleSafe';
|
||||
import { useNodeNeedsUpdate } from 'features/nodes/hooks/useNodeNeedsUpdate';
|
||||
import { useInvocationNodeNotes } from 'features/nodes/hooks/useNodeNotes';
|
||||
import { useNodeTemplate } from 'features/nodes/hooks/useNodeTemplate';
|
||||
import { useNodeTemplateOrThrow } from 'features/nodes/hooks/useNodeTemplateOrThrow';
|
||||
import { useNodeUserTitleSafe } from 'features/nodes/hooks/useNodeUserTitleSafe';
|
||||
import { useNodeVersion } from 'features/nodes/hooks/useNodeVersion';
|
||||
import { memo, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -29,7 +29,7 @@ const TooltipContent = memo(({ nodeId }: { nodeId: string }) => {
|
||||
const notes = useInvocationNodeNotes(nodeId);
|
||||
const label = useNodeUserTitleSafe(nodeId);
|
||||
const version = useNodeVersion(nodeId);
|
||||
const nodeTemplate = useNodeTemplate(nodeId);
|
||||
const nodeTemplate = useNodeTemplateOrThrow(nodeId);
|
||||
const { t } = useTranslation();
|
||||
|
||||
const title = useMemo(() => {
|
||||
|
||||
@@ -5,7 +5,7 @@ import ScrollableContent from 'common/components/OverlayScrollbars/ScrollableCon
|
||||
import { InvocationNodeNotesTextarea } from 'features/nodes/components/flow/nodes/Invocation/InvocationNodeNotesTextarea';
|
||||
import { TemplateGate } from 'features/nodes/components/sidePanel/inspector/NodeTemplateGate';
|
||||
import { useNodeNeedsUpdate } from 'features/nodes/hooks/useNodeNeedsUpdate';
|
||||
import { useNodeTemplate } from 'features/nodes/hooks/useNodeTemplate';
|
||||
import { useNodeTemplateOrThrow } from 'features/nodes/hooks/useNodeTemplateOrThrow';
|
||||
import { useNodeVersion } from 'features/nodes/hooks/useNodeVersion';
|
||||
import { selectLastSelectedNodeId } from 'features/nodes/store/selectors';
|
||||
import { memo } from 'react';
|
||||
@@ -36,7 +36,7 @@ export default memo(InspectorDetailsTab);
|
||||
const Content = memo(({ nodeId }: { nodeId: string }) => {
|
||||
const { t } = useTranslation();
|
||||
const version = useNodeVersion(nodeId);
|
||||
const template = useNodeTemplate(nodeId);
|
||||
const template = useNodeTemplateOrThrow(nodeId);
|
||||
const needsUpdate = useNodeNeedsUpdate(nodeId);
|
||||
|
||||
return (
|
||||
|
||||
@@ -5,7 +5,7 @@ import ScrollableContent from 'common/components/OverlayScrollbars/ScrollableCon
|
||||
import DataViewer from 'features/gallery/components/ImageMetadataViewer/DataViewer';
|
||||
import { TemplateGate } from 'features/nodes/components/sidePanel/inspector/NodeTemplateGate';
|
||||
import { useNodeExecutionState } from 'features/nodes/hooks/useNodeExecutionState';
|
||||
import { useNodeTemplate } from 'features/nodes/hooks/useNodeTemplate';
|
||||
import { useNodeTemplateOrThrow } from 'features/nodes/hooks/useNodeTemplateOrThrow';
|
||||
import { selectLastSelectedNodeId } from 'features/nodes/store/selectors';
|
||||
import { memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -37,7 +37,7 @@ const getKey = (result: AnyInvocationOutput, i: number) => `${result.type}-${i}`
|
||||
|
||||
const Content = memo(({ nodeId }: { nodeId: string }) => {
|
||||
const { t } = useTranslation();
|
||||
const template = useNodeTemplate(nodeId);
|
||||
const template = useNodeTemplateOrThrow(nodeId);
|
||||
const nes = useNodeExecutionState(nodeId);
|
||||
|
||||
if (!nes || nes.outputs.length === 0) {
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { IAINoContentFallback } from 'common/components/IAIImageFallback';
|
||||
import DataViewer from 'features/gallery/components/ImageMetadataViewer/DataViewer';
|
||||
import { TemplateGate } from 'features/nodes/components/sidePanel/inspector/NodeTemplateGate';
|
||||
import { useNodeTemplate } from 'features/nodes/hooks/useNodeTemplate';
|
||||
import { useNodeTemplateOrThrow } from 'features/nodes/hooks/useNodeTemplateOrThrow';
|
||||
import { selectLastSelectedNodeId } from 'features/nodes/store/selectors';
|
||||
import { memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -29,7 +29,7 @@ export default memo(NodeTemplateInspector);
|
||||
|
||||
const Content = memo(({ nodeId }: { nodeId: string }) => {
|
||||
const { t } = useTranslation();
|
||||
const template = useNodeTemplate(nodeId);
|
||||
const template = useNodeTemplateOrThrow(nodeId);
|
||||
|
||||
return <DataViewer data={template} label={t('nodes.nodeTemplate')} bg="base.850" color="base.200" />;
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useNodeTemplateSafe } from 'features/nodes/hooks/useNodeTemplate';
|
||||
import { useNodeTemplateSafe } from 'features/nodes/hooks/useNodeTemplateSafe';
|
||||
import type { PropsWithChildren, ReactNode } from 'react';
|
||||
import { memo } from 'react';
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useNodeData } from 'features/nodes/hooks/useNodeData';
|
||||
import { useNodeTemplate } from 'features/nodes/hooks/useNodeTemplate';
|
||||
import { useNodeTemplateOrThrow } from './useNodeTemplateOrThrow';
|
||||
import type { FieldInputTemplate } from 'features/nodes/types/field';
|
||||
import { isSingleOrCollection } from 'features/nodes/types/field';
|
||||
import { TEMPLATE_BUILDER_MAP } from 'features/nodes/util/schema/buildFieldInputTemplate';
|
||||
@@ -19,7 +19,7 @@ const isAnyOrDirectInputField = (field: FieldInputTemplate) => {
|
||||
};
|
||||
|
||||
export const useInputFieldNamesMissing = (nodeId: string) => {
|
||||
const template = useNodeTemplate(nodeId);
|
||||
const template = useNodeTemplateOrThrow(nodeId);
|
||||
const node = useNodeData(nodeId);
|
||||
const fieldNames = useMemo(() => {
|
||||
const instanceFields = new Set(Object.keys(node.inputs));
|
||||
@@ -30,7 +30,7 @@ export const useInputFieldNamesMissing = (nodeId: string) => {
|
||||
};
|
||||
|
||||
export const useInputFieldNamesAnyOrDirect = (nodeId: string) => {
|
||||
const template = useNodeTemplate(nodeId);
|
||||
const template = useNodeTemplateOrThrow(nodeId);
|
||||
const fieldNames = useMemo(() => {
|
||||
const anyOrDirectFields: string[] = [];
|
||||
for (const [fieldName, fieldTemplate] of Object.entries(template.inputs)) {
|
||||
@@ -44,7 +44,7 @@ export const useInputFieldNamesAnyOrDirect = (nodeId: string) => {
|
||||
};
|
||||
|
||||
export const useInputFieldNamesConnection = (nodeId: string) => {
|
||||
const template = useNodeTemplate(nodeId);
|
||||
const template = useNodeTemplateOrThrow(nodeId);
|
||||
const fieldNames = useMemo(() => {
|
||||
const connectionFields: string[] = [];
|
||||
for (const [fieldName, fieldTemplate] of Object.entries(template.inputs)) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useNodeTemplate } from 'features/nodes/hooks/useNodeTemplate';
|
||||
import { useNodeTemplateOrThrow } from './useNodeTemplateOrThrow';
|
||||
import type { FieldInputTemplate } from 'features/nodes/types/field';
|
||||
import { useMemo } from 'react';
|
||||
import { assert } from 'tsafe';
|
||||
@@ -13,7 +13,7 @@ import { assert } from 'tsafe';
|
||||
* @throws Will throw an error if the template for the input field is not found.
|
||||
*/
|
||||
export const useInputFieldTemplateOrThrow = (nodeId: string, fieldName: string): FieldInputTemplate => {
|
||||
const template = useNodeTemplate(nodeId);
|
||||
const template = useNodeTemplateOrThrow(nodeId);
|
||||
const fieldTemplate = useMemo(() => {
|
||||
const _fieldTemplate = template.inputs[fieldName];
|
||||
assert(_fieldTemplate, `Template for input field ${fieldName} not found.`);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useNodeTemplateSafe } from 'features/nodes/hooks/useNodeTemplate';
|
||||
import { useNodeTemplateSafe } from 'features/nodes/hooks/useNodeTemplateSafe';
|
||||
import type { FieldInputTemplate } from 'features/nodes/types/field';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { useNodeTemplate } from 'features/nodes/hooks/useNodeTemplate';
|
||||
import { useNodeTemplateOrThrow } from './useNodeTemplateOrThrow';
|
||||
import { useMemo } from 'react';
|
||||
import { assert } from 'tsafe';
|
||||
|
||||
export const useInputFieldTemplateTitleOrThrow = (nodeId: string, fieldName: string): string => {
|
||||
const template = useNodeTemplate(nodeId);
|
||||
const template = useNodeTemplateOrThrow(nodeId);
|
||||
|
||||
const title = useMemo(() => {
|
||||
const fieldTemplate = template.inputs[fieldName];
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { useNodeTemplate } from 'features/nodes/hooks/useNodeTemplate';
|
||||
import { useNodeTemplateOrThrow } from './useNodeTemplateOrThrow';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
export const useInputFieldTemplateTitleSafe = (nodeId: string, fieldName: string): string => {
|
||||
const template = useNodeTemplate(nodeId);
|
||||
const template = useNodeTemplateOrThrow(nodeId);
|
||||
const title = useMemo(() => template.inputs[fieldName]?.title ?? '', [fieldName, template.inputs]);
|
||||
return title;
|
||||
};
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { useNodeTemplate } from 'features/nodes/hooks/useNodeTemplate';
|
||||
import { useNodeTemplateOrThrow } from './useNodeTemplateOrThrow';
|
||||
import { isBatchNodeType, isGeneratorNodeType } from 'features/nodes/types/invocation';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
export const useIsExecutableNode = (nodeId: string) => {
|
||||
const template = useNodeTemplate(nodeId);
|
||||
const template = useNodeTemplateOrThrow(nodeId);
|
||||
const isExecutableNode = useMemo(
|
||||
() => !isBatchNodeType(template.type) && !isGeneratorNodeType(template.type),
|
||||
[template]
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { useNodeTemplate } from 'features/nodes/hooks/useNodeTemplate';
|
||||
import { useNodeTemplateOrThrow } from './useNodeTemplateOrThrow';
|
||||
import type { Classification } from 'features/nodes/types/common';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
export const useNodeClassification = (nodeId: string): Classification => {
|
||||
const template = useNodeTemplate(nodeId);
|
||||
const template = useNodeTemplateOrThrow(nodeId);
|
||||
const classification = useMemo(() => template.classification, [template]);
|
||||
return classification;
|
||||
};
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { useNodeTemplate } from 'features/nodes/hooks/useNodeTemplate';
|
||||
import { useNodeTemplateOrThrow } from './useNodeTemplateOrThrow';
|
||||
import { some } from 'lodash-es';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
export const useNodeHasImageOutput = (nodeId: string): boolean => {
|
||||
const template = useNodeTemplate(nodeId);
|
||||
const template = useNodeTemplateOrThrow(nodeId);
|
||||
const hasImageOutput = useMemo(
|
||||
() =>
|
||||
some(
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useNodeTemplate } from 'features/nodes/hooks/useNodeTemplate';
|
||||
import { useNodeTemplateOrThrow } from './useNodeTemplateOrThrow';
|
||||
import { useNodeType } from 'features/nodes/hooks/useNodeType';
|
||||
import { useNodeVersion } from 'features/nodes/hooks/useNodeVersion';
|
||||
import { useMemo } from 'react';
|
||||
@@ -6,7 +6,7 @@ import { useMemo } from 'react';
|
||||
export const useNodeNeedsUpdate = (nodeId: string) => {
|
||||
const type = useNodeType(nodeId);
|
||||
const version = useNodeVersion(nodeId);
|
||||
const template = useNodeTemplate(nodeId);
|
||||
const template = useNodeTemplateOrThrow(nodeId);
|
||||
const needsUpdate = useMemo(() => {
|
||||
if (type !== template.type) {
|
||||
return true;
|
||||
|
||||
@@ -5,7 +5,7 @@ import type { InvocationTemplate } from 'features/nodes/types/invocation';
|
||||
import { useMemo } from 'react';
|
||||
import { assert } from 'tsafe';
|
||||
|
||||
export const useNodeTemplate = (nodeId: string): InvocationTemplate => {
|
||||
export const useNodeTemplateOrThrow = (nodeId: string): InvocationTemplate => {
|
||||
const templates = useStore($templates);
|
||||
const type = useNodeType(nodeId);
|
||||
const template = useMemo(() => {
|
||||
@@ -15,10 +15,3 @@ export const useNodeTemplate = (nodeId: string): InvocationTemplate => {
|
||||
}, [templates, type]);
|
||||
return template;
|
||||
};
|
||||
|
||||
export const useNodeTemplateSafe = (nodeId: string): InvocationTemplate | null => {
|
||||
const templates = useStore($templates);
|
||||
const type = useNodeType(nodeId);
|
||||
const template = useMemo(() => templates[type] ?? null, [templates, type]);
|
||||
return template;
|
||||
};
|
||||
@@ -0,0 +1,12 @@
|
||||
import { useStore } from '@nanostores/react';
|
||||
import { useNodeType } from 'features/nodes/hooks/useNodeType';
|
||||
import { $templates } from 'features/nodes/store/nodesSlice';
|
||||
import type { InvocationTemplate } from 'features/nodes/types/invocation';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
export const useNodeTemplateSafe = (nodeId: string): InvocationTemplate | null => {
|
||||
const templates = useStore($templates);
|
||||
const type = useNodeType(nodeId);
|
||||
const template = useMemo(() => templates[type] ?? null, [templates, type]);
|
||||
return template;
|
||||
};
|
||||
@@ -1,10 +1,11 @@
|
||||
import { useNodeTemplate } from 'features/nodes/hooks/useNodeTemplate';
|
||||
import { getSortedFilteredFieldNames } from 'features/nodes/util/node/getSortedFilteredFieldNames';
|
||||
import { map } from 'lodash-es';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import { useNodeTemplateOrThrow } from './useNodeTemplateOrThrow';
|
||||
|
||||
export const useOutputFieldNames = (nodeId: string): string[] => {
|
||||
const template = useNodeTemplate(nodeId);
|
||||
const template = useNodeTemplateOrThrow(nodeId);
|
||||
const fieldNames = useMemo(() => getSortedFilteredFieldNames(map(template.outputs)), [template.outputs]);
|
||||
return fieldNames;
|
||||
};
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { useNodeTemplate } from 'features/nodes/hooks/useNodeTemplate';
|
||||
import { useNodeTemplateOrThrow } from './useNodeTemplateOrThrow';
|
||||
import type { FieldOutputTemplate } from 'features/nodes/types/field';
|
||||
import { useMemo } from 'react';
|
||||
import { assert } from 'tsafe';
|
||||
|
||||
export const useOutputFieldTemplate = (nodeId: string, fieldName: string): FieldOutputTemplate => {
|
||||
const template = useNodeTemplate(nodeId);
|
||||
const template = useNodeTemplateOrThrow(nodeId);
|
||||
const fieldTemplate = useMemo(() => {
|
||||
const _fieldTemplate = template.outputs[fieldName];
|
||||
assert(_fieldTemplate, `Template for output field ${fieldName} not found`);
|
||||
|
||||
Reference in New Issue
Block a user