1
0
mirror of https://github.com/quay/quay.git synced 2025-04-18 10:44:06 +03:00

ui: Upgrade to PatternFly v5 (PROJQUAY-6085) (#2281)

Upgrade to PatternFly v5
This commit is contained in:
Jeff Puzzo 2023-10-06 10:11:36 -04:00 committed by GitHub
parent a888350739
commit 033bcf6772
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
122 changed files with 13005 additions and 1217 deletions

View File

@ -2,8 +2,8 @@
"description": "Quay Integration Testing",
"license": "UNLICENSED",
"repository": {
"type" : "git",
"url" : "https://github.com/quay/quay.git",
"type": "git",
"url": "https://github.com/quay/quay.git",
"directory": "integration_tests"
},
"homepage": "https://github.com/quay/quay/blob/master/integration_tests/README.md",
@ -17,9 +17,9 @@
"debug-test-suite": "TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' node -r ts-node/register --inspect-brk ./node_modules/.bin/protractor protractor.conf.ts"
},
"dependencies": {
"@patternfly/patternfly": "2.6.7",
"@patternfly/react-charts": "^3.4.5",
"@patternfly/react-core": "3.16.16",
"@patternfly/patternfly": "^5.0.4",
"@patternfly/react-charts": "^7.1.0",
"@patternfly/react-core": "^5.1.0",
"brace": "0.11.x",
"classnames": "2.x",
"core-js": "2.x",
@ -34,9 +34,6 @@
"memoize-one": "5.x",
"murmurhash-js": "1.0.x",
"openshift-logos-icon": "1.7.1",
"patternfly": "^3.59.1",
"patternfly-react": "2.32.3",
"patternfly-react-extensions": "2.18.4",
"plotly.js": "1.47.3",
"prop-types": "15.6.x",
"react": "16.8.6",
@ -129,4 +126,3 @@
"node": ">=8.x"
}
}

11740
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -37,7 +37,7 @@ describe('Default permissions page', () => {
cy.get(`[data-testid="${createdBy}-WRITE"]`).click();
// verify success alert
cy.get('.pf-c-alert.pf-m-success')
cy.get('.pf-v5-c-alert.pf-m-success')
.contains(`Permission updated successfully to: owners`)
.should('exist');
});
@ -55,7 +55,7 @@ describe('Default permissions page', () => {
.click();
// verify success alert
cy.get('.pf-c-alert.pf-m-success')
cy.get('.pf-v5-c-alert.pf-m-success')
.contains(
`Permission created by: ${permissionToBeDeleted} successfully deleted`,
)
@ -84,7 +84,7 @@ describe('Default permissions page', () => {
cy.get('[data-testid="create-permission-button"]').click();
// verify success alert
cy.get('.pf-c-alert.pf-m-success')
cy.get('.pf-v5-c-alert.pf-m-success')
.contains(
`Successfully created default permission for creator: ${createdBy}`,
)
@ -109,7 +109,7 @@ describe('Default permissions page', () => {
cy.get('[data-testid="create-permission-button"]').click();
// verify success alert
cy.get('.pf-c-alert.pf-m-success')
cy.get('.pf-v5-c-alert.pf-m-success')
.contains(`Successfully applied default permission to: ${appliedTo}`)
.should('exist');
});
@ -137,7 +137,7 @@ describe('Default permissions page', () => {
cy.get('[data-testid="create-team-confirm"]').click();
// verify success alert
cy.get('.pf-c-alert.pf-m-success')
cy.get('.pf-v5-c-alert.pf-m-success')
.contains(`Successfully created new team: ${newTeam}`)
.should('exist');
@ -199,7 +199,7 @@ describe('Default permissions page', () => {
cy.get('[data-testid="create-permission-button"]').click();
// verify success alert
cy.get('.pf-c-alert.pf-m-success').should('exist');
cy.get('.pf-v5-c-alert.pf-m-success').should('exist');
});
it('Can create default permission applied to a new team along with creating new robot account from the drawer', () => {
@ -227,7 +227,7 @@ describe('Default permissions page', () => {
cy.get('[data-testid="create-team-confirm"]').click();
// verify success alert
cy.get('.pf-c-alert.pf-m-success')
cy.get('.pf-v5-c-alert.pf-m-success')
.contains(`Successfully created new team: ${newTeam}`)
.should('exist');
@ -294,7 +294,7 @@ describe('Default permissions page', () => {
cy.get('[data-testid="create-permission-button"]').click();
// verify success alert
cy.get('.pf-c-alert.pf-m-success').should('exist');
cy.get('.pf-v5-c-alert.pf-m-success').should('exist');
});
it('Can create default permission for repository creator with new robot account', () => {
@ -339,7 +339,7 @@ describe('Default permissions page', () => {
// step - Review and Finish
cy.get('[data-testid="review-and-finish-btn"]').click();
cy.get('.pf-c-alert.pf-m-success')
cy.get('.pf-v5-c-alert.pf-m-success')
.contains(
`Successfully created robot account with robot name: ${orgName}+${newRobotName}`,
)
@ -364,7 +364,7 @@ describe('Default permissions page', () => {
cy.get('[data-testid="create-permission-button"]').click();
// verify success alert
cy.get('.pf-c-alert.pf-m-success')
cy.get('.pf-v5-c-alert.pf-m-success')
.contains(
`Successfully created default permission for creator: ${orgName}+${newRobotName}`,
)

View File

@ -101,7 +101,7 @@ describe('Repository Settings - Permissions', () => {
cy.get('#permissions-select-all').click();
cy.contains('Actions').click();
cy.contains('Change Permissions').click();
cy.get('#change-permissions-menu').within(() => {
cy.get('[data-testid="change-permissions-menu-list"]').within(() => {
cy.contains('Write').click();
});
const user1Row = cy.get('tr:contains("user1")');

View File

@ -47,7 +47,7 @@ describe('Robot Accounts Page', () => {
cy.get('#create-robot-submit')
.click()
.then(() => {
cy.get('.pf-c-alert.pf-m-success')
cy.get('.pf-v5-c-alert.pf-m-success')
.contains(
'Successfully created robot account with robot name: testorg+newtestrob',
)
@ -82,7 +82,7 @@ describe('Robot Accounts Page', () => {
cy.get('[id="bulk-delete-modal"]')
.within(() => cy.get('button:contains("Delete")').click())
.then(() => {
cy.get('.pf-c-alert.pf-m-success')
cy.get('.pf-v5-c-alert.pf-m-success')
.contains('Successfully deleted robot account')
.should('exist');
cy.get('#robot-account-search').clear().type('testrobot2');
@ -100,7 +100,7 @@ describe('Robot Accounts Page', () => {
.find('button:contains("Save")')
.click()
.then(() => {
cy.get('.pf-c-alert.pf-m-success')
cy.get('.pf-v5-c-alert.pf-m-success')
.contains('Successfully updated repository permission')
.should('exist');
cy.get('footer').find('button:contains("Save")').should('not.exist');
@ -127,7 +127,7 @@ describe('Robot Accounts Page', () => {
.find('button:contains("Save")')
.click()
.then(() => {
cy.get('.pf-c-alert.pf-m-success')
cy.get('.pf-v5-c-alert.pf-m-success')
.contains('Successfully updated repository permission')
.should('exist');
cy.get('[data-label="Permissions"]').each(($item) => {
@ -138,16 +138,16 @@ describe('Robot Accounts Page', () => {
it('Create Robot Acct Wizard For Org', () => {
cy.visit('/organization/testorg');
cy.get('.pf-c-tabs').get('ul').contains('Robot accounts');
cy.get('.pf-c-tabs').get('ul').contains('Robot accounts').click();
cy.get('.pf-v5-c-tabs').get('ul').contains('Robot accounts');
cy.get('.pf-v5-c-tabs').get('ul').contains('Robot accounts').click();
cy.get('#create-robot-account-btn').click();
cy.get('#create-robot-account-modal')
.get('.pf-c-wizard__nav')
.get('.pf-c-wizard__nav-item')
.get('.pf-v5-c-wizard__nav')
.get('.pf-v5-c-wizard__nav-item')
.should('have.length', 5);
cy.get('#create-robot-account-modal')
.get('.pf-c-wizard__nav')
.get('.pf-c-wizard__nav-item')
.get('.pf-v5-c-wizard__nav')
.get('.pf-v5-c-wizard__nav-item')
.should((items) => {
expect(items[0]).to.contain.text('Robot name and description');
expect(items[1]).to.contain.text('Add to team (optional)');
@ -156,18 +156,18 @@ describe('Robot Accounts Page', () => {
expect(items[4]).to.contain.text('Review and Finish');
});
cy.get('#create-robot-account-modal')
.get('.pf-c-wizard__nav')
.get('.pf-c-wizard__nav-item')
.get('.pf-v5-c-wizard__nav')
.get('.pf-v5-c-wizard__nav-item')
.contains('Review and Finish')
.click();
cy.get('.pf-c-wizard__main-body')
cy.get('.pf-v5-c-wizard__main-body')
.find('form')
.find('.pf-c-toggle-group')
.find('.pf-v5-c-toggle-group')
.find('button')
.should('have.length', 3);
cy.get('.pf-c-wizard__main-body')
cy.get('.pf-v5-c-wizard__main-body')
.find('form')
.find('.pf-c-toggle-group__item')
.find('.pf-v5-c-toggle-group__item')
.should((items) => {
expect(items[0]).to.contain.text('Teams');
expect(items[1]).to.contain.text('Repositories');
@ -177,34 +177,34 @@ describe('Robot Accounts Page', () => {
it('Create Robot Acct Wizard For User Namespace', () => {
cy.visit('/organization/user1');
cy.get('.pf-c-tabs').get('ul').contains('Robot accounts');
cy.get('.pf-c-tabs').get('ul').contains('Robot accounts').click();
cy.get('.pf-v5-c-tabs').get('ul').contains('Robot accounts');
cy.get('.pf-v5-c-tabs').get('ul').contains('Robot accounts').click();
cy.contains('button', 'Create robot account').click();
cy.get('#create-robot-account-modal')
.get('.pf-c-wizard__nav')
.get('.pf-c-wizard__nav-item')
.get('.pf-v5-c-wizard__nav')
.get('.pf-v5-c-wizard__nav-item')
.should('have.length', 3);
cy.get('#create-robot-account-modal')
.get('.pf-c-wizard__nav')
.get('.pf-c-wizard__nav-item')
.get('.pf-v5-c-wizard__nav')
.get('.pf-v5-c-wizard__nav-item')
.should((items) => {
expect(items[0]).to.contain.text('Robot name and description');
expect(items[1]).to.contain.text('Add to repository (optional)');
expect(items[2]).to.contain.text('Review and Finish');
});
cy.get('#create-robot-account-modal')
.get('.pf-c-wizard__nav')
.get('.pf-c-wizard__nav-item')
.get('.pf-v5-c-wizard__nav')
.get('.pf-v5-c-wizard__nav-item')
.contains('Review and Finish')
.click();
cy.get('.pf-c-wizard__main-body')
cy.get('.pf-v5-c-wizard__main-body')
.find('form')
.find('.pf-c-toggle-group')
.find('.pf-v5-c-toggle-group')
.find('button')
.should('have.length', 1);
cy.get('.pf-c-wizard__main-body')
cy.get('.pf-v5-c-wizard__main-body')
.find('form')
.find('.pf-c-toggle-group__item')
.find('.pf-v5-c-toggle-group__item')
.should((items) => {
expect(items[0]).to.contain.text('Repositories');
});
@ -221,7 +221,7 @@ describe('Robot Accounts Page', () => {
cy.get('#create-robot-submit')
.click()
.then(() => {
cy.get('.pf-c-alert.pf-m-success')
cy.get('.pf-v5-c-alert.pf-m-success')
.contains(
'Successfully created robot account with robot name: user1+userrobot',
)

View File

@ -54,7 +54,7 @@ describe('Teams and membership page', () => {
cy.get(`[data-testid="${teamToBeUpdated}-Creator"]`).click();
// verify success alert
cy.get('.pf-c-alert.pf-m-success')
cy.get('.pf-v5-c-alert.pf-m-success')
.contains(`Team role updated successfully for: ${teamToBeUpdated}`)
.should('exist');
});
@ -73,7 +73,7 @@ describe('Teams and membership page', () => {
.click();
// verify success alert
cy.get('.pf-c-alert.pf-m-success')
cy.get('.pf-v5-c-alert.pf-m-success')
.contains(`Successfully deleted team`)
.should('exist');
});
@ -88,7 +88,7 @@ describe('Teams and membership page', () => {
cy.get(`[data-testid="${collaboratorName}-del-btn"]`).click();
// verify success alert
cy.get('.pf-c-alert.pf-m-success')
cy.get('.pf-v5-c-alert.pf-m-success')
.contains(`Successfully deleted collaborator`)
.should('exist');
});
@ -133,7 +133,7 @@ describe('Teams and membership page', () => {
cy.get('#update-team-repo-permissions').click();
// verify success alert
cy.get('.pf-c-alert.pf-m-success')
cy.get('.pf-v5-c-alert.pf-m-success')
.contains(`Updated repo perm for team: ${team} successfully`)
.should('exist');
});
@ -158,7 +158,7 @@ describe('Teams and membership page', () => {
cy.get('#update-team-repo-permissions').click();
// verify success alert
cy.get('.pf-c-alert.pf-m-success')
cy.get('.pf-v5-c-alert.pf-m-success')
.contains(`Updated repo perm for team: ${team} successfully`)
.should('exist');
});
@ -181,7 +181,7 @@ describe('Teams and membership page', () => {
cy.get(`[data-testid="${robotAccntToBeDeleted}-delete-icon"]`).click();
// verify success alert
cy.get('.pf-c-alert.pf-m-success')
cy.get('.pf-v5-c-alert.pf-m-success')
.contains(`Successfully deleted team member`)
.should('exist');
});

563
web/package-lock.json generated
View File

@ -8,11 +8,11 @@
"name": "quay-ui",
"version": "0.1.0",
"dependencies": {
"@patternfly/patternfly": "^4.185.1",
"@patternfly/patternfly": "^5.0.4",
"@patternfly/react-charts": "^7.0.1",
"@patternfly/react-core": "^4.202.16",
"@patternfly/react-icons": "^4.93.7",
"@patternfly/react-table": "^4.71.16",
"@patternfly/react-core": "^5.1.0",
"@patternfly/react-icons": "^5.1.0",
"@patternfly/react-table": "^5.1.0",
"@redhat-cloud-services/frontend-components": "^3.9.31",
"@redhat-cloud-services/frontend-components-config-utilities": "^3.0.4",
"@tanstack/react-query": "^4.13.5",
@ -4089,9 +4089,9 @@
}
},
"node_modules/@patternfly/patternfly": {
"version": "4.185.1",
"resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-4.185.1.tgz",
"integrity": "sha512-FhiuxdEGequKFQgev4uSiLZrX6o7yfKKFiNVDjpuqmGlme3iIGSwvVy+95hUCa6rwfJ3Vy8e4dpYBWq2gXQXYw=="
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-5.0.4.tgz",
"integrity": "sha512-8akdWzFpG384Q6Es8lzkfuhAlzVGrNK7TJqXGecHDAg8u1JsYn3+Nw6gLRviI88z8Kjxmg5YKirILjpclGxkIA=="
},
"node_modules/@patternfly/react-charts": {
"version": "7.0.1",
@ -4126,69 +4126,88 @@
"react-dom": "^17 || ^18"
}
},
"node_modules/@patternfly/react-charts/node_modules/@patternfly/react-styles": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/@patternfly/react-styles/-/react-styles-5.0.1.tgz",
"integrity": "sha512-kHP/lbvmhBnNfWiqJJLNwOQZnkcl6wfwAesRp22s4Lj941EWe0oFIqn925/uORIOAOz2du1121t7T4UTfLZg4w=="
},
"node_modules/@patternfly/react-charts/node_modules/@patternfly/react-tokens": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/@patternfly/react-tokens/-/react-tokens-5.0.1.tgz",
"integrity": "sha512-YafAGJYvxDP4GaQ0vMybalWmx7MJ+etUf1cGoaMh0wRD2eswltT/RckygtEBKR/M61qXbgG+CxKmMyY8leoiDw=="
},
"node_modules/@patternfly/react-core": {
"version": "4.239.0",
"resolved": "https://registry.npmjs.org/@patternfly/react-core/-/react-core-4.239.0.tgz",
"integrity": "sha512-6CmYABCJLUXTlzCk6C3WouMNZpS0BCT+aHU8CvYpFQ/NrpYp3MJaDsYbqgCRWV42rmIO5iXun/4WhXBJzJEoQg==",
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/@patternfly/react-core/-/react-core-5.1.0.tgz",
"integrity": "sha512-m6MtCQsWiyGM40L4oLc2aEFlxT8egdoz/58Q2oW1fMkqUaosuNUiwy9/e8zOM3SLOPOo/Qo9cetQkIHVQppCvw==",
"dependencies": {
"@patternfly/react-icons": "^4.90.0",
"@patternfly/react-styles": "^4.89.0",
"@patternfly/react-tokens": "^4.91.0",
"focus-trap": "6.9.2",
"react-dropzone": "9.0.0",
"tippy.js": "5.1.2",
"tslib": "^2.0.0"
"@patternfly/patternfly": "5.0.2",
"@patternfly/react-icons": "^5.1.0",
"@patternfly/react-styles": "^5.1.0",
"@patternfly/react-tokens": "^5.1.0",
"focus-trap": "7.4.3",
"react-dropzone": "^14.2.3",
"tslib": "^2.5.0"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0",
"react-dom": "^16.8.0 || ^17.0.0"
"react": "^17 || ^18",
"react-dom": "^17 || ^18"
}
},
"node_modules/@patternfly/react-core/node_modules/@patternfly/patternfly": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-5.0.2.tgz",
"integrity": "sha512-PB8+MLdYVgF1hIOxGmnVsZG+YHUX3RePe5W1oMS4gS00EmSgw1cobr1Qbpy/BqqS8/R9DRN4hZ2FKDT0d5tkFQ=="
},
"node_modules/@patternfly/react-icons": {
"version": "4.93.7",
"resolved": "https://registry.npmjs.org/@patternfly/react-icons/-/react-icons-4.93.7.tgz",
"integrity": "sha512-3kr35dgba7Qz5CSzmfH0rIjSvBC5xkmiknf3SvVUVxaiVA7KRowID8viYHeZlf3v/Oa3sEewaH830Q0t+nWsZQ==",
"peerDependencies": {
"react": "^16.8 || ^17 || ^18",
"react-dom": "^16.8 || ^17 || ^18"
}
},
"node_modules/@patternfly/react-styles": {
"version": "4.92.6",
"resolved": "https://registry.npmjs.org/@patternfly/react-styles/-/react-styles-4.92.6.tgz",
"integrity": "sha512-b8uQdEReMyeoMzjpMri845QxqtupY/tIFFYfVeKoB2neno8gkcW1RvDdDe62LF88q45OktCwAe/8A99ker10Iw=="
},
"node_modules/@patternfly/react-table": {
"version": "4.108.0",
"resolved": "https://registry.npmjs.org/@patternfly/react-table/-/react-table-4.108.0.tgz",
"integrity": "sha512-EUvd3rlkE1UXobAm7L6JHgNE3TW8IYTaVwwH/px4Mkn5mBayDO6f+w6QM3OeoDQVZcXK6IYFe7QQaYd/vWIJCQ==",
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/@patternfly/react-icons/-/react-icons-5.1.0.tgz",
"integrity": "sha512-mSFAJMrT6QUQ10DifYYGSXOPlFob88lWPZXeOyPdstJ8cJRRRVTMYgoR/VnXsUO/vthwFbViY+sS6+/jL8pl9w==",
"dependencies": {
"@patternfly/react-core": "^4.239.0",
"@patternfly/react-icons": "^4.90.0",
"@patternfly/react-styles": "^4.89.0",
"@patternfly/react-tokens": "^4.91.0",
"lodash": "^4.17.19",
"tslib": "^2.0.0"
"@patternfly/patternfly": "5.0.2"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0",
"react-dom": "^16.8.0 || ^17.0.0"
"react": "^17 || ^18",
"react-dom": "^17 || ^18"
}
},
"node_modules/@patternfly/react-icons/node_modules/@patternfly/patternfly": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-5.0.2.tgz",
"integrity": "sha512-PB8+MLdYVgF1hIOxGmnVsZG+YHUX3RePe5W1oMS4gS00EmSgw1cobr1Qbpy/BqqS8/R9DRN4hZ2FKDT0d5tkFQ=="
},
"node_modules/@patternfly/react-styles": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/@patternfly/react-styles/-/react-styles-5.1.0.tgz",
"integrity": "sha512-RnVS/v1PZuvnXXmPtJamuAprq1lg6tqw6dbeYbm9KmBNXSuB1Iu5fc6kjzrdoSLKBmf6rzpRmafYm2HRwFcrLw==",
"dependencies": {
"@patternfly/patternfly": "5.0.2"
}
},
"node_modules/@patternfly/react-styles/node_modules/@patternfly/patternfly": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-5.0.2.tgz",
"integrity": "sha512-PB8+MLdYVgF1hIOxGmnVsZG+YHUX3RePe5W1oMS4gS00EmSgw1cobr1Qbpy/BqqS8/R9DRN4hZ2FKDT0d5tkFQ=="
},
"node_modules/@patternfly/react-table": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/@patternfly/react-table/-/react-table-5.1.0.tgz",
"integrity": "sha512-lVMHx/VEcRNcthMPY9710GUaWcERQBZZRg6+PU/u6Ap0h3I5paFwkf7kTN692hUkqzUgCeWjH5mw1qFLD9Chwg==",
"dependencies": {
"@patternfly/react-core": "^5.1.0",
"@patternfly/react-icons": "^5.1.0",
"@patternfly/react-styles": "^5.1.0",
"@patternfly/react-tokens": "^5.1.0",
"lodash": "^4.17.19",
"tslib": "^2.5.0"
},
"peerDependencies": {
"react": "^17 || ^18",
"react-dom": "^17 || ^18"
}
},
"node_modules/@patternfly/react-tokens": {
"version": "4.94.6",
"resolved": "https://registry.npmjs.org/@patternfly/react-tokens/-/react-tokens-4.94.6.tgz",
"integrity": "sha512-tm7C6nat+uKMr1hrapis7hS3rN9cr41tpcCKhx6cod6FLU8KwF2Yt5KUxakhIOCEcE/M/EhXhAw/qejp8w0r7Q=="
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/@patternfly/react-tokens/-/react-tokens-5.1.0.tgz",
"integrity": "sha512-HRBoS3JMbW8vWqz91oW2NGUdLndC40TXvMnEaORNd/I25czOquxnx/HxVh+/bdSkNqByj6+fiTwH2X3fL2Cajg==",
"dependencies": {
"@patternfly/patternfly": "5.0.2"
}
},
"node_modules/@patternfly/react-tokens/node_modules/@patternfly/patternfly": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-5.0.2.tgz",
"integrity": "sha512-PB8+MLdYVgF1hIOxGmnVsZG+YHUX3RePe5W1oMS4gS00EmSgw1cobr1Qbpy/BqqS8/R9DRN4hZ2FKDT0d5tkFQ=="
},
"node_modules/@pkgr/utils": {
"version": "2.4.2",
@ -4473,12 +4492,12 @@
"node": ">=8"
}
},
"node_modules/@redhat-cloud-services/frontend-components-utilities": {
"version": "3.3.13",
"resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components-utilities/-/frontend-components-utilities-3.3.13.tgz",
"integrity": "sha512-3SdXwzXP1XMLN+hvlGZwX5Va3VwKW9xzRx9lgKGx2XU2nU3GF233hTeId5Cs58NZqBpf8NpRFYaBWnPBaXCWlQ==",
"node_modules/@redhat-cloud-services/frontend-components/node_modules/@redhat-cloud-services/frontend-components-utilities": {
"version": "3.7.6",
"resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components-utilities/-/frontend-components-utilities-3.7.6.tgz",
"integrity": "sha512-qXevUW8Clj1AoBLwfZAmS+oFJCWKZaMp8O33cyUhkoGjrwkQaL5eJg28zjLVa1uQhdJAvAdwTNtE+Gt3hJTC1g==",
"dependencies": {
"@redhat-cloud-services/types": "^0.0.17",
"@redhat-cloud-services/types": "^0.0.24",
"@sentry/browser": "^5.30.0",
"awesome-debounce-promise": "^2.1.0",
"axios": "^0.27.2",
@ -4491,13 +4510,18 @@
"@patternfly/react-table": "^4.108.0",
"@redhat-cloud-services/rbac-client": "^1.0.100",
"cypress": ">=10.0.0 < 13.0.0",
"react": "^16.14.0 || ^17.0.0",
"react-dom": "^16.14.0 || ^17.0.0",
"react": "^16.14.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.14.0 || ^17.0.0 || ^18.0.0",
"react-redux": ">=7.0.0",
"react-router-dom": "^5.0.0 || ^6.0.0"
}
},
"node_modules/@redhat-cloud-services/frontend-components-utilities/node_modules/axios": {
"node_modules/@redhat-cloud-services/frontend-components/node_modules/@redhat-cloud-services/frontend-components-utilities/node_modules/@redhat-cloud-services/types": {
"version": "0.0.24",
"resolved": "https://registry.npmjs.org/@redhat-cloud-services/types/-/types-0.0.24.tgz",
"integrity": "sha512-P50stc+mnWLycID46/AKmD/760r5N1eoam//O6MUVriqVorUdht7xkUL78aJZU1vw8WW6xlrDHwz3F6BM148qg=="
},
"node_modules/@redhat-cloud-services/frontend-components/node_modules/axios": {
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz",
"integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==",
@ -4506,12 +4530,12 @@
"form-data": "^4.0.0"
}
},
"node_modules/@redhat-cloud-services/frontend-components-utilities/node_modules/commander": {
"node_modules/@redhat-cloud-services/frontend-components/node_modules/commander": {
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
},
"node_modules/@redhat-cloud-services/frontend-components-utilities/node_modules/mkdirp": {
"node_modules/@redhat-cloud-services/frontend-components/node_modules/mkdirp": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
@ -4523,9 +4547,9 @@
}
},
"node_modules/@redhat-cloud-services/rbac-client": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/@redhat-cloud-services/rbac-client/-/rbac-client-1.2.2.tgz",
"integrity": "sha512-U9wL6k4mJHBLStLXmHpq8WsopRv4tGjtQ39lZo9UUEWmu6g7ul1Sw9lB7D4p0sHLTFBjVzlbyIMKqTJh96iH9w==",
"version": "1.2.9",
"resolved": "https://registry.npmjs.org/@redhat-cloud-services/rbac-client/-/rbac-client-1.2.9.tgz",
"integrity": "sha512-EyCf8WHaAdCumfK74PBedQvtqWwE42LESWu9KIInyHz6JgzsO0XmM7NsQQeUkO7PJsiHdKY+rpLF/ZXZWAjB4w==",
"peer": true,
"dependencies": {
"axios": "^0.27.2"
@ -5525,9 +5549,9 @@
"integrity": "sha512-HNB/9GHqu7Fo8AQiugyJbv6ZxYz58wef0esl4Mv828w1ZKpAshw/uFWVDUcIB9KKFeFKoxS3cHY07FFgtTRZ1g=="
},
"node_modules/@types/debounce-promise": {
"version": "3.1.6",
"resolved": "https://registry.npmjs.org/@types/debounce-promise/-/debounce-promise-3.1.6.tgz",
"integrity": "sha512-DowqK95aku+OxMCeG2EQSeXeGeE8OCwLpMsUfIbP7hMF8Otj8eQXnzpwdtIKV+UqQBtkMcF6vbi4Otbh8P/wmg=="
"version": "3.1.7",
"resolved": "https://registry.npmjs.org/@types/debounce-promise/-/debounce-promise-3.1.7.tgz",
"integrity": "sha512-XzqG8zCd9n33gmusdQo0d4p9iRKg/mZbG52wfHxnuZZyeO68ryOT5xyv9Fk3vLAvQBUsHmSL14Cqpsx4jjzz1Q=="
},
"node_modules/@types/eslint": {
"version": "8.44.2",
@ -7042,12 +7066,9 @@
}
},
"node_modules/attr-accept": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-1.1.3.tgz",
"integrity": "sha512-iT40nudw8zmCweivz6j58g+RT33I4KbaIvRUhjNmDwO2WmsQUxFEZZYZ5w3vXe5x5MX9D7mfvA/XaLOZYFR9EQ==",
"dependencies": {
"core-js": "^2.5.0"
},
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.2.tgz",
"integrity": "sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==",
"engines": {
"node": ">=4"
}
@ -9242,13 +9263,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/core-js": {
"version": "2.6.12",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz",
"integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==",
"deprecated": "core-js@<3.4 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Please, upgrade your dependencies to the actual version of core-js.",
"hasInstallScript": true
},
"node_modules/core-js-compat": {
"version": "3.22.5",
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.22.5.tgz",
@ -13028,14 +13042,14 @@
}
},
"node_modules/file-selector": {
"version": "0.1.19",
"resolved": "https://registry.npmjs.org/file-selector/-/file-selector-0.1.19.tgz",
"integrity": "sha512-kCWw3+Aai8Uox+5tHCNgMFaUdgidxvMnLWO6fM5sZ0hA2wlHP5/DHGF0ECe84BiB95qdJbKNEJhWKVDvMN+JDQ==",
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/file-selector/-/file-selector-0.6.0.tgz",
"integrity": "sha512-QlZ5yJC0VxHxQQsQhXvBaC7VRJ2uaxTf+Tfpu4Z/OcVQJVpZO+DGU0rkoVW5ce2SccxugvpBJoMvUs59iILYdw==",
"dependencies": {
"tslib": "^2.0.1"
"tslib": "^2.4.0"
},
"engines": {
"node": ">= 10"
"node": ">= 12"
}
},
"node_modules/file-uri-to-path": {
@ -13193,11 +13207,11 @@
}
},
"node_modules/focus-trap": {
"version": "6.9.2",
"resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-6.9.2.tgz",
"integrity": "sha512-gBEuXOPNOKPrLdZpMFUSTyIo1eT2NSZRrwZ9r/0Jqw5tmT3Yvxfmu8KBHw8xW2XQkw6E/JoG+OlEq7UDtSUNgw==",
"version": "7.4.3",
"resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.4.3.tgz",
"integrity": "sha512-BgSSbK4GPnS2VbtZ50VtOv1Sti6DIkj3+LkVjiWMNjLeAp1SH1UlLx3ULu/DCu4vq5R4/uvTm+zrvsMsuYmGLg==",
"dependencies": {
"tabbable": "^5.3.2"
"tabbable": "^6.1.2"
}
},
"node_modules/follow-redirects": {
@ -20862,16 +20876,6 @@
"node": ">=4"
}
},
"node_modules/popper.js": {
"version": "1.16.1",
"resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz",
"integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==",
"deprecated": "You can find the new Popper v2 at @popperjs/core, this package is dedicated to the legacy v1",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/popperjs"
}
},
"node_modules/posix-character-classes": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
@ -22078,23 +22082,6 @@
"react-is": "^16.13.1"
}
},
"node_modules/prop-types-extra": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz",
"integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==",
"dependencies": {
"react-is": "^16.3.2",
"warning": "^4.0.0"
},
"peerDependencies": {
"react": ">=0.14.0"
}
},
"node_modules/prop-types-extra/node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"node_modules/prop-types/node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
@ -23424,20 +23411,19 @@
}
},
"node_modules/react-dropzone": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-9.0.0.tgz",
"integrity": "sha512-wZ2o9B2qkdE3RumWhfyZT9swgJYJPeU5qHEcMU8weYpmLex1eeWX0CC32/Y0VutB+BBi2D+iePV/YZIiB4kZGw==",
"version": "14.2.3",
"resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-14.2.3.tgz",
"integrity": "sha512-O3om8I+PkFKbxCukfIR3QAGftYXDZfOE2N1mr/7qebQJHs7U+/RSL/9xomJNpRg9kM5h9soQSdf0Gc7OHF5Fug==",
"dependencies": {
"attr-accept": "^1.1.3",
"file-selector": "^0.1.8",
"prop-types": "^15.6.2",
"prop-types-extra": "^1.1.0"
"attr-accept": "^2.2.2",
"file-selector": "^0.6.0",
"prop-types": "^15.8.1"
},
"engines": {
"node": ">= 6"
"node": ">= 10.13"
},
"peerDependencies": {
"react": ">=0.14.0"
"react": ">= 16.8 || 18.0.0"
}
},
"node_modules/react-error-overlay": {
@ -27580,9 +27566,9 @@
}
},
"node_modules/tabbable": {
"version": "5.3.3",
"resolved": "https://registry.npmjs.org/tabbable/-/tabbable-5.3.3.tgz",
"integrity": "sha512-QD9qKY3StfbZqWOPLp0++pOrAVb/HbUi5xCc8cUo4XjP19808oaMiDzn0leBY5mCespIBM0CIZePzZjgzR83kA=="
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz",
"integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew=="
},
"node_modules/tailwindcss": {
"version": "3.0.24",
@ -27848,14 +27834,6 @@
"node": ">=0.6.0"
}
},
"node_modules/tippy.js": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-5.1.2.tgz",
"integrity": "sha512-Qtrv2wqbRbaKMUb6bWWBQWPayvcDKNrGlvihxtsyowhT7RLGEh1STWuy6EMXC6QLkfKPB2MLnf8W2mzql9VDAw==",
"dependencies": {
"popper.js": "^1.16.0"
}
},
"node_modules/titleize": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz",
@ -29423,14 +29401,6 @@
"makeerror": "1.0.12"
}
},
"node_modules/warning": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
"integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
"dependencies": {
"loose-envify": "^1.0.0"
}
},
"node_modules/watchpack": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
@ -33764,9 +33734,9 @@
}
},
"@patternfly/patternfly": {
"version": "4.185.1",
"resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-4.185.1.tgz",
"integrity": "sha512-FhiuxdEGequKFQgev4uSiLZrX6o7yfKKFiNVDjpuqmGlme3iIGSwvVy+95hUCa6rwfJ3Vy8e4dpYBWq2gXQXYw=="
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-5.0.4.tgz",
"integrity": "sha512-8akdWzFpG384Q6Es8lzkfuhAlzVGrNK7TJqXGecHDAg8u1JsYn3+Nw6gLRviI88z8Kjxmg5YKirILjpclGxkIA=="
},
"@patternfly/react-charts": {
"version": "7.0.1",
@ -33795,62 +33765,86 @@
"victory-tooltip": "^36.6.11",
"victory-voronoi-container": "^36.6.11",
"victory-zoom-container": "^36.6.11"
},
"dependencies": {
"@patternfly/react-styles": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/@patternfly/react-styles/-/react-styles-5.0.1.tgz",
"integrity": "sha512-kHP/lbvmhBnNfWiqJJLNwOQZnkcl6wfwAesRp22s4Lj941EWe0oFIqn925/uORIOAOz2du1121t7T4UTfLZg4w=="
},
"@patternfly/react-tokens": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/@patternfly/react-tokens/-/react-tokens-5.0.1.tgz",
"integrity": "sha512-YafAGJYvxDP4GaQ0vMybalWmx7MJ+etUf1cGoaMh0wRD2eswltT/RckygtEBKR/M61qXbgG+CxKmMyY8leoiDw=="
}
}
},
"@patternfly/react-core": {
"version": "4.239.0",
"resolved": "https://registry.npmjs.org/@patternfly/react-core/-/react-core-4.239.0.tgz",
"integrity": "sha512-6CmYABCJLUXTlzCk6C3WouMNZpS0BCT+aHU8CvYpFQ/NrpYp3MJaDsYbqgCRWV42rmIO5iXun/4WhXBJzJEoQg==",
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/@patternfly/react-core/-/react-core-5.1.0.tgz",
"integrity": "sha512-m6MtCQsWiyGM40L4oLc2aEFlxT8egdoz/58Q2oW1fMkqUaosuNUiwy9/e8zOM3SLOPOo/Qo9cetQkIHVQppCvw==",
"requires": {
"@patternfly/react-icons": "^4.90.0",
"@patternfly/react-styles": "^4.89.0",
"@patternfly/react-tokens": "^4.91.0",
"focus-trap": "6.9.2",
"react-dropzone": "9.0.0",
"tippy.js": "5.1.2",
"tslib": "^2.0.0"
"@patternfly/patternfly": "5.0.2",
"@patternfly/react-icons": "^5.1.0",
"@patternfly/react-styles": "^5.1.0",
"@patternfly/react-tokens": "^5.1.0",
"focus-trap": "7.4.3",
"react-dropzone": "^14.2.3",
"tslib": "^2.5.0"
},
"dependencies": {
"@patternfly/patternfly": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-5.0.2.tgz",
"integrity": "sha512-PB8+MLdYVgF1hIOxGmnVsZG+YHUX3RePe5W1oMS4gS00EmSgw1cobr1Qbpy/BqqS8/R9DRN4hZ2FKDT0d5tkFQ=="
}
}
},
"@patternfly/react-icons": {
"version": "4.93.7",
"resolved": "https://registry.npmjs.org/@patternfly/react-icons/-/react-icons-4.93.7.tgz",
"integrity": "sha512-3kr35dgba7Qz5CSzmfH0rIjSvBC5xkmiknf3SvVUVxaiVA7KRowID8viYHeZlf3v/Oa3sEewaH830Q0t+nWsZQ==",
"requires": {}
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/@patternfly/react-icons/-/react-icons-5.1.0.tgz",
"integrity": "sha512-mSFAJMrT6QUQ10DifYYGSXOPlFob88lWPZXeOyPdstJ8cJRRRVTMYgoR/VnXsUO/vthwFbViY+sS6+/jL8pl9w==",
"requires": {
"@patternfly/patternfly": "5.0.2"
},
"dependencies": {
"@patternfly/patternfly": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-5.0.2.tgz",
"integrity": "sha512-PB8+MLdYVgF1hIOxGmnVsZG+YHUX3RePe5W1oMS4gS00EmSgw1cobr1Qbpy/BqqS8/R9DRN4hZ2FKDT0d5tkFQ=="
}
}
},
"@patternfly/react-styles": {
"version": "4.92.6",
"resolved": "https://registry.npmjs.org/@patternfly/react-styles/-/react-styles-4.92.6.tgz",
"integrity": "sha512-b8uQdEReMyeoMzjpMri845QxqtupY/tIFFYfVeKoB2neno8gkcW1RvDdDe62LF88q45OktCwAe/8A99ker10Iw=="
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/@patternfly/react-styles/-/react-styles-5.1.0.tgz",
"integrity": "sha512-RnVS/v1PZuvnXXmPtJamuAprq1lg6tqw6dbeYbm9KmBNXSuB1Iu5fc6kjzrdoSLKBmf6rzpRmafYm2HRwFcrLw==",
"requires": {
"@patternfly/patternfly": "5.0.2"
},
"dependencies": {
"@patternfly/patternfly": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-5.0.2.tgz",
"integrity": "sha512-PB8+MLdYVgF1hIOxGmnVsZG+YHUX3RePe5W1oMS4gS00EmSgw1cobr1Qbpy/BqqS8/R9DRN4hZ2FKDT0d5tkFQ=="
}
}
},
"@patternfly/react-table": {
"version": "4.108.0",
"resolved": "https://registry.npmjs.org/@patternfly/react-table/-/react-table-4.108.0.tgz",
"integrity": "sha512-EUvd3rlkE1UXobAm7L6JHgNE3TW8IYTaVwwH/px4Mkn5mBayDO6f+w6QM3OeoDQVZcXK6IYFe7QQaYd/vWIJCQ==",
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/@patternfly/react-table/-/react-table-5.1.0.tgz",
"integrity": "sha512-lVMHx/VEcRNcthMPY9710GUaWcERQBZZRg6+PU/u6Ap0h3I5paFwkf7kTN692hUkqzUgCeWjH5mw1qFLD9Chwg==",
"requires": {
"@patternfly/react-core": "^4.239.0",
"@patternfly/react-icons": "^4.90.0",
"@patternfly/react-styles": "^4.89.0",
"@patternfly/react-tokens": "^4.91.0",
"@patternfly/react-core": "^5.1.0",
"@patternfly/react-icons": "^5.1.0",
"@patternfly/react-styles": "^5.1.0",
"@patternfly/react-tokens": "^5.1.0",
"lodash": "^4.17.19",
"tslib": "^2.0.0"
"tslib": "^2.5.0"
}
},
"@patternfly/react-tokens": {
"version": "4.94.6",
"resolved": "https://registry.npmjs.org/@patternfly/react-tokens/-/react-tokens-4.94.6.tgz",
"integrity": "sha512-tm7C6nat+uKMr1hrapis7hS3rN9cr41tpcCKhx6cod6FLU8KwF2Yt5KUxakhIOCEcE/M/EhXhAw/qejp8w0r7Q=="
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/@patternfly/react-tokens/-/react-tokens-5.1.0.tgz",
"integrity": "sha512-HRBoS3JMbW8vWqz91oW2NGUdLndC40TXvMnEaORNd/I25czOquxnx/HxVh+/bdSkNqByj6+fiTwH2X3fL2Cajg==",
"requires": {
"@patternfly/patternfly": "5.0.2"
},
"dependencies": {
"@patternfly/patternfly": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-5.0.2.tgz",
"integrity": "sha512-PB8+MLdYVgF1hIOxGmnVsZG+YHUX3RePe5W1oMS4gS00EmSgw1cobr1Qbpy/BqqS8/R9DRN4hZ2FKDT0d5tkFQ=="
}
}
},
"@pkgr/utils": {
"version": "2.4.2",
@ -33962,6 +33956,48 @@
"@scalprum/core": "^0.2.3",
"@scalprum/react-core": "^0.4.0",
"sanitize-html": "^2.7.2"
},
"dependencies": {
"@redhat-cloud-services/frontend-components-utilities": {
"version": "3.7.6",
"resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components-utilities/-/frontend-components-utilities-3.7.6.tgz",
"integrity": "sha512-qXevUW8Clj1AoBLwfZAmS+oFJCWKZaMp8O33cyUhkoGjrwkQaL5eJg28zjLVa1uQhdJAvAdwTNtE+Gt3hJTC1g==",
"requires": {
"@redhat-cloud-services/types": "^0.0.24",
"@sentry/browser": "^5.30.0",
"awesome-debounce-promise": "^2.1.0",
"axios": "^0.27.2",
"commander": "^2.20.3",
"mkdirp": "^1.0.4",
"react-content-loader": "^6.2.0"
},
"dependencies": {
"@redhat-cloud-services/types": {
"version": "0.0.24",
"resolved": "https://registry.npmjs.org/@redhat-cloud-services/types/-/types-0.0.24.tgz",
"integrity": "sha512-P50stc+mnWLycID46/AKmD/760r5N1eoam//O6MUVriqVorUdht7xkUL78aJZU1vw8WW6xlrDHwz3F6BM148qg=="
}
}
},
"axios": {
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz",
"integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==",
"requires": {
"follow-redirects": "^1.14.9",
"form-data": "^4.0.0"
}
},
"commander": {
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
},
"mkdirp": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="
}
}
},
"@redhat-cloud-services/frontend-components-config-utilities": {
@ -34019,45 +34055,10 @@
}
}
},
"@redhat-cloud-services/frontend-components-utilities": {
"version": "3.3.13",
"resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components-utilities/-/frontend-components-utilities-3.3.13.tgz",
"integrity": "sha512-3SdXwzXP1XMLN+hvlGZwX5Va3VwKW9xzRx9lgKGx2XU2nU3GF233hTeId5Cs58NZqBpf8NpRFYaBWnPBaXCWlQ==",
"requires": {
"@redhat-cloud-services/types": "^0.0.17",
"@sentry/browser": "^5.30.0",
"awesome-debounce-promise": "^2.1.0",
"axios": "^0.27.2",
"commander": "^2.20.3",
"mkdirp": "^1.0.4",
"react-content-loader": "^6.2.0"
},
"dependencies": {
"axios": {
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz",
"integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==",
"requires": {
"follow-redirects": "^1.14.9",
"form-data": "^4.0.0"
}
},
"commander": {
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
},
"mkdirp": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="
}
}
},
"@redhat-cloud-services/rbac-client": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/@redhat-cloud-services/rbac-client/-/rbac-client-1.2.2.tgz",
"integrity": "sha512-U9wL6k4mJHBLStLXmHpq8WsopRv4tGjtQ39lZo9UUEWmu6g7ul1Sw9lB7D4p0sHLTFBjVzlbyIMKqTJh96iH9w==",
"version": "1.2.9",
"resolved": "https://registry.npmjs.org/@redhat-cloud-services/rbac-client/-/rbac-client-1.2.9.tgz",
"integrity": "sha512-EyCf8WHaAdCumfK74PBedQvtqWwE42LESWu9KIInyHz6JgzsO0XmM7NsQQeUkO7PJsiHdKY+rpLF/ZXZWAjB4w==",
"peer": true,
"requires": {
"axios": "^0.27.2"
@ -34826,9 +34827,9 @@
"integrity": "sha512-HNB/9GHqu7Fo8AQiugyJbv6ZxYz58wef0esl4Mv828w1ZKpAshw/uFWVDUcIB9KKFeFKoxS3cHY07FFgtTRZ1g=="
},
"@types/debounce-promise": {
"version": "3.1.6",
"resolved": "https://registry.npmjs.org/@types/debounce-promise/-/debounce-promise-3.1.6.tgz",
"integrity": "sha512-DowqK95aku+OxMCeG2EQSeXeGeE8OCwLpMsUfIbP7hMF8Otj8eQXnzpwdtIKV+UqQBtkMcF6vbi4Otbh8P/wmg=="
"version": "3.1.7",
"resolved": "https://registry.npmjs.org/@types/debounce-promise/-/debounce-promise-3.1.7.tgz",
"integrity": "sha512-XzqG8zCd9n33gmusdQo0d4p9iRKg/mZbG52wfHxnuZZyeO68ryOT5xyv9Fk3vLAvQBUsHmSL14Cqpsx4jjzz1Q=="
},
"@types/eslint": {
"version": "8.44.2",
@ -34894,7 +34895,7 @@
"integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==",
"peer": true,
"requires": {
"@types/react": "*",
"@types/react": "^17.0.2",
"hoist-non-react-statics": "^3.3.0"
}
},
@ -35046,7 +35047,7 @@
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.16.tgz",
"integrity": "sha512-DWcXf8EbMrO/gWnQU7Z88Ws/p16qxGpPyjTKTpmBSFKeE+HveVubqGO1CVK7FrwlWD5MuOcvh8gtd0/XO38NdQ==",
"requires": {
"@types/react": "^17"
"@types/react": "^17.0.2"
}
},
"@types/react-router": {
@ -35056,7 +35057,7 @@
"dev": true,
"requires": {
"@types/history": "^4.7.11",
"@types/react": "*"
"@types/react": "^17.0.2"
}
},
"@types/react-router-dom": {
@ -35066,7 +35067,7 @@
"dev": true,
"requires": {
"@types/history": "^4.7.11",
"@types/react": "*",
"@types/react": "^17.0.2",
"@types/react-router": "*"
}
},
@ -36055,12 +36056,9 @@
"integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg=="
},
"attr-accept": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-1.1.3.tgz",
"integrity": "sha512-iT40nudw8zmCweivz6j58g+RT33I4KbaIvRUhjNmDwO2WmsQUxFEZZYZ5w3vXe5x5MX9D7mfvA/XaLOZYFR9EQ==",
"requires": {
"core-js": "^2.5.0"
}
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.2.tgz",
"integrity": "sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg=="
},
"autoprefixer": {
"version": "10.4.4",
@ -37743,11 +37741,6 @@
}
}
},
"core-js": {
"version": "2.6.12",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz",
"integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ=="
},
"core-js-compat": {
"version": "3.22.5",
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.22.5.tgz",
@ -40554,11 +40547,11 @@
}
},
"file-selector": {
"version": "0.1.19",
"resolved": "https://registry.npmjs.org/file-selector/-/file-selector-0.1.19.tgz",
"integrity": "sha512-kCWw3+Aai8Uox+5tHCNgMFaUdgidxvMnLWO6fM5sZ0hA2wlHP5/DHGF0ECe84BiB95qdJbKNEJhWKVDvMN+JDQ==",
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/file-selector/-/file-selector-0.6.0.tgz",
"integrity": "sha512-QlZ5yJC0VxHxQQsQhXvBaC7VRJ2uaxTf+Tfpu4Z/OcVQJVpZO+DGU0rkoVW5ce2SccxugvpBJoMvUs59iILYdw==",
"requires": {
"tslib": "^2.0.1"
"tslib": "^2.4.0"
}
},
"file-uri-to-path": {
@ -40699,11 +40692,11 @@
}
},
"focus-trap": {
"version": "6.9.2",
"resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-6.9.2.tgz",
"integrity": "sha512-gBEuXOPNOKPrLdZpMFUSTyIo1eT2NSZRrwZ9r/0Jqw5tmT3Yvxfmu8KBHw8xW2XQkw6E/JoG+OlEq7UDtSUNgw==",
"version": "7.4.3",
"resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.4.3.tgz",
"integrity": "sha512-BgSSbK4GPnS2VbtZ50VtOv1Sti6DIkj3+LkVjiWMNjLeAp1SH1UlLx3ULu/DCu4vq5R4/uvTm+zrvsMsuYmGLg==",
"requires": {
"tabbable": "^5.3.2"
"tabbable": "^6.1.2"
}
},
"follow-redirects": {
@ -46521,11 +46514,6 @@
}
}
},
"popper.js": {
"version": "1.16.1",
"resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz",
"integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ=="
},
"posix-character-classes": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
@ -47263,22 +47251,6 @@
}
}
},
"prop-types-extra": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz",
"integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==",
"requires": {
"react-is": "^16.3.2",
"warning": "^4.0.0"
},
"dependencies": {
"react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
}
}
},
"property-expr": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.5.tgz",
@ -48326,14 +48298,13 @@
}
},
"react-dropzone": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-9.0.0.tgz",
"integrity": "sha512-wZ2o9B2qkdE3RumWhfyZT9swgJYJPeU5qHEcMU8weYpmLex1eeWX0CC32/Y0VutB+BBi2D+iePV/YZIiB4kZGw==",
"version": "14.2.3",
"resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-14.2.3.tgz",
"integrity": "sha512-O3om8I+PkFKbxCukfIR3QAGftYXDZfOE2N1mr/7qebQJHs7U+/RSL/9xomJNpRg9kM5h9soQSdf0Gc7OHF5Fug==",
"requires": {
"attr-accept": "^1.1.3",
"file-selector": "^0.1.8",
"prop-types": "^15.6.2",
"prop-types-extra": "^1.1.0"
"attr-accept": "^2.2.2",
"file-selector": "^0.6.0",
"prop-types": "^15.8.1"
}
},
"react-error-overlay": {
@ -51411,9 +51382,9 @@
}
},
"tabbable": {
"version": "5.3.3",
"resolved": "https://registry.npmjs.org/tabbable/-/tabbable-5.3.3.tgz",
"integrity": "sha512-QD9qKY3StfbZqWOPLp0++pOrAVb/HbUi5xCc8cUo4XjP19808oaMiDzn0leBY5mCespIBM0CIZePzZjgzR83kA=="
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz",
"integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew=="
},
"tailwindcss": {
"version": "3.0.24",
@ -51615,14 +51586,6 @@
"setimmediate": "^1.0.4"
}
},
"tippy.js": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-5.1.2.tgz",
"integrity": "sha512-Qtrv2wqbRbaKMUb6bWWBQWPayvcDKNrGlvihxtsyowhT7RLGEh1STWuy6EMXC6QLkfKPB2MLnf8W2mzql9VDAw==",
"requires": {
"popper.js": "^1.16.0"
}
},
"titleize": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz",
@ -52804,14 +52767,6 @@
"makeerror": "1.0.12"
}
},
"warning": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
"integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
"requires": {
"loose-envify": "^1.0.0"
}
},
"watchpack": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",

View File

@ -7,11 +7,11 @@
},
"homepage": ".",
"dependencies": {
"@patternfly/patternfly": "^4.185.1",
"@patternfly/patternfly": "^5.0.4",
"@patternfly/react-charts": "^7.0.1",
"@patternfly/react-core": "^4.202.16",
"@patternfly/react-icons": "^4.93.7",
"@patternfly/react-table": "^4.71.16",
"@patternfly/react-core": "^5.1.0",
"@patternfly/react-icons": "^5.1.0",
"@patternfly/react-table": "^5.1.0",
"@redhat-cloud-services/frontend-components": "^3.9.31",
"@redhat-cloud-services/frontend-components-config-utilities": "^3.0.4",
"@tanstack/react-query": "^4.13.5",
@ -107,5 +107,11 @@
},
"optionalDependencies": {
"cypress": "^12.17.4"
},
"overrides": {
"@types/react": "^17.0.2",
"@patternfly/react-core": "^5.1.0",
"@patternfly/react-icons": "^5.1.0",
"@patternfly/react-table": "^5.1.0"
}
}

View File

@ -4,19 +4,23 @@ html, body, #root, .App {
height: 100%;
}
.pf-c-content {
--pf-c-content--small--Color: red; /* changes all <small> color to red */
--pf-c-content--blockquote--BorderLeftColor: purple; /* changes all <blockquote> left border color to purple */
--pf-c-content--hr--BackgroundColor: lemonchiffon; /* changes a <hr> color to lemonchiffon */
.pf-v5-c-content {
--pf-v5-c-content--small--Color: red; /* changes all <small> color to red */
--pf-v5-c-content--blockquote--BorderLeftColor: purple; /* changes all <blockquote> left border color to purple */
--pf-v5-c-content--hr--BackgroundColor: lemonchiffon; /* changes a <hr> color to lemonchiffon */
}
.page-sidebar {
.page-sidebar .pf-v5-c-page__sidebar-body {
background-color: black;
color: black;
}
.pf-c-page__sidebar-body {
.page-sidebar .pf-v5-c-nav__list {
padding-top: 0;
}
.pf-v5-c-page__sidebar-body {
padding-top: 0;
}
@ -38,11 +42,11 @@ html, body, #root, .App {
padding-right: 0;
}
.pf-c-tabs {
.pf-v5-c-tabs {
padding-left: 24px;
}
.pf-c-panel__footer {
.pf-v5-c-panel__footer {
padding: 24px 24px 0 0;
}

View File

@ -1,3 +1,4 @@
import React from 'react';
import {DatePicker, TimePicker} from '@patternfly/react-core';
import {isNullOrUndefined} from 'src/libs/utils';
@ -15,10 +16,14 @@ export default function DateTimePicker(props: DateTimePickerProps) {
}
};
const onDateChange = (value: string, dateValue: Date) => {
const onDateChange = (
_event: React.FormEvent<HTMLInputElement>,
_value: string,
dateValue?: Date,
) => {
if (!isNullOrUndefined(dateValue)) {
if (isNullOrUndefined(date)) {
setValue((prevDate) => dateValue);
setValue(() => dateValue);
} else {
setValue((prevDate) => {
const newDate = new Date(prevDate);
@ -33,13 +38,20 @@ export default function DateTimePicker(props: DateTimePickerProps) {
}
};
const onTimeChange = (time, hour, minute, seconds, isValid) => {
const onTimeChange = (
_event: React.FormEvent<HTMLInputElement>,
_time: string,
hour?: number,
minute?: number,
_seconds?: number,
isValid?: boolean,
) => {
if (hour !== null && minute !== null && isValid) {
if (isNullOrUndefined(date)) {
const newDate = new Date();
newDate.setHours(hour);
newDate.setMinutes(minute);
setValue((prevDate) => newDate);
setValue(() => newDate);
} else {
setValue((prevDate) => {
const newDate = new Date(prevDate);

View File

@ -1,4 +1,8 @@
import {Select, SelectOption, SelectVariant} from '@patternfly/react-core';
import {
Select,
SelectOption,
SelectVariant,
} from '@patternfly/react-core/deprecated';
import {useEffect, useState} from 'react';
import {useEntities} from 'src/hooks/UseEntities';
import {Entity, getMemberType} from 'src/resources/UserResource';

View File

@ -3,12 +3,14 @@ import {
EmptyState,
EmptyStateIcon,
EmptyStateBody,
EmptyStateSecondaryActions,
Title,
Spinner,
Bullseye,
PageSectionVariants,
PageSection,
EmptyStateActions,
EmptyStateHeader,
EmptyStateFooter,
} from '@patternfly/react-core';
export function LoadingPage(props: {
@ -21,17 +23,17 @@ export function LoadingPage(props: {
<PageSection variant={PageSectionVariants.light}>
<Bullseye>
<EmptyState>
<EmptyStateIcon variant="container" component={Spinner} />
<div>
<Title size="lg" headingLevel="h4">
{props.title ?? 'Loading'}
</Title>
<EmptyStateBody>{props.message}</EmptyStateBody>
</div>
{props.primaryAction}
<EmptyStateSecondaryActions>
{props.secondaryActions}
</EmptyStateSecondaryActions>
<EmptyStateHeader icon={<EmptyStateIcon icon={Spinner} />} />
<EmptyStateFooter>
<div>
<Title size="lg" headingLevel="h4">
{props.title ?? 'Loading'}
</Title>
<EmptyStateBody>{props.message}</EmptyStateBody>
</div>
{props.primaryAction}
<EmptyStateActions>{props.secondaryActions}</EmptyStateActions>
</EmptyStateFooter>
</EmptyState>
</Bullseye>
</PageSection>

View File

@ -5,26 +5,36 @@ import {
EmptyState,
EmptyStateVariant,
EmptyStateIcon,
Title,
EmptyStateBody,
Button,
EmptyStateHeader,
EmptyStateFooter,
} from '@patternfly/react-core';
import {UserIcon} from "@patternfly/react-icons";
import {UserIcon} from '@patternfly/react-icons';
export default function NewUserEmptyPage(props: NewUserEmptyPageProps) {
return (
<Page>
<PageSection variant={PageSectionVariants.light}>
<EmptyState variant={EmptyStateVariant.large}>
<EmptyStateIcon icon={UserIcon} color='black'/>
<Title headingLevel="h5" size="4xl">
Welcome to Quay
</Title>
<EmptyState variant={EmptyStateVariant.lg}>
<EmptyStateHeader
titleText="Welcome to Quay"
icon={<EmptyStateIcon icon={UserIcon} color="black" />}
headingLevel="h5"
/>
<EmptyStateBody>
To gain access to organizations and repositories on Quay.io you must <br />
To gain access to organizations and repositories on Quay.io you must{' '}
<br />
create a username.
</EmptyStateBody>
<Button variant="primary" onClick={() => props.setCreateUserModalOpen(true)}>Create username</Button>
<EmptyStateFooter>
<Button
variant="primary"
onClick={() => props.setCreateUserModalOpen(true)}
>
Create username
</Button>
</EmptyStateFooter>
</EmptyState>
</PageSection>
</Page>

View File

@ -1,34 +1,46 @@
import {Button, Flex, InputGroup, TextInput} from '@patternfly/react-core';
import React from 'react';
import {
Button,
Flex,
InputGroup,
TextInput,
InputGroupItem,
} from '@patternfly/react-core';
import {EyeIcon, EyeSlashIcon} from '@patternfly/react-icons';
import {useState} from 'react';
export default function ReadonlySecret(props: ReadonlySecretProps) {
const [secretHidden, setSecretHidden] = useState<boolean>(true);
const [secretHidden, setSecretHidden] = React.useState<boolean>(true);
return (
<Flex direction={{default: 'row'}}>
{props.label}
{':'}
<InputGroup style={{width: 'inherit'}}>
<TextInput
type={secretHidden ? 'password' : 'text'}
aria-label="secret input"
value={props.secret}
isDisabled
style={{
backgroundColor: 'white',
width: `${props.secret.length}ch`,
paddingRight: 0,
cursor: 'auto',
}}
/>
<Button
variant="plain"
onClick={() => setSecretHidden(!secretHidden)}
aria-label={secretHidden ? 'Show secret' : 'Hide secret'}
style={{paddingLeft: 0}}
>
{secretHidden ? <EyeIcon /> : <EyeSlashIcon />}
</Button>
<InputGroupItem isFill>
<TextInput
type={secretHidden ? 'password' : 'text'}
aria-label="secret input"
value={props.secret}
isDisabled
style={{
backgroundColor: 'white',
width: `${props.secret.length}ch`,
paddingRight: 0,
cursor: 'auto',
}}
/>
</InputGroupItem>
<InputGroupItem>
<Button
variant="plain"
onClick={() => setSecretHidden(!secretHidden)}
aria-label={secretHidden ? 'Show secret' : 'Hide secret'}
style={{paddingLeft: 0}}
>
{secretHidden ? <EyeIcon /> : <EyeSlashIcon />}
</Button>
</InputGroupItem>
</InputGroup>
</Flex>
);

View File

@ -69,7 +69,6 @@ export default function Menu({isOpen, setIsOpen, ...props}: MenuProps) {
}
appendTo={containerRef.current || undefined}
isVisible={isOpen}
popperMatchesTriggerWidth={false}
/>
</div>
);

View File

@ -1,31 +1,34 @@
import React from 'react';
import {
EmptyState,
EmptyStateBody,
EmptyStateIcon,
PageSection,
Title,
EmptyStateHeader,
EmptyStateFooter,
} from '@patternfly/react-core';
import {SVGIconProps} from '@patternfly/react-icons/dist/js/createIcon';
export default function Empty(props: EmptyProps) {
return (
<PageSection>
<EmptyState variant="large">
<EmptyStateIcon icon={props.icon} />
<Title headingLevel="h1" size="lg">
{props.title}
</Title>
<EmptyState variant="lg">
<EmptyStateHeader
titleText={<>{props.title}</>}
icon={<EmptyStateIcon icon={props.icon} />}
headingLevel="h1"
/>
<EmptyStateBody style={{paddingBottom: 20}}>
{props.body}
</EmptyStateBody>
{props.button}
<EmptyStateFooter>{props.button}</EmptyStateFooter>
</EmptyState>
</PageSection>
);
}
interface EmptyProps {
icon: React.ComponentClass<SVGIconProps, any>;
icon: React.ComponentClass<SVGIconProps, unknown>;
title: string;
body: string;
button?: JSX.Element;

View File

@ -1,12 +1,11 @@
import React from 'react';
import {
Button,
EmptyState,
EmptyStateBody,
EmptyStateIcon,
Page,
PageSection,
Title,
EmptyStateHeader,
} from '@patternfly/react-core';
import {ExclamationTriangleIcon} from '@patternfly/react-icons';
@ -15,10 +14,11 @@ export default function NotFound() {
<Page>
<PageSection>
<EmptyState variant="full">
<EmptyStateIcon icon={ExclamationTriangleIcon} />
<Title headingLevel="h1" size="lg">
404 Page not found
</Title>
<EmptyStateHeader
titleText="404 Page not found"
icon={<EmptyStateIcon icon={ExclamationTriangleIcon} />}
headingLevel="h1"
/>
<EmptyStateBody>
We didn&apos;t find a page that matches the address you navigated
to.

View File

@ -1,11 +1,11 @@
import {
Brand,
Button,
EmptyState,
EmptyStateBody,
EmptyStateIcon,
PageSection,
Title,
EmptyStateHeader,
EmptyStateFooter,
} from '@patternfly/react-core';
import {ExclamationTriangleIcon} from '@patternfly/react-icons';
@ -16,14 +16,17 @@ export default function PageLoadError() {
return (
<PageSection>
<EmptyState variant="full">
<EmptyStateIcon icon={ExclamationTriangleIcon} />
<Title headingLevel="h1" size="lg">
Unable to reach server
</Title>
<EmptyStateHeader
titleText="Unable to reach server"
icon={<EmptyStateIcon icon={ExclamationTriangleIcon} />}
headingLevel="h1"
/>
<EmptyStateBody>Page could not be loaded</EmptyStateBody>
<Button title="Home" onClick={() => window.location.reload()}>
Retry
</Button>
<EmptyStateFooter>
<Button title="Home" onClick={() => window.location.reload()}>
Retry
</Button>
</EmptyStateFooter>
</EmptyState>
</PageSection>
);

View File

@ -5,7 +5,8 @@ import {
EmptyStateIcon,
PageSection,
PageSectionVariants,
Title,
EmptyStateHeader,
EmptyStateFooter,
} from '@patternfly/react-core';
import {ExclamationTriangleIcon} from '@patternfly/react-icons';
@ -13,14 +14,17 @@ export default function RequestError(props: RequestErrorProps) {
return (
<PageSection variant={PageSectionVariants.light}>
<EmptyState variant="full">
<EmptyStateIcon icon={ExclamationTriangleIcon} />
<Title headingLevel="h1" size="lg">
Unable to complete request
</Title>
<EmptyStateHeader
titleText="Unable to complete request"
icon={<EmptyStateIcon icon={ExclamationTriangleIcon} />}
headingLevel="h1"
/>
<EmptyStateBody>{props.message}</EmptyStateBody>
<Button title="Home" onClick={() => window.location.reload()}>
Retry
</Button>
<EmptyStateFooter>
<Button title="Home" onClick={() => window.location.reload()}>
Retry
</Button>
</EmptyStateFooter>
</EmptyState>
</PageSection>
);

View File

@ -5,7 +5,8 @@ import {
EmptyStateIcon,
Page,
PageSection,
Title,
EmptyStateHeader,
EmptyStateFooter,
} from '@patternfly/react-core';
import {ExclamationCircleIcon} from '@patternfly/react-icons';
@ -14,18 +15,21 @@ export default function SiteUnavailableError() {
<Page>
<PageSection>
<EmptyState variant="full">
<EmptyStateIcon icon={ExclamationCircleIcon} />
<Title headingLevel="h1" size="lg">
This site is temporarily unavailable
</Title>
<EmptyStateHeader
titleText="This site is temporarily unavailable"
icon={<EmptyStateIcon icon={ExclamationCircleIcon} />}
headingLevel="h1"
/>
<EmptyStateBody>
Try refreshing the page. If the problem persists, contact your
organization administrator or visit our{' '}
<a href="https://status.quay.io/">status page</a> for known outages.
</EmptyStateBody>
<Button title="Home" onClick={() => window.location.reload()}>
Reload
</Button>
<EmptyStateFooter>
<Button title="Home" onClick={() => window.location.reload()}>
Reload
</Button>
</EmptyStateFooter>
</EmptyState>
</PageSection>
</Page>

View File

@ -1,13 +1,13 @@
.pf-c-form__group {
--pf-c-form--m-horizontal__group-label--md--GridColumnWidth: 4.25rem;
--pf-c-form--m-horizontal__group-control--md--GridColumnWidth: 1;
.pf-v5-c-form__group {
--pf-v5-c-form--m-horizontal__group-label--md--GridColumnWidth: 4.25rem;
--pf-v5-c-form--m-horizontal__group-control--md--GridColumnWidth: 1;
}
.pf-c-switch {
--pf-c-switch--Height: 1rem;
.pf-v5-c-switch {
--pf-v5-c-switch--Height: 1rem;
}
.pf-c-switch__label {
--pf-c-switch__input--checked__label--Color: white;
--pf-c-switch__input--not-checked__label--Color: white;
.pf-v5-c-switch__label {
--pf-v5-c-switch__input--checked__label--Color: white;
--pf-v5-c-switch__input--not-checked__label--Color: white;
}

View File

@ -1,17 +1,19 @@
import {
Button,
Dropdown,
DropdownGroup,
DropdownItem,
DropdownToggle,
Form,
FormGroup,
Flex,
FlexItem,
Switch,
Toolbar,
ToolbarContent,
ToolbarGroup,
ToolbarItem,
} from '@patternfly/react-core';
import {
Dropdown,
DropdownGroup,
DropdownItem,
DropdownToggle,
} from '@patternfly/react-core/deprecated';
import {UserIcon} from '@patternfly/react-icons';
import React from 'react';
import {useState} from 'react';
@ -84,7 +86,10 @@ export function HeaderToolbar() {
// Toggle between old UI and new UI
const [isChecked, setIsChecked] = React.useState<boolean>(true);
const toggleSwitch = (checked: boolean) => {
const toggleSwitch = (
_event: React.FormEvent<HTMLInputElement>,
checked: boolean,
) => {
setIsChecked(checked);
// Reload page and trigger patternfly cookie removal
@ -96,12 +101,6 @@ export function HeaderToolbar() {
const randomArg = '?_=' + new Date().getTime();
window.location.replace(`${protocol}//${host}/${path}/${randomArg}`);
};
const toolbarSpacers = {
default: 'spacerNone',
md: 'spacerSm',
lg: 'spacerMd',
xl: 'spacerLg',
};
return (
<>
@ -110,24 +109,34 @@ export function HeaderToolbar() {
<ToolbarContent>
<ToolbarGroup
variant="icon-button-group"
alignment={{default: 'alignRight'}}
align={{default: 'alignRight'}}
spacer={{default: 'spacerNone', md: 'spacerMd'}}
>
<ToolbarItem spacer={toolbarSpacers}>
<Form isHorizontal>
<FormGroup
label="Current UI"
fieldId="horizontal-form-stacked-options"
>
<Switch
id="header-toolbar-ui-switch"
label="New UI"
labelOff="New UI"
isChecked={isChecked}
onChange={toggleSwitch}
/>
</FormGroup>
</Form>
<ToolbarItem
spacer={{
default: 'spacerNone',
sm: 'spacerSm',
md: 'spacerSm',
lg: 'spacerMd',
xl: 'spacerLg',
}}
>
<Flex
spaceItems={{default: 'spaceItemsMd'}}
flexWrap={{default: 'nowrap'}}
className="pf-v5-u-text-nowrap pf-v5-u-pr-md"
>
<FlexItem alignSelf={{default: 'alignSelfFlexStart'}}>
Current UI
</FlexItem>
<Switch
id="header-toolbar-ui-switch"
label="New UI"
labelOff="New UI"
isChecked={isChecked}
onChange={toggleSwitch}
/>
</Flex>
</ToolbarItem>
<ToolbarItem>
{user.username ? userDropdown : signInButton}

View File

@ -1,55 +1,57 @@
import { Label, TextInput } from "@patternfly/react-core";
import { useEffect, useRef, useState } from "react";
import {Label, TextInput} from '@patternfly/react-core';
import {useEffect, useRef, useState} from 'react';
export default function EditableLabel(props: EditableLabelProps) {
const [isEditable, setIsEditable] = useState(false);
const wrapperRef = useRef(null);
const [isEditable, setIsEditable] = useState(false);
const wrapperRef = useRef(null);
// This re-renders the label component when clicking
// outside of the text input
useEffect(() => {
function handleClickOutside(event) {
if (wrapperRef.current && !wrapperRef.current.contains(event.target)) {
setIsEditable(false);
props.onEditComplete(props.value);
}
}
document.addEventListener("mousedown", handleClickOutside);
return () => {
document.removeEventListener("mousedown", handleClickOutside);
};
}, [wrapperRef, props.value]);
if (isEditable) {
return (
<TextInput
id='new-label-input'
ref={wrapperRef}
value={props.value}
onChange={(newValue) => props.setValue(newValue.trim())}
style={{ width: '50%' }}
placeholder='key=value'
validated={props.invalid ? 'error' : 'default'}
/>
)
} else {
return (
<Label
color={props.invalid ? "red" : "blue"}
key="add-label"
className="label"
onClick={() => { setIsEditable(true) }}
style={{ textDecorationStyle: 'dotted' }}
>
{props.value === '' ? 'Add new label' : props.value}
</Label>
)
// This re-renders the label component when clicking
// outside of the text input
useEffect(() => {
function handleClickOutside(event) {
if (wrapperRef.current && !wrapperRef.current.contains(event.target)) {
setIsEditable(false);
props.onEditComplete(props.value);
}
}
document.addEventListener('mousedown', handleClickOutside);
return () => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, [wrapperRef, props.value]);
if (isEditable) {
return (
<TextInput
id="new-label-input"
ref={wrapperRef}
value={props.value}
onChange={(_event, newValue) => props.setValue(newValue.trim())}
style={{width: '50%'}}
placeholder="key=value"
validated={props.invalid ? 'error' : 'default'}
/>
);
} else {
return (
<Label
color={props.invalid ? 'red' : 'blue'}
key="add-label"
className="label"
onClick={() => {
setIsEditable(true);
}}
style={{textDecorationStyle: 'dotted'}}
>
{props.value === '' ? 'Add new label' : props.value}
</Label>
);
}
}
interface EditableLabelProps {
invalid?: boolean;
value: string;
setValue: (value: string) => void;
onEditComplete: (value: string) => void;
invalid?: boolean;
value: string;
setValue: (value: string) => void;
onEditComplete: (value: string) => void;
}

View File

@ -3,6 +3,6 @@
}
.label {
--pf-c-label--BorderRadius: 1em;
--pf-v5-c-label--BorderRadius: 1em;
margin-bottom: 3px;
}

View File

@ -8,15 +8,9 @@ import {
Toolbar,
ToolbarContent,
ToolbarItem,
SearchInput,
} from '@patternfly/react-core';
import {
TableComposable,
Tbody,
Td,
Th,
Thead,
Tr,
} from '@patternfly/react-table';
import {Table, Tbody, Td, Th, Thead, Tr} from '@patternfly/react-table';
import {useEffect, useState} from 'react';
import {ToolbarPagination} from 'src/components/toolbar/ToolbarPagination';
@ -41,17 +35,21 @@ export const BulkDeleteModalTemplate = <T,>(
bulkModalPage * bulkModalPerPage - bulkModalPerPage + bulkModalPerPage,
);
const onSearch = (value: string) => {
const onSearch = (
_event: React.FormEvent<HTMLInputElement>,
value: string,
) => {
setSearchInput(value);
if (value === '') {
setItemsMarkedForDelete(props.selectedItems);
} else {
/* Note: This search filter assumes that the search is always based on the 1st column,
hence we do "colNames[0]" */
const filteredTableRow = props.selectedItems.filter((item) =>
item[props.mapOfColNamesToTableData[colNames[0]].label]
?.toLowerCase()
.includes(value.toLowerCase()),
const filteredTableRow = props.selectedItems.filter(
(item) =>
item[props.mapOfColNamesToTableData[colNames[0]].label]
?.toLowerCase()
.includes(value.toLowerCase()),
);
setItemsMarkedForDelete(filteredTableRow);
}
@ -108,15 +106,13 @@ export const BulkDeleteModalTemplate = <T,>(
</span>
<PageSection variant={PageSectionVariants.light}>
<Toolbar>
<ToolbarContent>
<ToolbarContent className="pf-v5-u-pl-0">
<ToolbarItem>
<TextInput
isRequired
<SearchInput
type="search"
id="modal-with-form-form-name"
name="search input"
placeholder="Search"
iconVariant="search"
value={searchInput}
onChange={onSearch}
/>
@ -127,10 +123,11 @@ export const BulkDeleteModalTemplate = <T,>(
itemsList={itemsMarkedForDelete}
setPage={setBulkModalPage}
setPerPage={setBulkModalPerPage}
className="pf-v5-u-mr-md"
/>
</ToolbarContent>
</Toolbar>
<TableComposable aria-label="Simple table" variant="compact">
<Table aria-label="Simple table" variant="compact">
<Thead>
<Tr>
{colNames.map((name, idx) => (
@ -152,7 +149,7 @@ export const BulkDeleteModalTemplate = <T,>(
</Tr>
))}
</Tbody>
</TableComposable>
</Table>
<Toolbar>
<ToolbarPagination
page={bulkModalPage}
@ -160,18 +157,16 @@ export const BulkDeleteModalTemplate = <T,>(
itemsList={itemsMarkedForDelete}
setPage={setBulkModalPage}
setPerPage={setBulkModalPerPage}
bottom={true}
/>
</Toolbar>
<p>
{' '}
Confirm deletion by typing <b>&quot;confirm&quot;</b> below:{' '}
<p className="pf-v5-u-pt-md">
Confirm deletion by typing <b>&quot;confirm&quot;</b> below:
</p>
<TextInput
id="delete-confirmation-input"
value={confirmDeletionInput}
type="text"
onChange={(value) => setConfirmDeletionInput(value)}
onChange={(_event, value) => setConfirmDeletionInput(value)}
aria-label="text input example"
/>
</PageSection>

View File

@ -4,8 +4,10 @@ import {
Button,
Form,
FormGroup,
Popover,
TextInput,
FormHelperText,
HelperText,
HelperTextItem,
} from '@patternfly/react-core';
import ExclamationCircleIcon from '@patternfly/react-icons/dist/esm/icons/exclamation-circle-icon';
import {useState} from 'react';
@ -16,7 +18,8 @@ type validate = 'success' | 'error' | 'default';
export function CreateNewUser(props: CreateNewUserProps) {
const [username, setUsername] = useState(props.user.username);
const [validatedUsername, setValidatedUsername] = useState<validate>('success');
const [validatedUsername, setValidatedUsername] =
useState<validate>('success');
const [helperText, setHelperText] = useState('');
const handleModalToggle = () => {
@ -77,14 +80,14 @@ export function CreateNewUser(props: CreateNewUserProps) {
function fetchDescription() {
return `The username ${props.user.username} was automatically generated to conform to the Docker CLI guidelines
for use as a namespace in Quay Container Registry.
Please confirm the selected username or enter a different username below:`
Please confirm the selected username or enter a different username below:`;
}
const updateUsername = async() => {
const updateUsername = async () => {
await updateUser(username);
handleModalToggle();
window.location.reload();
}
};
return (
<Modal
@ -107,25 +110,30 @@ export function CreateNewUser(props: CreateNewUserProps) {
</Button>,
]}
>
<Form id="confirm-username-form">
<FormGroup
isRequired
fieldId="confirm-username-form-group"
helperText={helperText}
helperTextInvalid={helperText}
helperTextInvalidIcon={<ExclamationCircleIcon />}
validated={validatedUsername}
>
<FormGroup isRequired fieldId="confirm-username-form-group">
<TextInput
isRequired
type="text"
id="confirm-username-input"
name="confirm-username-input"
value={username}
onChange={handleUsernameChange}
onChange={(_event, value) => handleUsernameChange(value)}
validated={validatedUsername}
/>
<FormHelperText>
<HelperText>
<HelperTextItem
variant={validatedUsername}
{...(validatedUsername === 'error' && {
icon: <ExclamationCircleIcon />,
})}
>
{helperText}
</HelperTextItem>
</HelperText>
</FormHelperText>
</FormGroup>
</Form>
</Modal>

View File

@ -6,12 +6,17 @@ import {
FormGroup,
TextInput,
Radio,
SelectVariant,
Select,
SelectOption,
Flex,
FlexItem,
FormHelperText,
HelperText,
HelperTextItem,
} from '@patternfly/react-core';
import {
Select,
SelectOption,
SelectVariant,
} from '@patternfly/react-core/deprecated';
import {IRepository} from 'src/resources/RepositoryResource';
import {useRef, useState} from 'react';
import FormError from 'src/components/errors/FormError';
@ -38,7 +43,11 @@ export default function CreateRepositoryModalTemplate(
const [currentOrganization, setCurrentOrganization] = useState({
// For org scoped view, the name is set current org and for Repository list view,
// the name is set to 1st value from the Namespace dropdown
name: props.orgName ? props.orgName : (props.username ? props.username : null),
name: props.orgName
? props.orgName
: props.username
? props.username
: null,
isDropdownOpen: false,
});
@ -65,7 +74,10 @@ export default function CreateRepositoryModalTemplate(
const nameInputRef = useRef();
const handleNameInputChange = (value) => {
const handleNameInputChange = (
_event: React.FormEvent<HTMLInputElement>,
value,
) => {
let regex = /^[a-z0-9][.a-z0-9_-]{0,254}$/;
if (quayConfig?.features.EXTENDED_REPOSITORY_NAMES) {
// Extended repostitory name regex: allows "/" in repo names
@ -149,18 +161,21 @@ export default function CreateRepositoryModalTemplate(
>
<FormError message={err} setErr={setErr} />
<Form id="modal-with-form-form" maxWidth="765px">
<Flex>
<Flex
flexWrap={{default: 'nowrap'}}
spaceItems={{default: 'spaceItemsMd'}}
>
<FlexItem>
<FormGroup
isInline
label="Namespace"
fieldId="modal-with-form-form-name"
isRequired
helperTextInvalid="Select a namespace"
helperTextInvalidIcon={<ExclamationCircleIcon />}
validated={validationState.namespace ? 'success' : 'error'}
>
<Flex>
<Flex
flexWrap={{default: 'nowrap'}}
spaceItems={{default: 'spaceItemsMd'}}
>
<FlexItem>
<Select
variant={SelectVariant.single}
@ -182,8 +197,21 @@ export default function CreateRepositoryModalTemplate(
{namespaceSelectionList()}
</Select>
</FlexItem>
<FlexItem> / </FlexItem>
<FlexItem>/</FlexItem>
</Flex>
{!validationState.namespace && (
<FormHelperText>
<HelperText>
<HelperTextItem
variant="error"
icon={<ExclamationCircleIcon />}
>
Select a namespace
</HelperTextItem>
</HelperText>
</FormHelperText>
)}
</FormGroup>
</FlexItem>
<FlexItem>
@ -191,9 +219,6 @@ export default function CreateRepositoryModalTemplate(
label="Repository name"
isRequired
fieldId="modal-with-form-form-name"
helperTextInvalid="Must contain only lowercase alphanumeric and _- characters. Max 255 characters."
helperTextInvalidIcon={<ExclamationCircleIcon />}
validated={validationState.repoName ? 'success' : 'error'}
>
<TextInput
isRequired
@ -204,6 +229,20 @@ export default function CreateRepositoryModalTemplate(
ref={nameInputRef}
validated={validationState.repoName ? 'default' : 'error'}
/>
{!validationState.repoName && (
<FormHelperText>
<HelperText>
<HelperTextItem
variant="error"
icon={<ExclamationCircleIcon />}
>
Must contain only lowercase alphanumeric and _-
characters. Max 255 characters.
</HelperTextItem>
</HelperText>
</FormHelperText>
)}
</FormGroup>
</FlexItem>
</Flex>
@ -216,7 +255,7 @@ export default function CreateRepositoryModalTemplate(
id="repository-description-input"
name="modal-with-form-form-name"
value={newRepository.description}
onChange={handleRepoDescriptionChange}
onChange={(_event, value) => handleRepoDescriptionChange(value)}
ref={nameInputRef}
/>
</FormGroup>
@ -224,25 +263,29 @@ export default function CreateRepositoryModalTemplate(
label="Repository visibility"
fieldId="modal-with-form-form-email"
>
<Radio
isChecked={repoVisibility === visibilityType.PUBLIC}
name="Public"
onChange={() => setrepoVisibility(visibilityType.PUBLIC)}
label="Public"
id={visibilityType.PUBLIC}
value={visibilityType.PUBLIC}
description="Anyone can see and pull from this repository. You choose who can push."
/>
<br />
<Radio
isChecked={repoVisibility === visibilityType.PRIVATE}
name="Private"
onChange={() => setrepoVisibility(visibilityType.PRIVATE)}
label="Private"
id={visibilityType.PRIVATE}
value={visibilityType.PRIVATE}
description="You choose who can see,pull and push from/to this repository."
/>
<Flex
direction={{default: 'column'}}
spaceItems={{default: 'spaceItemsMd'}}
>
<Radio
isChecked={repoVisibility === visibilityType.PUBLIC}
name="Public"
onChange={() => setrepoVisibility(visibilityType.PUBLIC)}
label="Public"
id={visibilityType.PUBLIC}
value={visibilityType.PUBLIC}
description="Anyone can see and pull from this repository. You choose who can push."
/>
<Radio
isChecked={repoVisibility === visibilityType.PRIVATE}
name="Private"
onChange={() => setrepoVisibility(visibilityType.PRIVATE)}
label="Private"
id={visibilityType.PRIVATE}
value={visibilityType.PRIVATE}
description="You choose who can see,pull and push from/to this repository."
/>
</Flex>
</FormGroup>
</Form>
</Modal>

View File

@ -1,3 +1,4 @@
import {SetStateAction, useState} from 'react';
import {
Alert,
Modal,
@ -5,9 +6,8 @@ import {
Text,
TextContent,
TextVariants,
Wizard,
} from '@patternfly/react-core';
import {SetStateAction, useState} from 'react';
import {Wizard} from '@patternfly/react-core/deprecated';
import NameAndDescription from './robotAccountWizard/NameAndDescription';
import {useCreateRobotAccount} from 'src/hooks/useRobotAccounts';

View File

@ -1,4 +1,4 @@
import {useEffect, useState} from 'react';
import {useState} from 'react';
import {
Tabs,
Tab,
@ -37,13 +37,13 @@ const EmptyRobotToken = {
export default function RobotTokensModal(props: RobotTokensModalProps) {
const [activeTabKey, setActiveTabKey] = useState<string | number>(0);
const [isSecretExpanded, setSecretExpanded] = useState(false);
const [loading, setLoading] = useState<boolean>(true);
const [, setLoading] = useState<boolean>(true);
const [tokenData, setTokenData] = useState<IRobotToken>(EmptyRobotToken);
const [err, setErr] = useState<string[]>();
const [, setErr] = useState<string[]>();
const config = useQuayConfig();
const domain = config?.config.SERVER_HOSTNAME;
const {robotAccountToken, regenerateRobotToken} = useRobotToken({
const {regenerateRobotToken} = useRobotToken({
orgName: props.namespace,
robotAcct: props.robotAccount.name,
onSuccess: (result) => {
@ -134,7 +134,7 @@ export default function RobotTokensModal(props: RobotTokensModalProps) {
};
const handleTabClick = (
event: React.MouseEvent<any> | React.KeyboardEvent | MouseEvent,
_event: React.MouseEvent<unknown> | React.KeyboardEvent | MouseEvent,
tabIndex: string | number,
) => {
setActiveTabKey(tabIndex);
@ -209,9 +209,11 @@ export default function RobotTokensModal(props: RobotTokensModalProps) {
<>
<TabTitleIcon>
<img
src={require(activeTabKey == 1
? 'src/assets/kubernetes.svg'
: 'src/assets/kubernetes-grey.svg')}
src={require(
activeTabKey == 1
? 'src/assets/kubernetes.svg'
: 'src/assets/kubernetes-grey.svg',
)}
/>
</TabTitleIcon>
<TabTitleText>Kubernetes</TabTitleText>
@ -253,7 +255,8 @@ export default function RobotTokensModal(props: RobotTokensModalProps) {
>
<TextArea
value={getKubernetesContent().join('')}
isReadOnly={true}
readOnly
readOnlyVariant="default"
autoResize={true}
className="text-area-height"
id="expandable-kube-content"
@ -296,9 +299,11 @@ export default function RobotTokensModal(props: RobotTokensModalProps) {
<>
<TabTitleIcon>
<img
src={require(activeTabKey == 2
? 'src/assets/podman.svg'
: 'src/assets/podman-grey.svg')}
src={require(
activeTabKey == 2
? 'src/assets/podman.svg'
: 'src/assets/podman-grey.svg',
)}
/>
</TabTitleIcon>
<TabTitleText>Podman</TabTitleText>

View File

@ -1,8 +1,8 @@
.pf-c-alert {
--pf-c-alert--PaddingTop: 25rem;
.pf-v5-c-alert {
--pf-v5-c-alert--PaddingTop: 25rem;
}
.fas{
font-size: var(--pf-global--icon--FontSize--md);
}
font-size: var(--pf-v5-global--icon--FontSize--md);
}

View File

@ -13,21 +13,16 @@ import {
Toolbar,
ToolbarContent,
ToolbarItem,
} from '@patternfly/react-core';
import {
Dropdown,
DropdownItem,
DropdownSeparator,
KebabToggle,
} from '@patternfly/react-core';
KebabToggleProps,
} from '@patternfly/react-core/deprecated';
import {DropdownCheckbox} from 'src/components/toolbar/DropdownCheckbox';
import {ToolbarPagination} from 'src/components/toolbar/ToolbarPagination';
import {
TableComposable,
Tbody,
Td,
Th,
Thead,
Tr,
} from '@patternfly/react-table';
import {Table, Tbody, Td, Th, Thead, Tr} from '@patternfly/react-table';
import {DropdownWithDescription} from 'src/components/toolbar/DropdownWithDescription';
import {IRepository} from 'src/resources/RepositoryResource';
import {formatDate} from 'src/libs/utils';
@ -42,9 +37,6 @@ const ColumnNames = {
type TableModeType = 'All' | 'Selected';
const defaultSelectedVal = 'Read';
const defaultUnSelectedVal = 'None';
export default function AddToRepository(props: AddToRepositoryProps) {
const [tableMode, setTableMode] = useState<TableModeType>('All');
const [page, setPage] = useState(1);
@ -60,10 +52,7 @@ export default function AddToRepository(props: AddToRepositoryProps) {
return r1.last_modified > r2.last_modified ? -1 : 1;
});
const onTableModeChange: ToggleGroupItemProps['onChange'] = (
_isSelected,
event,
) => {
const onTableModeChange: ToggleGroupItemProps['onChange'] = (event) => {
const id = event.currentTarget.id;
setTableMode(id as TableModeType);
if (id == 'All') {
@ -189,7 +178,10 @@ export default function AddToRepository(props: AddToRepositoryProps) {
});
};
const onKebabToggle = (isKebabOpen: boolean) => {
const onKebabToggle: KebabToggleProps['onToggle'] = (
_event,
isKebabOpen: boolean,
) => {
setKebabOpen(isKebabOpen);
};
@ -290,7 +282,7 @@ export default function AddToRepository(props: AddToRepositoryProps) {
/>
</ToolbarContent>
</Toolbar>
<TableComposable aria-label="Selectable table">
<Table aria-label="Selectable table">
<Thead>
<Tr>
<Th />
@ -336,7 +328,7 @@ export default function AddToRepository(props: AddToRepositoryProps) {
</Tbody>
);
})}
</TableComposable>
</Table>
<PanelFooter>
<ToolbarPagination
itemsList={filteredItems}

View File

@ -1,10 +1,5 @@
import {
DropdownItem,
Button,
Text,
TextVariants,
TextContent,
} from '@patternfly/react-core';
import {Button, Text, TextVariants, TextContent} from '@patternfly/react-core';
import {DropdownItem} from '@patternfly/react-core/deprecated';
import {useState} from 'react';
import {DesktopIcon} from '@patternfly/react-icons';
import ToggleDrawer from 'src/components/ToggleDrawer';

View File

@ -1,8 +1,8 @@
import {Button} from '@patternfly/react-core';
import {
Button,
WizardContextConsumer,
WizardFooter,
} from '@patternfly/react-core';
} from '@patternfly/react-core/deprecated';
export default function Footer(props: FooterProps) {
if (props.isDrawerExpanded) {
@ -11,14 +11,7 @@ export default function Footer(props: FooterProps) {
return (
<WizardFooter>
<WizardContextConsumer>
{({
activeStep,
goToStepByName,
goToStepById,
onNext,
onBack,
onClose,
}) => {
{({activeStep, onNext, onBack, onClose}) => {
return (
<>
{activeStep.name != 'Review and Finish' ? (

View File

@ -1,4 +1,11 @@
import {Form, FormGroup, TextInput} from '@patternfly/react-core';
import {
Form,
FormGroup,
FormHelperText,
HelperText,
HelperTextItem,
TextInput,
} from '@patternfly/react-core';
import ExclamationCircleIcon from '@patternfly/react-icons/dist/esm/icons/exclamation-circle-icon';
import {useEffect, useState} from 'react';
@ -29,15 +36,7 @@ export default function NameAndDescription(props: NameAndDescriptionProps) {
return (
<Form>
<FormGroup
label={props.nameLabel}
fieldId="form-name"
isRequired
helperText={nameHelperText}
helperTextInvalid={nameHelperText}
validated={validatedName}
helperTextInvalidIcon={<ExclamationCircleIcon />}
>
<FormGroup label={props.nameLabel} fieldId="form-name" isRequired>
<TextInput
data-testid="new-robot-name-input"
isRequired
@ -45,25 +44,40 @@ export default function NameAndDescription(props: NameAndDescriptionProps) {
id="robot-wizard-form-name"
name="form-name"
value={props.name}
onChange={handleNameChange}
onChange={(_event, robotName: string) => handleNameChange(robotName)}
validated={validatedName}
/>
<FormHelperText>
<HelperText>
<HelperTextItem
variant={validatedName}
{...(validatedName === 'error' && {
icon: <ExclamationCircleIcon />,
})}
>
{nameHelperText}
</HelperTextItem>
</HelperText>
</FormHelperText>
</FormGroup>
<FormGroup
label={props.descriptionLabel}
fieldId="form-description"
helperText={props.helperText}
>
<FormGroup label={props.descriptionLabel} fieldId="form-description">
<TextInput
data-testid="new-robot-description-input"
type="text"
id="robot-wizard-form-description"
name="form-description"
value={props.description}
onChange={(robotDescription: string) =>
onChange={(_event, robotDescription: string) =>
props.setDescription(robotDescription)
}
/>
<FormHelperText>
<HelperText>
<HelperTextItem>{props.helperText}</HelperTextItem>
</HelperText>
</FormHelperText>
</FormGroup>
</Form>
);

View File

@ -5,13 +5,12 @@ import {
TextInput,
FormGroup,
Form,
Dropdown,
DropdownToggle,
ToggleGroup,
ToggleGroupItem,
ToggleGroupItemProps,
} from '@patternfly/react-core';
import {TableComposable, Tbody, Td, Tr} from '@patternfly/react-table';
import {Dropdown, DropdownToggle} from '@patternfly/react-core/deprecated';
import {Table, Tbody, Td, Tr} from '@patternfly/react-table';
import React, {useState} from 'react';
type TableModeType = 'Teams' | 'Repositories' | 'Default-permissions';
@ -34,10 +33,7 @@ export default function ReviewAndFinish(props: ReviewAndFinishProps) {
props.userNamespace ? 'Repositories' : 'Teams',
);
const onTableModeChange: ToggleGroupItemProps['onChange'] = (
_isSelected,
event,
) => {
const onTableModeChange: ToggleGroupItemProps['onChange'] = (event) => {
const id = event.currentTarget.id;
setTableMode(id as TableModeType);
};
@ -54,7 +50,7 @@ export default function ReviewAndFinish(props: ReviewAndFinishProps) {
const fetchSelectedTeams = () => {
return (
<TableComposable aria-label="Selectable table">
<Table aria-label="Selectable table">
<Tbody>
{props.selectedTeams.map((team, rowIndex) => (
<Tr key={team.name}>
@ -62,7 +58,7 @@ export default function ReviewAndFinish(props: ReviewAndFinishProps) {
select={{
rowIndex,
isSelected: true,
disable: true,
isDisabled: true,
}}
/>
<Td dataLabel={TeamColumnNames.name}>{team.name}</Td>
@ -78,13 +74,13 @@ export default function ReviewAndFinish(props: ReviewAndFinishProps) {
</Tr>
))}
</Tbody>
</TableComposable>
</Table>
);
};
const fetchSelectedRepos = () => {
return (
<TableComposable aria-label="Selectable table">
<Table aria-label="Selectable table">
<Tbody>
{props.selectedRepos.map((repo, rowIndex) => (
<Tr key={repo.name}>
@ -92,7 +88,7 @@ export default function ReviewAndFinish(props: ReviewAndFinishProps) {
select={{
rowIndex,
isSelected: true,
disable: true,
isDisabled: true,
}}
/>
<Td dataLabel={RepoColumnNames.name}>{repo.name}</Td>
@ -111,7 +107,7 @@ export default function ReviewAndFinish(props: ReviewAndFinishProps) {
</Tr>
))}
</Tbody>
</TableComposable>
</Table>
);
};

View File

@ -1,11 +1,4 @@
import {
TableComposable,
Tbody,
Td,
Th,
Thead,
Tr,
} from '@patternfly/react-table';
import {Table, Tbody, Td, Th, Thead, Tr} from '@patternfly/react-table';
import {
PageSection,
PanelFooter,
@ -66,10 +59,7 @@ export default function TeamView(props: TeamViewProps) {
page * perPage - perPage + perPage,
);
const onTableModeChange: ToggleGroupItemProps['onChange'] = (
_isSelected,
event,
) => {
const onTableModeChange: ToggleGroupItemProps['onChange'] = (event) => {
const id = event.currentTarget.id;
setTableMode(id as TableModeType);
};
@ -146,7 +136,7 @@ export default function TeamView(props: TeamViewProps) {
/>
</ToolbarContent>
</Toolbar>
<TableComposable aria-label="Selectable table">
<Table aria-label="Selectable table">
<Thead>
<Tr>
{props.showCheckbox ? <Th /> : null}
@ -185,7 +175,7 @@ export default function TeamView(props: TeamViewProps) {
</Tbody>
);
})}
</TableComposable>
</Table>
<PanelFooter>
<ToolbarPagination
itemsList={filteredItems}

View File

@ -1,4 +1,10 @@
import {Nav, NavItem, NavList, PageSidebar} from '@patternfly/react-core';
import {
Nav,
NavItem,
NavList,
PageSidebar,
PageSidebarBody,
} from '@patternfly/react-core';
import {Link, useLocation} from 'react-router-dom';
import {SidebarState} from 'src/atoms/SidebarState';
import {NavigationPath} from 'src/routes/NavigationPath';
@ -24,7 +30,7 @@ const routes: SideNavProps[] = [
isSideNav: true,
navPath: NavigationPath.repositoriesList,
title: 'Repositories',
component: <RepositoriesList organizationName={null}/>,
component: <RepositoriesList organizationName={null} />,
},
];
@ -51,7 +57,9 @@ export function QuaySidebar() {
if (sidebarState.isOpen) {
return (
<PageSidebar className="page-sidebar" theme="dark" nav={Navigation} />
<PageSidebar className="page-sidebar" theme="dark">
<PageSidebarBody>{Navigation}</PageSidebarBody>
</PageSidebar>
);
}
return <></>;

View File

@ -6,15 +6,12 @@ import {
} from '@patternfly/react-core';
import React from 'react';
type TableModeType = 'All' | 'Selected';
type TableModeType = 'All' | 'Selected' | 'Collapse';
export function AllSelectedToggleButton(props: AllSelectedToggleButtonProps) {
const [tableMode, setTableMode] = React.useState<TableModeType>('All');
const onTableModeChange: ToggleGroupItemProps['onChange'] = (
_isSelected,
event,
) => {
const onTableModeChange: ToggleGroupItemProps['onChange'] = (event) => {
const id = event.currentTarget.id;
setTableMode(id as TableModeType);
if (id == 'All') {

View File

@ -1,11 +1,11 @@
import {useState} from 'react';
import {ToolbarItem} from '@patternfly/react-core';
import {
Dropdown,
DropdownToggle,
DropdownToggleCheckbox,
DropdownItem,
ToolbarItem,
} from '@patternfly/react-core';
} from '@patternfly/react-core/deprecated';
export function DropdownCheckbox(props: DropdownCheckboxProps) {
const [isOpen, setIsOpen] = useState(false);
@ -70,7 +70,7 @@ export function DropdownCheckbox(props: DropdownCheckboxProps) {
key="split-checkbox"
aria-label="Select all"
isChecked={props.selectedItems?.length > 0 ? true : false}
onChange={(checked) =>
onChange={(_event, checked) =>
checked ? selectPageItems() : deSelectAll()
}
>
@ -91,10 +91,10 @@ export function DropdownCheckbox(props: DropdownCheckboxProps) {
}
type DropdownCheckboxProps = {
selectedItems: any[];
selectedItems: unknown[];
deSelectAll: (selectedList) => void;
allItemsList: any[];
itemsPerPageList: any[];
allItemsList: unknown[];
itemsPerPageList: unknown[];
onItemSelect: (Item, rowIndex, isSelecting) => void;
id?: string;
};

View File

@ -1,5 +1,9 @@
import {useEffect, useState} from 'react';
import {Dropdown, DropdownItem, DropdownToggle} from '@patternfly/react-core';
import {
Dropdown,
DropdownItem,
DropdownToggle,
} from '@patternfly/react-core/deprecated';
import * as React from 'react';
const defaultSelectedVal = 'Read';
@ -50,7 +54,7 @@ export function DropdownWithDescription(props: DropdownWithDescriptionProps) {
toggle={
<DropdownToggle
id="toggle-descriptions"
onToggle={(isOpen) => setIsOpen(isOpen)}
onToggle={(_event, isOpen) => setIsOpen(isOpen)}
>
{dropdownToggle}
</DropdownToggle>

View File

@ -10,10 +10,7 @@ type TableModeType = 'Expand' | 'Collapse';
export function ExpandCollapseButton(props: ExpandCollapseButtonProps) {
const [tableMode, setTableMode] = React.useState<TableModeType>('Collapse');
const onTableModeChange: ToggleGroupItemProps['onChange'] = (
_isSelected,
event,
) => {
const onTableModeChange: ToggleGroupItemProps['onChange'] = (event) => {
const id = event.currentTarget.id;
setTableMode(id as TableModeType);
if (id == 'Expand') {

View File

@ -4,8 +4,13 @@ import {SearchState} from './SearchTypes';
import {SetterOrUpdater} from 'recoil';
export function FilterInput(props: FilterInputProps) {
const setSearchState = (val: string) => {
props.onChange((prev: SearchState) => ({...prev, query: val.trim()}));
const setSearchState = (
_event:
| React.FormEvent<HTMLInputElement>
| React.SyntheticEvent<HTMLButtonElement>,
value: string,
) => {
props.onChange((prev: SearchState) => ({...prev, query: value.trim()}));
};
return (
@ -14,7 +19,7 @@ export function FilterInput(props: FilterInputProps) {
placeholder="Search"
value={props.searchState.query}
onChange={setSearchState}
onClear={() => setSearchState('')}
onClear={(event) => setSearchState(event, '')}
id={props.id}
/>
</ToolbarItem>

View File

@ -1,10 +1,6 @@
import React from 'react';
import {
TextInput,
ToolbarItem,
Dropdown,
DropdownToggle,
} from '@patternfly/react-core';
import {TextInput, ToolbarItem} from '@patternfly/react-core';
import {Dropdown, DropdownToggle} from '@patternfly/react-core/deprecated';
import {SearchState} from './SearchTypes';
import {SetterOrUpdater} from 'recoil';
@ -33,10 +29,10 @@ export function FilterWithDropdown(props: FilterWithDropdownProps) {
name="search input"
placeholder={props.searchInputText}
value={props.searchState.query}
onChange={setSearchState}
onChange={(_event, val: string) => setSearchState(val)}
/>,
]}
onToggle={(isOpen: boolean) => setIsOpen(isOpen)}
onToggle={(_event, isOpen: boolean) => setIsOpen(isOpen)}
id="toggle-split-button"
/>
}

View File

@ -1,4 +1,8 @@
import {Dropdown, DropdownToggle, KebabToggle} from '@patternfly/react-core';
import {
Dropdown,
DropdownToggle,
KebabToggle,
} from '@patternfly/react-core/deprecated';
import * as React from 'react';
export function Kebab(props: KebabProps) {

View File

@ -1,10 +1,10 @@
import {useState} from 'react';
import {ToolbarItem} from '@patternfly/react-core';
import {
Dropdown,
DropdownToggle,
DropdownItem,
ToolbarItem,
} from '@patternfly/react-core';
} from '@patternfly/react-core/deprecated';
import {SetterOrUpdater} from 'recoil';
import {SearchState} from './SearchTypes';

View File

@ -16,7 +16,7 @@ export function SearchInput(props: SearchInput) {
name="search input"
placeholder={`Search by ${props.searchState.field}...`}
value={props.searchState.query}
onChange={setSearchState}
onChange={(_event, val) => setSearchState(val)}
/>
</ToolbarItem>
);

View File

@ -8,7 +8,6 @@ export const ToolbarPagination = (props: ToolbarPaginationProps) => {
return (
<ToolbarItem variant="pagination">
<Pagination
perPageComponent="button"
itemCount={props.total || props.itemsList?.length}
perPage={props.perPage}
id={props.id ? props.id : 'toolbar-pagination'}
@ -29,7 +28,7 @@ export const ToolbarPagination = (props: ToolbarPaginationProps) => {
};
type ToolbarPaginationProps = {
itemsList?: any[];
itemsList?: unknown[];
perPage: number;
page: number;
setPage: (pageNumber: number) => void;

View File

@ -5,7 +5,11 @@ import {
Form,
FormGroup,
TextInput,
FormHelperText,
HelperText,
HelperTextItem,
} from '@patternfly/react-core';
import ExclamationCircleIcon from '@patternfly/react-icons/dist/esm/icons/exclamation-circle-icon';
import './css/Organizations.scss';
import {isValidEmail} from 'src/libs/utils';
import {useState} from 'react';
@ -42,7 +46,7 @@ export const CreateOrganizationModal = (
},
});
const handleNameInputChange = (value: any) => {
const handleNameInputChange = (value: string) => {
const regex = /^([a-z0-9]+(?:[._-][a-z0-9]+)*)$/;
if (!regex.test(value) || value.length >= 256 || value.length < 2) {
setValidation({
@ -71,7 +75,7 @@ export const CreateOrganizationModal = (
setOrganizationName(value);
};
const handleEmailInputChange = (value: any) => {
const handleEmailInputChange = (value: string) => {
setOrganizationEmail(value);
};
@ -125,35 +129,56 @@ export const CreateOrganizationModal = (
label="Organization Name"
isRequired
fieldId="create-org-name"
helperText={validation.message}
helperTextInvalid={validation.message}
validated={validation.type}
>
<TextInput
isRequired
type="text"
id="create-org-name-input"
value={organizationName}
onChange={handleNameInputChange}
onChange={(_event, value) => handleNameInputChange(value)}
validated={validation.type}
/>
<FormHelperText>
<HelperText>
<HelperTextItem
variant={validation.type}
{...(validation.type === 'error' && {
icon: <ExclamationCircleIcon />,
})}
>
{validation.message}
</HelperTextItem>
</HelperText>
</FormHelperText>
</FormGroup>
<FormGroup
label="Organization Email"
fieldId="create-org-email"
helperText="This address must be different from your account's email"
helperTextInvalid={'Enter a valid email: email@provider.com'}
validated={invalidEmailFlag ? 'error' : 'default'}
>
<FormGroup label="Organization Email" fieldId="create-org-email">
<TextInput
type="email"
id="create-org-email-input"
name="create-org-email-input"
value={organizationEmail}
onChange={handleEmailInputChange}
onChange={(_event, value) => handleEmailInputChange(value)}
validated={invalidEmailFlag ? 'error' : 'default'}
onBlur={onInputBlur}
/>
<FormHelperText>
<HelperText>
{invalidEmailFlag ? (
<HelperTextItem
variant="error"
icon={<ExclamationCircleIcon />}
>
Enter a valid email: email@provider.com
</HelperTextItem>
) : (
<HelperTextItem>
{"This address must be different from your account's email"}
</HelperTextItem>
)}
</HelperText>
</FormHelperText>
</FormGroup>
<br />
</Form>

View File

@ -1,4 +1,8 @@
import {Dropdown, DropdownItem, DropdownToggle} from '@patternfly/react-core';
import {
Dropdown,
DropdownItem,
DropdownToggle,
} from '@patternfly/react-core/deprecated';
import {useEffect, useState} from 'react';
import {
IDefaultPermission,

View File

@ -6,14 +6,7 @@ import {
TextVariants,
Spinner,
} from '@patternfly/react-core';
import {
TableComposable,
Tbody,
Td,
Th,
Thead,
Tr,
} from '@patternfly/react-table';
import {Table, Tbody, Td, Th, Thead, Tr} from '@patternfly/react-table';
import {useState} from 'react';
import {
IDefaultPermission,
@ -109,7 +102,7 @@ export default function DefaultPermissionsList(
searchOptions={[permissionColumnNames.repoCreatedBy]}
setDrawerContent={props.setDrawerContent}
>
<TableComposable aria-label="Selectable table">
<Table aria-label="Selectable table">
<Thead>
<Tr>
<Th />
@ -153,7 +146,7 @@ export default function DefaultPermissionsList(
</Tr>
))}
</Tbody>
</TableComposable>
</Table>
</DefaultPermissionsToolbar>
</PageSection>
);

View File

@ -33,7 +33,7 @@ export default function DefaultPermissionsToolbar(
searchState={props.search}
setSearchState={props.setSearch}
/>
<Flex className="pf-u-mr-md">
<Flex className="pf-v5-u-mr-md">
<FlexItem>
<SearchInput
searchState={props.search}

View File

@ -1,4 +1,8 @@
import {Dropdown, DropdownItem, KebabToggle} from '@patternfly/react-core';
import {
Dropdown,
DropdownItem,
KebabToggle,
} from '@patternfly/react-core/deprecated';
import {useEffect, useState} from 'react';
import {AlertVariant} from 'src/atoms/AlertState';
import {useAlerts} from 'src/hooks/UseAlerts';

View File

@ -7,16 +7,18 @@ import {
DrawerHead,
DrawerPanelBody,
DrawerPanelContent,
Dropdown,
DropdownItem,
DropdownToggle,
Form,
FormGroup,
Radio,
SelectGroup,
SelectOption,
Spinner,
} from '@patternfly/react-core';
import {
Dropdown,
DropdownItem,
DropdownToggle,
SelectOption,
SelectGroup,
} from '@patternfly/react-core/deprecated';
import {DesktopIcon, UsersIcon} from '@patternfly/react-icons';
import {useState, Ref} from 'react';
import EntitySearch from 'src/components/EntitySearch';
@ -397,7 +399,7 @@ export default function CreatePermissionDrawer(
{createRobotModalForAppliedTo}
</Conditional>
<DrawerPanelContent>
<DrawerHead className="pf-c-title pf-m-xl">
<DrawerHead className="pf-v5-c-title pf-m-xl">
<h6
tabIndex={props.drawerContent != DrawerContentType.None ? 0 : -1}
ref={props.drawerRef}
@ -410,7 +412,7 @@ export default function CreatePermissionDrawer(
</DrawerActions>
</DrawerHead>
<DrawerPanelBody>
<h3 className="pf-c-title pf-m-md">
<h3 className="pf-v5-c-title pf-m-md">
Applies when a repository is created by:
</h3>
</DrawerPanelBody>

View File

@ -5,6 +5,9 @@ import {
Modal,
ModalVariant,
TextInput,
FormHelperText,
HelperText,
HelperTextItem,
} from '@patternfly/react-core';
import {ExclamationCircleIcon} from '@patternfly/react-icons';
import {useEffect, useState} from 'react';
@ -22,13 +25,19 @@ export const CreateTeamModal = (props: CreateTeamModalProps): JSX.Element => {
const [nameHelperText, setNameHelperText] = useState(props.nameHelperText);
const {addAlert} = useAlerts();
const handleNameChange = (name: string) => {
const handleNameChange = (
_event: React.FormEvent<HTMLInputElement>,
name: string,
) => {
setInputTeamName(name);
props.setTeamName(name);
setNameHelperText('Validating...');
};
const handleDescriptionChange = (descr: string) => {
const handleDescriptionChange = (
_event: React.FormEvent<HTMLInputElement>,
descr: string,
) => {
setInputTeamDescription(descr);
props.setDescription(descr);
};
@ -104,15 +113,7 @@ export const CreateTeamModal = (props: CreateTeamModalProps): JSX.Element => {
]}
>
<Form>
<FormGroup
label={props.nameLabel}
fieldId="form-name"
isRequired
helperText={nameHelperText}
helperTextInvalid={nameHelperText}
validated={validatedName}
helperTextInvalidIcon={<ExclamationCircleIcon />}
>
<FormGroup label={props.nameLabel} fieldId="form-name" isRequired>
<TextInput
data-testid="new-team-name-input"
isRequired
@ -123,12 +124,21 @@ export const CreateTeamModal = (props: CreateTeamModalProps): JSX.Element => {
onChange={handleNameChange}
validated={validatedName}
/>
<FormHelperText>
<HelperText>
<HelperTextItem
variant={validatedName}
{...(validatedName === 'error' && {
icon: <ExclamationCircleIcon />,
})}
>
{nameHelperText}
</HelperTextItem>
</HelperText>
</FormHelperText>
</FormGroup>
<FormGroup
label={props.descriptionLabel}
fieldId="form-description"
helperText={props.helperText}
>
<FormGroup label={props.descriptionLabel} fieldId="form-description">
<TextInput
data-testid="new-team-description-input"
type="text"
@ -137,6 +147,12 @@ export const CreateTeamModal = (props: CreateTeamModalProps): JSX.Element => {
value={inputTeamDescription}
onChange={handleDescriptionChange}
/>
<FormHelperText>
<HelperText>
<HelperTextItem>{props.helperText}</HelperTextItem>
</HelperText>
</FormHelperText>
</FormGroup>
</Form>
</Modal>

View File

@ -5,14 +5,7 @@ import {
Text,
TextVariants,
} from '@patternfly/react-core';
import {
TableComposable,
Tbody,
Td,
Th,
Thead,
Tr,
} from '@patternfly/react-table';
import {Table, Tbody, Td, Th, Thead, Tr} from '@patternfly/react-table';
import {ITeamMember} from 'src/hooks/UseMembers';
import {useEffect, useState} from 'react';
import AddTeamToolbar from 'src/routes/OrganizationsList/Organization/Tabs/DefaultPermissions/createTeamWizard/AddTeamToolbar';
@ -184,7 +177,7 @@ export default function AddTeamMember(props: AddTeamMemberProps) {
addTeamMemberHandler={addTeamMemberHandler}
setDrawerExpanded={props.setDrawerExpanded}
>
<TableComposable aria-label="Selectable table">
<Table aria-label="Selectable table">
<Thead>
<Tr>
<Th>{memberAndRobotColNames.teamMember}</Th>
@ -214,7 +207,7 @@ export default function AddTeamMember(props: AddTeamMemberProps) {
</Tr>
))}
</Tbody>
</TableComposable>
</Table>
</AddTeamToolbar>
</PageSection>
</>

View File

@ -1,11 +1,10 @@
import {
Divider,
SelectGroup,
SelectOption,
Toolbar,
ToolbarContent,
ToolbarItem,
} from '@patternfly/react-core';
import {SelectGroup, SelectOption} from '@patternfly/react-core/deprecated';
import {DesktopIcon} from '@patternfly/react-icons';
import React from 'react';
import {useState} from 'react';

View File

@ -4,11 +4,11 @@ import {
TextContent,
Text,
TextVariants,
Wizard,
AlertGroup,
Alert,
AlertActionCloseButton,
} from '@patternfly/react-core';
import {Wizard} from '@patternfly/react-core/deprecated';
import {useEffect, useState} from 'react';
import {
ITeamMember,

View File

@ -1,15 +1,16 @@
import {Form, FormGroup, TextInput} from '@patternfly/react-core';
import ExclamationCircleIcon from '@patternfly/react-icons/dist/esm/icons/exclamation-circle-icon';
import {
Form,
FormGroup,
TextInput,
FormHelperText,
HelperText,
HelperTextItem,
} from '@patternfly/react-core';
export default function NameAndDescription(props: NameAndDescriptionProps) {
return (
<Form>
<FormGroup
label={props.nameLabel}
fieldId="form-name"
isRequired
helperTextInvalidIcon={<ExclamationCircleIcon />}
>
<FormGroup label={props.nameLabel} fieldId="form-name" isRequired>
<TextInput
data-testid="create-team-wizard-form-name"
isRequired
@ -21,11 +22,7 @@ export default function NameAndDescription(props: NameAndDescriptionProps) {
isDisabled
/>
</FormGroup>
<FormGroup
label={props.descriptionLabel}
fieldId="form-description"
helperText={props.helperText}
>
<FormGroup label={props.descriptionLabel} fieldId="form-description">
<TextInput
data-testid="create-team-wizard-form-description"
type="text"
@ -35,6 +32,12 @@ export default function NameAndDescription(props: NameAndDescriptionProps) {
aria-label="disabled teamDescription input"
isDisabled
/>
<FormHelperText>
<HelperText>
<HelperTextItem>{props.helperText}</HelperTextItem>
</HelperText>
</FormHelperText>
</FormGroup>
</Form>
);

View File

@ -1,8 +1,8 @@
import {Button} from '@patternfly/react-core';
import {
Button,
WizardContextConsumer,
WizardFooter,
} from '@patternfly/react-core';
} from '@patternfly/react-core/deprecated';
export default function ReviewAndFinishFooter(
props: ReviewAndFinishFooterProps,

View File

@ -15,8 +15,10 @@ import {
Button,
Alert,
AlertGroup,
FormHelperText,
HelperText,
HelperTextItem,
} from '@patternfly/react-core';
import {useLocation} from 'react-router-dom';
import {useCurrentUser} from 'src/hooks/UseCurrentUser';
import {useOrganization} from 'src/hooks/UseOrganization';
import {useOrganizationSettings} from 'src/hooks/UseOrganizationSettings';
@ -35,7 +37,6 @@ const timeMachineOptions = {
};
const GeneralSettings = (props: GeneralSettingsProps) => {
const location = useLocation();
const quayConfig = useQuayConfig();
const organizationName = props.organizationName;
const {user, loading: isUserLoading} = useCurrentUser();
@ -45,7 +46,7 @@ const GeneralSettings = (props: GeneralSettingsProps) => {
const {updateOrgSettings} = useOrganizationSettings({
name: props.organizationName,
onSuccess: (result) => {
onSuccess: () => {
setAlerts((prevAlerts) => {
return [
...prevAlerts,
@ -88,7 +89,7 @@ const GeneralSettings = (props: GeneralSettingsProps) => {
// Email
const namespaceEmail = isUserOrganization
? user?.email || ''
: (organization as any)?.email || '';
: organization?.email || '';
const [emailFormValue, setEmailFormValue] = useState<string>('');
const [validated, setValidated] = useState<validate>('default');
@ -165,46 +166,49 @@ const GeneralSettings = (props: GeneralSettingsProps) => {
<Alert variant="danger" title={error} aria-live="polite" isInline />
</FormAlert>
)}
<FormGroup
isInline
label="Organization"
fieldId="form-organization"
helperText={'Namespace names cannot be changed once set.'}
>
<FormGroup isInline label="Organization" fieldId="form-organization">
<TextInput
isDisabled
type="text"
id="form-name"
value={organizationName}
/>
<FormHelperText>
<HelperText>
<HelperTextItem>
Namespace names cannot be changed once set.
</HelperTextItem>
</HelperText>
</FormHelperText>
</FormGroup>
<FormGroup
isInline
label="Email"
fieldId="form-email"
helperText="The e-mail address associated with the organization."
>
<FormGroup isInline label="Email" fieldId="form-email">
<TextInput
type="email"
id="modal-with-form-form-name"
value={emailFormValue}
onChange={handleEmailChange}
onChange={(_event, emailFormValue) =>
handleEmailChange(emailFormValue)
}
/>
<FormHelperText>
<HelperText>
<HelperTextItem>
The e-mail address associated with the organization.
</HelperTextItem>
</HelperText>
</FormHelperText>
</FormGroup>
<FormGroup
isInline
label="Time Machine"
fieldId="form-time-machine"
helperText="The amount of time, after a tag is deleted, that the tag is accessible in time machine before being garbage collected."
>
<FormGroup isInline label="Time Machine" fieldId="form-time-machine">
<FormSelect
placeholder="Time Machine"
aria-label="Time Machine select"
data-testid="arch-select"
value={timeMachineFormValue}
onChange={(val) => setTimeMachineFormValue(val)}
onChange={(_event, val) => setTimeMachineFormValue(val)}
>
{quayConfig?.config?.TAG_EXPIRATION_OPTIONS.map((option, index) => (
<FormSelectOption
@ -214,6 +218,15 @@ const GeneralSettings = (props: GeneralSettingsProps) => {
/>
))}
</FormSelect>
<FormHelperText>
<HelperText>
<HelperTextItem>
The amount of time, after a tag is deleted, that the tag is
accessible in time machine before being garbage collected.
</HelperTextItem>
</HelperText>
</FormHelperText>
</FormGroup>
<ActionGroup>

View File

@ -6,14 +6,7 @@ import {
Spinner,
} from '@patternfly/react-core';
import CollaboratorsViewToolbar from './CollaboratorsViewToolbar';
import {
TableComposable,
Tbody,
Td,
Th,
Thead,
Tr,
} from '@patternfly/react-table';
import {Table, Tbody, Td, Th, Thead, Tr} from '@patternfly/react-table';
import {useFetchCollaborators} from 'src/hooks/UseMembers';
import {useEffect, useState} from 'react';
import {IMembers} from 'src/resources/MembersResource';
@ -109,7 +102,7 @@ export default function CollaboratorsViewList(
/>
{props.children}
<Conditional if={isDeleteModalOpen}>{deleteCollabModal}</Conditional>
<TableComposable aria-label="Selectable table">
<Table aria-label="Selectable table">
<Thead>
<Tr>
<Th />
@ -156,7 +149,7 @@ export default function CollaboratorsViewList(
</Tr>
))}
</Tbody>
</TableComposable>
</Table>
<PanelFooter>
<ToolbarPagination
itemsList={filteredCollaborators}

View File

@ -24,7 +24,7 @@ export default function CollaboratorsViewToolbar(
searchState={props.search}
setSearchState={props.setSearch}
/>
<Flex className="pf-u-mr-md">
<Flex className="pf-v5-u-mr-md">
<FlexItem>
<SearchInput
searchState={props.search}

View File

@ -1,11 +1,4 @@
import {
TableComposable,
Tbody,
Td,
Th,
Thead,
Tr,
} from '@patternfly/react-table';
import {Table, Tbody, Td, Th, Thead, Tr} from '@patternfly/react-table';
import {Link, useSearchParams} from 'react-router-dom';
import {
Label,
@ -131,7 +124,7 @@ export default function MembersViewList(props: MembersViewListProps) {
))}
isVisible={isPopoverOpen}
shouldClose={handleClick}
reference={() =>
triggerRef={() =>
document.getElementById('team-popover') as HTMLButtonElement
}
/>
@ -159,7 +152,7 @@ export default function MembersViewList(props: MembersViewListProps) {
searchOptions={[memberViewColumnNames.username]}
/>
{props.children}
<TableComposable aria-label="Selectable table">
<Table aria-label="Selectable table">
<Thead>
<Tr>
<Th />
@ -192,7 +185,7 @@ export default function MembersViewList(props: MembersViewListProps) {
</Tr>
))}
</Tbody>
</TableComposable>
</Table>
<PanelFooter>
<ToolbarPagination
itemsList={filteredMembers}

View File

@ -22,7 +22,7 @@ export default function MembersViewToolbar(props: MembersViewToolbarProps) {
searchState={props.search}
setSearchState={props.setSearch}
/>
<Flex className="pf-u-mr-md">
<Flex className="pf-v5-u-mr-md">
<FlexItem>
<SearchInput
searchState={props.search}

View File

@ -24,10 +24,7 @@ export default function TeamsAndMembershipList(
TableModeType.Teams,
);
const onTableModeChange: ToggleGroupItemProps['onChange'] = (
_isSelected,
event,
) => {
const onTableModeChange: ToggleGroupItemProps['onChange'] = (event) => {
const id = event.currentTarget.id;
setTableMode(id);
fetchTableItems();

View File

@ -12,14 +12,7 @@ import {
} from '@patternfly/react-core';
import {useEffect, useState} from 'react';
import ManageMembersToolbar from './ManageMembersToolbar';
import {
TableComposable,
Tbody,
Td,
Th,
Thead,
Tr,
} from '@patternfly/react-table';
import {Table, Tbody, Td, Th, Thead, Tr} from '@patternfly/react-table';
import {
ITeamMember,
useDeleteTeamMember,
@ -102,10 +95,7 @@ export default function ManageMembersList() {
}
}, [tableMode, allMembers]);
const onTableModeChange: ToggleGroupItemProps['onChange'] = (
_isSelected,
event,
) => {
const onTableModeChange: ToggleGroupItemProps['onChange'] = (event) => {
const id = event.currentTarget.id;
setTableMode(id);
};
@ -212,7 +202,7 @@ export default function ManageMembersList() {
searchOptions={[manageMemberColumnNames.teamMember]}
>
{viewToggle}
<TableComposable aria-label="Selectable table">
<Table aria-label="Selectable table">
<Thead>
<Tr>
<Th />
@ -256,7 +246,7 @@ export default function ManageMembersList() {
</Tr>
))}
</Tbody>
</TableComposable>
</Table>
</ManageMembersToolbar>
</PageSection>
);

View File

@ -29,7 +29,7 @@ export default function ManageMembersToolbar(props: ManageMembersToolbarProps) {
searchState={props.search}
setSearchState={props.setSearch}
/>
<Flex className="pf-u-mr-md">
<Flex className="pf-v5-u-mr-md">
<FlexItem>
<SearchInput
searchState={props.search}

View File

@ -1,4 +1,8 @@
import {Dropdown, DropdownItem, DropdownToggle} from '@patternfly/react-core';
import {
Dropdown,
DropdownItem,
DropdownToggle,
} from '@patternfly/react-core/deprecated';
import {useEffect, useState} from 'react';
import {ITeamRepoPerms} from 'src/hooks/UseTeams';
import {RepoPermissionDropdownItems} from 'src/routes/RepositoriesList/RobotAccountsList';

View File

@ -1,11 +1,4 @@
import {
TableComposable,
Tbody,
Td,
Th,
Thead,
Tr,
} from '@patternfly/react-table';
import {Table, Tbody, Td, Th, Thead, Tr} from '@patternfly/react-table';
import {Button, Modal, ModalVariant, Spinner} from '@patternfly/react-core';
import {useEffect, useState} from 'react';
import Empty from 'src/components/empty/Empty';
@ -207,7 +200,7 @@ export default function SetRepoPermissionForTeamModal(
setKebabOpen={setKebabOpen}
updateModifiedRepoPerms={updateModifiedRepoPerms}
>
<TableComposable aria-label="Selectable table">
<Table aria-label="Selectable table">
<Thead>
<Tr>
<Th />
@ -246,7 +239,7 @@ export default function SetRepoPermissionForTeamModal(
</Tr>
))}
</Tbody>
</TableComposable>
</Table>
</SetRepoPermissionsToolbar>
)}
</Modal>

View File

@ -1,5 +1,4 @@
import {
DropdownItem,
Flex,
FlexItem,
PanelFooter,
@ -7,6 +6,7 @@ import {
ToolbarContent,
ToolbarItem,
} from '@patternfly/react-core';
import {DropdownItem} from '@patternfly/react-core/deprecated';
import Conditional from 'src/components/empty/Conditional';
import {DropdownCheckbox} from 'src/components/toolbar/DropdownCheckbox';
import {Kebab} from 'src/components/toolbar/Kebab';
@ -43,7 +43,7 @@ export default function SetRepoPermissionsForTeamModalToolbar(
searchState={props.search}
setSearchState={props.setSearch}
/>
<Flex className="pf-u-mr-md">
<Flex className="pf-v5-u-mr-md">
<FlexItem>
<SearchInput
searchState={props.search}

View File

@ -3,7 +3,7 @@ import {
DropdownItem,
KebabToggle,
DropdownPosition,
} from '@patternfly/react-core';
} from '@patternfly/react-core/deprecated';
import {useState} from 'react';
import {Link, useSearchParams} from 'react-router-dom';
import {AlertVariant} from 'src/atoms/AlertState';

View File

@ -1,4 +1,8 @@
import {Dropdown, DropdownItem, DropdownToggle} from '@patternfly/react-core';
import {
Dropdown,
DropdownItem,
DropdownToggle,
} from '@patternfly/react-core/deprecated';
import {useEffect, useState} from 'react';
import {AlertVariant} from 'src/atoms/AlertState';
import {useAlerts} from 'src/hooks/UseAlerts';

View File

@ -1,22 +1,17 @@
import {
TableComposable,
Tbody,
Td,
Th,
Thead,
Tr,
} from '@patternfly/react-table';
import {Table, Tbody, Td, Th, Thead, Tr} from '@patternfly/react-table';
import TeamsViewToolbar from './TeamsViewToolbar';
import {Link, useSearchParams} from 'react-router-dom';
import {
Dropdown,
DropdownItem,
DropdownToggle,
PageSection,
PageSectionVariants,
PanelFooter,
Spinner,
} from '@patternfly/react-core';
import {
Dropdown,
DropdownItem,
DropdownToggle,
} from '@patternfly/react-core/deprecated';
import {useEffect, useState} from 'react';
import TeamViewKebab from './TeamViewKebab';
import {ITeams, useDeleteTeam, useFetchTeams} from 'src/hooks/UseTeams';
@ -221,7 +216,7 @@ export default function TeamsViewList(props: TeamsViewListProps) {
setRepoPermModal={setRepoPermModal}
/>
{props.children}
<TableComposable aria-label="Selectable table">
<Table aria-label="Selectable table">
<Thead>
<Tr>
<Th />
@ -286,7 +281,7 @@ export default function TeamsViewList(props: TeamsViewListProps) {
</Tr>
))}
</Tbody>
</TableComposable>
</Table>
<PanelFooter>
<ToolbarPagination
itemsList={filteredTeams}

View File

@ -30,7 +30,7 @@ export default function TeamsViewToolbar(props: TeamsViewToolbarProps) {
searchState={props.search}
setSearchState={props.setSearch}
/>
<Flex className="pf-u-mr-md">
<Flex className="pf-v5-u-mr-md">
<FlexItem>
<SearchInput
searchState={props.search}

View File

@ -1,18 +1,11 @@
import {
TableComposable,
Thead,
Tr,
Th,
Tbody,
Td,
} from '@patternfly/react-table';
import {Table, Thead, Tr, Th, Tbody, Td} from '@patternfly/react-table';
import {
PageSection,
PageSectionVariants,
Title,
DropdownItem,
PanelFooter,
} from '@patternfly/react-core';
import {DropdownItem} from '@patternfly/react-core/deprecated';
import './css/Organizations.scss';
import {CreateOrganizationModal} from './CreateOrganizationModal';
import {useRecoilState} from 'recoil';
@ -38,7 +31,6 @@ import ColumnNames from './ColumnNames';
import RepoCount from 'src/components/Table/RepoCount';
import {useOrganizations} from 'src/hooks/UseOrganizations';
import {useDeleteOrganizations} from 'src/hooks/UseDeleteOrganizations';
import {Router} from 'react-router-dom';
export interface OrganizationsTableItem {
name: string;
@ -307,7 +299,7 @@ export default function OrganizationsList() {
paginatedOrganizationsList={paginatedOrganizationsList}
onSelectOrganization={onSelectOrganization}
/>
<TableComposable aria-label="Selectable table">
<Table aria-label="Selectable table">
<Thead>
<Tr>
<Th />
@ -328,7 +320,7 @@ export default function OrganizationsList() {
onSelect: (_event, isSelecting) =>
onSelectOrganization(org, rowIndex, isSelecting),
isSelected: isOrganizationSelected(org),
disable: !isOrgSelectable(org),
isDisabled: !isOrgSelectable(org),
}}
/>
<OrgTableData
@ -338,7 +330,7 @@ export default function OrganizationsList() {
</Tr>
))}
</Tbody>
</TableComposable>
</Table>
<PanelFooter>
<ToolbarPagination
itemsList={filteredOrgs}

View File

@ -26,11 +26,11 @@
}
.fas.fa-trash {
font-size: var(--pf-global--icon--FontSize--lg);
font-size: var(--pf-v5-global--icon--FontSize--lg);
color: grey;
}
.pf-c-button.pf-m-plain {
--pf-c-button--disabled--BackgroundColor: transparent
.pf-v5-c-button.pf-m-plain {
--pf-v5-c-button--disabled--BackgroundColor: transparent
;
}

View File

@ -1,19 +1,14 @@
// .text-input-width {
// --pf-c-form-control--Width: 60%;
// }
$screen-sm: 768px;
$pf-global-gutter: 1rem;
$pf-global-gutter--md: 1.5rem;
$pf-v5-global-gutter: 1rem;
$pf-v5-global-gutter--md: 1.5rem;
// Page layout
.co-m-nav-title {
margin-top: $pf-global-gutter--md;
padding: 0 $pf-global-gutter 0;
margin-top: $pf-v5-global-gutter--md;
padding: 0 $pf-v5-global-gutter 0;
@media (min-width: 500px) {
padding-left: $pf-global-gutter--md;
padding-right: $pf-global-gutter--md;
padding-left: $pf-v5-global-gutter--md;
padding-right: $pf-v5-global-gutter--md;
}
&--row {
@media (min-width: $screen-sm) {
@ -26,19 +21,14 @@ $pf-global-gutter--md: 1.5rem;
// Trash icon
.fas.fa-trash {
font-size: var(--pf-global--icon--FontSize--lg);
font-size: var(--pf-v5-global--icon--FontSize--lg);
color: grey;
}
.pf-c-button.pf-m-plain {
--pf-c-button--disabled--BackgroundColor: transparent
.pf-v5-c-button.pf-m-plain {
--pf-v5-c-button--disabled--BackgroundColor: transparent
}
.create-org-modal-slider {
word-break: normal;
}
// search placeholder text color
// .pf-c-form-control {
// --pf-c-form-control--placeholder--Color: #989898
// }

View File

@ -95,7 +95,7 @@ function PluginMain() {
isModalOpen={isConfirmUserModalOpen}
setModalOpen={setConfirmUserModalOpen}
/>
<Banner variant="info">
<Banner variant="blue">
<Flex
spaceItems={{default: 'spaceItemsSm'}}
justifyContent={{default: 'justifyContentCenter'}}

View File

@ -1,19 +1,12 @@
import {
DropdownItem,
PageSection,
PageSectionVariants,
Spinner,
Title,
PanelFooter,
} from '@patternfly/react-core';
import {
TableComposable,
Thead,
Tr,
Th,
Tbody,
Td,
} from '@patternfly/react-table';
import {DropdownItem} from '@patternfly/react-core/deprecated';
import {Table, Thead, Tr, Th, Tbody, Td} from '@patternfly/react-table';
import {useRecoilState} from 'recoil';
import {IRepository} from 'src/resources/RepositoryResource';
import {ReactElement, useState} from 'react';
@ -328,7 +321,7 @@ export default function RepositoriesList(props: RepositoriesListProps) {
paginatedRepositoryList={paginatedRepositoryList}
onSelectRepo={onSelectRepo}
/>
<TableComposable aria-label="Selectable table">
<Table aria-label="Selectable table">
<Thead>
<Tr>
<Th />
@ -359,7 +352,7 @@ export default function RepositoriesList(props: RepositoriesListProps) {
onSelect: (_event, isSelecting) =>
onSelectRepo(repo, rowIndex, isSelecting),
isSelected: isRepoSelected(repo),
disable: !isRepoSelectable(repo),
isDisabled: !isRepoSelectable(repo),
}}
/>
<Td dataLabel={RepositoryListColumnNames.name}>
@ -403,7 +396,7 @@ export default function RepositoriesList(props: RepositoriesListProps) {
))
)}
</Tbody>
</TableComposable>
</Table>
<PanelFooter>
<ToolbarPagination
total={totalResults}

View File

@ -3,7 +3,7 @@ import {
DropdownItem,
KebabToggle,
DropdownPosition,
} from '@patternfly/react-core';
} from '@patternfly/react-core/deprecated';
import {IRobot} from 'src/resources/RobotsResource';
import {useState} from 'react';

View File

@ -1,6 +1,4 @@
import {
AlertGroup,
DropdownItem,
PageSection,
PageSectionVariants,
PanelFooter,
@ -9,8 +7,9 @@ import {
Text,
TextVariants,
} from '@patternfly/react-core';
import {DropdownItem} from '@patternfly/react-core/deprecated';
import {
TableComposable,
Table,
ExpandableRowContent,
Thead,
Tr,
@ -483,7 +482,7 @@ export default function RobotAccountsList(props: RobotAccountsListProps) {
if (loading && paginatedRobotAccountList?.length == 0) {
return (
<TableComposable aria-label="Empty state table" borders={false}>
<Table aria-label="Empty state table" borders={false}>
<Tbody>
<Tr>
<Td colSpan={8} textCenter={true}>
@ -498,7 +497,7 @@ export default function RobotAccountsList(props: RobotAccountsListProps) {
</Td>
</Tr>
</Tbody>
</TableComposable>
</Table>
);
}
return (
@ -586,7 +585,7 @@ export default function RobotAccountsList(props: RobotAccountsListProps) {
}
showFooter={true}
/>
<TableComposable aria-label="Expandable table" variant={undefined}>
<Table aria-label="Expandable table" variant={undefined}>
<Thead>
<Tr>
<Th />
@ -627,7 +626,7 @@ export default function RobotAccountsList(props: RobotAccountsListProps) {
onSelect: (_event, isSelecting) =>
onSelectRobot(robotAccount, rowIndex, isSelecting),
isSelected: isRobotAccountSelected(robotAccount),
disable: !isRobotAccountSelectable(robotAccount),
isDisabled: !isRobotAccountSelectable(robotAccount),
}}
/>
<Td dataLabel={RobotAccountColumnNames.robotAccountName}>
@ -679,7 +678,7 @@ export default function RobotAccountsList(props: RobotAccountsListProps) {
</Tbody>
);
})}
</TableComposable>
</Table>
<PanelFooter>
<ToolbarPagination
itemsList={filteredRobotAccounts}

View File

@ -1,8 +1,8 @@
.pf-c-alert {
--pf-c-alert--PaddingTop: 25rem;
.pf-v5-c-alert {
--pf-v5-c-alert--PaddingTop: 25rem;
}
.fas{
font-size: var(--pf-global--icon--FontSize--md);
}
font-size: var(--pf-v5-global--icon--FontSize--md);
}

View File

@ -75,7 +75,7 @@ export default function DeleteRepository({org, repo}: DeleteRepositoryProps) {
<TextInput
value={repoNameInput}
type="text"
onChange={(value) => setRepoNameInput(value.trim())}
onChange={(_event, value) => setRepoNameInput(value.trim())}
aria-label="repo-delete-name-input"
placeholder="Enter repository here"
/>

View File

@ -9,7 +9,7 @@ import {
import {BellIcon} from '@patternfly/react-icons';
import {
ExpandableRowContent,
TableComposable,
Table,
Tbody,
Td,
Th,
@ -130,7 +130,7 @@ export default function Notifications({
setFilter={setFilter}
resetFilter={resetFilter}
/>
<TableComposable aria-label="Repository notifications table">
<Table aria-label="Repository notifications table">
<Thead>
<Tr>
<Th />
@ -198,7 +198,7 @@ export default function Notifications({
</Tr>
</Tbody>
))}
</TableComposable>
</Table>
</>
);
}

View File

@ -2,10 +2,12 @@ import {
Alert,
AlertActionCloseButton,
AlertGroup,
} from '@patternfly/react-core';
import {
Dropdown,
DropdownItem,
DropdownToggle,
} from '@patternfly/react-core';
} from '@patternfly/react-core/deprecated';
import {useEffect, useState} from 'react';
import Conditional from 'src/components/empty/Conditional';
import {useUpdateNotifications} from 'src/hooks/UseUpdateNotifications';
@ -78,7 +80,7 @@ export default function Actions(props: ActionsProps) {
toggle={
<DropdownToggle
isDisabled={props.isDisabled}
onToggle={(isOpen) => setIsOpen(isOpen)}
onToggle={(_event, isOpen) => setIsOpen(isOpen)}
>
Actions
</DropdownToggle>

View File

@ -1,13 +1,15 @@
import {
Alert,
AlertActionCloseButton,
Dropdown,
DropdownItem,
DropdownToggle,
Form,
FormGroup,
Title,
} from '@patternfly/react-core';
import {
Dropdown,
DropdownItem,
DropdownToggle,
} from '@patternfly/react-core/deprecated';
import {useState} from 'react';
import './NotificationsCreateNotification.css';
import Conditional from 'src/components/empty/Conditional';
@ -53,7 +55,9 @@ export default function CreateNotification(props: CreateNotificationProps) {
required
onSelect={() => setIsEventOpen(false)}
toggle={
<DropdownToggle onToggle={(isOpen) => setIsEventOpen(isOpen)}>
<DropdownToggle
onToggle={(_event, isOpen) => setIsEventOpen(isOpen)}
>
{event?.title ? event?.title : 'Select event...'}
</DropdownToggle>
}
@ -76,7 +80,9 @@ export default function CreateNotification(props: CreateNotificationProps) {
className="create-notification-dropdown"
onSelect={() => setIsMethodOpen(false)}
toggle={
<DropdownToggle onToggle={(isOpen) => setIsMethodOpen(isOpen)}>
<DropdownToggle
onToggle={(_event, isOpen) => setIsMethodOpen(isOpen)}
>
{method?.title ? method?.title : 'Select method...'}
</DropdownToggle>
}

View File

@ -4,6 +4,9 @@ import {
AlertActionCloseButton,
Button,
FormGroup,
FormHelperText,
HelperText,
HelperTextItem,
Modal,
ModalVariant,
TextInput,
@ -177,26 +180,29 @@ export default function CreateEmailNotification(
>
Unable to verify email confirmation. Please wait a moment and retry.
</Modal>
<FormGroup
fieldId="email"
label="E-mail address"
isRequired
validated={email == '' || isValidEmail(email) ? 'default' : 'error'}
helperTextInvalid="Invalid email"
helperTextInvalidIcon={<ExclamationCircleIcon />}
>
<FormGroup fieldId="email" label="E-mail address" isRequired>
<TextInput
id="notification-email"
isRequired
value={email}
onChange={(value) => setEmail(value)}
onChange={(_event, value) => setEmail(value)}
/>
{!isValidEmail(email) && (
<FormHelperText>
<HelperText>
<HelperTextItem variant="error" icon={<ExclamationCircleIcon />}>
Invalid email
</HelperTextItem>
</HelperText>
</FormHelperText>
)}
</FormGroup>
<FormGroup fieldId="title" label="Title">
<TextInput
id="notification-title"
value={title}
onChange={(value) => setTitle(value)}
onChange={(_event, value) => setTitle(value)}
/>
</FormGroup>
<ActionGroup>

View File

@ -2,12 +2,8 @@ import {NotificationEvent} from 'src/hooks/UseEvents';
import {NotificationMethod} from 'src/hooks/UseNotificationMethods';
import {
ActionGroup,
Alert,
AlertActionCloseButton,
Button,
FormGroup,
Modal,
ModalVariant,
TextInput,
} from '@patternfly/react-core';
import {useEffect, useState} from 'react';
@ -65,14 +61,14 @@ export default function CreateFlowdockNotification(
required
id="flowdock-api-token-field"
value={apiTopken}
onChange={(value) => setAPIToken(value)}
onChange={(_event, value) => setAPIToken(value)}
/>
</FormGroup>
<FormGroup fieldId="title" label="Title">
<TextInput
id="notification-title"
value={title}
onChange={(value) => setTitle(value)}
onChange={(_event, value) => setTitle(value)}
/>
</FormGroup>
<ActionGroup>

View File

@ -4,6 +4,9 @@ import {
ActionGroup,
Button,
FormGroup,
FormHelperText,
HelperText,
HelperTextItem,
TextInput,
} from '@patternfly/react-core';
import {useEffect, useState} from 'react';
@ -64,20 +67,23 @@ export default function CreateHipchatNotification(
return (
<>
<FormGroup
fieldId="room-id-number"
label="Room ID #"
isRequired
helperTextInvalid="Must be a number"
helperTextInvalidIcon={<ExclamationCircleIcon />}
validated={roomId == '' || isValidRoomId(roomId) ? 'default' : 'error'}
>
<FormGroup fieldId="room-id-number" label="Room ID #" isRequired>
<TextInput
required
id="room-id-number-field"
value={roomId}
onChange={(value) => setRoomId(value)}
onChange={(_event, value) => setRoomId(value)}
/>
{!isValidRoomId(roomId) && (
<FormHelperText>
<HelperText>
<HelperTextItem variant="error" icon={<ExclamationCircleIcon />}>
Must be a number
</HelperTextItem>
</HelperText>
</FormHelperText>
)}
</FormGroup>
<FormGroup
fieldId="room-notification-token"
@ -88,14 +94,14 @@ export default function CreateHipchatNotification(
required
id="room-notification-token-field"
value={token}
onChange={(value) => setToken(value)}
onChange={(_event, value) => setToken(value)}
/>
</FormGroup>
<FormGroup fieldId="title" label="Title">
<TextInput
id="notification-title"
value={title}
onChange={(value) => setTitle(value)}
onChange={(_event, value) => setTitle(value)}
/>
</FormGroup>
<ActionGroup>

View File

@ -2,12 +2,8 @@ import {NotificationEvent} from 'src/hooks/UseEvents';
import {NotificationMethod} from 'src/hooks/UseNotificationMethods';
import {
ActionGroup,
Alert,
AlertActionCloseButton,
Button,
FormGroup,
Modal,
ModalVariant,
TextInput,
} from '@patternfly/react-core';
import {useEffect, useState} from 'react';
@ -73,7 +69,7 @@ export default function CreateQuayNotification(props: CreateQuayNotification) {
<TextInput
id="notification-title"
value={title}
onChange={(value) => setTitle(value)}
onChange={(_event, value) => setTitle(value)}
/>
</FormGroup>
<ActionGroup>

View File

@ -2,12 +2,11 @@ import {NotificationEvent} from 'src/hooks/UseEvents';
import {NotificationMethod} from 'src/hooks/UseNotificationMethods';
import {
ActionGroup,
Alert,
AlertActionCloseButton,
Button,
FormGroup,
Modal,
ModalVariant,
FormHelperText,
HelperText,
HelperTextItem,
TextInput,
} from '@patternfly/react-core';
import {useEffect, useState} from 'react';
@ -66,26 +65,30 @@ export default function CreateSlackNotification(
return (
<>
<FormGroup
fieldId="slack-webhook-url"
label="Webhook URL"
isRequired
helperTextInvalid="Must be a valid slack url in the form ^https://hooks.slack.com/services/[A-Z0-9]+/[A-Z0-9]+/[a-zA-Z0-9]+$/"
helperTextInvalidIcon={<ExclamationCircleIcon />}
validated={url == '' || isValidWebhookURL(url) ? 'default' : 'error'}
>
<FormGroup fieldId="slack-webhook-url" label="Webhook URL" isRequired>
<TextInput
required
id="slack-webhook-url-field"
value={url}
onChange={(value) => setUrl(value)}
onChange={(_event, value) => setUrl(value)}
/>
{!isValidWebhookURL(url) && (
<FormHelperText>
<HelperText>
<HelperTextItem variant="error" icon={<ExclamationCircleIcon />}>
Must be a valid slack url in the form
^https://hooks.slack.com/services/[A-Z0-9]+/[A-Z0-9]+/[a-zA-Z0-9]+$/
</HelperTextItem>
</HelperText>
</FormHelperText>
)}
</FormGroup>
<FormGroup fieldId="title" label="Title">
<TextInput
id="notification-title"
value={title}
onChange={(value) => setTitle(value)}
onChange={(_event, value) => setTitle(value)}
/>
</FormGroup>
<ActionGroup>

View File

@ -4,6 +4,9 @@ import {
ActionGroup,
Button,
FormGroup,
FormHelperText,
HelperText,
HelperTextItem,
TextArea,
TextInput,
} from '@patternfly/react-core';
@ -63,33 +66,36 @@ export default function CreateWebhookNotification(
return (
<>
<FormGroup
fieldId="webhook-url"
label="Webhook URL"
isRequired
helperTextInvalid="URL must begin with http(s)://"
helperTextInvalidIcon={<ExclamationCircleIcon />}
validated={url == '' || isValidURL(url) ? 'default' : 'error'}
>
<FormGroup fieldId="webhook-url" label="Webhook URL" isRequired>
<TextInput
required
id="webhook-url-field"
value={url}
onChange={(value) => setUrl(value)}
onChange={(_event, value) => setUrl(value)}
/>
{!isValidURL(url) && (
<FormHelperText>
<HelperText>
<HelperTextItem variant="error" icon={<ExclamationCircleIcon />}>
URL must begin with http(s)://
</HelperTextItem>
</HelperText>
</FormHelperText>
)}
</FormGroup>
<FormGroup fieldId="webhook-body" label="POST JSON body template">
<TextArea
id="json-body-field"
value={jsonBody}
onChange={(value) => setJsonBody(value)}
onChange={(_event, value) => setJsonBody(value)}
/>
</FormGroup>
<FormGroup fieldId="title" label="Title">
<TextInput
id="notification-title"
value={title}
onChange={(value) => setTitle(value)}
onChange={(_event, value) => setTitle(value)}
/>
</FormGroup>
<ActionGroup>

View File

@ -53,7 +53,7 @@ export default function NotificationsFilter(props: NotificationsFilterProps) {
id={`${e.title}-checkbox`}
label={e.title}
isChecked={props.filter.event.includes(e.type)}
onChange={(checked: boolean) => {
onChange={(_event, checked: boolean) => {
selectEvent(checked, e.type);
}}
name={`${e.title}-checkbox`}
@ -84,7 +84,7 @@ export default function NotificationsFilter(props: NotificationsFilterProps) {
isChecked={props.filter.status.includes(
NotifiationStatus.enabled,
)}
onChange={(checked: boolean) => {
onChange={(_event, checked: boolean) => {
selectStatus(checked, NotifiationStatus.enabled);
}}
name="enabled-checkbox"
@ -100,7 +100,7 @@ export default function NotificationsFilter(props: NotificationsFilterProps) {
isChecked={props.filter.status.includes(
NotifiationStatus.disabled,
)}
onChange={(checked: boolean) => {
onChange={(_event, checked: boolean) => {
selectStatus(checked, NotifiationStatus.disabled);
}}
name="disabled-checkbox"

View File

@ -1,4 +1,4 @@
import {Toolbar, ToolbarFilter} from '@patternfly/react-core';
import {ToolbarFilter} from '@patternfly/react-core';
import {NotificationFilter} from 'src/hooks/UseNotifications';
export default function NotificationsFilterChips(
@ -18,7 +18,7 @@ export default function NotificationsFilterChips(
<>
<ToolbarFilter
chips={props.filter.event}
deleteChip={(category, chip) => deleteFilter('event', chip as string)}
deleteChip={(_category, chip) => deleteFilter('event', chip as string)}
deleteChipGroup={() => props.resetFilter('event')}
categoryName="Event"
>
@ -26,7 +26,7 @@ export default function NotificationsFilterChips(
</ToolbarFilter>
<ToolbarFilter
chips={props.filter.status}
deleteChip={(category, chip) => deleteFilter('status', chip as string)}
deleteChip={(_category, chip) => deleteFilter('status', chip as string)}
deleteChipGroup={() => props.resetFilter('status')}
categoryName="Status"
>

View File

@ -3,12 +3,14 @@ import {
AlertActionCloseButton,
AlertGroup,
Button,
Dropdown,
DropdownItem,
KebabToggle,
Modal,
ModalVariant,
} from '@patternfly/react-core';
import {
Dropdown,
DropdownItem,
KebabToggle,
} from '@patternfly/react-core/deprecated';
import {useEffect, useState} from 'react';
import {useUpdateNotifications} from 'src/hooks/UseUpdateNotifications';
import Conditional from 'src/components/empty/Conditional';

View File

@ -1,12 +1,5 @@
import {Spinner} from '@patternfly/react-core';
import {
TableComposable,
Tbody,
Td,
Th,
Thead,
Tr,
} from '@patternfly/react-table';
import {Table, Tbody, Td, Th, Thead, Tr} from '@patternfly/react-table';
import {useEffect, useState} from 'react';
import {useRepositoryPermissions} from 'src/hooks/UseRepositoryPermissions';
import PermissionsToolbar from './PermissionsToolbar';
@ -77,7 +70,7 @@ export default function Permissions(props: PermissionsProps) {
deselectAll={() => setSelectedMembers([])}
setDrawerContent={props.setDrawerContent}
/>
<TableComposable aria-label="Repository permissions table">
<Table aria-label="Repository permissions table">
<Thead>
<Tr>
<Th />
@ -113,7 +106,7 @@ export default function Permissions(props: PermissionsProps) {
</Tr>
))}
</Tbody>
</TableComposable>
</Table>
</>
);
}

View File

@ -2,7 +2,6 @@ import {
Alert,
AlertActionCloseButton,
AlertGroup,
DropdownItem,
Menu,
MenuContent,
MenuItem,
@ -47,7 +46,7 @@ export default function ChangePermissions(props: ChangePermissionsProps) {
flyoutMenu={
<Menu key={1}>
<MenuContent>
<MenuList>
<MenuList data-testid="change-permissions-menu-list">
{roles.map((role) => (
<MenuItem
key={role.name}

View File

@ -1,20 +1,22 @@
import {SetStateAction, useEffect, useState} from 'react';
import {
ActionGroup,
Alert,
AlertActionCloseButton,
Button,
Divider,
Dropdown,
DropdownItem,
DropdownToggle,
Form,
FormGroup,
Title,
} from '@patternfly/react-core';
import {
Dropdown,
DropdownItem,
DropdownToggle,
SelectGroup,
SelectOption,
} from '@patternfly/react-core';
} from '@patternfly/react-core/deprecated';
import {DesktopIcon, UsersIcon} from '@patternfly/react-icons';
import {SetStateAction, useEffect, useState} from 'react';
import Conditional from 'src/components/empty/Conditional';
import EntitySearch from 'src/components/EntitySearch';
import {useUpdateRepositoryPermissions} from 'src/hooks/UseUpdateRepositoryPermissions';
@ -162,7 +164,7 @@ export default function AddPermissions(props: AddPermissionsProps) {
onSelect={() => setIsPermissionOpen(false)}
toggle={
<DropdownToggle
onToggle={(isOpen) => setIsPermissionOpen(isOpen)}
onToggle={(_event, isOpen) => setIsPermissionOpen(isOpen)}
>
{role}
</DropdownToggle>

View File

@ -2,10 +2,12 @@ import {
Alert,
AlertActionCloseButton,
AlertGroup,
} from '@patternfly/react-core';
import {
Dropdown,
DropdownItem,
DropdownToggle,
} from '@patternfly/react-core';
} from '@patternfly/react-core/deprecated';
import {useState} from 'react';
import Conditional from 'src/components/empty/Conditional';
import {useUpdateRepositoryPermissions} from 'src/hooks/UseUpdateRepositoryPermissions';
@ -38,7 +40,7 @@ export default function PermissionsDropdown({
<Dropdown
onSelect={() => setIsOpen(false)}
toggle={
<DropdownToggle onToggle={(isOpen) => setIsOpen(isOpen)}>
<DropdownToggle onToggle={(_event, isOpen) => setIsOpen(isOpen)}>
{member.role}
</DropdownToggle>
}

View File

@ -2,10 +2,12 @@ import {
Alert,
AlertActionCloseButton,
AlertGroup,
} from '@patternfly/react-core';
import {
Dropdown,
DropdownItem,
KebabToggle,
} from '@patternfly/react-core';
} from '@patternfly/react-core/deprecated';
import {useState} from 'react';
import Conditional from 'src/components/empty/Conditional';
import {useUpdateRepositoryPermissions} from 'src/hooks/UseUpdateRepositoryPermissions';

Some files were not shown because too many files have changed in this diff Show More