diff --git a/ui/.betterer.results b/ui/.betterer.results index 6487e82e39..c0a7eb37ad 100644 --- a/ui/.betterer.results +++ b/ui/.betterer.results @@ -7,6 +7,7 @@ exports[`stricter compilation`] = { [162, 4, 36, "Object is possibly \'null\'.", "1039669632"] ], "src/app/App.tsx:2048624384": [ + [21, 7, 25, "Could not find a declaration file for module \'@maas-ui/maas-ui-shared\'. \'/home/caleb/Projects/maas-ui/shared/dist/index.js\' implicitly has an \'any\' type.\\n Try \`npm install @types/maas-ui__maas-ui-shared\` if it exists or add a new declaration (.d.ts) file containing \`declare module \'@maas-ui/maas-ui-shared\';\`", "1778274862"], [188, 17, 17, "Object is possibly \'null\'.", "2133029343"], [193, 7, 7, "Variable \'content\' is used before being assigned.", "3716929964"] ], @@ -41,6 +42,9 @@ exports[`stricter compilation`] = { "src/app/base/components/FormikForm/FormikForm.tsx:1590075926": [ [77, 4, 5, "Argument of type \'boolean | undefined\' is not assignable to parameter of type \'boolean\'.\\n Type \'undefined\' is not assignable to type \'boolean\'.", "195688512"] ], + "src/app/base/components/LegacyLink/LegacyLink.tsx:2706551295": [ + [4, 52, 25, "Could not find a declaration file for module \'@maas-ui/maas-ui-shared\'. \'/home/caleb/Projects/maas-ui/shared/dist/index.js\' implicitly has an \'any\' type.\\n Try \`npm install @types/maas-ui__maas-ui-shared\` if it exists or add a new declaration (.d.ts) file containing \`declare module \'@maas-ui/maas-ui-shared\';\`", "1778274862"] + ], "src/app/base/components/NotificationGroup/Notification/Notification.tsx:122297593": [ [26, 26, 12, "Argument of type \'Notification | null\' is not assignable to parameter of type \'Notification\'.\\n Type \'null\' is not assignable to type \'Notification\'.\\n Type \'null\' is not assignable to type \'Model\'.", "148512008"], [31, 8, 12, "Object is possibly \'null\'.", "148512008"], @@ -81,7 +85,7 @@ exports[`stricter compilation`] = { [214, 7, 11, "Property \'placeholder\' is missing in type \'{ disabledTags: { id: number; name: string; }[]; initialSelected: { id: number; name: string; }[]; tags: { id: number; name: string; }[]; }\' but required in type \'Props\'.", "3766634306"] ], "src/app/base/components/TagSelector/TagSelector.tsx:2755544058": [ - [1, 18, 51, "Could not find a declaration file for module \'@canonical/react-components/dist/components/Field\'. \'/home/multipass/code/maas-ui/node_modules/@canonical/react-components/dist/components/Field/index.js\' implicitly has an \'any\' type.\\n Try \`npm install @types/canonical__react-components\` if it exists or add a new declaration (.d.ts) file containing \`declare module \'@canonical/react-components/dist/components/Field\';\`", "1535046059"], + [1, 18, 51, "Could not find a declaration file for module \'@canonical/react-components/dist/components/Field\'. \'/home/caleb/Projects/maas-ui/node_modules/@canonical/react-components/dist/components/Field/index.js\' implicitly has an \'any\' type.\\n Try \`npm install @types/canonical__react-components\` if it exists or add a new declaration (.d.ts) file containing \`declare module \'@canonical/react-components/dist/components/Field\';\`", "1535046059"], [37, 2, 12, "Binding element \'allowNewTags\' implicitly has an \'any\' type.", "3979358209"], [38, 2, 6, "Binding element \'filter\' implicitly has an \'any\' type.", "1355726373"], [39, 2, 12, "Binding element \'selectedTags\' implicitly has an \'any\' type.", "2698915821"], @@ -347,16 +351,19 @@ exports[`stricter compilation`] = { "src/app/machines/views/MachineDetails/MachineSummary/NumaCard/NumaCard.test.tsx:2502469861": [ [33, 27, 10, "Property \'numa_nodes\' does not exist on type \'Machine\'.\\n Property \'numa_nodes\' does not exist on type \'BaseMachine\'.", "3857696382"] ], - "src/app/machines/views/MachineDetails/MachineSummary/TestResults/TestResults.tsx:247086798": [ + "src/app/machines/views/MachineDetails/MachineSummary/OverviewCard/DetailsCard/DetailsCard.tsx:2883346391": [ + [4, 33, 25, "Could not find a declaration file for module \'@maas-ui/maas-ui-shared\'. \'/home/caleb/Projects/maas-ui/shared/dist/index.js\' implicitly has an \'any\' type.\\n Try \`npm install @types/maas-ui__maas-ui-shared\` if it exists or add a new declaration (.d.ts) file containing \`declare module \'@maas-ui/maas-ui-shared\';\`", "1778274862"] + ], + "src/app/machines/views/MachineDetails/MachineSummary/TestResults/TestResults.tsx:3588892375": [ [18, 18, 36, "Element implicitly has an \'any\' type because expression of type \'string\' can\'t be used to index type \'MachineDetails\'.\\n No index signature with a parameter of type \'string\' was found on type \'MachineDetails\'.", "830072625"], [37, 9, 36, "Element implicitly has an \'any\' type because expression of type \'string\' can\'t be used to index type \'MachineDetails\'.\\n No index signature with a parameter of type \'string\' was found on type \'MachineDetails\'.", "830072625"], - [50, 15, 36, "Element implicitly has an \'any\' type because expression of type \'string\' can\'t be used to index type \'MachineDetails\'.\\n No index signature with a parameter of type \'string\' was found on type \'MachineDetails\'.", "830072625"], - [55, 9, 36, "Element implicitly has an \'any\' type because expression of type \'string\' can\'t be used to index type \'MachineDetails\'.\\n No index signature with a parameter of type \'string\' was found on type \'MachineDetails\'.", "830072625"], - [56, 10, 36, "Element implicitly has an \'any\' type because expression of type \'string\' can\'t be used to index type \'MachineDetails\'.\\n No index signature with a parameter of type \'string\' was found on type \'MachineDetails\'.", "830072625"], - [70, 15, 36, "Element implicitly has an \'any\' type because expression of type \'string\' can\'t be used to index type \'MachineDetails\'.\\n No index signature with a parameter of type \'string\' was found on type \'MachineDetails\'.", "830072625"], - [71, 16, 36, "Element implicitly has an \'any\' type because expression of type \'string\' can\'t be used to index type \'MachineDetails\'.\\n No index signature with a parameter of type \'string\' was found on type \'MachineDetails\'.", "830072625"], - [76, 9, 36, "Element implicitly has an \'any\' type because expression of type \'string\' can\'t be used to index type \'MachineDetails\'.\\n No index signature with a parameter of type \'string\' was found on type \'MachineDetails\'.", "830072625"], - [89, 15, 36, "Element implicitly has an \'any\' type because expression of type \'string\' can\'t be used to index type \'MachineDetails\'.\\n No index signature with a parameter of type \'string\' was found on type \'MachineDetails\'.", "830072625"] + [51, 17, 36, "Element implicitly has an \'any\' type because expression of type \'string\' can\'t be used to index type \'MachineDetails\'.\\n No index signature with a parameter of type \'string\' was found on type \'MachineDetails\'.", "830072625"], + [57, 9, 36, "Element implicitly has an \'any\' type because expression of type \'string\' can\'t be used to index type \'MachineDetails\'.\\n No index signature with a parameter of type \'string\' was found on type \'MachineDetails\'.", "830072625"], + [58, 10, 36, "Element implicitly has an \'any\' type because expression of type \'string\' can\'t be used to index type \'MachineDetails\'.\\n No index signature with a parameter of type \'string\' was found on type \'MachineDetails\'.", "830072625"], + [73, 17, 36, "Element implicitly has an \'any\' type because expression of type \'string\' can\'t be used to index type \'MachineDetails\'.\\n No index signature with a parameter of type \'string\' was found on type \'MachineDetails\'.", "830072625"], + [74, 18, 36, "Element implicitly has an \'any\' type because expression of type \'string\' can\'t be used to index type \'MachineDetails\'.\\n No index signature with a parameter of type \'string\' was found on type \'MachineDetails\'.", "830072625"], + [80, 9, 36, "Element implicitly has an \'any\' type because expression of type \'string\' can\'t be used to index type \'MachineDetails\'.\\n No index signature with a parameter of type \'string\' was found on type \'MachineDetails\'.", "830072625"], + [94, 17, 36, "Element implicitly has an \'any\' type because expression of type \'string\' can\'t be used to index type \'MachineDetails\'.\\n No index signature with a parameter of type \'string\' was found on type \'MachineDetails\'.", "830072625"] ], "src/app/machines/views/MachineList/MachineListHeader/MachineListHeader.tsx:539216384": [ [104, 10, 17, "Type \'(action: MachineAction, deselect?: boolean | undefined) => void\' is not assignable to type \'SetSelectedAction\'.\\n Types of parameters \'action\' and \'action\' are incompatible.\\n Type \'SelectedAction | null\' is not assignable to type \'MachineAction\'.\\n Type \'null\' is not assignable to type \'MachineAction\'.", "167402512"], @@ -383,6 +390,9 @@ exports[`stricter compilation`] = { [87, 4, 39, "Cannot invoke an object which is possibly \'undefined\'.", "2019447570"], [92, 6, 24, "Expected 1 arguments, but got 2.", "3437019925"] ], + "src/app/settings/views/Configuration/GeneralForm/GeneralForm.tsx:227377903": [ + [5, 34, 25, "Could not find a declaration file for module \'@maas-ui/maas-ui-shared\'. \'/home/caleb/Projects/maas-ui/shared/dist/index.js\' implicitly has an \'any\' type.\\n Try \`npm install @types/maas-ui__maas-ui-shared\` if it exists or add a new declaration (.d.ts) file containing \`declare module \'@maas-ui/maas-ui-shared\';\`", "1778274862"] + ], "src/app/settings/views/LicenseKeys/LicenseKeyList/LicenseKeyList.test.tsx:3551628603": [ [25, 10, 4, "Type \'{ osystems: [string, string][]; releases: [string, string][]; }\' is missing the following properties from type \'OSInfo\': kernels, default_osystem, default_release", "2087377941"] ], @@ -509,7 +519,7 @@ exports[`stricter compilation`] = { [233, 2, 4, "Type \'null\' is not assignable to type \'OSInfo | ArrayFactory | AttributeFunction | Factory | DerivedFunction\'.", "2087377941"], [312, 2, 6, "Type \'null\' is not assignable to type \'string | ArrayFactory | AttributeFunction | Factory | DerivedFunction, string>\'.", "2158674347"], [314, 2, 4, "Type \'null\' is not assignable to type \'string | ArrayFactory | AttributeFunction | Factory | DerivedFunction, string>\'.", "2087809207"], - [319, 2, 6, "Type \'null\' is not assignable to type \'\\"PUSH\\" | \\"POP\\" | \\"REPLACE\\" | ArrayFactory | AttributeFunction | Factory | DerivedFunction, Action>\'.", "1314712411"] + [319, 2, 6, "Type \'null\' is not assignable to type \'ArrayFactory | \\"PUSH\\" | \\"POP\\" | \\"REPLACE\\" | AttributeFunction | Factory | DerivedFunction, Action>\'.", "1314712411"] ] }` }; diff --git a/ui/src/app/machines/views/MachineDetails/MachineSummary/NetworkCard/NetworkCard.tsx b/ui/src/app/machines/views/MachineDetails/MachineSummary/NetworkCard/NetworkCard.tsx index 2ba4bf06a6..755ba1a48b 100644 --- a/ui/src/app/machines/views/MachineDetails/MachineSummary/NetworkCard/NetworkCard.tsx +++ b/ui/src/app/machines/views/MachineDetails/MachineSummary/NetworkCard/NetworkCard.tsx @@ -144,11 +144,10 @@ const NetworkCard = ({ id, setSelectedAction }: Props): JSX.Element => { ))} - +

Information about tagged traffic can be seen in the{" "} Network tab. - - +

{ const machine = useSelector((state: RootState) => machineSelectors.getById(state, id) ); - let content: JSX.Element; + let numaNodeString = "NUMA node"; + let content: JSX.Element | null; // Confirm that the full machine details have been fetched. This also allows // TypeScript know we're using the right union type (otherwise it will @@ -25,35 +26,32 @@ const NumaCard = ({ id }: Props): JSX.Element => { content = ; } else { const numaNodes = machine.numa_nodes; - content = ( - <> - - {pluralize("NUMA node", numaNodes.length, true)} - -
- {numaNodes.length ? ( - ({ - className: "numa-card", - content: ( - - ), - }))} - /> - ) : null} - - ); + numaNodeString = pluralize("NUMA node", numaNodes.length, true); + content = numaNodes.length ? ( + ({ + className: "numa-card", + content: ( + + ), + }))} + /> + ) : null; } return (
- {content} + + {numaNodeString} +
+ {content} +
); }; diff --git a/ui/src/app/machines/views/MachineDetails/MachineSummary/OverviewCard/OverviewCard.tsx b/ui/src/app/machines/views/MachineDetails/MachineSummary/OverviewCard/OverviewCard.tsx index e9d5b042d6..b42199d49a 100644 --- a/ui/src/app/machines/views/MachineDetails/MachineSummary/OverviewCard/OverviewCard.tsx +++ b/ui/src/app/machines/views/MachineDetails/MachineSummary/OverviewCard/OverviewCard.tsx @@ -28,7 +28,11 @@ const OverviewCard = ({ id, setSelectedAction }: Props): JSX.Element => { // TypeScript know we're using the right union type (otherwise it will // complain that metadata doesn't exist on the base machine type). if (!machine || !("metadata" in machine)) { - content = ; + content = ( +
+ +
+ ); } else { content = (
diff --git a/ui/src/app/machines/views/MachineDetails/MachineSummary/OverviewCard/StatusCard/StatusCard.tsx b/ui/src/app/machines/views/MachineDetails/MachineSummary/OverviewCard/StatusCard/StatusCard.tsx index 749c4a60d3..f1ab798141 100644 --- a/ui/src/app/machines/views/MachineDetails/MachineSummary/OverviewCard/StatusCard/StatusCard.tsx +++ b/ui/src/app/machines/views/MachineDetails/MachineSummary/OverviewCard/StatusCard/StatusCard.tsx @@ -32,36 +32,40 @@ const showFailedTestsWarning = (machine: MachineDetails) => { const StatusCard = ({ machine }: Props): JSX.Element => { return ( -
- - {isVM(machine) ? "Virtual Machine Status" : "Machine Status"} - + <> +
+ + {isVM(machine) ? "Virtual Machine Status" : "Machine Status"} + -

- {machine.locked ? ( - - Locked:{" "} - - ) : null} - {machine.status} -

- - {machine.show_os_info ? ( -

- {`${machine.osystem}/${machine.distro_series}`} -

- ) : null} +

+ {machine.locked ? ( + + Locked:{" "} + + ) : null} + {machine.status} +

+ {machine.show_os_info ? ( +

+ {`${machine.osystem}/${machine.distro_series}`} +

+ ) : null} +
{showFailedTestsWarning(machine) ? (
- Warning: Some tests failed, use - with caution. + Warning: + + {" "} + Some tests failed, use with caution. +
) : null} -
+ ); }; diff --git a/ui/src/app/machines/views/MachineDetails/MachineSummary/OverviewCard/StorageCard/StorageCard.tsx b/ui/src/app/machines/views/MachineDetails/MachineSummary/OverviewCard/StorageCard/StorageCard.tsx index 8e29354f3f..77ed21e3bc 100644 --- a/ui/src/app/machines/views/MachineDetails/MachineSummary/OverviewCard/StorageCard/StorageCard.tsx +++ b/ui/src/app/machines/views/MachineDetails/MachineSummary/OverviewCard/StorageCard/StorageCard.tsx @@ -16,11 +16,11 @@ const StorageCard = ({ machine, setSelectedAction }: Props): JSX.Element => (
Storage

- {machine.storage ? `${machine.storage}GB` : "Unknown"} + {machine.storage ? `${machine.storage} GB` : "Unknown"} {machine.storage && machine.physical_disk_count ? ( - +  over {pluralize("disk", machine.physical_disk_count, true)} - + ) : null}

diff --git a/ui/src/app/machines/views/MachineDetails/MachineSummary/OverviewCard/_index.scss b/ui/src/app/machines/views/MachineDetails/MachineSummary/OverviewCard/_index.scss index aa4a7ca85e..ce2b4a00ee 100644 --- a/ui/src/app/machines/views/MachineDetails/MachineSummary/OverviewCard/_index.scss +++ b/ui/src/app/machines/views/MachineDetails/MachineSummary/OverviewCard/_index.scss @@ -114,39 +114,6 @@ } } - @media only screen and (max-width: $breakpoint-x-large) { - grid: - [row1-start] "cpu cpu cpu memory memory memory storage storage storage" min-content [row1-end] - [row2-start] "cpu-tests cpu-tests cpu-tests memory-tests memory-tests memory-tests storage-tests storage-tests storage-tests" min-content [row2-end] - [row3-start] "status status details details details details details details details" min-content [row3-end] - [row4-start] "status test-warning test-warning test-warning test-warning test-warning test-warning test-warning" min-content [row4-end] - / 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr; - - .overview-card__cpu { - padding: $spv-inner--large 0 $spv-inner--large $sph-inner; - } - - .overview-card__cpu-tests { - padding: $spv-inner--large 0 $spv-inner--large $sph-inner; - &::after { - content: none; - } - } - - .overview-card__overview { - @include pseudo-border(top); - padding: $spv-inner--large 0 $spv-inner--large $sph-inner; - &::before { - right: -#{map-get($grid-gutter-widths, large)}; - } - } - - .overview-card__test-warning { - @include pseudo-border(top); - padding: $spv-inner--large $sph-inner $spv-inner--large 0; - } - } - @media only screen and (max-width: $breakpoint-large) { grid: [row1-start] "status cpu" min-content [row1-end] @@ -253,4 +220,11 @@ } } } + + .overview-card__placeholder { + align-items: center; + display: flex; + height: 10rem; + justify-content: center; + } } diff --git a/ui/src/app/machines/views/MachineDetails/MachineSummary/SummaryNotifications/SummaryNotifications.test.tsx b/ui/src/app/machines/views/MachineDetails/MachineSummary/SummaryNotifications/SummaryNotifications.test.tsx index 2ceb606e09..33e905d09e 100644 --- a/ui/src/app/machines/views/MachineDetails/MachineSummary/SummaryNotifications/SummaryNotifications.test.tsx +++ b/ui/src/app/machines/views/MachineDetails/MachineSummary/SummaryNotifications/SummaryNotifications.test.tsx @@ -26,6 +26,7 @@ describe("SummaryNotifications", () => { general: generalStateFactory({ architectures: architecturesStateFactory({ data: ["amd64"], + loaded: true, }), powerTypes: powerTypesStateFactory({ data: [powerTypeFactory()], @@ -142,6 +143,7 @@ describe("SummaryNotifications", () => { it("can display a boot images error", () => { state.general.architectures = architecturesStateFactory({ data: [], + loaded: true, }); const store = mockStore(state); const wrapper = mount( diff --git a/ui/src/app/machines/views/MachineDetails/MachineSummary/SummaryNotifications/SummaryNotifications.tsx b/ui/src/app/machines/views/MachineDetails/MachineSummary/SummaryNotifications/SummaryNotifications.tsx index c5b0a4944c..7695a1750c 100644 --- a/ui/src/app/machines/views/MachineDetails/MachineSummary/SummaryNotifications/SummaryNotifications.tsx +++ b/ui/src/app/machines/views/MachineDetails/MachineSummary/SummaryNotifications/SummaryNotifications.tsx @@ -1,5 +1,4 @@ import { Link } from "react-router-dom"; -import { Spinner } from "@canonical/react-components"; import { useDispatch, useSelector } from "react-redux"; import React, { useEffect } from "react"; @@ -34,12 +33,15 @@ const formatEventText = (event: Event) => { return text.join(" - "); }; -const SummaryNotifications = ({ id }: Props): JSX.Element => { +const SummaryNotifications = ({ id }: Props): JSX.Element | null => { const dispatch = useDispatch(); const machine = useSelector((state: RootState) => machineSelectors.getById(state, id) ); const architectures = useSelector(generalSelectors.architectures.get); + const architecturesLoaded = useSelector( + generalSelectors.architectures.loaded + ); const hasUsableArchitectures = architectures.length > 0; const canEdit = useCanEdit(machine, true); const isRackControllerConnected = useIsRackControllerConnected(); @@ -52,8 +54,8 @@ const SummaryNotifications = ({ id }: Props): JSX.Element => { // Confirm that the full machine details have been fetched. This also allows // TypeScript know we're using the right union type (otherwise it will // complain that events don't exist on the base machine type). - if (!machine || !("events" in machine)) { - return ; + if (!machine || !("events" in machine) || !architecturesLoaded) { + return null; } return ( diff --git a/ui/src/app/machines/views/MachineDetails/MachineSummary/SystemCard/SystemCard.tsx b/ui/src/app/machines/views/MachineDetails/MachineSummary/SystemCard/SystemCard.tsx index aafa77c9df..06ac4bdd0e 100644 --- a/ui/src/app/machines/views/MachineDetails/MachineSummary/SystemCard/SystemCard.tsx +++ b/ui/src/app/machines/views/MachineDetails/MachineSummary/SystemCard/SystemCard.tsx @@ -25,8 +25,6 @@ const SystemCard = ({ id }: Props): JSX.Element => { } else { content = ( <> - System -
{ ); } - return {content}; + return ( + + System +
+ {content} +
+ ); }; export default SystemCard; diff --git a/ui/src/app/machines/views/MachineDetails/MachineSummary/TestResults/TestResults.tsx b/ui/src/app/machines/views/MachineDetails/MachineSummary/TestResults/TestResults.tsx index 225bddb353..76ef135ea2 100644 --- a/ui/src/app/machines/views/MachineDetails/MachineSummary/TestResults/TestResults.tsx +++ b/ui/src/app/machines/views/MachineDetails/MachineSummary/TestResults/TestResults.tsx @@ -48,7 +48,9 @@ const TestResults = ({ } > - {machine[`${scriptType}_test_status`].passed} + + {machine[`${scriptType}_test_status`].passed} + ) : null} @@ -68,8 +70,10 @@ const TestResults = ({ } > - {machine[`${scriptType}_test_status`].pending + - machine[`${scriptType}_test_status`].running} + + {machine[`${scriptType}_test_status`].pending + + machine[`${scriptType}_test_status`].running} + ) : null} @@ -87,7 +91,9 @@ const TestResults = ({ } > - {machine[`${scriptType}_test_status`].failed} + + {machine[`${scriptType}_test_status`].failed} + ) : null} diff --git a/ui/src/app/machines/views/MachineDetails/MachineSummary/_index.scss b/ui/src/app/machines/views/MachineDetails/MachineSummary/_index.scss index 3cef773dd0..b57be0c99d 100644 --- a/ui/src/app/machines/views/MachineDetails/MachineSummary/_index.scss +++ b/ui/src/app/machines/views/MachineDetails/MachineSummary/_index.scss @@ -36,6 +36,7 @@ .machine-summary__overview-card { grid-area: overview-card; + padding: 0; } .machine-summary__system-card { diff --git a/ui/src/scss/_utilities.scss b/ui/src/scss/_utilities.scss index 7405a74300..6b4d9a201b 100644 --- a/ui/src/scss/_utilities.scss +++ b/ui/src/scss/_utilities.scss @@ -71,6 +71,10 @@ padding-right: $sph-inner--small !important; } + .u-nudge-left--x-small { + padding-right: $sp-x-small !important; + } + .u-nudge-right { padding-left: $sph-inner !important; } @@ -79,6 +83,10 @@ padding-left: $sph-inner--small !important; } + .u-nudge-right--x-small { + padding-left: $sp-x-small !important; + } + .u-text--light { color: $color-mid-dark !important; }