import * as fs from 'fs' ; import minimist from 'minimist' ; import { exit } from 'process' ; import { ArchiveUtils } from '../../webapp/src/blocks/archive' ; import { Block } from '../../webapp/src/blocks/block' ; import { IPropertyOption , IPropertyTemplate , createBoard } from '../../webapp/src/blocks/board' ; import { createBoardView } from '../../webapp/src/blocks/boardView' ; import { createCard } from '../../webapp/src/blocks/card' ; import { createTextBlock } from '../../webapp/src/blocks/textBlock' ; import { Asana , Workspace } from './asana' ; import { Utils } from './utils' ; ( global . window as any ) = { } ; const optionColors = [ 'propColorGray' , 'propColorBrown' , 'propColorOrange' , 'propColorYellow' , 'propColorGreen' , 'propColorBlue' , 'propColorPurple' , 'propColorPink' , 'propColorRed' , ] ; let optionColorIndex = 0 ; function main ( ) { const args = minimist ( process . argv . slice ( 2 ) ) ; const inputFile = args [ 'i' ] ; const outputFile = args [ 'o' ] || 'archive.focalboard' ; if ( ! inputFile ) { showHelp ( ) ; } if ( ! fs . existsSync ( inputFile ) ) { console . error ( `File not found: ${ inputFile }` ) ; exit ( 2 ) ; } const inputData = fs . readFileSync ( inputFile , 'utf-8' ) ; const input = JSON . parse ( inputData ) as Asana ; const blocks = convert ( input ) ; const outputData = ArchiveUtils . buildBlockArchive ( blocks ) ; fs . writeFileSync ( outputFile , outputData ) ; console . log ( `Exported to ${ outputFile }` ) ; } function getProjects ( input ) { const projectMap = new Map < string , Workspace > ( ) ; input . data . forEach ( datum => { datum . projects . forEach ( project => { if ( ! projectMap . get ( project . gid ) ) { projectMap . set ( project . gid , project ) ; } } ) ; } ) ; return [ ... projectMap . values ( ) ] ; } function getSections ( input , projectId ) { const sectionMap = new Map < string , Workspace > ( ) ; input . data . forEach ( datum => { const membership = datum . memberships . find ( o => o . project . gid === projectId ) ; if ( membership ) { if ( ! sectionMap . get ( membership . section . gid ) ) { sectionMap . set ( membership . section . gid , membership . section ) ; } } } ) ; return [ ... sectionMap . values ( ) ] ; } function convert ( input ) { const projects = getProjects ( input ) ; if ( projects . length < 1 ) { console . error ( 'No projects found' ) ; return [ ] ; } const project = projects [ 0 ] ; const blocks = [ ] ; const board = createBoard ( ) ; console . log ( `Board: ${ project . name }` ) ; board . rootId = board . id ; board . title = project . name ; const optionIdMap = new Map < string , string > ( ) ; const options = [ ] ; const sections = getSections ( input , project . gid ) ; sections . forEach ( section => { const optionId = Utils . createGuid ( ) ; optionIdMap . set ( section . gid , optionId ) ; const color = optionColors [ optionColorIndex % optionColors . length ] ; optionColorIndex += 1 ; const option = { id : optionId , value : section . name , color , } ; options . push ( option ) ; } ) ; const cardProperty = { id : Utils . createGuid ( ) , name : 'Section' , type : 'select' , options } ; board . fields . cardProperties = [ cardProperty ] ; blocks . push ( board ) ; const view = createBoardView ( ) ; view . title = 'Board View' ; view . fields . viewType = 'board' ; view . rootId = board . id ; view . parentId = board . id ; blocks . push ( view ) ; input . data . forEach ( card => { console . log ( `Card: ${ card . name }` ) ; const outCard = createCard ( ) ; outCard . title = card . name ; outCard . rootId = board . id ; outCard . parentId = board . id ; const membership = card . memberships . find ( o => o . project . gid === project . gid ) ; if ( membership ) { const optionId = optionIdMap . get ( membership . section . gid ) ; if ( optionId ) { outCard . fields . properties [ cardProperty . id ] = optionId ; } else { console . warn ( `Invalid idList: ${ membership . section . gid } for card: ${ card . name }` ) ; } } else { console . warn ( `Missing idList for card: ${ card . name }` ) ; } blocks . push ( outCard ) ; if ( card . notes ) { const text = createTextBlock ( ) ; text . title = card . notes ; text . rootId = board . id ; text . parentId = outCard . id ; blocks . push ( text ) ; outCard . fields . contentOrder = [ text . id ] ; } } ) ; console . log ( '' ) ; console . log ( `Found ${ input . data . length } card(s).` ) ; return blocks ; } function showHelp ( ) { console . log ( 'import -i <input.json> -o [output.focalboard]' ) ; exit ( 1 ) ; } main ( ) ;