Skip to content

Commit

Permalink
Merge pull request #709 from barrymcgee/panel-tables
Browse files Browse the repository at this point in the history
Enable panel tables on model details page
  • Loading branch information
barrymcgee authored Oct 16, 2020
2 parents 6ae0f5d + 6d65f9e commit a19319a
Show file tree
Hide file tree
Showing 11 changed files with 369 additions and 281 deletions.
4 changes: 2 additions & 2 deletions src/app/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
@returns {Object|Null} The list of model data or null if none found.
*/
export const getModelData = (state) => {
if (state.juju && state.juju.modelData) {
if (state?.juju?.modelData) {
return state.juju.modelData;
}
return null;
Expand Down Expand Up @@ -107,7 +107,7 @@ const getFilteredModelData = (filters) =>
*/
const getUserCredentials = (state) => {
let storedMacaroons = null;
if (state.root && state.root.bakery) {
if (state?.root?.bakery) {
storedMacaroons = state.root.bakery.storage._store;
}
return storedMacaroons;
Expand Down
73 changes: 31 additions & 42 deletions src/components/panels/AppsPanel/AppsPanel.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React, { useMemo } from "react";
import { useSelector } from "react-redux";
import { getConfig } from "app/selectors";
import SlidePanel from "components/SlidePanel/SlidePanel";
import MainTable from "@canonical/react-components/dist/components/MainTable";

import useModelStatus from "hooks/useModelStatus";
Expand All @@ -24,7 +23,7 @@ import {

import "./_apps-panel.scss";

export default function AppsPanel({ isActive, onClose, entity }) {
export default function AppsPanel({ entity, panelRowClick }) {
// Get model status info
const modelStatusData = useModelStatus();

Expand Down Expand Up @@ -105,56 +104,46 @@ export default function AppsPanel({ isActive, onClose, entity }) {
);

const machinesPanelRows = useMemo(
() => generateMachineRows(filteredModelStatusData),
[filteredModelStatusData]
() => generateMachineRows(filteredModelStatusData, panelRowClick),
[filteredModelStatusData, panelRowClick]
);

const unitPanelRows = useMemo(
() => generateUnitRows(filteredModelStatusData, baseAppURL),
[baseAppURL, filteredModelStatusData]
() => generateUnitRows(filteredModelStatusData, panelRowClick),
[filteredModelStatusData, panelRowClick]
);

const relationPanelRows = useMemo(
() => generateRelationRows(filteredModelStatusData, baseAppURL),
[filteredModelStatusData, baseAppURL]
);

// Check for loading status
const isLoading = !filteredModelStatusData?.applications?.[entity];

return (
<SlidePanel
isActive={isActive}
onClose={onClose}
isLoading={isLoading}
className="apps-panel"
>
<>
{appPanelHeader}
<div className="slide-panel__tables">
<MainTable
headers={unitTableHeaders}
rows={unitPanelRows}
className="model-details__units p-main-table panel__table"
sortable
emptyStateMsg={"There are no units in this model"}
/>
<MainTable
headers={machineTableHeaders}
rows={machinesPanelRows}
className="model-details__machines p-main-table panel__table"
sortable
emptyStateMsg={"There are no machines in this model"}
/>
<MainTable
headers={relationTableHeaders}
rows={relationPanelRows}
className="model-details__relations p-main-table panel__table"
sortable
emptyStateMsg={"There are no relations in this model"}
/>
</div>
</>
</SlidePanel>
<>
{appPanelHeader}
<div className="slide-panel__tables">
<MainTable
headers={unitTableHeaders}
rows={unitPanelRows}
className="model-details__units p-main-table panel__table"
sortable
emptyStateMsg={"There are no units in this model"}
/>
<MainTable
headers={machineTableHeaders}
rows={machinesPanelRows}
className="model-details__machines p-main-table panel__table"
sortable
emptyStateMsg={"There are no machines in this model"}
/>
<MainTable
headers={relationTableHeaders}
rows={relationPanelRows}
className="model-details__relations p-main-table panel__table"
sortable
emptyStateMsg={"There are no relations in this model"}
/>
</div>
</>
);
}
127 changes: 92 additions & 35 deletions src/components/panels/MachinesPanel/MachinesPanel.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
import React, { useMemo, useCallback } from "react";
import SlidePanel from "components/SlidePanel/SlidePanel";
import MainTable from "@canonical/react-components/dist/components/MainTable";
import cloneDeep from "clone-deep";

import useModelStatus from "hooks/useModelStatus";

import {
unitTableHeaders,
generateUnitRows,
applicationTableHeaders,
generateApplicationRows,
} from "pages/Models/Details/generators";

import { generateStatusElement } from "app/utils";

import "./_machines-panel.scss";

export default function MachinesPanel({
isActive,
onClose,
entity: machineId,
}) {
export default function MachinesPanel({ entity: machineId, panelRowClick }) {
const modelStatusData = useModelStatus();
const machine = modelStatusData?.machines[machineId];

Expand All @@ -39,7 +37,7 @@ export default function MachinesPanel({
{machine && (
<div className="row">
<div className="col-4">
<div className="machine-panel__id">
<div className="machines-panel__id">
<strong>
<span className="entity-name">
Machine '{machineId}' - {machine?.series}
Expand Down Expand Up @@ -86,35 +84,94 @@ export default function MachinesPanel({
[modelStatusData, machineId, generateMachinesPanelHeader]
);

// Check for loading status
const isLoading = !modelStatusData?.machines;
const filteredModelStatusDataByApp = useCallback(
(machineId) => {
const filteredModelStatusData = cloneDeep(modelStatusData);
filteredModelStatusData &&
Object.keys(filteredModelStatusData.applications).forEach(
(application) => {
const units =
filteredModelStatusData.applications[application]?.units;

if (Object.entries(units).length) {
Object.values(units).forEach((unit) => {
if (
// Delete any app without a unit matching this machineId...
unit.machine !== machineId ||
// ...delete any app without units at all
!Object.entries(units).length
) {
delete filteredModelStatusData.applications[application];
}
});
} else {
delete filteredModelStatusData.applications[application];
}
}
);
return filteredModelStatusData;
},
[modelStatusData]
);

const filteredModelStatusDataByUnit = useCallback(
(machineId) => {
const filteredModelStatusData = cloneDeep(modelStatusData);
filteredModelStatusData &&
Object.keys(filteredModelStatusData.applications).forEach(
(application) => {
const units =
filteredModelStatusData.applications[application].units;
for (let [key, unit] of Object.entries(units)) {
if (unit.machine !== machineId) {
delete filteredModelStatusData.applications[application].units[
key
];
}
}
}
);
return filteredModelStatusData;
},
[modelStatusData]
);

// Generate apps table content
const applicationRows = useMemo(
() =>
generateApplicationRows(
filteredModelStatusDataByApp(machineId),
panelRowClick
),
[filteredModelStatusDataByApp, machineId, panelRowClick]
);

// Generate units table content
const unitRows = useMemo(
() =>
generateUnitRows(filteredModelStatusDataByUnit(machineId), panelRowClick),
[filteredModelStatusDataByUnit, machineId, panelRowClick]
);

return (
<SlidePanel
isActive={isActive}
onClose={onClose}
isLoading={isLoading}
className="machines-panel"
>
<>
{machinePanelHeader}
<div className="slide-panel__tables">
<MainTable
headers={unitTableHeaders}
rows={[]} // Temp disable
className="model-details__units p-main-table"
sortable
emptyStateMsg={"There are no units in this model"}
/>
<MainTable
headers={applicationTableHeaders}
rows={[]} // Temp disable
className="model-details__apps p-main-table"
sortable
emptyStateMsg={"There are no apps in this model"}
/>
</div>
</>
</SlidePanel>
<>
{machinePanelHeader}
<div className="slide-panel__tables">
<MainTable
headers={unitTableHeaders}
rows={unitRows}
className="model-details__units p-main-table"
sortable
emptyStateMsg={"There are no units in this model"}
/>
<MainTable
headers={applicationTableHeaders}
rows={applicationRows}
className="model-details__apps p-main-table"
sortable
emptyStateMsg={"There are no apps in this model"}
/>
</div>
</>
);
}
2 changes: 1 addition & 1 deletion src/components/panels/MachinesPanel/_machines-panel.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
@import "../panels";

.machine-panel {
.machines-panel {
&__id {
padding-left: 2rem;
text-transform: capitalize;
Expand Down
Loading

0 comments on commit a19319a

Please sign in to comment.