Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
326ecfb
feat(ui): add new themed table component
yannisbarlas Jul 16, 2026
93e62f5
refactor(ui): first pass at new manusccripts table
yannisbarlas Jul 28, 2026
bcd56cf
feat(ui): table search should reset on clear
yannisbarlas Jul 30, 2026
b6e7bc5
Merge branch 'staging' into dashboard-tables
yannisbarlas Aug 3, 2026
8c88bfb
refactor(*): remake manuscript search to only match manuscript table …
yannisbarlas Aug 4, 2026
692a532
feat(ui): table ui search \& filter
yannisbarlas Aug 6, 2026
71b3e46
feat(ui): add person datatype to new table
yannisbarlas Aug 6, 2026
a80b8bb
feat(ui): new reviewer status summary in manuscripts table
yannisbarlas Aug 7, 2026
58d7f0c
feat(ui): add title rendering options to new table
yannisbarlas Aug 7, 2026
7a812c1
feat(ui): multi value options in new table
yannisbarlas Aug 10, 2026
6622396
feat(ui): handle rich text in the new table
yannisbarlas Aug 10, 2026
8c3b4f8
feat(ui): add editable option to new table
yannisbarlas Aug 11, 2026
c1d0f18
feat(ui): selection actions in new table
yannisbarlas Aug 12, 2026
f9833ea
feat(ui): add view archived toggle to new table
yannisbarlas Aug 12, 2026
ef80f62
fix(ui): fix new table not respecting changed theme
yannisbarlas Aug 14, 2026
13d9534
feat(ui): handle two-tone manuscript statuses in new table
yannisbarlas Aug 14, 2026
1d9ccb1
feat(ui): handle links in titles in new table
yannisbarlas Aug 14, 2026
833a99b
feat(ui): add column sorting to new table
yannisbarlas Aug 14, 2026
c5d9de8
feat(ui): sort by short id in new table
yannisbarlas Aug 17, 2026
195a5f4
feat(ui): sort dates in new table
yannisbarlas Aug 17, 2026
2d009ba
feat(ui): get sort and filter working on dates in new table on submis…
yannisbarlas Aug 17, 2026
13e8a1e
feat(ui): make statuses filterable in submissions table
yannisbarlas Aug 18, 2026
7dc7bca
feat(ui): sort title and rich text in new table
yannisbarlas Aug 18, 2026
e4464b8
feat(ui): make free text sortable in new table
yannisbarlas Aug 18, 2026
3798289
feat(ui): make manuscript versions count column non-sortable in new t…
yannisbarlas Aug 18, 2026
4adb7c3
feat(ui): let search and sort co-exist on new table
yannisbarlas Aug 18, 2026
6f46d42
chore(*): backup
yannisbarlas Aug 19, 2026
b42f433
feat(client): flesh out manuscripts table hook
yannisbarlas Aug 20, 2026
b04f865
feat(ui): search ux
yannisbarlas Aug 21, 2026
23479dd
feat(client): add bundle analyzer
yannisbarlas Aug 24, 2026
baa3bfc
feat(client): replace reviewer table
yannisbarlas Aug 24, 2026
b14a89b
feat(client): replace editor table with new ui
yannisbarlas Aug 24, 2026
e7a3817
feat(client): use new manuscripts table for admin manuscripts
yannisbarlas Aug 25, 2026
2d3c95f
feat(client): clean up download json manuscripts output
yannisbarlas Aug 25, 2026
d101826
fix(client): make sure all special column titles are used and in tran…
yannisbarlas Aug 25, 2026
591cc79
fix(client): fix editor special column in manuscripts table
yannisbarlas Aug 25, 2026
22622ae
fix(client): change list of statuses based on instance name
yannisbarlas Aug 25, 2026
d6b418f
fix(client): use created date of first version to display in table
yannisbarlas Aug 25, 2026
bdc3862
fix(ui): fix table horizontal scrolling when squeezed
yannisbarlas Aug 25, 2026
0b906ae
refactor(ui): organize the manuscripts table file
yannisbarlas Aug 25, 2026
16191e6
chore(client): drop dead code and unused dependencies
yannisbarlas Aug 25, 2026
d16b964
chore(client): set up bundle analyzer outside of coko client
yannisbarlas Aug 26, 2026
424eb09
chore(client): drop unused regenerator-runtime
yannisbarlas Aug 26, 2026
4c23fd9
test(*): fix journal cypress tests up to 003
yannisbarlas Aug 26, 2026
2eaff34
test(*): fix cypress tests up to 103
yannisbarlas Aug 27, 2026
01929a8
test(*): fix cypress tests up to 107
yannisbarlas Aug 27, 2026
f03a065
test(*): fix all cypress tests locally
yannisbarlas Aug 27, 2026
3c82116
chore(*): merge staging
yannisbarlas Aug 27, 2026
ce66485
chore(*): fix linter errors
yannisbarlas Aug 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,4 @@ packages/server/scripts/local
!**/.yarn/versions

.claude
stats.html
4 changes: 3 additions & 1 deletion cypress/e2e/a-journal/002-assign_reviewers_spec.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ describe('Editor assigning reviewers', () => {

// Go to dashboard and verify number of invited reviewer
Menu.clickDashboard()
cy.getByDataTestId('donut-center-label').contains('6')
cy.getByDataTestId('statusCounts')
.find('[role="img"]')
.should('have.length', 6)
})
})
35 changes: 20 additions & 15 deletions cypress/e2e/a-journal/003-review_spec.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,20 +50,20 @@ describe('Completing reviews', () => {

cy.wait(1000)
DashboardPage.clickDashboardTab(2)
cy.get('[fill="#56b984"]')
.should('be.visible')
.trigger('mouseover', { force: true })
cy.contains('Completed: 3')
cy.wait(1000)
cy.get('[fill="#fff2cd"]').should('be.visible').trigger('mouseover')
cy.contains('Invited: 1')
cy.get('[fill="#d7efd4"]').should('be.visible').trigger('mouseover')
cy.contains('Accepted: 1')

cy.get('[fill="#c23d20"]').should('be.visible').trigger('mouseover')
cy.contains('Declined: 1')

cy.get('[data-testid="control-panel-team"]').click()
cy.getByDataTestId('statusCounts')
.find('[role="img"][aria-label$="Completed"]')
.should('have.length', 3)
cy.getByDataTestId('statusCounts')
.find('[role="img"][aria-label$="Invited"]')
.should('have.length', 1)
cy.getByDataTestId('statusCounts')
.find('[role="img"][aria-label$="Accepted"]')
.should('have.length', 1)
cy.getByDataTestId('statusCounts')
.find('[role="img"][aria-label$="Declined"]')
.should('have.length', 1)

cy.get('[data-testid="control-link"]').click()
cy.awaitDisappearSpinner()
cy.get(
'[data-testid=kanban] > :nth-child(1) > [data-testid=kanban-cards-wrapper] > [data-testid=kanban-card]',
Expand Down Expand Up @@ -92,7 +92,9 @@ const doReview = (name, reviewData) => {
// Accpet Review Request Workflow
if (reviewData.verdict === 'accept') {
DashboardPage.clickAcceptReviewButton()
cy.contains('button', 'Do Review').should('exist')
cy.contains('Accept this review invitation?').should('be.visible')
cy.contains('button', 'OK').click()
DashboardPage.getDoReviewButton().should('contain', 'Do Review')

// Only do the review if there'a comment present
if (reviewData.comment) {
Expand All @@ -116,6 +118,7 @@ const doReview = (name, reviewData) => {

// Verify the review got completed
cy.get('nav').contains('Dashboard').click()
cy.url().should('contain', '/dashboard/reviews')
DashboardPage.getDoReviewButton().should('contain', 'View')
cy.getByDataTestId('menu-user').click()
cy.contains('Logout').click()
Expand All @@ -125,6 +128,8 @@ const doReview = (name, reviewData) => {
// Reject Review Request Workflow
if (reviewData.verdict === 'reject') {
DashboardPage.clickRejectReviewButton()
cy.contains('Decline this review invitation?').should('be.visible')
cy.contains('button', 'OK').click()
DashboardPage.getDoReviewButton().should('not.exist')
cy.getByDataTestId('menu-user').click()
cy.contains('Logout').click()
Expand Down
2 changes: 1 addition & 1 deletion cypress/e2e/a-journal/004-assigning_editor_spec.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ describe('Assigning editors and decision reject', () => {
cy.wait(1000)
Menu.clickManuscripts()

ManuscriptsPage.selectOptionWithText('Control')
ManuscriptsPage.clickControlLink()

cy.wait(1000)
ControlPage.clickAssignSeniorEditorDropdown()
Expand Down
8 changes: 3 additions & 5 deletions cypress/e2e/a-journal/005-decision_spec.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ describe('Completing a decision', () => {

cy.wait(2000)
DashboardPage.clickManuscriptNavButton()
ManuscriptsPage.selectOptionWithText('Control')
ManuscriptsPage.clickControlLink()
ControlPage.getAssignSeniorEditorDropdown().click({ force: true })
cy.contains(name.role.seniorEditor).click({ force: true })
})
Expand Down Expand Up @@ -61,7 +61,7 @@ describe('Completing a decision', () => {

/* View Decision as an Author */
cy.login(name.role.author, dashboard) // Login as an Author
DashboardPage.getSubmittedManuscript().click() // Click on first MySubmission
DashboardPage.clickSubmissionActionLink() // Click on first MySubmission

// Verify Decision Content
DashboardPage.getDecisionField(0).should('contain', decisionTextContent)
Expand All @@ -77,9 +77,7 @@ describe('Completing a decision', () => {
)
SubmissionFormPage.clickSubmitResearch()
SubmissionFormPage.clickSubmitYourManuscript()
DashboardPage.getSubmittedManuscript()
.contains('test pdf')
.should('exist') // Verify new submission got created
DashboardPage.getSubmissionTitle().contains('test pdf').should('exist') // Verify new submission got created
})
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,16 @@ describe('Checking manuscripts page: label selection and tooltip', () => {

it('verifies the selected label after choosing from the dropdown', () => {
cy.contains('div', 'Manuscripts').should('exist')
// Click the Select button
ManuscriptsPage.getSelectButton().should('be.visible')
ManuscriptsPage.clickArticleLabel(-1)
ManuscriptsPage.getArticleLabel().should('be.visible')

// Function to select a label and verify it
const selectLabelAndVerify = label => {
cy.getByDataTestId('label-dropdown-element').click()
cy.screenshot('before-dropdown')
cy.get('body').then($body => {
if (!$body.find('[data-testid=label-dropdown-menu]').length) {
cy.log('Dropdown not found in body!')
}
})

cy.get('[data-testid=label-dropdown-menu]').contains(label).click()
ManuscriptsPage.getLabelDropdown().should('contain', label)
ManuscriptsPage.clickArticleLabel(-1)
cy.getByDataTestId('select-dropdown')
.find('[data-testid="editable-option"]')
.contains(label)
.click({ force: true })
ManuscriptsPage.getArticleLabel().eq(-1).should('contain', label)
Menu.clickManuscriptsAndAssertPageLoad()
}

Expand All @@ -51,11 +45,10 @@ describe('Checking manuscripts page: label selection and tooltip', () => {
labels.forEach(selectLabelAndVerify)

// Unset the custom label
cy.get('[data-testid=label-dropdown-styled-button]').eq(0).click()
cy.get('[data-testid=manuscripts-table-styled-button]').should(
'contain',
'Select',
)
ManuscriptsPage.clickArticleLabelClear(-1)
ManuscriptsPage.getArticleLabel()
.eq(-1)
.should('not.contain', 'Ready to publish')
})

context('tooltip tests', () => {
Expand All @@ -69,7 +62,8 @@ describe('Checking manuscripts page: label selection and tooltip', () => {
it('check no tooltip for empty abstract', () => {
Menu.clickManuscriptsAndAssertPageLoad()
ManuscriptsPage.getTooltipText().should('not.exist')
ManuscriptsPage.getTooltipIcon().should('not.exist')
ManuscriptsPage.getTooltipIcon().should('be.visible').click()
ManuscriptsPage.getTooltipText().should('contain', 'No abstract provided')
})

it('check tooltip text', () => {
Expand All @@ -78,28 +72,29 @@ describe('Checking manuscripts page: label selection and tooltip', () => {
SubmissionFormPage.fillInAbstractColab(data.abstract)
Menu.clickManuscriptsAndAssertPageLoad()
ManuscriptsPage.getTooltipText().should('not.exist')
ManuscriptsPage.getTooltipIcon()
.should('be.visible')
.trigger('mouseover')
ManuscriptsPage.getTooltipIcon().should('be.visible').click()
ManuscriptsPage.getTooltipText()
.should('contain', data.abstract)
.and('not.contain', '<p class="paragraph">')
})
})

it('check length for the tooltip text, to be less than 1000', () => {
it('truncates a long abstract to 60 words', () => {
const longAbstract = Array.from(
{ length: 65 },
(_, i) => `word${i + 1}`,
).join(' ')

cy.contains('Continue Submission').click()
cy.fixture('submission_form_data').then(data => {
SubmissionFormPage.fillInAbstractColab(
data.abstractWithMoreThan1000Characters,
)
Menu.clickManuscriptsAndAssertPageLoad()
ManuscriptsPage.getTooltipText().should('not.exist')
ManuscriptsPage.getTooltipIcon().trigger('mouseover')
ManuscriptsPage.getTooltipText()
.should('contain', '...')
.should('have.lengthOf.lessThan', 1000)
})
SubmissionFormPage.fillInAbstractColab(longAbstract)
Menu.clickManuscriptsAndAssertPageLoad()
ManuscriptsPage.getTooltipText().should('not.exist')
ManuscriptsPage.getTooltipIcon().click()
ManuscriptsPage.getTooltipText()
.should('contain', '...')
.should($el => {
expect($el.text().trim().split(/\s+/).length).to.be.at.most(61)
})
})
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ describe('manuscripts page tests - Filter, sort, bulk select, archive', () => {
context('filter and sort articles', () => {
it('filter per status', () => {
ManuscriptsPage.getTableRowsCount().should('eq', 3)
ManuscriptsPage.clickStatus(-1)
ManuscriptsPage.filterColumnByValue('status', 'Unsubmitted')
ManuscriptsPage.getTableRowsCount().should('eq', 2)
ManuscriptsPage.getStatus(0).should('contain', 'Unsubmitted')
cy.url().should('contain', 'new')
Expand All @@ -97,18 +97,15 @@ describe('manuscripts page tests - Filter, sort, bulk select, archive', () => {
cy.url().should('contain', 'readyToEvaluate')
ManuscriptsPage.getLabelRow(0).should('contain', 'Ready to evaluate')
ManuscriptsPage.getLabelRow(1).should('contain', 'Ready to evaluate')
ManuscriptsPage.getLabelRow(2).should('contain', 'Ready to evaluate')
Menu.clickManuscriptsAndAssertPageLoad()
ManuscriptsPage.selectCustomStatus('Evaluated')
ManuscriptsPage.getTableRowsCount().should('eq', 1)
cy.url().should('contain', 'evaluated')
ManuscriptsPage.getLabelRow(0).should('contain', 'Evaluated')
ManuscriptsPage.getLabelRow(1).should('contain', 'Evaluated')
Menu.clickManuscriptsAndAssertPageLoad()
ManuscriptsPage.selectCustomStatus('Ready to publish')
ManuscriptsPage.assertNoTableRows()
cy.url().should('contain', 'readyToPublish')
ManuscriptsPage.getLabelRow(0).should('contain', 'Ready to publish')
})
})

Expand All @@ -134,7 +131,7 @@ describe('manuscripts page tests - Filter, sort, bulk select, archive', () => {
ManuscriptsPage.clickDelete()
ManuscriptsPage.getConfirmationMessageForBulkDelete().should(
'contain',
'Please confirm you wish to archive the selected manuscripts.',
'Archive 2 manuscripts?',
)
ManuscriptsPage.clickConfirm()
ManuscriptsPage.getConfirmationMessageForBulkDelete().should('not.exist')
Expand Down
17 changes: 10 additions & 7 deletions cypress/e2e/b-colab-prc/104-control_page_spec.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 +175,10 @@ describe('control page tests', () => {
cy.login(name.role.admin, manuscripts)
cy.awaitDisappearSpinner()
Menu.clickManuscriptsAndAssertPageLoad()
ManuscriptsPage.selectOptionWithText('Control')
ManuscriptsPage.clickControlLink()
cy.awaitDisappearSpinner()
ControlPage.getAssignSeniorEditorDropdown().should('be.visible')
cy.awaitDisappearSpinner()
ControlPage.inviteReviewer(name.role.reviewers[1])
cy.reload()
cy.get('input[value = "isCollaborative"]').should('not.exist')
Expand All @@ -188,8 +189,10 @@ describe('control page tests', () => {
cy.wait(1000)
DashboardPage.clickDashboardTab(1)
DashboardPage.clickAcceptReviewButton()
cy.contains('Accept this review invitation?').should('be.visible')
cy.contains('button', 'OK').click()

cy.contains('button', 'Do Review').should('exist')
DashboardPage.getDoReviewButton().should('contain', 'Do Review')
DashboardPage.clickDoReview()
cy.fixture('submission_form_data').then(data => {
cy.contains('div', 'Metadata').should('be.visible')
Expand All @@ -202,7 +205,7 @@ describe('control page tests', () => {
ReviewPage.clickSubmitButton()
ReviewPage.clickConfirmSubmitButton()

cy.get('[name="submission.$title"]').contains('test pdf')
cy.get('[data-testid="submission.$title"]').contains('test pdf')
})
})
})
Expand All @@ -211,7 +214,7 @@ describe('control page tests', () => {
cy.fixture('role_names').then(name => {
cy.login(name.role.admin, manuscripts)
cy.awaitDisappearSpinner()
ManuscriptsPage.selectOptionWithText('Control')
ManuscriptsPage.clickControlLink()
cy.awaitDisappearSpinner()
ControlPage.getAssignSeniorEditorDropdown().should('be.visible')
})
Expand All @@ -223,7 +226,7 @@ describe('control page tests', () => {
ControlPage.getHideReviewerNameCheckbox().should('be.checked')
cy.fixture('role_names').then(name => {
cy.login(name.role.reviewers[1], dashboard)
cy.get('[data-testid="submission.$title"]:last').click()
DashboardPage.clickDoReview()
cy.get('[data-testid=tab-container]').contains('Review').click()
ControlPage.getReviewerName().should(
'not.contain',
Expand All @@ -239,7 +242,7 @@ describe('control page tests', () => {
ControlPage.getHideReviewerNameCheckbox('should', 'not.be.checked')
cy.fixture('role_names').then(name => {
cy.login(name.role.reviewers[1], dashboard)
cy.get('[data-testid="submission.$title"]:last').click()
DashboardPage.clickDoReview()
cy.get('[data-testid=tab-container]').contains('Review').click()
ControlPage.getReviewerName().should('contain', name.role.reviewers[1])
})
Expand Down Expand Up @@ -304,7 +307,7 @@ describe('control page tests', () => {
cy.awaitDisappearSpinner()
DashboardPage.getHeader().should('be.visible')
Menu.clickManuscriptsAndAssertPageLoad()
ManuscriptsPage.selectOptionWithText('Control')
ManuscriptsPage.clickControlLink()
cy.awaitDisappearSpinner()
cy.contains('Tasks & Notifications').click()
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,9 @@ Cypress.Commands.add(
cy.wait(1000)
DashboardPage.clickDashboardTab(1)
DashboardPage.clickAcceptReviewButton()
cy.contains('button', 'Do Review').should('be.visible')
cy.contains('Accept this review invitation?').should('be.visible')
cy.contains('button', 'OK').click()
DashboardPage.getDoReviewButton().should('contain', 'Do Review')
DashboardPage.clickDoReviewAndVerifyPageLoaded()
cy.contains('div', 'Metadata').should('be.visible')

Expand All @@ -121,7 +123,7 @@ Cypress.Commands.add(

Cypress.Commands.add('submitDecision', (decisionText, decisionAction) => {
cy.awaitDisappearSpinner()
ManuscriptsPage.selectOptionWithText('Control')
ManuscriptsPage.clickControlLink()
ControlPage.clickDecisionTab(1)
ControlPage.fillInDecision(decisionText)

Expand Down
6 changes: 2 additions & 4 deletions cypress/e2e/b-colab-prc/107-new_manuscript_version_spec.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ describe('checking manuscript version', () => {
cy.wait(1000)
cy.login(name.role.author, dashboard)
/* Click on first MySubmission */
DashboardPage.getSubmittedManuscript().click()
DashboardPage.clickSubmissionActionLink()

/* Verify Decision Content */
DashboardPage.getDecisionField(0).should('contain', decisionTextContent)
Expand All @@ -76,9 +76,7 @@ describe('checking manuscript version', () => {
SubmissionFormPage.clickSubmitResearch()
SubmissionFormPage.clickSubmitYourManuscript()
/* Verify new submission got created */
DashboardPage.getSubmittedManuscript()
.contains('test pdf')
.should('exist')
DashboardPage.getSubmissionTitle().contains('test pdf').should('exist')

/* Login as editor and check the new version submission form */
cy.login(name.role.seniorEditor, dashboard)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ describe('validating required field and doi values in submission form', () => {
})
ManuscriptsPage.getTableHead().should('be.visible')
Menu.clickManuscripts()
ManuscriptsPage.getOptionsElifeText('Evaluation').click()
ManuscriptsPage.clickEvaluationLink()
})

context('check the Submission form based on form builder', () => {
Expand Down Expand Up @@ -75,7 +75,7 @@ describe('validating required field and doi values in submission form', () => {
SubmissionFormPage.clickElifeSubmitResearch()

// check for the submission form contains doi
ManuscriptsPage.getOptionsElifeText('Evaluation').click()
ManuscriptsPage.clickEvaluationLink()
SubmissionFormPage.getDoi().should(
'have.value',
data.doi.split('https://doi.org/')[1],
Expand Down
Loading
Loading