77import { icons , ns , utils , widgets } from 'solid-ui'
88import { store } from 'solid-logic'
99
10+ const TestCSVstring = 'A,B,C\n1,2,3\n4,5,6\nfoo,bar,baz\n'
11+
1012export function quoteString ( value ) {
1113 // https://www.rfc-editor.org/rfc/rfc4180
12- const stripped = value . replace ( '\n' , ' ' )
14+ const stripped = value . replaceAll ( '\n' , ' ' )
1315 if ( ! stripped . includes ( ',' ) ) {
1416 return stripped
1517 } // If contains comma then put in quotes and double up internal quotes
16- return '"' + stripped . replace ( '"' , '""' ) + '"'
18+ const quoted = '"' + stripped . replaceAll ( '"' , '""' ) + '"'
19+ console . log ( 'Quoted: >>>' + quoted + '<<<' )
20+ const check = quoted . slice ( 1 , - 1 ) . replaceAll ( '""' , '' )
21+ if ( check . includes ( '"' ) ) throw new Error ( 'CSV inconsistecy' )
22+ return quoted
1723}
1824
1925export function csvText ( store , tracker ) {
@@ -22,11 +28,12 @@ export function csvText(store, tracker) {
2228 let thing
2329 if ( column . predicate ) {
2430 thing = store . any ( task , column . predicate )
31+ return thing ? thing . value : '--'
2532 }
2633 else if ( column . category ) {
2734 const types = store . each ( task , ns . rdf ( 'type' ) )
2835 for ( const t of types ) {
29- console . log ( '@@ checking subclass type: ' , t , ' category: ' , column . category )
36+ // console.log('@@ checking subclass type: ', t, ' category: ', column.category )
3037 if ( store . holds ( t , ns . rdfs ( 'subClassOf' ) , column . category ) ) {
3138 thing = t
3239 }
@@ -43,37 +50,49 @@ export function csvText(store, tracker) {
4350 return columns . map ( column => columnText ( task , column ) )
4451 . map ( quoteString )
4552 . join ( ',' )
46- + '/ n'
53+ + '\ n'
4754 }
4855 const stateStore = store . any ( tracker , ns . wf ( 'stateStore' ) )
4956 const tasks = store . each ( null , ns . wf ( 'tracker' ) , tracker , stateStore )
57+ console . log ( ' CSV: Tasks:' , tasks . length )
58+
59+ const columns = [
60+
61+ { label : 'Name' , predicate : ns . dc ( 'title' ) } ,
62+ /* { label: 'Description', predicate: ns.wf('description') }, */
5063
51- let columns = [
52- /* like:
53- { label: 'Name', predicate: ns.dct('title') },
54- { label: 'State', category: ns.wf('Task') }
64+ /* { label: 'State', category: ns.wf('Task') }
5565 */
5666]
5767 const states = store . any ( tracker , ns . wf ( 'issueClass' ) ) // Main states are subclasses of this class
5868 console . log ( ' CSV: States - main superclass:' , states )
69+ const stateColumn = { label : 'State' , category : states } // better than 'task'
70+ console . log ( ' CSV: found column from state' , stateColumn )
71+ columns . push ( stateColumn )
5972
6073 const categories = store . each ( tracker , ns . wf ( 'issueCategory' ) )
6174 console . log ( ' CSV: Categories : ' , categories )
6275 console . log ( ' CSV: Categories : length: ' , categories . length )
6376 console . log ( ' CSV: Categories : first: ' , categories [ 0 ] )
6477
65- const classifications = [ states ] . concat ( categories )
78+ const classifications = categories
6679 for ( const c of classifications ) {
6780 const column = { label : utils . label ( c ) , category : c }
6881 console . log ( ' CSV: found column from classifications' , column )
6982 columns . push ( column ) // Classes are different
7083 }
7184
7285 // const propertyList = ns.wf('propertyList')
73- const form = store . any ( tracker , ns . wf ( 'extrasEntryForm' ) , null , tracker . doc ( ) )
86+ const form = store . any ( tracker , ns . wf ( 'extrasEntryForm' ) , null , null )
87+ console . log ( ' CSV: Form : ' , form )
88+
7489 if ( form ) {
7590 const parts = store . any ( form , ns . ui ( 'parts' ) , null , form . doc ( ) )
91+ console . log ( ' CSV: parts : ' , parts )
92+
7693 const fields = parts . elements
94+ console . log ( ' CSV: fields : ' , fields )
95+
7796 for ( const field of fields ) {
7897 const prop = store . any ( field , ns . ui ( 'property' ) )
7998 const lab = utils . label ( prop )
@@ -82,23 +101,49 @@ export function csvText(store, tracker) {
82101 columns . push ( column )
83102 }
84103 }
104+ // Put description on the end as it can be long
105+ columns . push ( { label : 'Description' , predicate : ns . wf ( 'description' ) } )
106+ console . log ( 'Columns: ' , columns . length )
85107 const header = columns . map ( col => col . label ) . join ( ',' ) + '\n'
108+ console . log ( 'CSV: Header= ' , header )
86109 // Order tasks?? By Creation date? By Status?
87- const body = tasks . map ( taskLine )
110+ const body = tasks . map ( taskLine ) . join ( '' )
88111 return header + body
89112}
90113
91114export function csvButton ( dom , tracker ) {
92115 const wrapper = dom . createElement ( 'div' )
93116 // Add a button
94- const button = widgets . button ( dom , icons . iconBase + 'noun_479395.svg' ,
95- 'Copy as CSV' , async _event => {
96- const csv = csvText ( store , tracker )
117+ const button = widgets . button ( dom , icons . iconBase + 'noun_Document_998605.svg' ,
118+ 'Copy as CSV' , async event => {
119+
120+ const div = button . parentNode . parentNode
121+ console . log ( 'button gparent div' , div )
122+ div . addEventListener ( 'copy' , event => {
123+ alert ( 'Copy caught' ) ;
124+ const csv = csvText ( store , tracker ) ;
125+ const csv1 = TestCSVstring
126+ event . clipboardData . setData ( "text/plain" , csv ) ;
127+ event . clipboardData . setData ( "text/csv" , csv ) ;
128+ alert ( 'Copy data: ' + csv )
129+ event . preventDefault ( ) ;
130+ } )
131+
97132 var copyEvent = new ClipboardEvent ( 'copy' ) ;
98- copyEvent . clipboardData . items . add ( csv , 'text/csv' ) ;
99- copyEvent . clipboardData . items . add ( csv , 'text/plain' ) ;
100- dom . dispatchEvent ( copyEvent ) ;
101- alert ( 'Copy dispatched.' )
133+ if ( ! copyEvent ) {
134+ alert ( 'CSV: Copy event failed.' )
135+ } else if ( ! copyEvent . clipboardData ) {
136+ alert ( 'CSV: Copy event no clipboardData' )
137+ } else {
138+ copyEvent . clipboardData . items . add ( csv , 'text/csv' ) ;
139+ copyEvent . clipboardData . items . add ( csv , 'text/plain' ) ;
140+ dom . dispatchEvent ( copyEvent ) ;
141+ alert ( 'Copy dispatched.' )
142+ // https://developer.mozilla.org/en-US/docs/Web/API/Element/copy_event
143+ // t's possible to construct and dispatch a synthetic copy event,
144+ // but this will not affect the system clipboard.
145+ }
146+ event . preventDefault ( )
102147 } )
103148
104149 wrapper . appendChild ( button )
0 commit comments