Skip to content

Adapted to the new component structure #11

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

Merged
merged 1 commit into from
Jan 21, 2025
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
46 changes: 26 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,16 @@ If you have an empty CMS instance, and you want to see how it all
works go to your CMS (SaaS) instance and:

1. Go to **Settings** > **Content Types**.
2. Click **Create New** and select **Element Type** from the drop-down list.
2. Click **Create New** and select **Block Type** from the drop-down list.
3. Enter _ParagraphElement_ for the **Name** and **Display name** fields.
4. Click **Create**.
5. Click **Add Property** and select **Text** from the drop-down list.
6. Enter _Text_ for the **Name** in the **Configure Property** page.
7. Click on the **Text Type** drop-down menu and select **XHTML string (>255)**.
8. Click **Save**.
8. Go to **Setting**
9. Tick checkboxes **Available for composition in Visual Builder** and **Display as Element**
10. Click **Save**.

Then in order to run the sample you need to do the following:

Expand Down Expand Up @@ -110,21 +113,24 @@ We now need to add a new script to package.json

This script will generate types based your graphql schema.

### Adding element type
### Adding element

Before we run the codegen let's add a simple Element type to our SaaS CMS instance.
Before we run the codegen let's add a simple Element to our SaaS CMS instance.
Please open `Settings` and `Content types` screen.

Click on `Create New...` menu item and choose `Element type` option.
![clicking add element type](docs/contenttype_add_elementtype.png)
Click on `Create New...` menu item and choose `Block type` option.
![clicking add element type](docs/contenttype_add_block.png)

Fill in the name and display name and hit the `Create` button.
![adding element name](docs/contenttype_add_elementtype_dialog.png)
![adding element name](docs/contenttype_add_block_dialog.png)

You will see an empty list of properties, hit the `Add property` button and add a single `Text` `XHTML string` property:
![adding property](docs/contenttype_add_property.png)

After that you should see the newly created element type in the list.
After that click on `Settings`and tick `Available for composition in Visual Builder` and `Display as Element` checkboxes
![display as element](docs/block_settings_display_as.png)

You should see the newly created element type in the list.
![added element type](docs/contenttype_list.png)

### Graphql generation
Expand Down Expand Up @@ -201,7 +207,7 @@ query VisualBuilder($key: String, $version: String) {
... on CompositionStructureNode {
key
elements: nodes {
...compositionElementNode
...compositionComponentNode
}
}
}
Expand Down Expand Up @@ -265,7 +271,7 @@ const VisualBuilderComponent: FC<VisualBuilderProps> = ({ key, version }) => {
<div className="flex-1 flex flex-col flex-nowrap justify-start vb:col" key={column.key}>
{column.elements?.map((element: any) =>
<div data-epi-block-id={element?.key} key={element?.key}>
<CompositionNodeComponent compositionElementNode={element}/>
<CompositionNodeComponent compositionComponentNode={element}/>
</div>
)}
</div>
Expand All @@ -292,10 +298,10 @@ import { FragmentType, useFragment } from '../../graphql/fragment-masking'
import { graphql } from '@/graphql'
import ParagraphElementComponent from '../elements/ParagraphElementComponent'

export const CompositionElementNodeFragment = graphql(/* GraphQL */ `
fragment compositionElementNode on CompositionElementNode {
export const CompositionComponentNodeFragment = graphql(/* GraphQL */ `
fragment compositionComponentNode on CompositionComponentNode {
key
element {
component {
_metadata {
types
}
Expand All @@ -304,23 +310,23 @@ export const CompositionElementNodeFragment = graphql(/* GraphQL */ `
}
`)

const CompositionElementNodeComponent = (props: {
compositionElementNode: FragmentType<typeof CompositionElementNodeFragment>
const CompositionComponentNodeComponent = (props: {
compositionComponentNode: FragmentType<typeof CompositionComponentNodeFragment>
}) => {
const compositionElementNode = useFragment(CompositionElementNodeFragment, props.compositionElementNode)
const element = compositionElementNode.element
switch (element?.__typename) {
const compositionComponentNode = useFragment(CompositionComponentNodeFragment, props.compositionComponentNode)
const component = compositionComponentNode.component
switch (component?.__typename) {
case "ParagraphElement":
return <ParagraphElementComponent paragraphElement={element}/>
return <ParagraphElementComponent paragraphElement={component}/>
default:
return <>NotImplementedException</>
}
}

export default CompositionElementNodeComponent
export default CompositionComponentNodeComponent
```

As you can see based on `element.__typename` we can use different components - in our
As you can see based on `component.__typename` we can use different components - in our
example we will use `ParagraphElementComponent`.

### Subscribing to content changes
Expand Down
Binary file added docs/block_settings_display_as.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/contenttype_add_block.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/contenttype_add_block_dialog.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed docs/contenttype_add_elementtype.png
Binary file not shown.
Binary file removed docs/contenttype_add_elementtype_dialog.png
Binary file not shown.
Binary file modified docs/contenttype_add_property.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/contenttype_list.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 10 additions & 10 deletions src/components/base/CompositionNodeComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import { FragmentType, useFragment } from '../../graphql/fragment-masking'
import { graphql } from '@/graphql'
import ParagraphElementComponent from '../elements/ParagraphElementComponent'

export const CompositionElementNodeFragment = graphql(/* GraphQL */ `
fragment compositionElementNode on CompositionElementNode {
export const CompositionComponentNodeFragment = graphql(/* GraphQL */ `
fragment compositionComponentNode on CompositionComponentNode {
key
element {
component {
_metadata {
types
}
Expand All @@ -14,17 +14,17 @@ export const CompositionElementNodeFragment = graphql(/* GraphQL */ `
}
`)

const CompositionElementNodeComponent = (props: {
compositionElementNode: FragmentType<typeof CompositionElementNodeFragment>
const CompositionComponentNodeComponent = (props: {
compositionComponentNode: FragmentType<typeof CompositionComponentNodeFragment>
}) => {
const compositionElementNode = useFragment(CompositionElementNodeFragment, props.compositionElementNode)
const element = compositionElementNode.element
switch (element?.__typename) {
const compositionComponentNode = useFragment(CompositionComponentNodeFragment, props.compositionComponentNode)
const component = compositionComponentNode.component
switch (component?.__typename) {
case "ParagraphElement":
return <ParagraphElementComponent paragraphElement={element}/>
return <ParagraphElementComponent paragraphElement={component}/>
default:
return <>NotImplementedException</>
}
}

export default CompositionElementNodeComponent
export default CompositionComponentNodeComponent
4 changes: 2 additions & 2 deletions src/components/base/VisualBuilderComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ query VisualBuilder($key: String, $version: String) {
... on CompositionStructureNode {
key
elements: nodes {
...compositionElementNode
...compositionComponentNode
}
}
}
Expand Down Expand Up @@ -94,7 +94,7 @@ const VisualBuilderComponent: FC<VisualBuilderProps> = ({ version, contentKey })
<div className="flex-1 flex flex-col flex-nowrap justify-start vb:col" key={column.key}>
{column.elements?.map((element: any) =>
<div data-epi-block-id={element?.key} key={element?.key}>
<CompositionNodeComponent compositionElementNode={element}/>
<CompositionNodeComponent compositionComponentNode={element}/>
</div>
)}
</div>
Expand Down
8 changes: 4 additions & 4 deletions src/graphql/gql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/
* Therefore it is highly recommended to use the babel or swc plugin for production.
*/
const documents = {
"\n fragment compositionElementNode on CompositionElementNode {\n key\n element {\n _metadata {\n types\n }\n ...paragraphElement\n }\n }\n": types.CompositionElementNodeFragmentDoc,
"\nquery VisualBuilder($key: String, $version: String) {\n _Experience(where: {\n _metadata: { key: { eq: $key } }\n _or: { _metadata: { version: { eq: $version } } }\n }) {\n items { \n composition {\n grids: nodes {\n ... on CompositionStructureNode {\n key\n rows: nodes {\n ... on CompositionStructureNode {\n key\n columns: nodes {\n ... on CompositionStructureNode {\n key\n elements: nodes {\n ...compositionElementNode\n }\n }\n }\n }\n }\n }\n }\n }\n _metadata {\n key\n version, \n }\n }\n }\n}\n": types.VisualBuilderDocument,
"\n fragment compositionComponentNode on CompositionComponentNode {\n key\n component {\n _metadata {\n types\n }\n ...paragraphElement\n }\n }\n": types.CompositionComponentNodeFragmentDoc,
"\nquery VisualBuilder($key: String, $version: String) {\n _Experience(where: {\n _metadata: { key: { eq: $key } }\n _or: { _metadata: { version: { eq: $version } } }\n }) {\n items { \n composition {\n grids: nodes {\n ... on CompositionStructureNode {\n key\n rows: nodes {\n ... on CompositionStructureNode {\n key\n columns: nodes {\n ... on CompositionStructureNode {\n key\n elements: nodes {\n ...compositionComponentNode\n }\n }\n }\n }\n }\n }\n }\n }\n _metadata {\n key\n version, \n }\n }\n }\n}\n": types.VisualBuilderDocument,
"\n fragment paragraphElement on ParagraphElement {\n Text {\n html\n }\n }\n": types.ParagraphElementFragmentDoc,
};

Expand All @@ -35,11 +35,11 @@ export function graphql(source: string): unknown;
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function graphql(source: "\n fragment compositionElementNode on CompositionElementNode {\n key\n element {\n _metadata {\n types\n }\n ...paragraphElement\n }\n }\n"): (typeof documents)["\n fragment compositionElementNode on CompositionElementNode {\n key\n element {\n _metadata {\n types\n }\n ...paragraphElement\n }\n }\n"];
export function graphql(source: "\n fragment compositionComponentNode on CompositionComponentNode {\n key\n component {\n _metadata {\n types\n }\n ...paragraphElement\n }\n }\n"): (typeof documents)["\n fragment compositionComponentNode on CompositionComponentNode {\n key\n component {\n _metadata {\n types\n }\n ...paragraphElement\n }\n }\n"];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function graphql(source: "\nquery VisualBuilder($key: String, $version: String) {\n _Experience(where: {\n _metadata: { key: { eq: $key } }\n _or: { _metadata: { version: { eq: $version } } }\n }) {\n items { \n composition {\n grids: nodes {\n ... on CompositionStructureNode {\n key\n rows: nodes {\n ... on CompositionStructureNode {\n key\n columns: nodes {\n ... on CompositionStructureNode {\n key\n elements: nodes {\n ...compositionElementNode\n }\n }\n }\n }\n }\n }\n }\n }\n _metadata {\n key\n version, \n }\n }\n }\n}\n"): (typeof documents)["\nquery VisualBuilder($key: String, $version: String) {\n _Experience(where: {\n _metadata: { key: { eq: $key } }\n _or: { _metadata: { version: { eq: $version } } }\n }) {\n items { \n composition {\n grids: nodes {\n ... on CompositionStructureNode {\n key\n rows: nodes {\n ... on CompositionStructureNode {\n key\n columns: nodes {\n ... on CompositionStructureNode {\n key\n elements: nodes {\n ...compositionElementNode\n }\n }\n }\n }\n }\n }\n }\n }\n _metadata {\n key\n version, \n }\n }\n }\n}\n"];
export function graphql(source: "\nquery VisualBuilder($key: String, $version: String) {\n _Experience(where: {\n _metadata: { key: { eq: $key } }\n _or: { _metadata: { version: { eq: $version } } }\n }) {\n items { \n composition {\n grids: nodes {\n ... on CompositionStructureNode {\n key\n rows: nodes {\n ... on CompositionStructureNode {\n key\n columns: nodes {\n ... on CompositionStructureNode {\n key\n elements: nodes {\n ...compositionComponentNode\n }\n }\n }\n }\n }\n }\n }\n }\n _metadata {\n key\n version, \n }\n }\n }\n}\n"): (typeof documents)["\nquery VisualBuilder($key: String, $version: String) {\n _Experience(where: {\n _metadata: { key: { eq: $key } }\n _or: { _metadata: { version: { eq: $version } } }\n }) {\n items { \n composition {\n grids: nodes {\n ... on CompositionStructureNode {\n key\n rows: nodes {\n ... on CompositionStructureNode {\n key\n columns: nodes {\n ... on CompositionStructureNode {\n key\n elements: nodes {\n ...compositionComponentNode\n }\n }\n }\n }\n }\n }\n }\n }\n _metadata {\n key\n version, \n }\n }\n }\n}\n"];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
Expand Down
Loading
Loading