Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
DRAFT. We have impending technical debt where our expanding number of table components (images, volumes, pods, containers, soon adding Kubernetes objects) will cross with our future design ideas (tables should be sortable, columns configurable, environments groupable, etc). We can't copy/paste these features into every page, and deal with differences between them. This is the best I've come up with so far. Each page passes an array of objects to a Table component, which is responsible for creating the basic layout and calling back a Row component to render each cell in the table. This seems like just enough abstraction b/c all of the basic/common table capability can be handled in that component, and each Row doesn't know or care if columns are missing or sorted differently. A TableHelper class providers a few functions like whether objects can be selected & sorting. Switched to grid layout, which also helped to reduce code in *Row components. I am still getting bizarre changes when I try to tweak the column widths, but it appears to be in a happy spot here. Added sorting with a sort indicator in the header, and tests. Sorting by image and volume size was left out for now b/c it shouldn't be alphabetical. Still to do before removing draft status: - Filtering isn't working great... but maybe that's how it was working before. - Volume* and Image* will be extracted to their own PRs, but I felt like it helps to see how they change here. Support for 'object containers' in order to support Pod and Container lists will be done separately since this is already a big PR. Fixes #4365. Signed-off-by: Tim deBoer <git@tdeboer.ca>
- Loading branch information
1 parent
a26d368
commit e3a635c
Showing
9 changed files
with
561 additions
and
237 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
<script lang="ts"> | ||
import { router } from 'tinro'; | ||
import ImageActions from './ImageActions.svelte'; | ||
import type { ImageInfoUI } from './ImageInfoUI'; | ||
import PushImageModal from './PushImageModal.svelte'; | ||
import RenameImageModal from './RenameImageModal.svelte'; | ||
import ImageIcon from '../images/ImageIcon.svelte'; | ||
import StatusIcon from '../images/StatusIcon.svelte'; | ||
export let object: any; | ||
export let column: string; | ||
$: image = object; | ||
export let multipleEngines = false; // TODO | ||
function openDetailsImage(image: ImageInfoUI) { | ||
router.goto(`/images/${image.id}/${image.engineId}/${image.base64RepoTag}/summary`); | ||
} | ||
let pushImageModal = false; | ||
let pushImageModalImageInfo: ImageInfoUI | undefined = undefined; | ||
function handlePushImageModal(imageInfo: ImageInfoUI) { | ||
pushImageModalImageInfo = imageInfo; | ||
pushImageModal = true; | ||
} | ||
let renameImageModal = false; | ||
let renameImageModalImageInfo: ImageInfoUI | undefined = undefined; | ||
function handleRenameImageModal(imageInfo: ImageInfoUI) { | ||
renameImageModalImageInfo = imageInfo; | ||
renameImageModal = true; | ||
} | ||
function closeModals() { | ||
pushImageModal = false; | ||
renameImageModal = false; | ||
} | ||
</script> | ||
|
||
{#if column === 'Status'} | ||
<StatusIcon icon="{ImageIcon}" status="{image.inUse ? 'USED' : 'UNUSED'}" /> | ||
{:else if column === 'Name'} | ||
<!-- svelte-ignore a11y-click-events-have-key-events --> | ||
<!-- svelte-ignore a11y-no-static-element-interactions --> | ||
<div class="hover:cursor-pointer flex flex-col" on:click="{() => openDetailsImage(image)}"> | ||
<div class="flex flex-row items-center"> | ||
<div class="text-sm text-gray-300">{image.name}</div> | ||
</div> | ||
<div class="flex flex-row items-center"> | ||
<div class="text-xs text-violet-400">{image.shortId}</div> | ||
<div class="ml-1 text-xs font-extra-light text-gray-400">{image.tag}</div> | ||
</div> | ||
<div class="flex flex-row text-xs font-extra-light text-gray-900"> | ||
<!-- Hide in case of single engine--> | ||
{#if multipleEngines} | ||
<div class="px-2 inline-flex text-xs font-extralight rounded-full bg-slate-800 text-slate-400"> | ||
{image.engineName} | ||
</div> | ||
{/if} | ||
</div> | ||
</div> | ||
{:else if column === 'Age'} | ||
<div class="text-sm text-gray-700"> | ||
{image.age} | ||
</div> | ||
{:else if column === 'Size'} | ||
<div class="text-sm text-gray-700"> | ||
{image.humanSize} | ||
</div> | ||
{:else} | ||
<ImageActions | ||
image="{image}" | ||
onPushImage="{handlePushImageModal}" | ||
onRenameImage="{handleRenameImageModal}" | ||
dropdownMenu="{true}" /> | ||
{/if} | ||
{#if pushImageModal && pushImageModalImageInfo} | ||
<PushImageModal | ||
imageInfoToPush="{pushImageModalImageInfo}" | ||
closeCallback="{() => { | ||
closeModals(); | ||
}}" /> | ||
{/if} | ||
{#if renameImageModal && renameImageModalImageInfo} | ||
<RenameImageModal | ||
imageInfoToRename="{renameImageModalImageInfo}" | ||
closeCallback="{() => { | ||
closeModals(); | ||
}}" /> | ||
{/if} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.