import * as React from 'react'; import { MetadataApi } from '../data/metadataApi'; import { ElementModel, LinkModel, sameLink } from '../data/model'; import { EditorController } from '../editor/editorController'; import { DiagramView } from '../diagram/view'; import { LinkDirection } from '../diagram/elements'; import { Cancellation } from '../viewUtils/async'; import { ProgressBar, ProgressState } from '../widgets/progressBar'; import { LinkTypeSelector, LinkValue, validateLinkType } from './linkTypeSelector'; const CLASS_NAME = 'ontodia-edit-form'; export interface Props { editor: EditorController; view: DiagramView; metadataApi: MetadataApi | undefined; link: LinkModel; source: ElementModel; target: ElementModel; onChange: (entity: LinkModel) => void; onApply: (entity: LinkModel) => void; onCancel: () => void; } export interface State { linkValue?: LinkValue; isValidating?: boolean; } export class EditLinkForm extends React.Component { private validationCancellation = new Cancellation(); constructor(props: Props) { super(props); this.state = { linkValue: { value: {link: props.link, direction: LinkDirection.out}, validated: true, allowChange: true, }, }; } componentDidMount() { this.validate(); } componentDidUpdate(prevProps: Props, prevState: State) { const {linkValue} = this.state; if (!sameLink(linkValue.value.link, prevState.linkValue.value.link)) { this.validate(); } if (linkValue !== prevState.linkValue && linkValue.validated && linkValue.allowChange) { this.props.onChange(linkValue.value.link); } } componentWillUnmount() { this.validationCancellation.abort(); } private validate() { const {editor, link: originalLink} = this.props; const {linkValue: {value}} = this.state; this.setState({isValidating: true}); this.validationCancellation.abort(); this.validationCancellation = new Cancellation(); const signal = this.validationCancellation.signal; validateLinkType(editor, value.link, originalLink).then(error => { if (signal.aborted) { return; } this.setState(({linkValue}) => ({ linkValue: {...linkValue, ...error, validated: true}, isValidating: false, })); }); } render() { const {editor, view, metadataApi, source, target} = this.props; const {linkValue, isValidating} = this.state; const isValid = !linkValue.error; return (
this.setState({ linkValue: {value, error: undefined, validated: false, allowChange: false}, })} /> {isValidating ? (
) : null}
); } }