bhch / django-jsonform

A better, user-friendly JSON editing form field for Django admin. Also supports Postgres ArrayField.
https://django-jsonform.rtfd.io
BSD 3-Clause "New" or "Revised" License
307 stars 31 forks source link

Title is not populated for `oneOf` when referenced through `$ref` #164

Open sshishov opened 3 months ago

sshishov commented 3 months ago

In the processing of oneOf options we rely that the title should be inside the components, but sometimes the oneOf is the array of just references, therefore title can be unavailable there.

We can replace the current implementation

    getOptions = () => {
        return this.props.args.schema[this.schemaName].map((option, index) => {
            return {label: option.title || 'Option ' + (index + 1), value: index};
        });
    }

with this one

    getOptions = () => {
        return Array.from(this.props.args.schema[this.schemaName].keys(), (index) => ({label: this.getSchema(index).title || 'Option ' + (index + 1), value: index}));
    }

or similar. The main point - we should receive the full schema first to make sure that we properly retrieve options.

I would recommend to store the schemas of objects in the internal state of the Container (same list with index acces). In this case we should not retrieve and parse it every time.

Example of the broken schema ```json { "$defs": { "ChoiceModel": { "additionalProperties": false, "properties": { "value": { "title": "Value", "type": "string" }, "label": { "title": "Label", "type": "string" }, }, "required": [ "label" ], "title": "ChoiceModel", "type": "object" }, "CustomFieldNumberMetadataModel": { "additionalProperties": false, "properties": {}, "title": "Metadata", "type": "object" }, "CustomFieldNumberModel": { "additionalProperties": false, "properties": { "field_type": { "const": "NUMBER", "title": "Field Type" }, "metadata": { "$ref": "#/$defs/CustomFieldNumberMetadataModel" } }, "required": [ "field_type" ], "title": "Number", "type": "object" }, "CustomFieldSelectMetadataModel": { "additionalProperties": false, "properties": { "choices": { "items": { "$ref": "#/$defs/ChoiceModel" }, "title": "Choices", "type": "array" } }, "required": [ "choices" ], "title": "Metadata", "type": "object" }, "CustomFieldSelectModel": { "additionalProperties": false, "properties": { "field_type": { "const": "SELECT", "title": "Field Type" }, "metadata": { "$ref": "#/$defs/CustomFieldSelectMetadataModel" } }, "required": [ "field_type", "metadata" ], "title": "Select", "type": "object" }, "CustomFieldTextMetadataModel": { "additionalProperties": false, "properties": {}, "title": "Metadata", "type": "object" }, "CustomFieldTextModel": { "additionalProperties": false, "properties": { "field_type": { "const": "TEXT", "title": "Field Type" }, "metadata": { "$ref": "#/$defs/CustomFieldTextMetadataModel" } }, "required": [ "field_type" ], "title": "Text", "type": "object" } }, "discriminator": { "mapping": { "NUMBER": "#/$defs/CustomFieldNumberModel", "SELECT": "#/$defs/CustomFieldSelectModel", "TEXT": "#/$defs/CustomFieldTextModel" }, "propertyName": "field_type" }, "final": true, "oneOf": [ { "$ref": "#/$defs/CustomFieldSelectModel" }, { "$ref": "#/$defs/CustomFieldNumberModel" }, { "$ref": "#/$defs/CustomFieldTextModel" } ], "title": "Discriminator" } ```
Actual and Expected screenshots on playground Screenshot 2024-03-28 at 00 04 13Screenshot 2024-03-28 at 00 04 27

NOTE: tested locally, working like a charm.

bhch commented 3 months ago

Thanks for taking the time to go through the source code and providing a fix.

I'll ship it in the next release.

bhch commented 3 months ago

Hi @sshishov, would you like to contribute and open a Pull Request at bhch/react-json-form?

If not, it's still okay and I can make these changes myself. Let me know.

Thanks again.

abe-101 commented 1 month ago

Any Update? I'd really appreciate this enhancment