Skip to content

Commit

Permalink
show placement indicator for dragging over column elements
Browse files Browse the repository at this point in the history
  • Loading branch information
aghontpi committed Oct 13, 2021
1 parent 54be3e7 commit 548bb29
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 11 deletions.
17 changes: 14 additions & 3 deletions src/Components/HtmlWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ import { findClosestParent, findUniqueIdentifier } from '../Utils/closestParent'
import { detectEmptyElement } from '../Utils/detectEmptyBody';
import { findElementInJson } from '../Utils/findElementInMjmlJson';
import { findColumnOfElement } from '../Utils/findElementsParent';
import { generateDropItemPlaceholder } from '../Utils/generateDropItemPlaceholder';
import {
generateDropItemPlaceholder,
genereateDropItemPlaceholderForColumn,
} from '../Utils/generateDropItemPlaceholder';

interface HtmlWrapperProps {
// children: React.DOMElement<React.DOMAttributes<Element>, Element>;
Expand Down Expand Up @@ -161,15 +164,23 @@ export const HtmlWrapper = memo(({ uniqueKey, originalNode }: HtmlWrapperProps)
const nearestTag = findClosestParent(currentTarget);
// only show place item sign for column's children
if (nearestTag?.includes('mj-column') || nearestTag?.includes('mj-section')) {
return;
console.log('::indicator: trigger->column');
if (nearestTag.includes('mj-column')) {
const madeChange = genereateDropItemPlaceholderForColumn({ mjmlJson, nearestTag, setMjmlJson });
if (madeChange === true) {
console.log('::indicator: trigger->column -> stopping further processing');
return;
}
console.log('::indicator: trigger->column -> no updates where done -> proceeding further processing');
}
}

let columnElement = memoFind(currentTarget);
// find column of element returns element and uniqueIdentifier
if (columnElement) {
[columnElement] = columnElement;
}

console.log('::indicator: trigger->insideColumn');
generateDropItemPlaceholder({
mjmlJson,
nearestTag,
Expand Down
97 changes: 89 additions & 8 deletions src/Utils/generateDropItemPlaceholder.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import _ from 'lodash';
import { findUniqueIdentifier } from './closestParent';
import { findUniqueIdentifier, findUniqueIdentifierFromString } from './closestParent';
import { closeToTopOrBottom, isEventWithTargetElement } from './eventElementRelation';
import { findElementInJson } from './findElementInMjmlJson';
import { cleanMjmlJson } from './mjmlProcessor';
Expand Down Expand Up @@ -27,12 +27,12 @@ const generateDropItemPlaceholder = ({
if (isEventWithTargetElement(e, columnElement)) {
const suggestionDirection = closeToTopOrBottom(e, nearestElement);
if (suggestionDirection) {
let item = findElementInJson(mjmlJson, nearestTag);
let item = findElementInJson(_.cloneDeep(mjmlJson), nearestTag);
if (item) {
const [, path]: [any, string] = item;
// omit the last .child.. index, cuz parent is needed
const parent = path.slice(1, path.lastIndexOf('.children'));
let parentObj = _.get(mjmlJson, parent);
let parentObj = _.get(_.cloneDeep(mjmlJson), parent);
let newOrder = [];
for (var i = 0; parentObj && parentObj.children && i < parentObj.children.length; i++) {
let childItem = parentObj['children'][i];
Expand All @@ -56,17 +56,27 @@ const generateDropItemPlaceholder = ({
if (parentObj && newOrder.length > 0) {
// replace with new order
parentObj.children = newOrder;
const updated = _.set(mjmlJson, parent, parentObj);
const updated = _.set(_.cloneDeep(mjmlJson), parent, parentObj);
const uniqueColumnIdentifier = findUniqueIdentifier(
columnElement,
columnElement.classList,
'identifier-mj-column'
);
if (uniqueColumnIdentifier) {
const cleaned = cleanMjmlJson(updated, uniqueColumnIdentifier);
setMjmlJson({ ...cleaned });
if (!_.isEqual(mjmlJson, cleaned)) {
console.log('::update::', mjmlJson, cleaned);
setMjmlJson({ ...cleaned });
} else {
console.log('::update:: -> but elements are the same, not triggering rerender');
}
} else {
setMjmlJson({ ...updated });
if (!_.isEqual(mjmlJson, updated)) {
console.log('::update::', mjmlJson, updated);
setMjmlJson({ ...updated });
} else {
console.log('::update:: -> but elements are the same, not triggering rerender');
}
}
}
}
Expand All @@ -76,13 +86,84 @@ const generateDropItemPlaceholder = ({
}
};

export { generateDropItemPlaceholder };
const genereateDropItemPlaceholderForColumn = ({
mjmlJson,
setMjmlJson,
nearestTag,
}: Omit<generateDropItemPlacehodlerProps, 'event' | 'columnElement' | 'currentTarget'>) => {
if (nearestTag) {
let find = findElementInJson(mjmlJson, nearestTag);
if (find) {
const cleanedMjmlJson = cleanMjmlJson(_.cloneDeep(mjmlJson));
console.log('::beforechange::', mjmlJson, cleanedMjmlJson);
const [, path]: [any, string] = find;
let columnObj = _.get(_.cloneDeep(cleanedMjmlJson), path.slice(1));
let newOrder = [];
for (let i = 0; columnObj && columnObj.children && i < columnObj.children.length; i++) {
const childItem = columnObj['children'][i];
const cssClass = childItem.attributes && childItem['attributes']['css-class'];
// if there is existing placeholders, removing them
if (cssClass && cssClass.includes('placeitem-placeholder')) {
continue;
}
// remove column empty placeholders
if (cssClass && cssClass.includes('mj-placeholder')) {
continue;
}
newOrder.push(childItem);
}

// newOrder will not be zero if the column already has items
if (newOrder.length > 0) {
// todo: handle generateDropItemPlaceholder inside this fn.
// by getting event and performing calculations.
return false;
}

// add the new element
newOrder.push(placeItemPlaceHolder);

let sectionPath = path.slice(1, path.lastIndexOf('.children'));
if (columnObj) {
// section can contain multiple,
// identify which column is active and replace with new order
columnObj.children = newOrder;
let parentSection = _.get(_.cloneDeep(cleanedMjmlJson), sectionPath);
let columnChildrenNewOrder = [];
debugger;
for (let i = 0; parentSection && parentSection.children && i < parentSection.children.length; i++) {
const childColumn = parentSection['children'][i];
const cssClass = childColumn.attributes && childColumn['attributes']['css-class'];
const uniqueIdentifer = findUniqueIdentifierFromString(cssClass);
// nearestTag is the uniqueId of the column,
// replace the old column with new one
if (uniqueIdentifer === nearestTag) {
columnChildrenNewOrder.push(columnObj);
continue;
}
columnChildrenNewOrder.push(childColumn);
}
parentSection.children = columnChildrenNewOrder;
const updated = _.set(cleanedMjmlJson, sectionPath, parentSection);
if (!_.isEqual(mjmlJson, updated)) {
console.log('::update::', cleanedMjmlJson, updated);
setMjmlJson({ ...updated });
} else {
console.log('::update:: -> but elements are the same, not triggering rerender');
}
return true;
}
}
}
};

export { generateDropItemPlaceholder, genereateDropItemPlaceholderForColumn };

const placeItemPlaceHolder = {
tagName: 'mj-text',
attributes: {
align: 'center',
'css-class': 'placeitem-placeholder',
},
content: '<h1>+</h1>',
content: '<h1> + </h1>',
};
9 changes: 9 additions & 0 deletions src/Utils/mjmlProcessor.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { columnPlaceholder } from '../Components/Section';

const cleanMjmlJson = (mjmlJson: any, ignore: string = '') => {
if (!mjmlJson) {
return null;
Expand Down Expand Up @@ -27,6 +29,13 @@ const cleanMjmlJson = (mjmlJson: any, ignore: string = '') => {
newChildren.push(result);
}
}

// if the children is column and its length is 0,
// then add a placeholder to the column
if (mjmlJson && mjmlJson['tagName'] === 'mj-column' && newChildren.length === 0) {
newChildren.push(...columnPlaceholder);
}

if (newChildren.length) {
mjmlJson['children'] = newChildren;
}
Expand Down

0 comments on commit 548bb29

Please sign in to comment.