3232 :name =" props.name"
3333 :label =" t('issue.issue')"
3434 :description =" t('publication.assignToIssue.issueDescription')"
35- :is-required =" isRequired "
35+ :is-required =" isIssueSelectionRequired "
3636 :value =" selectedIssueId"
3737 :options =" availableIssues"
3838 :all-errors =" {}"
@@ -88,7 +88,7 @@ const props = defineProps({
8888 },
8989 isRequired: {
9090 type: Boolean ,
91- default: false ,
91+ default: true ,
9292 },
9393 isPhpForm: {
9494 type: Boolean ,
@@ -149,7 +149,7 @@ const fetchAssignmentOptions = async () => {
149149};
150150
151151const fetchAssignmentType = async () => {
152- // we will not fetch if the assignment type is give for the publication
152+ // will not fetch if the assignment type is give for the publication
153153 // for example, it's can be given from the PHP form
154154 if (props .assignmentType !== null ) {
155155 return ;
@@ -184,18 +184,45 @@ const showIssueDropdown = computed(() => {
184184 return option? .isPublished !== null ;
185185});
186186
187+ // TODO : need it ?
188+ // dynamic isRequired based on selection and props.isRequired
189+ const isIssueSelectionRequired = computed (() => {
190+ // Only require issue selection if:
191+ // 1. The field is marked as required (from PHP or JS)
192+ // 2. AND the selected assignment type actually requires an issue (isPublished !== null)
193+ const selectedOption = assignmentOptions .value .find (
194+ (opt ) => opt .value === selectedAssignmentType .value ,
195+ );
196+
197+ return props .isRequired && selectedOption? .isPublished !== null ;
198+ });
199+
187200const shouldFetchPublishedIssues = computed (() => {
188201 const option = assignmentOptions .value .find (
189202 (opt ) => opt .value === selectedAssignmentType .value ,
190203 );
191204 return option? .isPublished ;
192205});
193206
207+ // TODO : need this ?
208+ // better validation logic
194209const isValid = computed (() => {
210+ // If no assignment type selected, not valid
211+ if (! selectedAssignmentType .value ) {
212+ return false ;
213+ }
214+
195215 const option = assignmentOptions .value .find (
196216 (opt ) => opt .value === selectedAssignmentType .value ,
197217 );
198- return option? .isPublished === null || selectedIssueId .value ;
218+
219+ // If assignment type doesn't require issue selection, always valid
220+ if (option? .isPublished === null ) {
221+ return true ;
222+ }
223+
224+ // If assignment type requires issue selection, check if issue is selected
225+ return selectedIssueId .value !== null ;
199226});
200227
201228const publicationStatus = computed (() => {
@@ -205,23 +232,38 @@ const publicationStatus = computed(() => {
205232 return option? .status || null ;
206233});
207234
235+ // TODO : need this ?
236+ // validation error messages
208237const validationErrors = computed (() => {
209238 if (! isValid .value ) {
210- return [t (' publication.assignToIssue.validation.issueRequired' )];
239+ // If assignment type requires issue but none selected
240+ if (isIssueSelectionRequired .value && ! selectedIssueId .value ) {
241+ return [t (' publication.assignToIssue.validation.issueRequired' )];
242+ }
243+ // If no assignment type selected
244+ if (! selectedAssignmentType .value ) {
245+ return [t (' publication.assignToIssue.validation.assignmentRequired' )];
246+ }
211247 }
212248 return [];
213249});
214250
215- // Emit validation errors to the form system
216- // FIXME : NOT propagating to top level from component
217251watch (
218252 validationErrors,
219253 (errors ) => {
220- if (errors .length > 0 ) {
221- emit (' set-errors' , props .name , errors);
222- } else {
223- emit (' set-errors' , props .name , []);
224- }
254+ errors .length > 0
255+ ? emit (' set-errors' , props .name , errors) // emit errors
256+ : emit (' set-errors' , props .name , []); // clear errors
257+ },
258+ {immediate: true },
259+ );
260+
261+ // Watch for assignment type changes to update validation
262+ watch (
263+ selectedAssignmentType,
264+ () => {
265+ // Trigger validation update when assignment type changes
266+ // This ensures validationErrors computed property updates
225267 },
226268 {immediate: true },
227269);
@@ -262,9 +304,10 @@ const emitValue = () => {
262304 }
263305 } else {
264306 const value = {
265- assignmentType: selectedAssignmentType .value , // User's assignment type selection
266- issueId: selectedIssueId .value , // User's issue selection
267- publicationStatus: publicationStatus .value , // Calculated status from user's selection
307+ assignmentType: selectedAssignmentType .value ,
308+ issueId: selectedIssueId .value ,
309+ publicationStatus: publicationStatus .value ,
310+ isValid: isValid .value ,
268311 };
269312
270313 // TODO: Remove this after testing
@@ -339,6 +382,52 @@ watch(selectedIssueId, () => {
339382 emitValue ();
340383});
341384
385+ // Watch for changes and emit required state
386+ watch (
387+ [selectedAssignmentType, selectedIssueId],
388+ () => {
389+ // Determine if field is currently required
390+ let isCurrentlyRequired = true ; // Default to required
391+
392+ if (selectedAssignmentType .value ) {
393+ const selectedOption = assignmentOptions .value .find (
394+ (opt ) => opt .value === selectedAssignmentType .value ,
395+ );
396+
397+ // If assignment type doesn't require issue selection, not required
398+ if (selectedOption? .isPublished === null ) {
399+ isCurrentlyRequired = false ;
400+ }
401+ }
402+
403+ // Emit the current required state
404+ emit (' set-field-required' , props .name , isCurrentlyRequired);
405+
406+ emitValue (); // emit the value change
407+ },
408+ {immediate: false }, // not run immediately since we handle it in onMounted
409+ );
410+
411+ // ✅ NEW: Function to emit initial required state
412+ const emitInitialRequiredState = () => {
413+ // Determine if field is currently required based on initial values
414+ let isCurrentlyRequired = true ; // Default to required
415+
416+ if (selectedAssignmentType .value ) {
417+ const selectedOption = assignmentOptions .value .find (
418+ (opt ) => opt .value === selectedAssignmentType .value ,
419+ );
420+
421+ // If assignment type doesn't require issue selection, not required
422+ if (selectedOption? .isPublished === null ) {
423+ isCurrentlyRequired = false ;
424+ }
425+ }
426+
427+ // Emit the initial required state
428+ emit (' set-field-required' , props .name , isCurrentlyRequired);
429+ };
430+
342431onMounted (async () => {
343432 selectedAssignmentType .value = props .assignmentType || null ;
344433
@@ -354,12 +443,9 @@ onMounted(async () => {
354443 await fetchIssues ();
355444 }
356445
357- // FIXME : remove this once the emit issue for hidden field is fixed
358- if (props .isPhpForm ) {
359- $ (' input[name="prePublishStatus"]' ).hide ();
360- }
361-
362446 emitValue ();
447+
448+ emitInitialRequiredState ();
363449});
364450< / script>
365451
0 commit comments