diff --git a/src/managers/GalleyManager/galleyManagerStore.js b/src/managers/GalleyManager/galleyManagerStore.js
index 4e75137e6..b2ae5215f 100644
--- a/src/managers/GalleyManager/galleyManagerStore.js
+++ b/src/managers/GalleyManager/galleyManagerStore.js
@@ -103,7 +103,9 @@ export const useGalleyManagerStore = defineComponentStore(
/**
* Actions
*/
- const _galleyActionsFns = useGalleyManagerActions();
+ const _galleyActionsFns = useGalleyManagerActions({
+ galleyGridComponent: _galleyConfigurationFns.getGalleyGridComponent(),
+ });
function getActionArgs() {
return {
canEdit: props.canEdit,
diff --git a/src/managers/GalleyManager/useGalleyManagerActions.js b/src/managers/GalleyManager/useGalleyManagerActions.js
index 95f4de0f8..90b9a380e 100644
--- a/src/managers/GalleyManager/useGalleyManagerActions.js
+++ b/src/managers/GalleyManager/useGalleyManagerActions.js
@@ -9,7 +9,7 @@ export const Actions = {
GALLEY_DELETE: 'galleyDelete',
};
-export function useGalleyManagerActions() {
+export function useGalleyManagerActions({galleyGridComponent}) {
const {t} = useLocalize();
function getBottomActions({canEdit}) {
@@ -76,7 +76,7 @@ export function useGalleyManagerActions() {
function galleyAdd({submission, publication}, finishedCallback) {
const {openLegacyModal} = useLegacyGridUrl({
- component: 'grid.articleGalleys.ArticleGalleyGridHandler',
+ component: galleyGridComponent,
op: 'addGalley',
params: {
submissionId: submission.id,
@@ -123,7 +123,7 @@ export function useGalleyManagerActions() {
function galleyEdit({submission, publication, galley}, finishedCallback) {
const {openLegacyModal} = useLegacyGridUrl({
- component: 'grid.articleGalleys.ArticleGalleyGridHandler',
+ component: galleyGridComponent,
op: 'editGalley',
params: {
submissionId: submission.id,
@@ -153,7 +153,7 @@ export function useGalleyManagerActions() {
// http://localhost:7002/index.php/publicknowledge/$$$call$$$/grid/article-galleys/article-galley-grid/delete-galley
// ?submissionId=17&publicationId=22&representationId=9
const {url} = useLegacyGridUrl({
- component: 'grid.articleGalleys.ArticleGalleyGridHandler',
+ component: galleyGridComponent,
op: 'deleteGalley',
params: {
submissionId: submission.id,
diff --git a/src/managers/GalleyManager/useGalleyManagerConfiguration.js b/src/managers/GalleyManager/useGalleyManagerConfiguration.js
index 546b0d3f1..dc641310a 100644
--- a/src/managers/GalleyManager/useGalleyManagerConfiguration.js
+++ b/src/managers/GalleyManager/useGalleyManagerConfiguration.js
@@ -3,6 +3,14 @@ import {useLocalize} from '@/composables/useLocalize';
export function useGalleyManagerConfiguration() {
const {t} = useLocalize();
+ function getGalleyGridComponent() {
+ if (pkp.context.app === 'ops') {
+ return 'grid.preprintGalleys.PreprintGalleyGridHandler';
+ } else {
+ return 'grid.articleGalleys.ArticleGalleyGridHandler';
+ }
+ }
+
function getColumns() {
const columns = [];
@@ -29,5 +37,5 @@ export function useGalleyManagerConfiguration() {
return columns;
}
- return {getColumns};
+ return {getColumns, getGalleyGridComponent};
}
diff --git a/src/pages/workflow/WorkflowPage.vue b/src/pages/workflow/WorkflowPage.vue
index 76bd1c434..ffc9988a6 100644
--- a/src/pages/workflow/WorkflowPage.vue
+++ b/src/pages/workflow/WorkflowPage.vue
@@ -47,12 +47,29 @@
#publication-controls-left
>
+
+
+
+
diff --git a/src/pages/workflow/components/publication/WorkflowPublicationRelationDropdownOPS.vue b/src/pages/workflow/components/publication/WorkflowPublicationRelationDropdownOPS.vue
new file mode 100644
index 000000000..f18ce5c8d
--- /dev/null
+++ b/src/pages/workflow/components/publication/WorkflowPublicationRelationDropdownOPS.vue
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
diff --git a/src/pages/workflow/composables/useWorkflowConfig/useWorkflowConfigOMP.js b/src/pages/workflow/composables/useWorkflowConfig/useWorkflowConfigOMP.js
index 24b29d1e4..abfe194db 100644
--- a/src/pages/workflow/composables/useWorkflowConfig/useWorkflowConfigOMP.js
+++ b/src/pages/workflow/composables/useWorkflowConfig/useWorkflowConfigOMP.js
@@ -1,8 +1,8 @@
import {useLocalize} from '@/composables/useLocalize';
import {DashboardPageTypes} from '@/pages/dashboard/dashboardPageStore';
-import * as ConfigAuthorShared from './workflowConfigAuthorOJS';
-import * as ConfigEditorialShared from './workflowConfigEditorialOJS';
+import * as ConfigAuthorOJS from './workflowConfigAuthorOJS';
+import * as ConfigEditorialOJS from './workflowConfigEditorialOJS';
import * as ConfigAuthorOMP from './workflowConfigAuthorOMP';
import * as ConfigEditorialOMP from './workflowConfigEditorialOMP';
@@ -16,11 +16,11 @@ export function useWorkflowConfigOMP({dashboardPage}) {
Configs = {
getHeaderItems: ConfigEditorialOMP.getHeaderItems,
WorkflowConfig: {
- ...ConfigEditorialShared.WorkflowConfig,
+ ...ConfigEditorialOJS.WorkflowConfig,
...ConfigEditorialOMP.WorkflowConfig,
},
PublicationConfig: {
- ...ConfigEditorialShared.PublicationConfig,
+ ...ConfigEditorialOJS.PublicationConfig,
...ConfigEditorialOMP.PublicationConfig,
},
MarketingConfig: ConfigEditorialOMP.MarketingConfig,
@@ -29,11 +29,11 @@ export function useWorkflowConfigOMP({dashboardPage}) {
Configs = {
getHeaderItems: ConfigEditorialOMP.getHeaderItems,
WorkflowConfig: {
- ...ConfigAuthorShared.WorkflowConfig,
+ ...ConfigAuthorOJS.WorkflowConfig,
...ConfigAuthorOMP.WorkflowConfig,
},
PublicationConfig: {
- ...ConfigAuthorShared.PublicationConfig,
+ ...ConfigAuthorOJS.PublicationConfig,
...ConfigAuthorOMP.PublicationConfig,
},
};
diff --git a/src/pages/workflow/composables/useWorkflowConfig/useWorkflowConfigOPS.js b/src/pages/workflow/composables/useWorkflowConfig/useWorkflowConfigOPS.js
new file mode 100644
index 000000000..b0bd76d5e
--- /dev/null
+++ b/src/pages/workflow/composables/useWorkflowConfig/useWorkflowConfigOPS.js
@@ -0,0 +1,134 @@
+import {useLocalize} from '@/composables/useLocalize';
+import {DashboardPageTypes} from '@/pages/dashboard/dashboardPageStore';
+
+import * as ConfigAuthorOPS from './workflowConfigAuthorOPS';
+import * as ConfigEditorialOPS from './workflowConfigEditorialOPS';
+
+export function useWorkflowConfigOPS({dashboardPage}) {
+ const {t} = useLocalize();
+
+ let Configs = null;
+
+ if (dashboardPage === DashboardPageTypes.EDITORIAL_DASHBOARD) {
+ Configs = {
+ getHeaderItems: ConfigEditorialOPS.getHeaderItems,
+ WorkflowConfig: {
+ //...ConfigEditorialShared.WorkflowConfig,
+ ...ConfigEditorialOPS.WorkflowConfig,
+ },
+ PublicationConfig: {
+ //...ConfigEditorialShared.PublicationConfig,
+ ...ConfigEditorialOPS.PublicationConfig,
+ },
+ };
+ } else {
+ Configs = {
+ getHeaderItems: ConfigEditorialOPS.getHeaderItems,
+ WorkflowConfig: {
+ ...ConfigAuthorOPS.WorkflowConfig,
+ },
+ PublicationConfig: {
+ ...ConfigAuthorOPS.PublicationConfig,
+ },
+ };
+ }
+
+ function _getItems(
+ getterFnName,
+ {
+ selectedMenuState,
+ submission,
+ pageInitConfig,
+ selectedPublication,
+ selectedPublicationId,
+ selectedReviewRound,
+ permissions,
+ },
+ ) {
+ if (selectedMenuState.stageId) {
+ const itemsArgs = {
+ submission,
+ selectedPublication,
+ selectedPublicationId,
+ selectedStageId: selectedMenuState.stageId,
+ selectedReviewRound,
+ permissions,
+ };
+ if (!submission) {
+ return [];
+ }
+
+ if (!permissions.accessibleStages.includes(selectedMenuState.stageId)) {
+ if (getterFnName === 'getPrimaryItems') {
+ return [
+ {
+ component: 'PrimaryBasicMetadata',
+ props: {body: t('user.authorization.accessibleWorkflowStage')},
+ },
+ ];
+ } else {
+ return [];
+ }
+ }
+
+ return [
+ ...(Configs.WorkflowConfig?.common?.[getterFnName]?.(itemsArgs) || []),
+ ...(Configs.WorkflowConfig[selectedMenuState.stageId]?.[getterFnName]?.(
+ itemsArgs,
+ ) || []),
+ ];
+ } else if (selectedMenuState.primaryMenuItem === 'publication') {
+ const itemsArgs = {
+ submission,
+ pageInitConfig: pageInitConfig,
+ selectedPublication,
+ selectedPublicationId,
+ permissions,
+ };
+ if (!submission || !selectedPublication) {
+ return [];
+ }
+
+ return [
+ ...(Configs.PublicationConfig?.common?.[getterFnName]?.(itemsArgs) ||
+ []),
+ ...(Configs.PublicationConfig[selectedMenuState.secondaryMenuItem]?.[
+ getterFnName
+ ]?.(itemsArgs) || []),
+ ];
+ }
+ }
+
+ function getHeaderItems(args) {
+ return Configs.getHeaderItems(args);
+ }
+
+ function getPrimaryItems(args) {
+ return _getItems('getPrimaryItems', args);
+ }
+
+ function getSecondaryItems(args) {
+ return _getItems('getSecondaryItems', args);
+ }
+
+ function getActionItems(args) {
+ return _getItems('getActionItems', args);
+ }
+
+ function getPublicationControlsLeft(args) {
+ return _getItems('getPublicationControlsLeft', args);
+ }
+
+ function getPublicationControlsRight(args) {
+ return _getItems('getPublicationControlsRight', args);
+ }
+
+ return {
+ getHeaderItems,
+ getPrimaryItems,
+ getSecondaryItems,
+ getActionItems,
+ getPublicationControlsLeft,
+ getPublicationControlsRight,
+ };
+}
diff --git a/src/pages/workflow/composables/useWorkflowConfig/workflowConfigAuthorOPS.js b/src/pages/workflow/composables/useWorkflowConfig/workflowConfigAuthorOPS.js
new file mode 100644
index 000000000..8883ff887
--- /dev/null
+++ b/src/pages/workflow/composables/useWorkflowConfig/workflowConfigAuthorOPS.js
@@ -0,0 +1,182 @@
+import {useLocalize} from '@/composables/useLocalize';
+import {Actions} from '../useWorkflowActions';
+
+export function getHeaderItems({
+ submission,
+ selectedPublication,
+ publicationSettings,
+}) {
+ if (!submission) {
+ return [];
+ }
+ const {t} = useLocalize();
+ const actions = [];
+
+ actions.push({
+ component: 'WorkflowActionButton',
+ props: {
+ label: t('editor.submissionLibrary'),
+ action: Actions.WORKFLOW_VIEW_LIBRARY,
+ },
+ });
+
+ return actions;
+}
+
+export const WorkflowConfig = {};
+
+export const PublicationConfig = {
+ common: {
+ getPrimaryItems: ({
+ submission,
+ selectedPublicationId,
+ selectedPublication,
+ }) => {
+ const items = [];
+ if (selectedPublication.status === pkp.const.STATUS_PUBLISHED) {
+ items.push({
+ component: 'WorkflowPublicationEditDisabled',
+ props: {},
+ });
+ }
+ return items;
+ },
+ getPublicationControlsLeft: ({
+ submission,
+ selectedPublicationId,
+ selectedPublication,
+ }) => {
+ const items = [];
+
+ items.push([
+ {
+ component: 'WorkflowPublicationVersionControl',
+ props: {
+ submission,
+ selectedPublicationId: selectedPublicationId,
+ },
+ },
+ {
+ component: 'WorkflowPublicationRelationDropdownOPS',
+ props: {publication: selectedPublication},
+ },
+ ]);
+
+ return items;
+ },
+ getPublicationControlsRight: ({
+ submission,
+ selectedPublicationId,
+ selectedPublication,
+ }) => {
+ const items = [];
+ return items;
+ },
+ },
+ titleAbstract: {
+ getPrimaryItems: ({
+ submission,
+ selectedPublication,
+ pageInitConfig,
+ permissions,
+ }) => {
+ return [
+ {
+ component: 'WorkflowPublicationForm',
+ props: {
+ formName: 'titleAbstract',
+ submission,
+ publication: selectedPublication,
+ canEdit: permissions.canEditPublication,
+ },
+ },
+ ];
+ },
+ },
+ contributors: {
+ getPrimaryItems: ({
+ submission,
+ selectedPublication,
+ pageInitConfig,
+ permissions,
+ }) => {
+ return [
+ {
+ component: 'ContributorManager',
+ props: {
+ submission: submission,
+ publication: selectedPublication,
+ },
+ },
+ ];
+ },
+ },
+ metadata: {
+ getPrimaryItems: ({
+ submission,
+ selectedPublication,
+ pageInitConfig,
+ permissions,
+ }) => {
+ return [
+ {
+ component: 'WorkflowPublicationForm',
+ props: {
+ formName: 'metadata',
+ submission,
+ publication: selectedPublication,
+ noFieldsMessage: 'No metadata fields are currently enabled.',
+ canEdit: permissions.canEditPublication,
+ },
+ },
+ ];
+ },
+ },
+ citations: {
+ getPrimaryItems: ({
+ submission,
+ selectedPublication,
+ pageInitConfig,
+ permissions,
+ }) => {
+ return [
+ {
+ component: 'WorkflowPublicationForm',
+ props: {
+ formName: 'reference',
+ submission,
+ publication: selectedPublication,
+ canEdit: permissions.canEditPublication,
+ },
+ },
+ ];
+ },
+ },
+ galleys: {
+ getPrimaryItems: ({submission, selectedPublication, permissions}) => {
+ return [
+ {
+ component: 'GalleyManager',
+ props: {
+ submission,
+ publication: selectedPublication,
+ canEditPublication: permissions.canEditPublication,
+ },
+ },
+ ];
+ },
+ },
+ discussions: {
+ getPrimaryItems: ({submission, selectedPublication, permissions}) => {
+ return [
+ {
+ component: 'DiscussionManager',
+ props: {
+ submissionId: submission.id,
+ stageId: pkp.const.WORKFLOW_STAGE_ID_PRODUCTION,
+ },
+ },
+ ];
+ },
+ },
+};
diff --git a/src/pages/workflow/composables/useWorkflowConfig/workflowConfigEditorialOJS.js b/src/pages/workflow/composables/useWorkflowConfig/workflowConfigEditorialOJS.js
index 8f4f02b13..8aba7d3c6 100644
--- a/src/pages/workflow/composables/useWorkflowConfig/workflowConfigEditorialOJS.js
+++ b/src/pages/workflow/composables/useWorkflowConfig/workflowConfigEditorialOJS.js
@@ -511,7 +511,7 @@ export const WorkflowConfig = {
label: t('editor.submission.schedulePublication'),
isPrimary: true,
action: 'navigateToMenu',
- actionArgs: {key: 'publication_titleAbstract'},
+ actionArgs: 'publication_titleAbstract',
},
});
diff --git a/src/pages/workflow/composables/useWorkflowConfig/workflowConfigEditorialOPS.js b/src/pages/workflow/composables/useWorkflowConfig/workflowConfigEditorialOPS.js
new file mode 100644
index 000000000..80be03ca6
--- /dev/null
+++ b/src/pages/workflow/composables/useWorkflowConfig/workflowConfigEditorialOPS.js
@@ -0,0 +1,461 @@
+import {useLocalize} from '@/composables/useLocalize';
+import {Actions} from '../useWorkflowActions';
+import {useSubmission} from '@/composables/useSubmission';
+import {Actions as DecisionActions} from '../useWorkflowDecisions';
+const {hasSubmissionPassedStage, hasNotSubmissionStartedStage} =
+ useSubmission();
+const {t} = useLocalize();
+
+export function getHeaderItems({
+ submission,
+ selectedPublication,
+ publicationSettings,
+ permissions,
+}) {
+ if (!submission) {
+ return [];
+ }
+ const {t} = useLocalize();
+ const actions = [];
+
+ if (submission.status === pkp.const.STATUS_PUBLISHED) {
+ actions.push({
+ component: 'WorkflowActionButton',
+ props: {
+ label: t('common.view'),
+ action: Actions.WORKFLOW_VIEW_PUBLISHED_SUBMISSION,
+ },
+ });
+ }
+
+ if (permissions.canAccessEditorialHistory) {
+ actions.push({
+ component: 'WorkflowActionButton',
+ props: {
+ label: t('editor.activityLog'),
+ action: Actions.WORKFLOW_VIEW_ACTIVITY_LOG,
+ },
+ });
+ }
+ actions.push({
+ component: 'WorkflowActionButton',
+ props: {
+ label: t('editor.submissionLibrary'),
+ action: Actions.WORKFLOW_VIEW_LIBRARY,
+ },
+ });
+
+ return actions;
+}
+
+export const WorkflowConfig = {
+ common: {
+ getPrimaryItems: ({submission, permissions}) => {
+ return [
+ {
+ component: 'WorkflowChangeSubmissionLanguage',
+ props: {
+ submission,
+ canChangeSubmissionLanguage: false,
+ },
+ },
+ ];
+ },
+ },
+ [pkp.const.WORKFLOW_STAGE_ID_PRODUCTION]: {
+ getPrimaryItems: ({submission, selectedStageId, selectedReviewRound}) => {
+ const items = [];
+ if (submission.status === pkp.const.STATUS_PUBLISHED) {
+ items.push({
+ component: 'WorkflowPrimaryBasicMetadata',
+ props: {
+ body: t('editor.submission.workflowDecision.submission.published'),
+ },
+ });
+ }
+
+ items.push({
+ component: 'WorkflowNotificationDisplay',
+ props: {submission: submission},
+ });
+
+ items.push({
+ component: 'DiscussionManager',
+ props: {
+ submissionId: submission.id,
+ stageId: selectedStageId,
+ },
+ });
+
+ return items;
+ },
+ getSecondaryItems: ({submission, selectedReviewRound, selectedStageId}) => {
+ const items = [];
+ items.push({
+ component: 'ParticipantManager',
+ props: {
+ submission,
+ submissionStageId: selectedStageId,
+ },
+ });
+
+ return items;
+ },
+
+ getActionItems: ({submission, selectedStageId, selectedReviewRound}) => {
+ const items = [];
+ if (
+ hasNotSubmissionStartedStage(
+ submission,
+ pkp.const.WORKFLOW_STAGE_ID_PRODUCTION,
+ ) ||
+ hasSubmissionPassedStage(
+ submission,
+ pkp.const.WORKFLOW_STAGE_ID_PRODUCTION,
+ )
+ ) {
+ return [];
+ }
+
+ items.push({
+ component: 'WorkflowActionButton',
+ props: {
+ label: t('editor.submission.schedulePublication'),
+ isPrimary: true,
+ action: 'navigateToMenu',
+ actionArgs: 'publication_titleAbstract',
+ },
+ });
+
+ items.push({
+ component: 'WorkflowActionButton',
+ props: {
+ label: t('editor.submission.decision.decline'),
+ isWarnable: true,
+ action: DecisionActions.DECISION_INITIAL_DECLINE,
+ },
+ });
+
+ return items;
+ },
+ },
+};
+
+export const PublicationConfig = {
+ common: {
+ getPrimaryItems: ({
+ submission,
+ selectedPublicationId,
+ selectedPublication,
+ }) => {
+ const items = [];
+ if (selectedPublication.status === pkp.const.STATUS_PUBLISHED) {
+ items.push({
+ component: 'WorkflowPublicationEditDisabled',
+ props: {},
+ });
+ }
+ return items;
+ },
+ getPublicationControlsLeft: ({
+ submission,
+ selectedPublicationId,
+ selectedPublication,
+ permissions,
+ }) => {
+ const items = [];
+
+ if (
+ submission.status !== pkp.const.STATUS_PUBLISHED &&
+ submission.publications.length < 2
+ ) {
+ items.push({
+ component: 'WorkflowChangeSubmissionLanguage',
+ props: {
+ submission,
+ canChangeSubmissionLanguage:
+ permissions.canChangeSubmissionLanguage,
+ },
+ });
+ }
+
+ // publication controls left supports subarray for horizontal items, and array for vertical
+ items.push([
+ {
+ component: 'WorkflowPublicationVersionControl',
+ props: {
+ submission,
+ selectedPublicationId: selectedPublicationId,
+ },
+ },
+ {
+ component: 'WorkflowPublicationRelationDropdownOPS',
+ props: {publication: selectedPublication},
+ },
+ ]);
+
+ return items;
+ },
+ getPublicationControlsRight: ({
+ submission,
+ selectedPublicationId,
+ selectedPublication,
+ permissions,
+ }) => {
+ const items = [];
+ const {t} = useLocalize();
+
+ if (!permissions.canPublish) {
+ return [];
+ }
+ if (selectedPublication.status === pkp.const.STATUS_QUEUED) {
+ if (
+ hasSubmissionPassedStage(
+ submission,
+ pkp.const.WORKFLOW_STAGE_ID_EXTERNAL_REVIEW,
+ )
+ ) {
+ items.push({
+ component: 'WorkflowActionButton',
+ props: {
+ label: t('common.preview'),
+ isSecondary: true,
+ action: Actions.WORKFLOW_PREVIEW_PUBLICATION,
+ },
+ });
+ }
+
+ items.push({
+ component: 'WorkflowActionButton',
+ props: {
+ // {{ submission.status === getConstant('STATUS_PUBLISHED') ? publishLabel : schedulePublicationLabel }}
+
+ label:
+ submission.status === pkp.const.STATUS_PUBLISHED
+ ? t('publication.publish')
+ : t('editor.submission.schedulePublication'),
+ isSecondary: true,
+ action:
+ Actions.WORKFLOW_ASSIGN_TO_ISSUE_AND_SCHEDULE_FOR_PUBLICATION,
+ },
+ });
+ } else if (selectedPublication.status === pkp.const.STATUS_SCHEDULED) {
+ items.push({
+ component: 'WorkflowActionButton',
+ props: {
+ label: t('dashboard.summary.preview'),
+ isSecondary: true,
+ action: Actions.WORKFLOW_PREVIEW_PUBLICATION,
+ },
+ });
+
+ items.push({
+ component: 'WorkflowActionButton',
+ props: {
+ label: t('publication.unschedule'),
+ isWarnable: true,
+ action: Actions.WORKFLOW_UNSCHEDULE_PUBLICATION,
+ },
+ });
+ } else if (selectedPublication.status === pkp.const.STATUS_PUBLISHED) {
+ items.push({
+ component: 'WorkflowActionButton',
+ props: {
+ label: t('publication.unpublish'),
+ isWarnable: true,
+ action: Actions.WORKFLOW_UNPUBLISH_PUBLICATION,
+ },
+ });
+
+ const {getLatestPublication} = useSubmission();
+ const latestPublication = getLatestPublication(submission);
+
+ if (latestPublication.id === selectedPublication.id) {
+ items.push({
+ component: 'WorkflowActionButton',
+ props: {
+ label: t('publication.createVersion'),
+ isSecondary: true,
+ action: Actions.WORKFLOW_CREATE_NEW_VERSION,
+ },
+ });
+ }
+ }
+
+ return items;
+ },
+ },
+ titleAbstract: {
+ getPrimaryItems: ({
+ submission,
+ selectedPublication,
+ pageInitConfig,
+ permissions,
+ }) => {
+ return [
+ {
+ component: 'WorkflowPublicationForm',
+ props: {
+ formName: 'titleAbstract',
+ submission,
+ publication: selectedPublication,
+ canEdit: permissions.canEditPublication,
+ },
+ },
+ ];
+ },
+ },
+ contributors: {
+ getPrimaryItems: ({
+ submission,
+ selectedPublication,
+ pageInitConfig,
+ permissions,
+ }) => {
+ return [
+ {
+ component: 'ContributorManager',
+ props: {
+ submission: submission,
+ publication: selectedPublication,
+ canEdit: permissions.canEditPublication,
+ },
+ },
+ ];
+ },
+ },
+ metadata: {
+ getPrimaryItems: ({
+ submission,
+ selectedPublication,
+ pageInitConfig,
+ permissions,
+ }) => {
+ return [
+ {
+ component: 'WorkflowPublicationForm',
+ props: {
+ formName: 'metadata',
+ submission,
+ publication: selectedPublication,
+ noFieldsMessage: 'No metadata fields are currently enabled.',
+ canEdit: permissions.canEditPublication,
+ },
+ },
+ ];
+ },
+ },
+ citations: {
+ getPrimaryItems: ({
+ submission,
+ selectedPublication,
+ pageInitConfig,
+ permissions,
+ }) => {
+ return [
+ {
+ component: 'WorkflowPublicationForm',
+ props: {
+ formName: 'reference',
+ submission,
+ publication: selectedPublication,
+ canEdit: permissions.canEditPublication,
+ },
+ },
+ ];
+ },
+ },
+ identifiers: {
+ getPrimaryItems: ({
+ submission,
+ selectedPublication,
+ pageInitConfig,
+ permissions,
+ }) => {
+ return [
+ {
+ component: 'WorkflowPublicationForm',
+ props: {
+ formName: 'identifier',
+ submission,
+ publication: selectedPublication,
+ canEdit: permissions.canEditPublication,
+ },
+ },
+ ];
+ },
+ },
+ jats: {
+ getPrimaryItems: ({
+ submission,
+ selectedPublication,
+ pageInitConfig,
+ permissions,
+ }) => {
+ return [
+ {
+ component: 'WorkflowPublicationJats',
+ props: {
+ canEdit: permissions.canEditPublication,
+ submission,
+ publication: selectedPublication,
+ },
+ },
+ ];
+ },
+ },
+ galleys: {
+ getPrimaryItems: ({submission, selectedPublication, permissions}) => {
+ return [
+ {
+ component: 'GalleyManager',
+ props: {
+ submission,
+ publication: selectedPublication,
+ canEdit: permissions.canEditPublication,
+ },
+ },
+ ];
+ },
+ },
+ license: {
+ getPrimaryItems: ({
+ submission,
+ selectedPublication,
+ pageInitConfig,
+ permissions,
+ }) => {
+ return [
+ {
+ component: 'WorkflowPublicationForm',
+ props: {
+ formName: 'permissionDisclosure',
+ submission,
+ publication: selectedPublication,
+ canEdit: permissions.canEditPublication,
+ },
+ },
+ ];
+ },
+ },
+ preprintEntry: {
+ getPrimaryItems: ({
+ submission,
+ selectedPublication,
+ pageInitConfig,
+ permissions,
+ }) => {
+ return [
+ {
+ component: 'WorkflowPublicationForm',
+ props: {
+ formName: 'issue',
+ submission,
+ publication: selectedPublication,
+ canEdit: permissions.canEditPublication,
+ },
+ },
+ ];
+ },
+ },
+};
diff --git a/src/pages/workflow/composables/useWorkflowNavigationConfig/useWorkflowNavigationConfigOPS.js b/src/pages/workflow/composables/useWorkflowNavigationConfig/useWorkflowNavigationConfigOPS.js
new file mode 100644
index 000000000..13867ecfa
--- /dev/null
+++ b/src/pages/workflow/composables/useWorkflowNavigationConfig/useWorkflowNavigationConfigOPS.js
@@ -0,0 +1,277 @@
+import {useSubmission} from '@/composables/useSubmission';
+import {useLocalize} from '@/composables/useLocalize';
+import {DashboardPageTypes} from '@/pages/dashboard/dashboardPageStore';
+
+const {t} = useLocalize();
+
+const StageColors = {
+ [pkp.const.WORKFLOW_STAGE_ID_SUBMISSION]: 'border-stage-desk-review',
+ [pkp.const.WORKFLOW_STAGE_ID_EXTERNAL_REVIEW]: 'border-stage-in-review',
+ [pkp.const.WORKFLOW_STAGE_ID_EDITING]: 'border-stage-copyediting',
+ [pkp.const.WORKFLOW_STAGE_ID_PRODUCTION]: 'border-stage-production',
+};
+
+export function getPublicationItem({label, name}) {
+ return {
+ key: `publication_${name}`,
+ label: label,
+ action: 'selectMenu',
+ actionArgs: {
+ primaryMenuItem: 'publication',
+ secondaryMenuItem: name,
+ title: getPublicationTitle(label),
+ },
+ };
+}
+
+export function getWorkflowItem({stageId, label, isActive, isDisabled, items}) {
+ return {
+ key: `workflow_${stageId}`,
+ label: label,
+ colorStripe: isActive ? StageColors[stageId] : null,
+ action: isDisabled ? undefined : 'selectMenu',
+ actionArgs: {
+ primaryMenuItem: 'workflow',
+ stageId: stageId,
+ title: getWorkflowTitle(label),
+ },
+ items,
+ };
+}
+
+export function getWorkflowTitle(stageLabel) {
+ return `${t('semicolon', {label: t('manager.workflow')})} ${stageLabel} `;
+}
+
+export function getPublicationTitle(publicationMenuTitle) {
+ return `${t('semicolon', {
+ label: t('submission.publication'),
+ })} ${publicationMenuTitle}`;
+}
+
+export function getReviewItems({submission, stageId, title}) {
+ const {getActiveStage, getCurrentReviewRound} = useSubmission();
+
+ const activeStage = getActiveStage(submission);
+
+ const activeReviewRound = getCurrentReviewRound(submission, stageId);
+
+ const reviewMenuItems = [];
+
+ const {getReviewRoundsForStage} = useSubmission();
+ const reviewRounds = getReviewRoundsForStage(submission, stageId);
+
+ reviewRounds.forEach((reviewRound) => {
+ reviewMenuItems.push(
+ getReviewItem({
+ stageId,
+ reviewRound,
+ isActive:
+ activeStage.id === stageId && activeReviewRound.id === reviewRound.id,
+ title: title,
+ }),
+ );
+ });
+
+ return reviewMenuItems;
+}
+
+export function getReviewItem({stageId, reviewRound, isActive, title}) {
+ return {
+ key: `workflow_${stageId}_${reviewRound.id}`,
+ label: t('dashboard.workflow.reviewRoundN', {number: reviewRound.round}),
+ colorStripe: isActive ? StageColors[stageId] : null,
+ action: 'selectMenu',
+ actionArgs: {
+ primaryMenuItem: 'workflow',
+ stageId: stageId,
+ reviewRoundId: reviewRound.id,
+ title: title,
+ },
+ };
+}
+
+export function useWorkflowNavigationConfigOPS(pageInitConfig) {
+ const {publicationSettings} = pageInitConfig;
+ const {t} = useLocalize();
+
+ function getWorkflowItems({submission}) {
+ const {getActiveStage} = useSubmission();
+
+ const activeStage = getActiveStage(submission);
+
+ const items = [];
+
+ items.push(
+ getWorkflowItem({
+ stageId: pkp.const.WORKFLOW_STAGE_ID_PRODUCTION,
+ label: t('dashboard.stage.production'),
+ isActive: activeStage.id === pkp.const.WORKFLOW_STAGE_ID_PRODUCTION,
+ }),
+ );
+
+ return items;
+ }
+
+ function getPublicationItemsAuthor({submission, permissions}) {
+ const items = [];
+
+ items.push(
+ getPublicationItem({
+ name: 'titleAbstract',
+ label: t('publication.titleAbstract'),
+ }),
+ );
+
+ items.push(
+ getPublicationItem({
+ name: 'contributors',
+ label: t('publication.contributors'),
+ }),
+ );
+
+ items.push(
+ getPublicationItem({
+ name: 'metadata',
+ label: t('submission.informationCenter.metadata'),
+ }),
+ );
+
+ if (publicationSettings.supportsCitations) {
+ items.push(
+ getPublicationItem({
+ name: 'citations',
+ label: t('submission.citations'),
+ }),
+ );
+ }
+
+ items.push(
+ getPublicationItem({
+ name: 'galleys',
+ label: t('submission.layout.galleys'),
+ }),
+ );
+
+ items.push(
+ getPublicationItem({
+ name: 'discussions',
+ label: t('submission.queries.production'),
+ }),
+ );
+
+ return items;
+ }
+
+ function getPublicationItemsEditorial({submission, permissions}) {
+ const items = [];
+
+ items.push(
+ getPublicationItem({
+ name: 'titleAbstract',
+ label: t('publication.titleAbstract'),
+ }),
+ );
+
+ items.push(
+ getPublicationItem({
+ name: 'contributors',
+ label: t('publication.contributors'),
+ }),
+ );
+
+ items.push(
+ getPublicationItem({
+ name: 'metadata',
+ label: t('submission.informationCenter.metadata'),
+ }),
+ );
+
+ if (publicationSettings.supportsCitations) {
+ items.push(
+ getPublicationItem({
+ name: 'citations',
+ label: t('submission.citations'),
+ }),
+ );
+ }
+
+ if (publicationSettings.identifiersEnabled) {
+ items.push(
+ getPublicationItem({
+ name: 'identifiers',
+ label: t('submission.identifiers'),
+ }),
+ );
+ }
+
+ if (permissions.canAccessProduction) {
+ items.push(
+ getPublicationItem({
+ name: 'galleys',
+ label: t('submission.layout.galleys'),
+ }),
+ );
+
+ items.push(
+ getPublicationItem({
+ name: 'license',
+ label: t('publication.publicationLicense'),
+ }),
+ );
+
+ items.push(
+ getPublicationItem({
+ name: 'preprintEntry',
+ label: t('preprint.entry'),
+ }),
+ );
+ }
+
+ return items;
+ }
+
+ function getMenuItems({submission, permissions}) {
+ if (!submission) {
+ return [];
+ }
+
+ const menuItems = [];
+
+ if (
+ pageInitConfig.dashboardPage === DashboardPageTypes.EDITORIAL_DASHBOARD
+ ) {
+ menuItems.push({
+ key: 'workflow',
+ label: t('manager.workflow'),
+ icon: 'Dashboard',
+ items: getWorkflowItems({submission, permissions}),
+ });
+ }
+
+ menuItems.push({
+ key: 'publication',
+ label: t('submission.publication'),
+ icon: 'MySubmissions',
+ items:
+ pageInitConfig.dashboardPage === DashboardPageTypes.EDITORIAL_DASHBOARD
+ ? getPublicationItemsEditorial({submission, permissions})
+ : getPublicationItemsAuthor({submission, permissions}),
+ });
+
+ return menuItems;
+ }
+
+ function getInitialSelectionItemKey(submission) {
+ if (
+ submission.stageId === pkp.const.WORKFLOW_STAGE_ID_PRODUCTION &&
+ submission.status !== pkp.const.STATUS_QUEUED
+ ) {
+ return `publication_titleAbstract`;
+ } else {
+ return `workflow_${submission.stageId}`;
+ }
+ }
+
+ return {getMenuItems, getInitialSelectionItemKey};
+}
diff --git a/src/pages/workflow/workflowStoreOPS.js b/src/pages/workflow/workflowStoreOPS.js
new file mode 100644
index 000000000..5faaba5aa
--- /dev/null
+++ b/src/pages/workflow/workflowStoreOPS.js
@@ -0,0 +1,248 @@
+import {computed, watch, markRaw} from 'vue';
+
+import {defineComponentStore} from '@/utils/defineComponentStore';
+import {
+ useWorkflowActions,
+ Actions as WorkflowActions,
+} from './composables/useWorkflowActions';
+
+import {
+ useWorkflowDecisions,
+ Actions as DecisionActions,
+} from './composables/useWorkflowDecisions';
+
+import {useDataChangedProvider} from '@/composables/useDataChangedProvider';
+
+import {wrapActionFns} from '@/utils/wrapActionFns';
+
+import {useWorkflowConfigOPS as useWorkflowConfig} from './composables/useWorkflowConfig/useWorkflowConfigOPS';
+import {useWorkflowNavigationConfigOPS as useWorkflowNavigationConfig} from './composables/useWorkflowNavigationConfig/useWorkflowNavigationConfigOPS';
+
+import {useWorkflowDataSubmissionPublication} from './composables/useWorkflowDataSubmissionPublication';
+import {useWorkflowPermissions} from './composables/useWorkflowPermissions';
+import {useWorkflowMenu} from './composables/useWorkflowMenu';
+import {useWorkflowItems} from './composables/useWorkflowItems';
+import {useSubmission} from '@/composables/useSubmission';
+
+import FileManager from '@/managers/FileManager/FileManager.vue';
+import ReviewerManager from '@/managers/ReviewerManager/ReviewerManager.vue';
+import DiscussionManager from '@/managers/DiscussionManager/DiscussionManager.vue';
+import ContributorManager from '@/managers/ContributorManager/ContributorManager.vue';
+import ParticipantManager from '@/managers/ParticipantManager/ParticipantManager.vue';
+import GalleyManager from '@/managers/GalleyManager/GalleyManager.vue';
+import WorkflowActionButton from './components/action/WorkflowActionButton.vue';
+import WorkflowNotificationDisplay from './components/primary/WorkflowNotificationDisplay.vue';
+import WorkflowPublicationForm from './components/publication/WorkflowPublicationForm.vue';
+import WorkflowPublicationVersionControl from './components/publication/WorkflowPublicationVersionControl.vue';
+import WorkflowChangeSubmissionLanguage from './components/publication/WorkflowChangeSubmissionLanguage.vue';
+import WorkflowPrimaryBasicMetadata from './components/primary/WorkflowPrimaryBasicMetadata.vue';
+import WorkflowPublicationRelationDropdownOPS from './components/publication/WorkflowPublicationRelationDropdownOPS.vue';
+import WorkflowSubmissionStatus from './components/primary/WorkflowSubmissionStatus.vue';
+import WorkflowPublicationEditDisabled from './components/publication/WorkflowPublicationEditDisabled.vue';
+
+export const useWorkflowStore = defineComponentStore('workflow', (props) => {
+ const dashboardPage = props.pageInitConfig.dashboardPage;
+
+ /**
+ * Submission & Publication
+ */
+ const {
+ submission,
+ submissionId,
+ selectPublicationId,
+ selectedPublication,
+ selectedPublicationId,
+ refetchSubmissionPublication,
+ } = useWorkflowDataSubmissionPublication({submissionId: props.submissionId});
+
+ const {getExtendedStage, getExtendedStageLabel} = useSubmission();
+
+ /**
+ * Current Stage Indication
+ */
+ const extendedStage = computed(
+ () => submission.value && getExtendedStage(submission.value),
+ );
+ const stageLabel = computed(
+ () => submission.value && getExtendedStageLabel(submission.value),
+ );
+
+ /**
+ * Data changes tracking
+ */
+ const {triggerDataChange} = useDataChangedProvider(() => {
+ return refetchSubmissionPublication();
+ });
+
+ /**
+ * UI Permissions
+ */
+ const {permissions} = useWorkflowPermissions({
+ submission,
+ selectedPublication,
+ });
+
+ /**
+ * Navigation
+ */
+
+ const {getMenuItems, getInitialSelectionItemKey} =
+ useWorkflowNavigationConfig(props.pageInitConfig);
+
+ const menuItems = computed(() =>
+ getMenuItems({
+ submission: submission.value,
+ permissions: permissions.value,
+ }),
+ );
+
+ const {
+ menuTitle,
+ navigateToMenu,
+ selectedMenuState,
+ selectedReviewRound,
+ setExpandedKeys,
+ sideMenuProps,
+ } = useWorkflowMenu({menuItems, submission});
+
+ setExpandedKeys(['workflow', 'publication']);
+
+ /** When submission is loaded initially - select relevant menu */
+ watch(submission, (newSubmission, oldSubmission) => {
+ // Once the submission is fetched, select relevant stage in navigaton
+ if (!oldSubmission && newSubmission) {
+ navigateToMenu(getInitialSelectionItemKey(newSubmission));
+ }
+ });
+
+ /**
+ * Expose workflow actions
+ *
+ */
+ const _workflowActionsFns = useWorkflowActions(props.pageInitConfig);
+ const workflowActions = wrapActionFns(
+ WorkflowActions,
+ _workflowActionsFns,
+ (actionFn, actionArgs, finishedCallback = null) =>
+ actionFn(
+ {
+ ...actionArgs,
+ submission: submission.value,
+ selectedPublication: selectedPublication.value,
+ reviewRoundId: selectedReviewRound.value?.id,
+ store,
+ },
+ (finishedData) => {
+ triggerDataChange();
+ if (finishedCallback) {
+ finishedCallback(finishedData);
+ }
+ },
+ ),
+ );
+
+ /**
+ * Expose decision functions
+ *
+ * */
+ const _workflowDecisionsFns = useWorkflowDecisions();
+ const decisionActions = wrapActionFns(
+ DecisionActions,
+ _workflowDecisionsFns,
+ (actionFn, actionArgs) =>
+ actionFn({
+ ...actionArgs,
+ submission: submission.value,
+ selectedPublication: selectedPublication.value,
+ reviewRoundId: selectedReviewRound.value?.id,
+ }),
+ );
+
+ /**
+ * Items
+ *
+ * */
+
+ const _workflowConfigFns = useWorkflowConfig({dashboardPage});
+
+ const {
+ headerItems,
+ primaryItems,
+ secondaryItems,
+ actionItems,
+ publicationControlsLeft,
+ publicationControlsRight,
+ } = useWorkflowItems(_workflowConfigFns, () => ({
+ selectedMenuState: selectedMenuState.value,
+ submission: submission.value,
+ pageInitConfig: props.pageInitConfig,
+ selectedPublication: selectedPublication.value,
+ selectedPublicationId: selectedPublicationId.value,
+ selectedReviewRound: selectedReviewRound.value,
+ permissions: permissions.value,
+ publicationSettings: props.pageInitConfig.publicationSettings,
+ }));
+
+ const Components = markRaw({
+ FileManager,
+ ReviewerManager,
+ DiscussionManager,
+ ContributorManager,
+ ParticipantManager,
+ GalleyManager,
+ WorkflowActionButton,
+ WorkflowNotificationDisplay,
+ WorkflowPrimaryBasicMetadata,
+ WorkflowPublicationForm,
+ WorkflowPublicationRelationDropdownOPS,
+ WorkflowPublicationVersionControl,
+ WorkflowChangeSubmissionLanguage,
+ WorkflowSubmissionStatus,
+ WorkflowPublicationEditDisabled,
+ });
+
+ const store = {
+ dashboardPage,
+ submission,
+ submissionId,
+ selectedPublication,
+ selectPublicationId,
+ extendedStage,
+ stageLabel,
+
+ /**
+ * Navigation
+ * */
+ sideMenuProps,
+ selectedMenuState,
+ navigateToMenu,
+
+ /** Actions
+ *
+ */
+ ...workflowActions,
+ ...decisionActions,
+
+ /**
+ * Summary
+ */
+ menuTitle,
+ headerItems,
+ primaryItems,
+ secondaryItems,
+ actionItems,
+ publicationControlsLeft,
+ publicationControlsRight,
+
+ permissions,
+ /**
+ * Expose for extensions
+ */
+
+ _workflowActionsFns,
+ _workflowDecisionsFns,
+
+ Components,
+ };
+ return store;
+});