Skip to content

Commit

Permalink
Add finder
Browse files Browse the repository at this point in the history
  • Loading branch information
KevinLanvin committed Jul 11, 2024
1 parent 572a9d9 commit c9334f2
Show file tree
Hide file tree
Showing 11 changed files with 300 additions and 56 deletions.
36 changes: 18 additions & 18 deletions _dev/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion _dev/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"@heroicons/vue": "^2.1.1",
"@meforma/vue-toaster": "^1.3.0",
"@tailwindcss/forms": "^0.5.7",
"@tinymce/tinymce-vue": "^5.1.1",
"@tinymce/tinymce-vue": "^6.0.1",
"@vitejs/plugin-vue": "^2.3.4",
"@vueform/multiselect": "^2.6.6",
"autoprefixer": "^10.4.16",
Expand Down
11 changes: 2 additions & 9 deletions _dev/src/core-logic/entities/BlockContent.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
import { ComponentContent } from "./ComponentContent";
import { PrimitiveFieldContent } from "./PrimitiveFieldContent";
import { PrimitiveFieldType } from "./ElementType";
import { Repeater } from "./Repeater";
import { FieldContent } from "./ComponentContent";

export type BlockContent = {
id: string;
block_id: string;
fields: (
| ComponentContent
| PrimitiveFieldContent<PrimitiveFieldType>
| Repeater<ComponentContent>
)[];
fields: FieldContent[];
};
11 changes: 6 additions & 5 deletions _dev/src/core-logic/entities/ComponentContent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ import { COMPONENT_TYPE, PrimitiveFieldType } from "./ElementType";
import { PrimitiveFieldContent } from "./PrimitiveFieldContent";
import { Repeater } from "./Repeater";

export type FieldContent =
| ComponentContent
| PrimitiveFieldContent<PrimitiveFieldType>
| Repeater<ComponentContent>;

export type ComponentContent = {
id: string;
component_id: string;
type: COMPONENT_TYPE;
label: string;
fields: (
| ComponentContent
| PrimitiveFieldContent<PrimitiveFieldType>
| Repeater<ComponentContent>
)[];
fields: FieldContent[];
};
2 changes: 1 addition & 1 deletion _dev/src/core-logic/tests/builder.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import columnBlockContent from "./newColumnContent.json";
import columnBlockStructure from "./columnStructure.json";

/*
Add a test here everytime you create a new builder or improve an existing one.
Add a test here every time you create a new builder or improve an existing one.
*/

describe("Block, component and Primitive content builder", () => {
Expand Down
156 changes: 156 additions & 0 deletions _dev/src/core-logic/tests/filledColumnContentWithId.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
{
"id": "block_id",
"block_id": "columnBlock",
"fields": [
{
"id": "field_0",
"type": "text",
"label": "Column block title",
"content": {
"value": "Column title"
}
},
{
"id": "field_1",
"component_id": "banner",
"type": "component",
"label": "Banner",
"fields": [
{
"id": "field_1_0",
"type": "text",
"label": "Image",
"content": {
"value": "BannerImage"
}
},
{
"id":"field_1_1",
"type":"text",
"label": "Intro",
"content": {
"value": "Wonderful intro"
}
}
]
},
{
"id": "field_2",
"sub_element_id": "column",
"type": "repeater",
"label": "Columns",
"sub_elements": [
{
"id": "field_2_0",
"component_id": "column",
"type": "component",
"label": "Columns-1",
"fields": [
{
"id": "field_2_0_0",
"type":"text",
"label": "Column title",
"content": {
"value": "Titre de colonne"
}
},
{
"id": "field_2_0_1",
"type": "repeater",
"label": "Cards",
"sub_elements": [
{
"id":"field_2_0_1_0",
"component_id": "card",
"type": "component",
"label": "Cards-1",
"fields": [
{
"id":"field_2_0_1_0_0",
"type": "text",
"label": "Card title",
"content": {
"value": "Titre de carte"
}
}
]
},
{
"id":"field_2_0_1_1",
"component_id": "card",
"type": "component",
"label": "Cards-2",
"fields": [
{
"id":"field_2_0_1_1_0",
"type": "text",
"label": "Card title",
"content": {
"value": "Titre de carte"
}
}
]
}
]
}
]
},
{
"id": "field_2_1",
"component_id": "column",
"type": "component",
"label": "Columns-2",
"fields": [
{
"id": "field_2_1_0",
"type":"text",
"label": "Column title",
"content": {
"value": "Titre de colonne"
}
},
{
"id": "field_2_1_1",
"type": "repeater",
"label": "Cards",
"sub_elements": [
{
"id":"field_2_1_1_0",
"component_id": "card",
"type": "component",
"label": "Cards-1",
"fields": [
{
"id":"field_2_1_1_0_0",
"type": "text",
"label": "Card title",
"content": {
"value": "Titre de carte"
}
}
]
},
{
"id":"field_2_1_1_1",
"component_id": "card",
"type": "component",
"label": "Cards-2",
"fields": [
{
"id":"field_2_1_1_1_0",
"type": "text",
"label": "Card title",
"content": {
"value": "Titre de carte"
}
}
]
}
]
}
]
}
]
}
]
}
46 changes: 46 additions & 0 deletions _dev/src/core-logic/tests/finder.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { BlockContent } from "../entities/BlockContent";
import filledColumnContent from "./filledColumnContentWithId.json";
import { findComponentById } from "../utils/finder";

describe("Component finder", () => {
let blockContent: BlockContent;
beforeAll(() => {
blockContent = filledColumnContent as BlockContent;
});

it("finds block id", () => {
const component = findComponentById(blockContent, "block_id");
expect(component.node.id).toEqual("block_id");
expect(component.parent).toBeUndefined();
});

it("finds a component", () => {
const component = findComponentById(blockContent, "field_0");
expect(component.node.id).toEqual("field_0");
});

it("gives block id as parent for 1st level component search", () => {
const component = findComponentById(blockContent, "field_0");
expect(component.parent.id).toEqual("block_id");
});

it("finds a repeatable component", () => {
const component = findComponentById(blockContent, "field_2_0");
expect(component.node.id).toEqual("field_2_0");
});

it("gives repeater id as parent for repeated component search", () => {
const component = findComponentById(blockContent, "field_2_0");
expect(component.parent.id).toEqual("field_2");
});

it("finds a recursively nested component", () => {
const component = findComponentById(blockContent, "field_2_1_1_0_0");
expect(component.node.id).toEqual("field_2_1_1_0_0");
});

it("gives right repeater id as parent for nested component search", () => {
const component = findComponentById(blockContent, "field_2_1_1_0_0");
expect(component.parent.id).toEqual("field_2_1_1_0");
});
});
2 changes: 1 addition & 1 deletion _dev/src/core-logic/usecases/addComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
} from "../entities/ComponentStructure";

import { BlockContent } from "../entities/BlockContent";
import { BlockStructure } from "./../entities/BlockStructure";
import { BlockStructure } from "../entities/BlockStructure";
import { ComponentContent } from "../entities/ComponentContent";
import { Repeater } from "../entities/Repeater";
import { buildNewSingleComponentFromStructure } from "../utils/builder";
Expand Down
48 changes: 48 additions & 0 deletions _dev/src/core-logic/utils/finder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { ComponentContent, FieldContent } from "../entities/ComponentContent";

import { BlockContent } from "../entities/BlockContent";
import { Repeater } from "../entities/Repeater";

export type SearchComponentResult = {
parent?: BlockContent | ComponentContent | Repeater<ComponentContent>;
node: BlockContent | FieldContent;
};

export const findComponentById = (
tree: BlockContent | ComponentContent,
id: string
): SearchComponentResult => {
// Check if block is searched id
if (tree.id === id) return { node: tree };
// Check if one of the current node fields matches the id
const foundField = tree.fields.find((field) => field.id === id);
if (foundField) return { node: foundField, parent: tree };
// Check all repeater subfields
return findComponentByIdInRepeaterFields(tree, id);
};

const findComponentByIdInRepeaterFields = (
tree: BlockContent | ComponentContent,
id: string
) => {
const repeaterFields: Repeater<ComponentContent>[] = tree.fields.filter(
(field) => field.type === "repeater"
) as Repeater<ComponentContent>[];
for (const repeater of repeaterFields) {
const foundElement = findComponentByIdInRepeater(repeater, id);
if (foundElement) return foundElement;
}
};

const findComponentByIdInRepeater = (
repeater: Repeater<ComponentContent>,
id: string
) => {
for (const field of repeater.sub_elements) {
// Check if subfield matches
if (field.id === id) return { node: field, parent: repeater };
// Else check recursively
const foundElement = findComponentById(field, id);
if (foundElement) return foundElement;
}
};
Loading

0 comments on commit c9334f2

Please sign in to comment.