@@ -4,9 +4,8 @@ import {computed, watch} from 'vue';
44import { useLocalize } from '@/composables/useLocalize' ;
55import { useWorkflowStore } from '@/pages/workflow/workflowStore' ;
66import { useForm } from '@/composables/useForm' ;
7- import { sanitizeHtml } from '@/directives/stripUnsafeHtml' ;
87
9- export async function useWorkflowPublicationFormIssue ( form ) {
8+ export function useWorkflowPublicationFormIssue ( form ) {
109 const { t} = useLocalize ( ) ;
1110 const store = useWorkflowStore ( ) ;
1211 const {
@@ -51,11 +50,6 @@ export async function useWorkflowPublicationFormIssue(form) {
5150
5251 let currentValue = getField ( 'assignment' ) ?. value ;
5352
54- // If no form value yet, try to get from store (for modal context)
55- if ( ! currentValue && assignmentStatus . value ?. assignmentType ) {
56- currentValue = assignmentStatus . value . assignmentType ;
57- }
58-
5953 if ( ! currentValue ) {
6054 return null ;
6155 }
@@ -95,7 +89,7 @@ export async function useWorkflowPublicationFormIssue(form) {
9589
9690 return issues . value . items . map ( ( issue ) => ( {
9791 value : issue . id ,
98- label : sanitizeHtml ( issue . identification ) ,
92+ label : issue . identification ,
9993 } ) ) ;
10094 } ) ;
10195
@@ -120,89 +114,150 @@ export async function useWorkflowPublicationFormIssue(form) {
120114 }
121115
122116 /**
123- * Create all required fields
117+ * Create fields immediately with placeholder data for instant UI rendering
124118 */
125119 function createFields ( ) {
126- const initialAssignment = assignmentStatus . value ?. assignmentType || null ;
127- const initialStatus =
128- assignmentStatus . value ?. status || pkp . const . submission . STATUS_QUEUED ;
129-
130120 addFieldOptions ( 'assignment' , 'radio' , {
131121 label : t ( 'publication.assignToIssue.assignmentType' ) ,
132- options : assignmentOptions . value ,
122+ options : [ ] ,
133123 isRequired : true ,
134- value : initialAssignment ,
124+ value : null ,
135125 } ) ;
136126
137127 addFieldSelect ( 'issueId' , {
138128 label : t ( 'issue.issue' ) ,
139129 description : t ( 'publication.assignToIssue.issueDescription' ) ,
140- options : issueOptions . value ,
130+ options : [ ] ,
141131 size : 'large' ,
142132 value : store . selectedPublication ?. issueId ,
143133 isRequired : true ,
144- showWhen : [ 'assignment' , showWhenAssignmentIds . value ] ,
134+ showWhen : [ 'assignment' , [ ] ] ,
145135 } ) ;
146136
147- setHiddenValue ( 'status' , initialStatus ) ;
137+ // Set initial status - will be updated by watchers when assignmentStatus data arrives
138+ setHiddenValue ( 'status' , store . selectedPublication ?. status ) ;
148139 }
149140
150141 /**
151- * Set up watchers for dynamic updates and validation
142+ * Set up watchers to handle data updates and field synchronization
152143 */
153- function setupWatchers ( ) {
154- // Watch assignment options changes and apply to form
155- watch ( assignmentOptions , ( newOptions ) => {
156- const assignmentField = getField ( 'assignment' ) ;
157- if ( assignmentField ) {
158- assignmentField . options = newOptions ;
159- }
160- } ) ;
144+ function setupDataWatchers ( ) {
145+ // Track if this is the initial data load to preserve existing issueId values
146+ let isInitialDataLoad = true ;
147+
148+ // Watch assignmentStatus and update initial assignment value
149+ watch (
150+ assignmentStatus ,
151+ ( newStatus ) => {
152+ if ( newStatus ?. assignmentType ) {
153+ const assignmentField = getField ( 'assignment' ) ;
154+
155+ if ( assignmentField && ! assignmentField . value ) {
156+ setValue ( 'assignment' , newStatus . assignmentType ) ;
157+ }
158+
159+ // At initial data load, if the publication is published or scheduled, don't set the new status
160+ if (
161+ ! [
162+ pkp . const . publication . STATUS_PUBLISHED ,
163+ pkp . const . publication . STATUS_SCHEDULED ,
164+ ] . includes ( store . selectedPublication ?. status )
165+ ) {
166+ setHiddenValue ( 'status' , newStatus . status ) ;
167+ }
168+ }
169+ } ,
170+ { immediate : true } ,
171+ ) ;
172+
173+ // Watch assignment options and update field options
174+ watch (
175+ assignmentOptions ,
176+ ( newOptions ) => {
177+ const assignmentField = getField ( 'assignment' ) ;
178+ if ( assignmentField ) {
179+ assignmentField . options = newOptions ;
180+ }
181+ } ,
182+ { immediate : true } ,
183+ ) ;
161184
162185 // Watch showWhen changes and apply to issue field
163- watch ( showWhenAssignmentIds , ( newShowWhenIds ) => {
164- const issueIdField = getField ( 'issueId' ) ;
165- if ( issueIdField ) {
166- issueIdField . showWhen = [ 'assignment' , newShowWhenIds ] ;
167- }
168- } ) ;
186+ watch (
187+ showWhenAssignmentIds ,
188+ ( newShowWhenIds ) => {
189+ const issueIdField = getField ( 'issueId' ) ;
190+ if ( issueIdField ) {
191+ issueIdField . showWhen = [ 'assignment' , newShowWhenIds ] ;
192+ }
193+ } ,
194+ { immediate : true } ,
195+ ) ;
169196
170197 // Watch current assignment option changes and update status
171198 watch ( currentAssignmentOption , async ( newOption ) => {
172199 if ( newOption ) {
173- setHiddenValue ( 'status' , newOption . status ) ;
174- setValue ( 'issueId' , null ) ;
200+ // Only reset issueId to null if this is NOT the initial data load
201+ // This preserves the initial issueId value from store.selectedPublication?.issueId
202+ // Or coming from PHP form's end
203+ // Also at initial data load, if the publication is published or scheduled, don't set the new status
204+ if ( ! isInitialDataLoad ) {
205+ setValue ( 'issueId' , null ) ;
206+ setHiddenValue ( 'status' , newOption . status ) ;
207+ } else {
208+ if (
209+ [
210+ pkp . const . publication . STATUS_PUBLISHED ,
211+ pkp . const . publication . STATUS_SCHEDULED ,
212+ ] . includes ( store . selectedPublication ?. status )
213+ ) {
214+ setHiddenValue ( 'status' , null ) ;
215+ }
216+ }
217+
175218 if ( newOption . isPublished !== null ) {
176219 await fetchIssues ( ) ;
177220 }
178221 }
179222 } ) ;
180223
181224 // Watch issue options and apply to form
182- watch ( issueOptions , ( newIssueOptions ) => {
183- const issueIdField = getField ( 'issueId' ) ;
184- if ( issueIdField ) {
185- issueIdField . options = newIssueOptions ;
186- issueIdField . isRequired = newIssueOptions . length > 0 ;
187- }
188- } ) ;
225+ watch (
226+ issueOptions ,
227+ ( newIssueOptions ) => {
228+ const issueIdField = getField ( 'issueId' ) ;
229+ if ( issueIdField ) {
230+ issueIdField . options = newIssueOptions ;
231+ }
232+ } ,
233+ { immediate : true } ,
234+ ) ;
235+
236+ // Mark initial data load as complete after a short delay
237+ // which in return all initial watchers have had a chance to run
238+ setTimeout ( ( ) => {
239+ isInitialDataLoad = false ;
240+ } , 100 ) ;
189241 }
190242
191243 /**
192- * Initialize the composable - fetch data, create fields, and set up watchers
244+ * Initialize the composable
245+ * Create fields immediately(if not exist) and fetch data in parallel
193246 */
194247 async function initialize ( ) {
195- await fetchAssignments ( ) ;
196- await fetchAssignmentStatus ( ) ;
197- await fetchIssues ( ) ;
198-
199248 const fieldsExist = await checkFieldsExist ( ) ;
249+
200250 if ( ! fieldsExist ) {
201251 createFields ( ) ;
202252 }
203253
204- setupWatchers ( ) ;
254+ setupDataWatchers ( ) ;
255+
256+ fetchAssignments ( ) ;
257+ fetchAssignmentStatus ( ) ;
205258 }
206259
207- await initialize ( ) ;
260+ return {
261+ initialize,
262+ } ;
208263}
0 commit comments