@atlaskit/editor-plugin-extension
Version:
editor-plugin-extension plugin for @atlaskit/editor-core
149 lines (146 loc) • 5.11 kB
JavaScript
import _extends from "@babel/runtime/helpers/extends";
import React, { useEffect, useState } from 'react';
import { injectIntl } from 'react-intl';
import { getCustomFieldResolver, configPanelMessages as messages } from '@atlaskit/editor-common/extensions';
import { Field } from '@atlaskit/form';
import { AsyncCreatableSelect } from '@atlaskit/select';
import FieldMessages from '../FieldMessages';
import { validate } from '../utils';
import { formatOptionLabel } from './SelectItem';
import UnhandledType from './UnhandledType';
function FieldError({
name,
field
}) {
const {
type
} = field.options.resolver;
return /*#__PURE__*/React.createElement(UnhandledType, {
key: name,
field: field,
errorMessage: `Field "${name}" can't be rendered. Missing resolver for "${type}".`
});
}
function CustomSelect({
name,
autoFocus,
extensionManifest,
placeholder,
field,
onFieldChange,
parameters,
intl
}) {
const {
defaultValue: fieldDefaultValue,
description,
isMultiple,
isRequired,
label,
options,
isDisabled
} = field;
const [loading, setLoading] = useState(true);
const [resolver, setResolver] = useState(null);
const [defaultOptions, setDefaultOptions] = useState([]);
const [defaultValue, setDefaultValue] = useState(undefined);
useEffect(() => {
let cancel = false;
async function fetchResolver() {
setLoading(true);
try {
const resolver = getCustomFieldResolver(extensionManifest, field.options.resolver);
if (cancel) {
return;
}
setResolver(() => resolver);
// fetch the default values
const options = await resolver(undefined, fieldDefaultValue, parameters);
setDefaultOptions(options);
if (cancel) {
return;
}
// filter returned values to match the defaultValue
if (fieldDefaultValue && isMultiple) {
setDefaultValue(options.filter(option => fieldDefaultValue.includes(option.value)));
}
if (fieldDefaultValue && !isMultiple) {
setDefaultValue(options.find(option => fieldDefaultValue === option.value));
}
} catch (e) {
// eslint-disable-next-line no-console
console.error(e);
}
setLoading(false);
}
fetchResolver();
return () => {
cancel = true;
};
}, [extensionManifest, field.options.resolver, fieldDefaultValue, isMultiple, parameters]);
function formatCreateLabel(value) {
if (!value) {
return null;
}
const message = intl.formatMessage(messages.createOption);
return `${message} "${value}"`;
}
const {
isCreatable,
formatCreateLabel: customFormatCreateLabel
} = options;
return /*#__PURE__*/React.createElement(Field, {
name: name,
label: label,
isRequired: isRequired,
defaultValue: defaultValue
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
,
validate: value => validate(field, value),
testId: `config-panel-custom-select-${name}`,
isDisabled: isDisabled
}, ({
fieldProps,
error
}) => /*#__PURE__*/React.createElement(React.Fragment, null, resolver && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(AsyncCreatableSelect
// Ignored via go/ees005
// eslint-disable-next-line react/jsx-props-no-spreading
, _extends({}, fieldProps, {
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
onChange: value => {
fieldProps.onChange(value);
// We assume onChange is called whenever values actually changed
// for isDirty
onFieldChange(name, true);
}
// add type cast to avoid adding a "IsMulti" generic prop (TODO: ED-12072)
,
isMulti: isMultiple || false,
isClearable: true
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
,
isValidNewOption: value => !!(isCreatable && value),
validationState: error ? 'error' : 'default',
defaultOptions: defaultOptions
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
,
formatCreateLabel: value => customFormatCreateLabel ? customFormatCreateLabel(value) : formatCreateLabel(value),
formatOptionLabel: formatOptionLabel
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
,
loadOptions: searchTerm => {
return resolver(searchTerm, fieldDefaultValue, parameters);
},
autoFocus: autoFocus,
placeholder: placeholder
})), /*#__PURE__*/React.createElement(FieldMessages, {
error: error,
description: description
})), !loading && !resolver && /*#__PURE__*/React.createElement(FieldError, {
name: name,
field: field
})));
}
// eslint-disable-next-line @typescript-eslint/ban-types
const _default_1 = injectIntl(CustomSelect);
export default _default_1;