@@ -11,30 +11,27 @@ import { ISettingRegistry } from '@jupyterlab/settingregistry';
11
11
import { runIcon } from '@jupyterlab/ui-components' ;
12
12
13
13
import { requestAPI } from './handler' ;
14
- import { METADATA_SQL_FORMAT , SqlWidget } from './widget' ;
14
+ import { CommandIDs , METADATA_SQL_FORMAT , SqlCell } from './common' ;
15
+ import { SqlWidget } from './widget' ;
15
16
16
17
/**
17
- * Initialization data for the @jupyter/sql- cell extension .
18
+ * Load the commands and the cell toolbar buttons (from settings) .
18
19
*/
19
20
const plugin : JupyterFrontEndPlugin < void > = {
20
21
id : '@jupyter/sql-cell:plugin' ,
21
- description : 'A JupyterLab extension to run SQL in notebook dedicated cells ' ,
22
+ description : 'Add the commands to the registry. ' ,
22
23
autoStart : true ,
23
- requires : [ INotebookTracker , IToolbarWidgetRegistry ] ,
24
- optional : [ ICommandPalette , IDefaultFileBrowser , ISettingRegistry ] ,
24
+ requires : [ INotebookTracker ] ,
25
+ optional : [ ICommandPalette , IDefaultFileBrowser ] ,
25
26
activate : (
26
27
app : JupyterFrontEnd ,
27
28
tracker : INotebookTracker ,
28
- toolbarRegistry : IToolbarWidgetRegistry ,
29
- commandPalette : ICommandPalette | null ,
30
- fileBrowser : IDefaultFileBrowser | null ,
31
- settingRegistry : ISettingRegistry | null
29
+ commandPalette : ICommandPalette ,
30
+ fileBrowser : IDefaultFileBrowser | null
32
31
) => {
33
32
const { commands } = app ;
34
33
35
- const commandID = 'jupyter-sql-cell:execute' ;
36
-
37
- commands . addCommand ( commandID , {
34
+ commands . addCommand ( CommandIDs . run , {
38
35
label : 'Run SQL' ,
39
36
caption : 'Run SQL' ,
40
37
icon : runIcon ,
@@ -53,7 +50,7 @@ const plugin: JupyterFrontEndPlugin<void> = {
53
50
body : JSON . stringify ( { query : source } )
54
51
} )
55
52
. then ( data => {
56
- saveData ( path , data . data , date , fileBrowser )
53
+ Private . saveData ( path , data . data , date , fileBrowser )
57
54
. then ( dataPath => console . log ( `Data saved ${ dataPath } ` ) )
58
55
. catch ( undefined ) ;
59
56
} )
@@ -63,20 +60,65 @@ const plugin: JupyterFrontEndPlugin<void> = {
63
60
) ;
64
61
} ) ;
65
62
} ,
66
- isEnabled : ( ) => {
63
+ isEnabled : ( ) => SqlCell . isSqlCell ( tracker . activeCell ?. model ) ,
64
+ isVisible : ( ) => SqlCell . isRaw ( tracker . activeCell ?. model )
65
+ } ) ;
66
+
67
+ commands . addCommand ( CommandIDs . switchSQL , {
68
+ label : 'SQL' ,
69
+ caption : ( ) => {
67
70
const model = tracker . activeCell ?. model ;
68
- if ( ! model ) {
69
- return false ;
71
+ return SqlCell . isRaw ( model )
72
+ ? SqlCell . isSqlCell ( model )
73
+ ? 'Switch to Raw'
74
+ : 'Switch to SQL'
75
+ : 'Not available' ;
76
+ } ,
77
+ execute : async ( ) => {
78
+ const model = tracker . activeCell ?. model ;
79
+ if ( ! model || model . type !== 'raw' ) {
80
+ return ;
70
81
}
71
- return (
72
- model . type === 'raw' &&
73
- model . getMetadata ( 'format' ) === METADATA_SQL_FORMAT
74
- ) ;
75
- }
82
+ if ( model . getMetadata ( 'format' ) !== METADATA_SQL_FORMAT ) {
83
+ model . setMetadata ( 'format' , METADATA_SQL_FORMAT ) ;
84
+ } else if ( model . getMetadata ( 'format' ) === METADATA_SQL_FORMAT ) {
85
+ model . deleteMetadata ( 'format' ) ;
86
+ }
87
+ app . commands . notifyCommandChanged ( CommandIDs . switchSQL ) ;
88
+ app . commands . notifyCommandChanged ( CommandIDs . run ) ;
89
+ } ,
90
+ isVisible : ( ) => SqlCell . isRaw ( tracker . activeCell ?. model ) ,
91
+ isToggled : ( ) => SqlCell . isSqlCell ( tracker . activeCell ?. model )
76
92
} ) ;
77
93
94
+ if ( commandPalette ) {
95
+ commandPalette . addItem ( {
96
+ command : CommandIDs . run ,
97
+ category : 'SQL'
98
+ } ) ;
99
+ }
100
+ }
101
+ } ;
102
+
103
+ /**
104
+ * The notebook toolbar widget.
105
+ */
106
+ const notebookToolbarWidget : JupyterFrontEndPlugin < void > = {
107
+ id : '@jupyter/sql-cell:notebook-toolbar' ,
108
+ description : 'A JupyterLab extension to run SQL in notebook dedicated cells' ,
109
+ autoStart : true ,
110
+ requires : [ INotebookTracker , IToolbarWidgetRegistry ] ,
111
+ optional : [ ISettingRegistry ] ,
112
+ activate : (
113
+ app : JupyterFrontEnd ,
114
+ tracker : INotebookTracker ,
115
+ toolbarRegistry : IToolbarWidgetRegistry ,
116
+ settingRegistry : ISettingRegistry | null
117
+ ) => {
118
+ const { commands } = app ;
119
+
78
120
const toolbarFactory = ( panel : NotebookPanel ) => {
79
- return new SqlWidget ( { commands, commandID, tracker } ) ;
121
+ return new SqlWidget ( { commands, commandID : CommandIDs . run , tracker } ) ;
80
122
} ;
81
123
82
124
toolbarRegistry . addFactory < NotebookPanel > (
@@ -87,7 +129,7 @@ const plugin: JupyterFrontEndPlugin<void> = {
87
129
88
130
if ( settingRegistry ) {
89
131
settingRegistry
90
- . load ( plugin . id )
132
+ . load ( notebookToolbarWidget . id )
91
133
. then ( settings => {
92
134
console . log ( '@jupyter/sql-cell settings loaded:' , settings . composite ) ;
93
135
} )
@@ -98,70 +140,65 @@ const plugin: JupyterFrontEndPlugin<void> = {
98
140
) ;
99
141
} ) ;
100
142
}
101
-
102
- if ( commandPalette ) {
103
- commandPalette . addItem ( {
104
- command : commandID ,
105
- category : 'SQL'
106
- } ) ;
107
- }
108
-
109
- console . log ( 'JupyterLab extension @jupyter/sql-cell is activated!' ) ;
110
143
}
111
144
} ;
112
145
113
- export default plugin ;
146
+ export default [ notebookToolbarWidget , plugin ] ;
147
+
148
+ namespace Private {
149
+ /**
150
+ * Save data in a CSV file.
151
+ *
152
+ * @param path - the path to the directory where to save data.
153
+ * @param data - the data to parse as CSV.
154
+ * @param date - the query date.
155
+ */
156
+ export async function saveData (
157
+ path : string ,
158
+ data : any ,
159
+ date : Date ,
160
+ fileBrowser : IDefaultFileBrowser | null
161
+ ) : Promise < string | undefined > {
162
+ const contentsManager = new ContentsManager ( ) ;
163
+ const parser = new Parser ( ) ;
164
+ const csv = parser . parse ( data ) ;
165
+
166
+ const dateText = date
167
+ . toLocaleString ( )
168
+ . replace ( / [ / : ] / g, '-' )
169
+ . replace ( / \s / g, '' )
170
+ . replace ( ',' , '_' ) ;
171
+
172
+ let currentPath = '' ;
173
+ if ( ! path . startsWith ( '/' ) ) {
174
+ currentPath = `${ fileBrowser ?. model . path } /` || '' ;
175
+ }
114
176
115
- /**
116
- * Save data in a CSV file.
117
- *
118
- * @param path - the path to the directory where to save data.
119
- * @param data - the data to parse as CSV.
120
- * @param date - the query date.
121
- */
122
- async function saveData (
123
- path : string ,
124
- data : any ,
125
- date : Date ,
126
- fileBrowser : IDefaultFileBrowser | null
127
- ) : Promise < string | undefined > {
128
- const contentsManager = new ContentsManager ( ) ;
129
- const parser = new Parser ( ) ;
130
- const csv = parser . parse ( data ) ;
131
-
132
- const dateText = date
133
- . toLocaleString ( )
134
- . replace ( / [ / : ] / g, '-' )
135
- . replace ( / \s / g, '' )
136
- . replace ( ',' , '_' ) ;
137
-
138
- let currentPath = '' ;
139
- if ( ! path . startsWith ( '/' ) ) {
140
- currentPath = `${ fileBrowser ?. model . path } /` || '' ;
141
- }
177
+ for ( const directory of path . split ( '/' ) ) {
178
+ currentPath = `${ currentPath } ${ directory } /` ;
179
+ await contentsManager
180
+ . get ( currentPath , { content : false } )
181
+ . catch ( error =>
182
+ contentsManager . save ( currentPath , { type : 'directory' } )
183
+ ) ;
184
+ }
142
185
143
- for ( const directory of path . split ( '/' ) ) {
144
- currentPath = `${ currentPath } ${ directory } /` ;
145
- await contentsManager
146
- . get ( currentPath , { content : false } )
147
- . catch ( ( ) => contentsManager . save ( currentPath , { type : 'directory' } ) ) ;
148
- }
186
+ const filename = `${ dateText } .csv` ;
187
+ const fileModel = {
188
+ name : filename ,
189
+ path : `${ currentPath } /${ filename } ` ,
190
+ format : 'text' as Contents . FileFormat ,
191
+ content : csv
192
+ } ;
149
193
150
- const filename = `${ dateText } .csv` ;
151
- const fileModel = {
152
- name : filename ,
153
- path : `${ currentPath } /${ filename } ` ,
154
- format : 'text' as Contents . FileFormat ,
155
- content : csv
156
- } ;
157
-
158
- return contentsManager
159
- . save ( fileModel . path , fileModel )
160
- . then ( ( ) => {
161
- return fileModel . path ;
162
- } )
163
- . catch ( e => {
164
- console . error ( e ) ;
165
- return undefined ;
166
- } ) ;
194
+ return contentsManager
195
+ . save ( fileModel . path , fileModel )
196
+ . then ( ( ) => {
197
+ return fileModel . path ;
198
+ } )
199
+ . catch ( e => {
200
+ console . error ( e ) ;
201
+ return undefined ;
202
+ } ) ;
203
+ }
167
204
}
0 commit comments