Page MenuHomeSealhub

component-preview-actions.ts
No OneTemporary

component-preview-actions.ts

/* eslint-disable @typescript-eslint/consistent-type-assertions */
import type { Registry, TableData } from "@sealcode/jdd";
import { List, makeSimpleEnglishJDDContext, Table } from "@sealcode/jdd";
import { isTableData, isTableRegularRow } from "@sealcode/jdd";
import objectPath from "object-path";
import type { JDDPageState } from "./jdd-page.js";
import type { StatefulPageActionArgument } from "@sealcode/sealgen";
import type JDDPage from "./jdd-page.js";
function moveElement<T>(
array: Array<T>,
fromIndex: number,
toIndex: number
): Array<T> {
const element = array.splice(fromIndex, 1)[0];
array.splice(toIndex, 0, element as T);
return array;
}
export function getComponentData(
state: JDDPageState,
arg_path: string[],
registry: Registry
) {
const index_arg = arg_path[1];
if (!index_arg) {
throw new Error("Missing component index in arg path");
}
const component_index = parseInt(index_arg);
const component_args = state.components[component_index]?.args || {};
const component_name =
state.components[component_index]?.component_name || "";
const component = registry.get(component_name);
const arg_path_within_component = arg_path.slice(3); // remove "components" and the index of the component and "args"
const [argument, , argument_value] = component?.getArgumentAtPath(
makeSimpleEnglishJDDContext({ registry }),
arg_path_within_component,
component_args
) || [null, null, null];
return {
component_index,
component_args,
component_name,
component,
argument,
argument_value,
arg_path_within_component,
};
}
export const ComponentPreviewActions = <const>{
add_array_item: async ({
ctx,
state,
args: [arg_path],
page,
}: StatefulPageActionArgument<JDDPageState, [string[]]>) => {
const {
component_name,
component,
argument,
arg_path_within_component,
argument_value,
} = getComponentData(state, arg_path, (page as JDDPage).registry);
if (!component) {
console.error("unknown component: ", component_name);
return state;
}
if (!argument) {
console.error(
"Didn't find a list argument at this path",
arg_path_within_component
);
console.debug("Found this instead:", argument);
return state;
}
if (!(argument instanceof List)) {
throw new Error(
`Expected argument in path ${arg_path.join(
"."
)} to be an instance of List`
);
}
objectPath.insert(
state,
arg_path,
await argument.item_type.getExampleValue(
(page as JDDPage).makeJDDContext(ctx)
),
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
Array.isArray(argument_value) ? argument_value.length : 0
);
return state;
},
remove_array_item: ({
state,
args: [arg_path, index_to_remove],
}: StatefulPageActionArgument<
JDDPageState,
[string[], number]
>): JDDPageState => {
objectPath.del(state, [...arg_path, index_to_remove]);
return state;
},
move_array_item_up: async ({
state,
args: [arg_path, element_index],
}: StatefulPageActionArgument<
JDDPageState,
[string[], number]
>): Promise<JDDPageState> => {
const array_values = objectPath.get(state, arg_path) as unknown[];
const curr = array_values[element_index];
const prev = array_values[element_index - 1];
if (!prev || !curr) {
throw new Error("No element at such index or cannot move it up");
}
[array_values[element_index - 1], array_values[element_index]] = [
curr,
prev,
];
return state;
},
move_array_item_down: async ({
state,
args: [arg_path, element_index],
}: StatefulPageActionArgument<
JDDPageState,
[string[], number]
>): Promise<JDDPageState> => {
const array_values = objectPath.get(state, arg_path) as unknown[];
const curr = array_values[element_index];
const next = array_values[element_index + 1];
if (!next || !curr) {
throw new Error("No element at such index or cannot move it up");
}
[array_values[element_index], array_values[element_index + 1]] = [
next,
curr,
];
return state;
},
change_component: async ({
ctx,
inputs,
state,
page,
}: StatefulPageActionArgument<JDDPageState, []>): Promise<JDDPageState> => {
const component_name = inputs.component;
if (!component_name || typeof component_name !== "string") {
throw new Error(
"Missing input: 'component' for action change_component. It should contain the name of the new component type"
);
}
const component = (page as JDDPage).registry.get(component_name);
if (!component) {
throw new Error(
`Unknown or disallowed component name: ${component_name}`
);
}
return {
...state,
components: [
{
component_name: component_name,
args:
(await component?.getExampleValues(
(page as JDDPage).makeJDDContext(ctx)
)) || {},
},
],
};
},
randomize_args: async ({
ctx,
state,
page,
args: [component_index_str],
}: StatefulPageActionArgument<
JDDPageState,
[string]
>): Promise<JDDPageState> => {
const { component_index, component } = getComponentData(
state,
["components", component_index_str],
(page as JDDPage).registry
);
const component_data = state.components[component_index];
if (!component_data) {
throw new Error("Missing component data");
}
component_data.args =
(await component?.getExampleValues(
(page as JDDPage).makeJDDContext(ctx)
)) || {};
return {
...state,
};
},
add_table_row: async ({
ctx,
state,
page,
args: [arg_path, columns, type = "row"],
}: StatefulPageActionArgument<
JDDPageState,
[string[], number, "header" | "row" | undefined]
>) => {
const jdd_context = (page as JDDPage).makeJDDContext(ctx);
const { component_args, argument } = getComponentData(
state,
arg_path,
(page as JDDPage).registry
);
let row;
if (!argument) {
console.error("Unknown component at path", arg_path);
return state;
}
if (!(argument instanceof Table)) {
throw new Error(
`Expected argument at path ${arg_path.join(
"."
)} to be of type Table`
);
}
if (type == "header") {
row = {
type: "header",
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
header_content: await argument.header_type.getExampleValue(
jdd_context
),
};
} else {
const cells = [];
for (let i = 0; i < columns; i++) {
cells.push(
// eslint-disable-next-line no-await-in-loop
await argument.cell_type.getExampleValue(jdd_context)
);
}
row = { type: "row", cells };
}
objectPath.push(state, [...arg_path, "rows"], row);
return state;
},
add_table_column: async ({
ctx,
state,
page,
args: [arg_path],
}: StatefulPageActionArgument<JDDPageState, [string[]]>) => {
const { argument } = getComponentData(
state,
arg_path,
(page as JDDPage).registry
) as unknown as {
argument: Table<unknown, unknown>;
};
if (!argument) {
console.error("Unknown component at path", arg_path);
return state;
}
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const tableData: TableData<unknown, unknown> = objectPath.get(
state,
arg_path
);
if (!isTableData(tableData)) {
throw new Error("wrong table data");
}
// eslint-disable-next-line @typescript-eslint/no-for-in-array
for (const i in tableData.rows) {
const row = tableData.rows[i];
if (isTableRegularRow(row)) {
row.cells.push(
// eslint-disable-next-line no-await-in-loop
await argument.cell_type.getExampleValue(
(page as JDDPage).makeJDDContext(ctx)
)
);
}
}
objectPath.set(state, arg_path, tableData);
console.log("NEW STATE AFTER ADDING THE COLUN");
console.dir(state, { depth: 10 });
return state;
},
remove_table_column: ({
state,
args: [arg_path, column_index_to_remove],
}: StatefulPageActionArgument<
JDDPageState,
[string[], number]
>): JDDPageState => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const tableData: TableData<unknown, unknown> = objectPath.get(
state,
arg_path
);
if (!isTableData(tableData)) {
throw new Error("wrong table data");
}
// eslint-disable-next-line @typescript-eslint/no-for-in-array
for (const i in tableData.rows) {
const row = tableData.rows[i];
if (isTableRegularRow(row)) {
row.cells = row.cells.filter(
(_, i) => i != column_index_to_remove
);
}
}
objectPath.set(state, arg_path, tableData);
return state;
},
remove_table_row: ({
state,
args: [arg_path, row_index],
}: StatefulPageActionArgument<
JDDPageState,
[string[], number]
>): JDDPageState => {
objectPath.del(state, [...arg_path, "rows", row_index]);
return state;
},
move_table_column_right: ({
state,
page,
args: [arg_path, column_index],
}: StatefulPageActionArgument<JDDPageState, [string[], number]>) => {
const { component_args } = getComponentData(
state,
arg_path,
(page as JDDPage).registry
);
const last_path_element = arg_path.at(-1);
if (!last_path_element) {
throw new Error("arg path is empty");
}
const data = objectPath.get<unknown>(
component_args,
last_path_element,
""
);
if (!isTableData(data)) {
throw new Error(
"Expected arg value for a table to be properly shaped"
);
}
for (const row of data.rows) {
if (row.type == "row") {
moveElement(row.cells, column_index, column_index + 1);
}
}
objectPath.set(state, [...arg_path, "rows"], data.rows);
return state;
},
move_table_row_down: ({
state,
page,
args: [arg_path, row_index],
}: StatefulPageActionArgument<JDDPageState, [string[], number]>) => {
const { component_args } = getComponentData(
state,
arg_path,
(page as JDDPage).registry
);
const last_path_element = arg_path.at(-1);
if (!last_path_element) {
throw new Error("arg path is empty");
}
const data = objectPath.get<unknown>(
component_args,
last_path_element,
""
);
if (!isTableData(data)) {
throw new Error(
"Expected arg value for a table to be properly shaped"
);
}
moveElement(data.rows, row_index, row_index + 1);
objectPath.set(state, [...arg_path, "rows"], data.rows);
return state;
},
change_size: ({
state,
inputs,
}: StatefulPageActionArgument<JDDPageState>) => {
return {
...state,
preview_size: inputs.size,
};
},
add_component: async ({
ctx,
state,
inputs,
page,
}: StatefulPageActionArgument<JDDPageState, []>): Promise<JDDPageState> => {
const component_name = inputs.component;
if (!component_name) {
throw new Error("Missing component name");
}
const component = (page as JDDPage).registry.get(component_name);
return {
...state,
components: [
...state.components,
{
component_name: component_name,
args:
(await component?.getExampleValues(
(page as JDDPage).makeJDDContext(ctx)
)) || {},
},
],
};
},
remove_component: async ({
state,
args: [component_index],
}: StatefulPageActionArgument<
JDDPageState,
[number]
>): Promise<JDDPageState> => {
const newComponentState = [...state.components];
newComponentState.splice(component_index, 1);
return {
...state,
components: newComponentState,
};
},
move_component_up: async ({
state,
args: [component_index],
}: StatefulPageActionArgument<
JDDPageState,
[number]
>): Promise<JDDPageState> => {
const newComps = [...state.components];
const prev = newComps[component_index - 1];
const curr = newComps[component_index];
if (!prev || !curr) {
throw new Error("No component at such index or cannot move it up");
}
[newComps[component_index], newComps[component_index - 1]] = [
prev,
curr,
];
return { ...state, components: newComps };
},
move_component_down: async ({
state,
args: [component_index],
}: StatefulPageActionArgument<
JDDPageState,
[number]
>): Promise<JDDPageState> => {
const newComps = [...state.components];
const next = newComps[component_index + 1];
const curr = newComps[component_index];
if (!next || !curr) {
throw new Error("No component at such index or cannot move it up");
}
[newComps[component_index], newComps[component_index + 1]] = [
next,
curr,
];
return { ...state, components: newComps };
},
remove_file: async ({
state,
args: [arg_path],
}: StatefulPageActionArgument<
JDDPageState,
[string[]]
>): Promise<JDDPageState> => {
objectPath.set(state, arg_path, null);
return state;
},
replace_state: async ({
ctx,
state,
inputs,
page,
}: StatefulPageActionArgument<JDDPageState>) => {
const new_state = await (page as JDDPage).deserializeState(
ctx,
inputs["state_override"] || "{}"
);
return {
...new_state,
preview_size: state.preview_size,
};
},
};

File Metadata

Mime Type
text/x-java
Expires
Fri, Nov 28, 15:09 (1 d, 18 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1063567
Default Alt Text
component-preview-actions.ts (12 KB)

Event Timeline