"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 __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
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 __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                t[p[i]] = s[p[i]];
        }
    return t;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AccordionArrayFieldTemplate = void 0;
const React = __importStar(require("react"));
const PropTypes = __importStar(require("prop-types"));
const deepmerge_1 = __importDefault(require("deepmerge"));
const utils_1 = require("../../utils");
const utils_2 = require("@rjsf/utils");
const components_1 = require("../components");
const ArrayFieldTemplate_1 = __importStar(require("../templates/ArrayFieldTemplate"));
const ArrayField_1 = require("./ArrayField");
const Context_1 = __importDefault(require("../../Context"));
const ReactContext_1 = __importDefault(require("../../ReactContext"));
const utils_3 = require("@rjsf/utils");
const memoizee_1 = __importDefault(require("memoizee"));
const ArrayField_2 = require("./ArrayField");
const popupMappers = {
    units: (schema, units, options) => {
        const identifications = units.map(item => (item && item.identifications && item.identifications[0]) ?
            item.identifications[0] :
            undefined).filter(item => item);
        return Promise.all(identifications.map(identification => Promise.resolve(identification.taxon))).then(result => {
            return Promise.resolve({ [(schema.units ? schema.units.title : undefined) || options.label || options.field]: result });
        });
    }
};
const getPopupDataPromise = (props, itemFormData) => {
    const { popupFields } = (0, utils_1.getUiOptions)(props.uiSchema);
    if (!props.formData)
        return Promise.resolve({});
    return Promise.all(popupFields.map(field => {
        const fieldName = field.field;
        let fieldData = itemFormData ? itemFormData[fieldName] : undefined;
        let fieldSchema = props.schema.items.properties;
        if (field.mapper && fieldData) {
            return popupMappers[field.mapper](fieldSchema, fieldData, field);
        }
        else if (fieldData) {
            return new Promise(resolve => resolve({ [fieldSchema && fieldSchema[fieldName] ? fieldSchema[fieldName].title : fieldName]: fieldData }));
        }
    })).then(fields => {
        const popupData = fields.reduce((popup, item) => {
            if (item)
                Object.keys(item).forEach(label => {
                    popup[label] = item[label];
                });
            return popup;
        }, {});
        return Promise.resolve(popupData);
    });
};
const isActive = (idx, activeIdx) => {
    return idx === activeIdx || (Array.isArray(activeIdx) && activeIdx.includes(idx));
};
class SingleActiveArrayField extends React.Component {
    constructor(props) {
        super(props);
        this.getInitialActiveIdx = (props) => {
            const { formData, uiSchema, schema } = props;
            const formDataLength = (formData || []).length;
            const options = (0, utils_1.getUiOptions)(uiSchema);
            return (formDataLength === 1 || formDataLength === 0 && schema.minItems) ? 0 : options.initialActiveIdx;
        };
        this.updatePopups = (props) => {
            const { popupFields } = (0, utils_1.getUiOptions)(this.props.uiSchema);
            let { popups } = this.state;
            let count = 0;
            if (popupFields)
                props.formData.forEach((item, idx) => {
                    getPopupDataPromise(props, item).then(popupData => {
                        count++;
                        popups = Object.assign(Object.assign({}, popups), { [idx]: popupData });
                        if (this.mounted && count === props.formData.length)
                            this.setState({ popups });
                    }).catch(() => {
                        count++;
                    });
                });
        };
        this.onHeaderAffixChange = (elem, value) => {
            this.setState({ scrollHeightFixed: value ? elem.scrollHeight : 0 });
        };
        this.getLocalFormContext = () => {
            if (this.localContextKey === this.state.scrollHeightFixed) {
                return this.localContext;
            }
            this.localContextKey = this.state.scrollHeightFixed;
            this.localContext = Object.assign(Object.assign({}, this.props.formContext), { topOffset: this.props.formContext.topOffset + this.state.scrollHeightFixed });
            this.localContext.utils = (0, utils_1.ReactUtils)(this.localContext);
            return this.localContext;
        };
        this.updateRenderingMode = (normalRendering, callback) => {
            this.setState({ normalRendering }, () => callback && callback(normalRendering));
        };
        this.onActiveChange = (idx, prop, callback) => {
            if (idx !== undefined) {
                idx = parseInt(idx);
            }
            if (this.state.activeIdx === idx) {
                idx = undefined;
            }
            const { onActiveChange } = (0, utils_1.getUiOptions)(this.props.uiSchema);
            onActiveChange ? onActiveChange(idx, prop, callback) : this.setState({ activeIdx: idx }, callback);
        };
        this.onDelete = (item) => (e) => {
            const newLength = this.props.formData.length - 1;
            if (!newLength) {
                this.onActiveChange(undefined);
            }
            else if (this.state.activeIdx > newLength - 1) {
                this.onActiveChange(newLength - 1);
            }
            item.onDropIndexClick(item.index)(e);
        };
        this.buttonDefinitions = {
            add: {
                callback: () => this.onActiveChange((this.props.formData || []).length)
            },
            addPredefined: {
                callback: () => this.onActiveChange((this.props.formData || []).length)
            },
            copy: {
                fn: () => (...params) => {
                    const { formData = [] } = this.props;
                    const idx = this.state.activeIdx !== undefined ?
                        this.state.activeIdx :
                        formData.length - 1;
                    (0, ArrayFieldTemplate_1.beforeAdd)(this.props, idx + 1);
                    this.props.onChange([
                        ...formData.slice(0, idx + 1),
                        (0, ArrayField_1.copyItemFunction)(this, formData[idx])(...params),
                        ...formData.slice(idx + 1)
                    ]);
                },
                callback: () => {
                    const idx = this.state.activeIdx !== undefined ?
                        this.state.activeIdx :
                        (this.props.formData || []).length - 1;
                    this.onActiveChange(idx + 1);
                },
                rules: {
                    minLength: 1
                }
            }
        };
        this.deleteButtonRefs = {};
        this.deleteButtonRefSetters = {};
        this.state = Object.assign(Object.assign({ activeIdx: this.getInitialActiveIdx(props), scrollHeightFixed: 0 }, this.getStateFromProps(props)), { popups: {} });
        const id = `${this.props.idSchema.$id}`;
        this.props.formContext.globals[`${id}.activeIdx`] = this.state.activeIdx;
    }
    componentDidMount() {
        this.mounted = true;
        this.updatePopups(this.props);
        if ((0, utils_1.getUiOptions)(this.props.uiSchema).receiveActiveIdxEvents !== false) {
            this.props.formContext.services.customEvents.add(this.props.idSchema.$id, "activeIdx", this.onActiveChange);
        }
    }
    componentWillUnmount() {
        this.mounted = false;
        if ((0, utils_1.getUiOptions)(this.props.uiSchema).receiveActiveIdxEvents !== false) {
            this.props.formContext.services.customEvents.remove(this.props.idSchema.$id, "activeIdx", this.onActiveChange);
        }
    }
    UNSAFE_componentWillReceiveProps(props) {
        this.prevActiveIdx = this.state.activeIdx;
        this.setState(this.getStateFromProps(props));
        this.updatePopups(props);
    }
    componentDidUpdate(prevProps, prevState) {
        const options = (0, utils_1.getUiOptions)(this.props);
        const prevOptions = (0, utils_1.getUiOptions)(prevProps);
        this.props.formContext.globals[`${this.props.idSchema.$id}.activeIdx`] = this.state.activeIdx;
        const { idToFocusAfterNavigate, idToScrollAfterNavigate, focusOnNavigate = true, renderer = "accordion", affixed } = (0, utils_1.getUiOptions)(this.props.uiSchema);
        if (renderer === "uncontrolled")
            return;
        if ((prevProps.formData || []).length === (this.props.formData || []).length && ("activeIdx" in options && options.activeIdx !== prevOptions.activeIdx || (!("activeIdx" in options) && this.state.activeIdx !== prevState.activeIdx))) {
            const id = `${this.props.idSchema.$id}_${(0, utils_1.getFormDataIndex)(this.state.activeIdx, this.props.uiSchema)}`;
            const idToScroll = idToScrollAfterNavigate
                ? idToScrollAfterNavigate
                : !affixed && (renderer === "accordion" || renderer === "pager")
                    ? `${id}-header`
                    : `${this.props.idSchema.$id}-add`;
            this.getLocalFormContext().utils.focusAndScroll(idToFocusAfterNavigate || id, idToScroll, focusOnNavigate);
        }
        if (prevProps.idSchema.$id !== this.props.idSchema.$id) {
            this.props.formContext.services.customEvents.remove(prevProps.idSchema.$id, "activeIdx", this.onActiveChange);
            this.props.formContext.services.customEvents.add(this.props.idSchema.$id, "activeIdx", this.onActiveChange);
        }
    }
    shouldComponentUpdate(prevProps, prevState) {
        if ((this.state.scrollHeightFixed && !prevState.scrollHeightFixed)
            || this.state.scrollHeightFixed && this.state.scrollHeightFixed !== prevState.scrollHeightFixed) {
            return false;
        }
        return true;
    }
    getStateFromProps(props) {
        const state = {};
        const options = (0, utils_1.getUiOptions)(props.uiSchema);
        if ("activeIdx" in options) {
            state.activeIdx = options.activeIdx;
        }
        else if ((props.formData || []).length === 1 && (this.props.formData || []).length === 0) {
            state.activeIdx = 0;
        }
        if (!state.activeIdx && this.props && props.idSchema.$id !== this.props.idSchema.$id) {
            state.activeIdx = this.getInitialActiveIdx(props);
        }
        if (options.sortCols && options.sortCols !== (0, utils_1.getUiOptions)(this.props.uiSchema).sortCols) {
            state.activeIdx = undefined;
        }
        return state;
    }
    render() {
        const { renderer = "accordion", tableActiveItemClassNames } = (0, utils_1.getUiOptions)(this.props.uiSchema);
        let ArrayFieldTemplate = undefined;
        switch (renderer) {
            case "accordion":
                ArrayFieldTemplate = AccordionArrayFieldTemplate;
                break;
            case "pager":
                ArrayFieldTemplate = PagerArrayFieldTemplate;
                break;
            case "uncontrolled":
                ArrayFieldTemplate = UncontrolledArrayFieldTemplate;
                break;
            case "table":
                ArrayFieldTemplate = TableArrayFieldTemplate;
                break;
            default:
                throw new Error(`Unknown renderer '${renderer}' for SingleActiveArrayField`);
        }
        const formContext = Object.assign(Object.assign({}, this.getLocalFormContext()), { this: this, prevActiveIdx: this.prevActiveIdx, activeIdx: this.state.activeIdx });
        const { registry: { fields: { ArrayField } } } = this.props;
        const { buttons = [], buttonDefinitions } = (0, utils_1.getUiOptions)(this.props.uiSchema);
        let uiSchema = Object.assign(Object.assign({}, this.props.uiSchema), { "ui:field": undefined, "ui:classNames": undefined, "ui:options": Object.assign(Object.assign({}, (0, utils_1.getUiOptions)(this.props.uiSchema)), { buttons, buttonDefinitions: buttonDefinitions
                    ? (0, deepmerge_1.default)(this.buttonDefinitions, buttonDefinitions)
                    : this.buttonDefinitions }) });
        if (renderer === "table" && tableActiveItemClassNames && !this.state.normalRendering) {
            uiSchema = Object.assign(Object.assign({}, uiSchema), { items: Object.assign(Object.assign({}, uiSchema.items), { "ui:classNames": tableActiveItemClassNames }) });
        }
        uiSchema["ui:ArrayFieldTemplate"] = ArrayFieldTemplate;
        return (React.createElement(ArrayField, Object.assign({}, this.props, { formContext: formContext, registry: Object.assign(Object.assign({}, this.props.registry), { formContext }), uiSchema: uiSchema })));
    }
}
SingleActiveArrayField.propTypes = {
    uiSchema: PropTypes.shape({
        "ui:options": PropTypes.shape({
            renderer: PropTypes.oneOf(["accordion", "pager", "uncontrolled", "table"]),
            activeIdx: PropTypes.number
        })
    }),
    schema: PropTypes.shape({
        type: PropTypes.oneOf(["array"])
    }).isRequired,
    formData: PropTypes.array
};
exports.default = SingleActiveArrayField;
class Popup extends React.Component {
    render() {
        const { data } = this.props;
        return (data && Object.keys(data).length) ? (React.createElement("ul", { className: "map-data-tooltip" }, data ? Object.keys(data).map(fieldName => {
            const item = data[fieldName];
            return React.createElement("li", { key: fieldName },
                React.createElement("strong", null,
                    fieldName,
                    ":"),
                " ",
                Array.isArray(item) ? item.filter(utils_1.hasData).join(", ") : item);
        }) : null)) : null;
    }
}
function handlesButtonsAndFocus(ComposedComponent) {
    let SingleAndMultiActiveArrayTemplateField = class SingleAndMultiActiveArrayTemplateField extends ComposedComponent {
        constructor() {
            super(...arguments);
            this.getFocusHandlers = (props) => {
                const that = props.formContext.this;
                return props.items.map((_, i) => {
                    const idx = (0, utils_1.getFormDataIndex)(i, that.props.uiSchema);
                    return [`${that.props.idSchema.$id}_${idx}`, () => {
                            if (!isActive(i, that.state.activeIdx))
                                return new Promise(resolve => {
                                    that.onActiveChange(i, undefined, () => resolve());
                                });
                        }];
                });
            };
            this.getSetOpenHandlers = (props) => {
                const that = props.formContext.this;
                return props.items.map((_, i) => {
                    const idx = (0, utils_1.getFormDataIndex)(i, that.props.uiSchema);
                    return [`${that.props.idSchema.$id}_${idx}`, (open) => {
                            if (!Array.isArray(that.state.activeIdx)) {
                                return;
                            }
                            const isActive = that.state.activeIdx.includes(i);
                            if ((open && !isActive) || (!open && isActive)) {
                                that.onActiveChange(i);
                            }
                        }];
                });
            };
        }
        getKeyHandlers(props) {
            const { renderer = "accordion" } = (0, utils_1.getUiOptions)(props.uiSchema);
            const that = props.formContext.this;
            return [ArrayFieldTemplate_1.arrayKeyFunctions, {
                    getProps: () => this.props,
                    insertCallforward: callback => that.onActiveChange((that.props.formData || []).length, undefined, callback),
                    getCurrentIdx: () => Array.isArray(that.state.activeIdx) ? undefined : that.state.activeIdx,
                    focusByIdx: (idx, prop, callback) => isActive(idx, that.state.activeIdx)
                        ? callback()
                        : that.onActiveChange(idx, prop, callback),
                    getIdToScrollAfterNavigate: (renderer === "accordion" || renderer === "pager") && !Array.isArray(that.state.activeIdx)
                        ? () => `${props.idSchema.$id}_${that.state.activeIdx}-header`
                        : undefined
                }];
        }
        componentDidMount() {
            this.addFocusHandlers();
            this.addSetOpenHandlers();
            if (super.componentDidMount)
                super.componentDidMount();
        }
        componentDidUpdate(...params) {
            this.removeFocusHandlers();
            this.addFocusHandlers();
            this.removeSetOpenHandlers();
            this.addSetOpenHandlers();
            if (super.componentDidUpdate)
                super.componentDidUpdate(...params);
        }
        componentWillUnmount() {
            this.removeFocusHandlers();
            this.removeSetOpenHandlers();
            if (super.componentWillUnmount)
                super.componentWillUnmount();
        }
        addFocusHandlers() {
            this.focusHandlers = this.getFocusHandlers(this.props);
            this.focusHandlers.forEach(handler => {
                this.props.formContext.services.focus.addFocusHandler(...handler);
            });
        }
        removeFocusHandlers() {
            this.focusHandlers.forEach(handler => {
                this.props.formContext.services.focus.removeFocusHandler(...handler);
            });
        }
        addSetOpenHandlers() {
            this.setAllOpenHandlers = this.getSetOpenHandlers(this.props);
            this.setAllOpenHandlers.forEach(handler => {
                this.props.formContext.services.multiActiveArray.addSetOpenHandler(...handler);
            });
        }
        removeSetOpenHandlers() {
            this.setAllOpenHandlers.forEach(handler => {
                this.props.formContext.services.multiActiveArray.removeSetOpenHandler(...handler);
            });
        }
        getChildKeyHandlers(props) {
            const that = props.formContext.this;
            const handlers = [];
            if (that.state.activeIdx !== undefined) {
                const activeIdxs = (0, utils_1.asArray)(that.state.activeIdx);
                activeIdxs.forEach((idx) => {
                    const id = `${props.idSchema.$id}_${idx}`;
                    handlers.push([id, ArrayFieldTemplate_1.arrayItemKeyFunctions, { id, getProps: () => this.props, getDeleteButton: () => {
                                return that.deleteButtonRefs[idx];
                            } }]);
                });
            }
            return handlers;
        }
    };
    SingleAndMultiActiveArrayTemplateField.displayName = (0, utils_1.getReactComponentName)(ComposedComponent);
    SingleAndMultiActiveArrayTemplateField = __decorate([
        ArrayFieldTemplate_1.handlesArrayKeys
    ], SingleAndMultiActiveArrayTemplateField);
    return SingleAndMultiActiveArrayTemplateField;
}
// Swallow unknown prop warnings.
const ButtonsWrapper = ({ props }) => {
    const buttons = (0, utils_1.getUiOptions)(props.uiSchema).buttons;
    return React.createElement("div", null, (0, ArrayFieldTemplate_1.getButtonElems)(buttons, props));
};
const AccordionButtonsWrapper = ({ props, position }) => {
    const buttons = (0, ArrayFieldTemplate_1.getButtonsForPosition)(props, (0, ArrayFieldTemplate_1.getButtons)((0, utils_1.getUiOptions)(props.uiSchema).buttons, props), position);
    const { Row, Col } = React.useContext(ReactContext_1.default).theme;
    if (!buttons)
        return null;
    const cols = Object.keys((0, utils_1.getBootstrapCols)()).reduce((cols, colType) => {
        cols[colType] = (colType === "xs" || buttons.length > 3) ? 12 : 12 / buttons.length;
        return cols;
    }, {});
    return (React.createElement(Row, { className: "laji-form-accordion-buttons" }, buttons.map((button, idx) => React.createElement(Col, Object.assign({}, cols, { key: idx }), button))));
};
// supports MultiActiveArrayField
let AccordionArrayFieldTemplate = class AccordionArrayFieldTemplate extends React.Component {
    constructor() {
        super(...arguments);
        this.setHeaderRef = (elem) => {
            this.headerRef = elem;
        };
        this.onSelect = key => {
            const that = this.props.formContext.this;
            that.onActiveChange(key);
        };
        this.setDeleteButtonRef = idx => elem => { this.props.formContext.this.deleteButtonRefs[idx] = elem; };
    }
    render() {
        const that = this.props.formContext.this;
        const arrayFieldTemplateProps = this.props;
        const activeIdx = that.state.activeIdx;
        const { translations, uiSchemaContext } = this.props.formContext;
        const { confirmDelete = uiSchemaContext.confirmDelete, closeButton, affixed } = (0, utils_1.getUiOptions)(arrayFieldTemplateProps.uiSchema);
        const { disabled, readonly } = arrayFieldTemplateProps;
        const containerRefs = {};
        (0, utils_1.asArray)(activeIdx).forEach(idx => {
            containerRefs[idx] = React.createRef();
        });
        const getHeader = (item, idx) => {
            let header = React.createElement(AccordionHeader, { ref: this.setHeaderRef, that: that, idx: idx, wrapperClassName: "panel-title", className: "laji-form-panel-header laji-form-clickable-panel-header laji-form-accordion-header" }, item.hasRemove && React.createElement(components_1.DeleteButton, { id: `${that.props.idSchema.$id}_${(0, utils_1.getFormDataIndex)(idx, that.props.uiSchema)}`, disabled: disabled || readonly, ref: this.setDeleteButtonRef(idx), className: "pull-right", confirm: confirmDelete, translations: translations, onClick: that.onDelete(item) }));
            if (affixed && isActive(idx, activeIdx)) {
                const offset = this.props.formContext.topOffset - (that.state.scrollHeightFixed);
                header = (React.createElement(components_1.Affix, { containerRef: containerRefs[idx], topOffset: offset, onAffixChange: this.onHeaderAffixChange }, header));
            }
            return header;
        };
        const { Panel, Accordion, Glyphicon } = this.context.theme;
        return (React.createElement("div", { className: "laji-form-single-active-array no-transition" },
            React.createElement(AccordionButtonsWrapper, { props: arrayFieldTemplateProps, position: "top" }),
            React.createElement(Accordion, { onSelect: this.onSelect, activeKey: activeIdx === undefined ? -1 : activeIdx, id: `${that.props.idSchema.$id}-accordion` },
                arrayFieldTemplateProps.items.map((item, idx) => (React.createElement(Panel, { key: idx, ref: containerRefs[idx], id: `${this.props.idSchema.$id}_${(0, utils_1.getFormDataIndex)(idx, that.props.uiSchema)}-panel`, className: "laji-form-panel laji-form-clickable-panel", eventKey: idx, variant: (0, utils_1.filteredErrors)(that.props.errorSchema)[(0, utils_1.getFormDataIndex)(idx, that.props.uiSchema)] ? "danger" : "default" },
                    React.createElement(Panel.Heading, null, getHeader(item, idx)),
                    isActive(idx, activeIdx) ? (React.createElement(Panel.Body, null,
                        item.children,
                        closeButton ? React.createElement(components_1.Button, { onClick: this.onSelect, small: true, className: "pull-right" },
                            React.createElement(Glyphicon, { glyph: "chevron-up" }),
                            " ",
                            translations.Close) : null)) : null))),
                React.createElement(AccordionButtonsWrapper, { props: arrayFieldTemplateProps, position: "bottom" }))));
    }
};
exports.AccordionArrayFieldTemplate = AccordionArrayFieldTemplate;
AccordionArrayFieldTemplate.contextType = ReactContext_1.default;
exports.AccordionArrayFieldTemplate = AccordionArrayFieldTemplate = __decorate([
    handlesButtonsAndFocus
], AccordionArrayFieldTemplate);
// does not support MultiActiveArrayField
let PagerArrayFieldTemplate = class PagerArrayFieldTemplate extends React.Component {
    constructor() {
        super(...arguments);
        this.containerRef = React.createRef();
        this.setHeaderRef = (elem) => {
            this.headerRef = elem;
        };
        this.onHeaderAffixChange = (value) => {
            const elem = this.headerRef;
            const that = this.props.formContext.this;
            that.onHeaderAffixChange(elem, value);
        };
        this.navigatePrev = () => this.props.formContext.this.onActiveChange(this.props.formContext.this.state.activeIdx - 1);
        this.navigateNext = () => this.props.formContext.this.onActiveChange(this.props.formContext.this.state.activeIdx + 1);
        this.setDeleteButtonRef = idx => elem => { this.props.formContext.this.deleteButtonRefs[idx] = elem; };
    }
    render() {
        const that = this.props.formContext.this;
        const arrayTemplateFieldProps = this.props;
        const { translations, uiSchemaContext } = that.props.formContext;
        const { buttons, affixed, headerClassName, confirmDelete = uiSchemaContext.confirmDelete } = (0, utils_1.getUiOptions)(arrayTemplateFieldProps.uiSchema);
        const activeIdx = that.state.activeIdx;
        const { Pager } = this.context.theme;
        let header = (React.createElement("div", { className: `laji-form-panel-header laji-form-accordion-header${headerClassName ? ` ${headerClassName}` : ""}`, ref: this.setHeaderRef },
            React.createElement(Pager, null,
                React.createElement(Pager.Item, { previous: true, href: "#", disabled: activeIdx <= 0 || activeIdx === undefined, onClick: this.navigatePrev },
                    "\u2190 ",
                    translations.Previous),
                activeIdx !== undefined
                    ? (React.createElement(AccordionHeader, { that: that, idx: activeIdx, className: "panel-title", canHaveUndefinedIdx: false }))
                    : null,
                React.createElement(Pager.Item, { next: true, href: "#", disabled: activeIdx >= (that.props.formData || []).length - 1 || activeIdx === undefined, onClick: this.navigateNext },
                    translations.Next,
                    "  \u2192"))));
        if (affixed) {
            const offset = this.props.formContext.topOffset - (that.state.scrollHeightFixed);
            header = (React.createElement(components_1.Affix, { containerRef: this.containerRef, topOffset: offset, onAffixChange: this.onHeaderAffixChange }, header));
        }
        const { Panel } = this.context.theme;
        return (React.createElement("div", { className: "laji-form-single-active-array", ref: this.containerRef },
            React.createElement("div", { className: "laji-form-field-template-item" },
                React.createElement("div", { className: "laji-form-field-template-schema" },
                    React.createElement(Panel, { className: "laji-form-panel" },
                        React.createElement(Panel.Heading, null, header),
                        React.createElement(Panel.Body, null,
                            React.createElement("div", { key: (0, utils_1.getUUID)(this.props.formData[activeIdx]) || activeIdx }, activeIdx !== undefined && arrayTemplateFieldProps.items && arrayTemplateFieldProps.items[activeIdx] ? arrayTemplateFieldProps.items[activeIdx].children : null))),
                    (0, ArrayFieldTemplate_1.getButtonElems)(buttons, arrayTemplateFieldProps)),
                React.createElement("div", { className: "laji-form-field-template-buttons" }, activeIdx !== undefined && arrayTemplateFieldProps.items[activeIdx].hasRemove
                    ? (React.createElement(components_1.DeleteButton, { id: `${that.props.idSchema.$id}_${(0, utils_1.getFormDataIndex)(activeIdx, that.props.uiSchema)}`, ref: this.setDeleteButtonRef(activeIdx), className: "pull-right", confirm: confirmDelete, translations: translations, onClick: that.onDelete(arrayTemplateFieldProps.items[activeIdx]) }))
                    : null))));
    }
};
PagerArrayFieldTemplate.contextType = ReactContext_1.default;
PagerArrayFieldTemplate = __decorate([
    handlesButtonsAndFocus
], PagerArrayFieldTemplate);
// does not support MultiActiveArrayField
let UncontrolledArrayFieldTemplate = class UncontrolledArrayFieldTemplate extends React.Component {
    render() {
        const that = this.props.formContext.this;
        const arrayTemplateFieldProps = this.props;
        const activeIdx = that.state.activeIdx;
        const TitleFieldTemplate = (0, utils_3.getTemplate)("TitleFieldTemplate", this.props.registry, (0, utils_1.getUiOptions)(this.props.uiSchema));
        const DescriptionFieldTemplate = (0, utils_3.getTemplate)("DescriptionFieldTemplate", this.props.registry, (0, utils_1.getUiOptions)(this.props.uiSchema));
        const { Label } = this.props.formContext;
        const Title = (0, utils_1.getUiOptions)(that.props.uiSchema).renderTitleAsLabel ? Label : TitleFieldTemplate;
        const title = (0, utils_1.getTitle)(this.props, activeIdx);
        const titleUiSchema = Object.assign(Object.assign({}, arrayTemplateFieldProps.uiSchema), { "ui:options": Object.assign(Object.assign({}, (0, utils_1.getUiOptions)(arrayTemplateFieldProps.uiSchema)), { titleFormatters: that.props.uiSchema.titleFormatters }) });
        return activeIdx !== undefined && arrayTemplateFieldProps.items && arrayTemplateFieldProps.items[activeIdx] ?
            React.createElement("div", { key: (0, utils_1.getUUID)(this.props.formData[activeIdx]) || activeIdx },
                React.createElement(Title, { title: title, label: title, schema: this.props.schema, uiSchema: titleUiSchema, formData: that.props.formData, registry: this.props.registry, id: this.props.idSchema.$id }),
                React.createElement(DescriptionFieldTemplate, { description: this.props.uiSchema["ui:description"], schema: this.props.schema }),
                arrayTemplateFieldProps.items[activeIdx].children)
            : null;
    }
};
UncontrolledArrayFieldTemplate = __decorate([
    handlesButtonsAndFocus
], UncontrolledArrayFieldTemplate);
// does not support MultiActiveArrayField
let TableArrayFieldTemplate = class TableArrayFieldTemplate extends React.Component {
    constructor(props) {
        super(props);
        this.mouseCache = { enter: {}, leave: {}, keydown: {} };
        this.onResize = () => {
            this.updateLayout();
        };
        // Sets state.normalRendering on if screen is too small for table layout.
        this.updateRenderingMode = (callback) => {
            const _callback = (updateLayout = true) => {
                if (updateLayout && this._lastWidth && (0, utils_1.pixelsToBsSize)(this._lastWidth) !== (0, utils_1.pixelsToBsSize)(window.innerWidth)) {
                    this.updateLayout(null, callback);
                }
            };
            const that = this.props.formContext.this;
            const { normalRenderingTreshold } = (0, utils_1.getUiOptions)(this.props.uiSchema);
            let initialized = false;
            if (Object.keys(this.state).length === 0) {
                initialized = true;
                const state = this.getStyles();
                if (state) {
                    this.setState(state, _callback);
                }
            }
            if (!normalRenderingTreshold) {
                if (!initialized) {
                    _callback();
                }
                return;
            }
            let treshold = (0, utils_1.bsSizeToPixels)(normalRenderingTreshold);
            requestAnimationFrame(() => {
                let normalRendering = undefined;
                if (!this.state.normalRendering && window.innerWidth <= treshold) {
                    normalRendering = true;
                }
                else if (this.state.normalRendering && window.innerWidth > treshold) {
                    normalRendering = false;
                }
                if (normalRendering !== undefined) {
                    that.updateRenderingMode(normalRendering, () => this.setState({ normalRendering }, () => this.updateLayout(null, () => _callback(false))));
                }
                else if (!this.state.normalRendering) {
                    this.updateLayout(null, _callback);
                }
            });
        };
        this.setActiveRef = (elem) => {
            this.activeElem = elem;
            this.activeElem && this.resizeObserver.observe(this.activeElem);
        };
        this.setTHeadRef = (elem) => {
            this.tHeadRef = elem;
        };
        this.updateLayout = (idx = null, callback) => {
            requestAnimationFrame(() => {
                this._lastWidth = window.innerWidth;
                const scrollBack = this.props.formContext.utils.shouldSyncScroll();
                const state = this.getStyles();
                if (!state) {
                    return;
                }
                if (idx !== null)
                    state.activeIdx = idx;
                const _callback = () => {
                    if (scrollBack) {
                        this.props.formContext.utils.syncScroll(!!"force");
                    }
                    if (callback)
                        callback();
                };
                this.setState(state, _callback);
            });
        };
        this.getStyles = () => {
            const that = this.props.formContext.this;
            const { activeIdx } = that.state;
            const { activeHeightOffset = 0 } = (0, utils_1.getUiOptions)(this.props.uiSchema);
            const rowElem = this.itemElems[activeIdx];
            if (!rowElem || !this.activeElem)
                return;
            return {
                activeStyle: activeIdx !== undefined ? {
                    position: "absolute",
                    top: rowElem.offsetTop,
                    width: "100%",
                    right: 0
                } : {},
                activeTrStyle: activeIdx !== undefined ? {
                    height: this.activeElem.offsetHeight + activeHeightOffset
                } : {}
            };
        };
        this.getDeleteButtonRef = (idx) => {
            const that = this.props.formContext.this;
            that.deleteButtonRefSetters[idx] = that.deleteButtonRefSetters[idx]
                || (elem => {
                    that.deleteButtonRefs[idx] = elem;
                });
            return that.deleteButtonRefSetters[idx];
        };
        this.customEventSender = (0, memoizee_1.default)((eventName) => (0, memoizee_1.default)((idx) => () => {
            const that = this.props.formContext.this;
            that.props.formContext.services.customEvents.send(that.props.idSchema.$id, eventName, { idx });
        }));
        this.onKeyDownActivate = (0, memoizee_1.default)((idx) => (e) => {
            if (idx !== this.state.activeIdx && (e.key === " " || e.key === "Enter")) {
                this.getOnChangeActive(idx)();
                e.preventDefault();
                e.stopPropagation();
            }
        });
        this.getOnChangeActive = (0, memoizee_1.default)(idx => () => {
            const that = this.props.formContext.this;
            idx !== that.state.activeIdx && that.onActiveChange(idx, undefined, this.updateLayout);
        });
        this.getOnHeaderClick = (0, memoizee_1.default)((col, onSortToggle) => () => onSortToggle(col));
        this.state = {};
        this.itemElems = [];
        this.resizeObserver = new ResizeObserver(this.onResize);
    }
    componentDidMount() {
        this._updateRenderingMode = () => this.updateRenderingMode();
        window.addEventListener("resize", this._updateRenderingMode);
        this.updateRenderingMode();
        this._prevCheckedLength = this.props.items.length;
    }
    componentWillUnmount() {
        window.removeEventListener("resize", this._updateRenderingMode);
        this.resizeObserver.disconnect();
    }
    componentDidUpdate(prevProps, prevState) {
        const that = this.props.formContext.this;
        let updated = false;
        if (this.props.items.length !== prevProps.items.length || this.state.activeIdx !== prevState.activeIdx) {
            if (!this.state.normalRendering && this.props.items.length === 1 && this.state.activeIdx === 0) {
                this.updateRenderingMode();
                updated = true;
            }
            else if (this.state.normalRendering && this.props.items.length > 1 || this.state.activeIdx !== 0) {
                this.updateRenderingMode();
                updated = true;
            }
        }
        if (!updated) {
            const activeChanged = this.state.activeIdx !== that.state.activeIdx;
            const itemsLengthChanged = this._prevCheckedLength !== this.props.items.length;
            let tHeadHeight, tHeadHeightChanged;
            if (this.tHeadRef) {
                tHeadHeight = this.tHeadRef.scrollHeight;
                tHeadHeightChanged = this.prevTHeadHeight && tHeadHeight !== this.prevTHeadHeight;
            }
            if (activeChanged || itemsLengthChanged || tHeadHeightChanged) {
                this.updateLayout(this.props.formContext.this.state.activeIdx);
            }
            if (tHeadHeight)
                this.prevTHeadHeight = tHeadHeight;
            this._prevCheckedLength = this.props.items.length;
        }
    }
    getSortableHeaderProps(col, props) {
        const { onSortToggle, sortCols, ui, sortableColumns, sortColTooltips } = (0, utils_1.getUiOptions)(props.uiSchema);
        if (!onSortToggle || sortableColumns && !sortableColumns.includes(col)) {
            return {};
        }
        const sortCol = sortCols.find(({ name }) => name === col);
        const className = (0, utils_1.classNames)((sortCol === null || sortCol === void 0 ? void 0 : sortCol.descending)
            ? "laji-form-col-desc"
            : (sortCol === null || sortCol === void 0 ? void 0 : sortCol.descending) === false
                ? "laji-form-col-asc"
                : undefined, "laji-form-col-sortable");
        const tooltip = sortColTooltips[col] || props.formContext.translations["ClickToSort"];
        return { onClick: this.getOnHeaderClick(col, onSortToggle), className, ui: ui[col], role: "button", tooltip };
    }
    render() {
        if (this.state.normalRendering) {
            return React.createElement(ArrayFieldTemplate_1.default, Object.assign({}, this.props));
        }
        const { schema, uiSchema = {}, formData = [], items, disabled, readonly } = this.props;
        const TitleFieldTemplate = (0, utils_3.getTemplate)("TitleFieldTemplate", this.props.registry, (0, utils_1.getUiOptions)(uiSchema));
        const DescriptionFieldTemplate = (0, utils_3.getTemplate)("DescriptionFieldTemplate", this.props.registry, (0, utils_1.getUiOptions)(uiSchema));
        const { renderTitleAsLabel, formatters = {}, shownColumns = [], removable = true } = (0, utils_1.getUiOptions)(uiSchema);
        const { Label } = this.props.formContext;
        const Title = renderTitleAsLabel ? Label : TitleFieldTemplate;
        const foundProps = {};
        const shownColumnsDict = (0, utils_1.dictionarify)(shownColumns);
        const { tmpImgs = {} } = (0, Context_1.default)("IMAGE_ARRAY_FIELD");
        let cols = Object.keys(schema.items.properties).reduce((_cols, prop) => {
            if (formData.some(item => {
                const found = shownColumnsDict[prop]
                    || foundProps[prop]
                    || (prop in item
                        && !(0, utils_1.isEmptyString)(item[prop])
                        && (!Array.isArray(item[prop])
                            || Array.isArray(item[prop]) && !item[prop].every(utils_1.isEmptyString))
                        && !(0, utils_1.isDefaultData)(item[prop], schema.items.properties[prop])
                        && !(0, utils_1.isHidden)(uiSchema.items || {}, prop)
                        && !(0, utils_1.isHidden)((0, utils_1.getNestedTailUiSchema)(uiSchema.items || {}), prop))
                    || uiSchema.items && uiSchema.items[prop] && uiSchema.items[prop]["ui:field"] === "ImageArrayField" && (0, utils_1.getUUID)(item) && tmpImgs[(0, utils_1.getUUID)(item)];
                if (found)
                    foundProps[prop] = true;
                return found;
            })) {
                _cols.push(prop);
            }
            return _cols;
        }, []);
        const { "ui:order": order } = (uiSchema.items || {});
        if (order)
            cols = (0, utils_2.orderProperties)(cols, order.filter(field => field === "*" || foundProps[field]));
        const that = this.props.formContext.this;
        const { errorSchema } = that.props;
        const activeIdx = that.state.activeIdx;
        const { confirmDelete = this.props.formContext.uiSchemaContext.confirmDelete } = (0, utils_1.getUiOptions)(uiSchema);
        const getDeleteButtonFor = (idx, item) => {
            return removable && React.createElement(components_1.DeleteButton, { id: `${that.props.idSchema.$id}_${idx}`, disabled: disabled || readonly, ref: this.getDeleteButtonRef(idx), key: (0, utils_1.getUUID)(this.props.formData[item.index]) || item.key, confirm: confirmDelete, translations: this.props.formContext.translations, onClick: that.onDelete(item) });
        };
        const setItemRef = idx => elem => {
            this.itemElems[idx] = elem;
        };
        const title = (0, utils_1.getTitle)(this.props, that.state.activeIdx);
        const onMouseEnter = this.customEventSender("startHighlight");
        const onMouseLeave = this.customEventSender("endHighlight");
        const { Table } = this.context.theme;
        return (React.createElement("div", { style: { position: "relative" }, className: "single-active-array-table-container" },
            React.createElement(Title, { title: title, label: title, uiSchema: uiSchema, schema: schema, formData: formData, registry: this.props.registry, id: this.props.idSchema.$id }),
            React.createElement(DescriptionFieldTemplate, { description: uiSchema["ui:description"], schema: this.props.schema }),
            React.createElement("div", { className: "laji-form-field-template-item" },
                React.createElement("div", { className: "table-responsive laji-form-field-template-schema" },
                    React.createElement(Table, { hover: true, bordered: true, condensed: true, className: "single-active-array-table" },
                        items.length > 1 || (that.state.activeIdx !== undefined && that.state.activeIdx !== 0) ? (React.createElement("thead", { ref: this.setTHeadRef },
                            React.createElement("tr", null,
                                cols.length ? cols.map(col => {
                                    const sortableHeaderProps = this.getSortableHeaderProps(col, this.props);
                                    const { ui, tooltip } = sortableHeaderProps, _sortableHeaderProps = __rest(sortableHeaderProps, ["ui", "tooltip"]);
                                    const className = (0, utils_1.classNames)("darker", sortableHeaderProps.className);
                                    return (React.createElement(components_1.TooltipComponent, { key: col, tooltip: tooltip, placement: "top", id: `${this.props.idSchema[col].$id}-header` },
                                        React.createElement("th", Object.assign({ key: col }, _sortableHeaderProps, { className: className }),
                                            ((uiSchema.items || {})[col] || {})["ui:title"] || schema.items.properties[col].title,
                                            ui || null)));
                                }) : React.createElement("th", { className: "darker" }),
                                React.createElement("th", { key: "_activeContent", className: "single-active-array-table-content-col" }),
                                React.createElement("th", { key: "_delete", className: "single-active-array-table-delete" })))) : null,
                        React.createElement("tbody", null, formData.map((_, idx) => {
                            const item = items[idx];
                            let className = "";
                            if ((0, utils_1.filteredErrors)(errorSchema)[(0, utils_1.getFormDataIndex)(idx, uiSchema)])
                                className = className ? `${className} bg-danger` : "bg-danger";
                            return [
                                React.createElement("tr", { key: (0, utils_1.getUUID)(this.props.formData[item.index]) || item.key, onClick: this.getOnChangeActive(idx), className: className, tabIndex: idx === activeIdx ? undefined : 0, role: idx === activeIdx ? undefined : "button", id: idx !== activeIdx ? `_laji-form_${ArrayField_2.ArrayFieldPatched.prototype.getIdSchema(this.props, idx).$id}` : undefined, ref: setItemRef(idx), style: idx === activeIdx ? this.state.activeTrStyle : undefined, onMouseEnter: onMouseEnter(idx), onMouseLeave: onMouseLeave(idx), onKeyDown: this.onKeyDownActivate(idx) },
                                    cols.length ? cols.map(col => React.createElement("td", { key: col }, (0, utils_1.formatValue)(Object.assign(Object.assign({}, that.props), { schema: schema.items.properties[col], uiSchema: (uiSchema.items || {})[col], formData: formData[idx][col] }), formatters[col], { formData: formData[idx] }))) : React.createElement("td", null),
                                    (activeIdx !== undefined && items[activeIdx] && idx === activeIdx) ? (React.createElement("td", { key: (0, utils_1.getUUID)(formData[activeIdx]) || activeIdx, className: "single-active-array-table-content-col" },
                                        React.createElement("div", { className: "laji-form-field-template-item keep-vertical", style: this.state.activeStyle, ref: this.setActiveRef },
                                            React.createElement("div", { className: "laji-form-field-template-schema" }, items[activeIdx].children),
                                            React.createElement("div", { className: "laji-form-field-template-buttons" })))) : React.createElement("td", { className: "single-active-array-table-content-col" }),
                                    React.createElement("td", { key: "delete", className: "delete-button-container" }, getDeleteButtonFor(idx, item)))
                            ];
                        })))),
                React.createElement("div", { className: "laji-form-field-template-buttons" })),
            React.createElement(ButtonsWrapper, { props: this.props })));
    }
};
TableArrayFieldTemplate.contextType = ReactContext_1.default;
TableArrayFieldTemplate = __decorate([
    handlesButtonsAndFocus
], TableArrayFieldTemplate);
const headerFormatters = {
    units: {
        component: (props) => {
            const { that: { props: { formContext: { translations }, formData } }, idx } = props;
            const item = formData[idx];
            const unitsLength = (item && item.units && "length" in item.units) ?
                item.units.filter(unit => unit &&
                    unit.identifications &&
                    unit.identifications[0] &&
                    unit.identifications[0].taxon).length
                : 0;
            return (React.createElement("span", { className: "text-muted" }, ` (${unitsLength} ${translations.unitsPartitive})`));
        },
        onClick: (that, idx) => {
            if (isActive(idx, that.state.activeIdx)) {
                headerFormatters.units.onMouseEnter(that, idx, !!"use the force");
            }
            else {
                headerFormatters.units.onMouseLeave(that);
            }
        },
        onMouseEnter: (that, idx, force) => {
            const { props: { formData } } = that;
            const item = formData[idx];
            that.hoveredIdx = idx;
            if (!force && isActive(idx, that.state.activeIdx))
                return;
            const map = (0, Context_1.default)(`${that.props.formContext.contextId}_MAP`).map;
            const gatheringGeometries = (item && item.geometry && item.geometry.geometries) ? item.geometry.geometries : [];
            const unitGeometries = [...(item && item.units ? item.units : [])]
                .filter(unit => unit.unitGathering && (0, utils_1.hasData)(unit.unitGathering.geometry))
                .map(unit => unit.unitGathering.geometry);
            const geometries = [...gatheringGeometries, ...unitGeometries]
                .map(geometry => {
                return { type: "Feature", properties: {}, geometry };
            });
            map.addData({
                featureCollection: { type: "featureCollection", features: geometries },
                getFeatureStyle: () => ({ opacity: 0.6, color: "#888888" }),
                temp: true
            });
        },
        onMouseLeave: (that) => {
            const map = (0, Context_1.default)(`${that.props.formContext.contextId}_MAP`).map;
            const lastData = map.data[map.data.length - 1];
            if (lastData && lastData.temp) {
                map.removeData(map.data.length - 1);
            }
            that.hoveredIdx = undefined;
        }
    },
    namedPlace: {
        component: class NamedPlaceHeader extends React.Component {
            constructor(props) {
                super(props);
                this.fetch = (props) => {
                    const { namedPlaceID } = (props.that.props.formData || {})[props.idx] || {};
                    if (namedPlaceID)
                        props.that.props.formContext.apiClient.get("/named-places/{id}", { path: { id: namedPlaceID } }).then(response => {
                            if (this.mounted && response.name !== this.state.name)
                                this.setState({
                                    namedPlaceID,
                                    name: response.name
                                });
                        }).catch(() => { });
                };
                this.state = {};
            }
            componentDidMount() {
                this.mounted = true;
                this.fetch(this.props);
            }
            componentWillUnmount() {
                this.mounted = false;
            }
            UNSAFE_componentWillReceiveProps(props) {
                this.fetch(props);
            }
            render() {
                const { name } = this.state;
                const { locality } = (this.props.that.props.formData || {})[this.props.idx] || {};
                return React.createElement("span", { className: "text-muted" }, !(0, utils_1.isEmptyString)(name) ? name : locality);
            }
        }
    },
    lineTransect: {
        component: (props) => {
            const item = props.that.props.formData[props.idx];
            const [start, end] = [item.gatheringFact.lineTransectSegmentMetersStart, item.gatheringFact.lineTransectSegmentMetersEnd];
            return props.idx !== undefined && end ? React.createElement("span", { className: "text-muted" }, `${start}-${end}m`) : null;
        }
    },
    number: {
        component: (props) => {
            return props.idx !== undefined ? (props.idx + 1) + "." : null;
        }
    },
    lolife: {
        onMouseEnter: (that, idx) => {
            that.props.formContext.services.customEvents.send(that.props.idSchema.$id, "startHighlight", { id: (0, utils_1.getUUID)(that.props.formData[idx]) });
        },
        onMouseLeave: (that, idx) => {
            that.props.formContext.services.customEvents.send(that.props.idSchema.$id, "endHighlight", { id: (0, utils_1.getUUID)(that.props.formData[idx]) });
        }
    },
    unitTaxons: {
        component: (props) => {
            var _a;
            const _props = props.that.props;
            const unit = (_a = _props.formData) === null || _a === void 0 ? void 0 : _a[props.idx];
            const results = ((unit === null || unit === void 0 ? void 0 : unit.identifications) || []).reduce((result, identification, idx) => {
                const taxonFields = [
                    `/identifications/${idx}/taxonRank`,
                    `/identifications/${idx}/taxon`,
                    `/identifications/${idx}/author`
                ];
                const taxonString = taxonFields.reduce((res, field) => {
                    const formattedValue = (0, utils_1.formatValue)(Object.assign(Object.assign({}, _props), { schema: (0, utils_1.parseSchemaFromFormDataPointer)(_props.schema.items, field), uiSchema: (0, utils_1.parseUiSchemaFromFormDataPointer)(_props.uiSchema.items, field), formData: (0, utils_1.parseJSONPointer)(unit, field, !!"safely") }));
                    if (!(0, utils_1.isEmptyString)(formattedValue)) {
                        res.push(formattedValue);
                    }
                    return res;
                }, []).join(" ");
                if (!(0, utils_1.isEmptyString)(taxonString)) {
                    result.push(taxonString);
                }
                return result;
            }, []);
            return results.length > 0 ? React.createElement("span", { className: "text-muted" }, results.join(", ")) : null;
        }
    },
    uri: {
        component: (props) => {
            var _a, _b;
            const id = (_b = (_a = props.that.props.formData) === null || _a === void 0 ? void 0 : _a[props.idx]) === null || _b === void 0 ? void 0 : _b.id;
            if (!id) {
                return null;
            }
            return React.createElement("span", { className: "text-muted" },
                React.createElement("small", null, (0, utils_1.getLajiUri)(id)));
        }
    }
};
class AccordionHeader extends React.Component {
    constructor() {
        super(...arguments);
        this.onHeaderClick = () => {
            const { that, idx, canHaveUndefinedIdx = true } = this.props;
            const formatters = this.getFormatters();
            if (!canHaveUndefinedIdx) {
                return;
            }
            that.onActiveChange(idx);
            formatters.forEach(formatter => { formatter.onClick && formatter.onClick(that, idx); });
        };
        this.onMouseEnter = () => {
            this.getFormatters().forEach(formatter => {
                formatter.onMouseEnter && formatter.onMouseEnter(this.props.that, this.props.idx);
            });
        };
        this.onMouseLeave = () => {
            this.getFormatters().forEach(formatter => {
                formatter.onMouseLeave && formatter.onMouseLeave(this.props.that, this.props.idx);
            });
        };
        this.getFormatters = () => {
            const { that } = this.props;
            const { uiSchema, schema } = that.props;
            const formData = (that.props.formData || {})[this.props.idx];
            // try both headerFormatters & headerFormatter for backward compatibility. TODO: Remove in future.
            const options = (0, utils_1.getUiOptions)(uiSchema);
            let _headerFormatters = options.headerFormatters || options.headerFormatter || [];
            if (_headerFormatters && !Array.isArray(_headerFormatters))
                _headerFormatters = [_headerFormatters];
            if (options.headerFormatter) {
                console.warn("laji-form warning: 'headerFormatter' is deprecated. Use 'headerFormatters' instead.");
            }
            return _headerFormatters.map(formatter => {
                if (headerFormatters[formatter])
                    return headerFormatters[formatter];
                else
                    return {
                        component: () => {
                            const { field, default: _default } = (0, utils_1.isObject)(formatter) ? formatter : { field: formatter };
                            const formattedValue = (0, utils_1.formatValue)(Object.assign(Object.assign({}, that.props), { schema: (0, utils_1.parseSchemaFromFormDataPointer)(schema.items, field), uiSchema: (0, utils_1.parseUiSchemaFromFormDataPointer)(uiSchema.items, field), formData: (0, utils_1.parseJSONPointer)(formData, field, !!"safely") }));
                            const value = (0, utils_1.isEmptyString)(formattedValue) ? _default : formattedValue;
                            return React.createElement("span", { className: "text-muted" }, value);
                        }
                    };
            });
        };
        this.onHelpFocus = () => {
            this.setState({ focused: true });
        };
        this.onHelpBlur = () => {
            this.setState({ focused: false });
        };
        this.onHelpClick = (e) => {
            e.preventDefault();
        };
        this.onKeyDown = this.props.that.props.formContext.utils.keyboardClick(this.onHeaderClick);
    }
    render() {
        var _a;
        const { that, idx } = this.props;
        const title = (0, utils_1.getTitle)(that.props, idx);
        const popupData = (_a = that.state.popups) === null || _a === void 0 ? void 0 : _a[idx];
        const { uiSchema } = that.props;
        const hasHelp = uiSchema && uiSchema["ui:help"];
        const spanProps = hasHelp
            ? { "aria-describedby": `${that.props.idSchema.$id}_${idx}--help` }
            : {};
        const headerText = (React.createElement("span", Object.assign({}, spanProps),
            title,
            this.getFormatters().map((formatter, i) => {
                const { component: Formatter } = formatter;
                return Formatter && (React.createElement("span", { key: i },
                    " ",
                    React.createElement(Formatter, { that: that, idx: idx }))) || null;
            }),
            hasHelp &&
                React.createElement(React.Fragment, null,
                    React.createElement(components_1.Help, { focusable: true, onFocus: this.onHelpFocus, onBlur: this.onHelpBlur, onClick: this.onHelpClick, id: `${that.props.idSchema.$id}_{idx}` }),
                    React.createElement("div", { id: `${that.props.idSchema.$id}_${idx}--help`, style: { display: "none" } }, uiSchema["ui:help"]))));
        const { Tooltip } = this.context.theme;
        const tooltip = React.createElement(Tooltip, { id: `${that.props.idSchema.$id}_${idx}-help` }, uiSchema["ui:help"]);
        const headerTextComponent = hasHelp ? React.createElement(components_1.OverlayTrigger, { placement: "right", overlay: tooltip, show: this.state && this.state.focused || undefined }, headerText) : headerText;
        const header = (React.createElement("div", { className: this.props.className, role: "tab", id: `${that.props.idSchema.$id}_${(0, utils_1.getFormDataIndex)(idx, that.props.uiSchema)}-header`, onClick: this.onHeaderClick, onMouseEnter: this.onMouseEnter, onMouseLeave: this.onMouseLeave, onKeyDown: this.onKeyDown, tabIndex: "0" },
            React.createElement("div", { className: this.props.wrapperClassName },
                headerTextComponent,
                this.props.children)));
        return (0, utils_1.hasData)(popupData) ? (React.createElement(components_1.OverlayTrigger, { placement: "left", overlay: React.createElement(Tooltip, { id: "nav-tooltip-" + idx },
                React.createElement(Popup, { data: popupData })) }, header)) : (header);
    }
}
AccordionHeader.contextType = ReactContext_1.default;
AccordionHeader.state = { focused: false };
