Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add includeInvisibleContent option to extractTextContents #3412

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .changeset/quiet-glasses-tan.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

Add `extractTextContents` method to blocks

`extractTextContents` can be used to extract plain text from blocks. This functionality is particularly useful for operations such as search indexing or using the content for LLM-based tasks.
`extractTextContents` can be used to extract plain text from blocks. This functionality is particularly useful for operations such as search indexing or using the content for LLM-based tasks. The option `includeInvisibleContent` can be set to include the content of invisible blocks in the extracted text.

The method is optional for now, but it is recommended to implement it for all blocks and documents. The default behavior is to return

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -868,13 +868,20 @@ export function createBlocksBlock<AdditionalItemFields extends Record<string, un
const childPath = block.resolveDependencyPath(blockItem.props, pathArr.slice(3).join("."));
return `${blockItem.key}/blocks/${childPath}`;
},
extractTextContents: (state) => {
extractTextContents: (state, options) => {
const includeInvisibleContent = options?.includeInvisibleContent ?? false;

return state.blocks.reduce<string[]>((content, child) => {
const block = blockForType(child.type);
if (!block) {
throw new Error(`No Block found for type ${child.type}`); // for TS
}
return [...content, ...(block.extractTextContents?.(child.props) ?? [])];

if (!child.visible && !includeInvisibleContent) {
return content;
}

return [...content, ...(block.extractTextContents?.(child.props, options) ?? [])];
}, []);
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -465,9 +465,15 @@ export function createColumnsBlock<T extends BlockInterface>(
return `${blockItem.key}/edit/${childPath}`;
},

extractTextContents: (state) => {
extractTextContents: (state, options) => {
const includeInvisibleContent = options?.includeInvisibleContent ?? false;

return state.columns.reduce<string[]>((content, column) => {
return [...content, ...(contentBlock.extractTextContents?.(column.props) ?? [])];
if (!column.visible && !includeInvisibleContent) {
return content;
}

return [...content, ...(contentBlock.extractTextContents?.(column.props, options) ?? [])];
}, []);
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -534,9 +534,15 @@ export function createListBlock<T extends BlockInterface, AdditionalItemFields e
const childPath = block.resolveDependencyPath(blockItem.props, pathArr.slice(3).join("."));
return `${blockItem.key}/edit/${childPath}`;
},
extractTextContents: (state) => {
extractTextContents: (state, options) => {
const includeInvisibleContent = options?.includeInvisibleContent ?? false;

const content = state.blocks.reduce<string[]>((content, child) => {
return [...content, ...(block.extractTextContents?.(child.props) ?? [])];
if (!child.visible && !includeInvisibleContent) {
return content;
}

return [...content, ...(block.extractTextContents?.(child.props, options) ?? [])];
}, []);
return content;
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -446,14 +446,22 @@ export const createOneOfBlock = <T extends boolean = boolean>(
}
},

extractTextContents: (state) => {
const { state: blockState, block } = getActiveBlock(state);
extractTextContents: (state, options) => {
const includeInvisibleContent = options?.includeInvisibleContent ?? false;

if (blockState === undefined) {
return [];
}
const content = state.attachedBlocks.reduce<string[]>((content, child) => {
const block = blockForType(child.type);
if (!block) {
throw new Error(`No Block found for type ${child.type}`); // for TS
}

if (child.type !== state.activeType && !includeInvisibleContent) {
return content;
}

return block?.extractTextContents?.(blockState.props) ?? [];
return [...content, ...(block.extractTextContents?.(child.props, options) ?? [])];
}, []);
return content;
},
};
if (override) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,12 +173,18 @@ export function createOptionalBlock<T extends BlockInterface>(
return block && visible ? decoratedBlock.previewContent(block, ctx) : [];
},

extractTextContents: (state) => {
if (state.block === undefined || !state.visible) {
extractTextContents: (state, options) => {
const includeInvisibleContent = options?.includeInvisibleContent ?? false;

if (state.block === undefined) {
return [];
}

return decoratedBlock.extractTextContents?.(state.block) ?? [];
if (state.visible || includeInvisibleContent) {
return decoratedBlock.extractTextContents?.(state.block, options) ?? [];
}

return [];
},
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,11 +214,11 @@ export function composeBlocks<C extends CompositeBlocksConfig>(compositeBlocks:
return dependencyPath;
},

extractTextContents: (state) => {
extractTextContents: (state, extractTextContentsOptions) => {
const contentsPerBlock: Record<keyof C, string[]> = applyToCompositeBlocks(compositeBlocks, ([block, options], attr) => {
const extractedData = extractData([block, options], attr, state);

return block.extractTextContents?.(extractedData) ?? [];
return block.extractTextContents?.(extractedData, extractTextContentsOptions) ?? [];
});

return Object.values(contentsPerBlock).reduce((contents, blockContents) => [...contents, ...blockContents], []);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ export function createCompositeBlockSelectField<T extends string | number>({
<SelectField name="value" {...legacyFieldProps} {...fieldProps} options={options} />
</BlocksFinalForm>
),
extractTextContents: (state) => extractTextContents?.(state) ?? [],
extractTextContents: (state, options) => extractTextContents?.(state, options) ?? [],
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ export function createCompositeBlockSwitchField({ defaultValue = false, fullWidt
<SwitchField name="value" fullWidth={fullWidth} {...fieldProps} />
</BlocksFinalForm>
),
extractTextContents: (state) => extractTextContents?.(state) ?? [],
extractTextContents: (state, options) => extractTextContents?.(state, options) ?? [],
});
}
2 changes: 1 addition & 1 deletion packages/admin/blocks-admin/src/blocks/types.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export interface BlockMethods<
dependencies?: (state: State) => BlockDependency[];
replaceDependenciesInOutput: (output: OutputApi, replacements: ReplaceDependencyObject[]) => OutputApi;
resolveDependencyPath: (state: State, jsonPath: string) => string;
extractTextContents?: (state: State) => string[];
extractTextContents?: (state: State, options: { includeInvisibleContent: boolean }) => string[];
}

export interface AnonymousBlockInterface<
Expand Down
17 changes: 14 additions & 3 deletions packages/admin/cms-admin/src/blocks/createTextLinkBlock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ export function createTextLinkBlock(
<AdminComponentPaper disablePadding>
<Box padding={3} paddingBottom={0}>
<BlocksFinalForm
onSubmit={({ text }) => {
updateState((prevState) => ({ ...prevState, text }));
onSubmit={({ text }: { text: string | undefined }) => {
updateState((prevState) => ({ ...prevState, text: text ?? "" }));
}}
initialValues={{ text: state.text }}
>
Expand All @@ -68,7 +68,18 @@ export function createTextLinkBlock(

dynamicDisplayName: (state) => LinkBlock.dynamicDisplayName?.(state.link),

extractTextContents: (state) => [state.text, ...(block.extractTextContents?.(state) ?? [])],
extractTextContents: (state, options) => {
const content = [];

if (state.text) {
content.push(state.text);
}

const blockContent = block.extractTextContents?.(state, options) ?? [];
content.push(...blockContent);

return content;
},
};

if (override) {
Expand Down