Skip to content

Commit

Permalink
feat: column type mapping
Browse files Browse the repository at this point in the history
It has come up a couple times so I thought I should make a proposal for how I
think we should share column renderers between tables. IMHO we have three cases:
1. Type-specific column rendering like Image name. These should continue to be
   type-specific as today.
2. Generic columns that really just need to (e.g.) render a string in a certain
   way.
3. The middle ground where it's a little more complex, or maybe you need to
   render a couple properties.

This commit adds a simple type-mapping function to directly support #2, and
applies it to VolumeList.

For the middle ground, I think we're going to have convenient cases where objects
used in two tables have the same property types & names (e.g. { id: string,
some-prop: number}) and we can just render those, and other cases where maybe the
renderer should use another type (e.g. Condition) or one of the objects has a
different property name. Again, this commit provides a simple way for tables to
do whatever mapping is required.

Based on top of #5005 assuming that would merge soon.

Fixes #5002. We would share more columns as we add other tables that would
use them.

Signed-off-by: Tim deBoer <git@tdeboer.ca>
  • Loading branch information
deboer-tim committed Nov 27, 2023
1 parent 8aa6bdd commit cc55ac3
Show file tree
Hide file tree
Showing 10 changed files with 59 additions and 40 deletions.
33 changes: 33 additions & 0 deletions packages/renderer/src/lib/table/SimpleColumn.spec.ts
@@ -0,0 +1,33 @@
/**********************************************************************
* Copyright (C) 2023 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
***********************************************************************/

import '@testing-library/jest-dom/vitest';
import { test, expect } from 'vitest';
import { render, screen } from '@testing-library/svelte';

import SimpleColumn from './SimpleColumn.svelte';

test('Expect simple column styling', async () => {
const obj = 'Test';
render(SimpleColumn, { object: obj });

const text = screen.getByText(obj);
expect(text).toBeInTheDocument();
expect(text).toHaveClass('text-sm');
expect(text).toHaveClass('text-gray-700');
});
Expand Up @@ -2,4 +2,6 @@
export let object: any;
</script>

{object.age}
<div class="text-sm text-gray-700">
{object}
</div>
4 changes: 3 additions & 1 deletion packages/renderer/src/lib/table/Table.svelte
Expand Up @@ -186,7 +186,9 @@ function setGridColumns() {
: 'justify-self-start'} self-center overflow-hidden max-w-full"
role="cell">
{#if column.info.renderer}
<svelte:component this="{column.info.renderer}" object="{object}" />
<svelte:component
this="{column.info.renderer}"
object="{column.info.renderMapping ? column.info.renderMapping(object) : object}" />
{/if}
</div>
{/each}
Expand Down
5 changes: 0 additions & 5 deletions packages/renderer/src/lib/table/TestColumnId.svelte

This file was deleted.

5 changes: 0 additions & 5 deletions packages/renderer/src/lib/table/TestColumnName.svelte

This file was deleted.

13 changes: 7 additions & 6 deletions packages/renderer/src/lib/table/TestTable.svelte
@@ -1,9 +1,7 @@
<script lang="ts">
import Table from './Table.svelte';
import TestColumnId from './TestColumnId.svelte';
import TestColumnName from './TestColumnName.svelte';
import TestColumnAge from './TestColumnAge.svelte';
import { Column, Row } from './table';
import SimpleColumn from './SimpleColumn.svelte';
let table: Table;
let selectedItemsNumber: number;
Expand All @@ -22,19 +20,22 @@ const people: Person[] = [
const idCol: Column<Person> = new Column('Id', {
align: 'right',
renderer: TestColumnId,
renderMapping: obj => obj.id,
renderer: SimpleColumn,
comparator: (a, b) => a.id - b.id,
});
const nameCol: Column<Person> = new Column('Name', {
width: '3fr',
renderer: TestColumnName,
renderMapping: obj => obj.name,
renderer: SimpleColumn,
comparator: (a, b) => a.name.localeCompare(b.name),
});
const ageCol: Column<Person> = new Column('Age', {
align: 'right',
renderer: TestColumnAge,
renderMapping: obj => obj.age,
renderer: SimpleColumn,
comparator: (a, b) => a.age - b.age,
initialOrder: 'descending',
});
Expand Down
8 changes: 8 additions & 0 deletions packages/renderer/src/lib/table/table.ts
Expand Up @@ -34,6 +34,14 @@ export interface ColumnInformation<Type> {
*/
readonly width?: string;

/**
* Map the source object to another type for rendering. Allows
* easier reuse and sharing of renderers by converting to simple
* types (e.g. rendering 'string' instead of 'type.name') or
* converting to a different type.
*/
readonly renderMapping?: (object: Type) => any;

/**
* Svelte component, renderer for each cell in the column.
* The component must have a property 'object' that has the
Expand Down
9 changes: 0 additions & 9 deletions packages/renderer/src/lib/volume/VolumeColumnAge.svelte

This file was deleted.

9 changes: 0 additions & 9 deletions packages/renderer/src/lib/volume/VolumeColumnSize.svelte

This file was deleted.

9 changes: 5 additions & 4 deletions packages/renderer/src/lib/volume/VolumesList.svelte
Expand Up @@ -22,8 +22,7 @@ import { Column, Row } from '../table/table';
import VolumeColumnStatus from './VolumeColumnStatus.svelte';
import VolumeColumnName from './VolumeColumnName.svelte';
import VolumeColumnEnvironment from './VolumeColumnEnvironment.svelte';
import VolumeColumnSize from './VolumeColumnSize.svelte';
import VolumeColumnAge from './VolumeColumnAge.svelte';
import SimpleColumn from '../table/SimpleColumn.svelte';
import VolumeColumnActions from './VolumeColumnActions.svelte';
export let searchTerm = '';
Expand Down Expand Up @@ -191,13 +190,15 @@ let envColumn = new Column<VolumeInfoUI>('Environment', {
});
let ageColumn = new Column<VolumeInfoUI>('Age', {
renderer: VolumeColumnAge,
renderMapping: object => object.age,
renderer: SimpleColumn,
comparator: (a, b) => moment().diff(a.created) - moment().diff(b.created),
});
let sizeColumn = new Column<VolumeInfoUI>('Size', {
align: 'right',
renderer: VolumeColumnSize,
renderMapping: object => object.humanSize,
renderer: SimpleColumn,
comparator: (a, b) => a.size - b.size,
initialOrder: 'descending',
});
Expand Down

0 comments on commit cc55ac3

Please sign in to comment.