-
Notifications
You must be signed in to change notification settings - Fork 613
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(app-page-builder): make website settings view configurable (#4145)
- Loading branch information
Showing
16 changed files
with
432 additions
and
260 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
141 changes: 0 additions & 141 deletions
141
packages/app-page-builder/src/modules/WebsiteSettings/AddPbWebsiteSettings.tsx
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
85 changes: 85 additions & 0 deletions
85
packages/app-page-builder/src/modules/WebsiteSettings/config/DocumentNodeModifier.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import { DocumentNode } from "graphql"; | ||
import { ExecutableDefinitionNode, FieldNode, OperationDefinitionNode } from "graphql/language/ast"; | ||
|
||
declare module "graphql" { | ||
interface DocumentNode { | ||
__cacheKey: string; | ||
} | ||
} | ||
|
||
let documentNodeModifier: DocumentNodeModifier; | ||
|
||
class DocumentNodeModifier { | ||
private cache = new Map<string, DocumentNode>(); | ||
|
||
public augmentDocument( | ||
document: DocumentNode, | ||
selectionPath: string, | ||
selections: DocumentNode[] | ||
) { | ||
const cacheKey = this.createCacheKey(document, selections); | ||
if (this.cache.has(cacheKey)) { | ||
return this.cache.get(cacheKey) as DocumentNode; | ||
} | ||
|
||
const NEW_QUERY = structuredClone(document); | ||
selections.forEach(selection => { | ||
this.addSelectionToQuery(NEW_QUERY, selectionPath, selection); | ||
}); | ||
|
||
this.cache.set(cacheKey, NEW_QUERY); | ||
|
||
return NEW_QUERY; | ||
} | ||
|
||
public addSelectionToQuery( | ||
document: DocumentNode, | ||
selectionPath: string, | ||
addSelection: DocumentNode | ||
): void { | ||
const firstQueryDefinition = document.definitions[0] as ExecutableDefinitionNode; | ||
if (!firstQueryDefinition) { | ||
return; | ||
} else if (!firstQueryDefinition.selectionSet) { | ||
return; | ||
} | ||
|
||
let tree = firstQueryDefinition.selectionSet.selections as FieldNode[]; | ||
const fields = selectionPath.split("."); | ||
|
||
fieldLoop: for (const field of fields) { | ||
for (const selection of tree) { | ||
if (!selection.selectionSet) { | ||
continue; | ||
} | ||
if (selection.name.value === field) { | ||
tree = selection.selectionSet.selections as FieldNode[]; | ||
continue fieldLoop; | ||
} | ||
} | ||
// If we get here, it means we didn't find the necessary selection | ||
return; | ||
} | ||
/** | ||
* We must cast because there are a lot of types that are not intertwined and TS is complaining | ||
*/ | ||
tree.push( | ||
...((addSelection.definitions[0] as ExecutableDefinitionNode).selectionSet | ||
.selections as FieldNode[]) | ||
); | ||
} | ||
|
||
private createCacheKey(document: DocumentNode, selections: DocumentNode[]) { | ||
const def = document.definitions[0] as OperationDefinitionNode; | ||
const operationName = def.name?.value; | ||
return [operationName, ...selections.map(node => node.__cacheKey)].join(":"); | ||
} | ||
} | ||
|
||
export function createDocumentNodeModifier() { | ||
if (!documentNodeModifier) { | ||
documentNodeModifier = new DocumentNodeModifier(); | ||
} | ||
|
||
return documentNodeModifier; | ||
} |
46 changes: 46 additions & 0 deletions
46
packages/app-page-builder/src/modules/WebsiteSettings/config/Element.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import React from "react"; | ||
import { DocumentNode } from "graphql"; | ||
import { makeDecoratable } from "@webiny/app-admin"; | ||
import { Property, useIdGenerator } from "@webiny/react-properties"; | ||
|
||
export interface ElementConfig { | ||
name: string; | ||
element: JSX.Element; | ||
} | ||
|
||
export interface ElementProps { | ||
name: string; | ||
element?: JSX.Element; | ||
children?: React.ReactNode; | ||
querySelection?: DocumentNode; | ||
remove?: boolean; | ||
before?: string; | ||
after?: string; | ||
} | ||
|
||
export const Element = makeDecoratable( | ||
"WebsiteSettingsElement", | ||
({ name, remove, before, after, ...props }: ElementProps) => { | ||
const getId = useIdGenerator("element"); | ||
const element = props.element ?? props.children; | ||
|
||
const placeAfter = after !== undefined ? getId(after) : undefined; | ||
const placeBefore = before !== undefined ? getId(before) : undefined; | ||
|
||
return ( | ||
<Property | ||
id={getId(name)} | ||
name={"elements"} | ||
remove={remove} | ||
array={true} | ||
before={placeBefore} | ||
after={placeAfter} | ||
> | ||
<Property id={getId(name, "name")} name={"name"} value={name} /> | ||
{element ? ( | ||
<Property id={getId(name, "element")} name={"element"} value={element} /> | ||
) : null} | ||
</Property> | ||
); | ||
} | ||
); |
Oops, something went wrong.