gentics / mesh

Gentics Mesh - The open source headless CMS for developers
https://getmesh.io
Apache License 2.0
569 stars 117 forks source link

Reordering of fields on schema is not preserved #981

Open jalberto-ghub opened 4 years ago

jalberto-ghub commented 4 years ago

Gentics Mesh Version, operating system, or hardware.

Operating System

JVM

DevNils commented 4 years ago

I have a similar problem when I add new schemas via the API. The order of fields in the schema is not preserved.

jalberto-ghub commented 4 years ago

The main problem with this is not how it looks on the JSON but what happens when one tries to use the schema to create a new node instance. The fields appear is some irrational order for the person adding the data that make little or no sense. The field use for display-name in the middle, the field used for the slug in some random location, optional fields at the top, required fields intermingled.

It makes very difficult for people to make sense of what they are editing.

s3-ckerwer commented 4 years ago

We create schemas and microschemas for different types of learning articles with 5 to 10 schema-fields. So we have different articles with different schemas and the fields of the articles are rendered in the order of the schema, because the schema defines structure of the article. Currently before updating a schema the user has to correct the order as it was before. Therefore we need to document the order of every schema.

It is obvious that the bug is in the HTML-Editor for the schema. After saving the schema and refreshing it the editor sorts the field alphabetical. As seen in the following screenshot.

Screenshot

Giusti commented 1 year ago

The issue seems to be related to a sorting function, that is called when opening the schema.

Reproduction steps:

I created a schema with 4 fields

After that I opened the schema again and reordered the fields -> 4Test, 3Name, 2A_Field, 1Date

Like this

gentics1

Then I clicked save and went back to the list and selected my schema and opened it and this is where the fields get sorted by name

schema-detail.component.ts (110)

this.subscription = this.schema$.subscribe(schema => {
      this.schemaJson$.next(schema ? JSON.stringify(stripSchemaFields(schema), undefined, 4) : `{}`);
});

this calls the stripSchemaFields method

schema-detail.component.ts (254)

function stripSchemaFields(schema: SchemaResponse): any {
    schema.fields.sort((a: any, b: any) => a.name.localeCompare(b.name));
    return updateFields.reduce((obj, key) => ({ ...obj, [key]: schema[key] || null }), {});
}

which sorts the fields by field.name -> changing the "saved" field order

Here is a gif stepping through the stack trace highlighting where the field order is modified.

gentics2

Proposed solution:

removing the line which sorts the schema works for this specific scenario

function stripSchemaFields(schema: SchemaResponse): any {
    //schema.fields.sort((a: any, b: any) => a.name.localeCompare(b.name));
    return updateFields.reduce((obj, key) => ({ ...obj, [key]: schema[key] || null }), {});
}

gentics3

but as this is called on multiple occasions it might have side-effects / is needed for other scenarios

Update:

After investigating a bit further, I noticed that this sorting is causing an additional issue with the change detection:

Situation

When rearranging the fields without changing any other content and then leaving the screen, the compare method should detect changes inside the schema and display a popup if the user wants to save / discard the changes

Problem

The comparison logic uses the same method and is therefore sorting the fields in both the original and modified schema

get schemaHasChanged(): boolean {
        try {
            const a = stripSchemaFields(JSON.parse(this.schemaJsonOriginal)); //original schema gets sorted
            const b = stripSchemaFields(JSON.parse(this.schemaJson)); //current schema gets sorted
            return !simpleDeepEquals(a, b);
        } catch (error) {
            return false;
        }
}

which results in "no changes" as both schema fields are identically sorted and even though I made changes to the order of fields I dont get a popup when leaving the screen

gentics_save