import _ from '../util' ; import store from '../store' ; import Layout from '../layout' ; import LDParse from '../ld_parse' ; import packageInfo from '../../package.json' ; interface PageSpan { start : number ; end : number ; } interface BookDivision { bookNumber : number ; pages : PageSpan ; steps : PageSpan ; } type FirstPageOptions = 'start_page_1' | 'preserve_page_count' ; type FileSplitOptions = 'separate_files' | 'one_file' ; export interface BookMutationInterface { add ( { bookNumber , pages } ) : Book ; delete ( ) : void ; setBookPageNumbers ( { book , firstPageNumber } ) : void ; splitFileByBook ( ) : void ; divideInstructions ( { bookDivisions , firstPageNumber , includeTitlePages , fileSplit } ) : void ; layout ( { book } ) : void ; } export const BookMutations = { add ( { bookNumber , pages } ) { const pageNumbers = _ . range ( pages . start , pages . end + 1 ) ; const pageList = pageNumbers . map ( pageNumber => { return store . get . itemByNumber ( 'page' , pageNumber ) ; } ) ; const parent = { id : - 1 , type : 'book' } ; const book = store . mutations . item . add < Book > ( { item : { type : 'book' , id : - 1 , parent , pages : [ ] , number : bookNumber , } , parent } ) ; pageList . forEach ( page => { if ( page != null ) { store . mutations . item . reparent ( { item : page , newParent : book , } ) ; } } ) ; return book ; } , delete ( ) { } , setBookPageNumbers ( { book , firstPageNumber } ) { const bookItem = store . get . book ( book ) ; if ( bookItem == null ) { throw 'Trying to set page numbers on non-existent Books' ; } if ( firstPageNumber === 'start_page_1' ) { const pages = bookItem . pages . map ( store . get . page ) ; store . mutations . renumber ( pages , 1 ) ; } else if ( firstPageNumber === 'preserve_page_count' ) { store . mutations . page . renumber ( ) ; } } , splitFileByBook ( ) { const modelName = store . get . modelFilenameBase ( ) ; const fn = modelName + '_instruction_books' ; const zip = new JSZip ( ) ; const fileFolder = zip . folder ( fn ) ; function addPartsFromPreviousSteps ( book ) { const visitedModels = new Set ( ) ; book . pages . map ( store . get . page ) . filter ( page => page . subtype === 'page' ) . map ( page => ( page || { } ) . steps ) . flat ( ) . map ( store . get . step ) . forEach ( step => { if ( step && ! visitedModels . has ( step . model . filename ) && step . parts ) { step . prevBookParts = store . get . partList ( step ) || [ ] ; visitedModels . add ( step . model . filename ) ; } } ) ; } function getStateForBook ( book ) { if ( book . id !== store . state . books [ 0 ] . id ) { addPartsFromPreviousSteps ( book ) ; } const originalState = _ . cloneDeep ( store . state ) ; const pagesToDelete = store . state . pages . filter ( page => { return page . parent != null && page . parent . id !== book . id && page . subtype !== 'templatePage' ; } ) ; pagesToDelete . forEach ( page => { store . mutations . page . delete ( { page , deleteSteps : true , doNotRenumber : true } ) ; } ) ; store . state . books = [ book ] ; return { originalState , newState : store . state } ; } const content = { partDictionary : LDParse . partDictionary , colorTable : LDParse . colorTable , modelFilename : store . model ?. filename , version : packageInfo . version , state : { } , } ; let firstBookState ; const books = _ . cloneDeep ( store . state . books ) ; books . forEach ( ( book , idx ) => { const res = getStateForBook ( book ) ; content . state = res . newState ; if ( idx === 0 ) { firstBookState = content . state ; } store . replaceState ( res . originalState ) ; const json = JSON . stringify ( content ) ; fileFolder . file ( `${ modelName }_book_${ book . number }.lic` , json ) ; } ) ; zip . generateAsync ( { type : 'blob' } ) . then ( ( zipContent ) => saveAs ( zipContent , fn + '.zip' ) ) ; store . replaceState ( firstBookState ) ; } , divideInstructions ( { bookDivisions , firstPageNumber , includeTitlePages , fileSplit , } ) { bookDivisions . forEach ( book => { store . mutations . book . add ( book ) ; } ) ; if ( includeTitlePages ) { store . mutations . titlePage . delete ( ) ; store . mutations . titlePage . add ( ) ; } bookDivisions . forEach ( bookDivision => { const book = store . get . itemByNumber ( 'book' , bookDivision . bookNumber ) ; if ( book != null ) { store . mutations . book . setBookPageNumbers ( { book , firstPageNumber } ) ; } } ) ; if ( fileSplit === 'separate_files' ) { store . mutations . book . splitFileByBook ( ) ; } } , layout ( { book } ) { const item = store . get . book ( book ) ; if ( item ) { Layout . book ( item ) ; } } , } ;