import { useEffect, useState } from "react"; import ContainerModel from "../models/ContainerModel"; import { check, list, update } from "../services/Api"; import ContainerList from "./ContainerList"; import Spinner from "./Spinner"; import SpinnerModal from "./SpinnerModal"; import { UpdateSelected, UpdateAll, UpdateCheck } from "./UpdateButtons"; interface ViewModel { Containers: ContainerModel[]; } const ContainerView = () => { const [loading, setLoading] = useState(true); const [checking, setChecking] = useState(false); const [updating, setUpdating] = useState(false); const [hasChecked, setHasChecked] = useState(false); const [viewModel, setViewModel] = useState({ Containers: [] }); const containers = viewModel.Containers; const containersWithUpdates = containers.filter((c) => c.HasUpdate); const containersWithoutUpdates = containers.filter((c) => !c.HasUpdate); const hasSelectedContainers = containers.some((c) => c.Selected); const hasUpdates = containersWithUpdates.length > 0; const checkForUpdates = async () => { setChecking(true); setViewModel((m) => ({ ...m, Containers: m.Containers.map((c) => ({ ...c, IsChecking: true })) })); await Promise.all(containers.map(async (c1) => { const result = await check(c1.ContainerID); setViewModel((m) => ({ ...m, Containers: m.Containers.map((c2) => (c1.ContainerID === c2.ContainerID ? { ...c2, ...result, IsChecking: false } : c2 )) })); })); setChecking(false); setHasChecked(true); }; const listContainers = async () => { setLoading(true); const data = await list(); setViewModel({ Containers: data.Containers.map((c) => ({ ...c, Selected: false, IsChecking: false, HasUpdate: false, IsUpdating: false, NewVersion: "", NewVersionCreated: "" })) }); setLoading(false); setHasChecked(false); }; const updateImages = async (imagesToUpdate?: string[]) => { setUpdating(true); await update(imagesToUpdate); await listContainers(); await checkForUpdates(); setUpdating(false); }; const updateAll = async () => { await updateImages(); }; const updateSelected = async () => { const selectedImages = containers.filter((c) => c.Selected === true).map((c) => c.ImageNameShort); await updateImages(selectedImages); }; const onContainerClick = (container: ContainerModel) => { setViewModel((m) => ({ ...m, Containers: m.Containers.map((c2) => (container.ContainerID === c2.ContainerID ? { ...c2, Selected: !c2.Selected, } : c2 )) })); }; useEffect(() => { listContainers(); }, []); return (
{hasUpdates ? {containersWithUpdates.length} container{containersWithUpdates.length === 1 ? " has" : "s have"} updates. : checking ? Checking for updates... : (hasChecked && containers.length > 0) ? <>All containers are up to date. : {containers.length} running container{containers.length !== 1 && "s"} found.}
{hasUpdates && } {hasUpdates && }
{hasUpdates && containersWithoutUpdates.length > 0 &&
{containersWithoutUpdates.length} container{containersWithoutUpdates.length === 1 ? " is" : "s are"} up to date.
} {loading && }
); }; export default ContainerView;