tracking-code-which-will-go-to-the-HEAD draw/action/LinkAction.js

Source

draw/action/LinkAction.js

import Action from './Action';
import ComponentLink from '../../models/ComponentLink';

/**
 * Action to link component to another.
 */
class LinkAction extends Action {
  /**
   * Default constructor.
   * @param {DefaultData} pluginData - Plugin data storage.
   * @param {object} viewport - D3 selection of the view port.
   * @param {DefaultLayout} layout - Layout to organise components.
   */
  constructor(pluginData, viewport, layout) {
    super(pluginData, viewport, layout);

    /**
     * Whether the action is initialized or not.
     * @type {boolean}
     */
    this.isInit = false;
    /**
     * Stored link for finalize.
     * @type {null}
     */
    this.link = null;
  }

  /**
   * Draw temporary link and store link for finalize.
   * @param {object} event - The event containing the target information.
   * @returns {boolean} Need to draw to display temporary link.
   */
  execute(event) {
    if (!this.isInit) {
      this.isInit = true;
      const sourceId = event.subject.datum().data.id;
      const source = this.pluginData.getComponentById(sourceId);

      this.viewport.style('cursor', 'grabbing');
      const anchorName = event.sourceEvent.target.closest('.anchor').attributes.name.value;

      this.pluginData.components
        .filter(({ definition }) => !this.pluginData.canBeLinked(
          source.definition.type,
          definition.type,
        ))
        .forEach((component) => {
          this.viewport.select(`.${component.id}.component .canBeHidden`)
            .classed('hide', true);
        });

      this.pluginData.createTemporaryLink(sourceId, anchorName);
      this.link = new ComponentLink({
        source: sourceId,
      });
    }

    this.pluginData.temporaryLink.endX = event.sourceEvent.clientX;
    this.pluginData.temporaryLink.endY = event.sourceEvent.clientY;

    return false;
  }

  /**
   * If target can be linked to source, create link otherwise delete and clear temporary link.
   * @param {object} event - The event containing the target information.
   * @returns {boolean} Need to draw to remove temporary link.
   */
  finalize(event) {
    this.isInit = false;
    this.pluginData.temporaryLink = null;
    this.viewport.style('cursor', null);
    const source = this.pluginData.getComponentById(event.subject.datum().data.id);
    const target = this.pluginData.getComponentById(this.getTargetId(event));
    const definition = this.pluginData.definitions.links
      .find(({ sourceRef, targetRef }) => source.definition.type === sourceRef
        && target?.definition.type === targetRef);

    if (target && definition) {
      source.setLinkAttribute(new ComponentLink({
        source: source.id,
        target: target.id,
        definition,
      }));

      this.pluginData.emitEvent({
        components: [source.id],
        type: 'Drawer',
        action: 'update',
        status: 'success',
      });
    }

    return true;
  }
}

export default LinkAction;