"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const React = __importStar(require("react"));
const PropTypes = __importStar(require("prop-types"));
const deepmerge_1 = __importDefault(require("deepmerge"));
const equals = require("deep-equal");
const react_spinner_1 = __importDefault(require("react-spinner"));
const components_1 = require("../components");
const utils_1 = require("../../utils");
const Context_1 = __importDefault(require("../../Context"));
const ReactContext_1 = __importDefault(require("../../ReactContext"));
const ConditionalUiSchemaField_1 = require("./ConditionalUiSchemaField");
const utils_2 = require("@rjsf/utils");
const scopeFieldSettings = {
    taxonGroups: {
        translate: (props, taxonGroup) => {
            return props.formContext.apiClient.get("/informal-taxon-groups/" + taxonGroup).then((response) => {
                return response.name;
            }).catch(() => {
                return "";
            });
        },
    }
};
/**
 * Field with fields, which are shown according to recursive scope.
 * uiSchema = {"ui:options": {
 * additionalsGroupingPath: path to the field scope that defines groups
 * additionalsGroupsTranslator: one of scopeFieldsSettings translator
 * additionalsPersistenceKey: instances with same persistence id use the same additional fields
 * additionalsPersistenceField: form data property value for more fine grained persistence behaviour
 * uiSchema: <uiSchema> (ui schema for inner schema)
 * fields: [<string>] (fields that are always shown)
 * fieldScopes: {
 *  fieldName: {
 *    fieldValue: {
 *      fields: [<string>] (fields that are shown if fieldName[fieldValue} == true)
 *      additionalFields: [<string>] (if grouping is enabled, additional fields are shown only if selected from the list)
 *      excludeFields: [<string>] (exclude fields from showing)
 *      excludeFields: [<string>] (fields that are shown by default)
 *      refs: [<string>] (root definitions that are merged recursively to this fieldScope)
 *      uiSchema: <uiSchema> (merged recursively to inner uiSchema)
 *      uiSchemaMergeType: See documentation for ConditionalUiSchemaField
 *      fieldScopes: {fieldName: <fieldScope>, fieldName2 ...}
 *    },
 *    fieldValue2, ...
 *  }
 * },
 * definitions: {
 *   defName: <fieldScope>,
 *   defname2: ...
 * }
 * }
 *
 * Field scope values accept asterisk (*) and plus (+) as field scope selector.
 */
class ScopeField extends React.Component {
    constructor(props) {
        super(props);
        this.getAdditionalPersistenceValue = (props, includeUndefined = true) => {
            const { additionalsPersistenceField, additionalPersistenceContextKey } = (0, utils_1.getUiOptions)(props.uiSchema);
            let formDataItem = props.formData[additionalsPersistenceField];
            if (additionalPersistenceContextKey && (formDataItem === undefined || Array.isArray(formDataItem) && formDataItem.length === 0)) {
                formDataItem = (0, Context_1.default)(this.props.formContext.contextId)[additionalPersistenceContextKey];
            }
            let items = (Array.isArray(formDataItem) ? formDataItem : [formDataItem]);
            if (includeUndefined)
                items = ["undefined", ...items];
            return items;
        };
        this.getSchemasAndAdditionals = (props, state) => {
            let { schema, uiSchema, formData } = props;
            let additionalFields = (state && state.additionalFields) ? Object.assign({}, state.additionalFields) : {};
            Object.keys(additionalFields).forEach(key => {
                if (!props.schema.properties[key]) {
                    delete additionalFields[key];
                }
            });
            let defaultFields = (state && state.defaultFields) ? Object.assign({}, state.defaultFields) : {};
            const options = (0, utils_1.getUiOptions)(uiSchema);
            let { fields, definitions, glyphFields = [], geometryField = "unitGathering_geometry", taxonField } = options;
            let generatedUiSchema = (0, utils_1.getInnerUiSchema)(uiSchema);
            let fieldsToShow = {};
            (fields || []).forEach(field => {
                fieldsToShow[field] = schema.properties[field];
            });
            let hasSetLocation = false;
            glyphFields.reduce((additionalFields, { show, open, fn }) => {
                if (fn === "setLocation") {
                    hasSetLocation = true;
                }
                if (!(show in additionalFields) && show && open) {
                    additionalFields[show] = open;
                }
                return additionalFields;
            }, additionalFields);
            function addFieldSelectorsValues(scopes, fieldSelector, fieldSelectorValue) {
                let fieldScope = scopes[fieldSelector][fieldSelectorValue];
                if (!fieldScope)
                    return;
                while (fieldScope.refs) {
                    let refs = fieldScope.refs;
                    fieldScope = Object.assign(Object.assign({}, fieldScope), { refs: undefined });
                    refs.forEach(ref => {
                        fieldScope = (0, deepmerge_1.default)(fieldScope, definitions[ref]);
                    });
                }
                const { excludeFields = [], fields: _fields = [], defaultFields: _defaultFields = [] } = fieldScope;
                excludeFields.forEach(fieldName => {
                    delete fieldsToShow[fieldName];
                });
                _defaultFields.forEach(fieldName => {
                    if (additionalFields[fieldName] !== false)
                        fieldsToShow[fieldName] = schema.properties[fieldName];
                });
                _fields.forEach((fieldName) => {
                    fieldsToShow[fieldName] = schema.properties[fieldName];
                    if (additionalFields[fieldName]) {
                        delete additionalFields[fieldName];
                    }
                });
                if (fieldScope.uiSchema) {
                    const { uiSchemaMergeType = "merge" } = fieldScope;
                    generatedUiSchema = (0, ConditionalUiSchemaField_1.computeUiSchema)(generatedUiSchema, { type: uiSchemaMergeType, uiSchema: fieldScope.uiSchema });
                }
                if (fieldScope.fieldScopes) {
                    addFieldScopeFieldsToFieldsToShow(fieldScope);
                }
            }
            const that = this;
            function addFieldScopeFieldsToFieldsToShow(fieldScope) {
                if (!fieldScope)
                    return;
                let scopes = fieldScope.fieldScopes;
                if (scopes)
                    Object.keys(scopes).forEach(fieldSelector => {
                        let fieldSelectorValues = formData[fieldSelector];
                        if (!fieldSelectorValues || Array.isArray(fieldSelectorValues) && !fieldSelectorValues.length) {
                            fieldSelectorValues = that.getAdditionalPersistenceValue(props);
                        }
                        if (!Array.isArray(fieldSelectorValues))
                            fieldSelectorValues = [fieldSelectorValues];
                        if (scopes[fieldSelector]["+"] && fieldSelectorValues.length > 0 && fieldSelectorValues.some(_fieldSelectorValue => _fieldSelectorValue !== "undefined" && (0, utils_1.hasData)(_fieldSelectorValue) && !(0, utils_1.isDefaultData)(_fieldSelectorValue, schema.properties[fieldSelector]))) {
                            addFieldSelectorsValues(scopes, fieldSelector, "+");
                        }
                        if (scopes[fieldSelector]["*"]) {
                            addFieldSelectorsValues(scopes, fieldSelector, "*");
                        }
                        fieldSelectorValues.forEach(fieldSelectorValue => {
                            if ((0, utils_1.hasData)(fieldSelectorValue) && !(0, utils_1.isDefaultData)(fieldSelectorValue, schema.properties[fieldSelector].type === "array" ? schema.properties[fieldSelector].items : schema.properties[fieldSelector])) {
                                addFieldSelectorsValues(scopes, fieldSelector, fieldSelectorValue);
                            }
                        });
                    });
            }
            function findScopedFields(fieldScope = {}, _fields = {}) {
                const { fields = [], additionalFields = [], fieldScopes = {} } = fieldScope;
                [...fields, ...additionalFields].forEach(f => {
                    _fields[f] = true;
                });
                Object.keys(fieldScopes).forEach(f => Object.keys(fieldScopes[f]).forEach(_f => findScopedFields(fieldScopes[f][_f], _fields)));
                return _fields;
            }
            // If no root fields defined, show all fields that aren't in any scopes' fields or additional fields.
            if (!fields) {
                const scopedFields = findScopedFields(options);
                glyphFields.forEach(({ show, open }) => {
                    if (open === false) {
                        scopedFields[show] = true;
                    }
                });
                fieldsToShow = Object.keys(props.schema.properties).reduce((_fields, f) => {
                    if (!scopedFields[f]) {
                        _fields[f] = props.schema.properties[f];
                    }
                    return _fields;
                }, {});
            }
            addFieldScopeFieldsToFieldsToShow(options);
            if (additionalFields) {
                Object.keys(additionalFields).filter(field => additionalFields[field]).forEach((property) => {
                    if (additionalFields[property]) {
                        fieldsToShow[property] = props.schema.properties[property];
                    }
                });
            }
            if (formData) {
                Object.keys(formData).forEach((property) => {
                    if (!schema.properties[property])
                        return;
                    const isDefault = (0, utils_1.isDefaultData)(formData[property], schema.properties[property]);
                    if (!isDefault) {
                        fieldsToShow[property] = props.schema.properties[property];
                    }
                });
            }
            Object.keys(schema.properties).forEach(prop => {
                if (!fieldsToShow[prop]) {
                    generatedUiSchema[prop] = { "ui:field": "HiddenField" };
                }
            });
            if (hasSetLocation) {
                console.warn("ScopeField's glyphField fn 'setLocation' is deprecated and will be removed in the future. The functionality is separated to a new component function 'LocationChooserField', use it instead.");
                const locationFn = {
                    "ui:field": "LocationChooserField",
                    "ui:options": {
                        geometryField,
                        taxonField
                    }
                };
                const uiFunctions = generatedUiSchema["ui:functions"]
                    ? (0, utils_1.isObject)(generatedUiSchema["ui:functions"])
                        ? [generatedUiSchema["ui:functions"], locationFn]
                        : [...generatedUiSchema["ui:functions"], locationFn]
                    : [locationFn];
                generatedUiSchema = Object.assign(Object.assign({}, generatedUiSchema), { "ui:functions": uiFunctions });
            }
            return {
                schema: schema,
                uiSchema: generatedUiSchema,
                additionalFields,
                defaultFields,
                fieldsToShow
            };
        };
        this.onToggleAdditionals = () => {
            this.setState({ additionalsOpen: !this.state.additionalsOpen });
        };
        this.renderAdditionalsButtons = () => {
            const glyphButtons = this.renderGlyphFields();
            if (!this.state.includeAdditionalFieldsChooserButton || Object.keys(this.props.formData || {}).length === 0) {
                if (glyphButtons) {
                    return glyphButtons;
                }
                return [];
            }
            const { additionalsGroupingPath } = (0, utils_1.getUiOptions)(this.props.uiSchema);
            let additionalProperties = {};
            Object.keys(this.props.schema.properties).forEach(property => {
                if (!this.state.fieldsToShow[property] ||
                    (this.state.fieldsToShow[property] && this.state.additionalFields[property]))
                    additionalProperties[property] = this.props.schema.properties[property];
            });
            return [
                additionalsGroupingPath
                    ? this.renderFieldsModal(additionalProperties)
                    : this.renderFieldsDropdown(additionalProperties),
                ...(glyphButtons ? glyphButtons : [])
            ];
        };
        this.onSelect = () => {
            this.preventCloseDropdown = true;
        };
        this.onToggle = (isOpen) => {
            if (!this.preventCloseDropdown)
                this.onToggleAdditionals(isOpen);
            this.preventCloseDropdown = false;
        };
        this.renderFieldsModal = (additionalProperties) => {
            const { translations } = this.props.formContext;
            let list = [];
            const options = (0, utils_1.getUiOptions)(this.props.uiSchema);
            const { additionalsGroupingPath } = options;
            let groupTranslations = this.state.additionalsGroupsTranslations;
            const groups = additionalsGroupingPath ? (0, utils_1.parseJSONPointer)(options, additionalsGroupingPath) : {};
            const additionalsPersistenceValue = this.getAdditionalPersistenceValue(this.props);
            let groupNames = Object.keys(groups);
            if (additionalsPersistenceValue)
                groupNames = groupNames.sort((a, b) => additionalsPersistenceValue.indexOf(b) - additionalsPersistenceValue.indexOf(a));
            groupNames.forEach(groupName => {
                list.push(React.createElement(_ListGroup, { key: groupName, group: groups[groupName], groupName: groupName, groupTranslations: groupTranslations, additionalProperties: additionalProperties, additionalPropertiesToList: this.additionalPropertiesToList, propertyIsIncluded: this.propertyIsIncluded, schema: this.props.schema, toggleAdditionalProperty: this.toggleAdditionalProperty }));
            });
            const { Modal } = this.context.theme;
            if (this.state.additionalsOpen)
                this.modal = (React.createElement(Modal, { key: "fields-modal", show: true, onHide: this.onToggleAdditionals, dialogClassName: "laji-form scope-field-modal" },
                    React.createElement(Modal.Header, { closeButton: true },
                        React.createElement(Modal.Title, null, translations.SelectMoreFields)),
                    React.createElement(Modal.Body, null, list)));
            return this.renderFieldsButton();
        };
        this.renderFieldsButton = (bsRole) => {
            const { OverlayTrigger, Tooltip } = this.context.theme;
            const tooltip = (React.createElement(Tooltip, { id: `${this.props.idSchema.$id}-additionals-tooltip` }, this.props.formContext.translations.SelectMoreFields));
            return (React.createElement(OverlayTrigger, { key: `${this.props.idSchema.$id}-scope`, overlay: tooltip, placement: "left", bsRole: bsRole },
                React.createElement(components_1.GlyphButton, { glyph: "cog", onClick: this.onToggleAdditionals, id: `${this.props.idSchema.$id}-additionals`, variant: "primary" })));
        };
        this.renderGlyphFields = () => {
            const { glyphFields } = (0, utils_1.getUiOptions)(this.props.uiSchema);
            return glyphFields ?
                glyphFields.filter(settings => !settings.fn || settings.fn !== "setLocation").map((settings, i) => React.createElement(GlyphField, { key: i, settings: settings, idSchema: this.props.idSchema, formData: this.props.formData, schema: this.props.schema, registry: this.props.registry, isIncluded: this.propertyIsIncluded(settings.show), toggleAdditionalProperty: this.toggleAdditionalProperty })) : null;
        };
        this.propertyIsIncluded = (property) => {
            const { additionalFields } = this.state;
            const isIncluded = additionalFields[property] === true || this.state.fieldsToShow[property];
            return !!isIncluded;
        };
        this.toggleAdditionalProperty = (fields) => {
            const { additionalsPersistenceField, additionalsPersistenceKey } = (0, utils_1.getUiOptions)(this.props.uiSchema);
            if (!Array.isArray(fields))
                fields = [fields];
            const additionalFields = fields.reduce((additionalFields, field) => {
                return Object.assign(Object.assign({}, additionalFields), { [field]: !this.propertyIsIncluded(field) });
            }, this.state.additionalFields);
            if (this._globals) {
                const additionalsPersistenceVal = this.getAdditionalPersistenceValue(this.props, !"don't include undefined");
                let globalsEntry = this._globals ? Object.assign({}, this._globals) : {};
                if (additionalsPersistenceField) {
                    let additionalsKeys = this.props.schema.properties[additionalsPersistenceField].type === "array"
                        ? additionalsPersistenceVal
                        : [additionalsPersistenceVal];
                    if (additionalsKeys.length === 0)
                        additionalsKeys = ["undefined"];
                    additionalsKeys.forEach(persistenceKey => {
                        globalsEntry[persistenceKey] = additionalFields;
                    });
                    this.props.formContext.globals[`scopeField_${additionalsPersistenceKey}`] = globalsEntry;
                }
                else if (additionalsPersistenceKey) {
                    this.props.formContext.globals[`scopeField_${additionalsPersistenceKey}`] = additionalFields;
                }
            }
            this.setState(Object.assign({ additionalFields }, this.getSchemasAndAdditionals(this.props, Object.assign(Object.assign({}, this.state), { additionalFields }))));
        };
        this.additionalPropertiesToList = (properties, ElemType) => {
            const titles = (0, utils_1.getUiOptions)(this.props.uiSchema).titles || {};
            return (0, utils_2.orderProperties)(Object.keys(properties), this.props.uiSchema["ui:order"])
                .map(property => {
                const isIncluded = this.propertyIsIncluded(property);
                const hasData = (0, utils_1.propertyHasData)(property, this.props.formData) && (!this.props.formData || !(0, utils_1.isDefaultData)(this.props.formData[property], this.props.schema.properties[property]));
                if (!this.propertyTogglers) {
                    this.propertyTogglers = {};
                }
                if (!this.propertyTogglers[property]) {
                    this.propertyTogglers[property] = () => this.toggleAdditionalProperty(property);
                }
                return (React.createElement(ElemType, { key: property, disabled: hasData, active: isIncluded, onClick: this.propertyTogglers[property] }, titles[property] || properties[property].title || property));
            });
        };
        this.translateAdditionalsGroups = (props) => {
            let options = (0, utils_1.getUiOptions)(props.uiSchema);
            const { additionalsGroupingPath, additionalsGroupsTranslator } = options;
            if (!additionalsGroupingPath)
                return;
            const groups = (0, utils_1.parseJSONPointer)(options, additionalsGroupingPath);
            const groupNames = Object.keys(groups).filter(groupName => !(0, utils_1.isNullOrUndefined)(groups[groupName]));
            let translations = {};
            let translationsToKeys = {};
            let translationCount = 0;
            groupNames.forEach(groupName => {
                const title = groups[groupName].title;
                const promise = (!(0, utils_1.isNullOrUndefined)(title)) ?
                    new Promise(resolve => resolve(title)) :
                    scopeFieldSettings[additionalsGroupsTranslator].translate(props, groupName);
                promise.then(translation => {
                    translations[groupName] = translation;
                    translationsToKeys[translation] = groupName;
                    translationCount++;
                    if (this.mounted && translationCount == groupNames.length) {
                        this.setState({
                            additionalsGroupsTranslations: translations,
                            additionalsGroupsTranslationsToKeys: translationsToKeys
                        });
                    }
                });
            });
        };
        this.props.formContext.services.settings.bind(this, props);
        this.state = this.getStateFromProps(props);
    }
    UNSAFE_componentWillReceiveProps(props) {
        const state = this.getStateFromProps(props);
        if (state)
            this.setState(state);
    }
    componentDidMount() {
        this.mounted = true;
    }
    componentWillUnmount() {
        this.mounted = false;
    }
    render() {
        const SchemaField = this.props.registry.fields.SchemaField;
        const { additionalsGroupingPath } = (0, utils_1.getUiOptions)(this.props.uiSchema);
        let uiSchema = Object.assign(Object.assign({}, this.state.uiSchema), { "ui:buttons": [
                ...(this.props.uiSchema["ui:buttons"] || []),
                ...this.renderAdditionalsButtons()
            ] });
        const addButton = button => {
            uiSchema = Object.assign(Object.assign({}, uiSchema), { "ui:buttons": [
                    ...uiSchema["ui:buttons"],
                    button
                ] });
        };
        if (this.state.additionalsOpen && additionalsGroupingPath) {
            addButton(this.modal);
        }
        return React.createElement(SchemaField, Object.assign({}, this.props, this.state, { uiSchema: uiSchema }));
    }
    componentDidUpdate(prevProps, prevState) {
        if (this.state.additionalsOpen
            && (!this.state.additionalsGroupsTranslations || prevProps.formContext.lang !== this.props.formContext.lang ||
                (0, utils_1.getUiOptions)(prevProps.uiSchema).additionalsGroupsTranslator !== (0, utils_1.getUiOptions)(this.props.uiSchema).additionalsGroupsTranslator)) {
            this.translateAdditionalsGroups(this.props);
        }
        if (!equals(prevState.fieldsToShow, this.state.fieldsToShow)) {
            this.props.formContext.utils.syncScroll();
        }
    }
    getStateFromProps(props) {
        const options = (0, utils_1.getUiOptions)(props.uiSchema);
        const includeAdditionalFieldsChooserButton = !!options.includeAdditionalFieldsChooserButton;
        let state = {
            includeAdditionalFieldsChooserButton
        };
        const { additionalsPersistenceField, additionalsPersistenceKey } = (0, utils_1.getUiOptions)(props.uiSchema);
        let additionalFields = additionalsPersistenceField
            ? {}
            : (this.state ? this.state.additionalFields : {});
        if (additionalsPersistenceKey) {
            if (!props.formContext.globals[`scopeField_${additionalsPersistenceKey}`]) {
                props.formContext.globals[`scopeField_${additionalsPersistenceKey}`] = {};
            }
            this._globals = props.formContext.globals[`scopeField_${additionalsPersistenceKey}`];
            let additionalsToAdd = {};
            if (additionalsPersistenceField) {
                const additionalPersistenceValue = this.getAdditionalPersistenceValue(props);
                additionalPersistenceValue.forEach(item => {
                    if (this._globals && this._globals[item])
                        additionalsToAdd = Object.assign(Object.assign({}, additionalsToAdd), this._globals[item]);
                });
            }
            else {
                if (this._globals)
                    additionalsToAdd = this._globals;
            }
            additionalFields = Object.assign(Object.assign({}, additionalFields), additionalsToAdd);
        }
        state.additionalFields = additionalFields;
        state = Object.assign(Object.assign({}, state), this.getSchemasAndAdditionals(props, state));
        return state;
    }
    renderFieldsDropdown(additionalProperties) {
        const { MenuItem, Glyphicon, Dropdown } = this.context.theme;
        return (React.createElement("div", { key: "scope-additionals-dropdown" },
            React.createElement(Dropdown, { pullRight: true, id: this.props.idSchema.$id + "-additionals", open: this.state.additionalsOpen, onToggle: this.onToggle },
                React.createElement(Dropdown.Toggle, { noCaret: true, variant: "primary" },
                    React.createElement(Glyphicon, { glyph: "cog" })),
                React.createElement(Dropdown.Menu, { onSelect: this.onSelect }, this.additionalPropertiesToList(additionalProperties, MenuItem)))));
    }
}
ScopeField.contextType = ReactContext_1.default;
ScopeField.propTypes = {
    uiSchema: PropTypes.shape({
        "ui:options": PropTypes.shape({
            includeAdditionalFieldsChooserButton: PropTypes.bool,
            additionalsGroupingPath: PropTypes.string,
            additionalsGroupsTranslator: PropTypes.oneOf(Object.keys(scopeFieldSettings)),
            additionalsPersistenceKey: PropTypes.string,
            additionalsPersistenceField: PropTypes.string,
            fieldScopes: PropTypes.object,
            fields: PropTypes.arrayOf(PropTypes.string),
            definitions: PropTypes.object,
            uiSchema: PropTypes.object
        }).isRequired
    }).isRequired,
    schema: PropTypes.shape({
        type: PropTypes.oneOf(["object"])
    }).isRequired,
    formData: PropTypes.object.isRequired
};
exports.default = ScopeField;
const getGroupFields = (group, additionalProperties, schema) => {
    const { fields = [], additionalFields = [] } = group;
    const additionalFieldsDict = (0, utils_1.dictionarify)(additionalFields);
    let combinedFields = Object.keys(Object.assign(Object.assign({}, (0, utils_1.dictionarify)(fields)), additionalFieldsDict));
    let groupFields = {};
    combinedFields.forEach(field => {
        if (additionalProperties[field]) {
            groupFields[field] = additionalProperties[field];
        }
        else if (additionalFieldsDict[field]) {
            groupFields[field] = schema.properties[field];
        }
    });
    return groupFields;
};
const _ListGroup = React.memo(function _ListGroup({ group = {}, groupTranslations = {}, additionalProperties, groupName, additionalPropertiesToList, propertyIsIncluded, schema, toggleAdditionalProperty }) {
    const groupFields = React.useMemo(() => getGroupFields(group, additionalProperties, schema), [group, additionalProperties, schema]);
    const { ListGroupItem, ListGroup } = React.useContext(ReactContext_1.default).theme;
    let groupsList = additionalPropertiesToList(groupFields, ListGroupItem);
    const someActive = Object.keys(groupFields).some(propertyIsIncluded);
    const onListGroupClick = React.useCallback(() => {
        toggleAdditionalProperty(Object.keys(groupFields)
            .filter(field => { return propertyIsIncluded(field) === someActive; }));
    }, [toggleAdditionalProperty, groupFields, propertyIsIncluded, someActive]);
    if (!groupsList.length) {
        return null;
    }
    const listGroup = [
        React.createElement(ListGroupItem, { key: groupName + "-list", active: someActive, onClick: onListGroupClick }, groupTranslations[groupName] !== undefined
            ? React.createElement("strong", null, groupTranslations[groupName])
            : React.createElement(react_spinner_1.default, { key: groupName + "-list" })),
        ...groupsList
    ];
    return (React.createElement("div", { key: groupName, className: "scope-field-modal-item" },
        React.createElement(ListGroup, null, listGroup)));
});
function GlyphField({ settings, idSchema, formData, schema, isIncluded, toggleAdditionalProperty }) {
    const { glyph, label, show } = settings;
    const property = show;
    const onButtonClick = React.useCallback(() => toggleAdditionalProperty(property), [property, toggleAdditionalProperty]);
    const { Tooltip, OverlayTrigger } = React.useContext(ReactContext_1.default).theme;
    if (!show) {
        return null;
    }
    const hasData = (0, utils_1.propertyHasData)(property, formData) && (!formData || !(0, utils_1.isDefaultData)(formData[property], schema.properties[property]));
    const tooltip = React.createElement(Tooltip, { id: `${idSchema.$id}-${property}-tooltip-${glyph}` }, label);
    return (React.createElement(OverlayTrigger, { key: property, overlay: tooltip, placement: "left" },
        React.createElement(components_1.GlyphButton, { glyph: glyph, disabled: hasData, active: isIncluded, onClick: onButtonClick })));
}
(0, Context_1.default)("SCHEMA_FIELD_WRAPPERS").ScopeField = true;
