Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
joseivanlopez committed Mar 8, 2024
1 parent f09b9c0 commit 8c3b701
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 111 deletions.
28 changes: 28 additions & 0 deletions web/src/assets/styles/blocks.scss
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,34 @@ ul[data-type="agama/list"][role="grid"] {
}
}

table[data-type="agama/tree-table"] {
tr.dimmed-row {
background-color: #fff;
opacity: 0.8;
background: repeating-linear-gradient( -45deg, #fcfcff, #fcfcff 3px, #fff 3px, #fff 10px );

td {
color: var(--color-gray-dimmed);
padding-block: 0;
}
}

@media (width > 768px) {
th.text-end,
td.text-end {
text-align: end;
padding-inline-end: var(--spacer-large);
}
}

@media (width <= 768px) {
td:empty {
display: none;
}
}
}


.tpm-hint {
container-type: inline-size;
container-name: tpm-info;
Expand Down
9 changes: 6 additions & 3 deletions web/src/components/core/TreeTable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ export default function TreeTable({
}) {
const renderColumns = (item, treeRow) => {
return columns.map((c, cIdx) => {
const props = { dataLabel: c.title };
const props = {
dataLabel: c.title,
className: c.classNames
};

if (cIdx === 0) props.treeRow = treeRow;

Expand Down Expand Up @@ -85,10 +88,10 @@ export default function TreeTable({
};

return (
<Table isTreeTable variant="compact">
<Table isTreeTable variant="compact" data-type="agama/tree-table">
<Thead>
<Tr>
{ columns.map((c, i) => <Th key={i}>{c.title}</Th>) }
{ columns.map((c, i) => <Th key={i} className={c.classNames}>{c.title}</Th>) }
</Tr>
</Thead>
<Tbody>
Expand Down
180 changes: 72 additions & 108 deletions web/src/components/storage/ProposalActionsSection.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import { sprintf } from "sprintf-js";

import { _, n_ } from "~/i18n";
import { deviceSize } from "~/components/storage/utils";
import { If, Section } from "~/components/core";
import { If, Section, TreeTable } from "~/components/core";
import { partition } from "~/utils";

// TODO: would be nice adding an aria-description to these lists, but aria-description still in
Expand Down Expand Up @@ -105,130 +105,93 @@ const ActionsSkeleton = () => {
);
};

class DevicesManager {
constructor(system, staging) {
this.system = system;
this.staging = staging;
}
const DeleteActions = ({ actions }) => {
const deleteActions = actions.filter(a => a.delete);

systemDevice(sid) {
return this.system.find(d => d.sid === sid);
}

device(sid) {
return this.staging.find(d => d.sid === sid);
}

lvmVgsWithMountPoints() {
const vgs = this.staging.filter(d => d.type === "lvmVg");
return vgs.filter(v => v.logicalVolumes.find(l => l.filesystem?.mountPath !== undefined));
}

children(device) {
if (device.partitionTable) return this.partitionTableChildren(device.partitionTable);
if (device.type === "lvmVg") return this.lvmVgChildren(device);
return [];
}

partitionTableChildren(partitionTable) {
const { partitions, unusedSlots } = partitionTable;
const children = partitions.concat(unusedSlots);

return children.sort((a, b) => a.start < b.start ? -1 : 1);
}

lvmVgChildren(lvmVg) {
return lvmVg.logicalVolumes.sort((a, b) => a.name < b.name ? -1 : 1);
}

isSlot(storageElement) {
return storageElement.sid === undefined;
}
}

class SlotPresenter {
constructor(slot) {
this.slot = slot;
}

name() {
return "";
}

details() {
return "Unused space";
}

size() {
return deviceSize(this.slot.size);
}

mountPoint() {
return "";
}
}

class DevicePresenter {
constructor(device, devicesManager) {
this.device = device;
this.devicesManager = devicesManager;
}

name() {
return this.device.name;
}

details() {
return this.device.description;
}

size() {
return deviceSize(this.device.size);
}

mountPoint() {
return this.device.filesystem?.mountPath || "";
}
}

const DeviceResult = ({ presenter }) => {
// TODO Add show the deleted system if any
return (
<ul>
<li>{presenter.name()}</li>
<ul>
<li>{presenter.details()}</li>
<li>{presenter.size()}</li>
<li>{presenter.mountPoint()}</li>
</ul>
{deleteActions.map((a, i) => <li key={i}>{a.text}</li>)}
</ul>
);
};

const DevicesResult = ({ settings, devices }) => {
const { system = [], staging = [] } = devices;
const devicesManager = new DevicesManager(system, staging);

const usedDevices = () => {
const diskDevices = settings.installationDevices.map(d => devicesManager.device(d.sid));
const lvmVgs = devicesManager.lvmVgsWithMountPoints();
const sids = settings.installationDevices.map(d => d.sid);
const instDevices = staging.filter(d => sids.includes(d.sid));
const lvmVgs = staging.filter(d => d.logicalVolumes?.find(l => l.filesystem?.mountPath !== undefined));

// FIXME This is only to avoid showing the existing VG of my VM. Remove and use lvmVgs.
const newLvmVgs = lvmVgs.filter(v => system.find(d => d.sid === v.sid) === undefined);

return instDevices.concat(newLvmVgs);
};

const children = (device) => {
const partitionTableChildren = (partitionTable) => {
const { partitions, unusedSlots } = partitionTable;
const children = partitions.concat(unusedSlots);

return children.sort((a, b) => a.start < b.start ? -1 : 1);
};

return diskDevices.concat(lvmVgs);
const lvmVgChildren = (lvmVg) => {
return lvmVg.logicalVolumes.sort((a, b) => a.name < b.name ? -1 : 1);
};

if (device.partitionTable) return partitionTableChildren(device.partitionTable);
if (device.type === "lvmVg") return lvmVgChildren(device);
return [];
};

const presenter = (storageElement) => {
if (devicesManager.isSlot(storageElement))
return new SlotPresenter(storageElement);
else
return new DevicePresenter(storageElement, devicesManager);
const renderDeviceName = (item) => {
const newLabel = (device) => {
const systemDevice = system.find(d => d.sid === device.sid);
if (!systemDevice) return _("(new)");
};

return (
<div className="split">
<span>{item.sid && item.name}</span>
<span><em>{newLabel(item)}</em></span>
</div>
);
};

return usedDevices().map(device => {
const devices = [device].concat(devicesManager.children(device));
const renderDetails = (item) => {
if (!item.sid) return _("Unused space");

return devices.map((d, i) => {
return <DeviceResult key={i} presenter={presenter(d)} />;
});
});
return (
<div className="split">
{/* <span><em>{newLabel(item)}</em></span> */}
<span>{item.description}</span>
<span><b>{item.filesystem?.label}</b></span>
</div>
);
};

const renderSize = (item) => deviceSize(item.size);

const renderMountPoint = (item) => item.sid && item.filesystem?.mountPath;

return (
<TreeTable
columns={[
{ title: _("Device"), content: renderDeviceName },
{ title: _("Details"), content: renderDetails },
{ title: _("Size"), content: renderSize, classNames: "text-end" },
{ title: _("Mount Point"), content: renderMountPoint }
]}
items={usedDevices()}
itemChildren={children}
rowClassNames={(item) => {
if (!item.sid) return "dimmed-row";
}}
/>
);
};

/**
Expand Down Expand Up @@ -267,6 +230,7 @@ export default function ProposalActionsSection({
then={<ActionsSkeleton />}
else={
<>
<DeleteActions actions={actions} />
<DevicesResult settings={settings} devices={devices} />
<ProposalActions actions={actions} />
</>
Expand Down

0 comments on commit 8c3b701

Please sign in to comment.