import React, { useState, useEffect, useCallback } from "react"; import { Form, Button, Table } from "react-bootstrap"; import { Icon } from "src/components/Shared"; import * as GQL from "src/core/generated-graphql"; import { FormattedMessage, useIntl } from "react-intl"; import { multiValueSceneFields, SceneField, sceneFields } from "./constants"; import { ThreeStateBoolean } from "./ThreeStateBoolean"; interface IFieldOptionsEditor { options: GQL.IdentifyFieldOptions | undefined; field: string; editField: () => void; editOptions: (o?: GQL.IdentifyFieldOptions | null) => void; editing: boolean; allowSetDefault: boolean; defaultOptions?: GQL.IdentifyMetadataOptionsInput; } interface IFieldOptions { field: string; strategy: GQL.IdentifyFieldStrategy | undefined; createMissing?: GQL.Maybe | undefined; } const FieldOptionsEditor: React.FC = ({ options, field, editField, editOptions, editing, allowSetDefault, defaultOptions, }) => { const intl = useIntl(); const [localOptions, setLocalOptions] = useState(); const resetOptions = useCallback(() => { let toSet: IFieldOptions; if (!options) { // unset - use default values toSet = { field, strategy: undefined, createMissing: undefined, }; } else { toSet = { field, strategy: options.strategy, createMissing: options.createMissing, }; } setLocalOptions(toSet); }, [options, field]); useEffect(() => { resetOptions(); }, [resetOptions]); function renderField() { return intl.formatMessage({ id: field }); } function renderStrategy() { if (!localOptions) { return; } const strategies = Object.entries(GQL.IdentifyFieldStrategy); let { strategy } = localOptions; if (strategy === undefined) { if (!allowSetDefault) { strategy = GQL.IdentifyFieldStrategy.Merge; } } if (!editing) { if (strategy === undefined) { return intl.formatMessage({ id: "actions.use_default" }); } const f = strategies.find((s) => s[1] === strategy); return intl.formatMessage({ id: `actions.${f![0].toLowerCase()}`, }); } if (!localOptions) { return <>; } return ( {allowSetDefault ? ( setLocalOptions({ ...localOptions, strategy: undefined, }) } disabled={!editing} label={intl.formatMessage({ id: "actions.use_default" })} /> ) : undefined} {strategies.map((f) => ( setLocalOptions({ ...localOptions, strategy: f[1], }) } disabled={!editing} label={intl.formatMessage({ id: `actions.${f[0].toLowerCase()}`, })} /> ))} ); } function maybeRenderCreateMissing() { if (!localOptions) { return; } if ( multiValueSceneFields.includes(localOptions.field as SceneField) && localOptions.strategy !== GQL.IdentifyFieldStrategy.Ignore ) { const value = localOptions.createMissing === null ? undefined : localOptions.createMissing; if (!editing) { if (value === undefined && allowSetDefault) { return intl.formatMessage({ id: "actions.use_default" }); } if (value) { return ; } return ; } const defaultVal = defaultOptions?.fieldOptions?.find( (f) => f.field === localOptions.field )?.createMissing; if (localOptions.strategy === undefined) { return; } return ( setLocalOptions({ ...localOptions, createMissing: v }) } defaultValue={defaultVal ?? undefined} /> ); } } function onEditOptions() { if (!localOptions) { return; } // send null if strategy is undefined if (localOptions.strategy === undefined) { editOptions(null); resetOptions(); } else { let { createMissing } = localOptions; if (createMissing === undefined && !allowSetDefault) { createMissing = false; } editOptions({ ...localOptions, strategy: localOptions.strategy, createMissing, }); } } return ( {renderField()} {renderStrategy()} {maybeRenderCreateMissing()} {editing ? ( <> ) : ( <> )} ); }; interface IFieldOptionsList { fieldOptions?: GQL.IdentifyFieldOptions[]; setFieldOptions: (o: GQL.IdentifyFieldOptions[]) => void; setEditingField: (v: boolean) => void; allowSetDefault?: boolean; defaultOptions?: GQL.IdentifyMetadataOptionsInput; } export const FieldOptionsList: React.FC = ({ fieldOptions, setFieldOptions, setEditingField, allowSetDefault = true, defaultOptions, }) => { const [localFieldOptions, setLocalFieldOptions] = useState< GQL.IdentifyFieldOptions[] >(); const [editField, setEditField] = useState(); useEffect(() => { if (fieldOptions) { setLocalFieldOptions([...fieldOptions]); } else { setLocalFieldOptions([]); } }, [fieldOptions]); function handleEditOptions(o?: GQL.IdentifyFieldOptions | null) { if (!localFieldOptions) { return; } if (o !== undefined) { const newOptions = [...localFieldOptions]; const index = newOptions.findIndex( (option) => option.field === editField ); if (index !== -1) { // if null, then we're removing if (o === null) { newOptions.splice(index, 1); } else { // replace in list newOptions.splice(index, 1, o); } } else if (o !== null) { // don't add if null newOptions.push(o); } setFieldOptions(newOptions); } setEditField(undefined); setEditingField(false); } function onEditField(field: string) { setEditField(field); setEditingField(true); } if (!localFieldOptions) { return <>; } return (
{/* eslint-disable-next-line jsx-a11y/control-has-associated-label */} {sceneFields.map((f) => ( o.field === f)} editField={() => onEditField(f)} editOptions={handleEditOptions} editing={f === editField} defaultOptions={defaultOptions} /> ))}
); };