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

Dynamic values improvements #6451

Merged
merged 72 commits into from
Mar 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
a5e8994
Avoid throwing errors if no condition is passed to a DataCondition
mohamedsalem401 Feb 20, 2025
b207f28
Refactor Condition class
mohamedsalem401 Feb 20, 2025
9a05a4b
Remove expecting errors for conditions tests
mohamedsalem401 Feb 20, 2025
265d7fb
Extend and refactor BaseOperator
mohamedsalem401 Feb 24, 2025
ebb99a6
Rename and refactor GenericOperator
mohamedsalem401 Feb 24, 2025
847ce26
Rename and refactor logicalOperator to BooleanOperator
mohamedsalem401 Feb 24, 2025
5420643
Refactor StringOperator
mohamedsalem401 Feb 24, 2025
72ca51b
Refactor NumberOperator
mohamedsalem401 Feb 24, 2025
2e80660
Refactor and fix DataResolverListener
mohamedsalem401 Feb 24, 2025
8a225b2
Update tests for condition Operators
mohamedsalem401 Feb 24, 2025
ed58822
Rename Condition class to ConditionEvaluator
mohamedsalem401 Feb 24, 2025
4049620
Add missing types file
mohamedsalem401 Feb 24, 2025
62c0684
Update and refactor DataCondition
mohamedsalem401 Feb 24, 2025
a951dd4
Update utils
mohamedsalem401 Feb 24, 2025
85abba3
Refactor StyleableModel class
mohamedsalem401 Feb 24, 2025
4f4d68d
Update ComponentDataCondition
mohamedsalem401 Feb 24, 2025
2aaf427
Refactor ComponentResolverWatcher
mohamedsalem401 Feb 24, 2025
b00ac0d
Fix conditional styles
mohamedsalem401 Feb 24, 2025
929ab42
Rename LogicalGroupStatement to LogicalGroupEvaluator
mohamedsalem401 Feb 24, 2025
761bdbf
Fix tests for DataCondition
mohamedsalem401 Feb 24, 2025
8a5d45d
Add setter methods for component data variable
mohamedsalem401 Feb 24, 2025
7e7e797
Add setters and getter to ComponentDataCondition
mohamedsalem401 Feb 24, 2025
c98b78b
Add getters to ComponentDataVariable
mohamedsalem401 Feb 24, 2025
d5e1f96
Rename test file
mohamedsalem401 Feb 24, 2025
6e266a2
Merge branch 'dev' of https://github.com/GrapesJS/grapesjs into dynam…
mohamedsalem401 Feb 25, 2025
deb5a74
Make dynamic components undroppable
mohamedsalem401 Feb 26, 2025
b93153d
Fix collection types
mohamedsalem401 Feb 26, 2025
af5a0c5
Update collections ( add setters and getter, first item editable, syn…
mohamedsalem401 Mar 3, 2025
ec81416
Update data collection tests
mohamedsalem401 Mar 5, 2025
ac8c576
Format tests
mohamedsalem401 Mar 5, 2025
04f72fb
Fix some ComponentData collection bugs
mohamedsalem401 Mar 5, 2025
1428d88
Refactor setStartIndex and setEndIndex
mohamedsalem401 Mar 5, 2025
9aae95c
Fix getComponentDef test
mohamedsalem401 Mar 5, 2025
a643411
Fix bug with end index = 0
mohamedsalem401 Mar 5, 2025
80237cd
fix test for setDataSource
mohamedsalem401 Mar 5, 2025
72f4d81
fix test for HTML updates
mohamedsalem401 Mar 5, 2025
e5fcba3
Format
mohamedsalem401 Mar 5, 2025
bee0643
Merge branch 'dev' of https://github.com/GrapesJS/grapesjs into dynam…
mohamedsalem401 Mar 5, 2025
215ade0
Add tests for the new option in getDataValue for conditions ( skipDyn…
mohamedsalem401 Mar 5, 2025
174b11b
rename Operation to DataConditionOperation
mohamedsalem401 Mar 5, 2025
dcfb273
Run __onStyleChange after style changes as before
mohamedsalem401 Mar 5, 2025
ef13f27
Format
mohamedsalem401 Mar 5, 2025
99fff68
Up BooleanOperator
artf Mar 10, 2025
9c6cb0c
Merge branch 'dev' of https://github.com/artf/grapesjs into dynamic-v…
artf Mar 10, 2025
6c8783a
Merge branch 'dev' of https://github.com/GrapesJS/grapesjs into dynam…
mohamedsalem401 Mar 13, 2025
154cbc9
Avoid raising errors for wrong dynamic value types
mohamedsalem401 Mar 13, 2025
1a90a53
Refactor DataCondition
mohamedsalem401 Mar 13, 2025
53b5006
Format
mohamedsalem401 Mar 13, 2025
3a6505a
Refactor how component data variable works internally
mohamedsalem401 Mar 13, 2025
4f7f1b6
Symbols fix
mohamedsalem401 Mar 17, 2025
a0ba9da
Add docs
mohamedsalem401 Mar 17, 2025
55b16d9
Refactor componentDatacondition
mohamedsalem401 Mar 17, 2025
1bb179d
Add types for Datacondition output ( result ) types
mohamedsalem401 Mar 17, 2025
13dacb3
Refactor DataCondition
mohamedsalem401 Mar 17, 2025
41e5887
Refactor ComponentDataCollection
mohamedsalem401 Mar 17, 2025
fbb5616
Refactor styleableModel
mohamedsalem401 Mar 17, 2025
63cefe9
Add missing files and utils
mohamedsalem401 Mar 17, 2025
a5a1dde
Up tests for ComponentDataCondition
mohamedsalem401 Mar 17, 2025
14bd129
Add new tests for component data condition
mohamedsalem401 Mar 17, 2025
3e2faf2
Fix quality check
mohamedsalem401 Mar 17, 2025
bb0650d
Merge branch 'dev' into dynamic-values-improvements
artf Mar 17, 2025
bca58dd
Move ComponentDataVariable path and default value to dataResolver pro…
mohamedsalem401 Mar 18, 2025
c893319
Update component data condition structure
mohamedsalem401 Mar 19, 2025
e33551d
Refactor data condition
mohamedsalem401 Mar 19, 2025
8dd768d
Merge branch 'dev' of https://github.com/GrapesJS/grapesjs into dynam…
mohamedsalem401 Mar 19, 2025
a14c4af
Fix ifTrue and ifFalse position in ComponentDataCondition
mohamedsalem401 Mar 19, 2025
5dcad3d
Fix typescript
mohamedsalem401 Mar 19, 2025
2af7785
Change setIfTrueContent to be setIfTrueComponents
mohamedsalem401 Mar 21, 2025
6cbca33
Fix memory leak for binding to this.postRender
mohamedsalem401 Mar 21, 2025
4e34882
Cleanup ComponentDataConditionView
mohamedsalem401 Mar 21, 2025
18309f0
Up tests
mohamedsalem401 Mar 21, 2025
e5479e0
Merge branch 'dev' into dynamic-values-improvements
mohamedsalem401 Mar 21, 2025
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
40 changes: 33 additions & 7 deletions packages/core/src/data_sources/model/ComponentDataVariable.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,35 @@
import { ObjectAny } from '../../common';
import Component from '../../dom_components/model/Component';
import { ComponentOptions } from '../../dom_components/model/types';
import { ComponentDefinition, ComponentOptions, ComponentProperties } from '../../dom_components/model/types';
import { toLowerCase } from '../../utils/mixins';
import DataVariable, { DataVariableProps, DataVariableType } from './DataVariable';

export interface ComponentDataVariableProps extends ComponentProperties {
type: typeof DataVariableType;
dataResolver: DataVariableProps;
}

export default class ComponentDataVariable extends Component {
dataResolver: DataVariable;

get defaults() {
return {
// @ts-ignore
...super.defaults,
type: DataVariableType,
path: '',
defaultValue: '',
droppable: false,
type: DataVariableType,
dataResolver: {
path: '',
defaultValue: '',
},
};
}

constructor(props: DataVariableProps, opt: ComponentOptions) {
constructor(props: ComponentDataVariableProps, opt: ComponentOptions) {
super(props, opt);
const { type, path, defaultValue } = props;
this.dataResolver = new DataVariable({ type, path, defaultValue }, opt);

this.dataResolver = new DataVariable(props.dataResolver, opt);
this.listenToPropsChange();
}

getPath() {
Expand All @@ -47,6 +56,23 @@ export default class ComponentDataVariable extends Component {
this.dataResolver.set('defaultValue', newValue);
}

private listenToPropsChange() {
this.on('change:dataResolver', () => {
this.dataResolver.set(this.get('dataResolver'));
});
}

toJSON(opts?: ObjectAny): ComponentDefinition {
const json = super.toJSON(opts);
const dataResolver = this.dataResolver.toJSON();
delete dataResolver.type;

return {
...json,
dataResolver,
};
}

static isComponent(el: HTMLElement) {
return toLowerCase(el.tagName) === DataVariableType;
}
Expand Down
19 changes: 12 additions & 7 deletions packages/core/src/data_sources/model/DataResolverListener.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ import { Model } from '../../common';
import EditorModel from '../../editor/model/Editor';
import DataVariable, { DataVariableType } from './DataVariable';
import { DataResolver } from '../types';
import { DataCondition, DataConditionType } from './conditional_variables/DataCondition';
import {
DataCondition,
DataConditionOutputChangedEvent,
DataConditionType,
} from './conditional_variables/DataCondition';
import { DataCollectionVariableType } from './data_collection/constants';
import DataCollectionVariable from './data_collection/DataCollectionVariable';

Expand Down Expand Up @@ -64,12 +68,13 @@ export default class DataResolverListener {
}

private listenToConditionalVariable(dataVariable: DataCondition): ListenerWithCallback[] {
const { em } = this;
const dataListeners = dataVariable.getDependentDataVariables().flatMap((dataVariable) => {
return this.listenToDataVariable(new DataVariable(dataVariable, { em }));
});

return dataListeners;
return [
{
obj: dataVariable,
event: DataConditionOutputChangedEvent,
callback: this.onChange,
},
];
}

private listenToDataVariable(dataVariable: DataVariable): ListenerWithCallback[] {
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/data_sources/model/DataVariable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import EditorModel from '../../editor/model/Editor';
export const DataVariableType = 'data-variable' as const;

export interface DataVariableProps {
type: typeof DataVariableType;
type?: typeof DataVariableType;
path: string;
defaultValue?: string;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,61 +1,123 @@
import Component from '../../../dom_components/model/Component';
import { ComponentDefinition, ComponentOptions } from '../../../dom_components/model/types';
import {
ComponentDefinition as ComponentProperties,
ComponentDefinitionDefined,
ComponentOptions,
ToHTMLOptions,
ComponentAddType,
} from '../../../dom_components/model/types';
import { toLowerCase } from '../../../utils/mixins';
import { DataCondition, DataConditionProps, DataConditionType } from './DataCondition';
import { DataCondition, DataConditionOutputChangedEvent, DataConditionProps, DataConditionType } from './DataCondition';
import { ConditionProps } from './DataConditionEvaluator';
import { StringOperation } from './operators/StringOperator';
import { ObjectAny } from '../../../common';
import { DataConditionIfTrueType, DataConditionIfFalseType } from './constants';

export type DataConditionDisplayType = typeof DataConditionIfTrueType | typeof DataConditionIfFalseType;

export interface ComponentDataConditionProps extends ComponentProperties {
type: typeof DataConditionType;
dataResolver: DataConditionProps;
}

export default class ComponentDataCondition extends Component {
dataResolver: DataCondition;

constructor(props: DataConditionProps, opt: ComponentOptions) {
const dataConditionInstance = new DataCondition(props, { em: opt.em });

super(
{
...props,
type: DataConditionType,
components: dataConditionInstance.getDataValue(),
droppable: false,
get defaults(): ComponentDefinitionDefined {
return {
// @ts-ignore
...super.defaults,
droppable: false,
type: DataConditionType,
dataResolver: {
condition: {
left: '',
operator: StringOperation.equalsIgnoreCase,
right: '',
},
},
opt,
);
this.dataResolver = dataConditionInstance;
this.dataResolver.onValueChange = this.handleConditionChange.bind(this);
components: [
{
type: DataConditionIfTrueType,
},
{
type: DataConditionIfFalseType,
},
],
};
}

getCondition() {
return this.dataResolver.getCondition();
constructor(props: ComponentDataConditionProps, opt: ComponentOptions) {
// @ts-ignore
super(props, opt);

const { condition } = props.dataResolver;
this.dataResolver = new DataCondition({ condition }, { em: opt.em });

this.listenToPropsChange();
}

getIfTrue() {
return this.dataResolver.getIfTrue();
isTrue() {
return this.dataResolver.isTrue();
}

getIfFalse() {
return this.dataResolver.getIfFalse();
getCondition() {
return this.dataResolver.getCondition();
}

private handleConditionChange() {
this.components(this.dataResolver.getDataValue());
getIfTrueContent(): Component | undefined {
return this.components().at(0);
}

static isComponent(el: HTMLElement) {
return toLowerCase(el.tagName) === DataConditionType;
getIfFalseContent(): Component | undefined {
return this.components().at(1);
}

getOutputContent(): Component | undefined {
return this.isTrue() ? this.getIfTrueContent() : this.getIfFalseContent();
}

setCondition(newCondition: ConditionProps) {
this.dataResolver.setCondition(newCondition);
}

setIfTrue(newIfTrue: any) {
this.dataResolver.setIfTrue(newIfTrue);
setIfTrueComponents(content: ComponentAddType) {
this.setComponentsAtIndex(0, content);
}

setIfFalseComponents(content: ComponentAddType) {
this.setComponentsAtIndex(1, content);
}

getInnerHTML(opts?: ToHTMLOptions): string {
return this.getOutputContent()?.getInnerHTML(opts) ?? '';
}

private setComponentsAtIndex(index: number, newContent: ComponentAddType) {
const component = this.components().at(index);
component?.components(newContent);
}

private listenToPropsChange() {
this.on('change:dataResolver', () => {
this.dataResolver.set(this.get('dataResolver'));
});
}

setIfFalse(newIfFalse: any) {
this.dataResolver.setIfFalse(newIfFalse);
toJSON(opts?: ObjectAny): ComponentProperties {
const json = super.toJSON(opts);
const dataResolver = this.dataResolver.toJSON();
delete dataResolver.type;
delete dataResolver.ifTrue;
delete dataResolver.ifFalse;

return {
...json,
dataResolver,
};
}

toJSON(): ComponentDefinition {
return this.dataResolver.toJSON();
static isComponent(el: HTMLElement) {
return toLowerCase(el.tagName) === DataConditionType;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import Component from '../../../dom_components/model/Component';
import { ComponentDefinitionDefined, ToHTMLOptions } from '../../../dom_components/model/types';
import { toLowerCase } from '../../../utils/mixins';
import { isDataConditionDisplayType } from '../../utils';

export default class ConditionalOutputBase extends Component {
get defaults(): ComponentDefinitionDefined {
return {
// @ts-ignore
...super.defaults,
removable: false,
draggable: false,
};
}

static isComponent(el: HTMLElement) {
return isDataConditionDisplayType(toLowerCase(el.tagName));
}
}
Loading