Skip to content

Commit b88a18c

Browse files
committed
pkp/pkp-lib#9295 code clean up and better composition implementation
1 parent 4b49b5f commit b88a18c

File tree

7 files changed

+120
-54
lines changed

7 files changed

+120
-54
lines changed

src/components/Form/Form.vue

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
type="hidden"
1414
:name="name"
1515
:value="value"
16-
@change="fieldChanged"
1716
/>
1817
<FormLocales
1918
v-if="availableLocales.length > 1"

src/components/Form/FormGroup.vue

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@
4545
:locales="availableLocales"
4646
@change="fieldChanged"
4747
@set-errors="setFieldErrors"
48-
@set-field-required="setFieldRequired"
4948
></component>
5049
</div>
5150
</div>

src/composables/useForm.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -622,7 +622,6 @@ export function useForm(_form = {}, {customSubmit} = {}) {
622622
initEmptyForm,
623623
addPage,
624624
addGroup,
625-
addField,
626625
addFieldText,
627626
addFieldSelect,
628627
addFieldOptions,

src/composables/useLegacyGridUrl.test.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,16 @@ describe('useLegacyGridUrl', () => {
3232
'http://mock/index.php/publicknowledge/$$$call$$$/grid/users/reviewer/reviewer-grid/read-review?submissionId=13&reviewAssignmentId=19&stageId=3',
3333
);
3434
});
35+
36+
test('modals.documentLibrary.DocumentLibraryHandler', () => {
37+
const {url} = useLegacyGridUrl({
38+
component: 'modals.documentLibrary.DocumentLibraryHandler',
39+
op: 'documentLibrary',
40+
params: {submissionId: 13},
41+
});
42+
43+
expect(url.value).toBe(
44+
'http://mock/index.php/publicknowledge/$$$call$$$/modals/document-library/document-library/document-library?submissionId=13',
45+
);
46+
});
3547
});

src/pages/workflow/components/publication/WorkflowPublicationForm.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@ watch(
8181
form,
8282
async (newForm) => {
8383
if (newForm && props.formName === 'issue' && isOJS()) {
84-
await useWorkflowPublicationFormIssue(newForm);
84+
const {initialize} = useWorkflowPublicationFormIssue(newForm);
85+
await initialize();
8586
}
8687
},
8788
{immediate: true},

src/pages/workflow/composables/useWorkflowPublicationFormIssue.js

Lines changed: 104 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@ import {computed, watch} from 'vue';
44
import {useLocalize} from '@/composables/useLocalize';
55
import {useWorkflowStore} from '@/pages/workflow/workflowStore';
66
import {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
}

src/pages/workflow/composables/useWorkflowVersionForm.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,8 @@ export function useWorkflowVersionForm(
321321
// it's in publish mode
322322
// have issues
323323
if (modeState.isPublishMode && issueCount > 0 && isOJS()) {
324-
await useWorkflowPublicationFormIssue(form);
324+
const {initialize} = useWorkflowPublicationFormIssue(form);
325+
await initialize();
325326
}
326327

327328
setValue(

0 commit comments

Comments
 (0)