Skip to content

Commit

Permalink
chore(editor-content): Reorder items in relationship field (#31389)
Browse files Browse the repository at this point in the history
### Parent Issue

#31383 

### Proposed Changes

This pull request includes several changes to the
`dot-edit-content-relationship-field` component and its associated store
and tests. The primary focus is on simplifying the data handling methods
and updating the UI for better consistency.

Changes to UI elements:

* Updated the drag handle icon in the template from a font-awesome icon
to a material icon for better visual consistency
(`dot-edit-content-relationship-field.component.html`).

Changes to data handling methods:

* Replaced the usage of `addData` and `reorderData` methods with
`setData` method to streamline data updates
(`dot-edit-content-relationship-field.component.ts`).
[[1]](diffhunk://#diff-5cb2225620beb3baaf219cbfa2241aa934812de8ece62e1d4f7e7747f5f15416L262-R262)
[[2]](diffhunk://#diff-5cb2225620beb3baaf219cbfa2241aa934812de8ece62e1d4f7e7747f5f15416L275-R275)
* Removed the `addData` and `reorderData` methods from the store,
consolidating data updates into the `setData` method
(`relationship-field.store.ts`).
[[1]](diffhunk://#diff-a2c980da63c75c9dc2cd899475beab89cb79492b1dc0819574fc380e856e7ed1L78-R77)
[[2]](diffhunk://#diff-a2c980da63c75c9dc2cd899475beab89cb79492b1dc0819574fc380e856e7ed1L101-L122)

Changes to tests:

* Removed tests related to the `addData` and `reorderData` methods since
these methods are no longer used (`relationship-field.store.spec.ts`).
[[1]](diffhunk://#diff-d2a9a6233c2b1ba38c683725d2e68092978e7023e9269dbabab2fcdfa47224e2L97-L103)
[[2]](diffhunk://#diff-d2a9a6233c2b1ba38c683725d2e68092978e7023e9269dbabab2fcdfa47224e2L133-L193)

### Checklist
- [ ] Tests
- [ ] Translations
- [ ] Security Implications Contemplated (add notes if applicable)

### Additional Info
** any additional useful context or info **

### Screenshots
Original             |  Updated
:-------------------------:|:-------------------------:
** original screenshot **  |  ** updated screenshot **
  • Loading branch information
nicobytes authored Feb 14, 2025
1 parent 4550215 commit 3ae0421
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 118 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
<ng-template pTemplate="body" let-item let-index="rowIndex">
<tr [pReorderableRow]="index">
<td>
<span class="pi pi-bars" pReorderableRowHandle></span>
<span class="pi pi-bars text-gray-500" pReorderableRowHandle></span>
</td>
<td class="max-w-12rem" style="min-width: 13rem">
<p class="truncate-text">{{ item.title }}</p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ export class DotEditContentRelationshipFieldComponent implements ControlValueAcc
takeUntilDestroyed(this.#destroyRef)
)
.subscribe((items: DotCMSContentlet[]) => {
this.store.addData(items);
this.store.setData(items);
});
}

Expand All @@ -272,6 +272,6 @@ export class DotEditContentRelationshipFieldComponent implements ControlValueAcc
return;
}

this.store.reorderData(event.dragIndex, event.dropIndex);
this.store.setData(this.store.data());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,6 @@ describe('RelationshipFieldStore', () => {
});
});

describe('addData', () => {
it('should add new data', () => {
store.addData(mockData);
expect(store.data()).toEqual(mockData);
});
});

describe('deleteItem', () => {
it('should delete item by inode', () => {
store.setData(mockData);
Expand Down Expand Up @@ -130,67 +123,6 @@ describe('RelationshipFieldStore', () => {
});
});
});

describe('reorderData', () => {
beforeEach(() => {
store.setData(mockData);
});

it('should reorder data when moving item up', () => {
const currentIndex = 1;
const newIndex = 0;
store.reorderData(currentIndex, newIndex);

const reorderedData = store.data();
expect(reorderedData[0].inode).toBe('inode2');
expect(reorderedData[1].inode).toBe('inode1');
expect(reorderedData[2].inode).toBe('inode3');
});

it('should reorder data when moving item down', () => {
const currentIndex = 0;
const newIndex = 2;
store.reorderData(currentIndex, newIndex);

const reorderedData = store.data();
expect(reorderedData[0].inode).toBe('inode2');
expect(reorderedData[1].inode).toBe('inode3');
expect(reorderedData[2].inode).toBe('inode1');
});

it('should not change data when current and new index are the same', () => {
const currentIndex = 1;
const newIndex = 1;
store.reorderData(currentIndex, newIndex);

const reorderedData = store.data();
expect(reorderedData[0].inode).toBe('inode1');
expect(reorderedData[1].inode).toBe('inode2');
expect(reorderedData[2].inode).toBe('inode3');
});

it('should handle edge case when moving first item to last position', () => {
const currentIndex = 0;
const newIndex = mockData.length - 1;
store.reorderData(currentIndex, newIndex);

const reorderedData = store.data();
expect(reorderedData[0].inode).toBe('inode2');
expect(reorderedData[1].inode).toBe('inode3');
expect(reorderedData[2].inode).toBe('inode1');
});

it('should handle edge case when moving last item to first position', () => {
const currentIndex = mockData.length - 1;
const newIndex = 0;
store.reorderData(currentIndex, newIndex);

const reorderedData = store.data();
expect(reorderedData[0].inode).toBe('inode3');
expect(reorderedData[1].inode).toBe('inode1');
expect(reorderedData[2].inode).toBe('inode2');
});
});
});

describe('Computed Properties', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ export const RelationshipFieldStore = signalStore(
*/
formattedRelationship: computed(() => {
const data = state.data();

const identifiers = data.map((item) => item.identifier).join(',');

return `${identifiers}`;
Expand All @@ -75,9 +74,7 @@ export const RelationshipFieldStore = signalStore(
* @param {RelationshipFieldItem[]} data - The data to be set.
*/
setData(data: DotCMSContentlet[]) {
patchState(store, {
data
});
patchState(store, { data: [...data] });
},
/**
* Sets the cardinality of the relationship field.
Expand All @@ -98,28 +95,6 @@ export const RelationshipFieldStore = signalStore(
data
});
},
/**
* Adds new data to the existing data in the state.
* @param {RelationshipFieldItem[]} data - The new data to be added.
*/
addData(data: DotCMSContentlet[]) {
patchState(store, { data });
},
/**
* Reorders the data in the store.
* @param {number} dragIndex - The index of the item to be dragged.
* @param {number} dropIndex - The index of the item to be dropped.
*/
reorderData(dragIndex: number, dropIndex: number) {
const currentData = store.data();
const newData = [...currentData];
const draggedItem = newData[dragIndex];

newData.splice(dragIndex, 1);
newData.splice(dropIndex, 0, draggedItem);

patchState(store, { data: newData });
},
/**
* Deletes an item from the store at the specified index.
* @param index - The index of the item to delete.
Expand Down
2 changes: 1 addition & 1 deletion e2e/dotcms-e2e-node/frontend/data/defaultContentType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export function createDefaultContentType() {
{
title: "Site or Folder Field",
fieldType: "siteOrFolder",
},
}
];
return defaultTypes;
}
32 changes: 22 additions & 10 deletions e2e/dotcms-e2e-node/frontend/models/newContentType.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
export enum TYPES {
Text = "text",
SiteOrFolder = "siteOrFolder",
Relationship = "relationship",
}

/**
Expand All @@ -13,30 +14,41 @@ export enum TYPES {
*/
export type Fields = `${TYPES}`;

export interface GenericField {
title: string;
fieldType: Fields;
required?: boolean;
hintText?: string;
}

/**
* Interface representing a text field configuration.
* @interface
*/
export interface TextField {
title: string;
export interface TextField extends GenericField {
fieldType: `${TYPES.Text}`;
required?: boolean;
hintText?: string;
}

/**
* Interface representing a site or host field configuration.
* @interface
*/
export interface SiteorHostField {
title: string;
export interface SiteorHostField extends GenericField {
fieldType: `${TYPES.SiteOrFolder}`;
required?: boolean;
hintText?: string;
}

/**
* Interface representing a relationship field configuration.
* @interface
*/
export interface RelationshipField extends GenericField {
fieldType: `${TYPES.Relationship}`;
entityToRelate: string;
cardinality: "1-1" | "1-many" | "many-1" | "many-many";
}

/**
* Union type of all possible field type configurations.
* @typedef {TextField | SiteorHostField} FieldsTypes
* @typedef {TextField | SiteorHostField | RelationshipField} FieldsTypes
*/
export type FieldsTypes = TextField | SiteorHostField;
export type FieldsTypes = TextField | SiteorHostField | RelationshipField;
33 changes: 33 additions & 0 deletions e2e/dotcms-e2e-node/frontend/pages/contentTypeForm.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
FieldsTypes,
TextField,
SiteorHostField,
RelationshipField,
} from "@models/newContentType.model";

export class ContentTypeFormPage {
Expand All @@ -16,6 +17,9 @@ export class ContentTypeFormPage {
if (field.fieldType === "siteOrFolder") {
return prevPromise.then(() => this.addSiteOrFolderField(field));
}
if (field.fieldType === "relationship") {
return prevPromise.then(() => this.addRelationshipField(field));
}
}, Promise.resolve());

await promise;
Expand Down Expand Up @@ -54,4 +58,33 @@ export class ContentTypeFormPage {
);
await dialogAcceptBtnLocator.click();
}

async addRelationshipField(field: RelationshipField) {
const dropZoneLocator = this.page.getByTestId("fields-bag-0");
const relationshipFieldItemLocator = this.page.getByTestId(
"com.dotcms.contenttype.model.field.ImmutableRelationshipField",
);
await relationshipFieldItemLocator.waitFor();
await relationshipFieldItemLocator.dragTo(dropZoneLocator);

const dialogInputLocator = this.page.locator("input#name");
await dialogInputLocator.fill(field.title);

const selectContentTypeLocator = this.page.locator("dot-searchable-dropdown");
await selectContentTypeLocator.click();

const entityToRelateLocator = this.page.getByLabel(field.entityToRelate);
await entityToRelateLocator.click();

const cardinalitySelectorLocator = this.page.locator("dot-cardinality-selector");
await cardinalitySelectorLocator.click();

const cardinalityOptionLocator = this.page.getByLabel(field.cardinality);
await cardinalityOptionLocator.click();

const dialogAcceptBtnLocator = this.page.getByTestId(
"dotDialogAcceptAction",
);
await dialogAcceptBtnLocator.click();
}
}
10 changes: 0 additions & 10 deletions e2e/dotcms-e2e-node/frontend/pages/textField.page.ts

This file was deleted.

0 comments on commit 3ae0421

Please sign in to comment.