diff --git a/docs/PULL_REQUEST_TEMPLATE.md b/docs/PULL_REQUEST_TEMPLATE.md index 01333bdab73..e6603ee17fb 100644 --- a/docs/PULL_REQUEST_TEMPLATE.md +++ b/docs/PULL_REQUEST_TEMPLATE.md @@ -1,15 +1,20 @@ ## Description πŸ“ + Highlight the Pull Request's context and intentions. ## Changes πŸ”„ -List any change relevant to the reviewer. + +List any change(s) relevant to the reviewer. + - ... - ... ## Target release date πŸ—“οΈ -Please specify a release date to guarantee timely review of this PR. If exact date is not known, please approximate and update it as needed. + +Please specify a release date (and environment, if applicable) to guarantee timely review of this PR. If exact date is not known, please approximate and update it as needed. ## Preview πŸ“· + **Include a screenshot or screen recording of the change.** :lock: Use the [Mask Sensitive Data](https://cloud.linode.com/profile/settings) setting for security. @@ -23,38 +28,53 @@ Please specify a release date to guarantee timely review of this PR. If exact da ## How to test πŸ§ͺ ### Prerequisites + (How to setup test environment) + - ... - ... ### Reproduction steps + (How to reproduce the issue, if applicable) -- ... -- ... + +- [ ] ... +- [ ] ... ### Verification steps + (How to verify changes) -- ... -- ... -## As an Author I have considered πŸ€” +- [ ] ... +- [ ] ... + +## As an Author, I have considered πŸ€” -*Check all that apply* +- πŸ‘€ Doing a self review +- ❔ Our [contribution guidelines](https://github.com/linode/manager/blob/develop/docs/CONTRIBUTING.md) +- 🀏 Splitting feature into small PRs +- βž• Adding a [changeset](https://github.com/linode/manager/blob/develop/docs/CONTRIBUTING.md#writing-a-changeset) +- πŸ§ͺ Providing/improving test coverage +- πŸ” Removing all sensitive information from the code and PR description +- 🚩 Using a feature flag to protect the release +- πŸ‘£ Providing comprehensive reproduction steps +- πŸ“‘ Providing or updating our documentation +- πŸ•› Scheduling a pair reviewing session +- πŸ“± Providing mobile support +- β™Ώ Providing accessibility support -- [ ] πŸ‘€ Doing a self review -- [ ] ❔ Our [contribution guidelines](https://github.com/linode/manager/blob/develop/docs/CONTRIBUTING.md) -- [ ] 🀏 Splitting feature into small PRs -- [ ] βž• Adding a [changeset](https://github.com/linode/manager/blob/develop/docs/CONTRIBUTING.md#writing-a-changeset) -- [ ] πŸ§ͺ Providing/Improving test coverage -- [ ] πŸ” Removing all sensitive information from the code and PR description -- [ ] 🚩 Using a feature flag to protect the release -- [ ] πŸ‘£ Providing comprehensive reproduction steps -- [ ] πŸ“‘ Providing or updating our documentation -- [ ] πŸ•› Scheduling a pair reviewing session -- [ ] πŸ“± Providing mobile support -- [ ] β™Ώ Providing accessibility support +
+ +- [ ] I have read and considered all applicable items listed above. + +## As an Author, before moving this PR from Draft to Open, I confirmed βœ… + +- [ ] All unit tests are passing +- [ ] TypeScript compilation succeeded without errors +- [ ] Code passes all linting rules --- + ## Commit message and pull request title format standards > **Note**: Remove this section before opening the pull request @@ -63,6 +83,7 @@ Please specify a release date to guarantee timely review of this PR. If exact da `: [JIRA-ticket-number] - ` **Commit Types:** + - `feat`: New feature for the user (not a part of the code, or ci, ...). - `fix`: Bugfix for the user (not a fix to build something, ...). - `change`: Modifying an existing visual UI instance. Such as a component or a feature. diff --git a/docs/development-guide/08-testing.md b/docs/development-guide/08-testing.md index 4a025ce90f4..a97bf29a06c 100644 --- a/docs/development-guide/08-testing.md +++ b/docs/development-guide/08-testing.md @@ -6,38 +6,38 @@ The unit tests for Cloud Manager are written in Typescript using the [Vitest](ht To run tests, first build the **api-v4** package: -``` +```shell yarn install:all && yarn workspace @linode/api-v4 build ``` Then you can start the tests: -``` +```shell yarn test ``` Or you can run the tests in watch mode with: -``` +```shell yarn test:watch ``` To run a specific file or files in a directory: -``` +```shell yarn test myFile.test.tsx yarn test src/some-folder ``` Vitest has built-in pattern matching, so you can also do things like run all tests whose filename contains "Linode" with: -``` +```shell yarn test linode ``` To run a test in debug mode, add a `debugger` breakpoint inside one of the test cases, then run: -``` +```shell yarn workspace linode-manager run test:debug ``` @@ -64,31 +64,25 @@ describe("My component", () => { Handling events such as clicks is a little more involved: ```js -import { fireEvent } from "@testing-library/react"; +import { userEvent } from '@testing-library/user-event'; import { renderWithTheme } from "src/utilities/testHelpers"; import Component from "./wherever"; const props = { onClick: vi.fn() }; describe("My component", () => { - it("should have some text", () => { + it("should have some text", async () => { const { getByText } = renderWithTheme(); const button = getByText("Submit"); - fireEvent.click(button); + await userEvent.click(button); expect(props.onClick).toHaveBeenCalled(); }); }); ``` -If, while using the Testing Library, your tests trigger a warning in the console from React ("Warning: An update to Component inside a test was not wrapped in act(...)"), first check out the library author's [blog post](https://kentcdodds.com/blog/fix-the-not-wrapped-in-act-warning) about this. Depending on your situation, you probably will have to `wait` for something in your test: - -```js -import { fireEvent, wait } from '@testing-library/react'; +We recommend using `userEvent` rather than `fireEvent` where possible. This is a [React Testing Library best practice](https://testing-library.com/docs/user-event/intro#differences-from-fireevent), because `userEvent` more accurately simulates user interactions in a browser and makes the test more reliable in catching unintended event handler behavior. -... -await wait(() => fireEvent.click(getByText('Delete'))); -... -``` +If, while using the Testing Library, your tests trigger a warning in the console from React ("Warning: An update to Component inside a test was not wrapped in act(...)"), first check out the library author's [blog post](https://kentcdodds.com/blog/fix-the-not-wrapped-in-act-warning) about this. Depending on your situation, you probably will have to use [`findBy`](https://testing-library.com/docs/dom-testing-library/api-async/#findby-queries) or [`waitFor`](https://testing-library.com/docs/dom-testing-library/api-async/) for something in your test to ensure asynchronous side-effects have completed. ### Mocking @@ -108,7 +102,9 @@ vi.mock('@linode/api-v4/lib/kubernetes', async () => { Some components, such as our ActionMenu, don't lend themselves well to unit testing (they often have complex DOM structures from MUI and it's hard to target). We have mocks for most of these components in a `__mocks__` directory adjacent to their respective components. To make use of these, just tell Vitest to use the mock: +```js vi.mock('src/components/ActionMenu/ActionMenu'); +``` Any ``s rendered by the test will be simplified versions that are easier to work with. @@ -157,6 +153,7 @@ We use [Cypress](https://cypress.io) for end-to-end testing. Test files are foun * Select a reasonable expiry time (avoid "Never") and make sure that every permission is set to "Read/Write". 3. Set the `MANAGER_OAUTH` environment variable in your `.env` file using your new personal access token. * Example of `.env` addition: + ```shell # Manager OAuth token for Cypress tests: # (The real token will be a 64-digit string of hexadecimals). @@ -174,6 +171,7 @@ We use [Cypress](https://cypress.io) for end-to-end testing. Test files are foun Cloud Manager UI tests can be configured using environment variables, which can be defined in `packages/manager/.env` or specified when running Cypress. ##### Cypress Environment Variables + These environment variables are used by Cypress out-of-the-box to override the default configuration. Cypress exposes many other options that can be configured with environment variables, but the items listed below are particularly relevant for Cloud Manager testing. More information can be found at [docs.cypress.io](https://docs.cypress.io/guides/guides/environment-variables). | Environment Variable | Description | Example | Default | @@ -181,9 +179,11 @@ These environment variables are used by Cypress out-of-the-box to override the d | `CYPRESS_BASE_URL` | URL to Cloud Manager environment for tests | `https://cloud.linode.com` | `http://localhost:3000` | ##### Cloud Manager-specific Environment Variables + These environment variables are specific to Cloud Manager UI tests. They can be distinguished from out-of-the-box Cypress environment variables by their `CY_TEST_` prefix. ###### General + Environment variables related to the general operation of the Cloud Manager Cypress tests. | Environment Variable | Description | Example | Default | @@ -192,6 +192,7 @@ Environment variables related to the general operation of the Cloud Manager Cypr | `CY_TEST_TAGS` | Query identifying tests that should run by specifying allowed and disallowed tags. | `method:e2e` | Unset; all tests run by default | ###### Overriding Behavior + These environment variables can be used to override some behaviors of Cloud Manager's UI tests. This can be useful when testing Cloud Manager for nonstandard or work-in-progress functionality. | Environment Variable | Description | Example | Default | @@ -200,6 +201,7 @@ These environment variables can be used to override some behaviors of Cloud Mana | `CY_TEST_FEATURE_FLAGS` | JSON string containing feature flag data | `{}` | Unset; feature flag data is not overridden | ###### Run Splitting + These environment variables facilitate splitting the Cypress run between multiple runners without the use of any third party services. This can be useful for improving Cypress test performance in some circumstances. For additional performance gains, an optional test weights file can be specified using `CY_TEST_SPLIT_RUN_WEIGHTS` (see `CY_TEST_GENWEIGHTS` to generate test weights). | Environment Variable | Description | Example | Default | @@ -210,6 +212,7 @@ These environment variables facilitate splitting the Cypress run between multipl | `CY_TEST_SPLIT_RUN_WEIGHTS` | Path to test weights file | `./weights.json` | Unset; disabled by default | ###### Development, Logging, and Reporting + Environment variables related to Cypress logging and reporting, as well as report generation. | Environment Variable | Description | Example | Default | @@ -222,6 +225,7 @@ Environment variables related to Cypress logging and reporting, as well as repor | `CY_TEST_GENWEIGHTS` | Generate and output test weights to the given path | `./weights.json` | Unset; disabled by default | ###### Performance + Environment variables that can be used to improve test performance in some scenarios. | Environment Variable | Description | Example | Default | @@ -233,6 +237,7 @@ Environment variables that can be used to improve test performance in some scena 1. Look here for [Cypress Best Practices](https://docs.cypress.io/guides/references/best-practices) 2. Test Example: + ```tsx /* this test will not pass on cloud manager. it is only intended to show correct test structure, syntax, @@ -293,13 +298,15 @@ Environment variables that can be used to improve test performance in some scena }); }); ``` + 3. How to use intercepts: + ```tsx // stub response syntax: cy.intercept('POST', β€˜/path’, {response}) or cy.intercept(β€˜/path’, (req) => { req.reply({response})}).as('something'); - // edit and end response syntax: + // edit and end response syntax: cy.intercept('GET', β€˜/path’, (req) => { req.send({edit: something})}).as('something'); - // edit request syntax: + // edit request syntax: cy.intercept('POST', β€˜/path’, (req) => { req.body.storyName = 'some name'; req.continue().as('something'); // use alias syntax: diff --git a/packages/api-v4/.changeset/pr-11152-added-1729713487291.md b/packages/api-v4/.changeset/pr-11152-added-1729713487291.md deleted file mode 100644 index 2a2770ce30c..00000000000 --- a/packages/api-v4/.changeset/pr-11152-added-1729713487291.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/api-v4": Added ---- - -DBaaS Suspend and Resume backend calls ([#11152](https://github.com/linode/manager/pull/11152)) diff --git a/packages/api-v4/.changeset/pr-11157-tech-stories-1729787265807.md b/packages/api-v4/.changeset/pr-11157-tech-stories-1729787265807.md deleted file mode 100644 index ecac9463430..00000000000 --- a/packages/api-v4/.changeset/pr-11157-tech-stories-1729787265807.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/api-v4": Tech Stories ---- - -Remove `@types/node` dependency ([#11157](https://github.com/linode/manager/pull/11157)) diff --git a/packages/api-v4/.changeset/pr-11178-added-1730961405650.md b/packages/api-v4/.changeset/pr-11178-added-1730961405650.md new file mode 100644 index 00000000000..00ede31e247 --- /dev/null +++ b/packages/api-v4/.changeset/pr-11178-added-1730961405650.md @@ -0,0 +1,5 @@ +--- +"@linode/api-v4": Added +--- + +Extend support for Object Storage in Support tickets ([#11178](https://github.com/linode/manager/pull/11178)) diff --git a/packages/api-v4/.changeset/pr-11196-upcoming-features-1730465602676.md b/packages/api-v4/.changeset/pr-11196-upcoming-features-1730465602676.md deleted file mode 100644 index aef96620c9a..00000000000 --- a/packages/api-v4/.changeset/pr-11196-upcoming-features-1730465602676.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/api-v4": Upcoming Features ---- - -DBaaS modify update payload to include version, add patch API ([#11196](https://github.com/linode/manager/pull/11196)) diff --git a/packages/api-v4/CHANGELOG.md b/packages/api-v4/CHANGELOG.md index 6f2f8dc95bf..06268e31c8f 100644 --- a/packages/api-v4/CHANGELOG.md +++ b/packages/api-v4/CHANGELOG.md @@ -1,3 +1,22 @@ +## [2024-11-12] - v0.130.0 + + +### Added: + +- DBaaS: Suspend and Resume backend calls ([#11152](https://github.com/linode/manager/pull/11152)) + +### Removed: + +- DBaaS: Deprecated types including MongoDB and Redis ([#11218](https://github.com/linode/manager/pull/11218)) + +### Tech Stories: + +- Remove `@types/node` dependency ([#11157](https://github.com/linode/manager/pull/11157)) + +### Upcoming Features: + +- DBaaS: Modify update payload to include version, add patch API ([#11196](https://github.com/linode/manager/pull/11196)) + ## [2024-10-28] - v0.129.0 diff --git a/packages/api-v4/package.json b/packages/api-v4/package.json index aab5a0bbb41..2c151782dbc 100644 --- a/packages/api-v4/package.json +++ b/packages/api-v4/package.json @@ -1,6 +1,6 @@ { "name": "@linode/api-v4", - "version": "0.129.0", + "version": "0.130.0", "homepage": "https://github.com/linode/manager/tree/develop/packages/api-v4", "bugs": { "url": "https://github.com/linode/manager/issues" diff --git a/packages/api-v4/src/databases/types.ts b/packages/api-v4/src/databases/types.ts index a499032962a..87b4458308a 100644 --- a/packages/api-v4/src/databases/types.ts +++ b/packages/api-v4/src/databases/types.ts @@ -20,7 +20,7 @@ export interface DatabaseType extends BaseType { engines: Engines; } -export type Engine = 'mysql' | 'postgresql' | 'mongodb' | 'redis'; +export type Engine = 'mysql' | 'postgresql'; export interface DatabaseEngine { id: string; @@ -103,6 +103,7 @@ export type ClusterSize = 1 | 2 | 3; type ReadonlyCount = 0 | 2; +/** @deprecated TODO (UIE-8214) remove POST GA */ export type MySQLReplicationType = 'none' | 'semi_synch' | 'asynch'; export interface CreateDatabasePayload { @@ -120,7 +121,10 @@ export interface CreateDatabasePayload { type: string; } +/** @deprecated TODO (UIE-8214) remove POST GA */ type DriverTypes = 'jdbc' | 'odbc' | 'php' | 'python' | 'ruby' | 'node.js'; + +/** @deprecated TODO (UIE-8214) remove POST GA */ interface ConnectionStrings { driver: DriverTypes; value: string; @@ -173,20 +177,24 @@ interface BaseDatabase extends DatabaseInstance { used_disk_size_gb?: number; } +/** @deprecated TODO (UIE-8214) remove POST GA */ export interface MySQLDatabase extends BaseDatabase { /** @Deprecated used by rdbms-legacy only */ replication_type?: MySQLReplicationType; } +/** @deprecated TODO (UIE-8214) remove POST GA */ export type PostgresReplicationType = 'none' | 'synch' | 'asynch'; -type ReplicationCommitTypes = +/** @deprecated TODO (UIE-8214) remove POST GA */ +export type ReplicationCommitTypes = | 'on' | 'local' | 'remote_write' | 'remote_apply' | 'off'; +/** @deprecated TODO (UIE-8214) remove POST GA */ export interface PostgresDatabase extends BaseDatabase { /** @Deprecated used by rdbms-legacy only */ replication_type?: PostgresReplicationType; @@ -194,22 +202,13 @@ export interface PostgresDatabase extends BaseDatabase { replication_commit_type?: ReplicationCommitTypes; } -type MongoStorageEngine = 'wiredtiger' | 'mmapv1'; -type MongoCompressionType = 'none' | 'snappy' | 'zlib'; -export interface MongoDatabase extends BaseDatabase { - storage_engine: MongoStorageEngine; - compression_type: MongoCompressionType; - replica_set: string | null; - peers: string[]; -} - +/** @deprecated TODO (UIE-8214) remove POST GA */ export type ComprehensiveReplicationType = MySQLReplicationType & PostgresReplicationType; export type Database = BaseDatabase & Partial & - Partial & - Partial; + Partial; export interface UpdateDatabasePayload { cluster_size?: number; diff --git a/packages/api-v4/src/support/types.ts b/packages/api-v4/src/support/types.ts index f2ab261a93e..a62c1d96040 100644 --- a/packages/api-v4/src/support/types.ts +++ b/packages/api-v4/src/support/types.ts @@ -35,10 +35,12 @@ export interface ReplyRequest { export interface TicketRequest { summary: string; description: string; + bucket?: string; domain_id?: number; linode_id?: number; longviewclient_id?: number; nodebalancer_id?: number; + region?: string; volume_id?: number; severity?: TicketSeverity; } diff --git a/packages/manager/.changeset/pr-11058-tech-stories-1729621320539.md b/packages/manager/.changeset/pr-11058-tech-stories-1729621320539.md deleted file mode 100644 index de8b6082d8f..00000000000 --- a/packages/manager/.changeset/pr-11058-tech-stories-1729621320539.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Tech Stories ---- - -Consolidate ImageSelect components ([#11058](https://github.com/linode/manager/pull/11058)) diff --git a/packages/manager/.changeset/pr-11080-changed-1730138781683.md b/packages/manager/.changeset/pr-11080-changed-1730138781683.md deleted file mode 100644 index b33939a9c8e..00000000000 --- a/packages/manager/.changeset/pr-11080-changed-1730138781683.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Changed ---- - -Incorporate Product Family Groups in Side Nav ([#11080](https://github.com/linode/manager/pull/11080)) diff --git a/packages/manager/.changeset/pr-11099-fixed-1728996803052.md b/packages/manager/.changeset/pr-11099-fixed-1728996803052.md deleted file mode 100644 index d5c87f66fb2..00000000000 --- a/packages/manager/.changeset/pr-11099-fixed-1728996803052.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Fixed ---- - -Align table headers in Account Maintenance page ([#11099](https://github.com/linode/manager/pull/11099)) diff --git a/packages/manager/.changeset/pr-11111-changed-1729082750525.md b/packages/manager/.changeset/pr-11111-changed-1729082750525.md deleted file mode 100644 index 2b0ecbe6829..00000000000 --- a/packages/manager/.changeset/pr-11111-changed-1729082750525.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Changed ---- - -Remove Double border on "Billing & Payment History" table with dark theme. ([#11111](https://github.com/linode/manager/pull/11111)) diff --git a/packages/manager/.changeset/pr-11132-tests-1729628045654.md b/packages/manager/.changeset/pr-11132-tests-1729628045654.md deleted file mode 100644 index 2005408f5ff..00000000000 --- a/packages/manager/.changeset/pr-11132-tests-1729628045654.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Tests ---- - -Added cypress tests for creating LKE clusters with ACL ([#11132](https://github.com/linode/manager/pull/11132)) diff --git a/packages/manager/.changeset/pr-11134-tech-stories-1729561221251.md b/packages/manager/.changeset/pr-11134-tech-stories-1729561221251.md deleted file mode 100644 index 38ed1150fe9..00000000000 --- a/packages/manager/.changeset/pr-11134-tech-stories-1729561221251.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Tech Stories ---- - -Refactor TextField component ([#11134](https://github.com/linode/manager/pull/11134)) diff --git a/packages/manager/.changeset/pr-11137-fixed-1729745562099.md b/packages/manager/.changeset/pr-11137-fixed-1729745562099.md deleted file mode 100644 index a502521a780..00000000000 --- a/packages/manager/.changeset/pr-11137-fixed-1729745562099.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Fixed ---- - -Database create page form being enabled for restricted users ([#11137](https://github.com/linode/manager/pull/11137)) diff --git a/packages/manager/.changeset/pr-11141-added-1730133012318.md b/packages/manager/.changeset/pr-11141-added-1730133012318.md deleted file mode 100644 index 9bb2a5137ae..00000000000 --- a/packages/manager/.changeset/pr-11141-added-1730133012318.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Added ---- - -Success toasts to profile display settings page (with other minor improvements) ([#11141](https://github.com/linode/manager/pull/11141)) diff --git a/packages/manager/.changeset/pr-11141-tech-stories-1729629238072.md b/packages/manager/.changeset/pr-11141-tech-stories-1729629238072.md deleted file mode 100644 index 28376d598a9..00000000000 --- a/packages/manager/.changeset/pr-11141-tech-stories-1729629238072.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Tech Stories ---- - -Clean up Profile Display Settings page ([#11141](https://github.com/linode/manager/pull/11141)) diff --git a/packages/manager/.changeset/pr-11142-tech-stories-1729715589096.md b/packages/manager/.changeset/pr-11142-tech-stories-1729715589096.md deleted file mode 100644 index c0517590945..00000000000 --- a/packages/manager/.changeset/pr-11142-tech-stories-1729715589096.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Tech Stories ---- - -`only-export-components` for Tanstack routes ([#11142](https://github.com/linode/manager/pull/11142)) diff --git a/packages/manager/.changeset/pr-11143-added-1729792743385.md b/packages/manager/.changeset/pr-11143-added-1729792743385.md deleted file mode 100644 index 1732ea131b2..00000000000 --- a/packages/manager/.changeset/pr-11143-added-1729792743385.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Added ---- - -Mask Sensitive Data preference to Profile Settings ([#11143](https://github.com/linode/manager/pull/11143)) diff --git a/packages/manager/.changeset/pr-11144-changed-1729684811107.md b/packages/manager/.changeset/pr-11144-changed-1729684811107.md deleted file mode 100644 index 2b69521036d..00000000000 --- a/packages/manager/.changeset/pr-11144-changed-1729684811107.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Changed ---- - -Slightly improve styles on support ticket flows ([#11144](https://github.com/linode/manager/pull/11144)) diff --git a/packages/manager/.changeset/pr-11145-tech-stories-1729655521664.md b/packages/manager/.changeset/pr-11145-tech-stories-1729655521664.md deleted file mode 100644 index 62836d869a4..00000000000 --- a/packages/manager/.changeset/pr-11145-tech-stories-1729655521664.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Tech Stories ---- - -Add more customization to legends and charts ([#11145](https://github.com/linode/manager/pull/11145)) diff --git a/packages/manager/.changeset/pr-11147-changed-1729684531663.md b/packages/manager/.changeset/pr-11147-changed-1729684531663.md deleted file mode 100644 index cf506d52a3b..00000000000 --- a/packages/manager/.changeset/pr-11147-changed-1729684531663.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Changed ---- - -Improve validation error when a backup is not selected ([#11147](https://github.com/linode/manager/pull/11147)) diff --git a/packages/manager/.changeset/pr-11149-fixed-1729690586892.md b/packages/manager/.changeset/pr-11149-fixed-1729690586892.md deleted file mode 100644 index fd597d442cd..00000000000 --- a/packages/manager/.changeset/pr-11149-fixed-1729690586892.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Fixed ---- - -Faux bold in Safari with & tags ([#11149](https://github.com/linode/manager/pull/11149)) diff --git a/packages/manager/.changeset/pr-11150-upcoming-features-1729746495913.md b/packages/manager/.changeset/pr-11150-upcoming-features-1729746495913.md deleted file mode 100644 index bbe5b071ce9..00000000000 --- a/packages/manager/.changeset/pr-11150-upcoming-features-1729746495913.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Upcoming Features ---- - -Add default xfilter for DBasS aiven clusters fetch in resource selection component ([#11150](https://github.com/linode/manager/pull/11150)) diff --git a/packages/manager/.changeset/pr-11152-added-1729713452489.md b/packages/manager/.changeset/pr-11152-added-1729713452489.md deleted file mode 100644 index b16be182d16..00000000000 --- a/packages/manager/.changeset/pr-11152-added-1729713452489.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Added ---- - -DBaaS Suspend and Resume for Database Landing and Details ([#11152](https://github.com/linode/manager/pull/11152)) diff --git a/packages/manager/.changeset/pr-11156-tech-stories-1729784052355.md b/packages/manager/.changeset/pr-11156-tech-stories-1729784052355.md deleted file mode 100644 index 63b427c420e..00000000000 --- a/packages/manager/.changeset/pr-11156-tech-stories-1729784052355.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@linode/manager': Tech Stories ---- - -Remove the feature flag and tracking events used for A/B testing in the API CLI Tools modal, and update the DX Tools modal button copy to 'View Code Snippets ([#11156](https://github.com/linode/manager/pull/11156)) diff --git a/packages/manager/.changeset/pr-11157-tech-stories-1729787405590.md b/packages/manager/.changeset/pr-11157-tech-stories-1729787405590.md deleted file mode 100644 index 04db0ba79dd..00000000000 --- a/packages/manager/.changeset/pr-11157-tech-stories-1729787405590.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Tech Stories ---- - -Update `@types/node` to `20.17.0` ([#11157](https://github.com/linode/manager/pull/11157)) diff --git a/packages/manager/.changeset/pr-11161-fixed-1729827835443.md b/packages/manager/.changeset/pr-11161-fixed-1729827835443.md deleted file mode 100644 index f3b0eacd8aa..00000000000 --- a/packages/manager/.changeset/pr-11161-fixed-1729827835443.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Fixed ---- - -Only run 'Coverage Comment' GHA on non-drafts ([#11161](https://github.com/linode/manager/pull/11161)) diff --git a/packages/manager/.changeset/pr-11165-upcoming-features-1729872623442.md b/packages/manager/.changeset/pr-11165-upcoming-features-1729872623442.md deleted file mode 100644 index 5732391876a..00000000000 --- a/packages/manager/.changeset/pr-11165-upcoming-features-1729872623442.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Upcoming Features ---- - -Replace one-off hardcoded black and white color values with colorTokens ([#11165](https://github.com/linode/manager/pull/11165)) diff --git a/packages/manager/.changeset/pr-11166-changed-1729892043474.md b/packages/manager/.changeset/pr-11166-changed-1729892043474.md deleted file mode 100644 index e177811b75a..00000000000 --- a/packages/manager/.changeset/pr-11166-changed-1729892043474.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Changed ---- - -Database settings text and labels ([#11166](https://github.com/linode/manager/pull/11166)) diff --git a/packages/manager/.changeset/pr-11167-fixed-1730095848948.md b/packages/manager/.changeset/pr-11167-fixed-1730095848948.md deleted file mode 100644 index 1aeb90eeca0..00000000000 --- a/packages/manager/.changeset/pr-11167-fixed-1730095848948.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Fixed ---- - -aria label of action menu button in IP address table row ([#11167](https://github.com/linode/manager/pull/11167)) diff --git a/packages/manager/.changeset/pr-11169-upcoming-features-1730713096724.md b/packages/manager/.changeset/pr-11169-upcoming-features-1730713096724.md deleted file mode 100644 index e35ed345e8f..00000000000 --- a/packages/manager/.changeset/pr-11169-upcoming-features-1730713096724.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Upcoming Features ---- - -Add global border radius token to theme and replace harcoded values where borderRadius = 0 ([#11169](https://github.com/linode/manager/pull/11169)) diff --git a/packages/manager/.changeset/pr-11170-upcoming-features-1730113218650.md b/packages/manager/.changeset/pr-11170-upcoming-features-1730113218650.md deleted file mode 100644 index 7dd7c9e1330..00000000000 --- a/packages/manager/.changeset/pr-11170-upcoming-features-1730113218650.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Upcoming Features ---- - -Handle API errors for global filters and dashboard components ([#11170](https://github.com/linode/manager/pull/11170)) diff --git a/packages/manager/.changeset/pr-11171-upcoming-features-1730182630692.md b/packages/manager/.changeset/pr-11171-upcoming-features-1730182630692.md deleted file mode 100644 index 69f6fb0cfd5..00000000000 --- a/packages/manager/.changeset/pr-11171-upcoming-features-1730182630692.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Upcoming Features ---- - -Add global `font` and `spacing` tokens to theme and refactor design tokens ([#11171](https://github.com/linode/manager/pull/11171)) diff --git a/packages/manager/.changeset/pr-11172-changed-1730121782530.md b/packages/manager/.changeset/pr-11172-changed-1730121782530.md new file mode 100644 index 00000000000..6993a57ddf2 --- /dev/null +++ b/packages/manager/.changeset/pr-11172-changed-1730121782530.md @@ -0,0 +1,5 @@ +--- +"@linode/manager": Changed +--- + +Linode details summary VPC IPv4 text to copy object ([#11172](https://github.com/linode/manager/pull/11172)) diff --git a/packages/manager/.changeset/pr-11176-tests-1730144406169.md b/packages/manager/.changeset/pr-11176-tests-1730144406169.md deleted file mode 100644 index 0a1b937db45..00000000000 --- a/packages/manager/.changeset/pr-11176-tests-1730144406169.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Tests ---- - -Add unit tests to declutter LKE ACL cypress tests, fix lke-create.spec.ts failures ([#11176](https://github.com/linode/manager/pull/11176)) diff --git a/packages/manager/.changeset/pr-11177-tech-stories-1730214757061.md b/packages/manager/.changeset/pr-11177-tech-stories-1730214757061.md deleted file mode 100644 index 1987e5ba9b7..00000000000 --- a/packages/manager/.changeset/pr-11177-tech-stories-1730214757061.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Tech Stories ---- - -Add `cypress_containerized` Docker Compose service ([#11177](https://github.com/linode/manager/pull/11177)) diff --git a/packages/manager/.changeset/pr-11177-tech-stories-1730214793474.md b/packages/manager/.changeset/pr-11177-tech-stories-1730214793474.md deleted file mode 100644 index 0c79ba70e01..00000000000 --- a/packages/manager/.changeset/pr-11177-tech-stories-1730214793474.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Tech Stories ---- - -Add `nodejs-cloud-manager` Dockerfile target ([#11177](https://github.com/linode/manager/pull/11177)) diff --git a/packages/manager/.changeset/pr-11178-added-1730961635027.md b/packages/manager/.changeset/pr-11178-added-1730961635027.md new file mode 100644 index 00000000000..a9984fd394a --- /dev/null +++ b/packages/manager/.changeset/pr-11178-added-1730961635027.md @@ -0,0 +1,5 @@ +--- +"@linode/manager": Added +--- + +Include Object Storage buckets in Support tickets dropdown ([#11178](https://github.com/linode/manager/pull/11178)) diff --git a/packages/manager/.changeset/pr-11179-added-1730201665174.md b/packages/manager/.changeset/pr-11179-added-1730201665174.md new file mode 100644 index 00000000000..6823f5d4bad --- /dev/null +++ b/packages/manager/.changeset/pr-11179-added-1730201665174.md @@ -0,0 +1,5 @@ +--- +"@linode/manager": Added +--- + +option to copy token in LKE details page ([#11179](https://github.com/linode/manager/pull/11179)) diff --git a/packages/manager/.changeset/pr-11180-changed-1730803608188.md b/packages/manager/.changeset/pr-11180-changed-1730803608188.md deleted file mode 100644 index 53ae4f23340..00000000000 --- a/packages/manager/.changeset/pr-11180-changed-1730803608188.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Changed ---- - -Refactored DatabaseResize to use shared components for node selection and summary section. ([#11180](https://github.com/linode/manager/pull/11180)) diff --git a/packages/manager/.changeset/pr-11184-tests-1730217933343.md b/packages/manager/.changeset/pr-11184-tests-1730217933343.md deleted file mode 100644 index 711c71f5d18..00000000000 --- a/packages/manager/.changeset/pr-11184-tests-1730217933343.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Tests ---- - -Add vitest workspace configuration ([#11184](https://github.com/linode/manager/pull/11184)) diff --git a/packages/manager/.changeset/pr-11187-fixed-1730229958854.md b/packages/manager/.changeset/pr-11187-fixed-1730229958854.md deleted file mode 100644 index 3fec311e5ee..00000000000 --- a/packages/manager/.changeset/pr-11187-fixed-1730229958854.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Fixed ---- - -Numerous UI bugs on the Object Storage bucket and access key landing pages ([#11187](https://github.com/linode/manager/pull/11187)) diff --git a/packages/manager/.changeset/pr-11188-added-1730298408749.md b/packages/manager/.changeset/pr-11188-added-1730298408749.md deleted file mode 100644 index 94abffd9b01..00000000000 --- a/packages/manager/.changeset/pr-11188-added-1730298408749.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Added ---- - -Pre-select a VPC subnet's on the Linode Create page when the VPC only has one subnet ([#11188](https://github.com/linode/manager/pull/11188)) diff --git a/packages/manager/.changeset/pr-11189-tests-1730310015248.md b/packages/manager/.changeset/pr-11189-tests-1730310015248.md deleted file mode 100644 index 0fbe1f93553..00000000000 --- a/packages/manager/.changeset/pr-11189-tests-1730310015248.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Tests ---- - -Delete test Linodes, LKE clusters, and Firewalls after Cypress runs ([#11189](https://github.com/linode/manager/pull/11189)) diff --git a/packages/manager/.changeset/pr-11190-tests-1730312266172.md b/packages/manager/.changeset/pr-11190-tests-1730312266172.md deleted file mode 100644 index 7ca92a9978c..00000000000 --- a/packages/manager/.changeset/pr-11190-tests-1730312266172.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Tests ---- - -Allow DBaaS resize test to pass when DBaaS v2 is enabled ([#11190](https://github.com/linode/manager/pull/11190)) diff --git a/packages/manager/.changeset/pr-11192-tech-stories-1730318704149.md b/packages/manager/.changeset/pr-11192-tech-stories-1730318704149.md deleted file mode 100644 index 15a849acd4c..00000000000 --- a/packages/manager/.changeset/pr-11192-tech-stories-1730318704149.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Tech Stories ---- - -Remove use of Redux for viewing StackScript details ([#11192](https://github.com/linode/manager/pull/11192)) diff --git a/packages/manager/.changeset/pr-11193-added-1730738415614.md b/packages/manager/.changeset/pr-11193-added-1730738415614.md deleted file mode 100644 index 031adeba93d..00000000000 --- a/packages/manager/.changeset/pr-11193-added-1730738415614.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Added ---- - -Summary Section for Database Create GA ([#11193](https://github.com/linode/manager/pull/11193)) diff --git a/packages/manager/.changeset/pr-11195-fixed-1730745532480.md b/packages/manager/.changeset/pr-11195-fixed-1730745532480.md deleted file mode 100644 index 9a7e1e0ad9f..00000000000 --- a/packages/manager/.changeset/pr-11195-fixed-1730745532480.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Fixed ---- - -Animation for VPC subnet drawers ([#11195](https://github.com/linode/manager/pull/11195)) diff --git a/packages/manager/.changeset/pr-11195-tech-stories-1730487840259.md b/packages/manager/.changeset/pr-11195-tech-stories-1730487840259.md deleted file mode 100644 index 6f78202aaf5..00000000000 --- a/packages/manager/.changeset/pr-11195-tech-stories-1730487840259.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Tech Stories ---- - -Convert from `formik` to `react-hook-form` for `SubnetCreateDrawer` ([#11195](https://github.com/linode/manager/pull/11195)) diff --git a/packages/manager/.changeset/pr-11196-upcoming-features-1730465663102.md b/packages/manager/.changeset/pr-11196-upcoming-features-1730465663102.md deleted file mode 100644 index c6d0b96144c..00000000000 --- a/packages/manager/.changeset/pr-11196-upcoming-features-1730465663102.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Upcoming Features ---- - -DBaaS add query to patch API, modify factory to include pendingUpdates ([#11196](https://github.com/linode/manager/pull/11196)) diff --git a/packages/manager/.changeset/pr-11198-upcoming-features-1730465952580.md b/packages/manager/.changeset/pr-11198-upcoming-features-1730465952580.md deleted file mode 100644 index cd7c2c8e48f..00000000000 --- a/packages/manager/.changeset/pr-11198-upcoming-features-1730465952580.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Upcoming Features ---- - -DBaaS add new Maintenance component, Upgrade version dialog, Review udpates dialog ([#11198](https://github.com/linode/manager/pull/11198)) diff --git a/packages/manager/.changeset/pr-11200-tests-1730467459621.md b/packages/manager/.changeset/pr-11200-tests-1730467459621.md deleted file mode 100644 index 3aa894d7438..00000000000 --- a/packages/manager/.changeset/pr-11200-tests-1730467459621.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Tests ---- - -Slight improvements to GitHub test result comment formatting ([#11200](https://github.com/linode/manager/pull/11200)) diff --git a/packages/manager/.changeset/pr-11202-changed-1730473350553.md b/packages/manager/.changeset/pr-11202-changed-1730473350553.md deleted file mode 100644 index 39c64d7c8fe..00000000000 --- a/packages/manager/.changeset/pr-11202-changed-1730473350553.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Changed ---- - -`.env.example` cypress warning ([#11202](https://github.com/linode/manager/pull/11202)) diff --git a/packages/manager/.changeset/pr-11211-tech-stories-1730836470267.md b/packages/manager/.changeset/pr-11211-tech-stories-1730836470267.md deleted file mode 100644 index 0a46b375401..00000000000 --- a/packages/manager/.changeset/pr-11211-tech-stories-1730836470267.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/manager": Tech Stories ---- - -Use unit tested function for Pendo url transformation ([#11211](https://github.com/linode/manager/pull/11211)) diff --git a/packages/manager/.changeset/pr-11217-fixed-1730913381751.md b/packages/manager/.changeset/pr-11217-fixed-1730913381751.md new file mode 100644 index 00000000000..8763a003d48 --- /dev/null +++ b/packages/manager/.changeset/pr-11217-fixed-1730913381751.md @@ -0,0 +1,5 @@ +--- +"@linode/manager": Fixed +--- + +Kubernetes details page UI issues ([#11217](https://github.com/linode/manager/pull/11217)) diff --git a/packages/manager/.changeset/pr-11221-changed-1731086980327.md b/packages/manager/.changeset/pr-11221-changed-1731086980327.md new file mode 100644 index 00000000000..5e42e2805a3 --- /dev/null +++ b/packages/manager/.changeset/pr-11221-changed-1731086980327.md @@ -0,0 +1,5 @@ +--- +"@linode/manager": Changed +--- + +Update developer docs on unit testing user events ([#11221](https://github.com/linode/manager/pull/11221)) diff --git a/packages/manager/.changeset/pr-11223-added-1730985113933.md b/packages/manager/.changeset/pr-11223-added-1730985113933.md new file mode 100644 index 00000000000..6e80abad54d --- /dev/null +++ b/packages/manager/.changeset/pr-11223-added-1730985113933.md @@ -0,0 +1,5 @@ +--- +"@linode/manager": Added +--- + +Tooltip for 'Usable Storage' in Create/Resize Database Table ([#11223](https://github.com/linode/manager/pull/11223)) diff --git a/packages/manager/.changeset/pr-11236-tech-stories-1731104032752.md b/packages/manager/.changeset/pr-11236-tech-stories-1731104032752.md new file mode 100644 index 00000000000..48da6c5bae5 --- /dev/null +++ b/packages/manager/.changeset/pr-11236-tech-stories-1731104032752.md @@ -0,0 +1,5 @@ +--- +"@linode/manager": Tech Stories +--- + +Update PULL_REQUEST_TEMPLATE ([#11219](https://github.com/linode/manager/pull/11219), [#11236](https://github.com/linode/manager/pull/11236)) diff --git a/packages/manager/CHANGELOG.md b/packages/manager/CHANGELOG.md index a7f48e42491..90a1a2761a8 100644 --- a/packages/manager/CHANGELOG.md +++ b/packages/manager/CHANGELOG.md @@ -4,6 +4,82 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [2024-11-12] - v1.132.0 + + +### Added: + +- Tooltip for 'Usable Storage' in Create/Resize Database Table ([#11223](https://github.com/linode/manager/pull/11223)) +- Success toasts to profile display settings page (with other minor improvements) ([#11141](https://github.com/linode/manager/pull/11141)) +- Mask Sensitive Data preference to Profile Settings ([#11143](https://github.com/linode/manager/pull/11143)) +- DBaaS Suspend and Resume for Database Landing and Details ([#11152](https://github.com/linode/manager/pull/11152)) +- Pre-selection of a VPC’s subnet on the Linode Create page when the VPC only has one subnet ([#11188](https://github.com/linode/manager/pull/11188)) +- Summary Section for Database Create GA ([#11193](https://github.com/linode/manager/pull/11193)) +- New GPUv2 egress transfer helpers ([#11209](https://github.com/linode/manager/pull/11209)) + +### Changed: + +- Optimize GPU egress data transfer copy ([#11235](https://github.com/linode/manager/pull/11235)) +- Incorporate Product Family Groups in Side Nav ([#11080](https://github.com/linode/manager/pull/11080)) +- Remove Double border on "Billing & Payment History" table with dark theme. ([#11111](https://github.com/linode/manager/pull/11111)) +- Slightly improve styles on support ticket flows ([#11144](https://github.com/linode/manager/pull/11144)) +- Improve validation error when a backup is not selected ([#11147](https://github.com/linode/manager/pull/11147)) +- Database settings text and labels ([#11166](https://github.com/linode/manager/pull/11166)) +- Refactor DatabaseResize to use shared components for node selection and summary section ([#11180](https://github.com/linode/manager/pull/11180)) +- `.env.example` cypress warning ([#11202](https://github.com/linode/manager/pull/11202)) +- Disable unsupported images for distributed regions ([#11206](https://github.com/linode/manager/pull/11206)) + +### Fixed: + +- Preserve default child cluster creation behavior ([#11234](https://github.com/linode/manager/pull/11234)) +- Misaligned table headers in Account Maintenance page ([#11099](https://github.com/linode/manager/pull/11099)) +- Database create page form being enabled for restricted users ([#11137](https://github.com/linode/manager/pull/11137)) +- Faux bold in Safari with `` & `` tags ([#11149](https://github.com/linode/manager/pull/11149)) +- `Coverage Comment` GHA running on drafts ([#11161](https://github.com/linode/manager/pull/11161)) +- Aria label of action menu button in IP address table row ([#11167](https://github.com/linode/manager/pull/11167)) +- UI bugs on the Object Storage bucket and access key landing pages ([#11187](https://github.com/linode/manager/pull/11187)) +- Animation for VPC subnet drawers ([#11195](https://github.com/linode/manager/pull/11195)) +- DBaaS enable creation of two node clusters ([#11218](https://github.com/linode/manager/pull/11218)) +- Crash on the Linode Create flow when a Linode with a `type` of `null` is selected ([#11247](https://github.com/linode/manager/pull/11247)) + +### Tech Stories: + +- Consolidate ImageSelect components ([#11058](https://github.com/linode/manager/pull/11058)) +- Refactor TextField component ([#11134](https://github.com/linode/manager/pull/11134)) +- Clean up Profile Display Settings page ([#11141](https://github.com/linode/manager/pull/11141)) +- `only-export-components` for Tanstack routes ([#11142](https://github.com/linode/manager/pull/11142)) +- Add more customization to legends and charts ([#11145](https://github.com/linode/manager/pull/11145)) +- Update `@types/node` to `20.17.0` ([#11157](https://github.com/linode/manager/pull/11157)) +- Add `cypress_containerized` Docker Compose service ([#11177](https://github.com/linode/manager/pull/11177)) +- Add `nodejs-cloud-manager` Dockerfile target ([#11177](https://github.com/linode/manager/pull/11177)) +- Remove use of Redux for viewing StackScript details ([#11192](https://github.com/linode/manager/pull/11192)) +- Convert from `formik` to `react-hook-form` for `SubnetCreateDrawer` ([#11195](https://github.com/linode/manager/pull/11195)) +- Use unit tested function for Pendo url transformation ([#11211](https://github.com/linode/manager/pull/11211)) +- Remove the feature flag and tracking events used for A/B testing in the API CLI Tools modal, and update the DX Tools modal button copy to 'View Code Snippets ([#11156](https://github.com/linode/manager/pull/11156)) + +### Tests: + +- Add cypress tests for creating LKE clusters with ACL ([#11132](https://github.com/linode/manager/pull/11132)) +- Add unit tests to declutter LKE ACL cypress tests and fix `lke-create.spec.ts` failures ([#11176](https://github.com/linode/manager/pull/11176)) +- Add vitest workspace configuration ([#11184](https://github.com/linode/manager/pull/11184)) +- Delete test Linodes, LKE clusters, and Firewalls after Cypress runs ([#11189](https://github.com/linode/manager/pull/11189)) +- Allow DBaaS resize test to pass when DBaaS v2 is enabled ([#11190](https://github.com/linode/manager/pull/11190)) +- Slight improvements to GitHub test result comment formatting ([#11200](https://github.com/linode/manager/pull/11200)) + +### Upcoming Features: + +- ACLP UI - DBaaS instances order by label ([#11226](https://github.com/linode/manager/pull/11226)) +- Add post processing for missing timestamp data across dimensions in ACLP charts ([#11225](https://github.com/linode/manager/pull/11225)) +- Add default x-filter for DBasS Aiven clusters fetch in resource selection component ([#11150](https://github.com/linode/manager/pull/11150)) +- Replace one-off hardcoded black and white color values with colorTokens ([#11165](https://github.com/linode/manager/pull/11165)) +- Add global border radius token to theme and replace hard coded values where `borderRadius = 0` ([#11169](https://github.com/linode/manager/pull/11169)) +- Handle API errors for global filters and dashboard components ([#11170](https://github.com/linode/manager/pull/11170)) +- Add global `font` and `spacing` tokens to theme and refactor design tokens ([#11171](https://github.com/linode/manager/pull/11171)) +- DBaaS: Add query to patch API, modify factory to include pendingUpdates ([#11196](https://github.com/linode/manager/pull/11196)) +- DBaaS: Add new Maintenance, Upgrade Version dialog, and Review Updates dialog components ([#11198](https://github.com/linode/manager/pull/11198)) +- DBaaS: major minor updates integration ([#11199](https://github.com/linode/manager/pull/11199)) + + ## [2024-11-05] - v1.131.2 diff --git a/packages/manager/cypress/e2e/core/kubernetes/lke-create.spec.ts b/packages/manager/cypress/e2e/core/kubernetes/lke-create.spec.ts index 2398df08e8c..c220c9e372b 100644 --- a/packages/manager/cypress/e2e/core/kubernetes/lke-create.spec.ts +++ b/packages/manager/cypress/e2e/core/kubernetes/lke-create.spec.ts @@ -503,13 +503,12 @@ describe('LKE Cluster Creation with ACL', () => { .should('be.visible') .click(); - // Disable ACL + // Confirm that ACL is disabled by default. cy.contains('Control Plane ACL').should('be.visible'); ui.toggle .find() - .should('have.attr', 'data-qa-toggle', 'true') - .should('be.visible') - .click(); + .should('have.attr', 'data-qa-toggle', 'false') + .should('be.visible'); // Add a node pool cy.log(`Adding ${nodeCount}x ${getLkePlanName(clusterPlan)} node(s)`); @@ -614,12 +613,16 @@ describe('LKE Cluster Creation with ACL', () => { .should('be.visible') .click(); - // Confirm ACL section + // Confirm ACL is disabled by default, then enable it. cy.contains('Control Plane ACL').should('be.visible'); ui.toggle .find() - .should('have.attr', 'data-qa-toggle', 'true') - .should('be.visible'); + .should('have.attr', 'data-qa-toggle', 'false') + .should('be.visible') + .click(); + + ui.toggle.find().should('have.attr', 'data-qa-toggle', 'true'); + // Add some IPv4s and an IPv6 cy.findByLabelText('IPv4 Addresses or CIDRs ip-address-0') .should('be.visible') @@ -733,11 +736,22 @@ describe('LKE Cluster Creation with ACL', () => { .should('be.visible') .click(); + // Enable ACL + cy.contains('Control Plane ACL').should('be.visible'); + ui.toggle + .find() + .should('have.attr', 'data-qa-toggle', 'false') + .should('be.visible') + .click(); + + ui.toggle.find().should('have.attr', 'data-qa-toggle', 'true'); + // Confirm ACL IPv4 validation works as expected cy.findByLabelText('IPv4 Addresses or CIDRs ip-address-0') .should('be.visible') .click() .type('invalid ip'); + // click out of textbox and confirm error is visible cy.contains('Control Plane ACL').should('be.visible').click(); cy.contains('Must be a valid IPv4 address.').should('be.visible'); diff --git a/packages/manager/cypress/e2e/core/kubernetes/lke-update.spec.ts b/packages/manager/cypress/e2e/core/kubernetes/lke-update.spec.ts index 7c20f14834f..09e600eb986 100644 --- a/packages/manager/cypress/e2e/core/kubernetes/lke-update.spec.ts +++ b/packages/manager/cypress/e2e/core/kubernetes/lke-update.spec.ts @@ -730,7 +730,7 @@ describe('LKE cluster updates', () => { cy.wait(['@getCluster', '@getNodePools', '@getVersions']); // Click "Reset" button, proceed through confirmation dialog. - cy.findByText('Reset').should('be.visible').click(); + cy.findByText('Reset').should('be.visible').click({ force: true }); ui.dialog .findByTitle('Reset Cluster Kubeconfig?') .should('be.visible') diff --git a/packages/manager/cypress/e2e/core/linodes/plan-selection.spec.ts b/packages/manager/cypress/e2e/core/linodes/plan-selection.spec.ts index 94827d5d9cf..99255a0241c 100644 --- a/packages/manager/cypress/e2e/core/linodes/plan-selection.spec.ts +++ b/packages/manager/cypress/e2e/core/linodes/plan-selection.spec.ts @@ -12,6 +12,7 @@ import { mockGetRegionAvailability, } from 'support/intercepts/regions'; import { mockGetLinodeTypes } from 'support/intercepts/linodes'; +import { mockAppendFeatureFlags } from 'support/intercepts/feature-flags'; const mockRegions = [ regionFactory.build({ @@ -356,11 +357,18 @@ describe('displays specific linode plans for GPU', () => { mockGetRegionAvailability(mockRegions[0].id, mockRegionAvailability).as( 'getRegionAvailability' ); + mockAppendFeatureFlags({ + gpuv2: { + transferBanner: true, + planDivider: true, + egressBanner: true, + }, + }).as('getFeatureFlags'); }); it('Should render divided tables when GPU divider enabled', () => { cy.visitWithLogin('/linodes/create'); - + cy.wait(['@getRegions', '@getLinodeTypes', '@getFeatureFlags']); ui.regionSelect.find().click(); ui.regionSelect.findItemByRegionLabel(mockRegions[0].label).click(); @@ -368,7 +376,7 @@ describe('displays specific linode plans for GPU', () => { // Should display two separate tables cy.findByText('GPU').click(); cy.get(linodePlansPanel).within(() => { - cy.findAllByRole('alert').should('have.length', 2); + cy.findAllByRole('alert').should('have.length', 3); cy.get(notices.unavailable).should('be.visible'); cy.findByRole('table', { diff --git a/packages/manager/package.json b/packages/manager/package.json index 8e840354de8..6d199b422df 100644 --- a/packages/manager/package.json +++ b/packages/manager/package.json @@ -2,7 +2,7 @@ "name": "linode-manager", "author": "Linode", "description": "The Linode Manager website", - "version": "1.131.2", + "version": "1.132.0", "private": true, "type": "module", "bugs": { diff --git a/packages/manager/src/assets/icons/entityIcons/distributed-region.svg b/packages/manager/src/assets/icons/entityIcons/distributed-region.svg deleted file mode 100644 index a9e44da4e6d..00000000000 --- a/packages/manager/src/assets/icons/entityIcons/distributed-region.svg +++ /dev/null @@ -1,7 +0,0 @@ - - -distributed-region - - - - diff --git a/packages/manager/src/components/AccessPanel/AccessPanel.tsx b/packages/manager/src/components/AccessPanel/AccessPanel.tsx index 7c26208c4e9..2652233c815 100644 --- a/packages/manager/src/components/AccessPanel/AccessPanel.tsx +++ b/packages/manager/src/components/AccessPanel/AccessPanel.tsx @@ -21,7 +21,7 @@ import { Typography } from 'src/components/Typography'; import { useRegionsQuery } from 'src/queries/regions/regions'; import { doesRegionSupportFeature } from 'src/utilities/doesRegionSupportFeature'; -import { Divider } from '../Divider'; +import { Divider } from '@linode/ui'; import UserSSHKeyPanel from './UserSSHKeyPanel'; import type { Theme } from '@mui/material/styles'; diff --git a/packages/manager/src/components/Accordion.tsx b/packages/manager/src/components/Accordion.tsx index 6302d388d1a..5cce4365273 100644 --- a/packages/manager/src/components/Accordion.tsx +++ b/packages/manager/src/components/Accordion.tsx @@ -1,22 +1,19 @@ +import { Notice } from '@linode/ui'; import KeyboardArrowDown from '@mui/icons-material/KeyboardArrowDown'; -import { - default as _Accordion, - AccordionProps as _AccordionProps, -} from '@mui/material/Accordion'; -import AccordionDetails, { - AccordionDetailsProps, -} from '@mui/material/AccordionDetails'; -import AccordionSummary, { - AccordionSummaryProps, -} from '@mui/material/AccordionSummary'; +import { default as _Accordion } from '@mui/material/Accordion'; +import AccordionDetails from '@mui/material/AccordionDetails'; +import AccordionSummary from '@mui/material/AccordionSummary'; import Grid from '@mui/material/Unstable_Grid2'; import * as React from 'react'; import { makeStyles } from 'tss-react/mui'; -import { Notice } from 'src/components/Notice/Notice'; -import { Typography, TypographyProps } from 'src/components/Typography'; +import { Typography } from 'src/components/Typography'; import type { Theme } from '@mui/material'; +import type { AccordionProps as _AccordionProps } from '@mui/material/Accordion'; +import type { AccordionDetailsProps } from '@mui/material/AccordionDetails'; +import type { AccordionSummaryProps } from '@mui/material/AccordionSummary'; +import type { TypographyProps } from 'src/components/Typography'; const useStyles = makeStyles()((theme: Theme) => ({ itemCount: { diff --git a/packages/manager/src/components/AkamaiBanner/AkamaiBanner.styles.ts b/packages/manager/src/components/AkamaiBanner/AkamaiBanner.styles.ts index 04c3ad2a2a0..3642372e4f2 100644 --- a/packages/manager/src/components/AkamaiBanner/AkamaiBanner.styles.ts +++ b/packages/manager/src/components/AkamaiBanner/AkamaiBanner.styles.ts @@ -1,11 +1,8 @@ -import { Box, omittedProps } from '@linode/ui'; +import { Box, Stack, WarningIcon, omittedProps } from '@linode/ui'; import { styled } from '@mui/material/styles'; -import Warning from 'src/assets/icons/warning.svg'; import AkamaiLogo from 'src/assets/logo/akamai-logo.svg'; -import { Stack } from '../Stack'; - export const StyledAkamaiLogo = styled(AkamaiLogo, { label: 'StyledAkamaiLogo', })(({ theme }) => ({ @@ -17,7 +14,7 @@ export const StyledAkamaiLogo = styled(AkamaiLogo, { }, })); -export const StyledWarningIcon = styled(Warning, { +export const StyledWarningIcon = styled(WarningIcon, { label: 'StyledWarningIcon', })(({ theme }) => ({ color: theme.tokens.color.Neutrals.Black, diff --git a/packages/manager/src/components/AkamaiBanner/AkamaiBanner.tsx b/packages/manager/src/components/AkamaiBanner/AkamaiBanner.tsx index 1e7421ac180..7ef3e3fcb8b 100644 --- a/packages/manager/src/components/AkamaiBanner/AkamaiBanner.tsx +++ b/packages/manager/src/components/AkamaiBanner/AkamaiBanner.tsx @@ -1,4 +1,4 @@ -import { Box } from '@linode/ui'; +import { Box, Stack } from '@linode/ui'; import { useMediaQuery, useTheme } from '@mui/material'; import * as React from 'react'; @@ -7,7 +7,6 @@ import { Typography } from 'src/components/Typography'; import { useFlags } from 'src/hooks/useFlags'; import { replaceNewlinesWithLineBreaks } from 'src/utilities/replaceNewlinesWithLineBreaks'; -import { Stack } from '../Stack'; import { StyledAkamaiLogo, StyledBanner, diff --git a/packages/manager/src/components/Autocomplete/Autocomplete.stories.tsx b/packages/manager/src/components/Autocomplete/Autocomplete.stories.tsx index 2516418fc67..5f55d3ea49d 100644 --- a/packages/manager/src/components/Autocomplete/Autocomplete.stories.tsx +++ b/packages/manager/src/components/Autocomplete/Autocomplete.stories.tsx @@ -1,6 +1,5 @@ -import { IconButton } from '@linode/ui'; +import { IconButton, Stack } from '@linode/ui'; import Close from '@mui/icons-material/Close'; -import { Stack } from '@mui/material'; import { styled } from '@mui/material/styles'; import { action } from '@storybook/addon-actions'; import React, { useState } from 'react'; diff --git a/packages/manager/src/components/CheckoutBar/DisplaySectionList.tsx b/packages/manager/src/components/CheckoutBar/DisplaySectionList.tsx index 0a383207b1b..ad365e380a1 100644 --- a/packages/manager/src/components/CheckoutBar/DisplaySectionList.tsx +++ b/packages/manager/src/components/CheckoutBar/DisplaySectionList.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; -import { Divider } from '../Divider'; +import { Divider } from '@linode/ui'; import { DisplaySection } from './DisplaySection'; interface DisplaySectionListProps { diff --git a/packages/manager/src/components/CopyTooltip/CopyTooltip.test.tsx b/packages/manager/src/components/CopyTooltip/CopyTooltip.test.tsx index e18c0dc546a..d90b014d13c 100644 --- a/packages/manager/src/components/CopyTooltip/CopyTooltip.test.tsx +++ b/packages/manager/src/components/CopyTooltip/CopyTooltip.test.tsx @@ -1,4 +1,3 @@ -import { act, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import * as React from 'react'; @@ -11,32 +10,29 @@ import type { CopyTooltipProps } from './CopyTooltip'; const mockText = 'Hello world'; const defaultProps: CopyTooltipProps = { + onClickCallback: vi.fn(), text: mockText, }; describe('CopyTooltip', () => { it('should render the copy icon button and tooltip', async () => { - const { getByLabelText, getByRole } = renderWithTheme( + const { findByRole, getByLabelText } = renderWithTheme( ); const copyIconButton = getByLabelText(`Copy ${mockText} to clipboard`); - await act(() => userEvent.hover(copyIconButton)); + await userEvent.hover(copyIconButton); - await waitFor(() => { - const copyTooltip = getByRole('tooltip'); - expect(copyTooltip).toBeInTheDocument(); - expect(copyTooltip).toHaveTextContent('Copy'); - }); + const copyTooltip = await findByRole('tooltip'); + expect(copyTooltip).toBeInTheDocument(); + expect(copyTooltip).toHaveTextContent('Copy'); await userEvent.click(copyIconButton); - await waitFor(() => { - const copiedTooltip = getByRole('tooltip', {}); - expect(copiedTooltip).toBeInTheDocument(); - expect(copiedTooltip).toHaveTextContent('Copied!'); - }); + const copiedTooltip = await findByRole('tooltip'); + expect(copiedTooltip).toBeInTheDocument(); + expect(copiedTooltip).toHaveTextContent('Copied!'); }); it('should render text with the copyableText property', async () => { @@ -80,7 +76,7 @@ describe('CopyTooltip', () => { expect(getByText('β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’')).toBeVisible(); expect(queryByText(mockText)).toBeNull(); - await act(() => userEvent.click(visibilityToggle)); + await userEvent.click(visibilityToggle); // Text should be unmasked expect(getByText('Hello world')).toBeVisible(); diff --git a/packages/manager/src/components/DeletionDialog/DeletionDialog.tsx b/packages/manager/src/components/DeletionDialog/DeletionDialog.tsx index bce1c53ad8d..89938fbeb61 100644 --- a/packages/manager/src/components/DeletionDialog/DeletionDialog.tsx +++ b/packages/manager/src/components/DeletionDialog/DeletionDialog.tsx @@ -1,9 +1,9 @@ +import { Notice } from '@linode/ui'; import { useTheme } from '@mui/material/styles'; import * as React from 'react'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { ConfirmationDialog } from 'src/components/ConfirmationDialog/ConfirmationDialog'; -import { Notice } from 'src/components/Notice/Notice'; import { TypeToConfirm } from 'src/components/TypeToConfirm/TypeToConfirm'; import { Typography } from 'src/components/Typography'; import { titlecase } from 'src/features/Linodes/presentation'; diff --git a/packages/manager/src/components/Dialog/Dialog.tsx b/packages/manager/src/components/Dialog/Dialog.tsx index 6002e942dfc..fbbb76cfaa1 100644 --- a/packages/manager/src/components/Dialog/Dialog.tsx +++ b/packages/manager/src/components/Dialog/Dialog.tsx @@ -1,11 +1,10 @@ -import { Box, omittedProps } from '@linode/ui'; +import { Box, Notice, omittedProps } from '@linode/ui'; import _Dialog from '@mui/material/Dialog'; import DialogContent from '@mui/material/DialogContent'; import { styled, useTheme } from '@mui/material/styles'; import * as React from 'react'; import { DialogTitle } from 'src/components/DialogTitle/DialogTitle'; -import { Notice } from 'src/components/Notice/Notice'; import { convertForAria } from 'src/utilities/stringUtils'; import type { DialogProps as _DialogProps } from '@mui/material/Dialog'; diff --git a/packages/manager/src/components/DismissibleBanner/DismissibleBanner.styles.ts b/packages/manager/src/components/DismissibleBanner/DismissibleBanner.styles.ts index 7ac4261bf71..acd8cea2d56 100644 --- a/packages/manager/src/components/DismissibleBanner/DismissibleBanner.styles.ts +++ b/packages/manager/src/components/DismissibleBanner/DismissibleBanner.styles.ts @@ -1,7 +1,6 @@ +import { Notice } from '@linode/ui'; import { styled } from '@mui/material/styles'; -import { Notice } from 'src/components/Notice/Notice'; - import { StyledLinkButton } from '../Button/StyledLinkButton'; export const StyledNotice = styled(Notice, { label: 'StyledNotice' })( diff --git a/packages/manager/src/components/DismissibleBanner/DismissibleBanner.tsx b/packages/manager/src/components/DismissibleBanner/DismissibleBanner.tsx index 0322ed2ffbf..4ee35065ea8 100644 --- a/packages/manager/src/components/DismissibleBanner/DismissibleBanner.tsx +++ b/packages/manager/src/components/DismissibleBanner/DismissibleBanner.tsx @@ -7,7 +7,7 @@ import { useDismissibleNotifications } from 'src/hooks/useDismissibleNotificatio import { StyledButton, StyledNotice } from './DismissibleBanner.styles'; -import type { NoticeProps } from 'src/components/Notice/Notice'; +import type { NoticeProps } from '@linode/ui'; import type { DismissibleNotificationOptions } from 'src/hooks/useDismissibleNotifications'; interface Props extends NoticeProps { diff --git a/packages/manager/src/components/DrawerContent/DrawerContent.tsx b/packages/manager/src/components/DrawerContent/DrawerContent.tsx index a19fb1949a6..bbc53f3b641 100644 --- a/packages/manager/src/components/DrawerContent/DrawerContent.tsx +++ b/packages/manager/src/components/DrawerContent/DrawerContent.tsx @@ -1,7 +1,7 @@ +import { Notice } from '@linode/ui'; import * as React from 'react'; import { CircleProgress } from 'src/components/CircleProgress'; -import { Notice } from 'src/components/Notice/Notice'; export interface DrawerContentProps { children: React.ReactNode; diff --git a/packages/manager/src/components/Encryption/Encryption.tsx b/packages/manager/src/components/Encryption/Encryption.tsx index 6b170531c2d..fb55ce2c2ff 100644 --- a/packages/manager/src/components/Encryption/Encryption.tsx +++ b/packages/manager/src/components/Encryption/Encryption.tsx @@ -1,12 +1,10 @@ -import { Box } from '@linode/ui'; +import { Box, Notice } from '@linode/ui'; import { List, ListItem } from '@mui/material'; import * as React from 'react'; import { Checkbox } from 'src/components/Checkbox'; import { Typography } from 'src/components/Typography'; -import { Notice } from '../Notice/Notice'; - export interface EncryptionProps { descriptionCopy: JSX.Element | string; disabled?: boolean; diff --git a/packages/manager/src/components/EntityDetail/EntityDetail.tsx b/packages/manager/src/components/EntityDetail/EntityDetail.tsx index d019a34c5ff..a72f98c7a77 100644 --- a/packages/manager/src/components/EntityDetail/EntityDetail.tsx +++ b/packages/manager/src/components/EntityDetail/EntityDetail.tsx @@ -51,8 +51,7 @@ const GridBody = styled(Grid, { ? undefined : `1px solid ${theme.borderColors.borderTable}`, // @TODO LKE-E: This conditional can be removed when/if the footer is introduced in M3-8348 borderTop: `1px solid ${theme.borderColors.borderTable}`, - paddingBottom: theme.spacing(), - paddingRight: theme.spacing(), + padding: theme.spacing(), })); const GridFooter = styled(Grid, { diff --git a/packages/manager/src/components/GenerateFirewallDialog/GenerateFirewallDialog.tsx b/packages/manager/src/components/GenerateFirewallDialog/GenerateFirewallDialog.tsx index e102a493d0c..7a06bf1465c 100644 --- a/packages/manager/src/components/GenerateFirewallDialog/GenerateFirewallDialog.tsx +++ b/packages/manager/src/components/GenerateFirewallDialog/GenerateFirewallDialog.tsx @@ -1,3 +1,4 @@ +import { Notice, Stack } from '@linode/ui'; import React from 'react'; import { useFlags } from 'src/hooks/useFlags'; @@ -8,8 +9,6 @@ import { Dialog } from '../Dialog/Dialog'; import { ErrorMessage } from '../ErrorMessage'; import { LinearProgress } from '../LinearProgress'; import { Link } from '../Link'; -import { Notice } from '../Notice/Notice'; -import { Stack } from '../Stack'; import { Typography } from '../Typography'; import { useCreateFirewallFromTemplate } from './useCreateFirewallFromTemplate'; diff --git a/packages/manager/src/components/ImageSelect/ImageOption.test.tsx b/packages/manager/src/components/ImageSelect/ImageOption.test.tsx index 8b704581f62..b3380fee7cb 100644 --- a/packages/manager/src/components/ImageSelect/ImageOption.test.tsx +++ b/packages/manager/src/components/ImageSelect/ImageOption.test.tsx @@ -10,7 +10,7 @@ describe('ImageOption', () => { const image = imageFactory.build({ eol: null }); const { getByText } = renderWithTheme( - + ); expect(getByText(image.label)).toBeVisible(); @@ -20,7 +20,7 @@ describe('ImageOption', () => { const image = imageFactory.build(); const { getByTestId } = renderWithTheme( - + ); expect(getByTestId('os-icon')).toBeVisible(); @@ -30,7 +30,7 @@ describe('ImageOption', () => { const image = imageFactory.build({ capabilities: ['cloud-init'] }); const { getByLabelText } = renderWithTheme( - , + , { flags: { metadata: true } } ); @@ -39,25 +39,40 @@ describe('ImageOption', () => { ).toBeVisible(); }); - it('renders a distributed icon if image has the "distributed-sites" capability', () => { - const image = imageFactory.build({ capabilities: ['distributed-sites'] }); + it('disables the image option if the image has a disabled reason', () => { + const image = imageFactory.build({ eol: null }); + const disabledReason = + 'The selected image cannot be deployed to a distributed region.'; - const { getByLabelText } = renderWithTheme( - + const { getByText } = renderWithTheme( + ); + expect( + getByText(image.label).closest('li')?.getAttribute('aria-label') + ).toBe(disabledReason); + }); + it('does not disable the image option if the image does not have a disabled reason', () => { + const image = imageFactory.build({ eol: null }); + + const { getByText } = renderWithTheme( + + ); expect( - getByLabelText( - 'This image is compatible with distributed compute regions.' - ) - ).toBeVisible(); + getByText(image.label).closest('li')?.getAttribute('aria-label') + ).toBe(''); }); it('renders (deprecated) if the image is deprecated', () => { const image = imageFactory.build({ deprecated: true }); const { getByText } = renderWithTheme( - + ); expect(getByText(`${image.label} (deprecated)`)).toBeVisible(); @@ -70,7 +85,7 @@ describe('ImageOption', () => { }); const { getByText } = renderWithTheme( - + ); expect(getByText(`${image.label} (deprecated)`)).toBeVisible(); @@ -80,7 +95,7 @@ describe('ImageOption', () => { const image = imageFactory.build(); const { getByTestId } = renderWithTheme( - + ); expect(getByTestId('DoneIcon')).toBeVisible(); diff --git a/packages/manager/src/components/ImageSelect/ImageOption.tsx b/packages/manager/src/components/ImageSelect/ImageOption.tsx index c1f229ca958..55c105bd6ad 100644 --- a/packages/manager/src/components/ImageSelect/ImageOption.tsx +++ b/packages/manager/src/components/ImageSelect/ImageOption.tsx @@ -1,61 +1,46 @@ -import { Tooltip } from '@linode/ui'; +import { Stack, Tooltip } from '@linode/ui'; import React from 'react'; import CloudInitIcon from 'src/assets/icons/cloud-init.svg'; -import DistributedRegionIcon from 'src/assets/icons/entityIcons/distributed-region.svg'; +import { ListItemOption } from 'src/components/ListItemOption'; import { useFlags } from 'src/hooks/useFlags'; -import { SelectedIcon } from '../Autocomplete/Autocomplete.styles'; import { OSIcon } from '../OSIcon'; -import { Stack } from '../Stack'; import { Typography } from '../Typography'; import { isImageDeprecated } from './utilities'; import type { Image } from '@linode/api-v4'; +import type { ListItemProps } from 'src/components/ListItemOption'; -interface Props { - image: Image; - isSelected: boolean; - listItemProps: Omit, 'key'>; -} - -export const ImageOption = ({ image, isSelected, listItemProps }: Props) => { +export const ImageOption = ({ + disabledOptions, + item, + props, + selected, +}: ListItemProps) => { const flags = useFlags(); return ( -
  • - - {image?.id !== 'any/all' && ( - - )} + + {item?.id !== 'any/all' && } - {image.label} {isImageDeprecated(image) && '(deprecated)'} + {item.label} {isImageDeprecated(item) && '(deprecated)'} - - {image.capabilities.includes('distributed-sites') && ( - -
    - -
    -
    - )} - {flags.metadata && image.capabilities.includes('cloud-init') && ( - - - - - - )} - {isSelected && } -
    -
  • + {flags.metadata && item.capabilities.includes('cloud-init') && ( + + + + + + )} + ); }; diff --git a/packages/manager/src/components/ImageSelect/ImageSelect.tsx b/packages/manager/src/components/ImageSelect/ImageSelect.tsx index c7f2ad94e12..ab07b89494e 100644 --- a/packages/manager/src/components/ImageSelect/ImageSelect.tsx +++ b/packages/manager/src/components/ImageSelect/ImageSelect.tsx @@ -8,10 +8,11 @@ import { OSIcon } from '../OSIcon'; import { ImageOption } from './ImageOption'; import { getAPIFilterForImageSelect, + getDisabledImages, getFilteredImagesForImageSelect, } from './utilities'; -import type { Image } from '@linode/api-v4'; +import type { Image, RegionSite } from '@linode/api-v4'; import type { EnhancedAutocompleteProps } from 'src/components/Autocomplete/Autocomplete'; export type ImageSelectVariant = 'all' | 'private' | 'public'; @@ -27,6 +28,7 @@ interface BaseProps label?: string; placeholder?: string; selectIfOnlyOneOption?: boolean; + siteType?: RegionSite; variant: ImageSelectVariant; } @@ -53,6 +55,7 @@ export const ImageSelect = (props: Props) => { onChange, placeholder, selectIfOnlyOneOption, + siteType, variant, ...rest } = props; @@ -62,6 +65,11 @@ export const ImageSelect = (props: Props) => { getAPIFilterForImageSelect(variant) ); + const disabledImages = getDisabledImages({ + images: images ?? [], + site_type: siteType, + }); + const _options = useMemo(() => { // We can't filter out Kubernetes images using the API so we do it client side const filteredOptions = @@ -144,10 +152,11 @@ export const ImageSelect = (props: Props) => { return ( ); }} @@ -182,6 +191,7 @@ export const ImageSelect = (props: Props) => { : !multiple && !Array.isArray(value) && onChange(value) } errorText={rest.errorText ?? error?.[0].reason} + getOptionDisabled={(option) => Boolean(disabledImages[option.id])} multiple={multiple} value={value} /> diff --git a/packages/manager/src/components/ImageSelect/utilities.ts b/packages/manager/src/components/ImageSelect/utilities.ts index cfd765da017..dcb1babfb1e 100644 --- a/packages/manager/src/components/ImageSelect/utilities.ts +++ b/packages/manager/src/components/ImageSelect/utilities.ts @@ -3,7 +3,8 @@ import { DateTime } from 'luxon'; import { MAX_MONTHS_EOL_FILTER } from 'src/constants'; import type { ImageSelectVariant } from './ImageSelect'; -import type { Image } from '@linode/api-v4'; +import type { Image, RegionSite } from '@linode/api-v4'; +import type { DisableItemOption } from 'src/components/ListItemOption'; /** * Given a Image Select "variant", this PR returns an @@ -88,3 +89,33 @@ export const isImageDeprecated = (image: Image) => { return image.deprecated || isImageEOL; }; + +interface DisabledImageOptions { + images: Image[]; + site_type?: RegionSite; +} + +/** + * Returns images that should be disabled on the Linode Create flow. + * + * @returns key/value pairs for disabled images. the key is the image id and the value is why the image is disabled + */ +export const getDisabledImages = (options: DisabledImageOptions) => { + const { images, site_type } = options; + + // Disable images that do not support distributed sites if the selected region is distributed + if (site_type === 'distributed') { + const disabledImages: Record = {}; + for (const image of images) { + if (!image.capabilities.includes('distributed-sites')) { + disabledImages[image.id] = { + reason: + 'The selected image cannot be deployed to a distributed region.', + }; + } + } + return disabledImages; + } + + return {}; +}; diff --git a/packages/manager/src/components/ListItemOption.tsx b/packages/manager/src/components/ListItemOption.tsx new file mode 100644 index 00000000000..8a8e4a2bb39 --- /dev/null +++ b/packages/manager/src/components/ListItemOption.tsx @@ -0,0 +1,115 @@ +import { Box, Tooltip } from '@linode/ui'; +import { styled } from '@mui/material/styles'; +import { visuallyHidden } from '@mui/utils'; +import React from 'react'; + +import { SelectedIcon } from 'src/components/Autocomplete/Autocomplete.styles'; +import { ListItem } from 'src/components/ListItem'; + +import type { ListItemComponentsPropsOverrides } from '@mui/material/ListItem'; + +export interface ListItemProps { + children?: React.ReactNode; + disabledOptions?: DisableItemOption; + item: T & { id: number | string }; + maxHeight?: number; + props: React.HTMLAttributes; + selected?: boolean; +} + +export interface DisableItemOption { + /** + * The reason the item option is disabled. + * This is shown to the user as a tooltip. + */ + reason: JSX.Element | string; + /** + * An optional minWith applied to the tooltip + * @default 215 + */ + tooltipWidth?: number; +} + +export const ListItemOption = ({ + children, + disabledOptions, + item, + maxHeight, + props, + selected, +}: ListItemProps) => { + const { className, onClick, ...rest } = props; + const isItemOptionDisabled = Boolean(disabledOptions); + const itemOptionDisabledReason = disabledOptions?.reason; + + return ( + + + isItemOptionDisabled + ? e.preventDefault() + : onClick + ? onClick(e) + : null + } + style={{ + display: 'flex', + justifyContent: 'space-between', + maxHeight, + }} + aria-disabled={undefined} + data-qa-disabled-item={isItemOptionDisabled} + > + {children} + {isItemOptionDisabled && ( + {itemOptionDisabledReason} + )} + {selected && } + + + ); +}; + +export const StyledDisabledItem = styled(ListItem, { + label: 'StyledDisabledItem', +})(() => ({ + '&.Mui-disabled': { + cursor: 'not-allowed', + }, + '&.MuiAutocomplete-option': { + minHeight: 'auto !important', + padding: '8px 10px !important', + }, + '&.MuiListItem-root[aria-disabled="true"]:active': { + pointerEvents: 'none !important', + }, +})); diff --git a/packages/manager/src/components/LongviewLineGraph/LongviewLineGraph.tsx b/packages/manager/src/components/LongviewLineGraph/LongviewLineGraph.tsx index 7bf5cf630d6..67551fdbdf2 100644 --- a/packages/manager/src/components/LongviewLineGraph/LongviewLineGraph.tsx +++ b/packages/manager/src/components/LongviewLineGraph/LongviewLineGraph.tsx @@ -1,15 +1,16 @@ -import { Theme } from '@mui/material/styles'; +import { Divider } from '@linode/ui'; import * as React from 'react'; import { makeStyles } from 'tss-react/mui'; -import { Divider } from 'src/components/Divider'; import { ErrorState } from 'src/components/ErrorState/ErrorState'; -import { +import { LineGraph } from 'src/components/LineGraph/LineGraph'; +import { Typography } from 'src/components/Typography'; + +import type { Theme } from '@mui/material/styles'; +import type { DataSet, - LineGraph, LineGraphProps, } from 'src/components/LineGraph/LineGraph'; -import { Typography } from 'src/components/Typography'; const useStyles = makeStyles()((theme: Theme) => ({ message: { diff --git a/packages/manager/src/components/MaintenanceBanner/MaintenanceBanner.tsx b/packages/manager/src/components/MaintenanceBanner/MaintenanceBanner.tsx index c01acbaf9ba..2c77c1d38f9 100644 --- a/packages/manager/src/components/MaintenanceBanner/MaintenanceBanner.tsx +++ b/packages/manager/src/components/MaintenanceBanner/MaintenanceBanner.tsx @@ -1,14 +1,15 @@ -import { AccountMaintenance } from '@linode/api-v4/lib/account'; +import { Notice } from '@linode/ui'; import * as React from 'react'; import { Link } from 'react-router-dom'; -import { Notice } from 'src/components/Notice/Notice'; import { Typography } from 'src/components/Typography'; import { useAllAccountMaintenanceQuery } from 'src/queries/account/maintenance'; import { useProfile } from 'src/queries/profile/profile'; import { formatDate } from 'src/utilities/formatDate'; import { isPast } from 'src/utilities/isPast'; +import type { AccountMaintenance } from '@linode/api-v4/lib/account'; + interface Props { maintenanceEnd?: null | string; /** please keep in mind here that it's possible the start time can be in the past */ diff --git a/packages/manager/src/components/MaintenanceScreen.tsx b/packages/manager/src/components/MaintenanceScreen.tsx index 03d1c85efae..d6fd0abfc96 100644 --- a/packages/manager/src/components/MaintenanceScreen.tsx +++ b/packages/manager/src/components/MaintenanceScreen.tsx @@ -1,3 +1,4 @@ +import { Stack } from '@linode/ui'; import { Box } from '@linode/ui'; import BuildIcon from '@mui/icons-material/Build'; import { useTheme } from '@mui/material/styles'; @@ -6,7 +7,6 @@ import * as React from 'react'; import Logo from 'src/assets/logo/akamai-logo.svg'; import { ErrorState } from 'src/components/ErrorState/ErrorState'; import { Link } from 'src/components/Link'; -import { Stack } from 'src/components/Stack'; import { Typography } from 'src/components/Typography'; import type { Theme } from '@mui/material/styles'; diff --git a/packages/manager/src/components/MaskableText/MaskableText.tsx b/packages/manager/src/components/MaskableText/MaskableText.tsx index ac0b8ccd68e..7f9b395fc8e 100644 --- a/packages/manager/src/components/MaskableText/MaskableText.tsx +++ b/packages/manager/src/components/MaskableText/MaskableText.tsx @@ -1,12 +1,10 @@ -import { VisibilityTooltip } from '@linode/ui'; +import { Stack, VisibilityTooltip } from '@linode/ui'; import { Typography } from '@mui/material'; import * as React from 'react'; import { usePreferences } from 'src/queries/profile/preferences'; import { createMaskedText } from 'src/utilities/createMaskedText'; -import { Stack } from '../Stack'; - export type MaskableTextLength = 'ipv4' | 'ipv6' | 'plaintext'; export interface MaskableTextProps { diff --git a/packages/manager/src/components/MultipleIPInput/MultipleIPInput.tsx b/packages/manager/src/components/MultipleIPInput/MultipleIPInput.tsx index e96367d4b1d..39e9e4939d0 100644 --- a/packages/manager/src/components/MultipleIPInput/MultipleIPInput.tsx +++ b/packages/manager/src/components/MultipleIPInput/MultipleIPInput.tsx @@ -1,4 +1,4 @@ -import { InputLabel } from '@linode/ui'; +import { InputLabel, Notice } from '@linode/ui'; import Close from '@mui/icons-material/Close'; import Grid from '@mui/material/Unstable_Grid2'; import * as React from 'react'; @@ -6,7 +6,6 @@ import { makeStyles } from 'tss-react/mui'; import { Button } from 'src/components/Button/Button'; import { LinkButton } from 'src/components/LinkButton'; -import { Notice } from 'src/components/Notice/Notice'; import { StyledLinkButtonBox } from 'src/components/SelectFirewallPanel/SelectFirewallPanel'; import { TextField } from 'src/components/TextField'; import { TooltipIcon } from 'src/components/TooltipIcon'; diff --git a/packages/manager/src/components/PasswordInput/PasswordInput.tsx b/packages/manager/src/components/PasswordInput/PasswordInput.tsx index 1168895d2f0..9c7f05f5677 100644 --- a/packages/manager/src/components/PasswordInput/PasswordInput.tsx +++ b/packages/manager/src/components/PasswordInput/PasswordInput.tsx @@ -1,8 +1,8 @@ +import { Stack } from '@linode/ui'; import * as React from 'react'; import zxcvbn from 'zxcvbn'; import { StrengthIndicator } from '../PasswordInput/StrengthIndicator'; -import { Stack } from '../Stack'; import { HideShowText } from './HideShowText'; import type { TextFieldProps } from 'src/components/TextField'; diff --git a/packages/manager/src/components/PlacementGroupsSelect/PlacementGroupSelectOption.tsx b/packages/manager/src/components/PlacementGroupsSelect/PlacementGroupSelectOption.tsx index f3e920c75b0..5e5904431ba 100644 --- a/packages/manager/src/components/PlacementGroupsSelect/PlacementGroupSelectOption.tsx +++ b/packages/manager/src/components/PlacementGroupsSelect/PlacementGroupSelectOption.tsx @@ -1,89 +1,38 @@ import { PLACEMENT_GROUP_TYPES } from '@linode/api-v4'; -import { Box, Tooltip } from '@linode/ui'; -import { visuallyHidden } from '@mui/utils'; +import { Box, Stack } from '@linode/ui'; import React from 'react'; -import { Stack } from 'src/components/Stack'; -import { PLACEMENT_GROUP_HAS_NO_CAPACITY } from 'src/features/PlacementGroups/constants'; - -import { - SelectedIcon, - StyledListItem, -} from '../RegionSelect/RegionSelect.styles'; +import { ListItemOption } from 'src/components/ListItemOption'; import type { PlacementGroup } from '@linode/api-v4'; -import type { ListItemComponentsPropsOverrides } from '@mui/material/ListItem'; - -interface PlacementGroupSelectOptionProps { - disabled?: boolean; - label: string; - props: React.HTMLAttributes; - selected?: boolean; - value: PlacementGroup; -} +import type { ListItemProps } from 'src/components/ListItemOption'; export const PlacementGroupSelectOption = ({ - disabled, - label, + disabledOptions, + item, props, selected, - value, -}: PlacementGroupSelectOptionProps) => { - return ( - - - disabled - ? e.preventDefault() - : props.onClick - ? props.onClick(e) - : null - } - aria-disabled={undefined} - > - - - {label} - - - ({PLACEMENT_GROUP_TYPES[value.placement_group_type]}) - - - {disabled && ( - {`Option disabled: ${PLACEMENT_GROUP_HAS_NO_CAPACITY}`} - )} - - {selected && } - - - ); -}; +}: ListItemProps) => ( + + + + {item.label} + + + ({PLACEMENT_GROUP_TYPES[item.placement_group_type]}) + + + + +); diff --git a/packages/manager/src/components/PlacementGroupsSelect/PlacementGroupsSelect.test.tsx b/packages/manager/src/components/PlacementGroupsSelect/PlacementGroupsSelect.test.tsx index e1b25164191..b8c47c37502 100644 --- a/packages/manager/src/components/PlacementGroupsSelect/PlacementGroupsSelect.test.tsx +++ b/packages/manager/src/components/PlacementGroupsSelect/PlacementGroupsSelect.test.tsx @@ -106,8 +106,6 @@ describe('PlacementGroupSelect', () => { const selectedRegionOption = getByText('my-placement-group'); fireEvent.click(selectedRegionOption); - expect( - getByText(`Option disabled: ${PLACEMENT_GROUP_HAS_NO_CAPACITY}`) - ).toBeVisible(); + expect(getByText(PLACEMENT_GROUP_HAS_NO_CAPACITY)).toBeVisible(); }); }); diff --git a/packages/manager/src/components/PlacementGroupsSelect/PlacementGroupsSelect.tsx b/packages/manager/src/components/PlacementGroupsSelect/PlacementGroupsSelect.tsx index 6118c431f1f..9d9b90f96b1 100644 --- a/packages/manager/src/components/PlacementGroupsSelect/PlacementGroupsSelect.tsx +++ b/packages/manager/src/components/PlacementGroupsSelect/PlacementGroupsSelect.tsx @@ -1,6 +1,7 @@ import * as React from 'react'; import { Autocomplete } from 'src/components/Autocomplete/Autocomplete'; +import { PLACEMENT_GROUP_HAS_NO_CAPACITY } from 'src/features/PlacementGroups/constants'; import { hasPlacementGroupReachedCapacity } from 'src/features/PlacementGroups/utils'; import { useAllPlacementGroupsQuery } from 'src/queries/placementGroups'; @@ -107,12 +108,15 @@ export const PlacementGroupsSelect = (props: PlacementGroupsSelectProps) => { return ( ); }} diff --git a/packages/manager/src/components/PrimaryNav/NavItem.tsx b/packages/manager/src/components/PrimaryNav/NavItem.tsx index 4e210b5f4ca..b42ac1ebe7a 100644 --- a/packages/manager/src/components/PrimaryNav/NavItem.tsx +++ b/packages/manager/src/components/PrimaryNav/NavItem.tsx @@ -1,9 +1,8 @@ -import { Tooltip } from '@linode/ui'; +import { Divider, Tooltip } from '@linode/ui'; import * as React from 'react'; import { Link } from 'react-router-dom'; import { useStyles } from 'tss-react/mui'; -import { Divider } from 'src/components/Divider'; import { ListItem } from 'src/components/ListItem'; import { ListItemText } from 'src/components/ListItemText'; diff --git a/packages/manager/src/components/PrimaryNav/PrimaryNav.styles.ts b/packages/manager/src/components/PrimaryNav/PrimaryNav.styles.ts index 69b998cfd4a..54c0316b385 100644 --- a/packages/manager/src/components/PrimaryNav/PrimaryNav.styles.ts +++ b/packages/manager/src/components/PrimaryNav/PrimaryNav.styles.ts @@ -1,11 +1,10 @@ -import { Box, omittedProps } from '@linode/ui'; +import { Box, Divider, omittedProps } from '@linode/ui'; import { styled } from '@mui/material/styles'; import Grid from '@mui/material/Unstable_Grid2'; import { Link } from 'react-router-dom'; import AkamaiLogo from 'src/assets/logo/akamai-logo.svg'; import { Accordion } from 'src/components/Accordion'; -import { Divider } from 'src/components/Divider'; import { SIDEBAR_WIDTH } from 'src/components/PrimaryNav/SideMenu'; export const StyledGrid = styled(Grid, { diff --git a/packages/manager/src/components/ProductInformationBanner/ProductInformationBanner.tsx b/packages/manager/src/components/ProductInformationBanner/ProductInformationBanner.tsx index 43ca759db6e..b681403808a 100644 --- a/packages/manager/src/components/ProductInformationBanner/ProductInformationBanner.tsx +++ b/packages/manager/src/components/ProductInformationBanner/ProductInformationBanner.tsx @@ -2,13 +2,13 @@ import * as React from 'react'; import { HighlightedMarkdown } from 'src/components/HighlightedMarkdown/HighlightedMarkdown'; import { reportException } from 'src/exceptionReporting'; -import { ProductInformationBannerLocation } from 'src/featureFlags'; import { useFlags } from 'src/hooks/useFlags'; import { isAfter } from 'src/utilities/date'; import { DismissibleBanner } from '../DismissibleBanner/DismissibleBanner'; -import type { NoticeProps } from 'src/components/Notice/Notice'; +import type { NoticeProps } from '@linode/ui'; +import type { ProductInformationBannerLocation } from 'src/featureFlags'; interface Props { bannerLocation: ProductInformationBannerLocation; diff --git a/packages/manager/src/components/ProductNotification/ProductNotification.tsx b/packages/manager/src/components/ProductNotification/ProductNotification.tsx index 0ee8d6eb8f0..d15bbd83c43 100644 --- a/packages/manager/src/components/ProductNotification/ProductNotification.tsx +++ b/packages/manager/src/components/ProductNotification/ProductNotification.tsx @@ -1,6 +1,7 @@ +import { Notice } from '@linode/ui'; import * as React from 'react'; -import { Notice, NoticeVariant } from 'src/components/Notice/Notice'; +import type { NoticeVariant } from '@linode/ui'; export interface ProductNotificationProps { onClick?: () => void; diff --git a/packages/manager/src/components/RegionSelect/RegionMultiSelect.tsx b/packages/manager/src/components/RegionSelect/RegionMultiSelect.tsx index 0bdf1469232..fffdca2ea64 100644 --- a/packages/manager/src/components/RegionSelect/RegionMultiSelect.tsx +++ b/packages/manager/src/components/RegionSelect/RegionMultiSelect.tsx @@ -1,3 +1,4 @@ +import { Stack } from '@linode/ui'; import CloseIcon from '@mui/icons-material/Close'; import React from 'react'; @@ -8,7 +9,6 @@ import { useAllAccountAvailabilitiesQuery } from 'src/queries/account/availabili import { getRegionCountryGroup } from 'src/utilities/formatRegion'; import { StyledListItem } from '../Autocomplete/Autocomplete.styles'; -import { Stack } from '../Stack'; import { RegionOption } from './RegionOption'; import { StyledAutocompleteContainer } from './RegionSelect.styles'; import { @@ -16,11 +16,9 @@ import { isRegionOptionUnavailable, } from './RegionSelect.utils'; -import type { - DisableRegionOption, - RegionMultiSelectProps, -} from './RegionSelect.types'; +import type { RegionMultiSelectProps } from './RegionSelect.types'; import type { Region } from '@linode/api-v4'; +import type { DisableItemOption } from 'src/components/ListItemOption'; interface RegionChipLabelProps { region: Region; @@ -71,7 +69,7 @@ export const RegionMultiSelect = React.memo((props: RegionMultiSelectProps) => { }; const disabledRegions = regionOptions.reduce< - Record + Record >((acc, region) => { if (disabledRegionsFromProps?.[region.id]) { acc[region.id] = disabledRegionsFromProps[region.id]; @@ -120,9 +118,9 @@ export const RegionMultiSelect = React.memo((props: RegionMultiSelectProps) => { return ( ); diff --git a/packages/manager/src/components/RegionSelect/RegionOption.tsx b/packages/manager/src/components/RegionSelect/RegionOption.tsx index efbe78c12cb..d3be0d72e22 100644 --- a/packages/manager/src/components/RegionSelect/RegionOption.tsx +++ b/packages/manager/src/components/RegionSelect/RegionOption.tsx @@ -1,101 +1,34 @@ -import { Box, Tooltip } from '@linode/ui'; -import { visuallyHidden } from '@mui/utils'; +import { Box, Stack } from '@linode/ui'; import React from 'react'; -import DistributedRegion from 'src/assets/icons/entityIcons/distributed-region.svg'; import { Flag } from 'src/components/Flag'; +import { ListItemOption } from 'src/components/ListItemOption'; import { useIsGeckoEnabled } from 'src/components/RegionSelect/RegionSelect.utils'; -import { Stack } from 'src/components/Stack'; -import { TooltipIcon } from 'src/components/TooltipIcon'; -import { - SelectedIcon, - StyledListItem, - sxDistributedRegionIcon, -} from './RegionSelect.styles'; - -import type { DisableRegionOption } from './RegionSelect.types'; import type { Region } from '@linode/api-v4'; -import type { ListItemComponentsPropsOverrides } from '@mui/material/ListItem'; - -interface Props { - disabledOptions?: DisableRegionOption; - props: React.HTMLAttributes; - region: Region; - selected?: boolean; -} +import type { ListItemProps } from 'src/components/ListItemOption'; export const RegionOption = ({ disabledOptions, + item, props, - region, selected, -}: Props) => { - const { className, onClick } = props; - const isRegionDisabled = Boolean(disabledOptions); - const isRegionDisabledReason = disabledOptions?.reason; - const { isGeckoBetaEnabled, isGeckoLAEnabled } = useIsGeckoEnabled(); - const displayDistributedRegionIcon = - isGeckoBetaEnabled && region.site_type === 'distributed'; +}: ListItemProps) => { + const { isGeckoLAEnabled } = useIsGeckoEnabled(); return ( - - - isRegionDisabled ? e.preventDefault() : onClick ? onClick(e) : null - } - aria-disabled={undefined} - className={isRegionDisabled ? `${className} Mui-disabled` : className} - data-qa-disabled-item={isRegionDisabled} - > - - - {isGeckoLAEnabled ? region.label : `${region.label} (${region.id})`} - {displayDistributedRegionIcon && ( - -  (This region is a distributed region.) - - )} - {isRegionDisabled && isRegionDisabledReason && ( - {isRegionDisabledReason} - )} - - {isGeckoLAEnabled && `(${region.id})`} - {selected && } - {displayDistributedRegionIcon && ( - } - status="other" - sxTooltipIcon={sxDistributedRegionIcon} - text="This region is a distributed region." - /> - )} - - - + + + {isGeckoLAEnabled ? item.label : `${item.label} (${item.id})`} + + {isGeckoLAEnabled && `(${item.id})`} + + ); }; diff --git a/packages/manager/src/components/RegionSelect/RegionSelect.styles.ts b/packages/manager/src/components/RegionSelect/RegionSelect.styles.ts index b6af8c5dffc..46605c20261 100644 --- a/packages/manager/src/components/RegionSelect/RegionSelect.styles.ts +++ b/packages/manager/src/components/RegionSelect/RegionSelect.styles.ts @@ -1,5 +1,4 @@ import { Box } from '@linode/ui'; -import DoneIcon from '@mui/icons-material/Done'; import { styled } from '@mui/material/styles'; import { Chip } from 'src/components/Chip'; @@ -30,44 +29,6 @@ export const StyledAutocompleteContainer = styled(Box, { }, })); -export const sxDistributedRegionIcon = { - '& svg': { - color: 'inherit !important', - height: 21, - width: 24, - }, - '&:hover': { - color: 'inherit', - }, - color: 'inherit', - padding: 0, -}; - -export const StyledDistributedRegionBox = styled(Box, { - label: 'StyledDistributedRegionBox', - shouldForwardProp: (prop) => prop != 'centerChildren', -})<{ centerChildren: boolean }>(({ centerChildren, theme }) => ({ - '& svg': { - height: 21, - marginLeft: 8, - marginRight: 8, - width: 24, - }, - alignSelf: centerChildren ? 'center' : 'end', - color: 'inherit', - display: 'flex', - marginTop: centerChildren ? 21 : 0, - padding: 8, - [theme.breakpoints.down('md')]: { - '& svg': { - marginLeft: 0, - }, - alignSelf: 'start', - marginTop: 0, - paddingLeft: 0, - }, -})); - export const StyledLParentListItem = styled(ListItem, { label: 'RegionSelectParentListItem', })(() => ({ @@ -80,32 +41,6 @@ export const StyledLParentListItem = styled(ListItem, { }, })); -export const StyledListItem = styled(ListItem, { - label: 'RegionSelectListItem', -})(() => ({ - '&.Mui-disabled': { - cursor: 'not-allowed', - }, - '&.MuiAutocomplete-option': { - minHeight: 'auto !important', - padding: '8px 10px !important', - }, - '&.MuiListItem-root[aria-disabled="true"]:active': { - pointerEvents: 'none !important', - }, -})); - -export const SelectedIcon = styled(DoneIcon, { - label: 'RegionSelectSelectedIcon', - shouldForwardProp: (prop) => prop != 'visible', -})<{ visible: boolean }>(({ visible }) => ({ - height: 17, - marginLeft: '-2px', - marginRight: '5px', - visibility: visible ? 'visible' : 'hidden', - width: 17, -})); - export const StyledChip = styled(Chip)(({ theme }) => ({ '& .MuiChip-deleteIcon': { '& svg': { diff --git a/packages/manager/src/components/RegionSelect/RegionSelect.test.tsx b/packages/manager/src/components/RegionSelect/RegionSelect.test.tsx index bd97e2a64a1..3f6721f2ac6 100644 --- a/packages/manager/src/components/RegionSelect/RegionSelect.test.tsx +++ b/packages/manager/src/components/RegionSelect/RegionSelect.test.tsx @@ -64,26 +64,4 @@ describe('RegionSelect', () => { ); expect(getByTestId('textfield-input')).toBeDisabled(); }); - - it('should render a Select component with distributed region text', () => { - const newProps = { - ...props, - showDistributedRegionIconHelperText: true, - }; - const { getByTestId } = renderWithTheme(); - expect( - getByTestId('region-select-distributed-region-text') - ).toBeInTheDocument(); - }); - - it('should render a Select component with no distributed region text', () => { - const newProps = { - ...props, - showDistributedRegionIconHelperText: false, - }; - const { queryByTestId } = renderWithTheme(); - expect( - queryByTestId('region-select-distributed-region-text') - ).not.toBeInTheDocument(); - }); }); diff --git a/packages/manager/src/components/RegionSelect/RegionSelect.tsx b/packages/manager/src/components/RegionSelect/RegionSelect.tsx index 49650ddee1d..b719eb824fd 100644 --- a/packages/manager/src/components/RegionSelect/RegionSelect.tsx +++ b/packages/manager/src/components/RegionSelect/RegionSelect.tsx @@ -1,32 +1,22 @@ -import { Typography } from '@mui/material'; import { createFilterOptions } from '@mui/material/Autocomplete'; import * as React from 'react'; -import DistributedRegion from 'src/assets/icons/entityIcons/distributed-region.svg'; import { Autocomplete } from 'src/components/Autocomplete/Autocomplete'; import { Flag } from 'src/components/Flag'; -import { Link } from 'src/components/Link'; import { useIsGeckoEnabled } from 'src/components/RegionSelect/RegionSelect.utils'; -import { TooltipIcon } from 'src/components/TooltipIcon'; import { useAllAccountAvailabilitiesQuery } from 'src/queries/account/availability'; import { getRegionCountryGroup } from 'src/utilities/formatRegion'; import { RegionOption } from './RegionOption'; -import { - StyledAutocompleteContainer, - StyledDistributedRegionBox, - sxDistributedRegionIcon, -} from './RegionSelect.styles'; +import { StyledAutocompleteContainer } from './RegionSelect.styles'; import { getRegionOptions, isRegionOptionUnavailable, } from './RegionSelect.utils'; -import type { - DisableRegionOption, - RegionSelectProps, -} from './RegionSelect.types'; +import type { RegionSelectProps } from './RegionSelect.types'; import type { Region } from '@linode/api-v4'; +import type { DisableItemOption } from 'src/components/ListItemOption'; /** * A specific select for regions. @@ -57,13 +47,12 @@ export const RegionSelect = < regionFilter, regions, required, - showDistributedRegionIconHelperText, tooltipText, value, width, } = props; - const { isGeckoBetaEnabled, isGeckoLAEnabled } = useIsGeckoEnabled(); + const { isGeckoLAEnabled } = useIsGeckoEnabled(); const { data: accountAvailability, @@ -81,7 +70,7 @@ export const RegionSelect = < : null; const disabledRegions = regionOptions.reduce< - Record + Record >((acc, region) => { if (disabledRegionsFromProps?.[region.id]) { acc[region.id] = disabledRegionsFromProps[region.id]; @@ -102,24 +91,6 @@ export const RegionSelect = < return acc; }, {}); - const EndAdornment = React.useMemo(() => { - // @TODO Gecko: Remove adornment after LA - if (isGeckoBetaEnabled && selectedRegion?.site_type === 'distributed') { - return ( - } - status="other" - sxTooltipIcon={sxDistributedRegionIcon} - text="This region is a distributed region." - /> - ); - } - if (isGeckoLAEnabled && selectedRegion) { - return `(${selectedRegion?.id})`; - } - return null; - }, [isGeckoBetaEnabled, isGeckoLAEnabled, selectedRegion]); - /* * When Gecko is enabled, allow regions to be searched by ID by passing a * custom stringify function. @@ -142,9 +113,9 @@ export const RegionSelect = < return ( ); }} @@ -156,7 +127,8 @@ export const RegionSelect = < textFieldProps={{ ...props.textFieldProps, InputProps: { - endAdornment: EndAdornment, + endAdornment: + isGeckoLAEnabled && selectedRegion && `(${selectedRegion?.id})`, required, startAdornment: selectedRegion && ( @@ -184,25 +156,6 @@ export const RegionSelect = < placeholder={placeholder ?? 'Select a Region'} value={selectedRegion as Region} /> - {showDistributedRegionIconHelperText && ( // @TODO Gecko Beta: Add docs link - - - - {' '} - Indicates a distributed region.{' '} - - Learn more - - . - - - )} ); }; diff --git a/packages/manager/src/components/RegionSelect/RegionSelect.types.ts b/packages/manager/src/components/RegionSelect/RegionSelect.types.ts index 8c46d66c574..87a9b6b9344 100644 --- a/packages/manager/src/components/RegionSelect/RegionSelect.types.ts +++ b/packages/manager/src/components/RegionSelect/RegionSelect.types.ts @@ -6,19 +6,7 @@ import type { } from '@linode/api-v4'; import type React from 'react'; import type { EnhancedAutocompleteProps } from 'src/components/Autocomplete/Autocomplete'; - -export interface DisableRegionOption { - /** - * The reason the region option is disabled. - * This is shown to the user as a tooltip. - */ - reason: JSX.Element | string; - /** - * An optional minWith applied to the tooltip - * @default 215 - */ - tooltipWidth?: number; -} +import type { DisableItemOption } from 'src/components/ListItemOption'; export type RegionFilterValue = | 'distributed-AF' @@ -49,7 +37,7 @@ export interface RegionSelectProps< /** * A key/value object for disabling regions by their ID. */ - disabledRegions?: Record; + disabledRegions?: Record; helperText?: string; /** * Ignores account availability information when rendering region options @@ -60,7 +48,6 @@ export interface RegionSelectProps< regionFilter?: RegionFilterValue; regions: Region[]; required?: boolean; - showDistributedRegionIconHelperText?: boolean; tooltipText?: string; /** * The ID of the selected region. @@ -79,7 +66,7 @@ export interface RegionMultiSelectProps selectedRegions: Region[]; }>; currentCapability: Capabilities | undefined; - disabledRegions?: Record; + disabledRegions?: Record; helperText?: string; isClearable?: boolean; label?: string; diff --git a/packages/manager/src/components/SelectFirewallPanel/SelectFirewallPanel.tsx b/packages/manager/src/components/SelectFirewallPanel/SelectFirewallPanel.tsx index 0c8e7a6ac1f..ce3198c04c4 100644 --- a/packages/manager/src/components/SelectFirewallPanel/SelectFirewallPanel.tsx +++ b/packages/manager/src/components/SelectFirewallPanel/SelectFirewallPanel.tsx @@ -1,8 +1,7 @@ -import { Box, Paper } from '@linode/ui'; +import { Box, Paper, Stack } from '@linode/ui'; import { styled } from '@mui/material/styles'; import * as React from 'react'; -import { Stack } from 'src/components/Stack'; import { Typography } from 'src/components/Typography'; import { CreateFirewallDrawer } from 'src/features/Firewalls/FirewallLanding/CreateFirewallDrawer'; import { useFlags } from 'src/hooks/useFlags'; diff --git a/packages/manager/src/components/SelectionCard/CardBase.tsx b/packages/manager/src/components/SelectionCard/CardBase.tsx index 09bb450ec65..d30d3943694 100644 --- a/packages/manager/src/components/SelectionCard/CardBase.tsx +++ b/packages/manager/src/components/SelectionCard/CardBase.tsx @@ -1,5 +1,7 @@ import * as React from 'react'; +import { useFlags } from 'src/hooks/useFlags'; + import { CardBaseGrid, CardBaseHeading, @@ -36,6 +38,18 @@ export const CardBase = (props: CardBaseProps) => { sxSubheading, } = props; + const flags = useFlags(); + + const isDatabaseCreateFlow = location.pathname.includes('/databases/create'); + const isDatabaseResizeFlow = + location.pathname.match(/\/databases\/.*\/(\d+\/resize)/)?.[0] === + location.pathname; + + const isDatabaseGA = + !flags.dbaasV2?.beta && + flags.dbaasV2?.enabled && + (isDatabaseCreateFlow || isDatabaseResizeFlow); + const renderSubheadings = subheadings.map((subheading, idx) => { const subHeadingIsString = typeof subheading === 'string'; @@ -46,7 +60,9 @@ export const CardBase = (props: CardBaseProps) => { key={idx} sx={sxSubheading} > - {subheading} + {subHeadingIsString && isDatabaseGA + ? subheading?.replace('Storage', 'Usable Storage') + : subheading} ); }); diff --git a/packages/manager/src/components/Snackbar/ToastNotifications.stories.tsx b/packages/manager/src/components/Snackbar/ToastNotifications.stories.tsx index 0d66a284d73..c7d2f1f2aef 100644 --- a/packages/manager/src/components/Snackbar/ToastNotifications.stories.tsx +++ b/packages/manager/src/components/Snackbar/ToastNotifications.stories.tsx @@ -1,3 +1,4 @@ +import { Stack } from '@linode/ui'; import { useSnackbar } from 'notistack'; import React from 'react'; @@ -5,8 +6,6 @@ import { Button } from 'src/components/Button/Button'; import { Snackbar } from 'src/components/Snackbar/Snackbar'; import { getEventMessage } from 'src/features/Events/utils'; -import { Stack } from '../Stack'; - import type { Meta, StoryObj } from '@storybook/react'; import type { VariantType } from 'notistack'; diff --git a/packages/manager/src/components/StackScript/StackScript.tsx b/packages/manager/src/components/StackScript/StackScript.tsx index 2951c34ee34..7ae7824d2f8 100644 --- a/packages/manager/src/components/StackScript/StackScript.tsx +++ b/packages/manager/src/components/StackScript/StackScript.tsx @@ -1,4 +1,4 @@ -import { Box } from '@linode/ui'; +import { Box, Divider } from '@linode/ui'; import { useTheme } from '@mui/material/styles'; import * as React from 'react'; import { Link, useHistory } from 'react-router-dom'; @@ -8,7 +8,6 @@ import { Button } from 'src/components/Button/Button'; import { Chip } from 'src/components/Chip'; import { CopyTooltip } from 'src/components/CopyTooltip/CopyTooltip'; import { DateTimeDisplay } from 'src/components/DateTimeDisplay'; -import { Divider } from 'src/components/Divider'; import { H1Header } from 'src/components/H1Header/H1Header'; import { ScriptCode } from 'src/components/ScriptCode/ScriptCode'; import { Typography } from 'src/components/Typography'; diff --git a/packages/manager/src/components/TabbedPanel/TabbedPanel.tsx b/packages/manager/src/components/TabbedPanel/TabbedPanel.tsx index 8393e3cbde1..5a678a2b89b 100644 --- a/packages/manager/src/components/TabbedPanel/TabbedPanel.tsx +++ b/packages/manager/src/components/TabbedPanel/TabbedPanel.tsx @@ -1,9 +1,8 @@ -import { Box, Paper, Tooltip } from '@linode/ui'; +import { Box, Notice, Paper, Tooltip } from '@linode/ui'; import HelpOutline from '@mui/icons-material/HelpOutline'; import { styled } from '@mui/material/styles'; import React, { useEffect, useState } from 'react'; -import { Notice } from 'src/components/Notice/Notice'; import { Tab } from 'src/components/Tabs/Tab'; import { TabList } from 'src/components/Tabs/TabList'; import { TabPanel } from 'src/components/Tabs/TabPanel'; diff --git a/packages/manager/src/components/TableCell/TableCell.tsx b/packages/manager/src/components/TableCell/TableCell.tsx index 159b10fcdde..f30c4a116dc 100644 --- a/packages/manager/src/components/TableCell/TableCell.tsx +++ b/packages/manager/src/components/TableCell/TableCell.tsx @@ -1,13 +1,12 @@ -import { - default as _TableCell, - TableCellProps as _TableCellProps, -} from '@mui/material/TableCell'; -import { Theme } from '@mui/material/styles'; +import { default as _TableCell } from '@mui/material/TableCell'; import * as React from 'react'; import { makeStyles } from 'tss-react/mui'; import { TooltipIcon } from 'src/components/TooltipIcon'; +import type { Theme } from '@mui/material/styles'; +import type { TableCellProps as _TableCellProps } from '@mui/material/TableCell'; + const useStyles = makeStyles()((theme: Theme) => ({ actionCell: { textAlign: 'right', @@ -106,7 +105,11 @@ export const TableCell = (props: TableCellProps) => { [classes.root]: true, [classes.sortable]: sortable, // hide the cell at small breakpoints if it's empty with no parent column - emptyCell: !parentColumn && !props.children, + emptyCell: + (!parentColumn && !props.children) || + (!parentColumn && + Array.isArray(props.children) && + !props.children[0]), }, className )} diff --git a/packages/manager/src/components/TextField.tsx b/packages/manager/src/components/TextField.tsx index da82c2b3bbc..41119007223 100644 --- a/packages/manager/src/components/TextField.tsx +++ b/packages/manager/src/components/TextField.tsx @@ -266,6 +266,7 @@ export const TextField = (props: TextFieldProps) => { display: 'flex', flexWrap: 'wrap', }), + ...containerProps?.sx, }} > { ...(Boolean(tooltipText) && { width: '415px', }), + ...props.sx, }} className={className} error={!!error || !!errorText} diff --git a/packages/manager/src/components/Tile/Tile.tsx b/packages/manager/src/components/Tile/Tile.tsx index b717753b230..fd7e48ee97f 100644 --- a/packages/manager/src/components/Tile/Tile.tsx +++ b/packages/manager/src/components/Tile/Tile.tsx @@ -1,8 +1,8 @@ +import { Notice } from '@linode/ui'; import Button from '@mui/material/Button'; import * as React from 'react'; import { Link } from 'src/components/Link'; -import { Notice } from 'src/components/Notice/Notice'; import { Typography } from 'src/components/Typography'; import { useStyles } from './Tile.styles'; diff --git a/packages/manager/src/components/TooltipIcon.tsx b/packages/manager/src/components/TooltipIcon.tsx index b5ad2776429..24f504d5bb5 100644 --- a/packages/manager/src/components/TooltipIcon.tsx +++ b/packages/manager/src/components/TooltipIcon.tsx @@ -11,7 +11,7 @@ import * as React from 'react'; import type { TooltipProps } from '@linode/ui'; import type { SxProps, Theme } from '@mui/material/styles'; -type TooltipIconStatus = +export type TooltipIconStatus = | 'error' | 'help' | 'info' diff --git a/packages/manager/src/components/TransferDisplay/TransferDisplayDialog.tsx b/packages/manager/src/components/TransferDisplay/TransferDisplayDialog.tsx index e5ad1ec0225..3b50311095b 100644 --- a/packages/manager/src/components/TransferDisplay/TransferDisplayDialog.tsx +++ b/packages/manager/src/components/TransferDisplay/TransferDisplayDialog.tsx @@ -1,10 +1,9 @@ -import { Box } from '@linode/ui'; +import { Box, Divider } from '@linode/ui'; import { useTheme } from '@mui/material/styles'; import { styled } from '@mui/material/styles'; import * as React from 'react'; import { Dialog } from 'src/components/Dialog/Dialog'; -import { Divider } from 'src/components/Divider'; import { Link } from 'src/components/Link'; import { Typography } from 'src/components/Typography'; diff --git a/packages/manager/src/components/Uploaders/ImageUploader/ImageUploader.tsx b/packages/manager/src/components/Uploaders/ImageUploader/ImageUploader.tsx index e5dc1d7121f..30c41276507 100644 --- a/packages/manager/src/components/Uploaders/ImageUploader/ImageUploader.tsx +++ b/packages/manager/src/components/Uploaders/ImageUploader/ImageUploader.tsx @@ -1,4 +1,4 @@ -import { Box } from '@linode/ui'; +import { Box, Stack } from '@linode/ui'; import { styled } from '@mui/material'; import { Duration } from 'luxon'; import * as React from 'react'; @@ -6,7 +6,6 @@ import { useDropzone } from 'react-dropzone'; import { BarPercent } from 'src/components/BarPercent'; import { Button } from 'src/components/Button/Button'; -import { Stack } from 'src/components/Stack'; import { Typography } from 'src/components/Typography'; import { MAX_FILE_SIZE_IN_BYTES } from 'src/components/Uploaders/reducer'; import { readableBytes } from 'src/utilities/unitConversions'; diff --git a/packages/manager/src/factories/databases.ts b/packages/manager/src/factories/databases.ts index 3877ef2a84a..a8cfd57cd1d 100644 --- a/packages/manager/src/factories/databases.ts +++ b/packages/manager/src/factories/databases.ts @@ -70,29 +70,6 @@ export const databaseTypeFactory = Factory.Sync.makeFactory({ class: 'standard', disk: Factory.each((i) => i * 20480), engines: { - mongodb: [ - { - price: { - hourly: 0.03, - monthly: 50, - }, - quantity: 1, - }, - { - price: { - hourly: 0.08, - monthly: 88, - }, - quantity: 2, - }, - { - price: { - hourly: 0.22, - monthly: 116, - }, - quantity: 3, - }, - ], mysql: [ { price: { @@ -139,29 +116,6 @@ export const databaseTypeFactory = Factory.Sync.makeFactory({ quantity: 3, }, ], - redis: [ - { - price: { - hourly: 0.08, - monthly: 180, - }, - quantity: 1, - }, - { - price: { - hourly: 0.16, - monthly: 360, - }, - quantity: 2, - }, - { - price: { - hourly: 0.32, - monthly: 540, - }, - quantity: 3, - }, - ], }, id: Factory.each((i) => possibleTypes[i % possibleTypes.length]), label: Factory.each((i) => `Linode ${i} GB`), @@ -254,7 +208,7 @@ export const databaseFactory = Factory.Sync.makeFactory({ '2.2.2.2': 'primary', }, oldest_restore_time: '2024-09-15T17:15:12', - platform: pickRandom(['rdbms-legacy', 'rdbms-default']), + platform: Factory.each((i) => (adb10(i) ? 'rdbms-legacy' : 'rdbms-default')), port: 3306, region: 'us-east', ssl_connection: false, diff --git a/packages/manager/src/featureFlags.ts b/packages/manager/src/featureFlags.ts index 9a92408132d..33b44d19c41 100644 --- a/packages/manager/src/featureFlags.ts +++ b/packages/manager/src/featureFlags.ts @@ -1,6 +1,6 @@ import type { OCA } from './features/OneClickApps/types'; import type { TPAProvider } from '@linode/api-v4/lib/profile'; -import type { NoticeVariant } from 'src/components/Notice/Notice'; +import type { NoticeVariant } from '@linode/ui'; // These flags should correspond with active features flags in LD @@ -72,6 +72,7 @@ export interface CloudPulseResourceTypeMapFlag { interface gpuV2 { egressBanner: boolean; planDivider: boolean; + transferBanner: boolean; } interface DesignUpdatesBannerFlag extends BaseFeatureFlag { diff --git a/packages/manager/src/features/Account/AccountLogins.tsx b/packages/manager/src/features/Account/AccountLogins.tsx index 7f44e77be56..f9fddc29fbb 100644 --- a/packages/manager/src/features/Account/AccountLogins.tsx +++ b/packages/manager/src/features/Account/AccountLogins.tsx @@ -1,8 +1,8 @@ +import { Notice } from '@linode/ui'; import * as React from 'react'; import { makeStyles } from 'tss-react/mui'; import { Hidden } from 'src/components/Hidden'; -import { Notice } from 'src/components/Notice/Notice'; import { PaginationFooter } from 'src/components/PaginationFooter/PaginationFooter'; import { Table } from 'src/components/Table'; import { TableBody } from 'src/components/TableBody'; diff --git a/packages/manager/src/features/Account/AutoBackups.tsx b/packages/manager/src/features/Account/AutoBackups.tsx index 0dd9a134ead..5386207805a 100644 --- a/packages/manager/src/features/Account/AutoBackups.tsx +++ b/packages/manager/src/features/Account/AutoBackups.tsx @@ -1,15 +1,16 @@ +import { Notice } from '@linode/ui'; import Grid from '@mui/material/Unstable_Grid2'; -import { Theme } from '@mui/material/styles'; import * as React from 'react'; import { makeStyles } from 'tss-react/mui'; import { Accordion } from 'src/components/Accordion'; import { FormControlLabel } from 'src/components/FormControlLabel'; import { Link } from 'src/components/Link'; -import { Notice } from 'src/components/Notice/Notice'; import { Toggle } from 'src/components/Toggle/Toggle'; import { Typography } from 'src/components/Typography'; +import type { Theme } from '@mui/material/styles'; + const useStyles = makeStyles()((theme: Theme) => ({ enableBackupsButton: { ...theme.applyLinkStyles, diff --git a/packages/manager/src/features/Account/CloseAccountDialog.tsx b/packages/manager/src/features/Account/CloseAccountDialog.tsx index 9513c701954..78226d57fd4 100644 --- a/packages/manager/src/features/Account/CloseAccountDialog.tsx +++ b/packages/manager/src/features/Account/CloseAccountDialog.tsx @@ -1,16 +1,18 @@ import { cancelAccount } from '@linode/api-v4/lib/account'; -import { APIError } from '@linode/api-v4/lib/types'; -import { Theme, styled } from '@mui/material/styles'; +import { Notice } from '@linode/ui'; +import { styled } from '@mui/material/styles'; import * as React from 'react'; import { useHistory } from 'react-router-dom'; import { makeStyles } from 'tss-react/mui'; -import { Notice } from 'src/components/Notice/Notice'; import { TextField } from 'src/components/TextField'; import { TypeToConfirmDialog } from 'src/components/TypeToConfirmDialog/TypeToConfirmDialog'; import { Typography } from 'src/components/Typography'; import { useProfile } from 'src/queries/profile/profile'; +import type { APIError } from '@linode/api-v4/lib/types'; +import type { Theme } from '@mui/material/styles'; + interface Props { closeDialog: () => void; open: boolean; diff --git a/packages/manager/src/features/Account/Maintenance/MaintenanceLanding.tsx b/packages/manager/src/features/Account/Maintenance/MaintenanceLanding.tsx index 634cd91be8d..7feb8689c43 100644 --- a/packages/manager/src/features/Account/Maintenance/MaintenanceLanding.tsx +++ b/packages/manager/src/features/Account/Maintenance/MaintenanceLanding.tsx @@ -1,7 +1,7 @@ +import { Stack } from '@linode/ui'; import * as React from 'react'; import { DocumentTitleSegment } from 'src/components/DocumentTitle'; -import { Stack } from 'src/components/Stack'; import { MaintenanceTable } from './MaintenanceTable'; diff --git a/packages/manager/src/features/Account/ObjectStorageSettings.tsx b/packages/manager/src/features/Account/ObjectStorageSettings.tsx index bbe8717ca9e..42b42cced98 100644 --- a/packages/manager/src/features/Account/ObjectStorageSettings.tsx +++ b/packages/manager/src/features/Account/ObjectStorageSettings.tsx @@ -1,4 +1,4 @@ -import { Box } from '@linode/ui'; +import { Box, Notice, Stack } from '@linode/ui'; import { enqueueSnackbar } from 'notistack'; import * as React from 'react'; @@ -6,8 +6,6 @@ import { Accordion } from 'src/components/Accordion'; import { Button } from 'src/components/Button/Button'; import { CircleProgress } from 'src/components/CircleProgress'; import { Link } from 'src/components/Link'; -import { Notice } from 'src/components/Notice/Notice'; -import { Stack } from 'src/components/Stack'; import { TypeToConfirmDialog } from 'src/components/TypeToConfirmDialog/TypeToConfirmDialog'; import { Typography } from 'src/components/Typography'; import { useAccountSettings } from 'src/queries/account/settings'; diff --git a/packages/manager/src/features/Account/SwitchAccountDrawer.tsx b/packages/manager/src/features/Account/SwitchAccountDrawer.tsx index 50f546ae1de..0c89986ada2 100644 --- a/packages/manager/src/features/Account/SwitchAccountDrawer.tsx +++ b/packages/manager/src/features/Account/SwitchAccountDrawer.tsx @@ -1,9 +1,9 @@ +import { Notice } from '@linode/ui'; import React from 'react'; import { StyledLinkButton } from 'src/components/Button/StyledLinkButton'; import { DebouncedSearchTextField } from 'src/components/DebouncedSearchTextField'; import { Drawer } from 'src/components/Drawer'; -import { Notice } from 'src/components/Notice/Notice'; import { Typography } from 'src/components/Typography'; import { PARENT_USER_SESSION_EXPIRED } from 'src/features/Account/constants'; import { useParentChildAuthentication } from 'src/features/Account/SwitchAccounts/useParentChildAuthentication'; diff --git a/packages/manager/src/features/Account/SwitchAccounts/ChildAccountList.tsx b/packages/manager/src/features/Account/SwitchAccounts/ChildAccountList.tsx index d2184880199..473b84ed6d7 100644 --- a/packages/manager/src/features/Account/SwitchAccounts/ChildAccountList.tsx +++ b/packages/manager/src/features/Account/SwitchAccounts/ChildAccountList.tsx @@ -1,4 +1,4 @@ -import { Box } from '@linode/ui'; +import { Box, Notice, Stack } from '@linode/ui'; import React, { useState } from 'react'; import { Waypoint } from 'react-waypoint'; @@ -6,8 +6,6 @@ import ErrorStateCloud from 'src/assets/icons/error-state-cloud.svg'; import { Button } from 'src/components/Button/Button'; import { StyledLinkButton } from 'src/components/Button/StyledLinkButton'; import { CircleProgress } from 'src/components/CircleProgress'; -import { Notice } from 'src/components/Notice/Notice'; -import { Stack } from 'src/components/Stack'; import { Typography } from 'src/components/Typography'; import { useChildAccountsInfiniteQuery } from 'src/queries/account/account'; diff --git a/packages/manager/src/features/Backups/AutoEnroll.tsx b/packages/manager/src/features/Backups/AutoEnroll.tsx index 9a1a6e4764c..1a7b8a2f138 100644 --- a/packages/manager/src/features/Backups/AutoEnroll.tsx +++ b/packages/manager/src/features/Backups/AutoEnroll.tsx @@ -1,10 +1,9 @@ -import { Paper } from '@linode/ui'; +import { Notice, Paper } from '@linode/ui'; import { styled } from '@mui/material/styles'; import * as React from 'react'; import { FormControlLabel } from 'src/components/FormControlLabel'; import { Link } from 'src/components/Link'; -import { Notice } from 'src/components/Notice/Notice'; import { Toggle } from 'src/components/Toggle/Toggle'; import { Typography } from 'src/components/Typography'; diff --git a/packages/manager/src/features/Backups/BackupDrawer.tsx b/packages/manager/src/features/Backups/BackupDrawer.tsx index 3eb601769d6..b1cb2884b59 100644 --- a/packages/manager/src/features/Backups/BackupDrawer.tsx +++ b/packages/manager/src/features/Backups/BackupDrawer.tsx @@ -1,4 +1,4 @@ -import { Box } from '@linode/ui'; +import { Box, Notice, Stack } from '@linode/ui'; import { styled } from '@mui/material'; import { useSnackbar } from 'notistack'; import * as React from 'react'; @@ -7,8 +7,6 @@ import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { DisplayPrice } from 'src/components/DisplayPrice'; import { Drawer } from 'src/components/Drawer'; import { Link } from 'src/components/Link'; -import { Notice } from 'src/components/Notice/Notice'; -import { Stack } from 'src/components/Stack'; import { Table } from 'src/components/Table'; import { TableBody } from 'src/components/TableBody'; import { TableCell } from 'src/components/TableCell'; diff --git a/packages/manager/src/features/Betas/BetaDetails.tsx b/packages/manager/src/features/Betas/BetaDetails.tsx index 811a24cee3b..ac81057d5b2 100644 --- a/packages/manager/src/features/Betas/BetaDetails.tsx +++ b/packages/manager/src/features/Betas/BetaDetails.tsx @@ -1,10 +1,10 @@ +import { Stack } from '@linode/ui'; import { useNavigate } from '@tanstack/react-router'; import * as React from 'react'; import { Button } from 'src/components/Button/Button'; import { DateTimeDisplay } from 'src/components/DateTimeDisplay'; import { Link } from 'src/components/Link'; -import { Stack } from 'src/components/Stack'; import { Typography } from 'src/components/Typography'; import type { AccountBeta, Beta } from '@linode/api-v4'; diff --git a/packages/manager/src/features/Betas/BetaDetailsList.tsx b/packages/manager/src/features/Betas/BetaDetailsList.tsx index 54926a1b8ac..b310162e1aa 100644 --- a/packages/manager/src/features/Betas/BetaDetailsList.tsx +++ b/packages/manager/src/features/Betas/BetaDetailsList.tsx @@ -1,10 +1,8 @@ -import { Paper } from '@linode/ui'; +import { Divider, Paper, Stack } from '@linode/ui'; import * as React from 'react'; import { CircleProgress } from 'src/components/CircleProgress'; -import { Divider } from 'src/components/Divider'; import { ErrorState } from 'src/components/ErrorState/ErrorState'; -import { Stack } from 'src/components/Stack'; import { Typography } from 'src/components/Typography'; import BetaDetails from './BetaDetails'; diff --git a/packages/manager/src/features/Betas/BetaSignup.tsx b/packages/manager/src/features/Betas/BetaSignup.tsx index 6ea06dbc27f..f35ade587c0 100644 --- a/packages/manager/src/features/Betas/BetaSignup.tsx +++ b/packages/manager/src/features/Betas/BetaSignup.tsx @@ -1,4 +1,4 @@ -import { Paper } from '@linode/ui'; +import { Paper, Stack } from '@linode/ui'; import { createLazyRoute, useNavigate, @@ -13,7 +13,6 @@ import { CircleProgress } from 'src/components/CircleProgress'; import { HighlightedMarkdown } from 'src/components/HighlightedMarkdown/HighlightedMarkdown'; import { LandingHeader } from 'src/components/LandingHeader/LandingHeader'; import { NotFound } from 'src/components/NotFound'; -import { Stack } from 'src/components/Stack'; import { Typography } from 'src/components/Typography'; import { useCreateAccountBetaMutation } from 'src/queries/account/betas'; import { useBetaQuery } from 'src/queries/betas'; diff --git a/packages/manager/src/features/Betas/BetasLanding.tsx b/packages/manager/src/features/Betas/BetasLanding.tsx index 9ac9a88e315..cb025ffcf0a 100644 --- a/packages/manager/src/features/Betas/BetasLanding.tsx +++ b/packages/manager/src/features/Betas/BetasLanding.tsx @@ -1,9 +1,9 @@ +import { Stack } from '@linode/ui'; import { createLazyRoute } from '@tanstack/react-router'; import * as React from 'react'; import { LandingHeader } from 'src/components/LandingHeader/LandingHeader'; import { ProductInformationBanner } from 'src/components/ProductInformationBanner/ProductInformationBanner'; -import { Stack } from 'src/components/Stack'; import { BetaDetailsList } from 'src/features/Betas/BetaDetailsList'; import { useAccountBetasQuery } from 'src/queries/account/betas'; import { useBetasQuery } from 'src/queries/betas'; diff --git a/packages/manager/src/features/Billing/BillingPanels/BillingSummary/BillingSummary.tsx b/packages/manager/src/features/Billing/BillingPanels/BillingSummary/BillingSummary.tsx index 6a99347fd21..5470fb0899f 100644 --- a/packages/manager/src/features/Billing/BillingPanels/BillingSummary/BillingSummary.tsx +++ b/packages/manager/src/features/Billing/BillingPanels/BillingSummary/BillingSummary.tsx @@ -1,4 +1,4 @@ -import { Box } from '@linode/ui'; +import { Box, Divider } from '@linode/ui'; import { useTheme } from '@mui/material/styles'; import Grid from '@mui/material/Unstable_Grid2'; import * as React from 'react'; @@ -6,7 +6,6 @@ import { useHistory, useLocation, useRouteMatch } from 'react-router-dom'; import { Button } from 'src/components/Button/Button'; import { Currency } from 'src/components/Currency'; -import { Divider } from 'src/components/Divider'; import { TooltipIcon } from 'src/components/TooltipIcon'; import { Typography } from 'src/components/Typography'; import { useAccountManagement } from 'src/hooks/useAccountManagement'; diff --git a/packages/manager/src/features/Billing/BillingPanels/BillingSummary/PaymentDrawer/PaymentBits/CreditCardDialog.tsx b/packages/manager/src/features/Billing/BillingPanels/BillingSummary/PaymentDrawer/PaymentBits/CreditCardDialog.tsx index e07974e3fd3..5741aff6eef 100644 --- a/packages/manager/src/features/Billing/BillingPanels/BillingSummary/PaymentDrawer/PaymentBits/CreditCardDialog.tsx +++ b/packages/manager/src/features/Billing/BillingPanels/BillingSummary/PaymentDrawer/PaymentBits/CreditCardDialog.tsx @@ -1,8 +1,8 @@ +import { Notice } from '@linode/ui'; import * as React from 'react'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { ConfirmationDialog } from 'src/components/ConfirmationDialog/ConfirmationDialog'; -import { Notice } from 'src/components/Notice/Notice'; import { Typography } from 'src/components/Typography'; interface Actions { @@ -18,7 +18,7 @@ interface Props extends Actions { } export const CreditCardDialog = (props: Props) => { - const { cancel, error, open, usd, isMakingPayment, executePayment } = props; + const { cancel, error, executePayment, isMakingPayment, open, usd } = props; return ( ({ input: { maxWidth: 'unset', diff --git a/packages/manager/src/features/Billing/BillingPanels/ContactInfoPanel/UpdateContactInformationForm/UpdateContactInformationForm.tsx b/packages/manager/src/features/Billing/BillingPanels/ContactInfoPanel/UpdateContactInformationForm/UpdateContactInformationForm.tsx index 0bab8d585f8..1d85088674b 100644 --- a/packages/manager/src/features/Billing/BillingPanels/ContactInfoPanel/UpdateContactInformationForm/UpdateContactInformationForm.tsx +++ b/packages/manager/src/features/Billing/BillingPanels/ContactInfoPanel/UpdateContactInformationForm/UpdateContactInformationForm.tsx @@ -1,3 +1,4 @@ +import { Notice } from '@linode/ui'; import Grid from '@mui/material/Unstable_Grid2'; import { allCountries } from 'country-region-data'; import { useFormik } from 'formik'; @@ -6,7 +7,6 @@ import { makeStyles } from 'tss-react/mui'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import EnhancedSelect from 'src/components/EnhancedSelect/Select'; -import { Notice } from 'src/components/Notice/Notice'; import { TextField } from 'src/components/TextField'; import { getRestrictedResourceText, diff --git a/packages/manager/src/features/Billing/BillingPanels/PaymentInfoPanel/AddPaymentMethodDrawer/AddCreditCardForm.tsx b/packages/manager/src/features/Billing/BillingPanels/PaymentInfoPanel/AddPaymentMethodDrawer/AddCreditCardForm.tsx index 5644c16737c..b41b64996dc 100644 --- a/packages/manager/src/features/Billing/BillingPanels/PaymentInfoPanel/AddPaymentMethodDrawer/AddCreditCardForm.tsx +++ b/packages/manager/src/features/Billing/BillingPanels/PaymentInfoPanel/AddPaymentMethodDrawer/AddCreditCardForm.tsx @@ -1,22 +1,24 @@ import { addPaymentMethod } from '@linode/api-v4/lib'; +import { Notice } from '@linode/ui'; import { CreditCardSchema } from '@linode/validation'; -import { InputBaseComponentProps } from '@mui/material/InputBase/InputBase'; -import { Theme } from '@mui/material/styles'; import Grid from '@mui/material/Unstable_Grid2'; import { useQueryClient } from '@tanstack/react-query'; import { useFormik, yupToFormErrors } from 'formik'; import { useSnackbar } from 'notistack'; import * as React from 'react'; -import NumberFormat, { NumberFormatProps } from 'react-number-format'; +import NumberFormat from 'react-number-format'; import { makeStyles } from 'tss-react/mui'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; -import { Notice } from 'src/components/Notice/Notice'; import { TextField } from 'src/components/TextField'; import { accountQueries } from 'src/queries/account/queries'; import { parseExpiryYear } from 'src/utilities/creditCard'; import { handleAPIErrors } from 'src/utilities/formikErrorUtils'; +import type { InputBaseComponentProps } from '@mui/material/InputBase/InputBase'; +import type { Theme } from '@mui/material/styles'; +import type { NumberFormatProps } from 'react-number-format'; + const useStyles = makeStyles()((theme: Theme) => ({ error: { marginTop: theme.spacing(2), diff --git a/packages/manager/src/features/Billing/BillingPanels/PaymentInfoPanel/AddPaymentMethodDrawer/AddPaymentMethodDrawer.tsx b/packages/manager/src/features/Billing/BillingPanels/PaymentInfoPanel/AddPaymentMethodDrawer/AddPaymentMethodDrawer.tsx index 90289afadcf..82357868ff4 100644 --- a/packages/manager/src/features/Billing/BillingPanels/PaymentInfoPanel/AddPaymentMethodDrawer/AddPaymentMethodDrawer.tsx +++ b/packages/manager/src/features/Billing/BillingPanels/PaymentInfoPanel/AddPaymentMethodDrawer/AddPaymentMethodDrawer.tsx @@ -1,11 +1,9 @@ -import { Box } from '@linode/ui'; +import { Box, Divider, Notice } from '@linode/ui'; import Grid from '@mui/material/Unstable_Grid2'; import * as React from 'react'; -import { Divider } from 'src/components/Divider'; import { Drawer } from 'src/components/Drawer'; import { LinearProgress } from 'src/components/LinearProgress'; -import { Notice } from 'src/components/Notice/Notice'; import { TooltipIcon } from 'src/components/TooltipIcon'; import { Typography } from 'src/components/Typography'; import { MAXIMUM_PAYMENT_METHODS } from 'src/constants'; @@ -19,8 +17,8 @@ import { PayPalErrorBoundary } from '../PayPalErrorBoundary'; import AddCreditCardForm from './AddCreditCardForm'; import type { PaymentMethod } from '@linode/api-v4/lib/account'; +import type { NoticeVariant } from '@linode/ui'; import type { VariantType } from 'notistack'; -import type { NoticeVariant } from 'src/components/Notice/Notice'; interface Props { onClose: () => void; diff --git a/packages/manager/src/features/Billing/InvoiceDetail/InvoiceDetail.tsx b/packages/manager/src/features/Billing/InvoiceDetail/InvoiceDetail.tsx index e88a7a0df46..4f7fb0e301d 100644 --- a/packages/manager/src/features/Billing/InvoiceDetail/InvoiceDetail.tsx +++ b/packages/manager/src/features/Billing/InvoiceDetail/InvoiceDetail.tsx @@ -1,4 +1,5 @@ import { getInvoice, getInvoiceItems } from '@linode/api-v4/lib/account'; +import { Notice, Paper } from '@linode/ui'; import { Box, IconButton } from '@linode/ui'; import KeyboardArrowLeft from '@mui/icons-material/KeyboardArrowLeft'; import { useTheme } from '@mui/material/styles'; @@ -12,8 +13,6 @@ import { Currency } from 'src/components/Currency'; import { DownloadCSV } from 'src/components/DownloadCSV/DownloadCSV'; import { LandingHeader } from 'src/components/LandingHeader'; import { Link } from 'src/components/Link'; -import { Notice } from 'src/components/Notice/Notice'; -import { Paper } from '@linode/ui'; import { Typography } from 'src/components/Typography'; import { printInvoice } from 'src/features/Billing/PdfGenerator/PdfGenerator'; import { useFlags } from 'src/hooks/useFlags'; diff --git a/packages/manager/src/features/CloudPulse/Overview/GlobalFilters.tsx b/packages/manager/src/features/CloudPulse/Overview/GlobalFilters.tsx index 5da22919834..b3ab3e678da 100644 --- a/packages/manager/src/features/CloudPulse/Overview/GlobalFilters.tsx +++ b/packages/manager/src/features/CloudPulse/Overview/GlobalFilters.tsx @@ -1,10 +1,10 @@ +import { Divider } from '@linode/ui'; import { IconButton, useTheme } from '@mui/material'; import { Grid } from '@mui/material'; import { styled } from '@mui/material/styles'; import * as React from 'react'; import Reload from 'src/assets/icons/refresh.svg'; -import { Divider } from 'src/components/Divider'; import { CloudPulseDashboardFilterBuilder } from '../shared/CloudPulseDashboardFilterBuilder'; import { CloudPulseDashboardSelect } from '../shared/CloudPulseDashboardSelect'; diff --git a/packages/manager/src/features/CloudPulse/Utils/CloudPulseWidgetUtils.ts b/packages/manager/src/features/CloudPulse/Utils/CloudPulseWidgetUtils.ts index 7a4e2a5b671..00afdd83ce7 100644 --- a/packages/manager/src/features/CloudPulse/Utils/CloudPulseWidgetUtils.ts +++ b/packages/manager/src/features/CloudPulse/Utils/CloudPulseWidgetUtils.ts @@ -347,3 +347,38 @@ export const getAutocompleteWidgetStyles = (theme: Theme) => ({ width: '90px', }, }); + +/** + * This method handles the existing issue in chart JS, and it will deleted when the recharts migration is completed + * @param arraysToBeFilled The list of dimension data to be filled + * @returns The list of dimension data filled with null values for missing timestamps + */ +// TODO: CloudPulse - delete when recharts migration completed +export const fillMissingTimeStampsAcrossDimensions = ( + ...arraysToBeFilled: [number, number | null][][] +): [number, number | null][][] => { + if (arraysToBeFilled.length === 0) return []; + + // Step 1: Collect all unique keys from all arrays + const allTimestamps = new Set(); + + // Collect timestamps from each array, array[0], contains the number timestamp + arraysToBeFilled.forEach((array) => { + array.forEach(([timeStamp]) => allTimestamps.add(timeStamp)); + }); + + // Step 2: Sort the timestamps to maintain chronological order + const sortedTimestamps = Array.from(allTimestamps).sort((a, b) => a - b); + + // Step 3: Synchronize the arrays to have null values for all missing timestamps + return arraysToBeFilled.map((array) => { + // Step 3.1: Convert the array into a map for fast lookup + const map = new Map(array.map(([key, value]) => [key, value])); + + // Step 3.2: Build the synchronized array by checking if a key exists + return sortedTimestamps.map((key) => { + // If the current array has the key, use its value; otherwise, set it to null, so that the gap is properly visible + return [key, map.get(key) ?? null] as [number, number | null]; + }); + }); +}; diff --git a/packages/manager/src/features/CloudPulse/Widget/CloudPulseWidget.tsx b/packages/manager/src/features/CloudPulse/Widget/CloudPulseWidget.tsx index 9573682af68..61c561eda0c 100644 --- a/packages/manager/src/features/CloudPulse/Widget/CloudPulseWidget.tsx +++ b/packages/manager/src/features/CloudPulse/Widget/CloudPulseWidget.tsx @@ -10,6 +10,7 @@ import { useProfile } from 'src/queries/profile/profile'; import { generateGraphData, getCloudPulseMetricRequest, + fillMissingTimeStampsAcrossDimensions, } from '../Utils/CloudPulseWidgetUtils'; import { AGGREGATE_FUNCTION, SIZE, TIME_GRANULARITY } from '../Utils/constants'; import { constructAdditionalRequestFilters } from '../Utils/FilterBuilder'; @@ -256,6 +257,17 @@ export const CloudPulseWidget = (props: CloudPulseWidgetProperties) => { }); data = generatedData.dimensions; + + // add missing timestamps across all the dimensions + const filledArrays = fillMissingTimeStampsAcrossDimensions( + ...data.map((data) => data.data) + ); + + //update the chart data with updated arrays + filledArrays.forEach((arr, index) => { + data[index].data = arr; + }); + legendRows = generatedData.legendRowsData; today = generatedData.today; scaledWidgetUnit.current = generatedData.unit; // here state doesn't matter, as this is always the latest re-render @@ -323,8 +335,10 @@ export const CloudPulseWidget = (props: CloudPulseWidgetProperties) => { ? metricsApiCallError ?? 'Error while rendering graph' : undefined } - formatData={(data: number) => - convertValueToUnit(data, scaledWidgetUnit.current) + formatData={(data: number | null) => + data === null + ? data + : convertValueToUnit(data, scaledWidgetUnit.current) } legendRows={ legendRows && legendRows.length > 0 ? legendRows : undefined diff --git a/packages/manager/src/features/CloudPulse/shared/CloudPulseResourcesSelect.tsx b/packages/manager/src/features/CloudPulse/shared/CloudPulseResourcesSelect.tsx index 3c6bd803237..437ee3bd8e1 100644 --- a/packages/manager/src/features/CloudPulse/shared/CloudPulseResourcesSelect.tsx +++ b/packages/manager/src/features/CloudPulse/shared/CloudPulseResourcesSelect.tsx @@ -43,8 +43,13 @@ export const CloudPulseResourcesSelect = React.memo( xFilter, } = props; - const platformFilter = - resourceType === 'dbaas' ? { platform: 'rdbms-default' } : {}; + const resourceFilterMap: Record = { + dbaas: { + '+order': 'asc', + '+order_by': 'label', + platform: 'rdbms-default', + }, + }; const { data: resources, isLoading, isError } = useResourcesQuery( disabled !== undefined ? !disabled : Boolean(region && resourceType), @@ -52,11 +57,11 @@ export const CloudPulseResourcesSelect = React.memo( {}, xFilter ? { - ...platformFilter, - ...xFilter, + ...(resourceFilterMap[resourceType ?? ''] ?? {}), + ...xFilter, // the usual xFilters } : { - ...platformFilter, + ...(resourceFilterMap[resourceType ?? ''] ?? {}), region, } ); diff --git a/packages/manager/src/features/Databases/DatabaseCreate/DatabaseClusterData.tsx b/packages/manager/src/features/Databases/DatabaseCreate/DatabaseClusterData.tsx index ddb10e80304..174486d23e0 100644 --- a/packages/manager/src/features/Databases/DatabaseCreate/DatabaseClusterData.tsx +++ b/packages/manager/src/features/Databases/DatabaseCreate/DatabaseClusterData.tsx @@ -1,7 +1,7 @@ +import { Divider } from '@linode/ui'; import Grid from '@mui/material/Unstable_Grid2'; import React from 'react'; -import { Divider } from 'src/components/Divider'; import Select from 'src/components/EnhancedSelect'; import { _SingleValue } from 'src/components/EnhancedSelect/components/SingleValue'; import { RegionSelect } from 'src/components/RegionSelect/RegionSelect'; @@ -19,10 +19,12 @@ import { getEngineOptions } from './utilities'; import type { ClusterSize, - ComprehensiveReplicationType, DatabaseEngine, Engine, + MySQLReplicationType, + PostgresReplicationType, Region, + ReplicationCommitTypes, } from '@linode/api-v4'; import type { FormikErrors } from 'formik'; import type { Item } from 'src/components/EnhancedSelect'; @@ -32,14 +34,15 @@ export interface DatabaseCreateValues { error: string; }[]; cluster_size: ClusterSize; - compression_type: undefined; engine: Engine; label: string; region: string; - replication_commit_type: undefined; - replication_type: ComprehensiveReplicationType; - ssl_connection: boolean; - storage_engine: undefined; + /** @Deprecated used by rdbms-legacy PostgreSQL only */ + replication_commit_type?: ReplicationCommitTypes; + /** @Deprecated used by rdbms-legacy only */ + replication_type?: MySQLReplicationType | PostgresReplicationType; + /** @Deprecated used by rdbms-legacy only, rdbms-default always uses TLS */ + ssl_connection?: boolean; type: string; } diff --git a/packages/manager/src/features/Databases/DatabaseCreate/DatabaseCreate.tsx b/packages/manager/src/features/Databases/DatabaseCreate/DatabaseCreate.tsx index 06bc649e980..1b58b3f7a39 100644 --- a/packages/manager/src/features/Databases/DatabaseCreate/DatabaseCreate.tsx +++ b/packages/manager/src/features/Databases/DatabaseCreate/DatabaseCreate.tsx @@ -1,4 +1,4 @@ -import { BetaChip, Paper } from '@linode/ui'; +import { BetaChip, Divider, Notice, Paper } from '@linode/ui'; import { createDatabaseSchema } from '@linode/validation/lib/databases.schema'; import Grid from '@mui/material/Unstable_Grid2'; import { createLazyRoute } from '@tanstack/react-router'; @@ -7,11 +7,9 @@ import * as React from 'react'; import { useHistory } from 'react-router-dom'; import { CircleProgress } from 'src/components/CircleProgress'; -import { Divider } from 'src/components/Divider'; import { ErrorMessage } from 'src/components/ErrorMessage'; import { ErrorState } from 'src/components/ErrorState/ErrorState'; import { LandingHeader } from 'src/components/LandingHeader'; -import { Notice } from 'src/components/Notice/Notice'; import { getRestrictedResourceText } from 'src/features/Account/utils'; import { DatabaseClusterData } from 'src/features/Databases/DatabaseCreate/DatabaseClusterData'; import { @@ -40,10 +38,8 @@ import { scrollErrorIntoViewV2 } from 'src/utilities/scrollErrorIntoViewV2'; import { DatabaseCreateAccessControls } from './DatabaseCreateAccessControls'; import { - determineCompressionType, determineReplicationCommitType, determineReplicationType, - determineStorageEngine, } from './utilities'; import type { @@ -54,6 +50,7 @@ import type { } from '@linode/api-v4/lib/databases/types'; import type { APIError } from '@linode/api-v4/lib/types'; import type { PlanSelectionWithDatabaseType } from 'src/features/components/PlansPanel/types'; +import type { DatabaseCreateValues } from 'src/features/Databases/DatabaseCreate/DatabaseClusterData'; import type { ExtendedIP } from 'src/utilities/ipUtils'; const DatabaseCreate = () => { @@ -138,9 +135,6 @@ const DatabaseCreate = () => { ...values, allow_list: _allow_list, }; - if (isDatabasesV2Enabled) { - delete createPayload.replication_type; - } try { const response = await createDatabase(createPayload); history.push(`/databases/${response.engine}/${response.id}`); @@ -157,6 +151,27 @@ const DatabaseCreate = () => { setSubmitting(false); }; + const initialValues: DatabaseCreateValues = { + allow_list: [ + { + address: '', + error: '', + }, + ], + cluster_size: -1 as ClusterSize, + engine: 'mysql' as Engine, + label: '', + region: '', + type: '', + }; + + if (!isDatabasesV2Enabled) { + // TODO (UIE-8214) remove POST GA + initialValues.replication_commit_type = undefined; // specific to Postgres + initialValues.replication_type = 'none' as ComprehensiveReplicationType; + initialValues.ssl_connection = true; + } + const { errors, handleSubmit, @@ -166,24 +181,7 @@ const DatabaseCreate = () => { setSubmitting, values, } = useFormik({ - initialValues: { - allow_list: [ - { - address: '', - error: '', - }, - ], - cluster_size: -1 as ClusterSize, - compression_type: undefined, // specific to MongoDB - engine: 'mysql' as Engine, - label: '', - region: '', - replication_commit_type: undefined, // specific to Postgres - replication_type: 'none' as ComprehensiveReplicationType, - ssl_connection: true, - storage_engine: undefined, // specific to MongoDB - type: '', - }, + initialValues, onSubmit: submitForm, validate: () => { handleIPValidation(); @@ -200,6 +198,7 @@ const DatabaseCreate = () => { values.cluster_size < 1 ? 3 : values.cluster_size ); if (!isDatabasesV2Enabled) { + // TODO (UIE-8214) remove POST GA setFieldValue( 'replication_type', determineReplicationType(values.cluster_size, values.engine) @@ -209,11 +208,6 @@ const DatabaseCreate = () => { determineReplicationCommitType(values.engine) ); } - setFieldValue('storage_engine', determineStorageEngine(values.engine)); - setFieldValue( - 'compression_type', - determineCompressionType(values.engine) - ); } }, [setFieldValue, values.cluster_size, values.engine, isDatabasesV2Enabled]); @@ -267,8 +261,10 @@ const DatabaseCreate = () => { const handleNodeChange = (size: ClusterSize | undefined) => { setFieldValue('cluster_size', size); - isDatabasesV2Enabled && + if (!isDatabasesV2Enabled) { + // TODO (UIE-8214) remove POST GA setFieldValue('replication_type', size === 1 ? 'none' : 'semi_synch'); + } }; return (
    diff --git a/packages/manager/src/features/Databases/DatabaseCreate/DatabaseCreateAccessControls.tsx b/packages/manager/src/features/Databases/DatabaseCreate/DatabaseCreateAccessControls.tsx index 360dfa533f4..6d62c66c179 100644 --- a/packages/manager/src/features/Databases/DatabaseCreate/DatabaseCreateAccessControls.tsx +++ b/packages/manager/src/features/Databases/DatabaseCreate/DatabaseCreateAccessControls.tsx @@ -7,7 +7,6 @@ import { makeStyles } from 'tss-react/mui'; import { FormControlLabel } from 'src/components/FormControlLabel'; import { Link } from 'src/components/Link'; import { MultipleIPInput } from 'src/components/MultipleIPInput/MultipleIPInput'; -import { Notice } from 'src/components/Notice/Notice'; import { Radio } from 'src/components/Radio/Radio'; import { RadioGroup } from 'src/components/RadioGroup'; import { Typography } from 'src/components/Typography'; @@ -16,6 +15,7 @@ import { ExtendedIP, ipFieldPlaceholder } from 'src/utilities/ipUtils'; import { useIsDatabasesEnabled } from '../utilities'; import type { APIError } from '@linode/api-v4/lib/types'; +import { Notice } from '@linode/ui'; const useStyles = makeStyles()((theme: Theme) => ({ container: { @@ -33,7 +33,7 @@ const useStyles = makeStyles()((theme: Theme) => ({ }, })); -export type AccessOption = 'specific' | 'none'; +export type AccessOption = 'none' | 'specific'; interface Props { disabled?: boolean; @@ -65,7 +65,7 @@ export const DatabaseCreateAccessControls = (props: Props) => { <> Add IPv4 addresses or ranges that should be authorized to access - this cluster.Β  + this cluster. Learn more diff --git a/packages/manager/src/features/Databases/DatabaseCreate/DatabaseNodeSelector.tsx b/packages/manager/src/features/Databases/DatabaseCreate/DatabaseNodeSelector.tsx index 50ae7d7998f..29f03cf8ffa 100644 --- a/packages/manager/src/features/Databases/DatabaseCreate/DatabaseNodeSelector.tsx +++ b/packages/manager/src/features/Databases/DatabaseCreate/DatabaseNodeSelector.tsx @@ -1,8 +1,7 @@ -import { FormControl } from '@linode/ui'; +import { FormControl, Notice } from '@linode/ui'; import React from 'react'; import { FormControlLabel } from 'src/components/FormControlLabel'; -import { Notice } from 'src/components/Notice/Notice'; import { Radio } from 'src/components/Radio/Radio'; import { RadioGroup } from 'src/components/RadioGroup'; import { Typography } from 'src/components/Typography'; diff --git a/packages/manager/src/features/Databases/DatabaseCreate/utilities.tsx b/packages/manager/src/features/Databases/DatabaseCreate/utilities.tsx index ec405a84c58..f7d560d2ced 100644 --- a/packages/manager/src/features/Databases/DatabaseCreate/utilities.tsx +++ b/packages/manager/src/features/Databases/DatabaseCreate/utilities.tsx @@ -4,8 +4,7 @@ import React from 'react'; import MongoDBIcon from 'src/assets/icons/mongodb.svg'; import MySQLIcon from 'src/assets/icons/mysql.svg'; import PostgreSQLIcon from 'src/assets/icons/postgresql.svg'; - -import { databaseEngineMap } from '../DatabaseLanding/DatabaseRow'; +import { getDatabasesDescription } from 'src/features/Databases/utilities'; import type { DatabaseEngine } from '@linode/api-v4'; @@ -101,9 +100,10 @@ export const getEngineOptions = (engines: DatabaseEngine[]) => { .map((engineObject) => ({ ...engineObject, flag: engineIcons[engineObject.engine], - label: `${databaseEngineMap[engineObject.engine]} v${ - engineObject.version - }`, + label: getDatabasesDescription({ + engine: engineObject.engine, + version: engineObject.version, + }), value: `${engineObject.engine}/${engineObject.version}`, })) .sort((a, b) => (a.version > b.version ? -1 : 1)), diff --git a/packages/manager/src/features/Databases/DatabaseDetail/AccessControls.tsx b/packages/manager/src/features/Databases/DatabaseDetail/AccessControls.tsx index ebbd3edbfe9..996387fd88a 100644 --- a/packages/manager/src/features/Databases/DatabaseDetail/AccessControls.tsx +++ b/packages/manager/src/features/Databases/DatabaseDetail/AccessControls.tsx @@ -1,3 +1,4 @@ +import { Notice } from '@linode/ui'; import * as React from 'react'; import { makeStyles } from 'tss-react/mui'; @@ -5,7 +6,6 @@ import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Button } from 'src/components/Button/Button'; import { ConfirmationDialog } from 'src/components/ConfirmationDialog/ConfirmationDialog'; import { InlineMenuAction } from 'src/components/InlineMenuAction/InlineMenuAction'; -import { Notice } from 'src/components/Notice/Notice'; import { Table } from 'src/components/Table'; import { TableBody } from 'src/components/TableBody'; import { TableCell } from 'src/components/TableCell'; diff --git a/packages/manager/src/features/Databases/DatabaseDetail/AddAccessControlDrawer.tsx b/packages/manager/src/features/Databases/DatabaseDetail/AddAccessControlDrawer.tsx index e05dd1d9a8e..c14f0c7e768 100644 --- a/packages/manager/src/features/Databases/DatabaseDetail/AddAccessControlDrawer.tsx +++ b/packages/manager/src/features/Databases/DatabaseDetail/AddAccessControlDrawer.tsx @@ -1,26 +1,27 @@ -import { APIError } from '@linode/api-v4/lib/types'; -import { Theme } from '@mui/material/styles'; +import { Notice } from '@linode/ui'; import { useFormik } from 'formik'; import * as React from 'react'; import { makeStyles } from 'tss-react/mui'; -import { Database, DatabaseInstance } from '@linode/api-v4'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Drawer } from 'src/components/Drawer'; import { MultipleIPInput } from 'src/components/MultipleIPInput/MultipleIPInput'; -import { Notice } from 'src/components/Notice/Notice'; import { Typography } from 'src/components/Typography'; import { enforceIPMasks } from 'src/features/Firewalls/FirewallDetail/Rules/FirewallRuleDrawer.utils'; import { useDatabaseMutation } from 'src/queries/databases/databases'; import { handleAPIErrors } from 'src/utilities/formikErrorUtils'; import { - ExtendedIP, extendedIPToString, ipFieldPlaceholder, stringToExtendedIP, validateIPs, } from 'src/utilities/ipUtils'; +import type { Database, DatabaseInstance } from '@linode/api-v4'; +import type { APIError } from '@linode/api-v4/lib/types'; +import type { Theme } from '@mui/material/styles'; +import type { ExtendedIP } from 'src/utilities/ipUtils'; + const useStyles = makeStyles()((theme: Theme) => ({ instructions: { marginBottom: '2rem', diff --git a/packages/manager/src/features/Databases/DatabaseDetail/DatabaseBackups/DatabaseBackups.tsx b/packages/manager/src/features/Databases/DatabaseDetail/DatabaseBackups/DatabaseBackups.tsx index 8d2387c989e..d8098c7b92a 100644 --- a/packages/manager/src/features/Databases/DatabaseDetail/DatabaseBackups/DatabaseBackups.tsx +++ b/packages/manager/src/features/Databases/DatabaseDetail/DatabaseBackups/DatabaseBackups.tsx @@ -1,4 +1,5 @@ -import { Box } from '@linode/ui'; +import { Paper } from '@linode/ui'; +import { Box, Divider, Notice } from '@linode/ui'; import { FormControl, FormControlLabel, @@ -14,9 +15,6 @@ import { useParams } from 'react-router-dom'; import { Autocomplete } from 'src/components/Autocomplete/Autocomplete'; import { Button } from 'src/components/Button/Button'; -import { Divider } from 'src/components/Divider'; -import { Notice } from 'src/components/Notice/Notice'; -import { Paper } from '@linode/ui'; import { Typography } from 'src/components/Typography'; import { StyledDateCalendar, diff --git a/packages/manager/src/features/Databases/DatabaseDetail/DatabaseBackups/DatabaseBackupsDialog.tsx b/packages/manager/src/features/Databases/DatabaseDetail/DatabaseBackups/DatabaseBackupsDialog.tsx index b8c3a97fc98..e2d616f71fa 100644 --- a/packages/manager/src/features/Databases/DatabaseDetail/DatabaseBackups/DatabaseBackupsDialog.tsx +++ b/packages/manager/src/features/Databases/DatabaseDetail/DatabaseBackups/DatabaseBackupsDialog.tsx @@ -1,19 +1,20 @@ +import { Notice } from '@linode/ui'; import { useSnackbar } from 'notistack'; +import { useState } from 'react'; import * as React from 'react'; import { useHistory } from 'react-router-dom'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Dialog } from 'src/components/Dialog/Dialog'; -import { Notice } from 'src/components/Notice/Notice'; import { Typography } from 'src/components/Typography'; import { useRestoreFromBackupMutation } from 'src/queries/databases/databases'; import { getAPIErrorOrDefault } from 'src/utilities/errorUtils'; +import { toDatabaseFork, toFormatedDate } from '../../utilities'; + import type { Database } from '@linode/api-v4/lib/databases'; -import { DateTime } from 'luxon'; -import { useState } from 'react'; +import type { DateTime } from 'luxon'; import type { DialogProps } from 'src/components/Dialog/Dialog'; -import { toDatabaseFork, toFormatedDate } from '../../utilities'; interface Props extends Omit { database: Database; diff --git a/packages/manager/src/features/Databases/DatabaseDetail/DatabaseBackups/legacy/RestoreLegacyFromBackupDialog.tsx b/packages/manager/src/features/Databases/DatabaseDetail/DatabaseBackups/legacy/RestoreLegacyFromBackupDialog.tsx index 63f9315ae91..cc51b819756 100644 --- a/packages/manager/src/features/Databases/DatabaseDetail/DatabaseBackups/legacy/RestoreLegacyFromBackupDialog.tsx +++ b/packages/manager/src/features/Databases/DatabaseDetail/DatabaseBackups/legacy/RestoreLegacyFromBackupDialog.tsx @@ -1,8 +1,8 @@ +import { Notice } from '@linode/ui'; import { useSnackbar } from 'notistack'; import * as React from 'react'; import { useHistory } from 'react-router-dom'; -import { Notice } from 'src/components/Notice/Notice'; import { TypeToConfirmDialog } from 'src/components/TypeToConfirmDialog/TypeToConfirmDialog'; import { Typography } from 'src/components/Typography'; import { useLegacyRestoreFromBackupMutation } from 'src/queries/databases/databases'; diff --git a/packages/manager/src/features/Databases/DatabaseDetail/DatabaseResize/DatabaseResize.tsx b/packages/manager/src/features/Databases/DatabaseDetail/DatabaseResize/DatabaseResize.tsx index 89e06beb12f..8e87fa684c7 100644 --- a/packages/manager/src/features/Databases/DatabaseDetail/DatabaseResize/DatabaseResize.tsx +++ b/packages/manager/src/features/Databases/DatabaseDetail/DatabaseResize/DatabaseResize.tsx @@ -1,12 +1,10 @@ -import { Box, Paper } from '@linode/ui'; +import { Box, Divider, Notice, Paper } from '@linode/ui'; import { useSnackbar } from 'notistack'; import * as React from 'react'; import { useHistory } from 'react-router-dom'; import { CircleProgress } from 'src/components/CircleProgress'; -import { Divider } from 'src/components/Divider'; import { ErrorState } from 'src/components/ErrorState/ErrorState'; -import { Notice } from 'src/components/Notice/Notice'; import { TypeToConfirmDialog } from 'src/components/TypeToConfirmDialog/TypeToConfirmDialog'; import { Typography } from 'src/components/Typography'; import { determineInitialPlanCategoryTab } from 'src/features/components/PlansPanel/utils'; diff --git a/packages/manager/src/features/Databases/DatabaseDetail/DatabaseResize/DatabaseResizeCurrentConfiguration.tsx b/packages/manager/src/features/Databases/DatabaseDetail/DatabaseResize/DatabaseResizeCurrentConfiguration.tsx index eba42f15ce6..a45c1814922 100644 --- a/packages/manager/src/features/Databases/DatabaseDetail/DatabaseResize/DatabaseResizeCurrentConfiguration.tsx +++ b/packages/manager/src/features/Databases/DatabaseDetail/DatabaseResize/DatabaseResizeCurrentConfiguration.tsx @@ -5,13 +5,13 @@ import * as React from 'react'; import { CircleProgress } from 'src/components/CircleProgress'; import { ErrorState } from 'src/components/ErrorState/ErrorState'; import { TooltipIcon } from 'src/components/TooltipIcon'; +import { DatabaseEngineVersion } from 'src/features/Databases/DatabaseEngineVersion'; import { useDatabaseTypesQuery } from 'src/queries/databases/databases'; import { useInProgressEvents } from 'src/queries/events/events'; import { useRegionsQuery } from 'src/queries/regions/regions'; import { formatStorageUnits } from 'src/utilities/formatStorageUnits'; import { convertMegabytesTo } from 'src/utilities/unitConversions'; -import { databaseEngineMap } from '../../DatabaseLanding/DatabaseRow'; import { DatabaseStatusDisplay } from '../DatabaseStatusDisplay'; import { StyledStatusBox, @@ -24,7 +24,6 @@ import { import type { Region } from '@linode/api-v4'; import type { Database, - DatabaseInstance, DatabaseType, } from '@linode/api-v4/lib/databases/types'; @@ -32,10 +31,6 @@ interface Props { database: Database; } -export const getDatabaseVersionNumber = ( - version: DatabaseInstance['version'] -) => version.split('/')[1]; - export const DatabaseResizeCurrentConfiguration = ({ database }: Props) => { const { data: types, @@ -94,7 +89,13 @@ export const DatabaseResizeCurrentConfiguration = ({ database }: Props) => { Version{' '} - {databaseEngineMap[database.engine]} v{database.version} + Nodes{' '} diff --git a/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSettings/DatabaseSettings.test.tsx b/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSettings/DatabaseSettings.test.tsx index 1ac650f0371..6edfcd27efe 100644 --- a/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSettings/DatabaseSettings.test.tsx +++ b/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSettings/DatabaseSettings.test.tsx @@ -3,28 +3,67 @@ import * as React from 'react'; import { databaseFactory } from 'src/factories/databases'; import { mockMatchMedia, renderWithTheme } from 'src/utilities/testHelpers'; -import DatabaseSettings from './DatabaseSettings'; import * as utils from '../../utilities'; +import DatabaseSettings from './DatabaseSettings'; beforeAll(() => mockMatchMedia()); +const v1 = () => { + return { + isDatabasesEnabled: true, + isDatabasesV1Enabled: true, + isDatabasesV2Beta: false, + isDatabasesV2Enabled: false, + isDatabasesV2GA: false, + isUserExistingBeta: false, + isUserNewBeta: false, + }; +}; + +const v2Beta = () => { + return { + isDatabasesEnabled: true, + isDatabasesV1Enabled: true, + isDatabasesV2Beta: true, + isDatabasesV2Enabled: true, + isDatabasesV2GA: false, + isUserExistingBeta: false, + isUserNewBeta: true, + }; +}; + +const v2GA = () => ({ + isDatabasesEnabled: true, + isDatabasesV1Enabled: true, + isDatabasesV2Beta: false, + isDatabasesV2Enabled: true, + isDatabasesV2GA: true, + isUserExistingBeta: false, + isUserNewBeta: false, +}); + +const spy = vi.spyOn(utils, 'useIsDatabasesEnabled'); +spy.mockReturnValue(v2GA()); + describe('DatabaseSettings Component', () => { - const database = databaseFactory.build(); + const database = databaseFactory.build({ platform: 'rdbms-default' }); it('Should exist and be renderable', () => { expect(DatabaseSettings).toBeDefined(); renderWithTheme(); }); it('Should render a Paper component with headers for Manage Access, Reseting the Root password, and Deleting the Cluster', () => { + spy.mockReturnValue(v2GA()); const { container, getAllByRole } = renderWithTheme( ); const paper = container.querySelector('.MuiPaper-root'); expect(paper).not.toBeNull(); const headings = getAllByRole('heading'); - expect(headings[0].textContent).toBe('Manage Access'); - expect(headings[1].textContent).toBe('Reset the Root Password'); - expect(headings[2].textContent).toBe('Delete the Cluster'); + expect(headings[0].textContent).toBe('Suspend Cluster'); + expect(headings[1].textContent).toBe('Manage Access'); + expect(headings[2].textContent).toBe('Reset the Root Password'); + expect(headings[3].textContent).toBe('Delete the Cluster'); }); it.each([ @@ -48,6 +87,106 @@ describe('DatabaseSettings Component', () => { } }); + it('should not render Maintenance for V1 view legacy db', async () => { + spy.mockReturnValue(v1()); + + const database = databaseFactory.build({ + engine: 'postgresql', + platform: 'rdbms-legacy', + version: '14.6', + }); + + const { container } = renderWithTheme( + + ); + + const maintenance = container.querySelector( + '[data-qa-settings-section="Maintenance"]' + ); + + expect(maintenance).not.toBeInTheDocument(); + }); + + it('should not render Maintenance for V2 beta view legacy db', async () => { + spy.mockReturnValue(v2Beta()); + + const database = databaseFactory.build({ + engine: 'postgresql', + platform: 'rdbms-legacy', + version: '14.6', + }); + + const { container } = renderWithTheme( + + ); + + const maintenance = container.querySelector( + '[data-qa-settings-section="Maintenance"]' + ); + + expect(maintenance).not.toBeInTheDocument(); + }); + + it('should not render Maintenance for V2 beta view default db', async () => { + spy.mockReturnValue(v2Beta()); + + const database = databaseFactory.build({ + engine: 'postgresql', + platform: 'rdbms-default', + version: '14.6', + }); + + const { container } = renderWithTheme( + + ); + + const maintenance = container.querySelector( + '[data-qa-settings-section="Maintenance"]' + ); + + expect(maintenance).not.toBeInTheDocument(); + }); + + it('should not render Maintenance for V2 GA view legacy db', async () => { + spy.mockReturnValue(v2GA()); + + const database = databaseFactory.build({ + engine: 'postgresql', + platform: 'rdbms-legacy', + version: '14.6', + }); + + const { container } = renderWithTheme( + + ); + + const maintenance = container.querySelector( + '[data-qa-settings-section="Maintenance"]' + ); + + expect(maintenance).not.toBeInTheDocument(); + }); + + it('should render Maintenance for V2 GA view default db', async () => { + spy.mockReturnValue(v2GA()); + + const database = databaseFactory.build({ + engine: 'postgresql', + platform: 'rdbms-default', + version: '14.6', + }); + + const { container } = renderWithTheme( + + ); + + const maintenance = container.querySelector( + '[data-qa-settings-section="Maintenance"]' + ); + + expect(maintenance).toBeInTheDocument(); + }); + it('Should render Maintenance Window with radio buttons', () => { const database = databaseFactory.build({ platform: 'rdbms-legacy', diff --git a/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSettings/DatabaseSettings.tsx b/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSettings/DatabaseSettings.tsx index fcf44207c2b..5e048b40542 100644 --- a/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSettings/DatabaseSettings.tsx +++ b/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSettings/DatabaseSettings.tsx @@ -1,19 +1,24 @@ +import { Divider, Paper } from '@linode/ui'; import * as React from 'react'; -import { Divider } from 'src/components/Divider'; -import { Paper } from '@linode/ui'; import { Typography } from 'src/components/Typography'; +import { DatabaseSettingsReviewUpdatesDialog } from 'src/features/Databases/DatabaseDetail/DatabaseSettings/DatabaseSettingsReviewUpdatesDialog'; +import { DatabaseSettingsUpgradeVersionDialog } from 'src/features/Databases/DatabaseDetail/DatabaseSettings/DatabaseSettingsUpgradeVersionDialog'; +import { + isDefaultDatabase, + useIsDatabasesEnabled, +} from 'src/features/Databases/utilities'; import { useProfile } from 'src/queries/profile/profile'; import AccessControls from '../AccessControls'; import DatabaseSettingsDeleteClusterDialog from './DatabaseSettingsDeleteClusterDialog'; +import { DatabaseSettingsMaintenance } from './DatabaseSettingsMaintenance'; import DatabaseSettingsMenuItem from './DatabaseSettingsMenuItem'; import DatabaseSettingsResetPasswordDialog from './DatabaseSettingsResetPasswordDialog'; +import { DatabaseSettingsSuspendClusterDialog } from './DatabaseSettingsSuspendClusterDialog'; import MaintenanceWindow from './MaintenanceWindow'; import type { Database } from '@linode/api-v4/lib/databases/types'; -import { DatabaseSettingsSuspendClusterDialog } from './DatabaseSettingsSuspendClusterDialog'; -import { useIsDatabasesEnabled } from '../../utilities'; interface Props { database: Database; @@ -24,6 +29,7 @@ export const DatabaseSettings: React.FC = (props) => { const { database, disabled } = props; const { data: profile } = useProfile(); const { isDatabasesV2GA } = useIsDatabasesEnabled(); + const isDefaultDB = isDefaultDatabase(database); const accessControlCopy = ( @@ -32,16 +38,13 @@ export const DatabaseSettings: React.FC = (props) => { ); - const isLegacy = database.platform === 'rdbms-legacy'; - const isDefault = database.platform === 'rdbms-default'; - const suspendClusterCopy = `Suspend the cluster if you don't use it temporarily to prevent being billed for it.`; - const resetRootPasswordCopy = isLegacy + const resetRootPasswordCopy = !isDefaultDB ? 'Resetting your root password will automatically generate a new password. You can view the updated password on your database cluster summary page. ' : 'Reset your root password if someone should no longer have access to the root user or if you believe your password may have been compromised. This will automatically generate a new password that you’ll be able to see on your database cluster summary page.'; - const deleteClusterCopy = isLegacy + const deleteClusterCopy = !isDefaultDB ? 'Deleting a database cluster is permanent and cannot be undone.' : 'Permanently remove an unused database cluster.'; @@ -55,6 +58,16 @@ export const DatabaseSettings: React.FC = (props) => { setIsSuspendClusterDialogOpen, ] = React.useState(false); + const [ + isUpgradeVersionDialogOpen, + setIsUpgradeVersionDialogOpen, + ] = React.useState(false); + + const [ + isReviewUpdatesDialogOpen, + setIsReviewUpdatesDialogOpen, + ] = React.useState(false); + const onResetRootPassword = () => { setIsResetRootPasswordDialogOpen(true); }; @@ -79,10 +92,26 @@ export const DatabaseSettings: React.FC = (props) => { setIsSuspendClusterDialogOpen(false); }; + const onUpgradeVersion = () => { + setIsUpgradeVersionDialogOpen(true); + }; + + const onUpgradeVersionClose = () => { + setIsUpgradeVersionDialogOpen(false); + }; + + const onReviewUpdates = () => { + setIsReviewUpdatesDialogOpen(true); + }; + + const onReviewUpdatesClose = () => { + setIsReviewUpdatesDialogOpen(false); + }; + return ( <> - {isDatabasesV2GA && isDefault && ( + {isDatabasesV2GA && isDefaultDB && ( <> = (props) => { onClick={onDeleteCluster} sectionTitle="Delete the Cluster" /> + {isDatabasesV2GA && isDefaultDB && ( + <> + + + + )} = (props) => { onClose={onSuspendDialogClose} open={isSuspendClusterDialogOpen} /> + + ); }; diff --git a/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSettings/DatabaseSettingsDeleteClusterDialog.tsx b/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSettings/DatabaseSettingsDeleteClusterDialog.tsx index 57f9a81b1a2..af880558943 100644 --- a/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSettings/DatabaseSettingsDeleteClusterDialog.tsx +++ b/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSettings/DatabaseSettingsDeleteClusterDialog.tsx @@ -1,14 +1,15 @@ -import { Engine } from '@linode/api-v4/lib/databases'; +import { Notice } from '@linode/ui'; import { useSnackbar } from 'notistack'; import * as React from 'react'; import { useHistory } from 'react-router-dom'; -import { Notice } from 'src/components/Notice/Notice'; import { TypeToConfirmDialog } from 'src/components/TypeToConfirmDialog/TypeToConfirmDialog'; import { Typography } from 'src/components/Typography'; import { useDeleteDatabaseMutation } from 'src/queries/databases/databases'; import { getAPIErrorOrDefault } from 'src/utilities/errorUtils'; +import type { Engine } from '@linode/api-v4/lib/databases'; + interface Props { databaseEngine: Engine; databaseID: number; diff --git a/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSettings/DatabaseSettingsResetPasswordDialog.tsx b/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSettings/DatabaseSettingsResetPasswordDialog.tsx index 6866fcc99f5..242ac52fea7 100644 --- a/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSettings/DatabaseSettingsResetPasswordDialog.tsx +++ b/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSettings/DatabaseSettingsResetPasswordDialog.tsx @@ -1,8 +1,8 @@ +import { Notice } from '@linode/ui'; import * as React from 'react'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { ConfirmationDialog } from 'src/components/ConfirmationDialog/ConfirmationDialog'; -import { Notice } from 'src/components/Notice/Notice'; import { Typography } from 'src/components/Typography'; import { useDatabaseCredentialsMutation } from 'src/queries/databases/databases'; diff --git a/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSettings/DatabaseSettingsReviewUpdatesDialog.tsx b/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSettings/DatabaseSettingsReviewUpdatesDialog.tsx index e531dc963c7..47b084ac172 100644 --- a/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSettings/DatabaseSettingsReviewUpdatesDialog.tsx +++ b/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSettings/DatabaseSettingsReviewUpdatesDialog.tsx @@ -1,10 +1,10 @@ +import { Notice } from '@linode/ui'; import { useTheme } from '@mui/material'; import { useSnackbar } from 'notistack'; import * as React from 'react'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { ConfirmationDialog } from 'src/components/ConfirmationDialog/ConfirmationDialog'; -import { Notice } from 'src/components/Notice/Notice'; import { Typography } from 'src/components/Typography'; import { usePatchDatabaseMutation } from 'src/queries/databases/databases'; import { getAPIErrorOrDefault } from 'src/utilities/errorUtils'; diff --git a/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSettings/DatabaseSettingsSuspendClusterDialog.tsx b/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSettings/DatabaseSettingsSuspendClusterDialog.tsx index 9b2e125404b..a9c8aa0b7d2 100644 --- a/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSettings/DatabaseSettingsSuspendClusterDialog.tsx +++ b/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSettings/DatabaseSettingsSuspendClusterDialog.tsx @@ -1,15 +1,17 @@ -import { Engine } from '@linode/api-v4/lib/databases'; +import { Notice } from '@linode/ui'; import { useSnackbar } from 'notistack'; import * as React from 'react'; import { useHistory } from 'react-router-dom'; + import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Checkbox } from 'src/components/Checkbox'; import { ConfirmationDialog } from 'src/components/ConfirmationDialog/ConfirmationDialog'; -import { Notice } from 'src/components/Notice/Notice'; import { Typography } from 'src/components/Typography'; import { useSuspendDatabaseMutation } from 'src/queries/databases/databases'; import { getAPIErrorOrDefault } from 'src/utilities/errorUtils'; +import type { Engine } from '@linode/api-v4/lib/databases'; + export interface SuspendDialogProps { databaseEngine: Engine; databaseId: number; @@ -24,9 +26,9 @@ export const DatabaseSettingsSuspendClusterDialog = ( const { databaseEngine, databaseId, databaseLabel, onClose, open } = props; const { enqueueSnackbar } = useSnackbar(); const { - mutateAsync: suspendDatabase, - isPending, error, + isPending, + mutateAsync: suspendDatabase, reset, } = useSuspendDatabaseMutation(databaseEngine, databaseId); diff --git a/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSettings/DatabaseSettingsUpgradeVersionDialog.tsx b/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSettings/DatabaseSettingsUpgradeVersionDialog.tsx index f42d1777e40..14d75204ef1 100644 --- a/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSettings/DatabaseSettingsUpgradeVersionDialog.tsx +++ b/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSettings/DatabaseSettingsUpgradeVersionDialog.tsx @@ -1,4 +1,4 @@ -import { FormControl } from '@linode/ui'; +import { FormControl, Notice } from '@linode/ui'; import { useTheme } from '@mui/material'; import { useSnackbar } from 'notistack'; import * as React from 'react'; @@ -6,7 +6,6 @@ import * as React from 'react'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Autocomplete } from 'src/components/Autocomplete/Autocomplete'; import { ConfirmationDialog } from 'src/components/ConfirmationDialog/ConfirmationDialog'; -import { Notice } from 'src/components/Notice/Notice'; import { Typography } from 'src/components/Typography'; import { DATABASE_ENGINE_MAP, diff --git a/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSettings/MaintenanceWindow.tsx b/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSettings/MaintenanceWindow.tsx index ad3a4734d1c..5b1cf264083 100644 --- a/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSettings/MaintenanceWindow.tsx +++ b/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSettings/MaintenanceWindow.tsx @@ -1,4 +1,4 @@ -import { FormControl } from '@linode/ui'; +import { FormControl, Notice } from '@linode/ui'; import { useFormik } from 'formik'; import { DateTime } from 'luxon'; import { useSnackbar } from 'notistack'; @@ -9,7 +9,6 @@ import { makeStyles } from 'tss-react/mui'; import { Button } from 'src/components/Button/Button'; import Select from 'src/components/EnhancedSelect/Select'; import { FormControlLabel } from 'src/components/FormControlLabel'; -import { Notice } from 'src/components/Notice/Notice'; import { Radio } from 'src/components/Radio/Radio'; import { RadioGroup } from 'src/components/RadioGroup'; import { TooltipIcon } from 'src/components/TooltipIcon'; diff --git a/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSummary/DatabaseSummary.tsx b/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSummary/DatabaseSummary.tsx index 2e2768e6c05..c0f4fedcbcc 100644 --- a/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSummary/DatabaseSummary.tsx +++ b/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSummary/DatabaseSummary.tsx @@ -1,7 +1,7 @@ +import { Divider } from '@linode/ui'; import Grid from '@mui/material/Unstable_Grid2'; import * as React from 'react'; -import { Divider } from 'src/components/Divider'; import { Link } from 'src/components/Link'; import { Paper } from '@linode/ui'; import { Typography } from 'src/components/Typography'; diff --git a/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSummary/DatabaseSummaryClusterConfiguration.tsx b/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSummary/DatabaseSummaryClusterConfiguration.tsx index f619078acab..54b733ed209 100644 --- a/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSummary/DatabaseSummaryClusterConfiguration.tsx +++ b/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSummary/DatabaseSummaryClusterConfiguration.tsx @@ -10,7 +10,7 @@ import { StyledLabelTypography, StyledValueGrid, } from 'src/features/Databases/DatabaseDetail/DatabaseSummary/DatabaseSummaryClusterConfiguration.style'; -import { databaseEngineMap } from 'src/features/Databases/DatabaseLanding/DatabaseRow'; +import { DatabaseEngineVersion } from 'src/features/Databases/DatabaseEngineVersion'; import { useDatabaseTypesQuery } from 'src/queries/databases/databases'; import { useInProgressEvents } from 'src/queries/events/events'; import { useRegionsQuery } from 'src/queries/regions/regions'; @@ -101,7 +101,13 @@ export const DatabaseSummaryClusterConfiguration = (props: Props) => { Engine - {databaseEngineMap[database.engine]} v{database.version} + Region diff --git a/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSummary/DatabaseSummaryConnectionDetails.tsx b/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSummary/DatabaseSummaryConnectionDetails.tsx index 48b122b70ef..9ccfea88542 100644 --- a/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSummary/DatabaseSummaryConnectionDetails.tsx +++ b/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSummary/DatabaseSummaryConnectionDetails.tsx @@ -63,6 +63,16 @@ export const DatabaseSummaryConnectionDetails = (props: Props) => { const password = showCredentials && credentials ? credentials?.password : 'β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’'; + const hostTooltipComponentProps = { + tooltip: { + style: { + minWidth: 285, + }, + }, + }; + const HOST_TOOLTIP_COPY = + 'Use the IPv6 address (AAAA record) for this hostname to avoid network transfer charges when connecting to this database from Linodes within the same region.'; + const handleShowPasswordClick = () => { setShowPassword((showCredentials) => !showCredentials); }; @@ -226,6 +236,14 @@ export const DatabaseSummaryConnectionDetails = (props: Props) => { className={classes.inlineCopyToolTip} text={database.hosts?.primary} /> + {!isLegacy && ( + + )} ) : ( diff --git a/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSummary/legacy/DatabaseSummaryClusterConfigurationLegacy.tsx b/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSummary/legacy/DatabaseSummaryClusterConfigurationLegacy.tsx index 8b018175505..dedbefe5070 100644 --- a/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSummary/legacy/DatabaseSummaryClusterConfigurationLegacy.tsx +++ b/packages/manager/src/features/Databases/DatabaseDetail/DatabaseSummary/legacy/DatabaseSummaryClusterConfigurationLegacy.tsx @@ -5,7 +5,7 @@ import { makeStyles } from 'tss-react/mui'; import { TooltipIcon } from 'src/components/TooltipIcon'; import { Typography } from 'src/components/Typography'; import { DatabaseStatusDisplay } from 'src/features/Databases/DatabaseDetail/DatabaseStatusDisplay'; -import { databaseEngineMap } from 'src/features/Databases/DatabaseLanding/DatabaseRow'; +import { DatabaseEngineVersion } from 'src/features/Databases/DatabaseEngineVersion'; import { useDatabaseTypesQuery } from 'src/queries/databases/databases'; import { useInProgressEvents } from 'src/queries/events/events'; import { useRegionsQuery } from 'src/queries/regions/regions'; @@ -94,7 +94,13 @@ export const DatabaseSummaryClusterConfigurationLegacy = (props: Props) => { Version - {databaseEngineMap[database.engine]} v{database.version} + Nodes diff --git a/packages/manager/src/features/Databases/DatabaseDetail/index.tsx b/packages/manager/src/features/Databases/DatabaseDetail/index.tsx index b8d125b0da4..117578b9986 100644 --- a/packages/manager/src/features/Databases/DatabaseDetail/index.tsx +++ b/packages/manager/src/features/Databases/DatabaseDetail/index.tsx @@ -1,3 +1,4 @@ +import { Notice } from '@linode/ui'; import { createLazyRoute } from '@tanstack/react-router'; import * as React from 'react'; import { matchPath, useHistory, useParams } from 'react-router-dom'; @@ -7,7 +8,6 @@ import { CircleProgress } from 'src/components/CircleProgress'; import { DocumentTitleSegment } from 'src/components/DocumentTitle'; import { ErrorState } from 'src/components/ErrorState/ErrorState'; import { LandingHeader } from 'src/components/LandingHeader'; -import { Notice } from 'src/components/Notice/Notice'; import { SafeTabPanel } from 'src/components/Tabs/SafeTabPanel'; import { TabLinkList } from 'src/components/Tabs/TabLinkList'; import { TabPanels } from 'src/components/Tabs/TabPanels'; diff --git a/packages/manager/src/features/Databases/DatabaseLanding/DatabaseLanding.tsx b/packages/manager/src/features/Databases/DatabaseLanding/DatabaseLanding.tsx index 47e5542387b..f8430e0871f 100644 --- a/packages/manager/src/features/Databases/DatabaseLanding/DatabaseLanding.tsx +++ b/packages/manager/src/features/Databases/DatabaseLanding/DatabaseLanding.tsx @@ -138,6 +138,9 @@ const DatabaseLanding = () => { const showTabs = isV2Enabled && !!legacyDatabases?.data.length; const isNewDatabase = isV2Enabled && !!newDatabases?.data.length; const showSuspend = isDatabasesV2GA && !!newDatabases?.data.length; + const docsLink = isV2Enabled + ? 'https://techdocs.akamai.com/cloud-computing/docs/aiven-database-clusters' + : 'https://techdocs.akamai.com/cloud-computing/docs/managed-databases'; const legacyTable = () => { return ( @@ -179,7 +182,7 @@ const DatabaseLanding = () => { }} createButtonText="Create Database Cluster" disabledCreateButton={isRestricted} - docsLink="https://techdocs.akamai.com/cloud-computing/docs/managed-databases" + docsLink={docsLink} onButtonClick={() => history.push('/databases/create')} title="Database Clusters" /> diff --git a/packages/manager/src/features/Databases/DatabaseLanding/DatabaseRow.tsx b/packages/manager/src/features/Databases/DatabaseLanding/DatabaseRow.tsx index f72696b2319..890247dae03 100644 --- a/packages/manager/src/features/Databases/DatabaseLanding/DatabaseRow.tsx +++ b/packages/manager/src/features/Databases/DatabaseLanding/DatabaseRow.tsx @@ -6,6 +6,7 @@ import { Hidden } from 'src/components/Hidden'; import { TableCell } from 'src/components/TableCell'; import { TableRow } from 'src/components/TableRow'; import { DatabaseStatusDisplay } from 'src/features/Databases/DatabaseDetail/DatabaseStatusDisplay'; +import { DatabaseEngineVersion } from 'src/features/Databases/DatabaseEngineVersion'; import { DatabaseActionMenu } from 'src/features/Databases/DatabaseLanding/DatabaseActionMenu'; import { useIsDatabasesEnabled } from 'src/features/Databases/utilities'; import { useDatabaseTypesQuery } from 'src/queries/databases/databases'; @@ -19,17 +20,9 @@ import type { Event } from '@linode/api-v4'; import type { DatabaseInstance, DatabaseType, - Engine, } from '@linode/api-v4/lib/databases/types'; import type { ActionHandlers } from 'src/features/Databases/DatabaseLanding/DatabaseActionMenu'; -export const databaseEngineMap: Record = { - mongodb: 'MongoDB', - mysql: 'MySQL', - postgresql: 'PostgreSQL', - redis: 'Redis', -}; - interface Props { database: DatabaseInstance; events?: Event[]; @@ -53,9 +46,11 @@ export const DatabaseRow = ({ engine, id, label, + platform, region, status, type, + updates, version, } = database; @@ -101,7 +96,15 @@ export const DatabaseRow = ({ {configuration} - {`${databaseEngineMap[engine]} v${version}`} + + + {actualRegion?.label ?? region} diff --git a/packages/manager/src/features/Databases/utilities.ts b/packages/manager/src/features/Databases/utilities.ts index 9f01754f3fa..217ab155cda 100644 --- a/packages/manager/src/features/Databases/utilities.ts +++ b/packages/manager/src/features/Databases/utilities.ts @@ -219,10 +219,8 @@ export const toDatabaseFork = ( }; export const DATABASE_ENGINE_MAP: Record = { - mongodb: 'MongoDB', mysql: 'MySQL', postgresql: 'PostgreSQL', - redis: 'Redis', } as const; export const getDatabasesDescription = ( diff --git a/packages/manager/src/features/Domains/CloneDomainDrawer.tsx b/packages/manager/src/features/Domains/CloneDomainDrawer.tsx index ff6345ffe27..0192c19a34a 100644 --- a/packages/manager/src/features/Domains/CloneDomainDrawer.tsx +++ b/packages/manager/src/features/Domains/CloneDomainDrawer.tsx @@ -1,18 +1,19 @@ -import { Domain } from '@linode/api-v4'; +import { Notice } from '@linode/ui'; import { useFormik } from 'formik'; import React from 'react'; import { useHistory } from 'react-router-dom'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Drawer } from 'src/components/Drawer'; -import { Notice } from 'src/components/Notice/Notice'; -import { Radio } from 'src/components/Radio/Radio'; -import { TextField } from 'src/components/TextField'; import { FormControlLabel } from 'src/components/FormControlLabel'; +import { Radio } from 'src/components/Radio/Radio'; import { RadioGroup } from 'src/components/RadioGroup'; +import { TextField } from 'src/components/TextField'; import { useCloneDomainMutation } from 'src/queries/domains'; import { useGrants, useProfile } from 'src/queries/profile/profile'; +import type { Domain } from '@linode/api-v4'; + interface CloneDomainDrawerProps { domain: Domain | undefined; onClose: () => void; diff --git a/packages/manager/src/features/Domains/CreateDomain/CreateDomain.tsx b/packages/manager/src/features/Domains/CreateDomain/CreateDomain.tsx index 7a4bd2d9362..1e346477f68 100644 --- a/packages/manager/src/features/Domains/CreateDomain/CreateDomain.tsx +++ b/packages/manager/src/features/Domains/CreateDomain/CreateDomain.tsx @@ -1,4 +1,4 @@ -import { FormHelperText, Paper } from '@linode/ui'; +import { FormHelperText, Notice, Paper } from '@linode/ui'; import { createDomainSchema } from '@linode/validation/lib/domains.schema'; import { styled } from '@mui/material/styles'; import Grid from '@mui/material/Unstable_Grid2'; @@ -14,7 +14,6 @@ import { DocumentTitleSegment } from 'src/components/DocumentTitle'; import { FormControlLabel } from 'src/components/FormControlLabel'; import { LandingHeader } from 'src/components/LandingHeader'; import { MultipleIPInput } from 'src/components/MultipleIPInput/MultipleIPInput'; -import { Notice } from 'src/components/Notice/Notice'; import { Radio } from 'src/components/Radio/Radio'; import { RadioGroup } from 'src/components/RadioGroup'; import { TextField } from 'src/components/TextField'; diff --git a/packages/manager/src/features/Domains/DomainBanner.tsx b/packages/manager/src/features/Domains/DomainBanner.tsx index 44160e35d1b..e170c35ead2 100644 --- a/packages/manager/src/features/Domains/DomainBanner.tsx +++ b/packages/manager/src/features/Domains/DomainBanner.tsx @@ -1,10 +1,10 @@ +import { Stack } from '@linode/ui'; import { styled } from '@mui/material/styles'; import { DateTime } from 'luxon'; import * as React from 'react'; import { DismissibleBanner } from 'src/components/DismissibleBanner/DismissibleBanner'; import { Link } from 'src/components/Link'; -import { Stack } from 'src/components/Stack'; import { Typography } from 'src/components/Typography'; interface DomainBannerProps { diff --git a/packages/manager/src/features/Domains/DomainDetail/DomainDetail.tsx b/packages/manager/src/features/Domains/DomainDetail/DomainDetail.tsx index 4cc6b0f8a6a..6958ddd56c2 100644 --- a/packages/manager/src/features/Domains/DomainDetail/DomainDetail.tsx +++ b/packages/manager/src/features/Domains/DomainDetail/DomainDetail.tsx @@ -1,3 +1,4 @@ +import { Notice, Paper } from '@linode/ui'; import { styled } from '@mui/material/styles'; import Grid from '@mui/material/Unstable_Grid2'; import * as React from 'react'; @@ -6,8 +7,6 @@ import { useHistory, useLocation, useParams } from 'react-router-dom'; import { CircleProgress } from 'src/components/CircleProgress'; import { ErrorState } from 'src/components/ErrorState/ErrorState'; import { LandingHeader } from 'src/components/LandingHeader'; -import { Notice } from 'src/components/Notice/Notice'; -import { Paper } from '@linode/ui'; import { TagCell } from 'src/components/TagCell/TagCell'; import { Typography } from 'src/components/Typography'; import { useIsResourceRestricted } from 'src/hooks/useIsResourceRestricted'; diff --git a/packages/manager/src/features/Domains/DomainRecordDrawer.tsx b/packages/manager/src/features/Domains/DomainRecordDrawer.tsx index ccc0ac55d03..42b03a8359d 100644 --- a/packages/manager/src/features/Domains/DomainRecordDrawer.tsx +++ b/packages/manager/src/features/Domains/DomainRecordDrawer.tsx @@ -1,13 +1,8 @@ import { - Domain, - DomainRecord, - DomainType, - RecordType, - UpdateDomainPayload, createDomainRecord, updateDomainRecord, } from '@linode/api-v4/lib/domains'; -import { APIError } from '@linode/api-v4/lib/types'; +import { Notice } from '@linode/ui'; import produce from 'immer'; import { cond, @@ -25,15 +20,10 @@ import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Autocomplete } from 'src/components/Autocomplete/Autocomplete'; import { Drawer } from 'src/components/Drawer'; import { MultipleIPInput } from 'src/components/MultipleIPInput/MultipleIPInput'; -import { Notice } from 'src/components/Notice/Notice'; import { TextField } from 'src/components/TextField'; import { getAPIErrorOrDefault } from 'src/utilities/errorUtils'; import { getAPIErrorFor } from 'src/utilities/getAPIErrorFor'; -import { - ExtendedIP, - extendedIPToString, - stringToExtendedIP, -} from 'src/utilities/ipUtils'; +import { extendedIPToString, stringToExtendedIP } from 'src/utilities/ipUtils'; import { maybeCastToNumber } from 'src/utilities/maybeCastToNumber'; import { scrollErrorIntoView } from 'src/utilities/scrollErrorIntoView'; @@ -44,6 +34,16 @@ import { isValidDomainRecord, } from './domainUtils'; +import type { + Domain, + DomainRecord, + DomainType, + RecordType, + UpdateDomainPayload, +} from '@linode/api-v4/lib/domains'; +import type { APIError } from '@linode/api-v4/lib/types'; +import type { ExtendedIP } from 'src/utilities/ipUtils'; + interface UpdateDomainDataProps extends UpdateDomainPayload { id: number; } @@ -117,74 +117,48 @@ export class DomainRecordDrawer extends React.Component< DomainRecordDrawerProps, State > { - componentDidUpdate(prevProps: DomainRecordDrawerProps) { - if (this.props.open && !prevProps.open) { - // Drawer is opening, set the fields according to props - this.setState({ - fields: DomainRecordDrawer.defaultFieldsState(this.props), - }); - } - } - - render() { - const { submitting } = this.state; - const { mode, open, records, type } = this.props; - const { fields } = this.types[type]; - const isCreating = mode === 'create'; - const isDomain = type === 'master' || type === 'slave'; - - const hasARecords = records.find((thisRecord) => - ['A', 'AAAA'].includes(thisRecord.type) - ); // If there are no A/AAAA records and a user tries to add an NS record, they'll see a warning message asking them to add an A/AAAA record. - - const noARecordsNoticeText = - 'Please create an A/AAAA record for this domain to avoid a Zone File invalidation.'; - - const otherErrors = [ - getAPIErrorFor({}, this.state.errors)('_unknown'), - getAPIErrorFor({}, this.state.errors)('none'), - ].filter(Boolean); - - return ( - - {otherErrors.length > 0 && - otherErrors.map((err, index) => { - return ; - })} - {!hasARecords && type === 'NS' && ( - - )} - {fields.map((field: any, idx: number) => field(idx))} + /** + * the defaultFieldState is used to pre-populate the drawer with either + * editable data or defaults. + */ + static defaultFieldsState = (props: Partial) => ({ + axfr_ips: getInitialIPs(props.axfr_ips), + description: '', + domain: props.domain, + expire_sec: props.expire_sec ?? 0, + id: props.id, + name: props.name ?? '', + port: props.port ?? '80', + priority: props.priority ?? '10', + protocol: props.protocol ?? 'tcp', + refresh_sec: props.refresh_sec ?? 0, + retry_sec: props.retry_sec ?? 0, + service: props.service ?? '', + soa_email: props.soa_email ?? '', + tag: props.tag ?? 'issue', + target: props.target ?? '', + ttl_sec: props.ttl_sec ?? 0, + weight: props.weight ?? '5', + }); - - - ); - } + static errorFields = { + axfr_ips: 'domain transfers', + domain: 'domain', + expire_sec: 'expire rate', + name: 'name', + port: 'port', + priority: 'priority', + protocol: 'protocol', + refresh_sec: 'refresh rate', + retry_sec: 'retry rate', + service: 'service', + soa_email: 'SOA email address', + tag: 'tag', + target: 'target', + ttl_sec: 'ttl_sec', + type: 'type', + weight: 'weight', + }; DefaultTTLField = () => ( @@ -474,49 +448,6 @@ export class DomainRecordDrawer extends React.Component< WeightField = () => ; - /** - * the defaultFieldState is used to pre-populate the drawer with either - * editable data or defaults. - */ - static defaultFieldsState = (props: Partial) => ({ - axfr_ips: getInitialIPs(props.axfr_ips), - description: '', - domain: props.domain, - expire_sec: props.expire_sec ?? 0, - id: props.id, - name: props.name ?? '', - port: props.port ?? '80', - priority: props.priority ?? '10', - protocol: props.protocol ?? 'tcp', - refresh_sec: props.refresh_sec ?? 0, - retry_sec: props.retry_sec ?? 0, - service: props.service ?? '', - soa_email: props.soa_email ?? '', - tag: props.tag ?? 'issue', - target: props.target ?? '', - ttl_sec: props.ttl_sec ?? 0, - weight: props.weight ?? '5', - }); - - static errorFields = { - axfr_ips: 'domain transfers', - domain: 'domain', - expire_sec: 'expire rate', - name: 'name', - port: 'port', - priority: 'priority', - protocol: 'protocol', - refresh_sec: 'refresh rate', - retry_sec: 'retry rate', - service: 'service', - soa_email: 'SOA email address', - tag: 'tag', - target: 'target', - ttl_sec: 'ttl_sec', - type: 'type', - weight: 'weight', - }; - filterDataByType = ( fields: EditableDomainFields | EditableRecordFields, t: DomainType | RecordType @@ -709,6 +640,16 @@ export class DomainRecordDrawer extends React.Component< key: keyof EditableDomainFields | keyof EditableRecordFields ) => (value: any) => this.setState(set(lensPath(['fields', key]), value)); + componentDidUpdate(prevProps: DomainRecordDrawerProps) { + if (this.props.open && !prevProps.open) { + // Drawer is opening, set the fields according to props + this.setState({ + fields: DomainRecordDrawer.defaultFieldsState(this.props), + }); + } + } + + // eslint-disable-next-line perfectionist/sort-classes setExpireSec = this.updateField('expire_sec'); setProtocol = this.updateField('protocol'); @@ -730,9 +671,6 @@ export class DomainRecordDrawer extends React.Component< A: { fields: [], }, - PTR: { - fields: [], - }, AAAA: { fields: [ (idx: number) => ( @@ -802,6 +740,9 @@ export class DomainRecordDrawer extends React.Component< (idx: number) => , ], }, + PTR: { + fields: [], + }, SRV: { fields: [ (idx: number) => , @@ -857,6 +798,66 @@ export class DomainRecordDrawer extends React.Component< fields: [], }, }; + + render() { + const { submitting } = this.state; + const { mode, open, records, type } = this.props; + const { fields } = this.types[type]; + const isCreating = mode === 'create'; + const isDomain = type === 'master' || type === 'slave'; + + const hasARecords = records.find((thisRecord) => + ['A', 'AAAA'].includes(thisRecord.type) + ); // If there are no A/AAAA records and a user tries to add an NS record, they'll see a warning message asking them to add an A/AAAA record. + + const noARecordsNoticeText = + 'Please create an A/AAAA record for this domain to avoid a Zone File invalidation.'; + + const otherErrors = [ + getAPIErrorFor({}, this.state.errors)('_unknown'), + getAPIErrorFor({}, this.state.errors)('none'), + ].filter(Boolean); + + return ( + + {otherErrors.length > 0 && + otherErrors.map((err, index) => { + return ; + })} + {!hasARecords && type === 'NS' && ( + + )} + {fields.map((field: any, idx: number) => field(idx))} + + + + ); + } } const modeMap = { diff --git a/packages/manager/src/features/Domains/DomainZoneImportDrawer.tsx b/packages/manager/src/features/Domains/DomainZoneImportDrawer.tsx index 0a59f0428a7..51803d22c3f 100644 --- a/packages/manager/src/features/Domains/DomainZoneImportDrawer.tsx +++ b/packages/manager/src/features/Domains/DomainZoneImportDrawer.tsx @@ -1,16 +1,17 @@ -import { ImportZonePayload } from '@linode/api-v4/lib/domains'; +import { Notice } from '@linode/ui'; import { useFormik } from 'formik'; import * as React from 'react'; import { useHistory } from 'react-router-dom'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Drawer } from 'src/components/Drawer'; -import { Notice } from 'src/components/Notice/Notice'; import { TextField } from 'src/components/TextField'; import { useImportZoneMutation } from 'src/queries/domains'; import { useGrants, useProfile } from 'src/queries/profile/profile'; import { getErrorMap } from 'src/utilities/errorUtils'; +import type { ImportZonePayload } from '@linode/api-v4/lib/domains'; + interface DomainZoneImportDrawerProps { onClose: () => void; open: boolean; diff --git a/packages/manager/src/features/Domains/DomainsLanding.tsx b/packages/manager/src/features/Domains/DomainsLanding.tsx index beb82cdaf22..a3ff5e3ec67 100644 --- a/packages/manager/src/features/Domains/DomainsLanding.tsx +++ b/packages/manager/src/features/Domains/DomainsLanding.tsx @@ -1,3 +1,4 @@ +import { Notice } from '@linode/ui'; import { styled } from '@mui/material/styles'; import { createLazyRoute } from '@tanstack/react-router'; import { useSnackbar } from 'notistack'; @@ -11,7 +12,6 @@ import { DocumentTitleSegment } from 'src/components/DocumentTitle'; import { ErrorState } from 'src/components/ErrorState/ErrorState'; import { Hidden } from 'src/components/Hidden'; import { LandingHeader } from 'src/components/LandingHeader'; -import { Notice } from 'src/components/Notice/Notice'; import { PaginationFooter } from 'src/components/PaginationFooter/PaginationFooter'; import { Table } from 'src/components/Table'; import { TableBody } from 'src/components/TableBody'; diff --git a/packages/manager/src/features/Domains/EditDomainDrawer.tsx b/packages/manager/src/features/Domains/EditDomainDrawer.tsx index 14c2c3c0c31..c664e3fb742 100644 --- a/packages/manager/src/features/Domains/EditDomainDrawer.tsx +++ b/packages/manager/src/features/Domains/EditDomainDrawer.tsx @@ -1,4 +1,4 @@ -import { Domain, UpdateDomainPayload } from '@linode/api-v4/lib/domains'; +import { Notice } from '@linode/ui'; import { useFormik } from 'formik'; import * as React from 'react'; @@ -6,7 +6,6 @@ import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Drawer } from 'src/components/Drawer'; import { FormControlLabel } from 'src/components/FormControlLabel'; import { MultipleIPInput } from 'src/components/MultipleIPInput/MultipleIPInput'; -import { Notice } from 'src/components/Notice/Notice'; import { Radio } from 'src/components/Radio/Radio'; import { RadioGroup } from 'src/components/RadioGroup'; import { TagsInput } from 'src/components/TagsInput/TagsInput'; @@ -15,14 +14,13 @@ import { useUpdateDomainMutation } from 'src/queries/domains'; import { useGrants, useProfile } from 'src/queries/profile/profile'; import { getErrorMap } from 'src/utilities/errorUtils'; import { handleFormikBlur } from 'src/utilities/formikTrimUtil'; -import { - ExtendedIP, - extendedIPToString, - stringToExtendedIP, -} from 'src/utilities/ipUtils'; +import { extendedIPToString, stringToExtendedIP } from 'src/utilities/ipUtils'; import { transferHelperText as helperText } from './domainUtils'; +import type { Domain, UpdateDomainPayload } from '@linode/api-v4/lib/domains'; +import type { ExtendedIP } from 'src/utilities/ipUtils'; + interface EditDomainDrawerProps { domain: Domain | undefined; onClose: () => void; diff --git a/packages/manager/src/features/EntityTransfers/EntityTransfersCreate/EntityTransferCreate.styles.ts b/packages/manager/src/features/EntityTransfers/EntityTransfersCreate/EntityTransferCreate.styles.ts index c9ba37b7794..aea30496629 100644 --- a/packages/manager/src/features/EntityTransfers/EntityTransfersCreate/EntityTransferCreate.styles.ts +++ b/packages/manager/src/features/EntityTransfers/EntityTransfersCreate/EntityTransferCreate.styles.ts @@ -1,7 +1,6 @@ -import Grid from '@mui/material/Unstable_Grid2'; +import { Notice } from '@linode/ui'; import { styled } from '@mui/material/styles'; - -import { Notice } from 'src/components/Notice/Notice'; +import Grid from '@mui/material/Unstable_Grid2'; export const StyledNotice = styled(Notice, { label: 'StyledNotice', diff --git a/packages/manager/src/features/EntityTransfers/EntityTransfersLanding/ConfirmTransferCancelDialog.tsx b/packages/manager/src/features/EntityTransfers/EntityTransfersLanding/ConfirmTransferCancelDialog.tsx index e282dc76cd6..2c1d12c8934 100644 --- a/packages/manager/src/features/EntityTransfers/EntityTransfersLanding/ConfirmTransferCancelDialog.tsx +++ b/packages/manager/src/features/EntityTransfers/EntityTransfersLanding/ConfirmTransferCancelDialog.tsx @@ -1,20 +1,19 @@ -import { - TransferEntities, - cancelTransfer, -} from '@linode/api-v4/lib/entity-transfers'; -import { APIError } from '@linode/api-v4/lib/types'; +import { cancelTransfer } from '@linode/api-v4/lib/entity-transfers'; +import { Notice } from '@linode/ui'; +import { useQueryClient } from '@tanstack/react-query'; import { useSnackbar } from 'notistack'; import * as React from 'react'; -import { useQueryClient } from '@tanstack/react-query'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { ConfirmationDialog } from 'src/components/ConfirmationDialog/ConfirmationDialog'; -import { Notice } from 'src/components/Notice/Notice'; import { Typography } from 'src/components/Typography'; import { queryKey } from 'src/queries/entityTransfers'; import { sendEntityTransferCancelEvent } from 'src/utilities/analytics/customEventAnalytics'; import { getAPIErrorOrDefault } from 'src/utilities/errorUtils'; +import type { TransferEntities } from '@linode/api-v4/lib/entity-transfers'; +import type { APIError } from '@linode/api-v4/lib/types'; + export interface Props { entities?: TransferEntities; onClose: () => void; diff --git a/packages/manager/src/features/EntityTransfers/EntityTransfersLanding/ConfirmTransferDialog.tsx b/packages/manager/src/features/EntityTransfers/EntityTransfersLanding/ConfirmTransferDialog.tsx index d1f99dab257..c79cecf7e04 100644 --- a/packages/manager/src/features/EntityTransfers/EntityTransfersLanding/ConfirmTransferDialog.tsx +++ b/packages/manager/src/features/EntityTransfers/EntityTransfersLanding/ConfirmTransferDialog.tsx @@ -1,17 +1,13 @@ -import { - TransferEntities, - acceptEntityTransfer, -} from '@linode/api-v4/lib/entity-transfers'; -import { APIError } from '@linode/api-v4/lib/types'; +import { acceptEntityTransfer } from '@linode/api-v4/lib/entity-transfers'; +import { Notice } from '@linode/ui'; +import { useQueryClient } from '@tanstack/react-query'; import { useSnackbar } from 'notistack'; import * as React from 'react'; -import { useQueryClient } from '@tanstack/react-query'; import { Checkbox } from 'src/components/Checkbox'; import { CircleProgress } from 'src/components/CircleProgress'; import { ConfirmationDialog } from 'src/components/ConfirmationDialog/ConfirmationDialog'; import { ErrorState } from 'src/components/ErrorState/ErrorState'; -import { Notice } from 'src/components/Notice/Notice'; import { TRANSFER_FILTERS, queryKey, @@ -35,6 +31,9 @@ import { StyledUl, } from './ConfirmTransferDialog.styles'; +import type { TransferEntities } from '@linode/api-v4/lib/entity-transfers'; +import type { APIError } from '@linode/api-v4/lib/types'; + export interface ConfirmTransferDialogProps { onClose: () => void; open: boolean; diff --git a/packages/manager/src/features/Firewalls/FirewallDetail/Devices/AddLinodeDrawer.tsx b/packages/manager/src/features/Firewalls/FirewallDetail/Devices/AddLinodeDrawer.tsx index cd4eab3e95d..faf5bf4a53c 100644 --- a/packages/manager/src/features/Firewalls/FirewallDetail/Devices/AddLinodeDrawer.tsx +++ b/packages/manager/src/features/Firewalls/FirewallDetail/Devices/AddLinodeDrawer.tsx @@ -1,3 +1,4 @@ +import { Notice } from '@linode/ui'; import { useTheme } from '@mui/material'; import { useSnackbar } from 'notistack'; import * as React from 'react'; @@ -6,7 +7,6 @@ import { useParams } from 'react-router-dom'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Drawer } from 'src/components/Drawer'; import { Link } from 'src/components/Link'; -import { Notice } from 'src/components/Notice/Notice'; import { SupportLink } from 'src/components/SupportLink'; import { LinodeSelect } from 'src/features/Linodes/LinodeSelect/LinodeSelect'; import { diff --git a/packages/manager/src/features/Firewalls/FirewallDetail/Devices/AddNodebalancerDrawer.tsx b/packages/manager/src/features/Firewalls/FirewallDetail/Devices/AddNodebalancerDrawer.tsx index 86f799f810a..28ea6434f45 100644 --- a/packages/manager/src/features/Firewalls/FirewallDetail/Devices/AddNodebalancerDrawer.tsx +++ b/packages/manager/src/features/Firewalls/FirewallDetail/Devices/AddNodebalancerDrawer.tsx @@ -1,3 +1,4 @@ +import { Notice } from '@linode/ui'; import { useTheme } from '@mui/material'; import { useSnackbar } from 'notistack'; import * as React from 'react'; @@ -6,7 +7,6 @@ import { useParams } from 'react-router-dom'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Drawer } from 'src/components/Drawer'; import { Link } from 'src/components/Link'; -import { Notice } from 'src/components/Notice/Notice'; import { SupportLink } from 'src/components/SupportLink'; import { FIREWALL_LIMITS_CONSIDERATIONS_LINK } from 'src/constants'; import { NodeBalancerSelect } from 'src/features/NodeBalancers/NodeBalancerSelect'; diff --git a/packages/manager/src/features/Firewalls/FirewallDetail/Devices/FirewallDeviceLanding.tsx b/packages/manager/src/features/Firewalls/FirewallDetail/Devices/FirewallDeviceLanding.tsx index 7943230962a..41e3135af1c 100644 --- a/packages/manager/src/features/Firewalls/FirewallDetail/Devices/FirewallDeviceLanding.tsx +++ b/packages/manager/src/features/Firewalls/FirewallDetail/Devices/FirewallDeviceLanding.tsx @@ -1,12 +1,12 @@ -import { useTheme } from '@mui/material/styles'; +import { Notice } from '@linode/ui'; import { styled } from '@mui/material/styles'; +import { useTheme } from '@mui/material/styles'; import Grid from '@mui/material/Unstable_Grid2'; import * as React from 'react'; import { useHistory, useLocation, useRouteMatch } from 'react-router-dom'; import { Button } from 'src/components/Button/Button'; import { DebouncedSearchTextField } from 'src/components/DebouncedSearchTextField'; -import { Notice } from 'src/components/Notice/Notice'; import { Typography } from 'src/components/Typography'; import { useAllFirewallDevicesQuery } from 'src/queries/firewalls'; diff --git a/packages/manager/src/features/Firewalls/FirewallDetail/Rules/FirewallRuleForm.tsx b/packages/manager/src/features/Firewalls/FirewallDetail/Rules/FirewallRuleForm.tsx index a0beae974dc..3a9ac80fcf8 100644 --- a/packages/manager/src/features/Firewalls/FirewallDetail/Rules/FirewallRuleForm.tsx +++ b/packages/manager/src/features/Firewalls/FirewallDetail/Rules/FirewallRuleForm.tsx @@ -1,3 +1,4 @@ +import { Notice } from '@linode/ui'; import { styled } from '@mui/material/styles'; import * as React from 'react'; @@ -5,14 +6,11 @@ import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Autocomplete } from 'src/components/Autocomplete/Autocomplete'; import { FormControlLabel } from 'src/components/FormControlLabel'; import { MultipleIPInput } from 'src/components/MultipleIPInput/MultipleIPInput'; -import { Notice } from 'src/components/Notice/Notice'; import { Radio } from 'src/components/Radio/Radio'; import { RadioGroup } from 'src/components/RadioGroup'; import { TextField } from 'src/components/TextField'; import { Typography } from 'src/components/Typography'; import { - FirewallOptionItem, - FirewallPreset, addressOptions, firewallOptionItemsShort, portPresets, @@ -25,6 +23,10 @@ import { enforceIPMasks } from './FirewallRuleDrawer.utils'; import { PORT_PRESETS, PORT_PRESETS_ITEMS } from './shared'; import type { FirewallRuleFormProps } from './FirewallRuleDrawer.types'; +import type { + FirewallOptionItem, + FirewallPreset, +} from 'src/features/Firewalls/shared'; import type { ExtendedIP } from 'src/utilities/ipUtils'; const ipNetmaskTooltipText = @@ -84,7 +86,7 @@ export const FirewallRuleForm = React.memo((props: FirewallRuleFormProps) => { // These handlers are all memoized because the form was laggy when I tried them inline. const handleTypeChange = React.useCallback( - (item: FirewallOptionItem | null) => { + (item: FirewallOptionItem<'custom' | FirewallPreset> | null) => { const selectedType = item?.value; // If the user re-selects the same preset or selectedType is undefined, don't do anything @@ -207,13 +209,13 @@ export const FirewallRuleForm = React.memo((props: FirewallRuleFormProps) => { /> )} { 'data-qa-protocol-select': true, }, }} - autoHighlight aria-label="Select rule protocol." - errorText={errors.protocol} + autoHighlight disableClearable + errorText={errors.protocol} label="Protocol" onBlur={handleBlur} onChange={(_, selected) => handleProtocolChange(selected.value)} @@ -264,26 +266,26 @@ export const FirewallRuleForm = React.memo((props: FirewallRuleFormProps) => { /> 0 ? ' ' : 'Select a port...'} + multiple onChange={(_, selected) => handlePortPresetChange(selected)} options={portOptions} + // If options are selected, hide the placeholder + placeholder={presetPorts.length > 0 ? ' ' : 'Select a port...'} value={presetPorts} /> {hasCustomInput ? ( @@ -299,6 +301,9 @@ export const FirewallRuleForm = React.memo((props: FirewallRuleFormProps) => { /> ) : null} { + handleAddressesChange(selected.value); + }} textFieldProps={{ InputProps: { required: true, @@ -307,15 +312,12 @@ export const FirewallRuleForm = React.memo((props: FirewallRuleFormProps) => { 'data-qa-address-source-select': true, }, }} - autoHighlight aria-label={`Select rule ${addressesLabel}s.`} - errorText={errors.addresses} + autoHighlight disableClearable + errorText={errors.addresses} label={`${capitalize(addressesLabel)}s`} onBlur={handleBlur} - onChange={(_, selected) => { - handleAddressesChange(selected.value); - }} options={addressOptions} placeholder={`Select ${addressesLabel}s...`} value={addressesValue} diff --git a/packages/manager/src/features/Firewalls/FirewallDetail/Rules/FirewallRulesLanding.tsx b/packages/manager/src/features/Firewalls/FirewallDetail/Rules/FirewallRulesLanding.tsx index d998e9809b2..6d010ca9717 100644 --- a/packages/manager/src/features/Firewalls/FirewallDetail/Rules/FirewallRulesLanding.tsx +++ b/packages/manager/src/features/Firewalls/FirewallDetail/Rules/FirewallRulesLanding.tsx @@ -1,3 +1,4 @@ +import { Notice } from '@linode/ui'; import { styled } from '@mui/material/styles'; import { useQueryClient } from '@tanstack/react-query'; import { useSnackbar } from 'notistack'; @@ -5,7 +6,6 @@ import * as React from 'react'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { ConfirmationDialog } from 'src/components/ConfirmationDialog/ConfirmationDialog'; -import { Notice } from 'src/components/Notice/Notice'; import { Prompt } from 'src/components/Prompt/Prompt'; import { Typography } from 'src/components/Typography'; import { diff --git a/packages/manager/src/features/Firewalls/FirewallLanding/CreateFirewallDrawer.tsx b/packages/manager/src/features/Firewalls/FirewallLanding/CreateFirewallDrawer.tsx index 3a728007b29..093f9592f8f 100644 --- a/packages/manager/src/features/Firewalls/FirewallLanding/CreateFirewallDrawer.tsx +++ b/packages/manager/src/features/Firewalls/FirewallLanding/CreateFirewallDrawer.tsx @@ -1,5 +1,5 @@ /* eslint-disable jsx-a11y/anchor-is-valid */ -import { Box } from '@linode/ui'; +import { Box, Notice } from '@linode/ui'; import { CreateFirewallSchema } from '@linode/validation/lib/firewalls.schema'; import { useFormik } from 'formik'; import { useSnackbar } from 'notistack'; @@ -11,7 +11,6 @@ import { Drawer } from 'src/components/Drawer'; import { ErrorMessage } from 'src/components/ErrorMessage'; import { FormControlLabel } from 'src/components/FormControlLabel'; import { Link } from 'src/components/Link'; -import { Notice } from 'src/components/Notice/Notice'; import { Radio } from 'src/components/Radio/Radio'; import { RadioGroup } from 'src/components/RadioGroup'; import { TextField } from 'src/components/TextField'; diff --git a/packages/manager/src/features/Footer.tsx b/packages/manager/src/features/Footer.tsx index b4cf958c96f..001ca7adaed 100644 --- a/packages/manager/src/features/Footer.tsx +++ b/packages/manager/src/features/Footer.tsx @@ -1,4 +1,4 @@ -import Stack from '@mui/material/Stack'; +import { Stack } from '@linode/ui'; import * as React from 'react'; import { Link } from 'src/components/Link'; diff --git a/packages/manager/src/features/GlobalNotifications/APIMaintenanceBanner.tsx b/packages/manager/src/features/GlobalNotifications/APIMaintenanceBanner.tsx index 4e8316e03d1..b784a113d80 100644 --- a/packages/manager/src/features/GlobalNotifications/APIMaintenanceBanner.tsx +++ b/packages/manager/src/features/GlobalNotifications/APIMaintenanceBanner.tsx @@ -1,14 +1,16 @@ +import { Stack } from '@linode/ui'; import * as React from 'react'; import { DismissibleBanner } from 'src/components/DismissibleBanner/DismissibleBanner'; import { Link } from 'src/components/Link'; -import { Stack } from 'src/components/Stack'; import { Typography } from 'src/components/Typography'; -import { SuppliedMaintenanceData } from 'src/featureFlags'; import { queryPresets } from 'src/queries/base'; -import { Maintenance, useMaintenanceQuery } from 'src/queries/statusPage'; +import { useMaintenanceQuery } from 'src/queries/statusPage'; import { sanitizeHTML } from 'src/utilities/sanitizeHTML'; +import type { SuppliedMaintenanceData } from 'src/featureFlags'; +import type { Maintenance } from 'src/queries/statusPage'; + interface Props { suppliedMaintenances: SuppliedMaintenanceData[] | undefined; } diff --git a/packages/manager/src/features/GlobalNotifications/DatabaseClusterInfoBanner.tsx b/packages/manager/src/features/GlobalNotifications/DatabaseClusterInfoBanner.tsx index dd09facc8b8..d844382a34d 100644 --- a/packages/manager/src/features/GlobalNotifications/DatabaseClusterInfoBanner.tsx +++ b/packages/manager/src/features/GlobalNotifications/DatabaseClusterInfoBanner.tsx @@ -1,8 +1,8 @@ +import { Notice } from '@linode/ui'; import { Box } from '@mui/material'; import { styled } from '@mui/material/styles'; import * as React from 'react'; -import { Notice } from 'src/components/Notice/Notice'; import { Typography } from 'src/components/Typography'; import { useIsDatabasesEnabled } from '../Databases/utilities'; diff --git a/packages/manager/src/features/GlobalNotifications/EmailBounce.tsx b/packages/manager/src/features/GlobalNotifications/EmailBounce.tsx index 65d4a952805..63b02b09e94 100644 --- a/packages/manager/src/features/GlobalNotifications/EmailBounce.tsx +++ b/packages/manager/src/features/GlobalNotifications/EmailBounce.tsx @@ -1,12 +1,12 @@ +import { Notice } from '@linode/ui'; +import { useTheme } from '@mui/material/styles'; import Grid from '@mui/material/Unstable_Grid2'; -import { Theme, useTheme } from '@mui/material/styles'; import useMediaQuery from '@mui/material/useMediaQuery'; import { useSnackbar } from 'notistack'; import * as React from 'react'; import { useHistory } from 'react-router-dom'; import { Button } from 'src/components/Button/Button'; -import { Notice } from 'src/components/Notice/Notice'; import { Typography } from 'src/components/Typography'; import { useAccount, useMutateAccount } from 'src/queries/account/account'; import { useNotificationsQuery } from 'src/queries/account/notifications'; @@ -14,6 +14,8 @@ import { useMutateProfile, useProfile } from 'src/queries/profile/profile'; import { StyledGrid } from './EmailBounce.styles'; +import type { Theme } from '@mui/material/styles'; + // ============================================================================= // // ============================================================================= diff --git a/packages/manager/src/features/GlobalNotifications/RegionStatusBanner.tsx b/packages/manager/src/features/GlobalNotifications/RegionStatusBanner.tsx index f369b2e6146..d3adb497e06 100644 --- a/packages/manager/src/features/GlobalNotifications/RegionStatusBanner.tsx +++ b/packages/manager/src/features/GlobalNotifications/RegionStatusBanner.tsx @@ -1,7 +1,7 @@ +import { Notice } from '@linode/ui'; import * as React from 'react'; import { Link } from 'src/components/Link'; -import { Notice } from 'src/components/Notice/Notice'; import { Typography } from 'src/components/Typography'; import { useRegionsQuery } from 'src/queries/regions/regions'; diff --git a/packages/manager/src/features/GlobalNotifications/VerificationDetailsBanner.tsx b/packages/manager/src/features/GlobalNotifications/VerificationDetailsBanner.tsx index 715dbdcd6e4..38c705b2712 100644 --- a/packages/manager/src/features/GlobalNotifications/VerificationDetailsBanner.tsx +++ b/packages/manager/src/features/GlobalNotifications/VerificationDetailsBanner.tsx @@ -1,9 +1,8 @@ -import { Box } from '@linode/ui'; +import { Box, Notice } from '@linode/ui'; import React from 'react'; import { useHistory } from 'react-router-dom'; import { Button } from 'src/components/Button/Button'; -import { Notice } from 'src/components/Notice/Notice'; import { Typography } from 'src/components/Typography'; interface Props { diff --git a/packages/manager/src/features/Help/Panels/AlgoliaSearchBar.tsx b/packages/manager/src/features/Help/Panels/AlgoliaSearchBar.tsx index c6c2372b08b..9ea11aa21f4 100644 --- a/packages/manager/src/features/Help/Panels/AlgoliaSearchBar.tsx +++ b/packages/manager/src/features/Help/Panels/AlgoliaSearchBar.tsx @@ -1,18 +1,22 @@ +import { Notice } from '@linode/ui'; import Search from '@mui/icons-material/Search'; -import { Theme } from '@mui/material/styles'; import { pathOr } from 'ramda'; import * as React from 'react'; -import { RouteComponentProps, withRouter } from 'react-router-dom'; +import { withRouter } from 'react-router-dom'; import { debounce } from 'throttle-debounce'; import { makeStyles } from 'tss-react/mui'; -import EnhancedSelect, { Item } from 'src/components/EnhancedSelect'; -import { Notice } from 'src/components/Notice/Notice'; +import EnhancedSelect from 'src/components/EnhancedSelect'; import { selectStyles } from 'src/features/TopMenu/SearchBar/SearchBar'; -import withSearch, { AlgoliaState as AlgoliaProps } from '../SearchHOC'; +import withSearch from '../SearchHOC'; import { SearchItem } from './SearchItem'; +import type { AlgoliaState as AlgoliaProps } from '../SearchHOC'; +import type { Theme } from '@mui/material/styles'; +import type { RouteComponentProps } from 'react-router-dom'; +import type { Item } from 'src/components/EnhancedSelect'; + const useStyles = makeStyles()((theme: Theme) => ({ enhancedSelectWrapper: { '& .input': { diff --git a/packages/manager/src/features/Help/SupportSearchLanding/SupportSearchLanding.tsx b/packages/manager/src/features/Help/SupportSearchLanding/SupportSearchLanding.tsx index 24ccb36326a..bec36434a12 100644 --- a/packages/manager/src/features/Help/SupportSearchLanding/SupportSearchLanding.tsx +++ b/packages/manager/src/features/Help/SupportSearchLanding/SupportSearchLanding.tsx @@ -1,4 +1,4 @@ -import { Box, InputAdornment } from '@linode/ui'; +import { Box, InputAdornment, Notice } from '@linode/ui'; import Search from '@mui/icons-material/Search'; import Grid from '@mui/material/Unstable_Grid2'; import { createLazyRoute } from '@tanstack/react-router'; @@ -7,7 +7,6 @@ import { useHistory } from 'react-router-dom'; import { makeStyles } from 'tss-react/mui'; import { H1Header } from 'src/components/H1Header/H1Header'; -import { Notice } from 'src/components/Notice/Notice'; import { TextField } from 'src/components/TextField'; import { COMMUNITY_SEARCH_URL, DOCS_SEARCH_URL } from 'src/constants'; import { getQueryParamFromQueryString } from 'src/utilities/queryParams'; diff --git a/packages/manager/src/features/Images/ImagesCreate/CreateImageTab.tsx b/packages/manager/src/features/Images/ImagesCreate/CreateImageTab.tsx index 968a7b84174..26da650b1c4 100644 --- a/packages/manager/src/features/Images/ImagesCreate/CreateImageTab.tsx +++ b/packages/manager/src/features/Images/ImagesCreate/CreateImageTab.tsx @@ -1,4 +1,5 @@ import { yupResolver } from '@hookform/resolvers/yup'; +import { Notice, Paper, Stack } from '@linode/ui'; import { Box } from '@linode/ui'; import { createImageSchema } from '@linode/validation'; import { useSnackbar } from 'notistack'; @@ -12,9 +13,6 @@ import { Checkbox } from 'src/components/Checkbox'; import { DISK_ENCRYPTION_IMAGES_CAVEAT_COPY } from 'src/components/Encryption/constants'; import { useIsDiskEncryptionFeatureEnabled } from 'src/components/Encryption/utils'; import { Link } from 'src/components/Link'; -import { Notice } from 'src/components/Notice/Notice'; -import { Paper } from '@linode/ui'; -import { Stack } from 'src/components/Stack'; import { TagsInput } from 'src/components/TagsInput/TagsInput'; import { TextField } from 'src/components/TextField'; import { TooltipIcon } from 'src/components/TooltipIcon'; diff --git a/packages/manager/src/features/Images/ImagesCreate/ImageUpload.tsx b/packages/manager/src/features/Images/ImagesCreate/ImageUpload.tsx index 1aaebc172b9..7b1c0a8dbe9 100644 --- a/packages/manager/src/features/Images/ImagesCreate/ImageUpload.tsx +++ b/packages/manager/src/features/Images/ImagesCreate/ImageUpload.tsx @@ -1,4 +1,5 @@ import { yupResolver } from '@hookform/resolvers/yup'; +import { Notice, Paper, Stack } from '@linode/ui'; import { Box } from '@linode/ui'; import { useSnackbar } from 'notistack'; import React, { useState } from 'react'; @@ -12,11 +13,8 @@ import { Button } from 'src/components/Button/Button'; import { Checkbox } from 'src/components/Checkbox'; import { ConfirmationDialog } from 'src/components/ConfirmationDialog/ConfirmationDialog'; import { Link } from 'src/components/Link'; -import { Notice } from 'src/components/Notice/Notice'; -import { Paper } from '@linode/ui'; import { Prompt } from 'src/components/Prompt/Prompt'; import { RegionSelect } from 'src/components/RegionSelect/RegionSelect'; -import { Stack } from 'src/components/Stack'; import { TagsInput } from 'src/components/TagsInput/TagsInput'; import { TextField } from 'src/components/TextField'; import { Typography } from 'src/components/Typography'; diff --git a/packages/manager/src/features/Images/ImagesLanding/EditImageDrawer.tsx b/packages/manager/src/features/Images/ImagesLanding/EditImageDrawer.tsx index 09c2d02e8b2..bd3c629d050 100644 --- a/packages/manager/src/features/Images/ImagesLanding/EditImageDrawer.tsx +++ b/packages/manager/src/features/Images/ImagesLanding/EditImageDrawer.tsx @@ -1,11 +1,11 @@ import { yupResolver } from '@hookform/resolvers/yup'; +import { Notice } from '@linode/ui'; import { updateImageSchema } from '@linode/validation'; import * as React from 'react'; import { Controller, useForm } from 'react-hook-form'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Drawer } from 'src/components/Drawer'; -import { Notice } from 'src/components/Notice/Notice'; import { TagsInput } from 'src/components/TagsInput/TagsInput'; import { TextField } from 'src/components/TextField'; import { useUpdateImageMutation } from 'src/queries/images'; diff --git a/packages/manager/src/features/Images/ImagesLanding/ImageRegions/ImageRegionRow.tsx b/packages/manager/src/features/Images/ImagesLanding/ImageRegions/ImageRegionRow.tsx index e60aefc45ab..0e8b07b032f 100644 --- a/packages/manager/src/features/Images/ImagesLanding/ImageRegions/ImageRegionRow.tsx +++ b/packages/manager/src/features/Images/ImagesLanding/ImageRegions/ImageRegionRow.tsx @@ -1,9 +1,8 @@ -import { Box, IconButton, Tooltip } from '@linode/ui'; +import { Box, IconButton, Stack, Tooltip } from '@linode/ui'; import Close from '@mui/icons-material/Close'; import React from 'react'; import { Flag } from 'src/components/Flag'; -import { Stack } from 'src/components/Stack'; import { StatusIcon } from 'src/components/StatusIcon/StatusIcon'; import { Typography } from 'src/components/Typography'; import { useRegionsQuery } from 'src/queries/regions/regions'; diff --git a/packages/manager/src/features/Images/ImagesLanding/ImageRegions/ManageImageRegionsForm.tsx b/packages/manager/src/features/Images/ImagesLanding/ImageRegions/ManageImageRegionsForm.tsx index 85c800b961f..02f3a154219 100644 --- a/packages/manager/src/features/Images/ImagesLanding/ImageRegions/ManageImageRegionsForm.tsx +++ b/packages/manager/src/features/Images/ImagesLanding/ImageRegions/ManageImageRegionsForm.tsx @@ -1,13 +1,11 @@ +import { Notice, Paper, Stack } from '@linode/ui'; import { useSnackbar } from 'notistack'; import React from 'react'; import { useForm } from 'react-hook-form'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Link } from 'src/components/Link'; -import { Notice } from 'src/components/Notice/Notice'; -import { Paper } from '@linode/ui'; import { RegionMultiSelect } from 'src/components/RegionSelect/RegionMultiSelect'; -import { Stack } from 'src/components/Stack'; import { Typography } from 'src/components/Typography'; import { useUpdateImageRegionsMutation } from 'src/queries/images'; import { useRegionsQuery } from 'src/queries/regions/regions'; @@ -21,7 +19,7 @@ import type { UpdateImageRegionsPayload, } from '@linode/api-v4'; import type { Resolver } from 'react-hook-form'; -import type { DisableRegionOption } from 'src/components/RegionSelect/RegionSelect.types'; +import type { DisableItemOption } from 'src/components/ListItemOption'; interface Props { image: Image | undefined; @@ -79,7 +77,7 @@ export const ManageImageReplicasForm = (props: Props) => { const values = watch(); - const disabledRegions: Record = {}; + const disabledRegions: Record = {}; const availableRegions = image?.regions.filter( (regionItem) => regionItem.status === 'available' diff --git a/packages/manager/src/features/Images/ImagesLanding/ImageRow.tsx b/packages/manager/src/features/Images/ImagesLanding/ImageRow.tsx index 4915ce42a5d..b3640a1b32a 100644 --- a/packages/manager/src/features/Images/ImagesLanding/ImageRow.tsx +++ b/packages/manager/src/features/Images/ImagesLanding/ImageRow.tsx @@ -1,10 +1,9 @@ -import { Tooltip } from '@linode/ui'; +import { Stack, Tooltip } from '@linode/ui'; import React from 'react'; import CloudInitIcon from 'src/assets/icons/cloud-init.svg'; import { Hidden } from 'src/components/Hidden'; import { LinkButton } from 'src/components/LinkButton'; -import { Stack } from 'src/components/Stack'; import { TableCell } from 'src/components/TableCell'; import { TableRow } from 'src/components/TableRow'; import { Typography } from 'src/components/Typography'; diff --git a/packages/manager/src/features/Images/ImagesLanding/ImagesLanding.tsx b/packages/manager/src/features/Images/ImagesLanding/ImagesLanding.tsx index d002d4c97e7..9882d8e8694 100644 --- a/packages/manager/src/features/Images/ImagesLanding/ImagesLanding.tsx +++ b/packages/manager/src/features/Images/ImagesLanding/ImagesLanding.tsx @@ -1,4 +1,4 @@ -import { IconButton, InputAdornment, Paper } from '@linode/ui'; +import { IconButton, InputAdornment, Notice, Paper } from '@linode/ui'; import CloseIcon from '@mui/icons-material/Close'; import { useQueryClient } from '@tanstack/react-query'; import { createLazyRoute } from '@tanstack/react-router'; @@ -16,7 +16,6 @@ import { Drawer } from 'src/components/Drawer'; import { ErrorState } from 'src/components/ErrorState/ErrorState'; import { Hidden } from 'src/components/Hidden'; import { LandingHeader } from 'src/components/LandingHeader'; -import { Notice } from 'src/components/Notice/Notice'; import { PaginationFooter } from 'src/components/PaginationFooter/PaginationFooter'; import { Table } from 'src/components/Table'; import { TableBody } from 'src/components/TableBody'; diff --git a/packages/manager/src/features/Images/ImagesLanding/RebuildImageDrawer.tsx b/packages/manager/src/features/Images/ImagesLanding/RebuildImageDrawer.tsx index dc2bf134a93..fc881f29992 100644 --- a/packages/manager/src/features/Images/ImagesLanding/RebuildImageDrawer.tsx +++ b/packages/manager/src/features/Images/ImagesLanding/RebuildImageDrawer.tsx @@ -1,13 +1,11 @@ +import { Divider, Notice, Stack } from '@linode/ui'; import * as React from 'react'; import { Controller, useForm } from 'react-hook-form'; import { useHistory } from 'react-router-dom'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { DescriptionList } from 'src/components/DescriptionList/DescriptionList'; -import { Divider } from 'src/components/Divider'; import { Drawer } from 'src/components/Drawer'; -import { Notice } from 'src/components/Notice/Notice'; -import { Stack } from 'src/components/Stack'; import { LinodeSelect } from 'src/features/Linodes/LinodeSelect/LinodeSelect'; import { REBUILD_LINODE_IMAGE_PARAM_NAME } from '../../Linodes/LinodesDetail/LinodeRebuild/RebuildFromImage'; diff --git a/packages/manager/src/features/Kubernetes/CreateCluster/ControlPlaneACLPane.tsx b/packages/manager/src/features/Kubernetes/CreateCluster/ControlPlaneACLPane.tsx index de7cfb34c41..5d672fda40a 100644 --- a/packages/manager/src/features/Kubernetes/CreateCluster/ControlPlaneACLPane.tsx +++ b/packages/manager/src/features/Kubernetes/CreateCluster/ControlPlaneACLPane.tsx @@ -1,11 +1,10 @@ -import { Box, FormControl } from '@linode/ui'; +import { Box, FormControl, Notice } from '@linode/ui'; import { FormLabel } from '@mui/material'; import * as React from 'react'; import { ErrorMessage } from 'src/components/ErrorMessage'; import { FormControlLabel } from 'src/components/FormControlLabel'; import { MultipleIPInput } from 'src/components/MultipleIPInput/MultipleIPInput'; -import { Notice } from 'src/components/Notice/Notice'; import { Toggle } from 'src/components/Toggle/Toggle'; import { Typography } from 'src/components/Typography'; import { validateIPs } from 'src/utilities/ipUtils'; diff --git a/packages/manager/src/features/Kubernetes/CreateCluster/CreateCluster.styles.ts b/packages/manager/src/features/Kubernetes/CreateCluster/CreateCluster.styles.ts index d9864096ce4..1dfcbc34a65 100644 --- a/packages/manager/src/features/Kubernetes/CreateCluster/CreateCluster.styles.ts +++ b/packages/manager/src/features/Kubernetes/CreateCluster/CreateCluster.styles.ts @@ -1,9 +1,7 @@ -import { Box } from '@linode/ui'; +import { Box, Stack } from '@linode/ui'; import { styled } from '@mui/material/styles'; import { makeStyles } from 'tss-react/mui'; -import { Stack } from 'src/components/Stack'; - import type { Theme } from '@mui/material/styles'; export const useStyles = makeStyles()((theme: Theme) => ({ diff --git a/packages/manager/src/features/Kubernetes/CreateCluster/CreateCluster.tsx b/packages/manager/src/features/Kubernetes/CreateCluster/CreateCluster.tsx index f77e7250caa..2cda374ee3f 100644 --- a/packages/manager/src/features/Kubernetes/CreateCluster/CreateCluster.tsx +++ b/packages/manager/src/features/Kubernetes/CreateCluster/CreateCluster.tsx @@ -1,4 +1,4 @@ -import { Box, Paper } from '@linode/ui'; +import { Box, Notice, Paper, Stack } from '@linode/ui'; import { Divider } from '@mui/material'; import Grid from '@mui/material/Unstable_Grid2'; import { createLazyRoute } from '@tanstack/react-router'; @@ -12,10 +12,8 @@ import { DocumentTitleSegment } from 'src/components/DocumentTitle'; import { ErrorMessage } from 'src/components/ErrorMessage'; import { ErrorState } from 'src/components/ErrorState/ErrorState'; import { LandingHeader } from 'src/components/LandingHeader'; -import { Notice } from 'src/components/Notice/Notice'; import { RegionSelect } from 'src/components/RegionSelect/RegionSelect'; import { RegionHelperText } from 'src/components/SelectRegionPanel/RegionHelperText'; -import { Stack } from 'src/components/Stack'; import { TextField } from 'src/components/TextField'; import { getKubeControlPlaneACL, @@ -79,7 +77,7 @@ export const CreateCluster = () => { const formContainerRef = React.useRef(null); const { mutateAsync: updateAccountAgreements } = useMutateAccountAgreements(); const [highAvailability, setHighAvailability] = React.useState(); - const [controlPlaneACL, setControlPlaneACL] = React.useState(true); + const [controlPlaneACL, setControlPlaneACL] = React.useState(false); const [apl_enabled, setApl_enabled] = React.useState(false); const { data, error: regionsError } = useRegionsQuery(); diff --git a/packages/manager/src/features/Kubernetes/CreateCluster/HAControlPlane.tsx b/packages/manager/src/features/Kubernetes/CreateCluster/HAControlPlane.tsx index 30496031138..789ecf75a7c 100644 --- a/packages/manager/src/features/Kubernetes/CreateCluster/HAControlPlane.tsx +++ b/packages/manager/src/features/Kubernetes/CreateCluster/HAControlPlane.tsx @@ -1,11 +1,10 @@ -import { Box, FormControl } from '@linode/ui'; +import { Box, FormControl, Notice } from '@linode/ui'; import { FormLabel } from '@mui/material'; import * as React from 'react'; import { CircleProgress } from 'src/components/CircleProgress'; import { FormControlLabel } from 'src/components/FormControlLabel'; import { Link } from 'src/components/Link'; -import { Notice } from 'src/components/Notice/Notice'; import { Radio } from 'src/components/Radio/Radio'; import { RadioGroup } from 'src/components/RadioGroup'; import { TooltipIcon } from 'src/components/TooltipIcon'; diff --git a/packages/manager/src/features/Kubernetes/KubeCheckoutBar/KubeCheckoutBar.tsx b/packages/manager/src/features/Kubernetes/KubeCheckoutBar/KubeCheckoutBar.tsx index fcf4339ed35..a44ad7ce3dd 100644 --- a/packages/manager/src/features/Kubernetes/KubeCheckoutBar/KubeCheckoutBar.tsx +++ b/packages/manager/src/features/Kubernetes/KubeCheckoutBar/KubeCheckoutBar.tsx @@ -1,11 +1,9 @@ -import { Box } from '@linode/ui'; +import { Box, Divider, Notice } from '@linode/ui'; import { Typography, styled } from '@mui/material'; import * as React from 'react'; import { CheckoutBar } from 'src/components/CheckoutBar/CheckoutBar'; import { CircleProgress } from 'src/components/CircleProgress'; -import { Divider } from 'src/components/Divider'; -import { Notice } from 'src/components/Notice/Notice'; import { RenderGuard } from 'src/components/RenderGuard'; import { EUAgreementCheckbox } from 'src/features/Account/Agreements/EUAgreementCheckbox'; import { useAccountAgreements } from 'src/queries/account/agreements'; diff --git a/packages/manager/src/features/Kubernetes/KubeCheckoutBar/NodePoolSummary.tsx b/packages/manager/src/features/Kubernetes/KubeCheckoutBar/NodePoolSummary.tsx index 7215aa6bf87..99163fa45c2 100644 --- a/packages/manager/src/features/Kubernetes/KubeCheckoutBar/NodePoolSummary.tsx +++ b/packages/manager/src/features/Kubernetes/KubeCheckoutBar/NodePoolSummary.tsx @@ -1,10 +1,9 @@ -import { Box, IconButton } from '@linode/ui'; +import { Box, Divider, IconButton } from '@linode/ui'; import Close from '@mui/icons-material/Close'; import * as React from 'react'; import { makeStyles } from 'tss-react/mui'; import { DisplayPrice } from 'src/components/DisplayPrice'; -import { Divider } from 'src/components/Divider'; import { EnhancedNumberInput } from 'src/components/EnhancedNumberInput/EnhancedNumberInput'; import { Typography } from 'src/components/Typography'; import { pluralize } from 'src/utilities/pluralize'; diff --git a/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/DeleteKubernetesClusterDialog.tsx b/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/DeleteKubernetesClusterDialog.tsx index b1e13f1a5ab..a991632db14 100644 --- a/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/DeleteKubernetesClusterDialog.tsx +++ b/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/DeleteKubernetesClusterDialog.tsx @@ -1,9 +1,9 @@ +import { Notice } from '@linode/ui'; import * as React from 'react'; import { useHistory } from 'react-router-dom'; import { List } from 'src/components/List'; import { ListItem } from 'src/components/ListItem'; -import { Notice } from 'src/components/Notice/Notice'; import { TypeToConfirmDialog } from 'src/components/TypeToConfirmDialog/TypeToConfirmDialog'; import { Typography } from 'src/components/Typography'; import { useDeleteKubernetesClusterMutation } from 'src/queries/kubernetes'; diff --git a/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/KubeClusterSpecs.tsx b/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/KubeClusterSpecs.tsx index d7f2407acb3..ac02162e06e 100644 --- a/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/KubeClusterSpecs.tsx +++ b/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/KubeClusterSpecs.tsx @@ -32,7 +32,6 @@ interface Props { const useStyles = makeStyles()((theme: Theme) => ({ iconTextOuter: { - flexBasis: '72%', minWidth: 115, }, item: { @@ -45,16 +44,6 @@ const useStyles = makeStyles()((theme: Theme) => ({ paddingBottom: theme.spacing(1), paddingTop: theme.spacing(1), }, - mainGridContainer: { - position: 'relative', - [theme.breakpoints.up('lg')]: { - justifyContent: 'space-between', - }, - }, - root: { - marginBottom: theme.spacing(3), - padding: `${theme.spacing(2.5)} ${theme.spacing(2.5)} ${theme.spacing(3)}`, - }, tooltip: { '& .MuiTooltip-tooltip': { minWidth: 320, @@ -147,7 +136,7 @@ export const KubeClusterSpecs = React.memo((props: Props) => { }; return ( - + {kubeSpecsLeft.map(kubeSpecItem)} {kubeSpecsRight.map(kubeSpecItem)} diff --git a/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/KubeConfigDisplay.tsx b/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/KubeConfigDisplay.tsx index 810a4c92446..2a762da39b8 100644 --- a/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/KubeConfigDisplay.tsx +++ b/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/KubeConfigDisplay.tsx @@ -1,5 +1,4 @@ -import { Box } from '@linode/ui'; -import Grid from '@mui/material/Unstable_Grid2'; +import { Box, Stack } from '@linode/ui'; import { useSnackbar } from 'notistack'; import * as React from 'react'; import { makeStyles } from 'tss-react/mui'; @@ -7,6 +6,7 @@ import { makeStyles } from 'tss-react/mui'; import DetailsIcon from 'src/assets/icons/code-file.svg'; import DownloadIcon from 'src/assets/icons/lke-download.svg'; import ResetIcon from 'src/assets/icons/reset.svg'; +import CopyIcon from 'src/assets/icons/copy.svg'; import { MaskableText } from 'src/components/MaskableText/MaskableText'; import { Typography } from 'src/components/Typography'; import { @@ -15,8 +15,11 @@ import { } from 'src/queries/kubernetes'; import { downloadFile } from 'src/utilities/downloadFile'; import { getAPIErrorOrDefault } from 'src/utilities/errorUtils'; +import copy from 'copy-to-clipboard'; +import { CircleProgress } from 'src/components/CircleProgress'; import type { Theme } from '@mui/material/styles'; +import { APIError } from '@linode/api-v4'; interface Props { clusterId: number; @@ -102,7 +105,30 @@ export const KubeConfigDisplay = (props: Props) => { const { enqueueSnackbar } = useSnackbar(); const { classes, cx } = useStyles(); - const { refetch } = useKubenetesKubeConfigQuery(clusterId); + const { isFetching, refetch: getKubeConfig } = useKubenetesKubeConfigQuery( + clusterId, + false + ); + + const onCopyToken = async () => { + try { + const { data } = await getKubeConfig(); + const token = data && data.match(/token:\s*(\S+)/); + if (token && token[1]) { + copy(token[1]); + } else { + enqueueSnackbar({ + message: 'Unable to find token within the Kubeconfig', + variant: 'error', + }); + } + } catch (error) { + enqueueSnackbar({ + message: (error as APIError[])[0].reason, + variant: 'error', + }); + } + }; const { data: endpoints, @@ -112,7 +138,7 @@ export const KubeConfigDisplay = (props: Props) => { const downloadKubeConfig = async () => { try { - const { data } = await refetch(); + const { data } = await getKubeConfig(); if (data) { downloadFile(`${clusterLabel}-kubeconfig.yaml`, data); @@ -135,8 +161,8 @@ export const KubeConfigDisplay = (props: Props) => { }; return ( - <> - + + Kubernetes API Endpoint: @@ -147,8 +173,8 @@ export const KubeConfigDisplay = (props: Props) => { endpointsLoading, endpointsError?.[0].reason )} - - + + Kubeconfig: @@ -169,6 +195,23 @@ export const KubeConfigDisplay = (props: Props) => { View + + {isFetching ? ( + + ) : ( + + )} + + Copy Token + + setResetKubeConfigDialogOpen(true)} @@ -189,7 +232,7 @@ export const KubeConfigDisplay = (props: Props) => { - - + + ); }; diff --git a/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/KubeControlPaneACLDrawer.tsx b/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/KubeControlPaneACLDrawer.tsx index 5daafad7648..65b282bf332 100644 --- a/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/KubeControlPaneACLDrawer.tsx +++ b/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/KubeControlPaneACLDrawer.tsx @@ -1,5 +1,5 @@ import { yupResolver } from '@hookform/resolvers/yup'; -import { Box, omittedProps } from '@linode/ui'; +import { Box, Notice, omittedProps } from '@linode/ui'; import { kubernetesControlPlaneACLPayloadSchema } from '@linode/validation'; import { Divider, Stack } from '@mui/material'; import { styled } from '@mui/material/styles'; @@ -11,7 +11,6 @@ import { Drawer } from 'src/components/Drawer'; import { DrawerContent } from 'src/components/DrawerContent'; import { FormControlLabel } from 'src/components/FormControlLabel'; import { MultipleNonExtendedIPInput } from 'src/components/MultipleIPInput/MultipleNonExtendedIPInput'; -import { Notice } from 'src/components/Notice/Notice'; import { TextField } from 'src/components/TextField'; import { Toggle } from 'src/components/Toggle/Toggle'; import { Typography } from 'src/components/Typography'; diff --git a/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/KubeSummaryPanel.tsx b/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/KubeSummaryPanel.tsx index 6b4cf458e50..a015b59c040 100644 --- a/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/KubeSummaryPanel.tsx +++ b/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/KubeSummaryPanel.tsx @@ -1,7 +1,6 @@ -import { Box } from '@linode/ui'; +import { Box, Stack } from '@linode/ui'; import OpenInNewIcon from '@mui/icons-material/OpenInNew'; import { useTheme } from '@mui/material/styles'; -import Grid from '@mui/material/Unstable_Grid2'; import { useSnackbar } from 'notistack'; import * as React from 'react'; @@ -11,7 +10,6 @@ import { Chip } from 'src/components/Chip'; import { ConfirmationDialog } from 'src/components/ConfirmationDialog/ConfirmationDialog'; import { EntityDetail } from 'src/components/EntityDetail/EntityDetail'; import { EntityHeader } from 'src/components/EntityHeader/EntityHeader'; -import { Stack } from 'src/components/Stack'; import { Typography } from 'src/components/Typography'; import { KubeClusterSpecs } from 'src/features/Kubernetes/KubernetesClusterDetail/KubeClusterSpecs'; import { getKubeControlPlaneACL } from 'src/features/Kubernetes/kubeUtils'; @@ -29,9 +27,10 @@ import { KubeConfigDisplay } from './KubeConfigDisplay'; import { KubeConfigDrawer } from './KubeConfigDrawer'; import { KubeControlPlaneACLDrawer } from './KubeControlPaneACLDrawer'; import { KubeEntityDetailFooter } from './KubeEntityDetailFooter'; -import { StyledActionRowGrid } from './KubeSummaryPanel.styles'; import type { KubernetesCluster } from '@linode/api-v4/lib/kubernetes'; +import { Hidden } from 'src/components/Hidden'; +import { ActionMenu } from 'src/components/ActionMenu/ActionMenu'; interface Props { cluster: KubernetesCluster; @@ -95,55 +94,32 @@ export const KubeSummaryPanel = React.memo((props: Props) => { setDrawerOpen(true); }; - const sxSpacing = { - paddingLeft: theme.spacing(3), - paddingRight: theme.spacing(1), - }; - - const sxMainGridContainer = { - paddingBottom: theme.spacing(2.5), - paddingTop: theme.spacing(2), - position: 'relative', - }; - return ( - + + - - + {cluster.control_plane.high_availability && ( + ({ + borderColor: theme.color.green, + position: 'absolute', + right: theme.spacing(3), + })} + label="HA CLUSTER" + size="small" + variant="outlined" /> - - - - {cluster.control_plane.high_availability && ( - ({ borderColor: theme.color.green })} - variant="outlined" - /> - )} - - - + )} + } footer={ { Summary - - { - window.open(dashboard?.url, '_blank'); - }} - sx={{ - '& svg': { - height: '14px', - marginLeft: '4px', - }, - alignItems: 'center', - display: 'flex', - }} - disabled={Boolean(dashboardError) || !dashboard} - > - Kubernetes Dashboard - - - setIsDeleteDialogOpen(true)} - > - Delete Cluster - + + + window.open(dashboard?.url, '_blank'), + title: 'Kubernetes Dashboard', + }, + { + onClick: () => setIsDeleteDialogOpen(true), + title: 'Delete Cluster', + }, + ]} + ariaLabel={`Action menu for Kubernetes Cluster ${cluster.label}`} + /> + + + } + onClick={() => window.open(dashboard?.url, '_blank')} + > + Kubernetes Dashboard + + setIsDeleteDialogOpen(true)}> + Delete Cluster + + } - noBodyBottomBorder /> { will no longer be able to access this cluster via your previous Kubeconfig file. This action cannot be undone. - + ); }); diff --git a/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/KubernetesClusterDetail.tsx b/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/KubernetesClusterDetail.tsx index e495d7db708..cc7c3e3e3e8 100644 --- a/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/KubernetesClusterDetail.tsx +++ b/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/KubernetesClusterDetail.tsx @@ -1,4 +1,4 @@ -import Grid from '@mui/material/Unstable_Grid2'; +import { Box, Stack } from '@linode/ui'; import { createLazyRoute } from '@tanstack/react-router'; import * as React from 'react'; import { useLocation, useParams } from 'react-router-dom'; @@ -78,16 +78,13 @@ export const KubernetesClusterDetail = () => { }; return ( - <> + - - - - + { docsLink="https://techdocs.akamai.com/cloud-computing/docs/getting-started-with-lke-linode-kubernetes-engine" title="Kubernetes Cluster Details" /> - + - - {showAPL && cluster.apl_enabled && ( - <> - - + {showAPL && cluster.apl_enabled && ( + + - - - )} - + + )} - + setIsUpgradeToHAOpen(false)} open={isUpgradeToHAOpen} regionID={cluster.region} /> - + ); }; diff --git a/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/NodePoolsDisplay/AddNodePoolDrawer.tsx b/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/NodePoolsDisplay/AddNodePoolDrawer.tsx index 9fedd22aac3..c858e21e93f 100644 --- a/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/NodePoolsDisplay/AddNodePoolDrawer.tsx +++ b/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/NodePoolsDisplay/AddNodePoolDrawer.tsx @@ -1,11 +1,10 @@ -import { Box } from '@linode/ui'; +import { Box, Notice } from '@linode/ui'; import * as React from 'react'; import { makeStyles } from 'tss-react/mui'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Drawer } from 'src/components/Drawer'; import { ErrorMessage } from 'src/components/ErrorMessage'; -import { Notice } from 'src/components/Notice/Notice'; import { Typography } from 'src/components/Typography'; import { useCreateNodePoolMutation } from 'src/queries/kubernetes'; import { useAllTypes } from 'src/queries/types'; diff --git a/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/NodePoolsDisplay/AutoscalePoolDialog.tsx b/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/NodePoolsDisplay/AutoscalePoolDialog.tsx index d0627395474..12de978e7d7 100644 --- a/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/NodePoolsDisplay/AutoscalePoolDialog.tsx +++ b/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/NodePoolsDisplay/AutoscalePoolDialog.tsx @@ -1,3 +1,4 @@ +import { Notice } from '@linode/ui'; import { AutoscaleNodePoolSchema } from '@linode/validation/lib/kubernetes.schema'; import Grid from '@mui/material/Unstable_Grid2'; import { useFormik } from 'formik'; @@ -10,7 +11,6 @@ import { Button } from 'src/components/Button/Button'; import { ConfirmationDialog } from 'src/components/ConfirmationDialog/ConfirmationDialog'; import { FormControlLabel } from 'src/components/FormControlLabel'; import { Link } from 'src/components/Link'; -import { Notice } from 'src/components/Notice/Notice'; import { TextField } from 'src/components/TextField'; import { Toggle } from 'src/components/Toggle/Toggle'; import { Typography } from 'src/components/Typography'; diff --git a/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/NodePoolsDisplay/NodePool.tsx b/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/NodePoolsDisplay/NodePool.tsx index 6f91f150b1c..f788c76b0ef 100644 --- a/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/NodePoolsDisplay/NodePool.tsx +++ b/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/NodePoolsDisplay/NodePool.tsx @@ -1,9 +1,9 @@ -import { Box, Paper, Tooltip } from '@linode/ui'; -import Grid from '@mui/material/Unstable_Grid2'; +import { Box, Paper, Stack, Tooltip } from '@linode/ui'; import * as React from 'react'; -import { makeStyles } from 'tss-react/mui'; +import { ActionMenu } from 'src/components/ActionMenu/ActionMenu'; import { StyledActionButton } from 'src/components/Button/StyledActionButton'; +import { Hidden } from 'src/components/Hidden'; import { Typography } from 'src/components/Typography'; import { NodeTable } from './NodeTable'; @@ -13,7 +13,6 @@ import type { PoolNodeResponse, } from '@linode/api-v4/lib/kubernetes'; import type { EncryptionStatus } from '@linode/api-v4/lib/linodes/types'; -import type { Theme } from '@mui/material/styles'; interface Props { autoscaler: AutoscaleSettings; @@ -29,19 +28,6 @@ interface Props { typeLabel: string; } -const useStyles = makeStyles()((theme: Theme) => ({ - autoscaleText: { - alignSelf: 'center', - paddingRight: theme.spacing(2), - }, - button: { - paddingRight: 8, - }, - deletePoolBtn: { - paddingRight: 8, - }, -})); - export const NodePool = (props: Props) => { const { autoscaler, @@ -57,10 +43,8 @@ export const NodePool = (props: Props) => { typeLabel, } = props; - const { classes } = useStyles(); - return ( - + { py: 0, }} > - - {typeLabel} - - - openAutoscalePoolDialog(poolId)} - > - Autoscale Pool - - {autoscaler.enabled ? ( - - {`(Min ${autoscaler.min} / Max ${autoscaler.max})`} - - ) : null} - handleClickResize(poolId)} - > - Resize Pool - - openRecycleAllNodesDialog(poolId)} - > - Recycle Pool Nodes - - -
    - openDeletePoolDialog(poolId)} - > - Delete Pool - -
    -
    -
    + {typeLabel} + + openAutoscalePoolDialog(poolId), + title: 'Autoscale Pool', + }, + { + onClick: () => handleClickResize(poolId), + title: 'Resize Pool', + }, + { + onClick: () => openRecycleAllNodesDialog(poolId), + title: 'Recycle Pool Nodes', + }, + { + disabled: isOnlyNodePool, + onClick: () => openDeletePoolDialog(poolId), + title: 'Delete Pool', + tooltip: isOnlyNodePool + ? 'Clusters must contain at least one node pool.' + : undefined, + }, + ]} + ariaLabel={`Action menu for Node Pool ${poolId}`} + /> + + + + openAutoscalePoolDialog(poolId)} + > + Autoscale Pool + + {autoscaler.enabled && ( + + (Min {autoscaler.min} / Max {autoscaler.max}) + + )} + handleClickResize(poolId)} + > + Resize Pool + + openRecycleAllNodesDialog(poolId)} + > + Recycle Pool Nodes + + +
    + openDeletePoolDialog(poolId)} + > + Delete Pool + +
    +
    +
    +
    { poolId={poolId} typeLabel={typeLabel} /> -
    + ); }; diff --git a/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/NodePoolsDisplay/NodePoolsDisplay.tsx b/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/NodePoolsDisplay/NodePoolsDisplay.tsx index 99a5957085d..c99d8364886 100644 --- a/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/NodePoolsDisplay/NodePoolsDisplay.tsx +++ b/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/NodePoolsDisplay/NodePoolsDisplay.tsx @@ -1,12 +1,10 @@ -import Grid from '@mui/material/Unstable_Grid2'; +import { Stack } from '@linode/ui'; import React, { useState } from 'react'; import { Waypoint } from 'react-waypoint'; -import { makeStyles } from 'tss-react/mui'; import { Button } from 'src/components/Button/Button'; import { CircleProgress } from 'src/components/CircleProgress'; import { ErrorState } from 'src/components/ErrorState/ErrorState'; -import { Stack } from 'src/components/Stack'; import { Typography } from 'src/components/Typography'; import { useAllKubernetesNodePoolQuery } from 'src/queries/kubernetes'; import { useSpecificTypes } from 'src/queries/types'; @@ -22,37 +20,6 @@ import { RecycleNodeDialog } from './RecycleNodeDialog'; import { ResizeNodePoolDrawer } from './ResizeNodePoolDrawer'; import type { Region } from '@linode/api-v4'; -import type { Theme } from '@mui/material/styles'; - -const useStyles = makeStyles()((theme: Theme) => ({ - button: { - marginBottom: theme.spacing(), - marginLeft: theme.spacing(), - }, - displayTable: { - '& > div': { - marginBottom: theme.spacing(3), - }, - '& > div:last-child': { - marginBottom: 0, - }, - padding: '8px 8px 0px', - width: '100%', - }, - nodePoolHeader: { - marginBottom: theme.spacing(), - [theme.breakpoints.only('sm')]: { - marginLeft: theme.spacing(), - }, - [theme.breakpoints.only('xs')]: { - marginLeft: theme.spacing(), - }, - }, - nodePoolHeaderOuter: { - alignItems: 'center', - display: 'flex', - }, -})); export interface Props { clusterID: number; @@ -63,7 +30,6 @@ export interface Props { export const NodePoolsDisplay = (props: Props) => { const { clusterID, clusterLabel, clusterRegionId, regionsData } = props; - const { classes, cx } = useStyles(); const { data: pools, @@ -117,138 +83,118 @@ export const NodePoolsDisplay = (props: Props) => { return ( <> - - - - Node Pools - - - + Node Pools + - - - - - {poolsError ? ( - - ) : ( - - - {_pools?.map((thisPool) => { - const { disk_encryption, id, nodes } = thisPool; - - const thisPoolType = types?.find( - (thisType) => thisType.id === thisPool.type - ); - - const typeLabel = - thisPoolType?.formattedLabel ?? 'Unknown type'; - - return ( - ({ paddingBottom: theme.spacing(2) })} - > - { - setSelectedPoolId(poolId); - setIsAutoscaleDialogOpen(true); - }} - openDeletePoolDialog={(id) => { - setSelectedPoolId(id); - setIsDeleteNodePoolOpen(true); - }} - openRecycleAllNodesDialog={(id) => { - setSelectedPoolId(id); - setIsRecycleAllPoolNodesOpen(true); - }} - openRecycleNodeDialog={(nodeId, linodeLabel) => { - setSelectedNodeId(nodeId); - setIsRecycleNodeOpen(true); - }} - autoscaler={thisPool.autoscaler} - encryptionStatus={disk_encryption} - handleClickResize={handleOpenResizeDrawer} - isOnlyNodePool={pools?.length === 1} - nodes={nodes ?? []} - poolId={thisPool.id} - typeLabel={typeLabel} - /> - - ); - })} - {pools?.length > numPoolsToDisplay && ( - -
    - - )} - - - setAddDrawerOpen(false)} - open={addDrawerOpen} - regionsData={regionsData} - /> - setIsResizeDrawerOpen(false)} - open={isResizeDrawerOpen} - /> - setIsDeleteNodePoolOpen(false)} - open={isDeleteNodePoolOpen} - /> - setIsAutoscaleDialogOpen(false)} - open={isAutoscaleDialogOpen} - /> - setIsRecycleNodeOpen(false)} - open={isRecycleNodeOpen} - /> - setIsRecycleAllPoolNodesOpen(false)} - open={isRecycleAllPoolNodesOpen} - /> - setIsRecycleClusterOpen(false)} - open={isRecycleClusterOpen} + + + {poolsError && } + + {_pools?.map((thisPool) => { + const { disk_encryption, id, nodes } = thisPool; + + const thisPoolType = types?.find( + (thisType) => thisType.id === thisPool.type + ); + + const typeLabel = thisPoolType?.formattedLabel ?? 'Unknown type'; + + return ( + { + setSelectedPoolId(poolId); + setIsAutoscaleDialogOpen(true); + }} + openDeletePoolDialog={(id) => { + setSelectedPoolId(id); + setIsDeleteNodePoolOpen(true); + }} + openRecycleAllNodesDialog={(id) => { + setSelectedPoolId(id); + setIsRecycleAllPoolNodesOpen(true); + }} + openRecycleNodeDialog={(nodeId, linodeLabel) => { + setSelectedNodeId(nodeId); + setIsRecycleNodeOpen(true); + }} + autoscaler={thisPool.autoscaler} + encryptionStatus={disk_encryption} + handleClickResize={handleOpenResizeDrawer} + isOnlyNodePool={pools?.length === 1} + key={id} + nodes={nodes ?? []} + poolId={thisPool.id} + typeLabel={typeLabel} /> - - )} + ); + })} + {pools?.length > numPoolsToDisplay && ( + +
    + + )} + setAddDrawerOpen(false)} + open={addDrawerOpen} + regionsData={regionsData} + /> + setIsResizeDrawerOpen(false)} + open={isResizeDrawerOpen} + /> + setIsDeleteNodePoolOpen(false)} + open={isDeleteNodePoolOpen} + /> + setIsAutoscaleDialogOpen(false)} + open={isAutoscaleDialogOpen} + /> + setIsRecycleNodeOpen(false)} + open={isRecycleNodeOpen} + /> + setIsRecycleAllPoolNodesOpen(false)} + open={isRecycleAllPoolNodesOpen} + /> + setIsRecycleClusterOpen(false)} + open={isRecycleClusterOpen} + /> ); }; diff --git a/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/NodePoolsDisplay/NodeRow.tsx b/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/NodePoolsDisplay/NodeRow.tsx index 2aba5674d8a..738c9249a60 100644 --- a/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/NodePoolsDisplay/NodeRow.tsx +++ b/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/NodePoolsDisplay/NodeRow.tsx @@ -1,3 +1,4 @@ +import { Box } from '@linode/ui'; import Grid from '@mui/material/Unstable_Grid2'; import * as React from 'react'; import { Link } from 'react-router-dom'; @@ -5,13 +6,13 @@ import { Link } from 'react-router-dom'; import { CopyTooltip } from 'src/components/CopyTooltip/CopyTooltip'; import { StatusIcon } from 'src/components/StatusIcon/StatusIcon'; import { TableCell } from 'src/components/TableCell'; +import { TableRow } from 'src/components/TableRow'; import { Typography } from 'src/components/Typography'; import { transitionText } from 'src/features/Linodes/transitions'; import { useInProgressEvents } from 'src/queries/events/events'; import { usePreferences } from 'src/queries/profile/preferences'; import NodeActionMenu from './NodeActionMenu'; -import { StyledCopyTooltip, StyledTableRow } from './NodeTable.styles'; import type { APIError } from '@linode/api-v4/lib/types'; @@ -73,7 +74,7 @@ export const NodeRow = React.memo((props: NodeRowProps) => { const displayIP = ip ?? ''; return ( - + @@ -113,15 +114,22 @@ export const NodeRow = React.memo((props: NodeRowProps) => { Error retrieving IP ) : displayIP.length > 0 ? ( - <> + - - + + ) : null} @@ -131,6 +139,6 @@ export const NodeRow = React.memo((props: NodeRowProps) => { openRecycleNodeDialog={openRecycleNodeDialog} /> - + ); }); diff --git a/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/NodePoolsDisplay/NodeTable.styles.ts b/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/NodePoolsDisplay/NodeTable.styles.ts index 97675764fff..df20b2298e4 100644 --- a/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/NodePoolsDisplay/NodeTable.styles.ts +++ b/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/NodePoolsDisplay/NodeTable.styles.ts @@ -2,33 +2,8 @@ import { styled } from '@mui/material/styles'; import VerticalDivider from 'src/assets/icons/divider-vertical.svg'; import { CopyTooltip } from 'src/components/CopyTooltip/CopyTooltip'; -import { Table } from 'src/components/Table'; -import { TableRow } from 'src/components/TableRow'; import { Typography } from 'src/components/Typography'; -export const StyledTableRow = styled(TableRow, { - label: 'TableRow', -})(({ theme }) => ({ - '& svg': { - height: `12px`, - width: `12px`, - }, - '&:hover': { - backgroundColor: theme.bg.lightBlue1, - }, - [`&:hover .copy-tooltip > svg, & .copy-tooltip:focus > svg`]: { - opacity: 1, - }, - marginLeft: 4, -})); - -export const StyledTable = styled(Table, { - label: 'Table', -})(({ theme }) => ({ - borderLeft: `1px solid ${theme.borderColors.borderTable}`, - borderRight: `1px solid ${theme.borderColors.borderTable}`, -})); - export const StyledCopyTooltip = styled(CopyTooltip, { label: 'CopyTooltip', })(() => ({ diff --git a/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/NodePoolsDisplay/NodeTable.tsx b/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/NodePoolsDisplay/NodeTable.tsx index c65f67dde39..ec38258918f 100644 --- a/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/NodePoolsDisplay/NodeTable.tsx +++ b/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/NodePoolsDisplay/NodeTable.tsx @@ -8,6 +8,7 @@ import { useIsDiskEncryptionFeatureEnabled } from 'src/components/Encryption/uti import OrderBy from 'src/components/OrderBy'; import Paginate from 'src/components/Paginate'; import { PaginationFooter } from 'src/components/PaginationFooter/PaginationFooter'; +import { Table } from 'src/components/Table'; import { TableBody } from 'src/components/TableBody'; import { TableCell } from 'src/components/TableCell'; import { TableContentWrapper } from 'src/components/TableContentWrapper/TableContentWrapper'; @@ -20,11 +21,7 @@ import { Typography } from 'src/components/Typography'; import { useAllLinodesQuery } from 'src/queries/linodes/linodes'; import { NodeRow as _NodeRow } from './NodeRow'; -import { - StyledTable, - StyledTypography, - StyledVerticalDivider, -} from './NodeTable.styles'; +import { StyledTypography, StyledVerticalDivider } from './NodeTable.styles'; import type { NodeRow } from './NodeRow'; import type { PoolNodeResponse } from '@linode/api-v4/lib/kubernetes'; @@ -70,7 +67,7 @@ export const NodeTable = React.memo((props: Props) => { pageSize, }) => ( <> - + { - +
    ); }; diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodePermissionsError.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodePermissionsError.tsx index 23951d4edcc..3a78d55b03e 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodePermissionsError.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodePermissionsError.tsx @@ -1,6 +1,6 @@ +import { Notice } from '@linode/ui'; import * as React from 'react'; -import { Notice } from 'src/components/Notice/Notice'; import { getRestrictedResourceText } from 'src/features/Account/utils'; export const LinodePermissionsError = () => ( diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeRebuild/ImageEmptyState.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeRebuild/ImageEmptyState.tsx index 960aed6ed8b..7bca294a5a1 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeRebuild/ImageEmptyState.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeRebuild/ImageEmptyState.tsx @@ -1,8 +1,7 @@ +import { Notice, Paper } from '@linode/ui'; import { useTheme } from '@mui/material/styles'; import * as React from 'react'; -import { Notice } from 'src/components/Notice/Notice'; -import { Paper } from '@linode/ui'; import { Typography } from 'src/components/Typography'; import type { SxProps, Theme } from '@mui/material/styles'; diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeRebuild/LinodeRebuildDialog.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeRebuild/LinodeRebuildDialog.tsx index c93992386a3..db001478398 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeRebuild/LinodeRebuildDialog.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeRebuild/LinodeRebuildDialog.tsx @@ -1,10 +1,10 @@ +import { Notice } from '@linode/ui'; import { styled, useTheme } from '@mui/material/styles'; import * as React from 'react'; import { Autocomplete } from 'src/components/Autocomplete/Autocomplete'; import { Dialog } from 'src/components/Dialog/Dialog'; import { ErrorMessage } from 'src/components/ErrorMessage'; -import { Notice } from 'src/components/Notice/Notice'; import { getIsDistributedRegion } from 'src/components/RegionSelect/RegionSelect.utils'; import { Typography } from 'src/components/Typography'; import { useLinodeQuery } from 'src/queries/linodes/linodes'; diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeRebuild/RebuildFromImage.styles.ts b/packages/manager/src/features/Linodes/LinodesDetail/LinodeRebuild/RebuildFromImage.styles.ts index a031081ee54..bf473765e04 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeRebuild/RebuildFromImage.styles.ts +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeRebuild/RebuildFromImage.styles.ts @@ -1,8 +1,8 @@ +import { Notice } from '@linode/ui'; import { styled } from '@mui/material/styles'; import Grid from '@mui/material/Unstable_Grid2'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; -import { Notice } from 'src/components/Notice/Notice'; export const StyledNotice = styled(Notice, { label: 'StyledNotice' })({ marginBottom: '0px !important', diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeRebuild/RebuildFromImage.test.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeRebuild/RebuildFromImage.test.tsx index 3ac60b9e85a..ecdc17ca5f1 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeRebuild/RebuildFromImage.test.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeRebuild/RebuildFromImage.test.tsx @@ -1,8 +1,8 @@ -import { render } from '@testing-library/react'; import * as React from 'react'; import { reactRouterProps } from 'src/__data__/reactRouterProps'; -import { renderWithTheme, wrapWithTheme } from 'src/utilities/testHelpers'; +import { wrapWithTheme } from 'src/utilities/testHelpers'; +import { renderWithThemeAndHookFormContext } from 'src/utilities/testHelpers'; import { RebuildFromImage } from './RebuildFromImage'; @@ -47,15 +47,17 @@ describe('RebuildFromImage', () => { }); it('renders a SelectImage panel', () => { - const { queryByText } = render( - wrapWithTheme() - ); + const { queryByText } = renderWithThemeAndHookFormContext({ + component: wrapWithTheme(), + }); expect(queryByText('Select Image')).toBeInTheDocument(); }); // @TODO LDE: Remove feature flagging/conditionality once LDE is fully rolled out it('does not render a "Disk Encryption" section when the Disk Encryption feature is disabled', () => { - const { queryByText } = renderWithTheme(); + const { queryByText } = renderWithThemeAndHookFormContext({ + component: , + }); expect(queryByText('Encrypt Disk')).not.toBeInTheDocument(); }); @@ -69,7 +71,9 @@ describe('RebuildFromImage', () => { } ); - const { queryByText } = renderWithTheme(); + const { queryByText } = renderWithThemeAndHookFormContext({ + component: , + }); expect(queryByText('Encrypt Disk')).toBeInTheDocument(); }); diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeRebuild/RebuildFromImage.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeRebuild/RebuildFromImage.tsx index a6e5d9374d1..87bd9d7c402 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeRebuild/RebuildFromImage.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeRebuild/RebuildFromImage.tsx @@ -1,5 +1,5 @@ import { rebuildLinode } from '@linode/api-v4'; -import { Box } from '@linode/ui'; +import { Box, Divider } from '@linode/ui'; import { RebuildLinodeSchema } from '@linode/validation/lib/linodes.schema'; import Grid from '@mui/material/Unstable_Grid2'; import { Formik } from 'formik'; @@ -10,7 +10,6 @@ import { useLocation } from 'react-router-dom'; import { AccessPanel } from 'src/components/AccessPanel/AccessPanel'; import { Checkbox } from 'src/components/Checkbox'; -import { Divider } from 'src/components/Divider'; import { ImageSelect } from 'src/components/ImageSelect/ImageSelect'; import { TypeToConfirm } from 'src/components/TypeToConfirm/TypeToConfirm'; import { Typography } from 'src/components/Typography'; diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeRebuild/UserDataAccordion/UserDataAccordion.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeRebuild/UserDataAccordion/UserDataAccordion.tsx index d20ae58c5c1..ef0683830cc 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeRebuild/UserDataAccordion/UserDataAccordion.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeRebuild/UserDataAccordion/UserDataAccordion.tsx @@ -1,9 +1,8 @@ -import { Box } from '@linode/ui'; +import { Box, Notice } from '@linode/ui'; import * as React from 'react'; import { Accordion } from 'src/components/Accordion'; import { Link } from 'src/components/Link'; -import { Notice } from 'src/components/Notice/Notice'; import { TextField } from 'src/components/TextField'; import { Typography } from 'src/components/Typography'; diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeRescue/RescueDescription.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeRescue/RescueDescription.tsx index c4a9c1eeb62..fd51eca05c7 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeRescue/RescueDescription.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeRescue/RescueDescription.tsx @@ -1,9 +1,9 @@ +import { Notice } from '@linode/ui'; import { useTheme } from '@mui/material/styles'; import * as React from 'react'; import { StyledLinkButton } from 'src/components/Button/StyledLinkButton'; import { Link } from 'src/components/Link'; -import { Notice } from 'src/components/Notice/Notice'; import { Typography } from 'src/components/Typography'; import { lishLaunch } from 'src/features/Lish/lishUtils'; import { useLinodeFirewallsQuery } from 'src/queries/linodes/firewalls'; diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeRescue/StandardRescueDialog.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeRescue/StandardRescueDialog.tsx index 0c3f4c1969e..cb9c5c6ef18 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeRescue/StandardRescueDialog.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeRescue/StandardRescueDialog.tsx @@ -1,3 +1,4 @@ +import { Notice, Paper } from '@linode/ui'; import { styled, useTheme } from '@mui/material/styles'; import { useSnackbar } from 'notistack'; import { assoc, clamp, equals, pathOr } from 'ramda'; @@ -7,8 +8,6 @@ import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Button } from 'src/components/Button/Button'; import { Dialog } from 'src/components/Dialog/Dialog'; import { ErrorState } from 'src/components/ErrorState/ErrorState'; -import { Notice } from 'src/components/Notice/Notice'; -import { Paper } from '@linode/ui'; import { usePrevious } from 'src/hooks/usePrevious'; import { useEventsPollingActions } from 'src/queries/events/events'; import { useAllLinodeDisksQuery } from 'src/queries/linodes/disks'; @@ -229,18 +228,18 @@ export const StandardRescueDialog = (props: Props) => { slots={['sda', 'sdb', 'sdc', 'sdd', 'sde', 'sdf', 'sdg']} /> { it('should render an Image Select', () => { - renderWithTheme(); + renderWithThemeAndHookFormContext({ + component: , + }); expect(screen.getByRole('combobox')); expect(screen.getByRole('combobox')).toBeEnabled(); }); it('should render a password error if defined', async () => { const errorMessage = 'Unable to set password.'; - const { findByText } = renderWithTheme( - - ); + const { findByText } = renderWithThemeAndHookFormContext({ + component: , + }); const passwordError = await findByText(errorMessage, undefined, { timeout: 2500, @@ -37,7 +39,9 @@ describe('ImageAndPassword', () => { expect(passwordError).toBeVisible(); }); it('should render an SSH Keys section', async () => { - const { getByText } = renderWithTheme(); + const { getByText } = renderWithThemeAndHookFormContext({ + component: , + }); expect(getByText('SSH Keys', { selector: 'h2' })).toBeVisible(); }); @@ -50,7 +54,9 @@ describe('ImageAndPassword', () => { }) ); - const { findByText } = renderWithTheme(); + const { findByText } = renderWithThemeAndHookFormContext({ + component: , + }); for (const user of users) { // eslint-disable-next-line no-await-in-loop diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeSettings/InterfaceSelect.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeSettings/InterfaceSelect.tsx index 2ef7b01e54b..f9de4f1d149 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeSettings/InterfaceSelect.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeSettings/InterfaceSelect.tsx @@ -1,12 +1,10 @@ +import { Divider, Notice, Stack } from '@linode/ui'; import { useTheme } from '@mui/material/styles'; import Grid from '@mui/material/Unstable_Grid2'; import useMediaQuery from '@mui/material/useMediaQuery'; import * as React from 'react'; import { Autocomplete } from 'src/components/Autocomplete/Autocomplete'; -import { Divider } from 'src/components/Divider'; -import { Notice } from 'src/components/Notice/Notice'; -import { Stack } from 'src/components/Stack'; import { TextField } from 'src/components/TextField'; import { Typography } from 'src/components/Typography'; import { VPCPanel } from 'src/features/Linodes/LinodesDetail/LinodeSettings/VPCPanel'; diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeSettings/LinodeSettingsAlertsPanel.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeSettings/LinodeSettingsAlertsPanel.tsx index 43923be7b1b..3cf6e2ae4c5 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeSettings/LinodeSettingsAlertsPanel.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeSettings/LinodeSettingsAlertsPanel.tsx @@ -1,4 +1,4 @@ -import { Linode } from '@linode/api-v4'; +import { Notice } from '@linode/ui'; import { styled } from '@mui/material/styles'; import { useFormik } from 'formik'; import { useSnackbar } from 'notistack'; @@ -6,7 +6,6 @@ import * as React from 'react'; import { Accordion } from 'src/components/Accordion'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; -import { Notice } from 'src/components/Notice/Notice'; import { useLinodeQuery, useLinodeUpdateMutation, @@ -16,6 +15,8 @@ import { getAPIErrorFor } from 'src/utilities/getAPIErrorFor'; import { AlertSection } from './AlertSection'; +import type { Linode } from '@linode/api-v4'; + interface Props { isReadOnly?: boolean; linodeId: number; diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeSettings/LinodeSettingsDeletePanel.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeSettings/LinodeSettingsDeletePanel.tsx index 820b50b27b0..44f6af63586 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeSettings/LinodeSettingsDeletePanel.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeSettings/LinodeSettingsDeletePanel.tsx @@ -1,9 +1,9 @@ +import { Notice } from '@linode/ui'; import * as React from 'react'; import { useHistory } from 'react-router-dom'; import { Accordion } from 'src/components/Accordion'; import { Button } from 'src/components/Button/Button'; -import { Notice } from 'src/components/Notice/Notice'; import { TypeToConfirmDialog } from 'src/components/TypeToConfirmDialog/TypeToConfirmDialog'; import { Typography } from 'src/components/Typography'; import { useEventsPollingActions } from 'src/queries/events/events'; diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeSettings/LinodeSettingsLabelPanel.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeSettings/LinodeSettingsLabelPanel.tsx index abe4ea91ee2..1615abbfb9f 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeSettings/LinodeSettingsLabelPanel.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeSettings/LinodeSettingsLabelPanel.tsx @@ -1,3 +1,4 @@ +import { Notice } from '@linode/ui'; import { styled } from '@mui/material/styles'; import { useFormik } from 'formik'; import { useSnackbar } from 'notistack'; @@ -5,7 +6,6 @@ import * as React from 'react'; import { Accordion } from 'src/components/Accordion'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; -import { Notice } from 'src/components/Notice/Notice'; import { TextField } from 'src/components/TextField'; import { useLinodeQuery, diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeSettings/LinodeSettingsPasswordPanel.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeSettings/LinodeSettingsPasswordPanel.tsx index b34f58107e8..081d69e081b 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeSettings/LinodeSettingsPasswordPanel.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeSettings/LinodeSettingsPasswordPanel.tsx @@ -1,3 +1,4 @@ +import { Notice } from '@linode/ui'; import { styled } from '@mui/material/styles'; import { useSnackbar } from 'notistack'; import * as React from 'react'; @@ -5,7 +6,6 @@ import * as React from 'react'; import { Accordion } from 'src/components/Accordion'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import EnhancedSelect from 'src/components/EnhancedSelect/Select'; -import { Notice } from 'src/components/Notice/Notice'; import { SuspenseLoader } from 'src/components/SuspenseLoader'; import { useAllLinodeDisksQuery, diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeSettings/LinodeWatchdogPanel.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeSettings/LinodeWatchdogPanel.tsx index c94d597c3a3..e4144c3dbb7 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeSettings/LinodeWatchdogPanel.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeSettings/LinodeWatchdogPanel.tsx @@ -1,3 +1,4 @@ +import { Notice } from '@linode/ui'; import { Box, Stack } from '@mui/material'; import Grid from '@mui/material/Unstable_Grid2'; import * as React from 'react'; @@ -5,7 +6,6 @@ import * as React from 'react'; import { Accordion } from 'src/components/Accordion'; import { CircleProgress } from 'src/components/CircleProgress'; import { FormControlLabel } from 'src/components/FormControlLabel'; -import { Notice } from 'src/components/Notice/Notice'; import { Toggle } from 'src/components/Toggle/Toggle'; import { Typography } from 'src/components/Typography'; import { diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeSettings/VPCPanel.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeSettings/VPCPanel.tsx index 68c87f6f469..601320ac9f0 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeSettings/VPCPanel.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeSettings/VPCPanel.tsx @@ -1,4 +1,4 @@ -import { Box, Paper } from '@linode/ui'; +import { Box, Paper, Stack } from '@linode/ui'; import { useTheme } from '@mui/material/styles'; import useMediaQuery from '@mui/material/useMediaQuery'; import * as React from 'react'; @@ -6,7 +6,6 @@ import * as React from 'react'; import { Autocomplete } from 'src/components/Autocomplete/Autocomplete'; import { Checkbox } from 'src/components/Checkbox'; import { FormControlLabel } from 'src/components/FormControlLabel'; -import { Stack } from 'src/components/Stack'; import { TextField } from 'src/components/TextField'; import { TooltipIcon } from 'src/components/TooltipIcon'; import { Typography } from 'src/components/Typography'; diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeStorage/CreateDiskDrawer.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeStorage/CreateDiskDrawer.tsx index 974754eb3dd..aaf0c092554 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeStorage/CreateDiskDrawer.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeStorage/CreateDiskDrawer.tsx @@ -1,5 +1,4 @@ -import { InputAdornment } from '@linode/ui'; -import { FormHelperText } from '@linode/ui'; +import { FormHelperText, InputAdornment, Notice } from '@linode/ui'; import { CreateLinodeDiskFromImageSchema, CreateLinodeDiskSchema, @@ -12,7 +11,6 @@ import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Autocomplete } from 'src/components/Autocomplete/Autocomplete'; import { Drawer } from 'src/components/Drawer'; import { ModeSelect } from 'src/components/ModeSelect/ModeSelect'; -import { Notice } from 'src/components/Notice/Notice'; import { TextField } from 'src/components/TextField'; import { useEventsPollingActions } from 'src/queries/events/events'; import { diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeStorage/LinodeDisks.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeStorage/LinodeDisks.tsx index 73895ce899a..66943ae8728 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeStorage/LinodeDisks.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeStorage/LinodeDisks.tsx @@ -1,4 +1,4 @@ -import { Box } from '@linode/ui'; +import { Box, Paper, Stack } from '@linode/ui'; import Grid from '@mui/material/Unstable_Grid2'; import * as React from 'react'; import { useParams } from 'react-router-dom'; @@ -8,8 +8,6 @@ import { Hidden } from 'src/components/Hidden'; import OrderBy from 'src/components/OrderBy'; import Paginate from 'src/components/Paginate'; import { PaginationFooter } from 'src/components/PaginationFooter/PaginationFooter'; -import { Paper } from '@linode/ui'; -import { Stack } from 'src/components/Stack'; import { Table } from 'src/components/Table'; import { TableBody } from 'src/components/TableBody'; import { TableCell } from 'src/components/TableCell'; diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeStorage/LinodeStorage.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeStorage/LinodeStorage.tsx index 0d8d8dba333..a95c6644edd 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeStorage/LinodeStorage.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeStorage/LinodeStorage.tsx @@ -1,7 +1,6 @@ +import { Stack } from '@linode/ui'; import * as React from 'react'; -import { Stack } from 'src/components/Stack'; - import { LinodeDisks } from './LinodeDisks'; import { LinodeVolumes } from './LinodeVolumes'; diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeStorage/RenameDiskDrawer.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeStorage/RenameDiskDrawer.tsx index 9ac1235d150..30177ef637d 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeStorage/RenameDiskDrawer.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeStorage/RenameDiskDrawer.tsx @@ -1,15 +1,16 @@ -import { Disk } from '@linode/api-v4/lib/linodes'; +import { Notice } from '@linode/ui'; import { useFormik } from 'formik'; import * as React from 'react'; import { object, string } from 'yup'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Drawer } from 'src/components/Drawer'; -import { Notice } from 'src/components/Notice/Notice'; import { TextField } from 'src/components/TextField'; import { useLinodeDiskUpdateMutation } from 'src/queries/linodes/disks'; import { handleAPIErrors } from 'src/utilities/formikErrorUtils'; +import type { Disk } from '@linode/api-v4/lib/linodes'; + const RenameDiskSchema = object({ label: string() .required('Label is required.') diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeStorage/ResizeDiskDrawer.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeStorage/ResizeDiskDrawer.tsx index 94d1c435f1a..716e42a843f 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeStorage/ResizeDiskDrawer.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeStorage/ResizeDiskDrawer.tsx @@ -1,5 +1,4 @@ -import { InputAdornment } from '@linode/ui'; -import { FormHelperText } from '@linode/ui'; +import { FormHelperText, InputAdornment, Notice } from '@linode/ui'; import { ResizeLinodeDiskSchema } from '@linode/validation'; import { styled } from '@mui/material/styles'; import { useFormik } from 'formik'; @@ -10,7 +9,6 @@ import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Code } from 'src/components/Code/Code'; import { Drawer } from 'src/components/Drawer'; import { Link } from 'src/components/Link'; -import { Notice } from 'src/components/Notice/Notice'; import { TextField } from 'src/components/TextField'; import { TextTooltip } from 'src/components/TextTooltip'; import { useEventsPollingActions } from 'src/queries/events/events'; diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodesDetailHeader/HostMaintenance.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodesDetailHeader/HostMaintenance.tsx index ecf4651fdba..59bfeb26c3c 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodesDetailHeader/HostMaintenance.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodesDetailHeader/HostMaintenance.tsx @@ -1,9 +1,10 @@ -import { LinodeStatus } from '@linode/api-v4/lib/linodes/types'; +import { Notice } from '@linode/ui'; import * as React from 'react'; -import { Notice } from 'src/components/Notice/Notice'; import { Typography } from 'src/components/Typography'; +import type { LinodeStatus } from '@linode/api-v4/lib/linodes/types'; + interface Props { linodeStatus: LinodeStatus; } diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodesDetailHeader/MigrationNotification.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodesDetailHeader/MigrationNotification.tsx index c6ecfe0e849..a30b2308f38 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodesDetailHeader/MigrationNotification.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodesDetailHeader/MigrationNotification.tsx @@ -1,12 +1,12 @@ -import { NotificationType } from '@linode/api-v4/lib/account'; import { scheduleOrQueueMigration } from '@linode/api-v4/lib/linodes'; +import { Notice } from '@linode/ui'; import { DateTime } from 'luxon'; import { useSnackbar } from 'notistack'; import * as React from 'react'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; +import { StyledLinkButton } from 'src/components/Button/StyledLinkButton'; import { ConfirmationDialog } from 'src/components/ConfirmationDialog/ConfirmationDialog'; -import { Notice } from 'src/components/Notice/Notice'; import { Typography } from 'src/components/Typography'; import { useDialog } from 'src/hooks/useDialog'; import { useProfile } from 'src/queries/profile/profile'; @@ -14,7 +14,8 @@ import { capitalize } from 'src/utilities/capitalize'; import { parseAPIDate } from 'src/utilities/date'; import { formatDate } from 'src/utilities/formatDate'; import { pluralize } from 'src/utilities/pluralize'; -import { StyledLinkButton } from 'src/components/Button/StyledLinkButton'; + +import type { NotificationType } from '@linode/api-v4/lib/account'; interface Props { linodeID: number; diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodesDetailHeader/MutationNotification.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodesDetailHeader/MutationNotification.tsx index 9c624845587..2ffdcd4b1b1 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodesDetailHeader/MutationNotification.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodesDetailHeader/MutationNotification.tsx @@ -1,8 +1,8 @@ +import { Notice } from '@linode/ui'; import { styled } from '@mui/material/styles'; import { useSnackbar } from 'notistack'; import * as React from 'react'; -import { Notice } from 'src/components/Notice/Notice'; import { Typography } from 'src/components/Typography'; import { MBpsIntraDC } from 'src/constants'; import { useEventsPollingActions } from 'src/queries/events/events'; diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodesDetailHeader/UpgradeVolumesDialog.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodesDetailHeader/UpgradeVolumesDialog.tsx index ec74531a2af..59268b789e1 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodesDetailHeader/UpgradeVolumesDialog.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodesDetailHeader/UpgradeVolumesDialog.tsx @@ -1,10 +1,9 @@ +import { Notice, Stack } from '@linode/ui'; import { useSnackbar } from 'notistack'; import * as React from 'react'; import { Button } from 'src/components/Button/Button'; import { ConfirmationDialog } from 'src/components/ConfirmationDialog/ConfirmationDialog'; -import { Notice } from 'src/components/Notice/Notice'; -import { Stack } from 'src/components/Stack'; import { Typography } from 'src/components/Typography'; import { VolumeUpgradeCopy } from 'src/features/Volumes/UpgradeVolumeDialog'; import { getUpgradeableVolumeIds } from 'src/features/Volumes/utils'; diff --git a/packages/manager/src/features/Linodes/LinodesDetail/MutateDrawer/MutateDrawer.tsx b/packages/manager/src/features/Linodes/LinodesDetail/MutateDrawer/MutateDrawer.tsx index dc4b56a8d77..9038bb00f0d 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/MutateDrawer/MutateDrawer.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/MutateDrawer/MutateDrawer.tsx @@ -1,10 +1,10 @@ +import { Notice } from '@linode/ui'; import * as React from 'react'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Drawer } from 'src/components/Drawer'; import { Link } from 'src/components/Link'; import { ListItem } from 'src/components/ListItem'; -import { Notice } from 'src/components/Notice/Notice'; import { Typography } from 'src/components/Typography'; interface MutateInfo { diff --git a/packages/manager/src/features/Linodes/LinodesDetail/VolumesUpgradeBanner.tsx b/packages/manager/src/features/Linodes/LinodesDetail/VolumesUpgradeBanner.tsx index 0728eb2ada4..61314ef5cfb 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/VolumesUpgradeBanner.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/VolumesUpgradeBanner.tsx @@ -1,11 +1,9 @@ +import { Notice, Paper, Stack } from '@linode/ui'; import React from 'react'; import { useHistory } from 'react-router-dom'; import { Button } from 'src/components/Button/Button'; import { Link } from 'src/components/Link'; -import { Notice } from 'src/components/Notice/Notice'; -import { Paper } from '@linode/ui'; -import { Stack } from 'src/components/Stack'; import { Typography } from 'src/components/Typography'; import { getUpgradeableVolumeIds } from 'src/features/Volumes/utils'; import { useNotificationsQuery } from 'src/queries/account/notifications'; diff --git a/packages/manager/src/features/Linodes/LinodesLanding/DeleteLinodeDialog.tsx b/packages/manager/src/features/Linodes/LinodesLanding/DeleteLinodeDialog.tsx index bc60145831a..c9288a5d3d2 100644 --- a/packages/manager/src/features/Linodes/LinodesLanding/DeleteLinodeDialog.tsx +++ b/packages/manager/src/features/Linodes/LinodesLanding/DeleteLinodeDialog.tsx @@ -1,7 +1,7 @@ +import { Notice } from '@linode/ui'; import { useQueryClient } from '@tanstack/react-query'; import * as React from 'react'; -import { Notice } from 'src/components/Notice/Notice'; import { TypeToConfirmDialog } from 'src/components/TypeToConfirmDialog/TypeToConfirmDialog'; import { Typography } from 'src/components/Typography'; import { useEventsPollingActions } from 'src/queries/events/events'; diff --git a/packages/manager/src/features/Linodes/MigrateLinode/CautionNotice.tsx b/packages/manager/src/features/Linodes/MigrateLinode/CautionNotice.tsx index ce97043923c..440ca5272b3 100644 --- a/packages/manager/src/features/Linodes/MigrateLinode/CautionNotice.tsx +++ b/packages/manager/src/features/Linodes/MigrateLinode/CautionNotice.tsx @@ -1,10 +1,10 @@ +import { Notice } from '@linode/ui'; import { styled, useTheme } from '@mui/material/styles'; import { DateTime } from 'luxon'; import * as React from 'react'; import { Checkbox } from 'src/components/Checkbox'; import { Link } from 'src/components/Link'; -import { Notice } from 'src/components/Notice/Notice'; import { Typography } from 'src/components/Typography'; import { API_MAX_PAGE_SIZE } from 'src/constants'; import { useLinodeVolumesQuery } from 'src/queries/volumes/volumes'; diff --git a/packages/manager/src/features/Linodes/MigrateLinode/ConfigureForm.tsx b/packages/manager/src/features/Linodes/MigrateLinode/ConfigureForm.tsx index 1964707fa22..16b9124d469 100644 --- a/packages/manager/src/features/Linodes/MigrateLinode/ConfigureForm.tsx +++ b/packages/manager/src/features/Linodes/MigrateLinode/ConfigureForm.tsx @@ -1,13 +1,9 @@ +import { Notice } from '@linode/ui'; import * as React from 'react'; -import DistributedRegion from 'src/assets/icons/entityIcons/distributed-region.svg'; import { Flag } from 'src/components/Flag'; -import { Notice } from 'src/components/Notice/Notice'; import { PlacementGroupsSelect } from 'src/components/PlacementGroupsSelect/PlacementGroupsSelect'; import { RegionSelect } from 'src/components/RegionSelect/RegionSelect'; -import { sxDistributedRegionIcon } from 'src/components/RegionSelect/RegionSelect.styles'; -import { useIsGeckoEnabled } from 'src/components/RegionSelect/RegionSelect.utils'; -import { TooltipIcon } from 'src/components/TooltipIcon'; import { Typography } from 'src/components/Typography'; import { NO_PLACEMENT_GROUPS_IN_SELECTED_REGION_MESSAGE } from 'src/features/PlacementGroups/constants'; import { useIsPlacementGroupsEnabled } from 'src/features/PlacementGroups/utils'; @@ -148,8 +144,6 @@ export const ConfigureForm = React.memo((props: Props) => { const linodeIsInDistributedRegion = currentActualRegion?.site_type === 'distributed'; - const { isGeckoBetaEnabled } = useIsGeckoEnabled(); - return ( Configure Migration @@ -161,14 +155,6 @@ export const ConfigureForm = React.memo((props: Props) => { {`${getRegionCountryGroup(currentActualRegion)}: ${ currentActualRegion?.label ?? currentRegion }`} - {isGeckoBetaEnabled && linodeIsInDistributedRegion && ( - } - status="other" - sxTooltipIcon={sxDistributedRegionIcon} - text="This region is a distributed region." - /> - )} {shouldDisplayPriceComparison && ( void; diff --git a/packages/manager/src/features/Managed/Credentials/AddCredentialDrawer.tsx b/packages/manager/src/features/Managed/Credentials/AddCredentialDrawer.tsx index fdb44a8ea4f..098fde3c6d0 100644 --- a/packages/manager/src/features/Managed/Credentials/AddCredentialDrawer.tsx +++ b/packages/manager/src/features/Managed/Credentials/AddCredentialDrawer.tsx @@ -1,16 +1,17 @@ -import { CredentialPayload } from '@linode/api-v4/lib/managed'; +import { Notice } from '@linode/ui'; import { Formik } from 'formik'; import * as React from 'react'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Drawer } from 'src/components/Drawer'; -import { Notice } from 'src/components/Notice/Notice'; import { SuspenseLoader } from 'src/components/SuspenseLoader'; import { TextField } from 'src/components/TextField'; import { handleFormikBlur } from 'src/utilities/formikTrimUtil'; import { creationSchema } from './credential.schema'; +import type { CredentialPayload } from '@linode/api-v4/lib/managed'; + const PasswordInput = React.lazy( () => import('src/components/PasswordInput/PasswordInput') ); diff --git a/packages/manager/src/features/Managed/Credentials/UpdateCredentialDrawer.tsx b/packages/manager/src/features/Managed/Credentials/UpdateCredentialDrawer.tsx index dbc382a18f2..c3114d00e66 100644 --- a/packages/manager/src/features/Managed/Credentials/UpdateCredentialDrawer.tsx +++ b/packages/manager/src/features/Managed/Credentials/UpdateCredentialDrawer.tsx @@ -1,16 +1,17 @@ -import { CredentialPayload } from '@linode/api-v4/lib/managed'; +import { Notice } from '@linode/ui'; import { Formik } from 'formik'; import * as React from 'react'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Drawer } from 'src/components/Drawer'; -import { Notice } from 'src/components/Notice/Notice'; import { SuspenseLoader } from 'src/components/SuspenseLoader'; import { TextField } from 'src/components/TextField'; import { handleFormikBlur } from 'src/utilities/formikTrimUtil'; import { updateLabelSchema, updatePasswordSchema } from './credential.schema'; +import type { CredentialPayload } from '@linode/api-v4/lib/managed'; + const PasswordInput = React.lazy( () => import('src/components/PasswordInput/PasswordInput') ); diff --git a/packages/manager/src/features/Managed/MonitorDrawer.tsx b/packages/manager/src/features/Managed/MonitorDrawer.tsx index e872cb239d6..9a314541d5a 100644 --- a/packages/manager/src/features/Managed/MonitorDrawer.tsx +++ b/packages/manager/src/features/Managed/MonitorDrawer.tsx @@ -1,4 +1,4 @@ -import { InputAdornment } from '@linode/ui'; +import { InputAdornment, Notice } from '@linode/ui'; import { createServiceMonitorSchema } from '@linode/validation/lib/managed.schema'; import Grid from '@mui/material/Unstable_Grid2'; import { Formik } from 'formik'; @@ -8,7 +8,6 @@ import * as React from 'react'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Drawer } from 'src/components/Drawer'; import Select from 'src/components/EnhancedSelect/Select'; -import { Notice } from 'src/components/Notice/Notice'; import { TextField } from 'src/components/TextField'; import type { diff --git a/packages/manager/src/features/Managed/SSHAccess/EditSSHAccessDrawer.tsx b/packages/manager/src/features/Managed/SSHAccess/EditSSHAccessDrawer.tsx index be63b6a4e08..758f6251cb0 100644 --- a/packages/manager/src/features/Managed/SSHAccess/EditSSHAccessDrawer.tsx +++ b/packages/manager/src/features/Managed/SSHAccess/EditSSHAccessDrawer.tsx @@ -1,13 +1,12 @@ -import { ManagedLinodeSetting } from '@linode/api-v4/lib/managed'; +import { Notice } from '@linode/ui'; import Grid from '@mui/material/Unstable_Grid2'; -import { Formik, FormikHelpers } from 'formik'; +import { Formik } from 'formik'; import * as React from 'react'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Drawer } from 'src/components/Drawer'; import { FormControlLabel } from 'src/components/FormControlLabel'; import { IPSelect } from 'src/components/IPSelect/IPSelect'; -import { Notice } from 'src/components/Notice/Notice'; import { TextField } from 'src/components/TextField'; import { Toggle } from 'src/components/Toggle/Toggle'; import { useUpdateLinodeSettingsMutation } from 'src/queries/managed/managed'; @@ -17,12 +16,15 @@ import { } from 'src/utilities/formikErrorUtils'; import { isPrivateIP, removePrefixLength } from 'src/utilities/ipUtils'; +import { DEFAULTS } from './common'; import { StyledIPGrid, StyledPortGrid, StyledTypography, } from './EditSSHAccessDrawer.styles'; -import { DEFAULTS } from './common'; + +import type { ManagedLinodeSetting } from '@linode/api-v4/lib/managed'; +import type { FormikHelpers } from 'formik'; interface EditSSHAccessDrawerProps { closeDrawer: () => void; diff --git a/packages/manager/src/features/NodeBalancers/ConfigNodeIPSelect.tsx b/packages/manager/src/features/NodeBalancers/ConfigNodeIPSelect.tsx index 706cacadcce..1412d22c9ed 100644 --- a/packages/manager/src/features/NodeBalancers/ConfigNodeIPSelect.tsx +++ b/packages/manager/src/features/NodeBalancers/ConfigNodeIPSelect.tsx @@ -1,9 +1,8 @@ -import { Box } from '@linode/ui'; +import { Box, Stack } from '@linode/ui'; import React from 'react'; import { Autocomplete } from 'src/components/Autocomplete/Autocomplete'; import { SelectedIcon } from 'src/components/Autocomplete/Autocomplete.styles'; -import { Stack } from 'src/components/Stack'; import { Typography } from 'src/components/Typography'; import { useAllLinodesQuery } from 'src/queries/linodes/linodes'; diff --git a/packages/manager/src/features/NodeBalancers/NodeBalancerConfigNode.tsx b/packages/manager/src/features/NodeBalancers/NodeBalancerConfigNode.tsx index 00a6c05c09c..e32e13724b4 100644 --- a/packages/manager/src/features/NodeBalancers/NodeBalancerConfigNode.tsx +++ b/packages/manager/src/features/NodeBalancers/NodeBalancerConfigNode.tsx @@ -1,4 +1,4 @@ -import { Box } from '@linode/ui'; +import { Box, Divider, Notice } from '@linode/ui'; import { styled } from '@mui/material/styles'; import Grid from '@mui/material/Unstable_Grid2'; import * as React from 'react'; @@ -6,8 +6,6 @@ import * as React from 'react'; import { Autocomplete } from 'src/components/Autocomplete/Autocomplete'; import { Button } from 'src/components/Button/Button'; import { Chip } from 'src/components/Chip'; -import { Divider } from 'src/components/Divider'; -import { Notice } from 'src/components/Notice/Notice'; import { TextField } from 'src/components/TextField'; import { Typography } from 'src/components/Typography'; import { getErrorMap } from 'src/utilities/errorUtils'; diff --git a/packages/manager/src/features/NodeBalancers/NodeBalancerConfigPanel.tsx b/packages/manager/src/features/NodeBalancers/NodeBalancerConfigPanel.tsx index 0260fd5f049..c6e82c69564 100644 --- a/packages/manager/src/features/NodeBalancers/NodeBalancerConfigPanel.tsx +++ b/packages/manager/src/features/NodeBalancers/NodeBalancerConfigPanel.tsx @@ -1,4 +1,4 @@ -import { FormHelperText } from '@linode/ui'; +import { Divider, FormHelperText, Notice } from '@linode/ui'; import { styled } from '@mui/material/styles'; import Grid from '@mui/material/Unstable_Grid2'; import * as React from 'react'; @@ -6,9 +6,7 @@ import * as React from 'react'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Autocomplete } from 'src/components/Autocomplete/Autocomplete'; import { Button } from 'src/components/Button/Button'; -import { Divider } from 'src/components/Divider'; import { Link } from 'src/components/Link'; -import { Notice } from 'src/components/Notice/Notice'; import { TextField } from 'src/components/TextField'; import { Typography } from 'src/components/Typography'; diff --git a/packages/manager/src/features/NodeBalancers/NodeBalancerCreate.tsx b/packages/manager/src/features/NodeBalancers/NodeBalancerCreate.tsx index 552f0d56928..e7a82ef8318 100644 --- a/packages/manager/src/features/NodeBalancers/NodeBalancerCreate.tsx +++ b/packages/manager/src/features/NodeBalancers/NodeBalancerCreate.tsx @@ -1,4 +1,4 @@ -import { Box, Paper } from '@linode/ui'; +import { Box, Notice, Paper, Stack } from '@linode/ui'; import { useTheme } from '@mui/material'; import useMediaQuery from '@mui/material/useMediaQuery'; import { createLazyRoute } from '@tanstack/react-router'; @@ -24,11 +24,9 @@ import { DocumentTitleSegment } from 'src/components/DocumentTitle'; import { ErrorMessage } from 'src/components/ErrorMessage'; import { LandingHeader } from 'src/components/LandingHeader'; import { Link } from 'src/components/Link'; -import { Notice } from 'src/components/Notice/Notice'; import { RegionSelect } from 'src/components/RegionSelect/RegionSelect'; import { SelectFirewallPanel } from 'src/components/SelectFirewallPanel/SelectFirewallPanel'; import { RegionHelperText } from 'src/components/SelectRegionPanel/RegionHelperText'; -import { Stack } from 'src/components/Stack'; import { TagsInput } from 'src/components/TagsInput/TagsInput'; import { TextField } from 'src/components/TextField'; import { Typography } from 'src/components/Typography'; @@ -54,8 +52,8 @@ import { sendCreateNodeBalancerEvent } from 'src/utilities/analytics/customEvent import { getAPIErrorOrDefault } from 'src/utilities/errorUtils'; import { getGDPRDetails } from 'src/utilities/formatRegion'; import { getAPIErrorFor } from 'src/utilities/getAPIErrorFor'; -import { PRICE_ERROR_TOOLTIP_TEXT } from 'src/utilities/pricing/constants'; import { DOCS_LINK_LABEL_DC_PRICING } from 'src/utilities/pricing/constants'; +import { PRICE_ERROR_TOOLTIP_TEXT } from 'src/utilities/pricing/constants'; import { getDCSpecificPriceByType, renderMonthlyPriceToCorrectDecimalPlace, diff --git a/packages/manager/src/features/NodeBalancers/NodeBalancerDeleteDialog.tsx b/packages/manager/src/features/NodeBalancers/NodeBalancerDeleteDialog.tsx index 982963c6716..adafe73aa42 100644 --- a/packages/manager/src/features/NodeBalancers/NodeBalancerDeleteDialog.tsx +++ b/packages/manager/src/features/NodeBalancers/NodeBalancerDeleteDialog.tsx @@ -1,7 +1,7 @@ +import { Notice } from '@linode/ui'; import * as React from 'react'; import { useHistory } from 'react-router-dom'; -import { Notice } from 'src/components/Notice/Notice'; import { TypeToConfirmDialog } from 'src/components/TypeToConfirmDialog/TypeToConfirmDialog'; import { Typography } from 'src/components/Typography'; import { useNodebalancerDeleteMutation } from 'src/queries/nodebalancers'; diff --git a/packages/manager/src/features/NodeBalancers/NodeBalancerDetail/NodeBalancerDetail.tsx b/packages/manager/src/features/NodeBalancers/NodeBalancerDetail/NodeBalancerDetail.tsx index 14ce668e8ca..5def42f3069 100644 --- a/packages/manager/src/features/NodeBalancers/NodeBalancerDetail/NodeBalancerDetail.tsx +++ b/packages/manager/src/features/NodeBalancers/NodeBalancerDetail/NodeBalancerDetail.tsx @@ -1,3 +1,4 @@ +import { Notice } from '@linode/ui'; import { createLazyRoute } from '@tanstack/react-router'; import * as React from 'react'; import { @@ -10,7 +11,6 @@ import { import { CircleProgress } from 'src/components/CircleProgress'; import { ErrorState } from 'src/components/ErrorState/ErrorState'; import { LandingHeader } from 'src/components/LandingHeader'; -import { Notice } from 'src/components/Notice/Notice'; import { SafeTabPanel } from 'src/components/Tabs/SafeTabPanel'; import { TabLinkList } from 'src/components/Tabs/TabLinkList'; import { TabPanels } from 'src/components/Tabs/TabPanels'; diff --git a/packages/manager/src/features/NodeBalancers/NodeBalancerDetail/NodeBalancerFirewalls.tsx b/packages/manager/src/features/NodeBalancers/NodeBalancerDetail/NodeBalancerFirewalls.tsx index 0ab0801891f..b4a2a09770e 100644 --- a/packages/manager/src/features/NodeBalancers/NodeBalancerDetail/NodeBalancerFirewalls.tsx +++ b/packages/manager/src/features/NodeBalancers/NodeBalancerDetail/NodeBalancerFirewalls.tsx @@ -1,6 +1,5 @@ /* eslint-disable jsx-a11y/anchor-is-valid */ -import { Box } from '@linode/ui'; -import { Stack } from '@mui/material'; +import { Box, Stack } from '@linode/ui'; import * as React from 'react'; import { Link } from 'src/components/Link'; diff --git a/packages/manager/src/features/NotificationCenter/Notifications/NotificationCenterNotificationMessage.tsx b/packages/manager/src/features/NotificationCenter/Notifications/NotificationCenterNotificationMessage.tsx index dedfb32743c..144877d0dad 100644 --- a/packages/manager/src/features/NotificationCenter/Notifications/NotificationCenterNotificationMessage.tsx +++ b/packages/manager/src/features/NotificationCenter/Notifications/NotificationCenterNotificationMessage.tsx @@ -1,10 +1,9 @@ -import { Box } from '@linode/ui'; +import { Box, Divider } from '@linode/ui'; import ErrorIcon from '@mui/icons-material/Error'; import WarningIcon from '@mui/icons-material/Warning'; import { useTheme } from '@mui/material/styles'; import * as React from 'react'; -import { Divider } from 'src/components/Divider'; import { Typography } from 'src/components/Typography'; import { sanitizeHTML } from 'src/utilities/sanitizeHTML'; diff --git a/packages/manager/src/features/ObjectStorage/AccessKeyLanding/AccessKeyDrawer.tsx b/packages/manager/src/features/ObjectStorage/AccessKeyLanding/AccessKeyDrawer.tsx index ec1772b47c2..5b98653ade1 100644 --- a/packages/manager/src/features/ObjectStorage/AccessKeyLanding/AccessKeyDrawer.tsx +++ b/packages/manager/src/features/ObjectStorage/AccessKeyLanding/AccessKeyDrawer.tsx @@ -1,3 +1,4 @@ +import { Notice } from '@linode/ui'; import { createObjectStorageKeysSchema } from '@linode/validation/lib/objectStorageKeys.schema'; import { Formik } from 'formik'; import * as React from 'react'; @@ -6,7 +7,6 @@ import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { CircleProgress } from 'src/components/CircleProgress'; import { Drawer } from 'src/components/Drawer'; import { Link } from 'src/components/Link'; -import { Notice } from 'src/components/Notice/Notice'; import { TextField } from 'src/components/TextField'; import { Typography } from 'src/components/Typography'; import { useAccountSettings } from 'src/queries/account/settings'; diff --git a/packages/manager/src/features/ObjectStorage/AccessKeyLanding/AccessKeyTable/AccessKeyActionMenu.tsx b/packages/manager/src/features/ObjectStorage/AccessKeyLanding/AccessKeyTable/AccessKeyActionMenu.tsx index b0c13b737c1..a0a89cfcb4b 100644 --- a/packages/manager/src/features/ObjectStorage/AccessKeyLanding/AccessKeyTable/AccessKeyActionMenu.tsx +++ b/packages/manager/src/features/ObjectStorage/AccessKeyLanding/AccessKeyTable/AccessKeyActionMenu.tsx @@ -1,9 +1,9 @@ +import { Stack } from '@linode/ui'; import { useMediaQuery } from '@mui/material'; import * as React from 'react'; import { ActionMenu } from 'src/components/ActionMenu/ActionMenu'; import { InlineMenuAction } from 'src/components/InlineMenuAction/InlineMenuAction'; -import { Stack } from 'src/components/Stack'; import { useAccountManagement } from 'src/hooks/useAccountManagement'; import { useFlags } from 'src/hooks/useFlags'; import { isFeatureEnabledV2 } from 'src/utilities/accountCapabilities'; diff --git a/packages/manager/src/features/ObjectStorage/AccessKeyLanding/AccessKeyTable/AccessKeyTableRow.tsx b/packages/manager/src/features/ObjectStorage/AccessKeyLanding/AccessKeyTable/AccessKeyTableRow.tsx index f9755977e65..9803c41c0f8 100644 --- a/packages/manager/src/features/ObjectStorage/AccessKeyLanding/AccessKeyTable/AccessKeyTableRow.tsx +++ b/packages/manager/src/features/ObjectStorage/AccessKeyLanding/AccessKeyTable/AccessKeyTableRow.tsx @@ -1,10 +1,10 @@ +import { Stack } from '@linode/ui'; import { styled } from '@mui/material/styles'; import React from 'react'; import { CopyTooltip } from 'src/components/CopyTooltip/CopyTooltip'; import { Hidden } from 'src/components/Hidden'; import { MaskableText } from 'src/components/MaskableText/MaskableText'; -import { Stack } from 'src/components/Stack'; import { TableCell } from 'src/components/TableCell'; import { TableRow } from 'src/components/TableRow'; import { Typography } from 'src/components/Typography'; diff --git a/packages/manager/src/features/ObjectStorage/AccessKeyLanding/OMC_AccessKeyDrawer.tsx b/packages/manager/src/features/ObjectStorage/AccessKeyLanding/OMC_AccessKeyDrawer.tsx index d2800c937b5..4d3f0b058a9 100644 --- a/packages/manager/src/features/ObjectStorage/AccessKeyLanding/OMC_AccessKeyDrawer.tsx +++ b/packages/manager/src/features/ObjectStorage/AccessKeyLanding/OMC_AccessKeyDrawer.tsx @@ -1,3 +1,4 @@ +import { Notice } from '@linode/ui'; import { createObjectStorageKeysSchema, updateObjectStorageKeysSchema, @@ -9,7 +10,6 @@ import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { CircleProgress } from 'src/components/CircleProgress'; import { Drawer } from 'src/components/Drawer'; import { Link } from 'src/components/Link'; -import { Notice } from 'src/components/Notice/Notice'; import { TextField } from 'src/components/TextField'; import { Typography } from 'src/components/Typography'; import { useAccountSettings } from 'src/queries/account/settings'; diff --git a/packages/manager/src/features/ObjectStorage/BucketDetail/AccessSelect.tsx b/packages/manager/src/features/ObjectStorage/BucketDetail/AccessSelect.tsx index 362a8b21f74..6e60543b31e 100644 --- a/packages/manager/src/features/ObjectStorage/BucketDetail/AccessSelect.tsx +++ b/packages/manager/src/features/ObjectStorage/BucketDetail/AccessSelect.tsx @@ -1,3 +1,4 @@ +import { Notice } from '@linode/ui'; import * as React from 'react'; import { Controller, useForm } from 'react-hook-form'; @@ -6,7 +7,6 @@ import { Autocomplete } from 'src/components/Autocomplete/Autocomplete'; import { ConfirmationDialog } from 'src/components/ConfirmationDialog/ConfirmationDialog'; import { FormControlLabel } from 'src/components/FormControlLabel'; import { Link } from 'src/components/Link'; -import { Notice } from 'src/components/Notice/Notice'; import { Toggle } from 'src/components/Toggle/Toggle'; import { Typography } from 'src/components/Typography'; import { useOpenClose } from 'src/hooks/useOpenClose'; diff --git a/packages/manager/src/features/ObjectStorage/BucketDetail/BucketSSL.tsx b/packages/manager/src/features/ObjectStorage/BucketDetail/BucketSSL.tsx index c410769f1db..dd52c4ad660 100644 --- a/packages/manager/src/features/ObjectStorage/BucketDetail/BucketSSL.tsx +++ b/packages/manager/src/features/ObjectStorage/BucketDetail/BucketSSL.tsx @@ -1,4 +1,4 @@ -import { Paper } from '@linode/ui'; +import { Notice, Paper } from '@linode/ui'; import { useTheme } from '@mui/material/styles'; import Grid from '@mui/material/Unstable_Grid2'; import { useFormik } from 'formik'; @@ -11,7 +11,6 @@ import { CircleProgress } from 'src/components/CircleProgress'; import { ConfirmationDialog } from 'src/components/ConfirmationDialog/ConfirmationDialog'; import { ErrorState } from 'src/components/ErrorState/ErrorState'; import { Link } from 'src/components/Link'; -import { Notice } from 'src/components/Notice/Notice'; import { TextField } from 'src/components/TextField'; import { Typography } from 'src/components/Typography'; import { diff --git a/packages/manager/src/features/ObjectStorage/BucketDetail/ObjectDetailsDrawer.tsx b/packages/manager/src/features/ObjectStorage/BucketDetail/ObjectDetailsDrawer.tsx index dbb4e111a0c..fb2a9e2fd26 100644 --- a/packages/manager/src/features/ObjectStorage/BucketDetail/ObjectDetailsDrawer.tsx +++ b/packages/manager/src/features/ObjectStorage/BucketDetail/ObjectDetailsDrawer.tsx @@ -1,8 +1,8 @@ +import { Divider } from '@linode/ui'; import { styled } from '@mui/material/styles'; import * as React from 'react'; import { CopyTooltip } from 'src/components/CopyTooltip/CopyTooltip'; -import { Divider } from 'src/components/Divider'; import { Drawer } from 'src/components/Drawer'; import { Link } from 'src/components/Link'; import { Typography } from 'src/components/Typography'; diff --git a/packages/manager/src/features/ObjectStorage/BucketLanding/BucketDetailsDrawer.tsx b/packages/manager/src/features/ObjectStorage/BucketLanding/BucketDetailsDrawer.tsx index 9a8c8f2dc55..fd5f87bfb7c 100644 --- a/packages/manager/src/features/ObjectStorage/BucketLanding/BucketDetailsDrawer.tsx +++ b/packages/manager/src/features/ObjectStorage/BucketLanding/BucketDetailsDrawer.tsx @@ -1,8 +1,8 @@ +import { Divider } from '@linode/ui'; import { styled } from '@mui/material/styles'; import * as React from 'react'; import { CopyTooltip } from 'src/components/CopyTooltip/CopyTooltip'; -import { Divider } from 'src/components/Divider'; import { Drawer } from 'src/components/Drawer'; import { Link } from 'src/components/Link'; import { MaskableText } from 'src/components/MaskableText/MaskableText'; diff --git a/packages/manager/src/features/ObjectStorage/BucketLanding/BucketLanding.tsx b/packages/manager/src/features/ObjectStorage/BucketLanding/BucketLanding.tsx index 0c8115d8b5c..3364a09a270 100644 --- a/packages/manager/src/features/ObjectStorage/BucketLanding/BucketLanding.tsx +++ b/packages/manager/src/features/ObjectStorage/BucketLanding/BucketLanding.tsx @@ -1,3 +1,4 @@ +import { Notice } from '@linode/ui'; import Grid from '@mui/material/Unstable_Grid2'; import * as React from 'react'; import { makeStyles } from 'tss-react/mui'; @@ -6,7 +7,6 @@ import { CircleProgress } from 'src/components/CircleProgress'; import { DocumentTitleSegment } from 'src/components/DocumentTitle'; import { ErrorState } from 'src/components/ErrorState/ErrorState'; import { Link } from 'src/components/Link'; -import { Notice } from 'src/components/Notice/Notice'; import OrderBy from 'src/components/OrderBy'; import { TransferDisplay } from 'src/components/TransferDisplay/TransferDisplay'; import { TypeToConfirmDialog } from 'src/components/TypeToConfirmDialog/TypeToConfirmDialog'; diff --git a/packages/manager/src/features/ObjectStorage/BucketLanding/BucketTableRow.tsx b/packages/manager/src/features/ObjectStorage/BucketLanding/BucketTableRow.tsx index a84a923baba..1febd590d2a 100644 --- a/packages/manager/src/features/ObjectStorage/BucketLanding/BucketTableRow.tsx +++ b/packages/manager/src/features/ObjectStorage/BucketLanding/BucketTableRow.tsx @@ -1,10 +1,10 @@ +import { Stack } from '@linode/ui'; import * as React from 'react'; import { DateTimeDisplay } from 'src/components/DateTimeDisplay'; import { Hidden } from 'src/components/Hidden'; import { Link } from 'src/components/Link'; import { MaskableText } from 'src/components/MaskableText/MaskableText'; -import { Stack } from 'src/components/Stack'; import { TableCell } from 'src/components/TableCell'; import { TableRow } from 'src/components/TableRow'; import { Typography } from 'src/components/Typography'; diff --git a/packages/manager/src/features/ObjectStorage/BucketLanding/CreateBucketDrawer.tsx b/packages/manager/src/features/ObjectStorage/BucketLanding/CreateBucketDrawer.tsx index 3adc16b1863..93e60b33c19 100644 --- a/packages/manager/src/features/ObjectStorage/BucketLanding/CreateBucketDrawer.tsx +++ b/packages/manager/src/features/ObjectStorage/BucketLanding/CreateBucketDrawer.tsx @@ -1,4 +1,5 @@ import { yupResolver } from '@hookform/resolvers/yup'; +import { Notice } from '@linode/ui'; import { CreateBucketSchema } from '@linode/validation'; import { styled } from '@mui/material/styles'; import * as React from 'react'; @@ -6,7 +7,6 @@ import { Controller, useForm } from 'react-hook-form'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Drawer } from 'src/components/Drawer'; -import { Notice } from 'src/components/Notice/Notice'; import { TextField } from 'src/components/TextField'; import { EUAgreementCheckbox } from 'src/features/Account/Agreements/EUAgreementCheckbox'; import { diff --git a/packages/manager/src/features/ObjectStorage/BucketLanding/OMC_BucketLanding.tsx b/packages/manager/src/features/ObjectStorage/BucketLanding/OMC_BucketLanding.tsx index df19e2f4efa..1c595b05674 100644 --- a/packages/manager/src/features/ObjectStorage/BucketLanding/OMC_BucketLanding.tsx +++ b/packages/manager/src/features/ObjectStorage/BucketLanding/OMC_BucketLanding.tsx @@ -1,3 +1,4 @@ +import { Notice } from '@linode/ui'; import Grid from '@mui/material/Unstable_Grid2'; import * as React from 'react'; import { makeStyles } from 'tss-react/mui'; @@ -6,7 +7,6 @@ import { CircleProgress } from 'src/components/CircleProgress'; import { DocumentTitleSegment } from 'src/components/DocumentTitle'; import { ErrorState } from 'src/components/ErrorState/ErrorState'; import { Link } from 'src/components/Link'; -import { Notice } from 'src/components/Notice/Notice'; import OrderBy from 'src/components/OrderBy'; import { TransferDisplay } from 'src/components/TransferDisplay/TransferDisplay'; import { TypeToConfirmDialog } from 'src/components/TypeToConfirmDialog/TypeToConfirmDialog'; diff --git a/packages/manager/src/features/ObjectStorage/BucketLanding/OMC_CreateBucketDrawer.tsx b/packages/manager/src/features/ObjectStorage/BucketLanding/OMC_CreateBucketDrawer.tsx index c1ba644e64d..dc3080c7efa 100644 --- a/packages/manager/src/features/ObjectStorage/BucketLanding/OMC_CreateBucketDrawer.tsx +++ b/packages/manager/src/features/ObjectStorage/BucketLanding/OMC_CreateBucketDrawer.tsx @@ -1,4 +1,5 @@ import { yupResolver } from '@hookform/resolvers/yup'; +import { Notice } from '@linode/ui'; import { CreateBucketSchema } from '@linode/validation'; import * as React from 'react'; import { Controller, useForm } from 'react-hook-form'; @@ -7,7 +8,6 @@ import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Autocomplete } from 'src/components/Autocomplete/Autocomplete'; import { Drawer } from 'src/components/Drawer'; import { Link } from 'src/components/Link'; -import { Notice } from 'src/components/Notice/Notice'; import { TextField } from 'src/components/TextField'; import { Typography } from 'src/components/Typography'; import { BucketRateLimitTable } from 'src/features/ObjectStorage/BucketLanding/BucketRateLimitTable'; diff --git a/packages/manager/src/features/ObjectStorage/EnableObjectStorageModal.tsx b/packages/manager/src/features/ObjectStorage/EnableObjectStorageModal.tsx index 10299d74625..ffe51b118b4 100644 --- a/packages/manager/src/features/ObjectStorage/EnableObjectStorageModal.tsx +++ b/packages/manager/src/features/ObjectStorage/EnableObjectStorageModal.tsx @@ -1,10 +1,10 @@ +import { Notice } from '@linode/ui'; import { styled } from '@mui/material/styles'; import * as React from 'react'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { ConfirmationDialog } from 'src/components/ConfirmationDialog/ConfirmationDialog'; import { Link } from 'src/components/Link'; -import { Notice } from 'src/components/Notice/Notice'; import { Typography } from 'src/components/Typography'; import { useObjectStorageTypesQuery } from 'src/queries/object-storage/queries'; import { diff --git a/packages/manager/src/features/PlacementGroups/PlacementGroupPolicyRadioGroup.tsx b/packages/manager/src/features/PlacementGroups/PlacementGroupPolicyRadioGroup.tsx index 27d4b7f299d..965414a2fed 100644 --- a/packages/manager/src/features/PlacementGroups/PlacementGroupPolicyRadioGroup.tsx +++ b/packages/manager/src/features/PlacementGroups/PlacementGroupPolicyRadioGroup.tsx @@ -1,9 +1,8 @@ -import { Box } from '@linode/ui'; +import { Box, Notice } from '@linode/ui'; import * as React from 'react'; import { FormControlLabel } from 'src/components/FormControlLabel'; import { FormLabel } from 'src/components/FormLabel'; -import { Notice } from 'src/components/Notice/Notice'; import { Radio } from 'src/components/Radio/Radio'; import { RadioGroup } from 'src/components/RadioGroup'; import { Typography } from 'src/components/Typography'; diff --git a/packages/manager/src/features/PlacementGroups/PlacementGroupsAssignLinodesDrawer.tsx b/packages/manager/src/features/PlacementGroups/PlacementGroupsAssignLinodesDrawer.tsx index 8aaa0e6eae6..89621be0775 100644 --- a/packages/manager/src/features/PlacementGroups/PlacementGroupsAssignLinodesDrawer.tsx +++ b/packages/manager/src/features/PlacementGroups/PlacementGroupsAssignLinodesDrawer.tsx @@ -2,16 +2,13 @@ import { PLACEMENT_GROUP_POLICIES, PLACEMENT_GROUP_TYPES, } from '@linode/api-v4'; -import { Box } from '@linode/ui'; +import { Box, Divider, Notice, Stack } from '@linode/ui'; import { useSnackbar } from 'notistack'; import * as React from 'react'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { DescriptionList } from 'src/components/DescriptionList/DescriptionList'; -import { Divider } from 'src/components/Divider'; import { Drawer } from 'src/components/Drawer'; -import { Notice } from 'src/components/Notice/Notice'; -import { Stack } from 'src/components/Stack'; import { TooltipIcon } from 'src/components/TooltipIcon'; import { Typography } from 'src/components/Typography'; import { useAllLinodesQuery } from 'src/queries/linodes/linodes'; diff --git a/packages/manager/src/features/PlacementGroups/PlacementGroupsCreateDrawer.tsx b/packages/manager/src/features/PlacementGroups/PlacementGroupsCreateDrawer.tsx index 16469439483..9da8bd6be02 100644 --- a/packages/manager/src/features/PlacementGroups/PlacementGroupsCreateDrawer.tsx +++ b/packages/manager/src/features/PlacementGroups/PlacementGroupsCreateDrawer.tsx @@ -1,3 +1,4 @@ +import { Divider, Notice, Stack } from '@linode/ui'; import { createPlacementGroupSchema } from '@linode/validation'; import { useFormik } from 'formik'; import { useSnackbar } from 'notistack'; @@ -6,13 +7,10 @@ import { useLocation } from 'react-router-dom'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { DescriptionList } from 'src/components/DescriptionList/DescriptionList'; -import { Divider } from 'src/components/Divider'; import { Drawer } from 'src/components/Drawer'; import { List } from 'src/components/List'; import { ListItem } from 'src/components/ListItem'; -import { Notice } from 'src/components/Notice/Notice'; import { RegionSelect } from 'src/components/RegionSelect/RegionSelect'; -import { Stack } from 'src/components/Stack'; import { TextField } from 'src/components/TextField'; import { Typography } from 'src/components/Typography'; import { getRestrictedResourceText } from 'src/features/Account/utils'; @@ -43,7 +41,7 @@ import type { Region, } from '@linode/api-v4'; import type { FormikHelpers } from 'formik'; -import type { DisableRegionOption } from 'src/components/RegionSelect/RegionSelect.types'; +import type { DisableItemOption } from 'src/components/ListItemOption'; export const PlacementGroupsCreateDrawer = ( props: PlacementGroupsCreateDrawerProps @@ -156,7 +154,7 @@ export const PlacementGroupsCreateDrawer = ( selectedRegion )}`; - const disabledRegions = regions?.reduce>( + const disabledRegions = regions?.reduce>( (acc, region) => { const isRegionAtCapacity = hasRegionReachedPlacementGroupCapacity({ allPlacementGroups: allPlacementGroupsInRegion, diff --git a/packages/manager/src/features/PlacementGroups/PlacementGroupsDeleteModal.tsx b/packages/manager/src/features/PlacementGroups/PlacementGroupsDeleteModal.tsx index 383bbc74093..902bd710643 100644 --- a/packages/manager/src/features/PlacementGroups/PlacementGroupsDeleteModal.tsx +++ b/packages/manager/src/features/PlacementGroups/PlacementGroupsDeleteModal.tsx @@ -1,3 +1,4 @@ +import { Notice } from '@linode/ui'; import { useSnackbar } from 'notistack'; import * as React from 'react'; @@ -6,7 +7,6 @@ import { CircleProgress } from 'src/components/CircleProgress'; import { ConfirmationDialog } from 'src/components/ConfirmationDialog/ConfirmationDialog'; import { List } from 'src/components/List'; import { ListItem } from 'src/components/ListItem'; -import { Notice } from 'src/components/Notice/Notice'; import { RemovableSelectionsList } from 'src/components/RemovableSelectionsList/RemovableSelectionsList'; import { TypeToConfirmDialog } from 'src/components/TypeToConfirmDialog/TypeToConfirmDialog'; import { Typography } from 'src/components/Typography'; diff --git a/packages/manager/src/features/PlacementGroups/PlacementGroupsDetail/PlacementGroupsDetail.tsx b/packages/manager/src/features/PlacementGroups/PlacementGroupsDetail/PlacementGroupsDetail.tsx index fce4cd920c0..27280179d3d 100644 --- a/packages/manager/src/features/PlacementGroups/PlacementGroupsDetail/PlacementGroupsDetail.tsx +++ b/packages/manager/src/features/PlacementGroups/PlacementGroupsDetail/PlacementGroupsDetail.tsx @@ -1,4 +1,5 @@ import { PLACEMENT_GROUP_TYPES } from '@linode/api-v4'; +import { Notice } from '@linode/ui'; import { createLazyRoute } from '@tanstack/react-router'; import * as React from 'react'; import { useParams } from 'react-router-dom'; @@ -8,7 +9,6 @@ import { DocumentTitleSegment } from 'src/components/DocumentTitle'; import { ErrorState } from 'src/components/ErrorState/ErrorState'; import { LandingHeader } from 'src/components/LandingHeader'; import { NotFound } from 'src/components/NotFound'; -import { Notice } from 'src/components/Notice/Notice'; import { getRestrictedResourceText } from 'src/features/Account/utils'; import { useRestrictedGlobalGrantCheck } from 'src/hooks/useRestrictedGlobalGrantCheck'; import { useAllLinodesQuery } from 'src/queries/linodes/linodes'; diff --git a/packages/manager/src/features/PlacementGroups/PlacementGroupsDetail/PlacementGroupsLinodes/PlacementGroupsLinodes.tsx b/packages/manager/src/features/PlacementGroups/PlacementGroupsDetail/PlacementGroupsLinodes/PlacementGroupsLinodes.tsx index 7347ff8ca95..dbdc218d306 100644 --- a/packages/manager/src/features/PlacementGroups/PlacementGroupsDetail/PlacementGroupsLinodes/PlacementGroupsLinodes.tsx +++ b/packages/manager/src/features/PlacementGroups/PlacementGroupsDetail/PlacementGroupsLinodes/PlacementGroupsLinodes.tsx @@ -1,3 +1,4 @@ +import { Stack } from '@linode/ui'; import Grid from '@mui/material/Unstable_Grid2/Grid2'; import * as React from 'react'; import { useHistory } from 'react-router-dom'; @@ -5,7 +6,6 @@ import { useHistory } from 'react-router-dom'; import { Button } from 'src/components/Button/Button'; import { DebouncedSearchTextField } from 'src/components/DebouncedSearchTextField'; import { ErrorState } from 'src/components/ErrorState/ErrorState'; -import { Stack } from 'src/components/Stack'; import { hasPlacementGroupReachedCapacity } from 'src/features/PlacementGroups/utils'; import { diff --git a/packages/manager/src/features/PlacementGroups/PlacementGroupsDetail/PlacementGroupsSummary/PlacementGroupsSummary.tsx b/packages/manager/src/features/PlacementGroups/PlacementGroupsDetail/PlacementGroupsSummary/PlacementGroupsSummary.tsx index d5b3489c74b..a539181243c 100644 --- a/packages/manager/src/features/PlacementGroups/PlacementGroupsDetail/PlacementGroupsSummary/PlacementGroupsSummary.tsx +++ b/packages/manager/src/features/PlacementGroups/PlacementGroupsDetail/PlacementGroupsSummary/PlacementGroupsSummary.tsx @@ -2,6 +2,7 @@ import { PLACEMENT_GROUP_POLICIES, PLACEMENT_GROUP_TYPES, } from '@linode/api-v4'; +import { Notice, Paper } from '@linode/ui'; import { Box } from '@linode/ui'; import { useTheme } from '@mui/material'; import { styled } from '@mui/material/styles'; @@ -9,8 +10,6 @@ import * as React from 'react'; import { DescriptionList } from 'src/components/DescriptionList/DescriptionList'; import { Link } from 'src/components/Link'; -import { Notice } from 'src/components/Notice/Notice'; -import { Paper } from '@linode/ui'; import { Typography } from 'src/components/Typography'; import { diff --git a/packages/manager/src/features/PlacementGroups/PlacementGroupsDetailPanel.tsx b/packages/manager/src/features/PlacementGroups/PlacementGroupsDetailPanel.tsx index 5b6d526718c..6ddd64f4751 100644 --- a/packages/manager/src/features/PlacementGroups/PlacementGroupsDetailPanel.tsx +++ b/packages/manager/src/features/PlacementGroups/PlacementGroupsDetailPanel.tsx @@ -1,10 +1,9 @@ -import { Box } from '@linode/ui'; +import { Box, Notice } from '@linode/ui'; import { useTheme } from '@mui/material/styles'; import * as React from 'react'; import { Button } from 'src/components/Button/Button'; import { ListItem } from 'src/components/ListItem'; -import { Notice } from 'src/components/Notice/Notice'; import { PlacementGroupsSelect } from 'src/components/PlacementGroupsSelect/PlacementGroupsSelect'; import { TextTooltip } from 'src/components/TextTooltip'; import { Typography } from 'src/components/Typography'; diff --git a/packages/manager/src/features/PlacementGroups/PlacementGroupsEditDrawer.tsx b/packages/manager/src/features/PlacementGroups/PlacementGroupsEditDrawer.tsx index 2689d6229a1..ed33610ca15 100644 --- a/packages/manager/src/features/PlacementGroups/PlacementGroupsEditDrawer.tsx +++ b/packages/manager/src/features/PlacementGroups/PlacementGroupsEditDrawer.tsx @@ -1,7 +1,8 @@ import { - PLACEMENT_GROUP_TYPES, PLACEMENT_GROUP_POLICIES, + PLACEMENT_GROUP_TYPES, } from '@linode/api-v4'; +import { Divider, Notice, Stack } from '@linode/ui'; import { updatePlacementGroupSchema } from '@linode/validation'; import { useFormik } from 'formik'; import { useSnackbar } from 'notistack'; @@ -11,11 +12,8 @@ import { useParams } from 'react-router-dom'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { CircleProgress } from 'src/components/CircleProgress'; import { DescriptionList } from 'src/components/DescriptionList/DescriptionList'; -import { Divider } from 'src/components/Divider'; import { Drawer } from 'src/components/Drawer'; import { NotFound } from 'src/components/NotFound'; -import { Notice } from 'src/components/Notice/Notice'; -import { Stack } from 'src/components/Stack'; import { TextField } from 'src/components/TextField'; import { useFormValidateOnChange } from 'src/hooks/useFormValidateOnChange'; import { diff --git a/packages/manager/src/features/PlacementGroups/PlacementGroupsUnassignModal.tsx b/packages/manager/src/features/PlacementGroups/PlacementGroupsUnassignModal.tsx index 5d41f301424..8b179291dde 100644 --- a/packages/manager/src/features/PlacementGroups/PlacementGroupsUnassignModal.tsx +++ b/packages/manager/src/features/PlacementGroups/PlacementGroupsUnassignModal.tsx @@ -1,3 +1,4 @@ +import { Notice } from '@linode/ui'; import { useSnackbar } from 'notistack'; import * as React from 'react'; import { useParams } from 'react-router-dom'; @@ -6,7 +7,6 @@ import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { CircleProgress } from 'src/components/CircleProgress'; import { ConfirmationDialog } from 'src/components/ConfirmationDialog/ConfirmationDialog'; import { NotFound } from 'src/components/NotFound'; -import { Notice } from 'src/components/Notice/Notice'; import { Typography } from 'src/components/Typography'; import { useIsResourceRestricted } from 'src/hooks/useIsResourceRestricted'; import { useLinodeQuery } from 'src/queries/linodes/linodes'; diff --git a/packages/manager/src/features/Profile/APITokens/APITokens.tsx b/packages/manager/src/features/Profile/APITokens/APITokens.tsx index 5acd5364415..5e466724443 100644 --- a/packages/manager/src/features/Profile/APITokens/APITokens.tsx +++ b/packages/manager/src/features/Profile/APITokens/APITokens.tsx @@ -1,4 +1,4 @@ -import { Stack } from '@mui/material'; +import { Stack } from '@linode/ui'; import { createLazyRoute } from '@tanstack/react-router'; import * as React from 'react'; diff --git a/packages/manager/src/features/Profile/APITokens/CreateAPITokenDrawer.tsx b/packages/manager/src/features/Profile/APITokens/CreateAPITokenDrawer.tsx index 58a0b8cc935..5ba5c47dcf0 100644 --- a/packages/manager/src/features/Profile/APITokens/CreateAPITokenDrawer.tsx +++ b/packages/manager/src/features/Profile/APITokens/CreateAPITokenDrawer.tsx @@ -1,4 +1,4 @@ -import { FormControl, FormHelperText } from '@linode/ui'; +import { FormControl, FormHelperText, Notice } from '@linode/ui'; import { useFormik } from 'formik'; import { DateTime } from 'luxon'; import * as React from 'react'; @@ -6,7 +6,6 @@ import * as React from 'react'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Autocomplete } from 'src/components/Autocomplete/Autocomplete'; import { Drawer } from 'src/components/Drawer'; -import { Notice } from 'src/components/Notice/Notice'; import { Radio } from 'src/components/Radio/Radio'; import { TableBody } from 'src/components/TableBody'; import { TableCell } from 'src/components/TableCell'; diff --git a/packages/manager/src/features/Profile/APITokens/EditAPITokenDrawer.tsx b/packages/manager/src/features/Profile/APITokens/EditAPITokenDrawer.tsx index 3aba5fb979f..5c4e9b2bc74 100644 --- a/packages/manager/src/features/Profile/APITokens/EditAPITokenDrawer.tsx +++ b/packages/manager/src/features/Profile/APITokens/EditAPITokenDrawer.tsx @@ -1,9 +1,9 @@ +import { Notice } from '@linode/ui'; import { useFormik } from 'formik'; import * as React from 'react'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Drawer } from 'src/components/Drawer'; -import { Notice } from 'src/components/Notice/Notice'; import { TextField } from 'src/components/TextField'; import { useUpdatePersonalAccessTokenMutation } from 'src/queries/profile/tokens'; import { getErrorMap } from 'src/utilities/errorUtils'; diff --git a/packages/manager/src/features/Profile/AuthenticationSettings/AuthenticationSettings.tsx b/packages/manager/src/features/Profile/AuthenticationSettings/AuthenticationSettings.tsx index efba74259d0..37bf55467c7 100644 --- a/packages/manager/src/features/Profile/AuthenticationSettings/AuthenticationSettings.tsx +++ b/packages/manager/src/features/Profile/AuthenticationSettings/AuthenticationSettings.tsx @@ -1,11 +1,10 @@ -import { Paper } from '@linode/ui'; +import { Divider, Paper } from '@linode/ui'; import { styled } from '@mui/material/styles'; import { createLazyRoute } from '@tanstack/react-router'; import * as React from 'react'; import { useLocation } from 'react-router-dom'; import { CircleProgress } from 'src/components/CircleProgress'; -import { Divider } from 'src/components/Divider'; import { DocumentTitleSegment } from 'src/components/DocumentTitle'; import { ErrorState } from 'src/components/ErrorState/ErrorState'; import { Link } from 'src/components/Link'; diff --git a/packages/manager/src/features/Profile/AuthenticationSettings/SMSMessaging.tsx b/packages/manager/src/features/Profile/AuthenticationSettings/SMSMessaging.tsx index d9cde16e883..7b09373c3ba 100644 --- a/packages/manager/src/features/Profile/AuthenticationSettings/SMSMessaging.tsx +++ b/packages/manager/src/features/Profile/AuthenticationSettings/SMSMessaging.tsx @@ -1,4 +1,4 @@ -import { Box } from '@linode/ui'; +import { Box, Notice } from '@linode/ui'; import { styled } from '@mui/material/styles'; import { useSnackbar } from 'notistack'; import * as React from 'react'; @@ -7,10 +7,9 @@ import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Button } from 'src/components/Button/Button'; import { ConfirmationDialog } from 'src/components/ConfirmationDialog/ConfirmationDialog'; import { Link } from 'src/components/Link'; -import { Notice } from 'src/components/Notice/Notice'; import { Typography } from 'src/components/Typography'; -import { useSMSOptOutMutation } from 'src/queries/profile/profile'; import { useProfile } from 'src/queries/profile/profile'; +import { useSMSOptOutMutation } from 'src/queries/profile/profile'; import { getFormattedNumber } from './PhoneVerification/helpers'; diff --git a/packages/manager/src/features/Profile/AuthenticationSettings/TPAProviders.styles.ts b/packages/manager/src/features/Profile/AuthenticationSettings/TPAProviders.styles.ts index f0cc13c638c..1a8ccc383f8 100644 --- a/packages/manager/src/features/Profile/AuthenticationSettings/TPAProviders.styles.ts +++ b/packages/manager/src/features/Profile/AuthenticationSettings/TPAProviders.styles.ts @@ -1,9 +1,8 @@ -import { Paper } from '@linode/ui'; +import { Notice, Paper } from '@linode/ui'; import { styled } from '@mui/material/styles'; import Grid from '@mui/material/Unstable_Grid2'; import { Button } from 'src/components/Button/Button'; -import { Notice } from 'src/components/Notice/Notice'; import { Typography } from 'src/components/Typography'; export const StyledRootContainer = styled(Paper, { diff --git a/packages/manager/src/features/Profile/AuthenticationSettings/TPAProviders.tsx b/packages/manager/src/features/Profile/AuthenticationSettings/TPAProviders.tsx index caed45a3d8f..2309057377e 100644 --- a/packages/manager/src/features/Profile/AuthenticationSettings/TPAProviders.tsx +++ b/packages/manager/src/features/Profile/AuthenticationSettings/TPAProviders.tsx @@ -1,4 +1,4 @@ -import { Box } from '@linode/ui'; +import { Box, Divider } from '@linode/ui'; import { useTheme } from '@mui/material/styles'; import Grid from '@mui/material/Unstable_Grid2'; import * as React from 'react'; @@ -7,7 +7,6 @@ import EnabledIcon from 'src/assets/icons/checkmark-enabled.svg'; import AkamaiWaveOnlyIcon from 'src/assets/icons/providers/akamai-logo-rgb-waveOnly.svg'; import GitHubIcon from 'src/assets/icons/providers/github-logo.svg'; import GoogleIcon from 'src/assets/icons/providers/google-logo.svg'; -import { Divider } from 'src/components/Divider'; import { Link } from 'src/components/Link'; import { Typography } from 'src/components/Typography'; import { useFlags } from 'src/hooks/useFlags'; diff --git a/packages/manager/src/features/Profile/AuthenticationSettings/TwoFactor/ConfirmToken.tsx b/packages/manager/src/features/Profile/AuthenticationSettings/TwoFactor/ConfirmToken.tsx index 2584b7bd3d1..af8c2d769d4 100644 --- a/packages/manager/src/features/Profile/AuthenticationSettings/TwoFactor/ConfirmToken.tsx +++ b/packages/manager/src/features/Profile/AuthenticationSettings/TwoFactor/ConfirmToken.tsx @@ -1,9 +1,8 @@ -import { Box } from '@linode/ui'; +import { Box, Notice } from '@linode/ui'; import { styled } from '@mui/material/styles'; import * as React from 'react'; import { Button } from 'src/components/Button/Button'; -import { Notice } from 'src/components/Notice/Notice'; import { TextField } from 'src/components/TextField'; import { Typography } from 'src/components/Typography'; diff --git a/packages/manager/src/features/Profile/AuthenticationSettings/TwoFactor/EnableTwoFactorForm.tsx b/packages/manager/src/features/Profile/AuthenticationSettings/TwoFactor/EnableTwoFactorForm.tsx index 118739bf97c..5881375ed7c 100644 --- a/packages/manager/src/features/Profile/AuthenticationSettings/TwoFactor/EnableTwoFactorForm.tsx +++ b/packages/manager/src/features/Profile/AuthenticationSettings/TwoFactor/EnableTwoFactorForm.tsx @@ -1,16 +1,16 @@ import { confirmTwoFactor } from '@linode/api-v4/lib/profile'; -import { APIError } from '@linode/api-v4/lib/types'; +import { Divider, Notice } from '@linode/ui'; import * as React from 'react'; import { CircleProgress } from 'src/components/CircleProgress'; -import { Divider } from 'src/components/Divider'; -import { Notice } from 'src/components/Notice/Notice'; import { getAPIErrorOrDefault, getErrorMap } from 'src/utilities/errorUtils'; import { scrollErrorIntoView } from 'src/utilities/scrollErrorIntoView'; import { ConfirmToken } from './ConfirmToken'; import { QRCodeForm } from './QRCodeForm'; +import type { APIError } from '@linode/api-v4/lib/types'; + interface Props { loading: boolean; onCancel: () => void; diff --git a/packages/manager/src/features/Profile/AuthenticationSettings/TwoFactor/TwoFactor.tsx b/packages/manager/src/features/Profile/AuthenticationSettings/TwoFactor/TwoFactor.tsx index 9dd8382c268..fc5fde78603 100644 --- a/packages/manager/src/features/Profile/AuthenticationSettings/TwoFactor/TwoFactor.tsx +++ b/packages/manager/src/features/Profile/AuthenticationSettings/TwoFactor/TwoFactor.tsx @@ -1,11 +1,11 @@ import { getTFAToken } from '@linode/api-v4/lib/profile'; -import { APIError } from '@linode/api-v4/lib/types'; -import * as React from 'react'; +import { Notice } from '@linode/ui'; import { useQueryClient } from '@tanstack/react-query'; +import * as React from 'react'; import { StyledLinkButton } from 'src/components/Button/StyledLinkButton'; -import { Notice } from 'src/components/Notice/Notice'; import { Typography } from 'src/components/Typography'; +import { profileQueries } from 'src/queries/profile/profile'; import { useSecurityQuestions } from 'src/queries/profile/securityQuestions'; import { getAPIErrorOrDefault } from 'src/utilities/errorUtils'; import { getAPIErrorFor } from 'src/utilities/getAPIErrorFor'; @@ -19,7 +19,8 @@ import { StyledRootContainer, } from './TwoFactor.styles'; import { TwoFactorToggle } from './TwoFactorToggle'; -import { profileQueries } from 'src/queries/profile/profile'; + +import type { APIError } from '@linode/api-v4/lib/types'; export interface TwoFactorProps { disabled?: boolean; diff --git a/packages/manager/src/features/Profile/DisplaySettings/AvatarColorPickerDialog.tsx b/packages/manager/src/features/Profile/DisplaySettings/AvatarColorPickerDialog.tsx index 52c0c3a4378..97401d291eb 100644 --- a/packages/manager/src/features/Profile/DisplaySettings/AvatarColorPickerDialog.tsx +++ b/packages/manager/src/features/Profile/DisplaySettings/AvatarColorPickerDialog.tsx @@ -1,3 +1,4 @@ +import { Stack } from '@linode/ui'; import { Typography } from '@mui/material'; import React from 'react'; import { useState } from 'react'; @@ -6,7 +7,6 @@ import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Avatar } from 'src/components/Avatar/Avatar'; import { ColorPicker } from 'src/components/ColorPicker/ColorPicker'; import { Dialog } from 'src/components/Dialog/Dialog'; -import { Stack } from 'src/components/Stack'; import { useMutatePreferences, usePreferences, diff --git a/packages/manager/src/features/Profile/DisplaySettings/DisplaySettings.tsx b/packages/manager/src/features/Profile/DisplaySettings/DisplaySettings.tsx index e1812a53fc5..f641329cf95 100644 --- a/packages/manager/src/features/Profile/DisplaySettings/DisplaySettings.tsx +++ b/packages/manager/src/features/Profile/DisplaySettings/DisplaySettings.tsx @@ -1,9 +1,7 @@ -import { Paper } from '@linode/ui'; +import { Divider, Paper, Stack } from '@linode/ui'; import { createLazyRoute } from '@tanstack/react-router'; import React from 'react'; -import { Divider } from 'src/components/Divider'; -import { Stack } from 'src/components/Stack'; import { useProfile } from 'src/queries/profile/profile'; import { AvatarForm } from './AvatarForm'; diff --git a/packages/manager/src/features/Profile/DisplaySettings/TimezoneForm.tsx b/packages/manager/src/features/Profile/DisplaySettings/TimezoneForm.tsx index 43c8e8053ea..ebb9d98b901 100644 --- a/packages/manager/src/features/Profile/DisplaySettings/TimezoneForm.tsx +++ b/packages/manager/src/features/Profile/DisplaySettings/TimezoneForm.tsx @@ -1,3 +1,4 @@ +import { Notice } from '@linode/ui'; import { styled } from '@mui/material/styles'; import { DateTime } from 'luxon'; import { useSnackbar } from 'notistack'; @@ -7,7 +8,6 @@ import { Controller, useForm } from 'react-hook-form'; import { timezones } from 'src/assets/timezones/timezones'; import { Autocomplete } from 'src/components/Autocomplete/Autocomplete'; import { Button } from 'src/components/Button/Button'; -import { Notice } from 'src/components/Notice/Notice'; import { useAuthentication } from 'src/hooks/useAuthentication'; import { useMutateProfile, useProfile } from 'src/queries/profile/profile'; diff --git a/packages/manager/src/features/Profile/LishSettings/LishSettings.tsx b/packages/manager/src/features/Profile/LishSettings/LishSettings.tsx index dc6f213bb8e..fb26da9094f 100644 --- a/packages/manager/src/features/Profile/LishSettings/LishSettings.tsx +++ b/packages/manager/src/features/Profile/LishSettings/LishSettings.tsx @@ -1,4 +1,4 @@ -import { Box, FormControl, Paper } from '@linode/ui'; +import { Box, FormControl, Notice, Paper } from '@linode/ui'; import { useTheme } from '@mui/material/styles'; import { createLazyRoute } from '@tanstack/react-router'; import { equals, lensPath, remove, set } from 'ramda'; @@ -8,7 +8,6 @@ import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Autocomplete } from 'src/components/Autocomplete/Autocomplete'; import { Button } from 'src/components/Button/Button'; import { DocumentTitleSegment } from 'src/components/DocumentTitle'; -import { Notice } from 'src/components/Notice/Notice'; import { TextField } from 'src/components/TextField'; import { Typography } from 'src/components/Typography'; import { useMutateProfile, useProfile } from 'src/queries/profile/profile'; diff --git a/packages/manager/src/features/Profile/OAuthClients/CreateOAuthClientDrawer.tsx b/packages/manager/src/features/Profile/OAuthClients/CreateOAuthClientDrawer.tsx index 5b49daef10d..47c80675997 100644 --- a/packages/manager/src/features/Profile/OAuthClients/CreateOAuthClientDrawer.tsx +++ b/packages/manager/src/features/Profile/OAuthClients/CreateOAuthClientDrawer.tsx @@ -1,4 +1,4 @@ -import { FormControl } from '@linode/ui'; +import { FormControl, Notice } from '@linode/ui'; import { useFormik } from 'formik'; import * as React from 'react'; @@ -6,7 +6,6 @@ import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Checkbox } from 'src/components/Checkbox'; import { Drawer } from 'src/components/Drawer'; import { FormControlLabel } from 'src/components/FormControlLabel'; -import { Notice } from 'src/components/Notice/Notice'; import { TextField } from 'src/components/TextField'; import { useCreateOAuthClientMutation } from 'src/queries/account/oauth'; import { getAPIErrorFor } from 'src/utilities/getAPIErrorFor'; diff --git a/packages/manager/src/features/Profile/OAuthClients/EditOAuthClientDrawer.tsx b/packages/manager/src/features/Profile/OAuthClients/EditOAuthClientDrawer.tsx index 4f2d4673e55..aa0d637bdfc 100644 --- a/packages/manager/src/features/Profile/OAuthClients/EditOAuthClientDrawer.tsx +++ b/packages/manager/src/features/Profile/OAuthClients/EditOAuthClientDrawer.tsx @@ -1,4 +1,4 @@ -import { FormControl } from '@linode/ui'; +import { FormControl, Notice } from '@linode/ui'; import { useFormik } from 'formik'; import * as React from 'react'; @@ -6,7 +6,6 @@ import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Checkbox } from 'src/components/Checkbox'; import { Drawer } from 'src/components/Drawer'; import { FormControlLabel } from 'src/components/FormControlLabel'; -import { Notice } from 'src/components/Notice/Notice'; import { TextField } from 'src/components/TextField'; import { useUpdateOAuthClientMutation } from 'src/queries/account/oauth'; import { getAPIErrorFor } from 'src/utilities/getAPIErrorFor'; diff --git a/packages/manager/src/features/Profile/Referrals/Referrals.styles.ts b/packages/manager/src/features/Profile/Referrals/Referrals.styles.ts index cca81a2f77e..68fac0090c6 100644 --- a/packages/manager/src/features/Profile/Referrals/Referrals.styles.ts +++ b/packages/manager/src/features/Profile/Referrals/Referrals.styles.ts @@ -1,7 +1,7 @@ -import Grid from '@mui/material/Unstable_Grid2'; +import { Notice } from '@linode/ui'; import { styled } from '@mui/material/styles'; +import Grid from '@mui/material/Unstable_Grid2'; -import { Notice } from 'src/components/Notice/Notice'; import { Typography } from 'src/components/Typography'; export const StyledResultsWrapper = styled('div', { diff --git a/packages/manager/src/features/Profile/Referrals/Referrals.tsx b/packages/manager/src/features/Profile/Referrals/Referrals.tsx index 6ea34956725..3694d5705ea 100644 --- a/packages/manager/src/features/Profile/Referrals/Referrals.tsx +++ b/packages/manager/src/features/Profile/Referrals/Referrals.tsx @@ -1,4 +1,4 @@ -import { Paper } from '@linode/ui'; +import { Notice, Paper } from '@linode/ui'; import Grid from '@mui/material/Unstable_Grid2'; import { createLazyRoute } from '@tanstack/react-router'; import * as React from 'react'; @@ -10,7 +10,6 @@ import { CircleProgress } from 'src/components/CircleProgress'; import { CopyableTextField } from 'src/components/CopyableTextField/CopyableTextField'; import { DocumentTitleSegment } from 'src/components/DocumentTitle'; import { Link } from 'src/components/Link'; -import { Notice } from 'src/components/Notice/Notice'; import { Typography } from 'src/components/Typography'; import { useProfile } from 'src/queries/profile/profile'; import { getAPIErrorOrDefault } from 'src/utilities/errorUtils'; diff --git a/packages/manager/src/features/Profile/SSHKeys/CreateSSHKeyDrawer.tsx b/packages/manager/src/features/Profile/SSHKeys/CreateSSHKeyDrawer.tsx index b845b8a2039..3236b371132 100644 --- a/packages/manager/src/features/Profile/SSHKeys/CreateSSHKeyDrawer.tsx +++ b/packages/manager/src/features/Profile/SSHKeys/CreateSSHKeyDrawer.tsx @@ -1,3 +1,4 @@ +import { Notice } from '@linode/ui'; import { useFormik } from 'formik'; import { useSnackbar } from 'notistack'; import * as React from 'react'; @@ -6,7 +7,6 @@ import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Code } from 'src/components/Code/Code'; import { Drawer } from 'src/components/Drawer'; import { Link } from 'src/components/Link'; -import { Notice } from 'src/components/Notice/Notice'; import { TextField } from 'src/components/TextField'; import { Typography } from 'src/components/Typography'; import { useCreateSSHKeyMutation } from 'src/queries/profile/profile'; diff --git a/packages/manager/src/features/Profile/SSHKeys/EditSSHKeyDrawer.tsx b/packages/manager/src/features/Profile/SSHKeys/EditSSHKeyDrawer.tsx index 05a0393ecc5..49078d5333d 100644 --- a/packages/manager/src/features/Profile/SSHKeys/EditSSHKeyDrawer.tsx +++ b/packages/manager/src/features/Profile/SSHKeys/EditSSHKeyDrawer.tsx @@ -1,3 +1,4 @@ +import { Notice } from '@linode/ui'; import { useFormik } from 'formik'; import { useSnackbar } from 'notistack'; import * as React from 'react'; @@ -5,7 +6,6 @@ import { useEffect } from 'react'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Drawer } from 'src/components/Drawer'; -import { Notice } from 'src/components/Notice/Notice'; import { TextField } from 'src/components/TextField'; import { useUpdateSSHKeyMutation } from 'src/queries/profile/profile'; import { getAPIErrorFor } from 'src/utilities/getAPIErrorFor'; diff --git a/packages/manager/src/features/Profile/SecretTokenDialog/SecretTokenDialog.tsx b/packages/manager/src/features/Profile/SecretTokenDialog/SecretTokenDialog.tsx index 6bb1e386a0f..8ca79c82a4a 100644 --- a/packages/manager/src/features/Profile/SecretTokenDialog/SecretTokenDialog.tsx +++ b/packages/manager/src/features/Profile/SecretTokenDialog/SecretTokenDialog.tsx @@ -1,11 +1,10 @@ -import { Box } from '@linode/ui'; +import { Box, Notice } from '@linode/ui'; import { styled } from '@mui/material/styles'; import * as React from 'react'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { ConfirmationDialog } from 'src/components/ConfirmationDialog/ConfirmationDialog'; import { CopyableTextField } from 'src/components/CopyableTextField/CopyableTextField'; -import { Notice } from 'src/components/Notice/Notice'; import { CopyAllHostnames } from 'src/features/ObjectStorage/AccessKeyLanding/CopyAllHostnames'; import { HostNamesList } from 'src/features/ObjectStorage/AccessKeyLanding/HostNamesList'; import { useAccountManagement } from 'src/hooks/useAccountManagement'; diff --git a/packages/manager/src/features/Profile/Settings/PreferenceEditor.tsx b/packages/manager/src/features/Profile/Settings/PreferenceEditor.tsx index c5905bb42f2..db175a0d279 100644 --- a/packages/manager/src/features/Profile/Settings/PreferenceEditor.tsx +++ b/packages/manager/src/features/Profile/Settings/PreferenceEditor.tsx @@ -1,10 +1,9 @@ -import { Box } from '@linode/ui'; +import { Box, Notice } from '@linode/ui'; import * as React from 'react'; import { Button } from 'src/components/Button/Button'; import { Dialog } from 'src/components/Dialog/Dialog'; import { Link } from 'src/components/Link'; -import { Notice } from 'src/components/Notice/Notice'; import { Typography } from 'src/components/Typography'; import { useMutatePreferences, diff --git a/packages/manager/src/features/Profile/Settings/Settings.tsx b/packages/manager/src/features/Profile/Settings/Settings.tsx index d8d9097879f..c355262f836 100644 --- a/packages/manager/src/features/Profile/Settings/Settings.tsx +++ b/packages/manager/src/features/Profile/Settings/Settings.tsx @@ -1,4 +1,4 @@ -import { Paper } from '@linode/ui'; +import { Paper, Stack } from '@linode/ui'; import { createLazyRoute } from '@tanstack/react-router'; import * as React from 'react'; import { useHistory, useLocation } from 'react-router-dom'; @@ -8,7 +8,6 @@ import { DocumentTitleSegment } from 'src/components/DocumentTitle'; import { FormControlLabel } from 'src/components/FormControlLabel'; import { Radio } from 'src/components/Radio/Radio'; import { RadioGroup } from 'src/components/RadioGroup'; -import { Stack } from 'src/components/Stack'; import { Toggle } from 'src/components/Toggle/Toggle'; import { Typography } from 'src/components/Typography'; import { diff --git a/packages/manager/src/features/Search/SearchLanding.styles.ts b/packages/manager/src/features/Search/SearchLanding.styles.ts index b8e7fc08930..6603686dd99 100644 --- a/packages/manager/src/features/Search/SearchLanding.styles.ts +++ b/packages/manager/src/features/Search/SearchLanding.styles.ts @@ -1,5 +1,5 @@ import { keyframes } from '@emotion/react'; -import { Stack } from '@mui/material'; +import { Stack } from '@linode/ui'; import { styled } from '@mui/material/styles'; import Grid from '@mui/material/Unstable_Grid2'; diff --git a/packages/manager/src/features/Search/SearchLanding.tsx b/packages/manager/src/features/Search/SearchLanding.tsx index 4ed6f58a824..383c50ffec1 100644 --- a/packages/manager/src/features/Search/SearchLanding.tsx +++ b/packages/manager/src/features/Search/SearchLanding.tsx @@ -1,3 +1,4 @@ +import { Notice } from '@linode/ui'; import Grid from '@mui/material/Unstable_Grid2'; import { createLazyRoute } from '@tanstack/react-router'; import { equals } from 'ramda'; @@ -5,7 +6,6 @@ import * as React from 'react'; import { debounce } from 'throttle-debounce'; import { CircleProgress } from 'src/components/CircleProgress'; -import { Notice } from 'src/components/Notice/Notice'; import { Typography } from 'src/components/Typography'; import { useAPISearch } from 'src/features/Search/useAPISearch'; import { useIsLargeAccount } from 'src/hooks/useIsLargeAccount'; @@ -28,6 +28,7 @@ import { isNilOrEmpty } from 'src/utilities/isNilOrEmpty'; import { isNotNullOrUndefined } from 'src/utilities/nullOrUndefined'; import { getQueryParamFromQueryString } from 'src/utilities/queryParams'; +import { useIsDatabasesEnabled } from '../Databases/utilities'; import { getImageLabelForLinode } from '../Images/utils'; import { ResultGroup } from './ResultGroup'; import './searchLanding.css'; @@ -43,7 +44,6 @@ import withStoreSearch from './withStoreSearch'; import type { SearchProps } from './withStoreSearch'; import type { RouteComponentProps } from 'react-router-dom'; -import { useIsDatabasesEnabled } from '../Databases/utilities'; const displayMap = { buckets: 'Buckets', diff --git a/packages/manager/src/features/StackScripts/SelectStackScriptPanel/SelectStackScriptPanel.tsx b/packages/manager/src/features/StackScripts/SelectStackScriptPanel/SelectStackScriptPanel.tsx index 246c633d453..9d549f97ba3 100644 --- a/packages/manager/src/features/StackScripts/SelectStackScriptPanel/SelectStackScriptPanel.tsx +++ b/packages/manager/src/features/StackScripts/SelectStackScriptPanel/SelectStackScriptPanel.tsx @@ -1,11 +1,10 @@ import { getStackScript } from '@linode/api-v4/lib/stackscripts'; -import { Box } from '@linode/ui'; +import { Box, Notice } from '@linode/ui'; import * as React from 'react'; import { compose } from 'recompose'; import { Button } from 'src/components/Button/Button'; import { CircleProgress } from 'src/components/CircleProgress'; -import { Notice } from 'src/components/Notice/Notice'; import { RenderGuard } from 'src/components/RenderGuard'; import { Typography } from 'src/components/Typography'; import { withProfile } from 'src/containers/profile.container'; diff --git a/packages/manager/src/features/StackScripts/StackScriptBase/StackScriptBase.tsx b/packages/manager/src/features/StackScripts/StackScriptBase/StackScriptBase.tsx index e08a0db4129..a08edd0ce3d 100644 --- a/packages/manager/src/features/StackScripts/StackScriptBase/StackScriptBase.tsx +++ b/packages/manager/src/features/StackScripts/StackScriptBase/StackScriptBase.tsx @@ -1,9 +1,7 @@ -import { Image } from '@linode/api-v4/lib/images'; -import { StackScript } from '@linode/api-v4/lib/stackscripts'; -import { APIError, Filter, ResourcePage } from '@linode/api-v4/lib/types'; +import { Notice } from '@linode/ui'; import { pathOr } from 'ramda'; import * as React from 'react'; -import { RouteComponentProps, withRouter } from 'react-router-dom'; +import { withRouter } from 'react-router-dom'; import { Waypoint } from 'react-waypoint'; import { compose } from 'recompose'; @@ -11,12 +9,7 @@ import StackScriptsIcon from 'src/assets/icons/entityIcons/stackscript.svg'; import { Button } from 'src/components/Button/Button'; import { CircleProgress } from 'src/components/CircleProgress'; import { ErrorState } from 'src/components/ErrorState/ErrorState'; -import { Notice } from 'src/components/Notice/Notice'; -import { - WithProfileProps, - withProfile, -} from 'src/containers/profile.container'; -import { WithQueryClientProps } from 'src/containers/withQueryClient.container'; +import { withProfile } from 'src/containers/profile.container'; import { isLinodeKubeImageId } from 'src/store/image/image.helpers'; import { getAPIErrorOrDefault } from 'src/utilities/errorUtils'; import { getDisplayName } from 'src/utilities/getDisplayName'; @@ -25,11 +18,9 @@ import { getQueryParamFromQueryString } from 'src/utilities/queryParams'; import { StackScriptTableHead } from '../Partials/StackScriptTableHead'; import { - AcceptedFilters, generateCatchAllFilter, generateSpecificFilter, } from '../stackScriptUtils'; -import { StackScriptsRequest } from '../types'; import { StyledContentDiv, StyledDebouncedSearchTextfield, @@ -40,6 +31,15 @@ import { } from './StackScriptBase.styles'; import { StackScriptsEmptyLandingState } from './StackScriptsEmptyLandingPage'; +import type { AcceptedFilters } from '../stackScriptUtils'; +import type { StackScriptsRequest } from '../types'; +import type { Image } from '@linode/api-v4/lib/images'; +import type { StackScript } from '@linode/api-v4/lib/stackscripts'; +import type { APIError, Filter, ResourcePage } from '@linode/api-v4/lib/types'; +import type { RouteComponentProps } from 'react-router-dom'; +import type { WithProfileProps } from 'src/containers/profile.container'; +import type { WithQueryClientProps } from 'src/containers/withQueryClient.container'; + type CurrentFilter = 'deploys' | 'label' | 'revision'; type SortOrder = 'asc' | 'desc'; @@ -102,199 +102,6 @@ const withStackScriptBase = (options: WithStackScriptBaseOptions) => ( const { isSelecting, useQueryString } = options; class EnhancedComponent extends React.Component { - componentDidMount() { - this.mounted = true; - // If the URL contains a QS param called "query" treat it as a filter. - const query = getQueryParamFromQueryString( - this.props.location.search, - 'query' - ); - if (query) { - return this.handleSearch(query); - } - - return this.getDataAtPage(1); - } - - componentWillUnmount() { - this.mounted = false; - } - - render() { - const { - allStackScriptsLoaded, - currentFilterType, - didSearch, - error, - fieldError, - getMoreStackScriptsFailed, - gettingMoreStackScripts, - isSearching, - isSorting, - listOfStackScripts, - sortOrder, - successMessage, - } = this.state; - - const { grants, profile } = this.props; - - const userCannotCreateStackScripts = - Boolean(profile.data?.restricted) && - !grants.data?.global.add_stackscripts; - - if (error) { - return ( -
    - -
    - ); - } - - if (this.state.loading) { - return ( - - - - ); - } - - // Use the query string if the argument has been specified. - const query = useQueryString - ? getQueryParamFromQueryString(this.props.location.search, 'query') - : undefined; - - return ( - - {fieldError && fieldError.reason && ( - - )} - {successMessage && } - {/* - * We only want to show this empty state on the initial GET StackScripts request - * If the user is searching and 0 results come back, we just want to show - * an empty table, rather than showing a message indicating no StackScripts exist - */} - {!didSearch && - listOfStackScripts && - listOfStackScripts.length === 0 ? ( - - {userCannotCreateStackScripts ? ( - - You don’t have any StackScripts to select from. - - ) : ( - - )} - - ) : ( - - - - - - - - - - {/* - * show loading indicator if we're getting more stackscripts - * and if we're not showing the "get more stackscripts" button - */} - {gettingMoreStackScripts && !isSorting && ( -
    - -
    - )} -
    - )} - {/* - * if we're sorting, or if we already loaded all results - * or if we're in the middle of getting more results, don't render - * the lazy load trigger - */} - {!isSorting && !allStackScriptsLoaded && !gettingMoreStackScripts && ( -
    - {/* - * If the lazy-load failed (marked by the catch in getNext), - * show the "Show more StackScripts button - * Otherwise, try to lazy load some more dang stackscripts - */} - {!getMoreStackScriptsFailed ? ( - - {/* - * The reason for this empty div is that there was some wonkiness when - * scrolling to the waypoint with trackpads. For some reason, the Waypoint - * would never be scrolled into view no matter how much you scrolled on the - * trackpad. Especially finicky at zoomed in browser sizes - */} -
    -
    - ) : ( - - )} -
    - )} -
    - ); - } - static displayName = `WithStackScriptBase(${getDisplayName(Component)})`; generateFilterInfo = (value: CurrentFilter): FilterInfo => { @@ -599,6 +406,199 @@ const withStackScriptBase = (options: WithStackScriptBaseOptions) => ( usesKubeImage = (stackScriptImages: string[]) => stackScriptImages.some((imageId) => isLinodeKubeImageId(imageId)); + + componentDidMount() { + this.mounted = true; + // If the URL contains a QS param called "query" treat it as a filter. + const query = getQueryParamFromQueryString( + this.props.location.search, + 'query' + ); + if (query) { + return this.handleSearch(query); + } + + return this.getDataAtPage(1); + } + + componentWillUnmount() { + this.mounted = false; + } + + render() { + const { + allStackScriptsLoaded, + currentFilterType, + didSearch, + error, + fieldError, + getMoreStackScriptsFailed, + gettingMoreStackScripts, + isSearching, + isSorting, + listOfStackScripts, + sortOrder, + successMessage, + } = this.state; + + const { grants, profile } = this.props; + + const userCannotCreateStackScripts = + Boolean(profile.data?.restricted) && + !grants.data?.global.add_stackscripts; + + if (error) { + return ( +
    + +
    + ); + } + + if (this.state.loading) { + return ( + + + + ); + } + + // Use the query string if the argument has been specified. + const query = useQueryString + ? getQueryParamFromQueryString(this.props.location.search, 'query') + : undefined; + + return ( + + {fieldError && fieldError.reason && ( + + )} + {successMessage && } + {/* + * We only want to show this empty state on the initial GET StackScripts request + * If the user is searching and 0 results come back, we just want to show + * an empty table, rather than showing a message indicating no StackScripts exist + */} + {!didSearch && + listOfStackScripts && + listOfStackScripts.length === 0 ? ( + + {userCannotCreateStackScripts ? ( + + You don’t have any StackScripts to select from. + + ) : ( + + )} + + ) : ( + + + + + + + + + + {/* + * show loading indicator if we're getting more stackscripts + * and if we're not showing the "get more stackscripts" button + */} + {gettingMoreStackScripts && !isSorting && ( +
    + +
    + )} +
    + )} + {/* + * if we're sorting, or if we already loaded all results + * or if we're in the middle of getting more results, don't render + * the lazy load trigger + */} + {!isSorting && !allStackScriptsLoaded && !gettingMoreStackScripts && ( +
    + {/* + * If the lazy-load failed (marked by the catch in getNext), + * show the "Show more StackScripts button + * Otherwise, try to lazy load some more dang stackscripts + */} + {!getMoreStackScriptsFailed ? ( + + {/* + * The reason for this empty div is that there was some wonkiness when + * scrolling to the waypoint with trackpads. For some reason, the Waypoint + * would never be scrolled into view no matter how much you scrolled on the + * trackpad. Especially finicky at zoomed in browser sizes + */} +
    +
    + ) : ( + + )} +
    + )} +
    + ); + } } return compose(withRouter, withProfile)(EnhancedComponent); diff --git a/packages/manager/src/features/StackScripts/StackScriptCreate/StackScriptCreate.test.tsx b/packages/manager/src/features/StackScripts/StackScriptCreate/StackScriptCreate.test.tsx index 27e340db290..49012e7b97b 100644 --- a/packages/manager/src/features/StackScripts/StackScriptCreate/StackScriptCreate.test.tsx +++ b/packages/manager/src/features/StackScripts/StackScriptCreate/StackScriptCreate.test.tsx @@ -3,7 +3,7 @@ import * as React from 'react'; import { reactRouterProps } from 'src/__data__/reactRouterProps'; import { profileFactory } from 'src/factories'; import { queryClientFactory } from 'src/queries/base'; -import { renderWithTheme } from 'src/utilities/testHelpers'; +import { renderWithThemeAndHookFormContext } from 'src/utilities/testHelpers'; import { StackScriptCreate } from './StackScriptCreate'; @@ -15,21 +15,22 @@ const queryClient = queryClientFactory(); describe('StackScriptCreate', () => { it('should render header, inputs, and buttons', () => { - const { getByLabelText, getByText } = renderWithTheme( - - } - grants={{ data: {} } as UseQueryResult} - mode="create" - queryClient={queryClient} - />, - { queryClient } - ); + const { getByLabelText, getByText } = renderWithThemeAndHookFormContext({ + component: ( + + } + grants={{ data: {} } as UseQueryResult} + mode="create" + queryClient={queryClient} + /> + ), + }); expect(getByText('Create')).toBeVisible(); diff --git a/packages/manager/src/features/StackScripts/StackScriptCreate/StackScriptCreate.tsx b/packages/manager/src/features/StackScripts/StackScriptCreate/StackScriptCreate.tsx index 0d232b42e56..039c4ce1a67 100644 --- a/packages/manager/src/features/StackScripts/StackScriptCreate/StackScriptCreate.tsx +++ b/packages/manager/src/features/StackScripts/StackScriptCreate/StackScriptCreate.tsx @@ -3,6 +3,7 @@ import { getStackScript, updateStackScript, } from '@linode/api-v4/lib/stackscripts'; +import { Notice } from '@linode/ui'; import { equals } from 'ramda'; import * as React from 'react'; import { withRouter } from 'react-router-dom'; @@ -15,7 +16,6 @@ import { ConfirmationDialog } from 'src/components/ConfirmationDialog/Confirmati import { DocumentTitleSegment } from 'src/components/DocumentTitle'; import { ErrorState } from 'src/components/ErrorState/ErrorState'; import { LandingHeader } from 'src/components/LandingHeader'; -import { Notice } from 'src/components/Notice/Notice'; import { Typography } from 'src/components/Typography'; import { withProfile } from 'src/containers/profile.container'; import { withQueryClient } from 'src/containers/withQueryClient.container'; diff --git a/packages/manager/src/features/StackScripts/StackScriptForm/StackScriptForm.styles.ts b/packages/manager/src/features/StackScripts/StackScriptForm/StackScriptForm.styles.ts index 296fda0b312..a004081854d 100644 --- a/packages/manager/src/features/StackScripts/StackScriptForm/StackScriptForm.styles.ts +++ b/packages/manager/src/features/StackScripts/StackScriptForm/StackScriptForm.styles.ts @@ -1,8 +1,8 @@ -import Grid from '@mui/material/Unstable_Grid2'; +import { Notice } from '@linode/ui'; import { styled } from '@mui/material/styles'; +import Grid from '@mui/material/Unstable_Grid2'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; -import { Notice } from 'src/components/Notice/Notice'; import { TextField } from 'src/components/TextField'; export const StyledActionsPanel = styled(ActionsPanel, { diff --git a/packages/manager/src/features/StackScripts/StackScriptForm/StackScriptForm.test.tsx b/packages/manager/src/features/StackScripts/StackScriptForm/StackScriptForm.test.tsx index 8b91134e9fd..b4be7d1e3eb 100644 --- a/packages/manager/src/features/StackScripts/StackScriptForm/StackScriptForm.test.tsx +++ b/packages/manager/src/features/StackScripts/StackScriptForm/StackScriptForm.test.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; -import { renderWithTheme } from 'src/utilities/testHelpers'; +import { renderWithThemeAndHookFormContext } from 'src/utilities/testHelpers'; import { StackScriptForm } from './StackScriptForm'; @@ -34,7 +34,9 @@ const props = { describe('StackScriptCreate', () => { it('should render', () => { - const { getByText } = renderWithTheme(); + const { getByText } = renderWithThemeAndHookFormContext({ + component: , + }); getByText(/stackscript label/i); }); }); diff --git a/packages/manager/src/features/StackScripts/StackScriptsLanding.tsx b/packages/manager/src/features/StackScripts/StackScriptsLanding.tsx index 1101d6b33c1..6b749ec1a29 100644 --- a/packages/manager/src/features/StackScripts/StackScriptsLanding.tsx +++ b/packages/manager/src/features/StackScripts/StackScriptsLanding.tsx @@ -1,3 +1,4 @@ +import { Notice } from '@linode/ui'; import Grid from '@mui/material/Unstable_Grid2'; import { createLazyRoute } from '@tanstack/react-router'; import * as React from 'react'; @@ -6,7 +7,6 @@ import { useHistory } from 'react-router-dom'; import { CircleProgress } from 'src/components/CircleProgress'; import { DocumentTitleSegment } from 'src/components/DocumentTitle'; import { LandingHeader } from 'src/components/LandingHeader'; -import { Notice } from 'src/components/Notice/Notice'; import { listToItemsByID } from 'src/queries/base'; import { useAllImagesQuery } from 'src/queries/images'; diff --git a/packages/manager/src/features/StackScripts/UserDefinedFieldsPanel/FieldTypes/UserDefinedMultiSelect.tsx b/packages/manager/src/features/StackScripts/UserDefinedFieldsPanel/FieldTypes/UserDefinedMultiSelect.tsx index 64d230bbc87..03263e8bc3e 100644 --- a/packages/manager/src/features/StackScripts/UserDefinedFieldsPanel/FieldTypes/UserDefinedMultiSelect.tsx +++ b/packages/manager/src/features/StackScripts/UserDefinedFieldsPanel/FieldTypes/UserDefinedMultiSelect.tsx @@ -1,7 +1,7 @@ +import { Notice } from '@linode/ui'; import * as React from 'react'; import { Autocomplete } from 'src/components/Autocomplete/Autocomplete'; -import { Notice } from 'src/components/Notice/Notice'; import { RenderGuard } from 'src/components/RenderGuard'; import type { UserDefinedField } from '@linode/api-v4/lib/stackscripts'; diff --git a/packages/manager/src/features/StackScripts/UserDefinedFieldsPanel/FieldTypes/UserDefinedSelect.tsx b/packages/manager/src/features/StackScripts/UserDefinedFieldsPanel/FieldTypes/UserDefinedSelect.tsx index 2d911c2ae12..b96c0aa0eb8 100644 --- a/packages/manager/src/features/StackScripts/UserDefinedFieldsPanel/FieldTypes/UserDefinedSelect.tsx +++ b/packages/manager/src/features/StackScripts/UserDefinedFieldsPanel/FieldTypes/UserDefinedSelect.tsx @@ -1,10 +1,9 @@ -import { InputLabel } from '@linode/ui'; +import { InputLabel, Notice } from '@linode/ui'; import { styled } from '@mui/material/styles'; import * as React from 'react'; import { Autocomplete } from 'src/components/Autocomplete/Autocomplete'; import { FormControlLabel } from 'src/components/FormControlLabel'; -import { Notice } from 'src/components/Notice/Notice'; import { Radio } from 'src/components/Radio/Radio'; import type { UserDefinedField } from '@linode/api-v4/lib/stackscripts'; diff --git a/packages/manager/src/features/StackScripts/UserDefinedFieldsPanel/UserDefinedFieldsPanel.tsx b/packages/manager/src/features/StackScripts/UserDefinedFieldsPanel/UserDefinedFieldsPanel.tsx index a87a4e5a2e7..b14d90c0097 100644 --- a/packages/manager/src/features/StackScripts/UserDefinedFieldsPanel/UserDefinedFieldsPanel.tsx +++ b/packages/manager/src/features/StackScripts/UserDefinedFieldsPanel/UserDefinedFieldsPanel.tsx @@ -1,10 +1,8 @@ -import { Box } from '@linode/ui'; +import { Box, Divider, Notice } from '@linode/ui'; import Grid from '@mui/material/Unstable_Grid2'; import * as React from 'react'; import { Link } from 'react-router-dom'; -import { Divider } from 'src/components/Divider'; -import { Notice } from 'src/components/Notice/Notice'; import { RenderGuard } from 'src/components/RenderGuard'; import { ShowMoreExpansion } from 'src/components/ShowMoreExpansion'; import { Typography } from 'src/components/Typography'; diff --git a/packages/manager/src/features/Support/Hively.tsx b/packages/manager/src/features/Support/Hively.tsx index 9c146e8649a..440e5d2dd0f 100644 --- a/packages/manager/src/features/Support/Hively.tsx +++ b/packages/manager/src/features/Support/Hively.tsx @@ -1,10 +1,8 @@ -import { Box } from '@linode/ui'; +import { Box, Divider, Stack } from '@linode/ui'; import { DateTime } from 'luxon'; import * as React from 'react'; -import { Divider } from 'src/components/Divider'; import { Link } from 'src/components/Link'; -import { Stack } from 'src/components/Stack'; import { Typography } from 'src/components/Typography'; import { parseAPIDate } from 'src/utilities/date'; diff --git a/packages/manager/src/features/Support/SupportTicketDetail/AttachmentError.tsx b/packages/manager/src/features/Support/SupportTicketDetail/AttachmentError.tsx index b6382a79daa..c709707ee13 100644 --- a/packages/manager/src/features/Support/SupportTicketDetail/AttachmentError.tsx +++ b/packages/manager/src/features/Support/SupportTicketDetail/AttachmentError.tsx @@ -1,7 +1,6 @@ +import { Notice } from '@linode/ui'; import * as React from 'react'; -import { Notice } from 'src/components/Notice/Notice'; - interface Props { fileName: string; reason: string; diff --git a/packages/manager/src/features/Support/SupportTicketDetail/SupportTicketDetail.tsx b/packages/manager/src/features/Support/SupportTicketDetail/SupportTicketDetail.tsx index be966b504cc..b1902189e0c 100644 --- a/packages/manager/src/features/Support/SupportTicketDetail/SupportTicketDetail.tsx +++ b/packages/manager/src/features/Support/SupportTicketDetail/SupportTicketDetail.tsx @@ -1,3 +1,4 @@ +import { Stack } from '@linode/ui'; import { styled } from '@mui/material/styles'; import Grid from '@mui/material/Unstable_Grid2'; import { createLazyRoute } from '@tanstack/react-router'; @@ -10,7 +11,6 @@ import { CircleProgress } from 'src/components/CircleProgress'; import { DocumentTitleSegment } from 'src/components/DocumentTitle'; import { ErrorState } from 'src/components/ErrorState/ErrorState'; import { LandingHeader } from 'src/components/LandingHeader'; -import { Stack } from 'src/components/Stack'; import { useProfile } from 'src/queries/profile/profile'; import { useInfiniteSupportTicketRepliesQuery, diff --git a/packages/manager/src/features/Support/SupportTicketDetail/TabbedReply/MarkdownReference.tsx b/packages/manager/src/features/Support/SupportTicketDetail/TabbedReply/MarkdownReference.tsx index 51c289edd7e..778e155250a 100644 --- a/packages/manager/src/features/Support/SupportTicketDetail/TabbedReply/MarkdownReference.tsx +++ b/packages/manager/src/features/Support/SupportTicketDetail/TabbedReply/MarkdownReference.tsx @@ -1,9 +1,8 @@ -import { Paper } from '@linode/ui'; +import { Paper, Stack } from '@linode/ui'; import * as React from 'react'; import { HighlightedMarkdown } from 'src/components/HighlightedMarkdown/HighlightedMarkdown'; import { Link } from 'src/components/Link'; -import { Stack } from 'src/components/Stack'; import { Typography } from 'src/components/Typography'; interface Props { diff --git a/packages/manager/src/features/Support/SupportTicketDetail/TabbedReply/ReplyContainer.tsx b/packages/manager/src/features/Support/SupportTicketDetail/TabbedReply/ReplyContainer.tsx index 383ed47eeb4..1fcdedd4ef5 100644 --- a/packages/manager/src/features/Support/SupportTicketDetail/TabbedReply/ReplyContainer.tsx +++ b/packages/manager/src/features/Support/SupportTicketDetail/TabbedReply/ReplyContainer.tsx @@ -1,4 +1,5 @@ import { uploadAttachment } from '@linode/api-v4'; +import { Notice } from '@linode/ui'; import Grid from '@mui/material/Unstable_Grid2'; import { lensPath, set } from 'ramda'; import * as React from 'react'; @@ -6,7 +7,6 @@ import { debounce } from 'throttle-debounce'; import { makeStyles } from 'tss-react/mui'; import { Accordion } from 'src/components/Accordion'; -import { Notice } from 'src/components/Notice/Notice'; import { useSupportTicketReplyMutation } from 'src/queries/support'; import { getAPIErrorOrDefault, getErrorMap } from 'src/utilities/errorUtils'; import { storage } from 'src/utilities/storage'; diff --git a/packages/manager/src/features/Support/SupportTicketDetail/TicketStatus.tsx b/packages/manager/src/features/Support/SupportTicketDetail/TicketStatus.tsx index e056efd29d6..f5a15031b24 100644 --- a/packages/manager/src/features/Support/SupportTicketDetail/TicketStatus.tsx +++ b/packages/manager/src/features/Support/SupportTicketDetail/TicketStatus.tsx @@ -1,11 +1,10 @@ -import { Paper } from '@linode/ui'; +import { Paper, Stack } from '@linode/ui'; import { styled } from '@mui/material/styles'; import Grid from '@mui/material/Unstable_Grid2'; import React from 'react'; import { Hidden } from 'src/components/Hidden'; import { Link } from 'src/components/Link'; -import { Stack } from 'src/components/Stack'; import { StatusIcon } from 'src/components/StatusIcon/StatusIcon'; import { Typography } from 'src/components/Typography'; import { useProfile } from 'src/queries/profile/profile'; diff --git a/packages/manager/src/features/Support/SupportTickets/SupportTicketDialog.tsx b/packages/manager/src/features/Support/SupportTickets/SupportTicketDialog.tsx index 066ac25045c..d009c0e262f 100644 --- a/packages/manager/src/features/Support/SupportTickets/SupportTicketDialog.tsx +++ b/packages/manager/src/features/Support/SupportTickets/SupportTicketDialog.tsx @@ -1,6 +1,6 @@ import { yupResolver } from '@hookform/resolvers/yup'; import { uploadAttachment } from '@linode/api-v4/lib/support'; -import { Box } from '@linode/ui'; +import { Box, Notice } from '@linode/ui'; import { update } from 'ramda'; import * as React from 'react'; import { Controller, FormProvider, useForm } from 'react-hook-form'; @@ -11,7 +11,6 @@ import { Accordion } from 'src/components/Accordion'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Autocomplete } from 'src/components/Autocomplete/Autocomplete'; import { Dialog } from 'src/components/Dialog/Dialog'; -import { Notice } from 'src/components/Notice/Notice'; import { TextField } from 'src/components/TextField'; import { Typography } from 'src/components/Typography'; import { useCreateSupportTicketMutation } from 'src/queries/support'; @@ -57,6 +56,7 @@ interface AttachmentWithTarget { } export type EntityType = + | 'bucket' | 'database_id' | 'domain_id' | 'firewall_id' @@ -344,12 +344,28 @@ export const SupportTicketDialog = (props: SupportTicketDialogProps) => { } setSubmitting(true); - createSupportTicket({ - [_entityType]: Number(_entityId), + const baseRequestPayload = { description: _description, severity: selectedSeverity, summary, - }) + }; + + let requestPayload; + if (entityType === 'bucket') { + const bucket_label = values.entityInputValue; + requestPayload = { + bucket: bucket_label, + region: _entityId, + ...baseRequestPayload, + }; + } else { + requestPayload = { + [_entityType]: Number(_entityId), + ...baseRequestPayload, + }; + } + + createSupportTicket(requestPayload) .then((response) => { return response; }) diff --git a/packages/manager/src/features/Support/SupportTickets/SupportTicketProductSelectionFields.tsx b/packages/manager/src/features/Support/SupportTickets/SupportTicketProductSelectionFields.tsx index 65f55f44187..d834f55fb2d 100644 --- a/packages/manager/src/features/Support/SupportTickets/SupportTicketProductSelectionFields.tsx +++ b/packages/manager/src/features/Support/SupportTickets/SupportTicketProductSelectionFields.tsx @@ -10,6 +10,7 @@ import { useAllFirewallsQuery } from 'src/queries/firewalls'; import { useAllKubernetesClustersQuery } from 'src/queries/kubernetes'; import { useAllLinodesQuery } from 'src/queries/linodes/linodes'; import { useAllNodeBalancersQuery } from 'src/queries/nodebalancers'; +import { useObjectStorageBuckets } from 'src/queries/object-storage/queries'; import { useAllVolumesQuery } from 'src/queries/volumes/volumes'; import { useAllVPCsQuery } from 'src/queries/vpcs/vpcs'; @@ -81,6 +82,12 @@ export const SupportTicketProductSelectionFields = (props: Props) => { isLoading: linodesLoading, } = useAllLinodesQuery({}, {}, entityType === 'linode_id'); + const { + data: buckets, + error: bucketsError, + isLoading: bucketsLoading, + } = useObjectStorageBuckets(entityType === 'bucket'); + const { data: volumes, error: volumesError, @@ -93,8 +100,9 @@ export const SupportTicketProductSelectionFields = (props: Props) => { isLoading: vpcsLoading, } = useAllVPCsQuery(entityType === 'vpc_id'); - const getEntityOptions = (): { label: string; value: number }[] => { + const getEntityOptions = (): { label: string; value: number | string }[] => { const reactQueryEntityDataMap = { + bucket: buckets, database_id: databases, domain_id: domains, firewall_id: firewalls, @@ -123,6 +131,17 @@ export const SupportTicketProductSelectionFields = (props: Props) => { ); } + if (entityType === 'bucket') { + return ( + reactQueryEntityDataMap['bucket']?.buckets?.map( + ({ label, region }) => ({ + label, + value: region ?? '', + }) + ) || [] + ); + } + return ( reactQueryEntityDataMap[entityType]?.map( ({ id, label }: { id: number; label: string }) => ({ @@ -134,6 +153,7 @@ export const SupportTicketProductSelectionFields = (props: Props) => { }; const loadingMap: Record = { + bucket: bucketsLoading, database_id: databasesLoading, domain_id: domainsLoading, firewall_id: firewallsLoading, @@ -147,6 +167,7 @@ export const SupportTicketProductSelectionFields = (props: Props) => { }; const errorMap: Record = { + bucket: bucketsError, database_id: databasesError, domain_id: domainsError, firewall_id: firewallsError, diff --git a/packages/manager/src/features/Support/SupportTickets/constants.tsx b/packages/manager/src/features/Support/SupportTickets/constants.tsx index 9e1134a0f02..9637bf42c73 100644 --- a/packages/manager/src/features/Support/SupportTickets/constants.tsx +++ b/packages/manager/src/features/Support/SupportTickets/constants.tsx @@ -69,11 +69,13 @@ export const ENTITY_MAP: Record = { Kubernetes: 'lkecluster_id', Linodes: 'linode_id', NodeBalancers: 'nodebalancer_id', + 'Object Storage': 'bucket', VPCs: 'vpc_id', Volumes: 'volume_id', }; export const ENTITY_ID_TO_NAME_MAP: Record = { + bucket: 'Bucket', database_id: 'Database Cluster', domain_id: 'Domain', firewall_id: 'Firewall', diff --git a/packages/manager/src/features/Support/TicketAttachmentRow.tsx b/packages/manager/src/features/Support/TicketAttachmentRow.tsx index eb978e15480..f418f016a20 100644 --- a/packages/manager/src/features/Support/TicketAttachmentRow.tsx +++ b/packages/manager/src/features/Support/TicketAttachmentRow.tsx @@ -1,8 +1,6 @@ -import { Box, Paper } from '@linode/ui'; +import { Box, Divider, Paper, Stack } from '@linode/ui'; import * as React from 'react'; -import { Divider } from 'src/components/Divider'; -import { Stack } from 'src/components/Stack'; import { Typography } from 'src/components/Typography'; interface Props { diff --git a/packages/manager/src/features/TopMenu/NotificationMenu/NotificationMenu.tsx b/packages/manager/src/features/TopMenu/NotificationMenu/NotificationMenu.tsx index 195bc0d7b65..063ca7d533c 100644 --- a/packages/manager/src/features/TopMenu/NotificationMenu/NotificationMenu.tsx +++ b/packages/manager/src/features/TopMenu/NotificationMenu/NotificationMenu.tsx @@ -1,4 +1,4 @@ -import { Box } from '@linode/ui'; +import { Box, Divider } from '@linode/ui'; import AutorenewIcon from '@mui/icons-material/Autorenew'; import { IconButton } from '@mui/material'; import Popover from '@mui/material/Popover'; @@ -8,7 +8,6 @@ import { useHistory } from 'react-router-dom'; import Bell from 'src/assets/icons/notification.svg'; import { Chip } from 'src/components/Chip'; -import { Divider } from 'src/components/Divider'; import { LinkButton } from 'src/components/LinkButton'; import { Typography } from 'src/components/Typography'; import { NotificationCenterEvent } from 'src/features/NotificationCenter/Events/NotificationCenterEvent'; diff --git a/packages/manager/src/features/TopMenu/UserMenu/UserMenu.tsx b/packages/manager/src/features/TopMenu/UserMenu/UserMenu.tsx index 6ea3b004c25..7ad661fdc8e 100644 --- a/packages/manager/src/features/TopMenu/UserMenu/UserMenu.tsx +++ b/packages/manager/src/features/TopMenu/UserMenu/UserMenu.tsx @@ -1,4 +1,4 @@ -import { Box, Tooltip } from '@linode/ui'; +import { Box, Divider, Stack, Tooltip } from '@linode/ui'; import KeyboardArrowDown from '@mui/icons-material/KeyboardArrowDown'; import KeyboardArrowUp from '@mui/icons-material/KeyboardArrowUp'; import { styled, useMediaQuery } from '@mui/material'; @@ -10,10 +10,8 @@ import * as React from 'react'; import { Avatar } from 'src/components/Avatar/Avatar'; import { AvatarForProxy } from 'src/components/AvatarForProxy'; import { Button } from 'src/components/Button/Button'; -import { Divider } from 'src/components/Divider'; import { Hidden } from 'src/components/Hidden'; import { Link } from 'src/components/Link'; -import { Stack } from 'src/components/Stack'; import { Typography } from 'src/components/Typography'; import { switchAccountSessionContext } from 'src/context/switchAccountSessionContext'; import { SwitchAccountButton } from 'src/features/Account/SwitchAccountButton'; diff --git a/packages/manager/src/features/Users/CreateUserDrawer.tsx b/packages/manager/src/features/Users/CreateUserDrawer.tsx index a41ce5521a2..b704b22da5e 100644 --- a/packages/manager/src/features/Users/CreateUserDrawer.tsx +++ b/packages/manager/src/features/Users/CreateUserDrawer.tsx @@ -1,17 +1,20 @@ -import { User, createUser } from '@linode/api-v4/lib/account'; -import { APIError } from '@linode/api-v4/lib/types'; +import { createUser } from '@linode/api-v4/lib/account'; +import { Notice } from '@linode/ui'; import * as React from 'react'; -import { RouteComponentProps, withRouter } from 'react-router-dom'; +import { withRouter } from 'react-router-dom'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Drawer } from 'src/components/Drawer'; import { FormControlLabel } from 'src/components/FormControlLabel'; -import { Notice } from 'src/components/Notice/Notice'; import { TextField } from 'src/components/TextField'; import { Toggle } from 'src/components/Toggle/Toggle'; import { getAPIErrorOrDefault } from 'src/utilities/errorUtils'; import { getAPIErrorFor } from 'src/utilities/getAPIErrorFor'; +import type { User } from '@linode/api-v4/lib/account'; +import type { APIError } from '@linode/api-v4/lib/types'; +import type { RouteComponentProps } from 'react-router-dom'; + interface Props { onClose: () => void; open: boolean; @@ -29,6 +32,64 @@ interface State { interface CreateUserDrawerProps extends Props, RouteComponentProps<{}> {} class CreateUserDrawer extends React.Component { + handleChangeEmail = (e: React.ChangeEvent) => { + this.setState({ + email: e.target.value, + }); + }; + + handleChangeRestricted = () => { + this.setState({ + restricted: !this.state.restricted, + }); + }; + + handleChangeUsername = ( + e: + | React.ChangeEvent + | React.FocusEvent + ) => { + this.setState({ + username: e.target.value, + }); + }; + + onSubmit = () => { + const { + history: { push }, + onClose, + refetch, + } = this.props; + const { email, restricted, username } = this.state; + this.setState({ errors: [], submitting: true }); + createUser({ email, restricted, username }) + .then((user: User) => { + this.setState({ submitting: false }); + onClose(); + if (user.restricted) { + push(`/account/users/${username}/permissions`, { + newUsername: user.username, + }); + } + refetch(); + }) + .catch((errResponse) => { + const errors = getAPIErrorOrDefault( + errResponse, + 'Error creating user.' + ); + this.setState({ errors, submitting: false }); + }); + }; + + state: State = { + email: '', + errors: [], + restricted: false, + submitting: false, + username: '', + }; + componentDidUpdate(prevProps: CreateUserDrawerProps) { if (this.props.open === true && prevProps.open === false) { this.setState({ @@ -113,64 +174,6 @@ class CreateUserDrawer extends React.Component { ); } - - handleChangeEmail = (e: React.ChangeEvent) => { - this.setState({ - email: e.target.value, - }); - }; - - handleChangeRestricted = () => { - this.setState({ - restricted: !this.state.restricted, - }); - }; - - handleChangeUsername = ( - e: - | React.ChangeEvent - | React.FocusEvent - ) => { - this.setState({ - username: e.target.value, - }); - }; - - onSubmit = () => { - const { - history: { push }, - onClose, - refetch, - } = this.props; - const { email, restricted, username } = this.state; - this.setState({ errors: [], submitting: true }); - createUser({ email, restricted, username }) - .then((user: User) => { - this.setState({ submitting: false }); - onClose(); - if (user.restricted) { - push(`/account/users/${username}/permissions`, { - newUsername: user.username, - }); - } - refetch(); - }) - .catch((errResponse) => { - const errors = getAPIErrorOrDefault( - errResponse, - 'Error creating user.' - ); - this.setState({ errors, submitting: false }); - }); - }; - - state: State = { - email: '', - errors: [], - restricted: false, - submitting: false, - username: '', - }; } export default withRouter(CreateUserDrawer); diff --git a/packages/manager/src/features/Users/UserPermissions.tsx b/packages/manager/src/features/Users/UserPermissions.tsx index 8bad43671f2..4bc2481f265 100644 --- a/packages/manager/src/features/Users/UserPermissions.tsx +++ b/packages/manager/src/features/Users/UserPermissions.tsx @@ -4,7 +4,7 @@ import { updateGrants, updateUser, } from '@linode/api-v4/lib/account'; -import { Box } from '@linode/ui'; +import { Box, Notice } from '@linode/ui'; import { Paper } from '@mui/material'; import Grid from '@mui/material/Unstable_Grid2'; import { enqueueSnackbar } from 'notistack'; @@ -15,7 +15,6 @@ import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { CircleProgress } from 'src/components/CircleProgress'; import { DocumentTitleSegment } from 'src/components/DocumentTitle'; import { FormControlLabel } from 'src/components/FormControlLabel'; -import { Notice } from 'src/components/Notice/Notice'; import { SelectionCard } from 'src/components/SelectionCard/SelectionCard'; import { SafeTabPanel } from 'src/components/Tabs/SafeTabPanel'; import { Tab } from 'src/components/Tabs/Tab'; diff --git a/packages/manager/src/features/Users/UserProfile/DeleteUserPanel.tsx b/packages/manager/src/features/Users/UserProfile/DeleteUserPanel.tsx index 4d941453204..ce7c366f6f2 100644 --- a/packages/manager/src/features/Users/UserProfile/DeleteUserPanel.tsx +++ b/packages/manager/src/features/Users/UserProfile/DeleteUserPanel.tsx @@ -1,9 +1,8 @@ -import { Box, Paper } from '@linode/ui'; +import { Box, Paper, Stack } from '@linode/ui'; import React, { useState } from 'react'; import { useHistory } from 'react-router-dom'; import { Button } from 'src/components/Button/Button'; -import { Stack } from 'src/components/Stack'; import { Typography } from 'src/components/Typography'; import { PARENT_USER } from 'src/features/Account/constants'; import { useProfile } from 'src/queries/profile/profile'; diff --git a/packages/manager/src/features/Users/UserProfile/UserDetailsPanel.tsx b/packages/manager/src/features/Users/UserProfile/UserDetailsPanel.tsx index 9236aaa831f..a559e7f07cb 100644 --- a/packages/manager/src/features/Users/UserProfile/UserDetailsPanel.tsx +++ b/packages/manager/src/features/Users/UserProfile/UserDetailsPanel.tsx @@ -1,10 +1,9 @@ -import { Paper } from '@linode/ui'; +import { Paper, Stack } from '@linode/ui'; import Grid from '@mui/material/Unstable_Grid2'; import React from 'react'; import { DateTimeDisplay } from 'src/components/DateTimeDisplay'; import { MaskableText } from 'src/components/MaskableText/MaskableText'; -import { Stack } from 'src/components/Stack'; import { StatusIcon } from 'src/components/StatusIcon/StatusIcon'; import { TextTooltip } from 'src/components/TextTooltip'; import { Typography } from 'src/components/Typography'; diff --git a/packages/manager/src/features/Users/UserProfile/UserProfile.tsx b/packages/manager/src/features/Users/UserProfile/UserProfile.tsx index d535ed50dcf..a422515620f 100644 --- a/packages/manager/src/features/Users/UserProfile/UserProfile.tsx +++ b/packages/manager/src/features/Users/UserProfile/UserProfile.tsx @@ -1,3 +1,4 @@ +import { Stack } from '@linode/ui'; import React from 'react'; import { useParams } from 'react-router-dom'; @@ -5,7 +6,6 @@ import { CircleProgress } from 'src/components/CircleProgress'; import { DocumentTitleSegment } from 'src/components/DocumentTitle'; import { ErrorState } from 'src/components/ErrorState/ErrorState'; import { NotFound } from 'src/components/NotFound'; -import { Stack } from 'src/components/Stack'; import { useAccountUser } from 'src/queries/account/users'; import { DeleteUserPanel } from './DeleteUserPanel'; diff --git a/packages/manager/src/features/Users/UserRow.tsx b/packages/manager/src/features/Users/UserRow.tsx index e49877489e9..e34eebd8ad0 100644 --- a/packages/manager/src/features/Users/UserRow.tsx +++ b/packages/manager/src/features/Users/UserRow.tsx @@ -1,4 +1,4 @@ -import { Box } from '@linode/ui'; +import { Box, Stack } from '@linode/ui'; import { useTheme } from '@mui/material/styles'; import React from 'react'; @@ -7,7 +7,6 @@ import { Chip } from 'src/components/Chip'; import { DateTimeDisplay } from 'src/components/DateTimeDisplay'; import { Hidden } from 'src/components/Hidden'; import { MaskableText } from 'src/components/MaskableText/MaskableText'; -import { Stack } from 'src/components/Stack'; import { StatusIcon } from 'src/components/StatusIcon/StatusIcon'; import { TableCell } from 'src/components/TableCell'; import { TableRow } from 'src/components/TableRow'; diff --git a/packages/manager/src/features/VPCs/VPCCreate/FormComponents/CannotCreateVPCNotice.tsx b/packages/manager/src/features/VPCs/VPCCreate/FormComponents/CannotCreateVPCNotice.tsx index 66f379fc05c..53220e98caa 100644 --- a/packages/manager/src/features/VPCs/VPCCreate/FormComponents/CannotCreateVPCNotice.tsx +++ b/packages/manager/src/features/VPCs/VPCCreate/FormComponents/CannotCreateVPCNotice.tsx @@ -1,7 +1,6 @@ +import { Notice } from '@linode/ui'; import * as React from 'react'; -import { Notice } from 'src/components/Notice/Notice'; - import { CANNOT_CREATE_VPC_MESSAGE } from '../../constants'; export const CannotCreateVPCNotice = ( diff --git a/packages/manager/src/features/VPCs/VPCCreate/FormComponents/SubnetContent.tsx b/packages/manager/src/features/VPCs/VPCCreate/FormComponents/SubnetContent.tsx index 313ac63afe1..0e514bec10c 100644 --- a/packages/manager/src/features/VPCs/VPCCreate/FormComponents/SubnetContent.tsx +++ b/packages/manager/src/features/VPCs/VPCCreate/FormComponents/SubnetContent.tsx @@ -1,8 +1,8 @@ +import { Notice } from '@linode/ui'; import * as React from 'react'; import { useLocation } from 'react-router-dom'; import { Link } from 'src/components/Link'; -import { Notice } from 'src/components/Notice/Notice'; import { sendLinodeCreateFormInputEvent } from 'src/utilities/analytics/formEventAnalytics'; import { getQueryParamsFromQueryString } from 'src/utilities/queryParams'; diff --git a/packages/manager/src/features/VPCs/VPCCreate/MultipleSubnetInput.tsx b/packages/manager/src/features/VPCs/VPCCreate/MultipleSubnetInput.tsx index 7c5dc9d88e5..1a4bcf8fcc3 100644 --- a/packages/manager/src/features/VPCs/VPCCreate/MultipleSubnetInput.tsx +++ b/packages/manager/src/features/VPCs/VPCCreate/MultipleSubnetInput.tsx @@ -1,8 +1,8 @@ +import { Divider } from '@linode/ui'; import Grid from '@mui/material/Unstable_Grid2'; import * as React from 'react'; import { Button } from 'src/components/Button/Button'; -import { Divider } from 'src/components/Divider'; import { DEFAULT_SUBNET_IPV4_VALUE, getRecommendedSubnetIPv4, diff --git a/packages/manager/src/features/VPCs/VPCCreate/SubnetNode.tsx b/packages/manager/src/features/VPCs/VPCCreate/SubnetNode.tsx index b47d5fa1b12..3bf621de650 100644 --- a/packages/manager/src/features/VPCs/VPCCreate/SubnetNode.tsx +++ b/packages/manager/src/features/VPCs/VPCCreate/SubnetNode.tsx @@ -1,6 +1,5 @@ -import { FormHelperText } from '@linode/ui'; +import { FormHelperText, Stack } from '@linode/ui'; import Close from '@mui/icons-material/Close'; -import Stack from '@mui/material/Stack'; import { styled } from '@mui/material/styles'; import Grid from '@mui/material/Unstable_Grid2'; import * as React from 'react'; diff --git a/packages/manager/src/features/VPCs/VPCCreate/VPCCreate.tsx b/packages/manager/src/features/VPCs/VPCCreate/VPCCreate.tsx index 8995ec53601..161425ee5c4 100644 --- a/packages/manager/src/features/VPCs/VPCCreate/VPCCreate.tsx +++ b/packages/manager/src/features/VPCs/VPCCreate/VPCCreate.tsx @@ -1,4 +1,4 @@ -import { Paper } from '@linode/ui'; +import { Notice, Paper } from '@linode/ui'; import { styled } from '@mui/material/styles'; import Grid from '@mui/material/Unstable_Grid2'; import { createLazyRoute } from '@tanstack/react-router'; @@ -7,7 +7,6 @@ import * as React from 'react'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { DocumentTitleSegment } from 'src/components/DocumentTitle'; import { LandingHeader } from 'src/components/LandingHeader'; -import { Notice } from 'src/components/Notice/Notice'; import { VPC_GETTING_STARTED_LINK } from 'src/features/VPCs/constants'; import { SubnetContent } from 'src/features/VPCs/VPCCreate/FormComponents/SubnetContent'; import { useCreateVPC } from 'src/hooks/useCreateVPC'; diff --git a/packages/manager/src/features/VPCs/VPCCreateDrawer/VPCCreateDrawer.tsx b/packages/manager/src/features/VPCs/VPCCreateDrawer/VPCCreateDrawer.tsx index f22abc2de96..d477be0dadb 100644 --- a/packages/manager/src/features/VPCs/VPCCreateDrawer/VPCCreateDrawer.tsx +++ b/packages/manager/src/features/VPCs/VPCCreateDrawer/VPCCreateDrawer.tsx @@ -1,11 +1,10 @@ -import { Box } from '@linode/ui'; +import { Box, Notice } from '@linode/ui'; import { useTheme } from '@mui/material/styles'; import Grid from '@mui/material/Unstable_Grid2'; import * as React from 'react'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Drawer } from 'src/components/Drawer'; -import { Notice } from 'src/components/Notice/Notice'; import { CannotCreateVPCNotice } from 'src/features/VPCs/VPCCreate/FormComponents/CannotCreateVPCNotice'; import { SubnetContent } from 'src/features/VPCs/VPCCreate/FormComponents/SubnetContent'; import { VPCTopSectionContent } from 'src/features/VPCs/VPCCreate/FormComponents/VPCTopSectionContent'; diff --git a/packages/manager/src/features/VPCs/VPCDetail/AssignIPRanges.tsx b/packages/manager/src/features/VPCs/VPCDetail/AssignIPRanges.tsx index 8856b1c656a..d743659cbe2 100644 --- a/packages/manager/src/features/VPCs/VPCDetail/AssignIPRanges.tsx +++ b/packages/manager/src/features/VPCs/VPCDetail/AssignIPRanges.tsx @@ -1,11 +1,9 @@ -import { Box } from '@linode/ui'; +import { Box, Divider, Notice } from '@linode/ui'; import { styled, useTheme } from '@mui/material/styles'; import * as React from 'react'; -import { Divider } from 'src/components/Divider'; import { Link } from 'src/components/Link'; import { MultipleIPInput } from 'src/components/MultipleIPInput/MultipleIPInput'; -import { Notice } from 'src/components/Notice/Notice'; import { TooltipIcon } from 'src/components/TooltipIcon'; import { Typography } from 'src/components/Typography'; import { diff --git a/packages/manager/src/features/VPCs/VPCDetail/SubnetAssignLinodesDrawer.tsx b/packages/manager/src/features/VPCs/VPCDetail/SubnetAssignLinodesDrawer.tsx index 7a53ece0254..5cac4973cf4 100644 --- a/packages/manager/src/features/VPCs/VPCDetail/SubnetAssignLinodesDrawer.tsx +++ b/packages/manager/src/features/VPCs/VPCDetail/SubnetAssignLinodesDrawer.tsx @@ -1,5 +1,5 @@ import { appendConfigInterface } from '@linode/api-v4'; -import { Box, FormHelperText } from '@linode/ui'; +import { Box, FormHelperText, Notice } from '@linode/ui'; import { useTheme } from '@mui/material/styles'; import { useFormik } from 'formik'; import * as React from 'react'; @@ -11,7 +11,6 @@ import { DownloadCSV } from 'src/components/DownloadCSV/DownloadCSV'; import { Drawer } from 'src/components/Drawer'; import { FormControlLabel } from 'src/components/FormControlLabel'; import { Link } from 'src/components/Link'; -import { Notice } from 'src/components/Notice/Notice'; import { RemovableSelectionsListTable } from 'src/components/RemovableSelectionsList/RemovableSelectionsListTable'; import { TextField } from 'src/components/TextField'; import { TooltipIcon } from 'src/components/TooltipIcon'; diff --git a/packages/manager/src/features/VPCs/VPCDetail/SubnetCreateDrawer.tsx b/packages/manager/src/features/VPCs/VPCDetail/SubnetCreateDrawer.tsx index d3d1326a69a..23bf08ab451 100644 --- a/packages/manager/src/features/VPCs/VPCDetail/SubnetCreateDrawer.tsx +++ b/packages/manager/src/features/VPCs/VPCDetail/SubnetCreateDrawer.tsx @@ -1,4 +1,5 @@ import { yupResolver } from '@hookform/resolvers/yup'; +import { Notice, Stack } from '@linode/ui'; import { FormHelperText } from '@linode/ui'; import { createSubnetSchema } from '@linode/validation'; import * as React from 'react'; @@ -6,8 +7,6 @@ import { Controller, useForm } from 'react-hook-form'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Drawer } from 'src/components/Drawer'; -import { Notice } from 'src/components/Notice/Notice'; -import { Stack } from 'src/components/Stack'; import { TextField } from 'src/components/TextField'; import { useGrants, useProfile } from 'src/queries/profile/profile'; import { useCreateSubnetMutation, useVPCQuery } from 'src/queries/vpcs/vpcs'; diff --git a/packages/manager/src/features/VPCs/VPCDetail/SubnetEditDrawer.tsx b/packages/manager/src/features/VPCs/VPCDetail/SubnetEditDrawer.tsx index 28b079c9bb2..9dfb64e400e 100644 --- a/packages/manager/src/features/VPCs/VPCDetail/SubnetEditDrawer.tsx +++ b/packages/manager/src/features/VPCs/VPCDetail/SubnetEditDrawer.tsx @@ -1,9 +1,9 @@ +import { Notice } from '@linode/ui'; import { useFormik } from 'formik'; import * as React from 'react'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Drawer } from 'src/components/Drawer'; -import { Notice } from 'src/components/Notice/Notice'; import { TextField } from 'src/components/TextField'; import { useGrants, useProfile } from 'src/queries/profile/profile'; import { useUpdateSubnetMutation } from 'src/queries/vpcs/vpcs'; diff --git a/packages/manager/src/features/VPCs/VPCDetail/SubnetLinodeRow.styles.ts b/packages/manager/src/features/VPCs/VPCDetail/SubnetLinodeRow.styles.ts index 066e2105715..4e75344d122 100644 --- a/packages/manager/src/features/VPCs/VPCDetail/SubnetLinodeRow.styles.ts +++ b/packages/manager/src/features/VPCs/VPCDetail/SubnetLinodeRow.styles.ts @@ -1,6 +1,6 @@ +import { WarningIcon } from '@linode/ui'; import { styled } from '@mui/material/styles'; -import Warning from 'src/assets/icons/warning.svg'; import { TableCell } from 'src/components/TableCell'; import { TableRow } from 'src/components/TableRow'; @@ -40,7 +40,7 @@ export const StyledTableHeadCell = styled(TableCell, { borderTop: 'none !important', })); -export const StyledWarningIcon = styled(Warning, { +export const StyledWarningIcon = styled(WarningIcon, { label: 'StyledWarningIcon', })(({ theme }) => ({ fill: theme.color.yellow, diff --git a/packages/manager/src/features/VPCs/VPCDetail/SubnetUnassignLinodesDrawer.tsx b/packages/manager/src/features/VPCs/VPCDetail/SubnetUnassignLinodesDrawer.tsx index 8b726a12699..eeda7874cd8 100644 --- a/packages/manager/src/features/VPCs/VPCDetail/SubnetUnassignLinodesDrawer.tsx +++ b/packages/manager/src/features/VPCs/VPCDetail/SubnetUnassignLinodesDrawer.tsx @@ -1,4 +1,4 @@ -import { Box } from '@linode/ui'; +import { Box, Notice } from '@linode/ui'; import { Stack, Typography } from '@mui/material'; import { useQueryClient } from '@tanstack/react-query'; import { useFormik } from 'formik'; @@ -8,7 +8,6 @@ import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Autocomplete } from 'src/components/Autocomplete/Autocomplete'; import { DownloadCSV } from 'src/components/DownloadCSV/DownloadCSV'; import { Drawer } from 'src/components/Drawer'; -import { Notice } from 'src/components/Notice/Notice'; import { RemovableSelectionsListTable } from 'src/components/RemovableSelectionsList/RemovableSelectionsListTable'; import { SUBNET_UNASSIGN_LINODES_WARNING } from 'src/features/VPCs/constants'; import { useFormattedDate } from 'src/hooks/useFormattedDate'; diff --git a/packages/manager/src/features/VPCs/VPCLanding/VPCEditDrawer.tsx b/packages/manager/src/features/VPCs/VPCLanding/VPCEditDrawer.tsx index d8264de1f43..c9034543df6 100644 --- a/packages/manager/src/features/VPCs/VPCLanding/VPCEditDrawer.tsx +++ b/packages/manager/src/features/VPCs/VPCLanding/VPCEditDrawer.tsx @@ -1,10 +1,10 @@ +import { Notice } from '@linode/ui'; import { updateVPCSchema } from '@linode/validation/lib/vpcs.schema'; import { useFormik } from 'formik'; import * as React from 'react'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Drawer } from 'src/components/Drawer'; -import { Notice } from 'src/components/Notice/Notice'; import { RegionSelect } from 'src/components/RegionSelect/RegionSelect'; import { TextField } from 'src/components/TextField'; import { useGrants, useProfile } from 'src/queries/profile/profile'; diff --git a/packages/manager/src/features/Volumes/AttachVolumeDrawer.tsx b/packages/manager/src/features/Volumes/AttachVolumeDrawer.tsx index b71987020a3..6a2d0ffa4b5 100644 --- a/packages/manager/src/features/Volumes/AttachVolumeDrawer.tsx +++ b/packages/manager/src/features/Volumes/AttachVolumeDrawer.tsx @@ -1,4 +1,4 @@ -import { Box, FormHelperText } from '@linode/ui'; +import { Box, FormHelperText, Notice } from '@linode/ui'; import { styled } from '@mui/material/styles'; import { useFormik } from 'formik'; import { useSnackbar } from 'notistack'; @@ -10,7 +10,6 @@ import { Checkbox } from 'src/components/Checkbox'; import { Drawer } from 'src/components/Drawer'; import { BLOCK_STORAGE_ENCRYPTION_SETTING_IMMUTABLE_COPY } from 'src/components/Encryption/constants'; import { useIsBlockStorageEncryptionFeatureEnabled } from 'src/components/Encryption/utils'; -import { Notice } from 'src/components/Notice/Notice'; import { LinodeSelect } from 'src/features/Linodes/LinodeSelect/LinodeSelect'; import { useEventsPollingActions } from 'src/queries/events/events'; import { useGrants } from 'src/queries/profile/profile'; diff --git a/packages/manager/src/features/Volumes/CloneVolumeDrawer.tsx b/packages/manager/src/features/Volumes/CloneVolumeDrawer.tsx index 1bd690b3043..5a8a21b59d9 100644 --- a/packages/manager/src/features/Volumes/CloneVolumeDrawer.tsx +++ b/packages/manager/src/features/Volumes/CloneVolumeDrawer.tsx @@ -1,4 +1,4 @@ -import { Box } from '@linode/ui'; +import { Box, Notice } from '@linode/ui'; import { CloneVolumeSchema } from '@linode/validation/lib/volumes.schema'; import { useFormik } from 'formik'; import * as React from 'react'; @@ -8,7 +8,6 @@ import { Checkbox } from 'src/components/Checkbox'; import { Drawer } from 'src/components/Drawer'; import { BLOCK_STORAGE_CLONING_INHERITANCE_CAVEAT } from 'src/components/Encryption/constants'; import { useIsBlockStorageEncryptionFeatureEnabled } from 'src/components/Encryption/utils'; -import { Notice } from 'src/components/Notice/Notice'; import { TextField } from 'src/components/TextField'; import { Typography } from 'src/components/Typography'; import { useEventsPollingActions } from 'src/queries/events/events'; diff --git a/packages/manager/src/features/Volumes/DeleteVolumeDialog.tsx b/packages/manager/src/features/Volumes/DeleteVolumeDialog.tsx index cc0db32476a..b36575e65b6 100644 --- a/packages/manager/src/features/Volumes/DeleteVolumeDialog.tsx +++ b/packages/manager/src/features/Volumes/DeleteVolumeDialog.tsx @@ -1,6 +1,6 @@ +import { Notice } from '@linode/ui'; import * as React from 'react'; -import { Notice } from 'src/components/Notice/Notice'; import { TypeToConfirmDialog } from 'src/components/TypeToConfirmDialog/TypeToConfirmDialog'; import { useEventsPollingActions } from 'src/queries/events/events'; import { useDeleteVolumeMutation } from 'src/queries/volumes/volumes'; diff --git a/packages/manager/src/features/Volumes/DetachVolumeDialog.tsx b/packages/manager/src/features/Volumes/DetachVolumeDialog.tsx index 4e1d7d6e186..06cf1444af6 100644 --- a/packages/manager/src/features/Volumes/DetachVolumeDialog.tsx +++ b/packages/manager/src/features/Volumes/DetachVolumeDialog.tsx @@ -1,7 +1,7 @@ +import { Notice } from '@linode/ui'; import { useSnackbar } from 'notistack'; import * as React from 'react'; -import { Notice } from 'src/components/Notice/Notice'; import { TypeToConfirmDialog } from 'src/components/TypeToConfirmDialog/TypeToConfirmDialog'; import { Typography } from 'src/components/Typography'; import { useEventsPollingActions } from 'src/queries/events/events'; diff --git a/packages/manager/src/features/Volumes/EditVolumeDrawer.tsx b/packages/manager/src/features/Volumes/EditVolumeDrawer.tsx index 94865d8de53..84ba1c888dc 100644 --- a/packages/manager/src/features/Volumes/EditVolumeDrawer.tsx +++ b/packages/manager/src/features/Volumes/EditVolumeDrawer.tsx @@ -1,4 +1,4 @@ -import { Box } from '@linode/ui'; +import { Box, Notice } from '@linode/ui'; import { UpdateVolumeSchema } from '@linode/validation'; import { useFormik } from 'formik'; import React from 'react'; @@ -8,7 +8,6 @@ import { Checkbox } from 'src/components/Checkbox'; import { Drawer } from 'src/components/Drawer'; import { BLOCK_STORAGE_ENCRYPTION_SETTING_IMMUTABLE_COPY } from 'src/components/Encryption/constants'; import { useIsBlockStorageEncryptionFeatureEnabled } from 'src/components/Encryption/utils'; -import { Notice } from 'src/components/Notice/Notice'; import { TagsInput } from 'src/components/TagsInput/TagsInput'; import { TextField } from 'src/components/TextField'; import { useGrants } from 'src/queries/profile/profile'; diff --git a/packages/manager/src/features/Volumes/ResizeVolumeDrawer.tsx b/packages/manager/src/features/Volumes/ResizeVolumeDrawer.tsx index 550e9afa576..d24e6992bba 100644 --- a/packages/manager/src/features/Volumes/ResizeVolumeDrawer.tsx +++ b/packages/manager/src/features/Volumes/ResizeVolumeDrawer.tsx @@ -1,4 +1,4 @@ -import { Volume } from '@linode/api-v4'; +import { Notice } from '@linode/ui'; import { ResizeVolumeSchema } from '@linode/validation'; import { useFormik } from 'formik'; import { useSnackbar } from 'notistack'; @@ -6,7 +6,6 @@ import React from 'react'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { Drawer } from 'src/components/Drawer'; -import { Notice } from 'src/components/Notice/Notice'; import { useEventsPollingActions } from 'src/queries/events/events'; import { useGrants } from 'src/queries/profile/profile'; import { @@ -22,6 +21,8 @@ import { PRICES_RELOAD_ERROR_NOTICE_TEXT } from 'src/utilities/pricing/constants import { PricePanel } from './VolumeDrawer/PricePanel'; import { SizeField } from './VolumeDrawer/SizeField'; +import type { Volume } from '@linode/api-v4'; + interface Props { onClose: () => void; open: boolean; diff --git a/packages/manager/src/features/Volumes/VolumeCreate.tsx b/packages/manager/src/features/Volumes/VolumeCreate.tsx index cc2ac13e4ea..4ebd1772e17 100644 --- a/packages/manager/src/features/Volumes/VolumeCreate.tsx +++ b/packages/manager/src/features/Volumes/VolumeCreate.tsx @@ -1,4 +1,4 @@ -import { Box, Paper } from '@linode/ui'; +import { Box, Notice, Paper, Stack } from '@linode/ui'; import { CreateVolumeSchema } from '@linode/validation/lib/volumes.schema'; import { useTheme } from '@mui/material/styles'; import { createLazyRoute } from '@tanstack/react-router'; @@ -22,9 +22,7 @@ import { Encryption } from 'src/components/Encryption/Encryption'; import { useIsBlockStorageEncryptionFeatureEnabled } from 'src/components/Encryption/utils'; import { ErrorMessage } from 'src/components/ErrorMessage'; import { LandingHeader } from 'src/components/LandingHeader'; -import { Notice } from 'src/components/Notice/Notice'; import { RegionSelect } from 'src/components/RegionSelect/RegionSelect'; -import { Stack } from 'src/components/Stack'; import { TextField } from 'src/components/TextField'; import { TooltipIcon } from 'src/components/TooltipIcon'; import { Typography } from 'src/components/Typography'; diff --git a/packages/manager/src/features/Volumes/VolumeDetailsDrawer.tsx b/packages/manager/src/features/Volumes/VolumeDetailsDrawer.tsx index 5be75d6d874..ac7ef2ce153 100644 --- a/packages/manager/src/features/Volumes/VolumeDetailsDrawer.tsx +++ b/packages/manager/src/features/Volumes/VolumeDetailsDrawer.tsx @@ -1,11 +1,12 @@ -import { Volume } from '@linode/api-v4'; +import { Stack } from '@linode/ui'; import React from 'react'; import { CopyableTextField } from 'src/components/CopyableTextField/CopyableTextField'; import { Drawer } from 'src/components/Drawer'; -import { Stack } from 'src/components/Stack'; import { Typography } from 'src/components/Typography'; +import type { Volume } from '@linode/api-v4'; + interface Props { onClose: () => void; open: boolean; diff --git a/packages/manager/src/features/Volumes/VolumeDrawer/LinodeVolumeAddDrawer.tsx b/packages/manager/src/features/Volumes/VolumeDrawer/LinodeVolumeAddDrawer.tsx index cb0c40d646f..4973aafbad1 100644 --- a/packages/manager/src/features/Volumes/VolumeDrawer/LinodeVolumeAddDrawer.tsx +++ b/packages/manager/src/features/Volumes/VolumeDrawer/LinodeVolumeAddDrawer.tsx @@ -1,9 +1,9 @@ +import { Notice } from '@linode/ui'; import * as React from 'react'; import { Drawer } from 'src/components/Drawer'; import { BLOCK_STORAGE_CLIENT_LIBRARY_UPDATE_REQUIRED_COPY } from 'src/components/Encryption/constants'; import { useIsBlockStorageEncryptionFeatureEnabled } from 'src/components/Encryption/utils'; -import { Notice } from 'src/components/Notice/Notice'; import { Typography } from 'src/components/Typography'; import { LinodeVolumeAttachForm } from './LinodeVolumeAttachForm'; diff --git a/packages/manager/src/features/Volumes/VolumeDrawer/LinodeVolumeAttachForm.tsx b/packages/manager/src/features/Volumes/VolumeDrawer/LinodeVolumeAttachForm.tsx index 8aa76a1345a..51b4b9e4c0d 100644 --- a/packages/manager/src/features/Volumes/VolumeDrawer/LinodeVolumeAttachForm.tsx +++ b/packages/manager/src/features/Volumes/VolumeDrawer/LinodeVolumeAttachForm.tsx @@ -1,10 +1,10 @@ +import { Notice } from '@linode/ui'; import { useFormik } from 'formik'; import { useSnackbar } from 'notistack'; import * as React from 'react'; import { number, object } from 'yup'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; -import { Notice } from 'src/components/Notice/Notice'; import { useEventsPollingActions } from 'src/queries/events/events'; import { useGrants } from 'src/queries/profile/profile'; import { diff --git a/packages/manager/src/features/Volumes/VolumeDrawer/LinodeVolumeCreateForm.tsx b/packages/manager/src/features/Volumes/VolumeDrawer/LinodeVolumeCreateForm.tsx index bc07204f6ba..ad3a3ae8d98 100644 --- a/packages/manager/src/features/Volumes/VolumeDrawer/LinodeVolumeCreateForm.tsx +++ b/packages/manager/src/features/Volumes/VolumeDrawer/LinodeVolumeCreateForm.tsx @@ -1,4 +1,4 @@ -import { Box } from '@linode/ui'; +import { Box, Notice } from '@linode/ui'; import { CreateVolumeSchema } from '@linode/validation/lib/volumes.schema'; import { useFormik } from 'formik'; import { useSnackbar } from 'notistack'; @@ -13,7 +13,6 @@ import { } from 'src/components/Encryption/constants'; import { Encryption } from 'src/components/Encryption/Encryption'; import { useIsBlockStorageEncryptionFeatureEnabled } from 'src/components/Encryption/utils'; -import { Notice } from 'src/components/Notice/Notice'; import { TagsInput } from 'src/components/TagsInput/TagsInput'; import { TextField } from 'src/components/TextField'; import { Typography } from 'src/components/Typography'; diff --git a/packages/manager/src/features/components/PlansPanel/DisabledPlanSelectionTooltip.tsx b/packages/manager/src/features/components/PlansPanel/DisabledPlanSelectionTooltip.tsx index 9a9bd187c8c..5a7d52752e8 100644 --- a/packages/manager/src/features/components/PlansPanel/DisabledPlanSelectionTooltip.tsx +++ b/packages/manager/src/features/components/PlansPanel/DisabledPlanSelectionTooltip.tsx @@ -1,5 +1,4 @@ -import { IconButton } from '@linode/ui'; -import { Tooltip } from '@linode/ui'; +import { IconButton, Tooltip } from '@linode/ui'; import HelpOutline from '@mui/icons-material/HelpOutline'; import * as React from 'react'; diff --git a/packages/manager/src/features/components/PlansPanel/DistributedRegionPlanTable.tsx b/packages/manager/src/features/components/PlansPanel/DistributedRegionPlanTable.tsx index ea927d09792..431570f54d5 100644 --- a/packages/manager/src/features/components/PlansPanel/DistributedRegionPlanTable.tsx +++ b/packages/manager/src/features/components/PlansPanel/DistributedRegionPlanTable.tsx @@ -1,8 +1,7 @@ -import { Box, Paper } from '@linode/ui'; +import { Box, Notice, Paper } from '@linode/ui'; import { styled } from '@mui/material/styles'; import React from 'react'; -import { Notice } from 'src/components/Notice/Notice'; import { Typography } from 'src/components/Typography'; import type { SxProps, Theme } from '@mui/material/styles'; diff --git a/packages/manager/src/features/components/PlansPanel/MetalNotice.tsx b/packages/manager/src/features/components/PlansPanel/MetalNotice.tsx index 35ef6810ec4..55044502c6d 100644 --- a/packages/manager/src/features/components/PlansPanel/MetalNotice.tsx +++ b/packages/manager/src/features/components/PlansPanel/MetalNotice.tsx @@ -1,6 +1,6 @@ +import { Notice } from '@linode/ui'; import * as React from 'react'; -import { Notice } from 'src/components/Notice/Notice'; import { useRegionsQuery } from 'src/queries/regions/regions'; import { StyledTypography } from './PlansPanel.styles'; diff --git a/packages/manager/src/features/components/PlansPanel/PlanContainer.styles.ts b/packages/manager/src/features/components/PlansPanel/PlanContainer.styles.ts index 6260a155855..dac60cbc026 100644 --- a/packages/manager/src/features/components/PlansPanel/PlanContainer.styles.ts +++ b/packages/manager/src/features/components/PlansPanel/PlanContainer.styles.ts @@ -12,14 +12,15 @@ interface StyledTableCellPropsProps extends TableCellProps { export const StyledTable = styled(Table, { label: 'StyledTable', -})(({ theme }) => ({ +})({ overflowX: 'hidden', -})); +}); export const StyledTableCell = styled(TableCell, { label: 'StyledTableCell', shouldForwardProp: omittedProps(['isPlanCell']), })(({ theme, ...props }) => ({ + ...(props.isPlanCell && { width: '30%' }), '&.emptyCell': { borderRight: 'none', }, diff --git a/packages/manager/src/features/components/PlansPanel/PlanContainer.tsx b/packages/manager/src/features/components/PlansPanel/PlanContainer.tsx index 512bcbb91fb..d0cf1a7231d 100644 --- a/packages/manager/src/features/components/PlansPanel/PlanContainer.tsx +++ b/packages/manager/src/features/components/PlansPanel/PlanContainer.tsx @@ -1,10 +1,9 @@ -import { LinodeTypeClass } from '@linode/api-v4/lib/linodes'; +import { Notice } from '@linode/ui'; import Grid from '@mui/material/Unstable_Grid2'; import * as React from 'react'; import { useLocation } from 'react-router-dom'; import { Hidden } from 'src/components/Hidden'; -import { Notice } from 'src/components/Notice/Notice'; import { Typography } from 'src/components/Typography'; import { useFlags } from 'src/hooks/useFlags'; import { PLAN_SELECTION_NO_REGION_SELECTED_MESSAGE } from 'src/utilities/pricing/constants'; @@ -14,7 +13,8 @@ import { PlanSelectionTable } from './PlanSelectionTable'; import type { PlanWithAvailability } from './types'; import type { Region } from '@linode/api-v4'; - +import type { LinodeTypeClass } from '@linode/api-v4/lib/linodes'; +import type { Theme } from '@mui/material/styles'; export interface PlanContainerProps { allDisabledPlans: PlanWithAvailability[]; currentPlanHeading?: string; @@ -50,7 +50,8 @@ export const PlanContainer = (props: PlanContainerProps) => { // Show the Transfer column if, for any plan, the api returned data and we're not in the Database Create flow const showTransfer = - showLimits && plans.some((plan: PlanWithAvailability) => plan.transfer); + showLimits && + plans.some((plan: PlanWithAvailability) => plan.transfer !== undefined); // Show the Network throughput column if, for any plan, the api returned data (currently Bare Metal does not) const showNetwork = @@ -64,6 +65,10 @@ export const PlanContainer = (props: PlanContainerProps) => { const shouldDisplayNoRegionSelectedMessage = !selectedRegionId && !isDatabaseCreateFlow && !isDatabaseResizeFlow; + const isDatabaseGA = + !flags.dbaasV2?.beta && + flags.dbaasV2?.enabled && + (isDatabaseCreateFlow || isDatabaseResizeFlow); interface PlanSelectionDividerTable { header?: string; planFilter?: (plan: PlanWithAvailability) => boolean; @@ -141,6 +146,18 @@ export const PlanContainer = (props: PlanContainerProps) => { return ( + {isCreate && isDatabaseGA && ( + ({ + marginBottom: theme.spacing(2), + marginLeft: theme.spacing(1), + marginTop: theme.spacing(1), + })} + > + Usable storage is smaller than the actual plan storage due to the + overhead from the database platform. + + )} {shouldDisplayNoRegionSelectedMessage ? ( { } key={`plan-filter-${idx}`} planFilter={table.planFilter} + plans={plans} showNetwork={showNetwork} showTransfer={showTransfer} /> @@ -213,6 +231,7 @@ export const PlanContainer = (props: PlanContainerProps) => { renderPlanSelection={renderPlanSelection} showNetwork={showNetwork} showTransfer={showTransfer} + showUsableStorage={isDatabaseCreateFlow || isDatabaseResizeFlow} /> ) )} diff --git a/packages/manager/src/features/components/PlansPanel/PlanInformation.tsx b/packages/manager/src/features/components/PlansPanel/PlanInformation.tsx index 56c159989a0..3d45ad31d42 100644 --- a/packages/manager/src/features/components/PlansPanel/PlanInformation.tsx +++ b/packages/manager/src/features/components/PlansPanel/PlanInformation.tsx @@ -1,7 +1,7 @@ +import { Notice } from '@linode/ui'; import * as React from 'react'; import { Link } from 'src/components/Link'; -import { Notice } from 'src/components/Notice/Notice'; import { Typography } from 'src/components/Typography'; import { StyledNoticeTypography } from 'src/features/components/PlansPanel/PlansAvailabilityNotice.styles'; import { useFlags } from 'src/hooks/useFlags'; @@ -45,6 +45,7 @@ export const PlanInformation = (props: PlanInformationProps) => { return Boolean(disabledClasses?.includes(thisClass)); }; const showGPUEgressBanner = Boolean(useFlags().gpuv2?.egressBanner); + const showTransferBanner = Boolean(useFlags().gpuv2?.transferBanner); return ( <> @@ -68,6 +69,23 @@ export const PlanInformation = (props: PlanInformationProps) => { )} + {showTransferBanner && ( + + theme.font.bold} + fontSize="1rem" + > + Some plans do not include bundled network transfer. If the + transfer allotment is 0, all outbound network transfer is + subject to charges. +
    + + Learn more about transfer costs + + . +
    +
    + )} { {showTransfer ? ( - {plan.transfer ? <>{plan.transfer / 1000} TB : ''} + {plan.transfer !== undefined ? ( + <>{plan.transfer / 1000} TB + ) : ( + '' + )} ) : null} {showNetwork ? ( diff --git a/packages/manager/src/features/components/PlansPanel/PlanSelectionTable.tsx b/packages/manager/src/features/components/PlansPanel/PlanSelectionTable.tsx index ee13cbe28b0..624a6605045 100644 --- a/packages/manager/src/features/components/PlansPanel/PlanSelectionTable.tsx +++ b/packages/manager/src/features/components/PlansPanel/PlanSelectionTable.tsx @@ -4,10 +4,14 @@ import { TableBody } from 'src/components/TableBody'; import { TableHead } from 'src/components/TableHead'; import { TableRow } from 'src/components/TableRow'; import { TableRowEmpty } from 'src/components/TableRowEmpty/TableRowEmpty'; +import { TooltipIcon } from 'src/components/TooltipIcon'; +import { useFlags } from 'src/hooks/useFlags'; import { PLAN_SELECTION_NO_REGION_SELECTED_MESSAGE } from 'src/utilities/pricing/constants'; import { StyledTable, StyledTableCell } from './PlanContainer.styles'; -import { PlanWithAvailability } from './types'; + +import type { PlanWithAvailability } from './types'; +import type { TooltipIconStatus } from 'src/components/TooltipIcon'; interface PlanSelectionFilterOptionsTable { header?: string; @@ -17,12 +21,14 @@ interface PlanSelectionFilterOptionsTable { interface PlanSelectionTableProps { filterOptions?: PlanSelectionFilterOptionsTable; planFilter?: (plan: PlanWithAvailability) => boolean; + plans?: PlanWithAvailability[]; renderPlanSelection: ( filterOptions?: PlanSelectionFilterOptionsTable | undefined ) => React.JSX.Element[]; shouldDisplayNoRegionSelectedMessage: boolean; showNetwork?: boolean; showTransfer?: boolean; + showUsableStorage?: boolean; } const tableCells = [ @@ -45,12 +51,51 @@ const tableCells = [ export const PlanSelectionTable = (props: PlanSelectionTableProps) => { const { filterOptions, + plans, renderPlanSelection, shouldDisplayNoRegionSelectedMessage, showNetwork: shouldShowNetwork, showTransfer: shouldShowTransfer, + showUsableStorage, } = props; + const flags = useFlags(); + + const showTransferTooltip = React.useCallback( + (cellName: string) => + plans?.some((plan) => { + return ( + flags.gpuv2?.transferBanner && + plan.class === 'gpu' && + filterOptions?.header?.includes('Ada') && + cellName === 'Transfer' + ); + }), + [plans, filterOptions, flags.gpuv2] + ); + + const showUsableStorageTooltip = (cellName: string) => + cellName === 'Usable Storage'; + const showTooltip = ( + status: TooltipIconStatus, + text: JSX.Element | string, + width?: number + ) => { + return ( + + ); + }; return ( { ) { return null; } + if ( + showUsableStorage && + !flags.dbaasV2?.beta && + flags.dbaasV2?.enabled && + cellName === 'Storage' + ) { + cellName = 'Usable Storage'; + } return ( { {isPlanCell && filterOptions?.header ? filterOptions?.header : cellName} + {showTransferTooltip(cellName) && + showTooltip( + 'help', + 'Some plans do not include bundled network transfer. If the transfer allotment is 0, all outbound network transfer is subject to charges.' + )} + {showUsableStorageTooltip(cellName) && + showTooltip( + 'help', + 'Usable storage is smaller than the actual plan storage due to the overhead from the database platform.', + 240 + )} ); })} diff --git a/packages/manager/src/features/components/PlansPanel/PlansAvailabilityNotice.tsx b/packages/manager/src/features/components/PlansPanel/PlansAvailabilityNotice.tsx index a839965ee10..c80c5be86bb 100644 --- a/packages/manager/src/features/components/PlansPanel/PlansAvailabilityNotice.tsx +++ b/packages/manager/src/features/components/PlansPanel/PlansAvailabilityNotice.tsx @@ -1,9 +1,9 @@ +import { Notice } from '@linode/ui'; import * as React from 'react'; import { ListItem } from 'src/components/ListItem'; -import { Notice } from 'src/components/Notice/Notice'; -import { getCapabilityFromPlanType } from 'src/utilities/planNotices'; import { formatPlanTypes } from 'src/utilities/planNotices'; +import { getCapabilityFromPlanType } from 'src/utilities/planNotices'; import { StyledFormattedRegionList, diff --git a/packages/manager/src/features/components/PlansPanel/PlansPanel.tsx b/packages/manager/src/features/components/PlansPanel/PlansPanel.tsx index 833cd24a11e..3cf6cc8a6bf 100644 --- a/packages/manager/src/features/components/PlansPanel/PlansPanel.tsx +++ b/packages/manager/src/features/components/PlansPanel/PlansPanel.tsx @@ -1,9 +1,9 @@ +import { Notice } from '@linode/ui'; import * as React from 'react'; import { useLocation } from 'react-router-dom'; -import { Notice } from 'src/components/Notice/Notice'; -import { useIsGeckoEnabled } from 'src/components/RegionSelect/RegionSelect.utils'; import { getIsDistributedRegion } from 'src/components/RegionSelect/RegionSelect.utils'; +import { useIsGeckoEnabled } from 'src/components/RegionSelect/RegionSelect.utils'; import { isDistributedRegionSupported } from 'src/components/RegionSelect/RegionSelect.utils'; import { TabbedPanel } from 'src/components/TabbedPanel/TabbedPanel'; import { useFlags } from 'src/hooks/useFlags'; diff --git a/packages/manager/src/mocks/serverHandlers.ts b/packages/manager/src/mocks/serverHandlers.ts index a1bf4dfe4bf..971878662c1 100644 --- a/packages/manager/src/mocks/serverHandlers.ts +++ b/packages/manager/src/mocks/serverHandlers.ts @@ -225,11 +225,8 @@ const databases = [ const dedicatedTypes = databaseTypeFactory.buildList(7, { class: 'dedicated', }); - const premiumTypes = databaseTypeFactory.buildList(7, { - class: 'premium', - }); return HttpResponse.json( - makeResourcePage([...standardTypes, ...dedicatedTypes, ...premiumTypes]) + makeResourcePage([...standardTypes, ...dedicatedTypes]) ); }), @@ -238,32 +235,32 @@ const databases = [ const engine2 = databaseEngineFactory.buildList(3, { engine: 'postgresql', }); - const engine3 = databaseEngineFactory.buildList(3, { - engine: 'mongodb', - }); - const combinedList = [...engine1, ...engine2, ...engine3]; + const combinedList = [...engine1, ...engine2]; return HttpResponse.json(makeResourcePage(combinedList)); }), http.get('*/databases/:engine/instances/:id', ({ params }) => { - const database = databaseFactory.build({ - compression_type: params.engine === 'mongodb' ? 'none' : undefined, + const isDefault = Number(params.id) % 2 !== 0; + const db: Record = { engine: params.engine as 'mysql', id: Number(params.id), label: `database-${params.id}`, - replication_commit_type: - params.engine === 'postgresql' ? 'local' : undefined, - replication_type: + platform: isDefault ? 'rdbms-default' : 'rdbms-legacy', + }; + if (!isDefault) { + db.replication_commit_type = + params.engine === 'postgresql' ? 'local' : undefined; + db.replication_type = params.engine === 'mysql' ? pickRandom(possibleMySQLReplicationTypes) : params.engine === 'postgresql' ? pickRandom(possiblePostgresReplicationTypes) - : (undefined as any), - ssl_connection: true, - storage_engine: params.engine === 'mongodb' ? 'wiredtiger' : undefined, - }); + : (undefined as any); + db.ssl_connection = true; + } + const database = databaseFactory.build(db); return HttpResponse.json(database); }), @@ -392,7 +389,17 @@ const nanodeType = linodeTypeFactory.build({ id: 'g6-nanode-1' }); const standardTypes = linodeTypeFactory.buildList(7); const dedicatedTypes = dedicatedTypeFactory.buildList(7); const proDedicatedType = proDedicatedTypeFactory.build(); - +const gpuTypesAda = linodeTypeFactory.buildList(7, { + class: 'gpu', + gpus: 5, + label: 'Ada Lovelace', + transfer: 0, +}); +const gpuTypesRX = linodeTypeFactory.buildList(7, { + class: 'gpu', + gpus: 1, + transfer: 5000, +}); const proxyAccountUser = accountUserFactory.build({ email: 'partner@proxy.com', last_login: null, @@ -586,6 +593,8 @@ export const handlers = [ nanodeType, ...standardTypes, ...dedicatedTypes, + ...gpuTypesAda, + ...gpuTypesRX, proDedicatedType, ]) ); diff --git a/packages/manager/src/queries/types.ts b/packages/manager/src/queries/types.ts index 8e736bfa1af..c40a91db098 100644 --- a/packages/manager/src/queries/types.ts +++ b/packages/manager/src/queries/types.ts @@ -25,7 +25,7 @@ export const useSpecificTypes = (types: string[], enabled = true) => { return useQueries({ queries: types.map>((type) => ({ - enabled, + enabled: enabled && Boolean(type), ...linodeQueries.types._ctx.type(type), ...queryPresets.oneTimeFetch, initialData() { diff --git a/packages/manager/src/utilities/getEventsActionLink.ts b/packages/manager/src/utilities/getEventsActionLink.ts index efd25755d06..0584e4b195c 100644 --- a/packages/manager/src/utilities/getEventsActionLink.ts +++ b/packages/manager/src/utilities/getEventsActionLink.ts @@ -6,6 +6,10 @@ export const getEngineFromDatabaseEntityURL = (url: string) => { return url.match(/databases\/(\w*)\/instances/i)?.[1]; }; +export const getRegionFromObjectStorageEntityURL = (url: string) => { + return url.match(/\/buckets\/([^/]+)/)?.[1]; +}; + export const getLinkForEvent = (action: EventAction, entity: Entity | null) => { const type = entity?.type; const id = entity?.id; @@ -143,10 +147,14 @@ export const getLinkTargets = (entity: Entity | null) => { return '/images'; case 'longview': return '/longview'; - case 'volume': - return '/volumes'; + case 'object_storage_bucket': + return `/object-storage/buckets/${getRegionFromObjectStorageEntityURL( + entity.url + )}/${entity.label}`; case 'placement_group': return `/placement-groups/${entity.id}`; + case 'volume': + return '/volumes'; case 'vpc': return `/vpcs/${entity.id}`; default: diff --git a/packages/ui/.changeset/pr-11125-added-1729871688954.md b/packages/ui/.changeset/pr-11125-added-1729871688954.md deleted file mode 100644 index 98553459363..00000000000 --- a/packages/ui/.changeset/pr-11125-added-1729871688954.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/ui": Added ---- - -Tooltip component and story ([#11125](https://github.com/linode/manager/pull/11125)) diff --git a/packages/ui/.changeset/pr-11138-upcoming-features-1730101798188.md b/packages/ui/.changeset/pr-11138-upcoming-features-1730101798188.md deleted file mode 100644 index bb0bd1164c4..00000000000 --- a/packages/ui/.changeset/pr-11138-upcoming-features-1730101798188.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/ui": Upcoming Features ---- - -Add Alias tokens to theme ([#11138](https://github.com/linode/manager/pull/11138)) diff --git a/packages/ui/.changeset/pr-11157-tech-stories-1729787461166.md b/packages/ui/.changeset/pr-11157-tech-stories-1729787461166.md deleted file mode 100644 index 92c48e1e383..00000000000 --- a/packages/ui/.changeset/pr-11157-tech-stories-1729787461166.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/ui": Tech Stories ---- - -Remove `@types/node` dependency ([#11157](https://github.com/linode/manager/pull/11157)) diff --git a/packages/ui/.changeset/pr-11158-added-1729864026236.md b/packages/ui/.changeset/pr-11158-added-1729864026236.md deleted file mode 100644 index 0f0762718da..00000000000 --- a/packages/ui/.changeset/pr-11158-added-1729864026236.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/ui": Added ---- - -IconButton component ([#11158](https://github.com/linode/manager/pull/11158)) diff --git a/packages/ui/.changeset/pr-11159-added-1729806253949.md b/packages/ui/.changeset/pr-11159-added-1729806253949.md deleted file mode 100644 index f6fdef00aaf..00000000000 --- a/packages/ui/.changeset/pr-11159-added-1729806253949.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/ui": Added ---- - -Migrate `FormControl`, `FormHelperText`, `Input`, `InputAdornment`, and `InputLabel` from `manager` to `ui` package ([#11159](https://github.com/linode/manager/pull/11159)) diff --git a/packages/ui/.changeset/pr-11163-added-1729870035646.md b/packages/ui/.changeset/pr-11163-added-1729870035646.md deleted file mode 100644 index 715546f8923..00000000000 --- a/packages/ui/.changeset/pr-11163-added-1729870035646.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/ui": Added ---- - -`Box` component from `manager` to `ui` package, part 1 ([#11163](https://github.com/linode/manager/pull/11163)) diff --git a/packages/ui/.changeset/pr-11164-added-1729871599808.md b/packages/ui/.changeset/pr-11164-added-1729871599808.md deleted file mode 100644 index bf250e40f84..00000000000 --- a/packages/ui/.changeset/pr-11164-added-1729871599808.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/ui": Added ---- - -`Box` component from `manager` to `ui` package, part 2 ([#11164](https://github.com/linode/manager/pull/11164)) diff --git a/packages/ui/.changeset/pr-11174-added-1730757183801.md b/packages/ui/.changeset/pr-11174-added-1730757183801.md new file mode 100644 index 00000000000..13ad8e0ff69 --- /dev/null +++ b/packages/ui/.changeset/pr-11174-added-1730757183801.md @@ -0,0 +1,5 @@ +--- +"@linode/ui": Added +--- + +Move `Notice` and `Tooltip` components to UI package ([#11174](https://github.com/linode/manager/pull/11174)) diff --git a/packages/ui/.changeset/pr-11183-added-1730215173323.md b/packages/ui/.changeset/pr-11183-added-1730215173323.md deleted file mode 100644 index c5a6464588a..00000000000 --- a/packages/ui/.changeset/pr-11183-added-1730215173323.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/ui": Added ---- - -Migrate `Paper` from `manager` to `ui` package ([#11183](https://github.com/linode/manager/pull/11183)) diff --git a/packages/ui/.changeset/pr-11205-added-1730725947069.md b/packages/ui/.changeset/pr-11205-added-1730725947069.md new file mode 100644 index 00000000000..ea4ab9ebe4c --- /dev/null +++ b/packages/ui/.changeset/pr-11205-added-1730725947069.md @@ -0,0 +1,5 @@ +--- +"@linode/ui": Added +--- + +Migrate Divider to ui package ([#11205](https://github.com/linode/manager/pull/11205)) diff --git a/packages/ui/.changeset/pr-11228-added-1730992441169.md b/packages/ui/.changeset/pr-11228-added-1730992441169.md new file mode 100644 index 00000000000..7ff25354ed9 --- /dev/null +++ b/packages/ui/.changeset/pr-11228-added-1730992441169.md @@ -0,0 +1,5 @@ +--- +"@linode/ui": Added +--- + +`Stack` component to `ui` package ([#11228](https://github.com/linode/manager/pull/11228)) diff --git a/packages/ui/.eslintrc.json b/packages/ui/.eslintrc.json index 3388926d8ea..c3e7d4466ad 100644 --- a/packages/ui/.eslintrc.json +++ b/packages/ui/.eslintrc.json @@ -56,7 +56,7 @@ "@typescript-eslint/no-explicit-any": "off", "@typescript-eslint/no-use-before-define": "off", "@typescript-eslint/interface-name-prefix": "off", - "sonarjs/cognitive-complexity": "warn", + "sonarjs/cognitive-complexity": "off", "sonarjs/no-duplicate-string": "warn", "sonarjs/prefer-immediate-return": "warn", "sonarjs/no-identical-functions": "warn", diff --git a/packages/ui/CHANGELOG.md b/packages/ui/CHANGELOG.md index 2cd676b2c6c..95daf390d8c 100644 --- a/packages/ui/CHANGELOG.md +++ b/packages/ui/CHANGELOG.md @@ -1,3 +1,23 @@ +## [2024-11-12] - v0.3.0 + +### Added: + +- Tooltip component and story ([#11125](https://github.com/linode/manager/pull/11125)) +- IconButton component ([#11158](https://github.com/linode/manager/pull/11158)) +- VisibilityIcon component and story ([#11143](https://github.com/linode/manager/pull/11143)) +- Migrate `FormControl`, `FormHelperText`, `Input`, `InputAdornment`, and `InputLabel` from `manager` to `ui` package ([#11159](https://github.com/linode/manager/pull/11159)) +- `Box` component from `manager` to `ui` package, part 1 ([#11163](https://github.com/linode/manager/pull/11163)) +- `Box` component from `manager` to `ui` package, part 2 ([#11164](https://github.com/linode/manager/pull/11164)) +- Migrate `Paper` from `manager` to `ui` package ([#11183](https://github.com/linode/manager/pull/11183)) + +### Tech Stories: + +- Remove `@types/node` dependency ([#11157](https://github.com/linode/manager/pull/11157)) + +### Upcoming Features: + +- Add Alias tokens to theme ([#11138](https://github.com/linode/manager/pull/11138)) + ## [2024-10-28] - v0.2.0 diff --git a/packages/ui/package.json b/packages/ui/package.json index 11fa556f13e..f4bac6c85eb 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -2,7 +2,7 @@ "name": "@linode/ui", "author": "Linode", "description": "Linode UI component library", - "version": "0.2.0", + "version": "0.3.0", "type": "module", "main": "src/index.ts", "module": "src/index.ts", diff --git a/packages/manager/src/assets/icons/alert.svg b/packages/ui/src/assets/icons/alert.svg similarity index 100% rename from packages/manager/src/assets/icons/alert.svg rename to packages/ui/src/assets/icons/alert.svg diff --git a/packages/manager/src/assets/icons/check.svg b/packages/ui/src/assets/icons/check.svg similarity index 100% rename from packages/manager/src/assets/icons/check.svg rename to packages/ui/src/assets/icons/check.svg diff --git a/packages/ui/src/assets/icons/index.ts b/packages/ui/src/assets/icons/index.ts new file mode 100644 index 00000000000..0103e50c33e --- /dev/null +++ b/packages/ui/src/assets/icons/index.ts @@ -0,0 +1,3 @@ +export { default as AlertIcon } from './alert.svg'; +export { default as CheckIcon } from './check.svg'; +export { default as WarningIcon } from './warning.svg'; diff --git a/packages/manager/src/assets/icons/warning.svg b/packages/ui/src/assets/icons/warning.svg similarity index 100% rename from packages/manager/src/assets/icons/warning.svg rename to packages/ui/src/assets/icons/warning.svg diff --git a/packages/ui/src/assets/index.ts b/packages/ui/src/assets/index.ts new file mode 100644 index 00000000000..838008a0b2f --- /dev/null +++ b/packages/ui/src/assets/index.ts @@ -0,0 +1 @@ +export * from './icons'; diff --git a/packages/manager/src/components/Divider.stories.tsx b/packages/ui/src/components/Divider/Divider.stories.tsx similarity index 73% rename from packages/manager/src/components/Divider.stories.tsx rename to packages/ui/src/components/Divider/Divider.stories.tsx index 52619e8223f..364e02f1308 100644 --- a/packages/manager/src/components/Divider.stories.tsx +++ b/packages/ui/src/components/Divider/Divider.stories.tsx @@ -1,7 +1,7 @@ import { Meta, StoryObj } from '@storybook/react'; import React from 'react'; -import { Divider } from 'src/components/Divider'; +import { Divider } from './Divider'; const meta: Meta = { component: Divider, @@ -11,6 +11,12 @@ const meta: Meta = { type Story = StoryObj; export const Default: Story = { + args: { + absolute: false, + light: true, + variant: 'inset', + }, + render: (args) => , }; diff --git a/packages/manager/src/components/Divider.tsx b/packages/ui/src/components/Divider/Divider.tsx similarity index 88% rename from packages/manager/src/components/Divider.tsx rename to packages/ui/src/components/Divider/Divider.tsx index 6186797e1e3..202d428a716 100644 --- a/packages/manager/src/components/Divider.tsx +++ b/packages/ui/src/components/Divider/Divider.tsx @@ -1,9 +1,8 @@ -import { omittedProps } from '@linode/ui'; import _Divider from '@mui/material/Divider'; import { styled } from '@mui/material/styles'; import * as React from 'react'; - import type { DividerProps as _DividerProps } from '@mui/material/Divider'; +import { omittedProps } from '../../utilities'; export interface DividerProps extends _DividerProps { dark?: boolean; @@ -24,7 +23,7 @@ const StyledDivider = styled(_Divider, { 'light', 'dark', ]), -})(({ theme, ...props }) => ({ +})(({ ...props }) => ({ marginBottom: props.spacingBottom, marginTop: props.spacingTop, })); diff --git a/packages/ui/src/components/Divider/index.ts b/packages/ui/src/components/Divider/index.ts new file mode 100644 index 00000000000..1f84888dc70 --- /dev/null +++ b/packages/ui/src/components/Divider/index.ts @@ -0,0 +1 @@ +export * from './Divider'; diff --git a/packages/ui/src/components/IconButton.tsx b/packages/ui/src/components/IconButton/IconButton.tsx similarity index 100% rename from packages/ui/src/components/IconButton.tsx rename to packages/ui/src/components/IconButton/IconButton.tsx diff --git a/packages/ui/src/components/IconButton/index.ts b/packages/ui/src/components/IconButton/index.ts new file mode 100644 index 00000000000..1a85f0f7251 --- /dev/null +++ b/packages/ui/src/components/IconButton/index.ts @@ -0,0 +1 @@ +export * from './IconButton'; diff --git a/packages/manager/src/components/Notice/Notice.stories.tsx b/packages/ui/src/components/Notice/Notice.stories.tsx similarity index 100% rename from packages/manager/src/components/Notice/Notice.stories.tsx rename to packages/ui/src/components/Notice/Notice.stories.tsx diff --git a/packages/manager/src/components/Notice/Notice.styles.ts b/packages/ui/src/components/Notice/Notice.styles.ts similarity index 100% rename from packages/manager/src/components/Notice/Notice.styles.ts rename to packages/ui/src/components/Notice/Notice.styles.ts diff --git a/packages/manager/src/components/Notice/Notice.test.tsx b/packages/ui/src/components/Notice/Notice.test.tsx similarity index 96% rename from packages/manager/src/components/Notice/Notice.test.tsx rename to packages/ui/src/components/Notice/Notice.test.tsx index e7d536cd907..3e1e343d900 100644 --- a/packages/manager/src/components/Notice/Notice.test.tsx +++ b/packages/ui/src/components/Notice/Notice.test.tsx @@ -1,9 +1,9 @@ import { fireEvent } from '@testing-library/react'; import React from 'react'; -import { renderWithTheme } from 'src/utilities/testHelpers'; - import { Notice } from './Notice'; +import { expect, describe, it, vi } from 'vitest'; +import { renderWithTheme } from '../../utilities/testHelpers'; describe('Notice Component', () => { it('renders without errors with proper spacing', () => { diff --git a/packages/manager/src/components/Notice/Notice.tsx b/packages/ui/src/components/Notice/Notice.tsx similarity index 92% rename from packages/manager/src/components/Notice/Notice.tsx rename to packages/ui/src/components/Notice/Notice.tsx index 55d7950def6..a75c8f428b7 100644 --- a/packages/manager/src/components/Notice/Notice.tsx +++ b/packages/ui/src/components/Notice/Notice.tsx @@ -1,15 +1,14 @@ import Grid from '@mui/material/Unstable_Grid2'; import * as React from 'react'; -import Error from 'src/assets/icons/alert.svg'; -import Check from 'src/assets/icons/check.svg'; -import Warning from 'src/assets/icons/warning.svg'; -import { Typography } from 'src/components/Typography'; +import { WarningIcon, AlertIcon as Error, CheckIcon } from '../../assets/icons'; + +import { Typography } from '@mui/material'; import { useStyles } from './Notice.styles'; import type { Grid2Props } from '@mui/material/Unstable_Grid2'; -import type { TypographyProps } from 'src/components/Typography'; +import type { TypographyProps } from '@mui/material'; export type NoticeVariant = | 'error' @@ -181,10 +180,10 @@ export const Notice = (props: NoticeProps) => { > {important && ((variantMap.success && ( - + )) || ((variantMap.warning || variantMap.info) && ( - + )) || (variantMap.error && ( diff --git a/packages/ui/src/components/Notice/index.ts b/packages/ui/src/components/Notice/index.ts new file mode 100644 index 00000000000..c2b2fea9b2b --- /dev/null +++ b/packages/ui/src/components/Notice/index.ts @@ -0,0 +1 @@ +export * from './Notice'; diff --git a/packages/manager/src/components/Stack.stories.tsx b/packages/ui/src/components/Stack/Stack.stories.tsx similarity index 93% rename from packages/manager/src/components/Stack.stories.tsx rename to packages/ui/src/components/Stack/Stack.stories.tsx index 07d01cd91bc..d28537ad374 100644 --- a/packages/manager/src/components/Stack.stories.tsx +++ b/packages/ui/src/components/Stack/Stack.stories.tsx @@ -1,8 +1,8 @@ -import { Paper } from '@linode/ui'; import React from 'react'; -import { Divider } from './Divider'; import { Stack } from './Stack'; +import { Divider } from '../Divider'; +import { Paper } from '../Paper'; import type { Meta, StoryObj } from '@storybook/react'; diff --git a/packages/manager/src/components/Stack.tsx b/packages/ui/src/components/Stack/Stack.tsx similarity index 78% rename from packages/manager/src/components/Stack.tsx rename to packages/ui/src/components/Stack/Stack.tsx index abaec23cbf8..40e4bb915c2 100644 --- a/packages/manager/src/components/Stack.tsx +++ b/packages/ui/src/components/Stack/Stack.tsx @@ -1,6 +1,8 @@ -import { default as _Stack, StackProps } from '@mui/material/Stack'; +import { default as _Stack } from '@mui/material/Stack'; import React from 'react'; +import type { StackProps } from '@mui/material/Stack'; + /** * A Stack is a layout component that uses flexbox to * vertically or horizontally align elements with optional spacing. diff --git a/packages/ui/src/components/Stack/index.ts b/packages/ui/src/components/Stack/index.ts new file mode 100644 index 00000000000..453d31cff2a --- /dev/null +++ b/packages/ui/src/components/Stack/index.ts @@ -0,0 +1 @@ +export * from './Stack'; diff --git a/packages/ui/src/components/index.ts b/packages/ui/src/components/index.ts index d1887cebe1c..377df45a01b 100644 --- a/packages/ui/src/components/index.ts +++ b/packages/ui/src/components/index.ts @@ -1,12 +1,15 @@ export * from './BetaChip'; export * from './Box'; export * from './Chip'; +export * from './Divider'; export * from './FormControl'; export * from './FormHelperText'; export * from './IconButton'; export * from './Input'; export * from './InputAdornment'; export * from './InputLabel'; +export * from './Notice'; export * from './Paper'; +export * from './Stack'; export * from './Tooltip'; export * from './VisibilityTooltip'; diff --git a/packages/ui/src/env.d.ts b/packages/ui/src/env.d.ts new file mode 100644 index 00000000000..f36c722baed --- /dev/null +++ b/packages/ui/src/env.d.ts @@ -0,0 +1,4 @@ +declare module '*.svg' { + const src: ComponentClass; + export default src; +} diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts index 952d61ff3b1..f43dcafbcfd 100644 --- a/packages/ui/src/index.ts +++ b/packages/ui/src/index.ts @@ -1,3 +1,4 @@ +export * from './assets'; export * from './components'; export * from './foundations'; export * from './utilities'; diff --git a/packages/ui/src/utilities/omittedProps.ts b/packages/ui/src/utilities/omittedProps.ts index 330b95f7f02..49af7e93bbd 100644 --- a/packages/ui/src/utilities/omittedProps.ts +++ b/packages/ui/src/utilities/omittedProps.ts @@ -15,10 +15,10 @@ export const omittedProps = (props: Array) => ( ): boolean => !props.includes(prop); /** - * Helper to filter out props we spread into a component. - * This helpers differs from `omittedProps` in that it omits the props - * from the object instead of returning a boolean. - * This util is a direct replacement for `omit` from lodash. + * Helper to filter out props we spread into a component. + * This helpers differs from `omittedProps` in that it omits the props + * from the object instead of returning a boolean. + * This util is a direct replacement for `omit` from lodash. * @param props Array of props to filter out * @param toRemove Array of props to remove diff --git a/packages/ui/src/utilities/testHelpers.tsx b/packages/ui/src/utilities/testHelpers.tsx new file mode 100644 index 00000000000..1fb55370691 --- /dev/null +++ b/packages/ui/src/utilities/testHelpers.tsx @@ -0,0 +1,28 @@ +import { StyledEngineProvider, ThemeProvider } from '@mui/material'; +import { render, RenderResult } from '@testing-library/react'; +import * as React from 'react'; + +import * as themes from '../foundations/themes'; + +interface Options { + theme?: 'dark' | 'light'; +} + +export const wrapWithTheme = (ui: any, options: Options = {}) => ( + + + {ui.children ?? ui} + + +); + +export const renderWithTheme = ( + ui: React.ReactNode, + options: Options = {} +): RenderResult => { + const renderResult = render(wrapWithTheme(ui, options)); + return { + ...renderResult, + rerender: (ui) => renderResult.rerender(wrapWithTheme(ui, options)), + }; +}; diff --git a/packages/ui/testSetup.ts b/packages/ui/testSetup.ts index e42051f8ee3..141cd45f9a4 100644 --- a/packages/ui/testSetup.ts +++ b/packages/ui/testSetup.ts @@ -1,5 +1,8 @@ +import * as matchers from '@testing-library/jest-dom/matchers'; import { cleanup } from '@testing-library/react'; -import { afterEach } from 'vitest'; +import { afterEach, expect } from 'vitest'; + +expect.extend(matchers); afterEach(() => { cleanup(); diff --git a/packages/validation/.changeset/pr-11157-tech-stories-1729787428923.md b/packages/validation/.changeset/pr-11157-tech-stories-1729787428923.md deleted file mode 100644 index c00c591cd64..00000000000 --- a/packages/validation/.changeset/pr-11157-tech-stories-1729787428923.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@linode/validation": Tech Stories ---- - -Remove `@types/node` dependency ([#11157](https://github.com/linode/manager/pull/11157)) diff --git a/packages/validation/CHANGELOG.md b/packages/validation/CHANGELOG.md index f5ca2e4dac9..743ff5202bc 100644 --- a/packages/validation/CHANGELOG.md +++ b/packages/validation/CHANGELOG.md @@ -1,3 +1,10 @@ +## [2024-11-12] - v0.56.0 + + +### Tech Stories: + +- Remove `@types/node` dependency ([#11157](https://github.com/linode/manager/pull/11157)) + ## [2024-10-28] - v0.55.0 diff --git a/packages/validation/package.json b/packages/validation/package.json index 4aaeb1f109f..37f62119cb8 100644 --- a/packages/validation/package.json +++ b/packages/validation/package.json @@ -1,6 +1,6 @@ { "name": "@linode/validation", - "version": "0.55.0", + "version": "0.56.0", "description": "Yup validation schemas for use with the Linode APIv4", "type": "module", "main": "lib/index.cjs", diff --git a/packages/validation/src/databases.schema.ts b/packages/validation/src/databases.schema.ts index 4830427c621..9cc4edd9b7f 100644 --- a/packages/validation/src/databases.schema.ts +++ b/packages/validation/src/databases.schema.ts @@ -14,37 +14,8 @@ export const createDatabaseSchema = object({ cluster_size: number() .oneOf([1, 2, 3], 'Nodes are required') .required('Nodes are required'), - replication_type: string().when('engine', { - is: (engine: string) => Boolean(engine.match(/mysql|postgres/g)), - then: string() - .when('engine', { - is: (engine: string) => Boolean(engine.match(/mysql/)), - then: string().oneOf(['none', 'semi_synch', 'asynch']), - }) - .when('engine', { - is: (engine: string) => Boolean(engine.match(/postgres/)), - then: string().oneOf(['none', 'synch', 'asynch']), - }) - .optional(), - otherwise: string().notRequired().nullable(true), - }), - replication_commit_type: string().when('engine', { - is: (engine: string) => Boolean(engine.match(/postgres/)), - then: string() - .oneOf(['off', 'on', 'local', 'remote_write', 'remote_apply']) - .optional(), - otherwise: string().notRequired().nullable(true), - }), - storage_engine: string().when('engine', { - is: (engine: string) => Boolean(engine.match(/mongodb/)), - then: string().oneOf(['wiredtiger', 'mmapv1']).notRequired(), - otherwise: string().notRequired().nullable(true), - }), - compression_type: string().when('engine', { - is: (engine: string) => Boolean(engine.match(/mongodb/)), - then: string().oneOf(['none', 'snappy', 'zlib']).notRequired(), - otherwise: string().notRequired().nullable(true), - }), + replication_type: string().notRequired().nullable(true), // TODO (UIE-8214) remove POST GA + replication_commit_type: string().notRequired().nullable(true), // TODO (UIE-8214) remove POST GA }); export const updateDatabaseSchema = object({