@@ -372,112 +372,126 @@ def generate_qualtrics_qsf(data):
372372 "QuestionID" : q_eval_id
373373 }
374374 })
375+
376+ # Add overall progress question for this project
377+ q_progress_id = f"QID{ qid_counter } "
378+ qid_counter += 1
379+ lab_block ["BlockElements" ].append ({"Type" : "Question" , "QuestionID" : q_progress_id })
380+
381+ questions .append ({
382+ "SurveyID" : survey_id ,
383+ "Element" : "SQ" ,
384+ "PrimaryAttribute" : q_progress_id ,
385+ "SecondaryAttribute" : f"How do you evaluate the team's overall progress toward publication in { project_name } ?" ,
386+ "TertiaryAttribute" : None ,
387+ "Payload" : {
388+ "QuestionText" : f"How do you evaluate the team's overall progress toward publication in { lab_name } Lab - { project_name } Project?" ,
389+ "DataExportTag" : f"Q_{ lab_name } _{ project_name } _Progress" ,
390+ "QuestionID" : q_progress_id ,
391+ "QuestionType" : "MC" ,
392+ "Selector" : "SAHR" ,
393+ "SubSelector" : "TX" ,
394+ "Configuration" : {
395+ "QuestionDescriptionOption" : "SpecifyLabel" ,
396+ "TextPosition" : "inline" ,
397+ "LabelPosition" : "BELOW"
398+ },
399+ "QuestionDescription" : f"How do you evaluate the team's overall progress toward publication in { project_name } ?" ,
400+ "Choices" : {
401+ "1" : {"Display" : "On Track" },
402+ "2" : {"Display" : "Needs Improvement" },
403+ "3" : {"Display" : "Blocked" }
404+ },
405+ "ChoiceOrder" : [1 , "2" , "3" ],
406+ "Validation" : {
407+ "Settings" : {
408+ "ForceResponse" : "ON" ,
409+ "ForceResponseType" : "ON" ,
410+ "Type" : "None"
411+ }
412+ },
413+ "DisplayLogic" : {
414+ "0" : {
415+ "0" : {
416+ "LogicType" : "Question" ,
417+ "QuestionID" : q_proj_id ,
418+ "QuestionIsInLoop" : "no" ,
419+ "ChoiceLocator" : f"q://{ q_proj_id } /SelectableChoice/{ proj_idx } " ,
420+ "Operator" : "Selected" ,
421+ "QuestionIDFromLocator" : q_proj_id ,
422+ "LeftOperand" : f"q://{ q_proj_id } /SelectableChoice/{ proj_idx } " ,
423+ "Type" : "Expression"
424+ },
425+ "Type" : "If"
426+ },
427+ "Type" : "BooleanExpression" ,
428+ "inPage" : False
429+ },
430+ "GradingData" : [],
431+ "Language" : [],
432+ "NextChoiceId" : 4 ,
433+ "NextAnswerId" : 4
434+ }
435+ })
436+
437+ # Add comments question for this project
438+ q_comments_id = f"QID{ qid_counter } "
439+ qid_counter += 1
440+ lab_block ["BlockElements" ].append ({"Type" : "Question" , "QuestionID" : q_comments_id })
441+
442+ questions .append ({
443+ "SurveyID" : survey_id ,
444+ "Element" : "SQ" ,
445+ "PrimaryAttribute" : q_comments_id ,
446+ "SecondaryAttribute" : f"Anything else you'd like to share about { project_name } ?" ,
447+ "TertiaryAttribute" : None ,
448+ "Payload" : {
449+ "QuestionText" : f"Anything else you'd like to share about this team's performance and progress in { lab_name } Lab - { project_name } Project?<i> (blockers, concerns, or positive notes)</i><br>" ,
450+ "DataExportTag" : f"Q_{ lab_name } _{ project_name } _Comments" ,
451+ "QuestionID" : q_comments_id ,
452+ "QuestionType" : "TE" ,
453+ "Selector" : "ML" ,
454+ "Configuration" : {
455+ "QuestionDescriptionOption" : "UseText"
456+ },
457+ "QuestionDescription" : f"Anything else you'd like to share about { project_name } ? (blockers, concerns...)" ,
458+ "Validation" : {
459+ "Settings" : {
460+ "ForceResponse" : "OFF" ,
461+ "Type" : "None"
462+ }
463+ },
464+ "DisplayLogic" : {
465+ "0" : {
466+ "0" : {
467+ "LogicType" : "Question" ,
468+ "QuestionID" : q_proj_id ,
469+ "QuestionIsInLoop" : "no" ,
470+ "ChoiceLocator" : f"q://{ q_proj_id } /SelectableChoice/{ proj_idx } " ,
471+ "Operator" : "Selected" ,
472+ "QuestionIDFromLocator" : q_proj_id ,
473+ "LeftOperand" : f"q://{ q_proj_id } /SelectableChoice/{ proj_idx } " ,
474+ "Type" : "Expression"
475+ },
476+ "Type" : "If"
477+ },
478+ "Type" : "BooleanExpression" ,
479+ "inPage" : False
480+ },
481+ "GradingData" : [],
482+ "Language" : [],
483+ "NextChoiceId" : 4 ,
484+ "NextAnswerId" : 1 ,
485+ "SearchSource" : {
486+ "AllowFreeResponse" : "false"
487+ }
488+ }
489+ })
375490
376491 # Store the lab block
377492 blocks [str (block_counter - 1 )] = lab_block
378493 block_counter += 1
379494
380- # Create "Overall Check" block with final questions
381- # Calculate block ID: BL_1 is initial, BL_2 through BL_(len+1) are labs, so overall is BL_(len+2)
382- overall_block_id = f"BL_{ len (lab_names ) + 2 } "
383- overall_block = {
384- "Type" : "Standard" ,
385- "Description" : "Overall Check" ,
386- "ID" : overall_block_id ,
387- "BlockElements" : [],
388- "Options" : {
389- "BlockLocking" : "false" ,
390- "RandomizeQuestions" : "false" ,
391- "BlockVisibility" : "Expanded"
392- }
393- }
394-
395- # Q: Overall progress toward publication
396- q_overall_id = f"QID{ qid_counter } "
397- qid_counter += 1
398- overall_block ["BlockElements" ].append ({"Type" : "Question" , "QuestionID" : q_overall_id })
399-
400- questions .append ({
401- "SurveyID" : survey_id ,
402- "Element" : "SQ" ,
403- "PrimaryAttribute" : q_overall_id ,
404- "SecondaryAttribute" : "How do you evaluate the team's overall progress toward publication?" ,
405- "TertiaryAttribute" : None ,
406- "Payload" : {
407- "QuestionText" : "How do you evaluate the team's overall progress toward publication?" ,
408- "DataExportTag" : "Q_Overall_Progress" ,
409- "QuestionID" : q_overall_id ,
410- "QuestionType" : "MC" ,
411- "Selector" : "SAHR" ,
412- "SubSelector" : "TX" ,
413- "Configuration" : {
414- "QuestionDescriptionOption" : "SpecifyLabel" ,
415- "TextPosition" : "inline" ,
416- "LabelPosition" : "BELOW"
417- },
418- "QuestionDescription" : "How do you evaluate the team's overall progress toward publication?" ,
419- "Choices" : {
420- "1" : {"Display" : "On Track" },
421- "2" : {"Display" : "Needs Improvement" },
422- "3" : {"Display" : "Blocked" }
423- },
424- "ChoiceOrder" : [1 , "2" , "3" ],
425- "Validation" : {
426- "Settings" : {
427- "ForceResponse" : "ON" ,
428- "ForceResponseType" : "ON" ,
429- "Type" : "None"
430- }
431- },
432- "GradingData" : [],
433- "Language" : [],
434- "NextChoiceId" : 4 ,
435- "NextAnswerId" : 4
436- }
437- })
438-
439- # Q: Anything else you'd like to share
440- q_comments_id = f"QID{ qid_counter } "
441- qid_counter += 1
442- overall_block ["BlockElements" ].append ({"Type" : "Question" , "QuestionID" : q_comments_id })
443-
444- questions .append ({
445- "SurveyID" : survey_id ,
446- "Element" : "SQ" ,
447- "PrimaryAttribute" : q_comments_id ,
448- "SecondaryAttribute" : "Anything else you'd like to share about this team's performance and progress?" ,
449- "TertiaryAttribute" : None ,
450- "Payload" : {
451- "QuestionText" : "Anything else you'd like to share about this team's performance and progress?<i> (blockers, concerns, or positive notes)</i><br>" ,
452- "DataExportTag" : "Q_Comments" ,
453- "QuestionID" : q_comments_id ,
454- "QuestionType" : "TE" ,
455- "Selector" : "ML" ,
456- "Configuration" : {
457- "QuestionDescriptionOption" : "UseText"
458- },
459- "QuestionDescription" : "Anything else you'd like to share about this team's performance and progress? (blockers, concerns...)" ,
460- "Validation" : {
461- "Settings" : {
462- "ForceResponse" : "OFF" ,
463- "Type" : "None"
464- }
465- },
466- "GradingData" : [],
467- "Language" : [],
468- "NextChoiceId" : 4 ,
469- "NextAnswerId" : 1 ,
470- "SearchSource" : {
471- "AllowFreeResponse" : "false"
472- }
473- }
474- })
475-
476- # Store the overall check block
477- # After n labs, blocks["0"] through blocks[str(n-1)] are used, and block_counter = n+1
478- # So we use blocks[str(block_counter - 1)] which is blocks[str(n)]
479- blocks [str (block_counter - 1 )] = overall_block
480-
481495 # Build SurveyElements in the correct order
482496 # 1. Blocks element (BL) - Payload is a dict, not array
483497 survey ["SurveyElements" ].append ({
@@ -507,15 +521,6 @@ def generate_qualtrics_qsf(data):
507521 "FlowID" : f"FL_{ lab_idx + 10 } " ,
508522 "Autofill" : []
509523 })
510-
511- # Add the Overall Check block at the end
512- overall_block_id = f"BL_{ len (lab_names ) + 2 } "
513- flow_elements .append ({
514- "Type" : "Standard" ,
515- "ID" : overall_block_id ,
516- "FlowID" : f"FL_{ len (lab_names ) + 100 } " ,
517- "Autofill" : []
518- })
519524
520525 survey_flow = {
521526 "Type" : "Root" ,
0 commit comments