import { ElementModel , ElementIri , LinkModel , sameLink } from '../data/model' ; import { Element , Link , FatLinkType , Cell , LinkVertex } from './elements' ; import { Vector , isPolylineEqual } from './geometry' ; import { Command } from './history' ; import { DiagramModel } from './model' ; export class RestoreGeometry implements Command { readonly title = 'Move elements and links' ; constructor ( private elementState , private linkState ) { } static capture ( model ) { return RestoreGeometry . captureElementsAndLinks ( model . elements , model . links ) ; } private static captureElementsAndLinks ( elements , links ) { return new RestoreGeometry ( elements . map ( ( element ) => ( { element , position : element . position } ) ) , links . map ( ( link ) => ( { link , vertices : link . vertices } ) ) ) ; } hasChanges ( ) { return this . elementState . length > 0 || this . linkState . length > 0 ; } filterOutUnchanged ( ) { return new RestoreGeometry ( this . elementState . filter ( ( { element , position } ) => ! Vector . equals ( element . position , position ) ) , this . linkState . filter ( ( { link , vertices } ) => ! isPolylineEqual ( link . vertices , vertices ) ) ) ; } invoke ( ) { const previous = RestoreGeometry . captureElementsAndLinks ( this . elementState . map ( ( state ) => state . element ) , this . linkState . map ( ( state ) => state . link ) ) ; for ( const { element , position } of [ ... this . elementState ] . reverse ( ) ) { element . setPosition ( position ) ; } for ( const { link , vertices } of this . linkState ) { link . setVertices ( vertices ) ; } return previous ; } } export function restoreCapturedLinkGeometry ( link ) { const vertices = link . vertices ; return Command . create ( 'Change link vertices' , ( ) => { const capturedInverse = restoreCapturedLinkGeometry ( link ) ; link . setVertices ( vertices ) ; return capturedInverse ; } ) ; } export function setElementExpanded ( element , expanded ) { const title = expanded ? 'Expand element' : 'Collapse element' ; return Command . create ( title , ( ) => { element . setExpanded ( expanded ) ; return setElementExpanded ( element , ! expanded ) ; } ) ; } export function changeLinkTypeVisibility ( params ) { const { linkType , visible , showLabel , preventLoading } = params ; return Command . create ( 'Change link type visibility' , ( ) => { const previousVisible = linkType . visible ; const previousShowLabel = linkType . showLabel ; linkType . setVisibility ( { visible , showLabel , preventLoading } ) ; return changeLinkTypeVisibility ( { linkType , visible : previousVisible , showLabel : previousShowLabel , preventLoading , } ) ; } ) ; } export function setElementData ( model , target , data ) { const elements = model . elements . filter ( ( el ) => el . iri === target ) ; const previous = elements . length > 0 ? elements [ 0 ] . data : undefined ; return Command . create ( 'Set element data' , ( ) => { for ( const element of model . elements . filter ( ( el ) => el . iri === target ) ) { element . setData ( data ) ; } return setElementData ( model , data . id , previous ) ; } ) ; } export function setLinkData ( model , oldData , newData ) { if ( ! sameLink ( oldData , newData ) ) { throw new Error ( 'Cannot change typeId, sourceId or targetId when changing link data' ) ; } return Command . create ( 'Set link data' , ( ) => { for ( const link of model . links ) { if ( sameLink ( link . data , oldData ) ) { link . setData ( newData ) ; } } return setLinkData ( model , newData , oldData ) ; } ) ; }