How can I display a table with arbitrary data in Workshop?

In Workshop, I can create a Table with Object instances, their properties, derived properties computed via Functions, …

However, how can I display a table with arbitrary data, not related to Objects instances ? Is there a way to display arbitrary data in a table format ?

One solution might to user the Markdown Widget to display a table

import { Function, Integer } from "@foundry/functions-api";
import { Objects, ExampleObjects, ObjectSet} from "@foundry/ontology-api";

type TableRow = {
  [key: string]: string | number;
};

export class MyFunctions {

    public generateMarkdownTable(rows: TableRow[]): string {
      if (rows.length === 0) {
          return "";
      }

      const header = Object.keys(rows[0]);
      const headerSeparator = header.map((key) => "-".repeat(key.length));
  
      const tableHeader = "| " + header.join(" | ") + " |";
      const tableSeparator = "| " + headerSeparator.join(" | ") + " |";
  
      const tableRows = rows
          .map((row) =>
          "| " +
          header.map((key) => row[key]).join(" | ") +
          " |"
          )
          .join("\n");
  
      return [tableHeader, tableSeparator, tableRows].join("\n");
    }

    @Function()
    public generateMarkdownTableFromObjects(objs: ObjectSet<ExampleObjects>, shouldBeCompressedNumber: boolean): string {
        // As any function, arbitrary parameters can be passed, like strings, booleans, etc. which can be used to filter objects, control the display, for example, control how numbers are formatted, etc.
        const all_objs = objs.all();

        var rows: TableRow[] = [];
        all_objs.map(curr_obj => 
        rows.push( 
            { 
                Name: curr_obj.title ?? "No title", 
                Age: curr_obj.value ?? -1, 
                Occupation:  curr_obj.someOtherProp
            }
        ))

		/*
		This is the datastructure passed to the generateMarkdownTable function to generate markdown: 
        const rowsStatic: TableRow[] = [
            { Name: "John", Age: 34, Occupation: "Engineer" },
            { Name: "Sarah", Age: 28, Occupation: "Designer" },
            { Name: "Mike", Age: 45, Occupation: "Doctor" },
        ];
		*/

        return this.generateMarkdownTable(rows);

    }
}

Here is how it will look.
Note: The below image only contains notional data for the purpose of this example
image

3 Likes

Another potential pattern is the usage of the iframe widget to use any JS-library for rendering the respective table. Using the markdown directly, however seems rather elegant since you have one less component to maintain.

1 Like