33 :id =" `${props.formId}-${props.name}`"
44 class =" pkpFormField pkpFormField--issueSelection"
55 >
6- <div class =" pkpFormField__heading" >
7- <FormFieldLabel
8- :control-id =" useId()"
9- :label =" t('publication.assignToIssue.label')"
10- :is-required =" isRequired"
11- :required-label =" t('common.required')"
12- class =" align-middle"
13- />
14- </div >
15- <div
16- v-strip-unsafe-html =" t('publication.assignToIssue.description')"
17- class =" pkpFormField__description semantic-defaults"
18- />
19- <div class =" pkpFormField__control" >
20- <FieldOptions
21- :name =" props.name + '_assignment'"
22- :label =" t('publication.assignToIssue.description')"
23- :is-required =" false"
24- :value =" finalAssignmentType"
25- :options =" assignmentOptions"
26- type =" radio"
27- :all-errors =" {}"
28- :is-loading =" isLoadingAssignmentOptions"
29- @change =" onAssignmentChange"
30- />
31-
32- <div v-if =" showIssueDropdown" class =" pkpFormField__issueDropdown" >
33- <FieldSelect
34- :name =" props.name"
35- :label =" t('issue.issue')"
36- :is-required =" isRequired"
37- :value =" selectedIssueId"
38- :options =" availableIssues"
39- :all-errors =" {}"
40- size =" large"
41- @change =" onIssueChange"
6+ <fieldset class =" pkpFormGroup pkpFormGroup--issueSelection" >
7+ <div class =" pkpFormGroup__heading" >
8+ <FormGroupHeader
9+ :label ="
10+ t('publication.assignToIssue.label') + (isRequired ? ' *' : '')
11+ "
12+ :description ="
13+ t('publication.assignToIssue.assignmentTypeDescription')
14+ "
4215 />
4316 </div >
17+ <div class =" pkpFormGroup__fields" >
18+ <FieldOptions
19+ :name =" props.name + '_assignment'"
20+ :label =" t('publication.assignToIssue.assignmentType')"
21+ :is-required =" false"
22+ :value =" finalAssignmentType"
23+ :options =" assignmentOptions"
24+ type =" radio"
25+ :all-errors =" {}"
26+ :is-loading =" isLoadingAssignmentOptions"
27+ @change =" onAssignmentChange"
28+ />
4429
45- <FieldError
46- v-if =" (errors && errors.length) || validationErrors.length"
47- :id =" describedByErrorId"
48- :messages =" errors && errors.length ? errors : validationErrors"
49- />
50- </div >
30+ <div v-if =" showIssueDropdown" class =" pkpFormField__issueDropdown" >
31+ <FieldSelect
32+ :name =" props.name"
33+ :label =" t('issue.issue')"
34+ :description =" t('publication.assignToIssue.issueDescription')"
35+ :is-required =" isRequired"
36+ :value =" selectedIssueId"
37+ :options =" availableIssues"
38+ :all-errors =" {}"
39+ size =" large"
40+ @change =" onIssueChange"
41+ />
42+ </div >
43+
44+ <FieldError
45+ v-if =" (errors && errors.length) || validationErrors.length"
46+ :id =" describedByErrorId"
47+ :messages =" errors && errors.length ? errors : validationErrors"
48+ />
49+ </div >
50+ </fieldset >
5151 </div >
5252</template >
5353
5454<script setup>
55- import {ref , computed , watch , onMounted , useId } from ' vue' ;
55+ import {ref , computed , watch , onMounted } from ' vue' ;
5656import {useLocalize } from ' @/composables/useLocalize' ;
5757import {useFetch } from ' @/composables/useFetch' ;
5858import {useUrl } from ' @/composables/useUrl' ;
59- import FormFieldLabel from ' @/components/Form/FormFieldLabel.vue' ;
6059import FieldError from ' @/components/Form/FieldError.vue' ;
6160import FieldOptions from ' @/components/Form/fields/FieldOptions.vue' ;
6261import FieldSelect from ' @/components/Form/fields/FieldSelect.vue' ;
62+ import FormGroupHeader from ' @/components/Form/FormGroupHeader.vue' ;
6363
6464const props = defineProps ({
6565 name: {
@@ -74,10 +74,6 @@ const props = defineProps({
7474 type: Array ,
7575 default : () => [],
7676 },
77- allErrors: {
78- type: Object ,
79- default : () => ({}),
80- },
8177 assignmentType: {
8278 type: Number ,
8379 default: null ,
@@ -103,11 +99,9 @@ const props = defineProps({
10399const emit = defineEmits ([' change' , ' set-errors' , ' set' ]);
104100const {t } = useLocalize ();
105101
106- // Local state - track user selections
107102const availableIssues = ref ([]);
108103const isLoadingIssues = ref (false );
109104
110- // User selections - these are what the user has actually chosen
111105const selectedIssueId = ref (props .publication ? .issueId || null );
112106const selectedAssignmentType = ref (props .assignmentType || null );
113107
@@ -155,7 +149,8 @@ const fetchAssignmentOptions = async () => {
155149};
156150
157151const fetchAssignmentType = async () => {
158- // Skip if there is a preset assignment type
152+ // we will not fetch if the assignment type is give for the publication
153+ // for example, it's can be given from the PHP form
159154 if (props .assignmentType !== null ) {
160155 return ;
161156 }
@@ -178,7 +173,7 @@ const fetchAssignmentType = async () => {
178173};
179174
180175const showIssueDropdown = computed (() => {
181- // Don't show dropdown if no assignment options are loaded yet
176+ // no dropdown if no assignment options available
182177 if (assignmentOptions .value .length === 0 ) {
183178 return false ;
184179 }
@@ -198,9 +193,9 @@ const shouldFetchPublishedIssues = computed(() => {
198193
199194const isValid = computed (() => {
200195 const option = assignmentOptions .value .find (
201- (opt ) => opt .value === selectedAssignmentType .value , // Use user's selection
196+ (opt ) => opt .value === selectedAssignmentType .value ,
202197 );
203- return option? .isPublished === null || selectedIssueId .value ; // Use user's issue selection
198+ return option? .isPublished === null || selectedIssueId .value ;
204199});
205200
206201const publicationStatus = computed (() => {
@@ -218,6 +213,7 @@ const validationErrors = computed(() => {
218213});
219214
220215// Emit validation errors to the form system
216+ // FIXME : NOT propagating to top level from component
221217watch (
222218 validationErrors,
223219 (errors ) => {
@@ -231,7 +227,7 @@ watch(
231227);
232228
233229const describedByErrorId = computed (() => {
234- return ` ${ useId () } -error` ;
230+ return ` ${ props . formId || ' form ' } - ${ props . name } -error` ;
235231});
236232
237233const onAssignmentChange = (fieldName , propName , newValue ) => {
@@ -344,22 +340,15 @@ watch(selectedIssueId, () => {
344340});
345341
346342onMounted (async () => {
347- // Initialize user selections with props or publication values
348343 selectedAssignmentType .value = props .assignmentType || null ;
349- selectedIssueId .value = props .publication ? .issueId || null ;
350344
351345 await Promise .all ([fetchAssignmentOptions (), fetchAssignmentType ()]);
352346
353- // Debug: Log the state after fetching
354- // console.log('FieldIssueSelection mounted:', {
355- // selectedAssignmentType: selectedAssignmentType.value,
356- // selectedIssueId: selectedIssueId.value,
357- // showIssueDropdown: showIssueDropdown.value,
358- // assignmentOptions: assignmentOptions.value,
359- // issueCount: props.issueCount
360- // });
347+ // Need to set the selected issue id after the fetch of assignment type as
348+ // the watcher of selected assignment type does update the `selectedIssueId`
349+ selectedIssueId .value = props .publication ? .issueId || null ;
361350
362- // If we have an assignment type that requires issue selection and an existing issue ID,
351+ // already pre-existed assignment type that requires issue selection and an existing issue ID,
363352 // fetch the issues so the dropdown is populated and the correct issue is pre-selected
364353 if (
365354 selectedAssignmentType .value &&
@@ -369,11 +358,43 @@ onMounted(async () => {
369358 await fetchIssues ();
370359 }
371360
372- // TODO : remove this once the emit issue for hidden field is fixed
361+ // FIXME : remove this once the emit issue for hidden field is fixed
373362 if (props .isPhpForm ) {
374363 $ (' input[name="prePublishStatus"]' ).hide ();
375364 }
376365
377366 emitValue ();
378367});
379368< / script>
369+
370+ < style lang= " less" scoped>
371+ .pkpFormGroup -- issueSelection {
372+ border: 1px solid #ddd;
373+ border- radius: 2px ;
374+
375+ .pkpFormGroup__heading {
376+ border- bottom: 1px solid #ddd;
377+ margin: - 2rem 0rem 2rem 0rem ;
378+ padding: 1 .5rem 0rem 2rem 0rem ;
379+ border- radius: 4px 4px 0 0 ;
380+ float: none;
381+ width: 100 % ;
382+ padding- inline- end: 2rem ;
383+ }
384+
385+ .pkpFormGroup__fields {
386+ float: none;
387+ width: 100 % ;
388+ padding- inline- start: 0 ;
389+
390+ > * + * {
391+ margin- top: 1 .5rem ;
392+ }
393+ }
394+
395+ .pkpFormField__issueDropdown {
396+ padding- top: 1rem ;
397+ margin- top: 1 .5rem ;
398+ }
399+ }
400+ < / style>
0 commit comments