@@ -88,7 +88,7 @@ const extractPDF = async function (base64String) {
8888 const allTextPromises = [ ]
8989
9090 for ( let pageNumber = 1 ; pageNumber <= totalPages ; pageNumber ++ ) {
91- let pageTextPromise = pdf . getPage ( pageNumber ) . then ( function ( page ) {
91+ const pageTextPromise = pdf . getPage ( pageNumber ) . then ( function ( page ) {
9292 return page . getTextContent ( )
9393 } ) . then ( function ( textContent ) {
9494 return textContent . items . map ( item => item . str ) . join ( ' ' )
@@ -98,13 +98,16 @@ const extractPDF = async function (base64String) {
9898 }
9999
100100 const allTexts = await Promise . all ( allTextPromises )
101- const allText = allTexts . join ( ' ' )
101+ const allText = allTexts . join ( '\n ' )
102102
103103 return allText
104104}
105105
106106window . dash_clientside . bulk_essay_feedback = {
107- send_to_loconnection : async function ( state , hash , clicks , query , systemPrompt , rubricText ) {
107+ /**
108+ * Sends data to server via websocket
109+ */
110+ send_to_loconnection : async function ( state , hash , clicks , query , systemPrompt , tags ) {
108111 if ( state === undefined ) {
109112 return window . dash_clientside . no_update
110113 }
@@ -120,7 +123,7 @@ window.dash_clientside.bulk_essay_feedback = {
120123 if ( trig . prop_id . includes ( 'bulk-essay-analysis-submit-btn' ) ) {
121124 decoded . gpt_prompt = query
122125 decoded . system_prompt = systemPrompt
123- decoded . rubric = rubricText
126+ decoded . tags = tags
124127 }
125128
126129 const message = {
@@ -135,12 +138,19 @@ window.dash_clientside.bulk_essay_feedback = {
135138 return window . dash_clientside . no_update
136139 } ,
137140
141+ /**
142+ * adds submitted query to history and clear input
143+ */
138144 update_input_history_on_query_submission : async function ( clicks , query , history ) {
139145 if ( clicks > 0 ) {
140146 return [ '' , history . concat ( query ) ]
141147 }
148+ return [ query , window . dash_clientside . no_update ]
142149 } ,
143150
151+ /**
152+ * update history based on history browser storage
153+ */
144154 update_history_list : function ( history ) {
145155 const items = history . map ( ( x ) => {
146156 return {
@@ -156,6 +166,9 @@ window.dash_clientside.bulk_essay_feedback = {
156166 }
157167 } ,
158168
169+ /**
170+ * update student cards based on new data in storage
171+ */
159172 update_student_grid : function ( message , history ) {
160173 const currPrompt = history . length > 0 ? history [ history . length - 1 ] : ''
161174 const cards = message . map ( ( x ) => {
@@ -164,14 +177,96 @@ window.dash_clientside.bulk_essay_feedback = {
164177 return cards
165178 } ,
166179
167- update_rubric : async function ( contents , filename ) {
180+ /**
181+ * show attachment panel upon uploading document and populate fields
182+ */
183+ open_and_populate_attachment_panel : async function ( contents , filename , timestamp , shown ) {
168184 if ( filename === undefined ) {
169- return [ '' , '' ]
185+ return [ '' , '' , shown ]
170186 }
171187 let data = ''
172188 if ( filename . endsWith ( '.pdf' ) ) {
173189 data = await extractPDF ( contents )
174190 }
175- return [ data , `Current: ${ filename } ` ]
191+ // TODO add support for docx-like files
192+ return [ data , filename . slice ( 0 , filename . lastIndexOf ( '.' ) ) , shown . concat ( 'attachment' ) ]
193+ } ,
194+
195+ /**
196+ * append tag in curly braces to input
197+ */
198+ add_tag_to_input : function ( clicks , curr , store ) {
199+ const trig = window . dash_clientside . callback_context . triggered [ 0 ]
200+ const trigProp = trig . prop_id
201+ const trigJSON = JSON . parse ( trigProp . slice ( 0 , trigProp . lastIndexOf ( '.' ) ) )
202+ if ( trig . value > 0 ) {
203+ return curr . concat ( ` {${ trigJSON . index } }` )
204+ }
205+ return window . dash_clientside . no_update
206+ } ,
207+
208+ /**
209+ * enable/disabled submit based on query
210+ * makes sure there is a query and the tags are properly formatted
211+ */
212+ disabled_query_submit : function ( query , store ) {
213+ if ( query . length === 0 ) {
214+ return [ true , 'Please create a request before submitting.' ]
215+ }
216+ const tags = Object . keys ( store )
217+ const queryTags = query . match ( / [ ^ { } ] + (? = } ) / g) || [ ]
218+ const diffs = queryTags . filter ( x => ! tags . includes ( x ) )
219+ if ( diffs . length > 0 ) {
220+ return [ true , `Unable to find [${ diffs . join ( ',' ) } ] within the tags. Please check that the spelling is correct or remove the extra tags.` ]
221+ } else if ( ! queryTags . includes ( 'student_text' ) ) {
222+ return [ true , 'Submission requires the inclusion of {student_text} to run the request over the student essays.' ]
223+ }
224+ return [ false , '' ]
225+ } ,
226+
227+ /**
228+ * enable/disable the save attachment button if tag is already in use/blank
229+ */
230+ disable_attachment_save_button : function ( label , tags ) {
231+ if ( label . length === 0 ) {
232+ return [ true , 'Please add a unique label to your attachment' ]
233+ } else if ( tags . includes ( label ) ) {
234+ return [ true , `Label ${ label } is already in use.` ]
235+ }
236+ return [ false , '' ]
237+ } ,
238+
239+ /**
240+ * populate word bank of tags
241+ */
242+ update_tag_buttons : function ( tagStore ) {
243+ const tagLabels = Object . keys ( tagStore )
244+ const tags = tagLabels . map ( ( val ) => {
245+ const button = {
246+ namespace : 'dash_bootstrap_components' ,
247+ type : 'Button' ,
248+ props : {
249+ children : val ,
250+ id : { type : 'bulk-essay-analysis-tag' , index : val } ,
251+ n_clicks : 0 ,
252+ size : 'sm' ,
253+ color : 'secondary'
254+ }
255+ }
256+ return button
257+ } )
258+ return tags
259+ } ,
260+
261+ /**
262+ * Save attachment to tag storage
263+ */
264+ save_attachment : function ( clicks , label , text , tagStore , shown ) {
265+ if ( clicks > 0 ) {
266+ const newStore = tagStore
267+ newStore [ label ] = text
268+ return [ newStore , shown . filter ( item => item !== 'attachment' ) ]
269+ }
270+ return tagStore
176271 }
177272}
0 commit comments