From 2293a5cc7c5a71a4267ec76693cc12c1153dcd09 Mon Sep 17 00:00:00 2001 From: heswell Date: Sun, 10 Nov 2024 14:53:22 +0000 Subject: [PATCH] integrate with TreeTable, generate treeSource in cli --- vuu-ui/package-lock.json | 63 +++++++++++++++-- .../src/tree-data-source/TreeDataSource.ts | 2 + .../src/split-button/SplitButton.css | 2 +- vuu-ui/showcase/showcase.config.json | 2 +- vuu-ui/tools/showcase-cli/README.md | 19 ++++- .../showcase-cli/cli/buildPackageTree.ts | 6 +- vuu-ui/tools/showcase-cli/{ => cli}/cli.js | 37 +++++----- vuu-ui/tools/showcase-cli/cli/main.ts | 6 -- vuu-ui/tools/showcase-cli/cli/prepare.ts | 24 +++++++ .../cli/treeSourceFromFileSystem.ts | 46 +++++++++++++ vuu-ui/tools/showcase-cli/package.json | 2 +- vuu-ui/tools/showcase-cli/scripts/build.mjs | 2 +- .../showcase-cli/{src => showcase-ui}/App.css | 0 .../showcase-cli/{src => showcase-ui}/App.tsx | 51 ++++++++------ .../{src => showcase-ui}/Showcase.css | 0 .../{src => showcase-ui}/Showcase.tsx | 17 +++-- .../ShowcaseStandalone.tsx | 0 .../components/iframe/IFrame.tsx | 0 .../iframe/IFrameContextProvider.tsx | 0 .../components/iframe/index.ts | 0 .../{src => showcase-ui}/components/index.ts | 0 .../{src => showcase-ui}/exhibit-utils.ts | 0 .../{src => showcase-ui}/index-main.tsx | 8 ++- .../{src => showcase-ui}/index-standalone.tsx | 0 .../{src => showcase-ui}/index.ts | 0 .../showcase-cli/{src => showcase-ui}/main.ts | 6 +- .../{src => showcase-ui}/showcase-utils.ts | 10 +++ .../{src => showcase-ui}/themes/vuu-theme.ts | 0 .../showcase-ui/useShowcaseApp.ts | 60 ++++++++++++++++ .../tools/showcase-cli/src/useShowcaseApp.ts | 69 ------------------- .../showcase-cli/templates/index.html.ts | 3 +- .../tools/vuu-showcase/src/showcase-utils.ts | 10 ++- 32 files changed, 305 insertions(+), 140 deletions(-) rename vuu-ui/tools/showcase-cli/{ => cli}/cli.js (63%) create mode 100644 vuu-ui/tools/showcase-cli/cli/prepare.ts create mode 100644 vuu-ui/tools/showcase-cli/cli/treeSourceFromFileSystem.ts rename vuu-ui/tools/showcase-cli/{src => showcase-ui}/App.css (100%) rename vuu-ui/tools/showcase-cli/{src => showcase-ui}/App.tsx (83%) rename vuu-ui/tools/showcase-cli/{src => showcase-ui}/Showcase.css (100%) rename vuu-ui/tools/showcase-cli/{src => showcase-ui}/Showcase.tsx (70%) rename vuu-ui/tools/showcase-cli/{src => showcase-ui}/ShowcaseStandalone.tsx (100%) rename vuu-ui/tools/showcase-cli/{src => showcase-ui}/components/iframe/IFrame.tsx (100%) rename vuu-ui/tools/showcase-cli/{src => showcase-ui}/components/iframe/IFrameContextProvider.tsx (100%) rename vuu-ui/tools/showcase-cli/{src => showcase-ui}/components/iframe/index.ts (100%) rename vuu-ui/tools/showcase-cli/{src => showcase-ui}/components/index.ts (100%) rename vuu-ui/tools/showcase-cli/{src => showcase-ui}/exhibit-utils.ts (100%) rename vuu-ui/tools/showcase-cli/{src => showcase-ui}/index-main.tsx (60%) rename vuu-ui/tools/showcase-cli/{src => showcase-ui}/index-standalone.tsx (100%) rename vuu-ui/tools/showcase-cli/{src => showcase-ui}/index.ts (100%) rename vuu-ui/tools/showcase-cli/{src => showcase-ui}/main.ts (62%) rename vuu-ui/tools/showcase-cli/{src => showcase-ui}/showcase-utils.ts (90%) rename vuu-ui/tools/showcase-cli/{src => showcase-ui}/themes/vuu-theme.ts (100%) create mode 100644 vuu-ui/tools/showcase-cli/showcase-ui/useShowcaseApp.ts delete mode 100644 vuu-ui/tools/showcase-cli/src/useShowcaseApp.ts diff --git a/vuu-ui/package-lock.json b/vuu-ui/package-lock.json index 51b5a881c..6e2a8a849 100644 --- a/vuu-ui/package-lock.json +++ b/vuu-ui/package-lock.json @@ -1402,9 +1402,10 @@ } }, "node_modules/@mdx-js/rollup": { - "version": "3.0.0", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@mdx-js/rollup/-/rollup-3.0.1.tgz", + "integrity": "sha512-j0II91OCm4ld+l5QVgXXMQGxVVcAWIQJakYWi1dv5pefDHASJyCYER2TsdH7Alf958GoFSM7ugukWyvDq/UY4A==", "dev": true, - "license": "MIT", "dependencies": { "@mdx-js/mdx": "^3.0.0", "@rollup/pluginutils": "^5.0.0", @@ -8303,6 +8304,17 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/mime-db": { "version": "1.52.0", "dev": true, @@ -8391,6 +8403,22 @@ "dev": true, "license": "MIT" }, + "node_modules/node-static": { + "version": "0.7.11", + "resolved": "https://registry.npmjs.org/node-static/-/node-static-0.7.11.tgz", + "integrity": "sha512-zfWC/gICcqb74D9ndyvxZWaI1jzcoHmf4UTHWQchBNuNMxdBLJMDiUgZ1tjGLEIe/BMhj2DxKD8HOuc2062pDQ==", + "dependencies": { + "colors": ">=0.6.0", + "mime": "^1.2.9", + "optimist": ">=0.3.4" + }, + "bin": { + "static": "bin/cli.js" + }, + "engines": { + "node": ">= 0.4.1" + } + }, "node_modules/normalize-path": { "version": "3.0.0", "dev": true, @@ -8576,6 +8604,20 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha512-snN4O4TkigujZphWLN0E//nQmm7790RYaE53DdL7ZYwee2D8DDo9/EyYiKUfN3rneWUjhJnueija3G9I2i0h3g==", + "dependencies": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + } + }, + "node_modules/optimist/node_modules/minimist": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", + "integrity": "sha512-iotkTvxc+TwOm5Ieim8VnSNvCDjCK9S8G3scJ50ZthspSxa7jx50jkhYduuAtAjvfDUwSgOwf8+If99AlOEhyw==" + }, "node_modules/optionator": { "version": "0.9.4", "license": "MIT", @@ -11270,6 +11312,14 @@ "node": ">=0.10.0" } }, + "node_modules/wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha512-1tMA907+V4QmxV7dbRvb4/8MaRALK6q9Abid3ndMYnbyo8piisCmeONVqVSXqQA3KaP4SLt5b7ud6E2sqP8TFw==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/wrap-ansi": { "version": "7.0.0", "dev": true, @@ -11594,6 +11644,7 @@ "version": "0.0.26", "license": "Apache-2.0", "dependencies": { + "@finos/vuu-datatable": "0.0.26", "@finos/vuu-filters": "0.0.26", "@finos/vuu-popups": "0.0.26", "@finos/vuu-table": "0.0.26", @@ -11964,7 +12015,7 @@ "node-static": "^0.7.11" }, "bin": { - "showcase-cli": "cli.js" + "showcase-cli": "cli/cli.js" } }, "tools/vite-plugin-inline-css": { @@ -11975,6 +12026,7 @@ "version": "0.0.1", "license": "Apache-2.0", "dependencies": { + "@finos/vuu-datatable": "0.0.26", "@finos/vuu-icons": "0.0.26", "@finos/vuu-layout": "0.0.26", "@finos/vuu-theme": "0.0.26", @@ -11984,7 +12036,10 @@ "@salt-ds/core": "1.37.1", "@salt-ds/theme": "1.23.1" }, - "devDependencies": {}, + "devDependencies": { + "@finos/vuu-data-types": "0.0.26", + "@finos/vuu-table-types": "0.0.26" + }, "peerDependencies": { "clsx": "^2.0.0", "react": ">=17.0.2", diff --git a/vuu-ui/packages/vuu-data-local/src/tree-data-source/TreeDataSource.ts b/vuu-ui/packages/vuu-data-local/src/tree-data-source/TreeDataSource.ts index 7fef467ff..20820f858 100644 --- a/vuu-ui/packages/vuu-data-local/src/tree-data-source/TreeDataSource.ts +++ b/vuu-ui/packages/vuu-data-local/src/tree-data-source/TreeDataSource.ts @@ -114,6 +114,8 @@ export class TreeDataSource extends BaseDataSource { }; } + console.log({ selectedKeyValues }); + if (this.#status !== "initialising") { //TODO check if subscription details are still the same return; diff --git a/vuu-ui/packages/vuu-ui-controls/src/split-button/SplitButton.css b/vuu-ui/packages/vuu-ui-controls/src/split-button/SplitButton.css index 176d79d17..2104ebc80 100644 --- a/vuu-ui/packages/vuu-ui-controls/src/split-button/SplitButton.css +++ b/vuu-ui/packages/vuu-ui-controls/src/split-button/SplitButton.css @@ -104,7 +104,7 @@ .vuuSplitButton-cta { --split-background: var(--background, var(--salt-actionable-accented-bold-background)); - --split-background-active: var(--salt-actionable-accented-bold-background-active; + --split-background-active: var(--salt-actionable-accented-bold-background-active); --split-color-active: var(--salt-actionable-bold-foreground-active); } .vuuSplitButton-cta:hover:not(.vuuSplitButton-disabled) { diff --git a/vuu-ui/showcase/showcase.config.json b/vuu-ui/showcase/showcase.config.json index 19df4d4d4..49ac53c1f 100644 --- a/vuu-ui/showcase/showcase.config.json +++ b/vuu-ui/showcase/showcase.config.json @@ -3,5 +3,5 @@ "port": 3100 }, "version": "1.0.0", - "exhibits": "./src/examples" + "exhibitsPath": "./src/examples" } diff --git a/vuu-ui/tools/showcase-cli/README.md b/vuu-ui/tools/showcase-cli/README.md index 84cce5b80..f58766d1c 100644 --- a/vuu-ui/tools/showcase-cli/README.md +++ b/vuu-ui/tools/showcase-cli/README.md @@ -2,7 +2,7 @@ ## startup sequence -#### cli.mjs +#### cli.js - load index.html from templates - get config file from input args, default to 'showcase.config.json' @@ -25,3 +25,20 @@ - integrate into vuu cli, using stricli. Parameter parsing will happen there - use jumpgen to monitor file system for new/edited exhibits in dev mode + +## Running + +run npm script from showcase + +showcase config file `showcase.config.json` defines following + +- http-server + - port +- version +- exhibits ' ./src/examples' + +``` +npm run showcase-cli +``` + +runs showcase-cli/cli.js diff --git a/vuu-ui/tools/showcase-cli/cli/buildPackageTree.ts b/vuu-ui/tools/showcase-cli/cli/buildPackageTree.ts index 03a3d6cf8..8678f886d 100644 --- a/vuu-ui/tools/showcase-cli/cli/buildPackageTree.ts +++ b/vuu-ui/tools/showcase-cli/cli/buildPackageTree.ts @@ -1,9 +1,11 @@ import fs from "fs"; import path from "path"; -const OUT = "./src/generated/stories.json"; +export interface ExhibitsJson { + [key: string]: string | ExhibitsJson; +} -export const buildPackageTree = (dir: string, tree = {}) => { +export const buildPackageTree = (dir: string, tree = {}): ExhibitsJson => { fs.readdirSync(dir).forEach((fileName) => { const filePath = path.join(dir, fileName); if (fs.lstatSync(filePath).isDirectory()) { diff --git a/vuu-ui/tools/showcase-cli/cli.js b/vuu-ui/tools/showcase-cli/cli/cli.js similarity index 63% rename from vuu-ui/tools/showcase-cli/cli.js rename to vuu-ui/tools/showcase-cli/cli/cli.js index 556ff4208..3aab26131 100755 --- a/vuu-ui/tools/showcase-cli/cli.js +++ b/vuu-ui/tools/showcase-cli/cli/cli.js @@ -2,16 +2,11 @@ import fs from "fs"; import path from "path"; -import { - copyFiles, - createFolder, - readJson, - writeFile, -} from "./cli/cli-utils.ts"; -import indexHtml from "./templates/index.html.ts"; +import { copyFiles, createFolder, readJson, writeFile } from "./cli-utils.ts"; +import indexHtml from "../templates/index.html.ts"; import { fileURLToPath } from "url"; -import start from "./cli/main.ts"; -import { buildPackageTree } from "./cli/buildPackageTree"; +import prepare from "./prepare.ts"; +import start from "./main.ts"; /** Parse the command line */ var args = process.argv.slice(2); @@ -37,11 +32,11 @@ if (args.length === 0) { } } -const distFolder = path.resolve(fileURLToPath(import.meta.url), "../dist"); +const distFolder = path.resolve(fileURLToPath(import.meta.url), "../../dist"); if (!fs.existsSync(".showcase")) { createFolder(".showcase"); - // DOn't do this until we create importmaps + // Don't do this until we create importmaps await writeFile(indexHtml, "./.showcase/index.html"); } else { console.log(".showcase folder present and correct"); @@ -49,24 +44,24 @@ if (!fs.existsSync(".showcase")) { // TODO check whether dist files already present in .showcase if (fs.existsSync(distFolder)) { + console.log(`copy dist files from dist folder ${distFolder} to .showcase `); copyFiles(distFolder, "./.showcase"); +} else { + console.log(`no dist folder ${distFolder}`); } const config = readJson(configFilePath); -//TODO use type validator to check config file -const { exhibits } = config; -if (!fs.existsSync(exhibits)) { - console.log("Error: Exhibits location doesn't exist. Given: ", exhibits); - process.exit(); -} +const [exhibitsJson, treeSourceJson] = await prepare(config); -const stories = buildPackageTree(exhibits); await writeFile( - `export default ${JSON.stringify(stories, null, 2)};`, + `export default ${JSON.stringify(exhibitsJson, null, 2)};`, "./.showcase/exhibits.js", ); -console.log(JSON.stringify(stories, null, 2)); +await writeFile( + `export default ${JSON.stringify(treeSourceJson, null, 2)};`, + "./.showcase/treeSourceJson.js", +); -start(config); +start(config, exhibitsJson, treeSourceJson); diff --git a/vuu-ui/tools/showcase-cli/cli/main.ts b/vuu-ui/tools/showcase-cli/cli/main.ts index 0429e2089..869dd840e 100644 --- a/vuu-ui/tools/showcase-cli/cli/main.ts +++ b/vuu-ui/tools/showcase-cli/cli/main.ts @@ -8,12 +8,6 @@ export type ShowcaseConfig = { }; export default async (config: ShowcaseConfig) => { - // fs.writeFile(OUT, JSON.stringify(stories, null, 2), (err) => { - // if (err) { - // console.log(err); - // } - // }); - const server = await createServer({ build: { manifest: true, diff --git a/vuu-ui/tools/showcase-cli/cli/prepare.ts b/vuu-ui/tools/showcase-cli/cli/prepare.ts new file mode 100644 index 000000000..8a3b689da --- /dev/null +++ b/vuu-ui/tools/showcase-cli/cli/prepare.ts @@ -0,0 +1,24 @@ +import fs from "fs"; +import { buildPackageTree, ExhibitsJson } from "./buildPackageTree.ts"; +import { writeFile } from "./cli-utils.ts"; +import { treeSourceFromFileSystem } from "./treeSourceFromFileSystem.ts"; +import { TreeSourceNode } from "@finos/vuu-utils"; + +export default async (config): Promise<[ExhibitsJson, TreeSourceNode[]]> => { + console.log("prepare"); + + //TODO use type validator to check config file + const { exhibitsPath } = config; + if (!fs.existsSync(exhibitsPath)) { + console.log( + "Error: Exhibits location doesn't exist. Given: ", + exhibitsPath, + ); + process.exit(); + } + + const exhibits = buildPackageTree(exhibitsPath); + const treeSource = treeSourceFromFileSystem(exhibits); + + return [exhibits, treeSource]; +}; diff --git a/vuu-ui/tools/showcase-cli/cli/treeSourceFromFileSystem.ts b/vuu-ui/tools/showcase-cli/cli/treeSourceFromFileSystem.ts new file mode 100644 index 000000000..28ebdd67e --- /dev/null +++ b/vuu-ui/tools/showcase-cli/cli/treeSourceFromFileSystem.ts @@ -0,0 +1,46 @@ +import type { Module, TreeSourceNode } from "@finos/vuu-utils"; +import { ExhibitsJson } from "./buildPackageTree"; + +export type VuuExample = { + (props?: any): JSX.Element; + displaySequence: number; +}; + +export type ExamplesModule = Module; + +const getFileType = (filePath: string) => { + const pos = filePath.lastIndexOf("."); + if (pos === -1) { + throw Error(`file path ${filePath} has no file type suffix`); + } + return filePath.slice(pos + 1); +}; + +export const treeSourceFromFileSystem = ( + exhibits: ExhibitsJson, + prefix = "", + icon = "folder", +): TreeSourceNode[] => { + const entries = Object.entries(exhibits); + return entries.map(([label, nestedExhibits]) => { + const id = `${prefix}${label}`; + // TODO how can we know when a potential docs node has docs + // console.log(`id=${id}`); + if (typeof nestedExhibits === "string") { + const fileType = getFileType(nestedExhibits); + return { + fileType, + id, + icon: "rings", + label, + loaded: false, + }; + } + return { + id, + icon, + label, + childNodes: treeSourceFromFileSystem(nestedExhibits, `${id}/`, "box"), + }; + }); +}; diff --git a/vuu-ui/tools/showcase-cli/package.json b/vuu-ui/tools/showcase-cli/package.json index 1c46d7b4a..d6b559393 100644 --- a/vuu-ui/tools/showcase-cli/package.json +++ b/vuu-ui/tools/showcase-cli/package.json @@ -3,7 +3,7 @@ "version": "1.0.0", "description": "", "main": "index.js", - "bin": "./cli.js", + "bin": "./cli/cli.js", "scripts": { "build": "node ./scripts/build.mjs" }, diff --git a/vuu-ui/tools/showcase-cli/scripts/build.mjs b/vuu-ui/tools/showcase-cli/scripts/build.mjs index 64adeb0a1..9ea95a4e6 100644 --- a/vuu-ui/tools/showcase-cli/scripts/build.mjs +++ b/vuu-ui/tools/showcase-cli/scripts/build.mjs @@ -11,7 +11,7 @@ import { build } from "../../../scripts/esbuild.mjs"; // TODO use a separate build call for each theme, without bundling // const themes = ["./src/themes/salt-theme.ts", "./src/themes/vuu-theme.ts"]; -const entryPoints = ["src/main.ts"]; +const entryPoints = ["showcase-ui/main.ts"]; const outdir = "dist"; diff --git a/vuu-ui/tools/showcase-cli/src/App.css b/vuu-ui/tools/showcase-cli/showcase-ui/App.css similarity index 100% rename from vuu-ui/tools/showcase-cli/src/App.css rename to vuu-ui/tools/showcase-cli/showcase-ui/App.css diff --git a/vuu-ui/tools/showcase-cli/src/App.tsx b/vuu-ui/tools/showcase-cli/showcase-ui/App.tsx similarity index 83% rename from vuu-ui/tools/showcase-cli/src/App.tsx rename to vuu-ui/tools/showcase-cli/showcase-ui/App.tsx index 4c609bc26..b61f3e7a1 100644 --- a/vuu-ui/tools/showcase-cli/src/App.tsx +++ b/vuu-ui/tools/showcase-cli/showcase-ui/App.tsx @@ -1,7 +1,7 @@ -import React from "react"; -import { Flexbox } from "@finos/vuu-layout"; -import { Tree } from "@finos/vuu-ui-controls"; -import { Density, ThemeMode } from "@finos/vuu-utils"; +import { TreeTable } from "@finos/vuu-datatable"; +import { Flexbox, View } from "@finos/vuu-layout"; +import { ThemeSwitch } from "@finos/vuu-shell"; +import { Density, ThemeMode, TreeSourceNode } from "@finos/vuu-utils"; import { Button, SaltProvider, @@ -9,18 +9,16 @@ import { ToggleButton, ToggleButtonGroup, } from "@salt-ds/core"; -import { useCallback, useEffect, useMemo, useState } from "react"; +import React, { useCallback, useEffect, useMemo, useState } from "react"; import { useLocation } from "react-router-dom"; import { IFrame } from "./components"; -import { loadTheme } from "./showcase-utils"; -import type { ExhibitsJson } from "./exhibit-utils"; -import { ThemeSwitch } from "@finos/vuu-shell"; +import { keysFromPath, loadTheme } from "./showcase-utils"; +import { useShowcaseApp } from "./useShowcaseApp"; import "./App.css"; -import { useShowcaseApp } from "./useShowcaseApp"; export interface AppProps { - exhibits: ExhibitsJson; + treeSource: TreeSourceNode[]; } type ThemeDescriptor = { label?: string; id: string }; @@ -46,10 +44,12 @@ const availableDensity: DensityDescriptor[] = [ { id: "touch", label: "Touch" }, ]; -export const App = ({ exhibits }: AppProps) => { +export const App = ({ treeSource }: AppProps) => { const [themeReady, setThemeReady] = useState(false); - const { onSelectionChange, source } = useShowcaseApp({ exhibits }); + const { onSelect, source } = useShowcaseApp({ + treeSource, + }); useEffect(() => { loadTheme("vuu-theme").then(() => { @@ -59,6 +59,7 @@ export const App = ({ exhibits }: AppProps) => { // // TODO cache source in localStorage const { pathname } = useLocation(); + const [themeIndex, setThemeIndex] = useState(2); const [themeModeIndex, setThemeModeIndex] = useState(0); const [densityIndex, setDensityIndex] = useState(0); @@ -104,15 +105,23 @@ export const App = ({ exhibits }: AppProps) => { Vuu Showcase - + + + Object.entries(examples) @@ -18,11 +18,20 @@ const createRoutes = (examples: ExhibitsJson, prefix = ""): JSX.Element[] => : routes.concat(); }, []); -export const Showcase = ({ exhibits }: { exhibits: ExhibitsJson }) => { +export const Showcase = ({ + exhibits, + treeSource, +}: { + exhibits: ExhibitsJson; + treeSource: TreeSourceNode[]; +}) => { return ( - }> + } + > {createRoutes(exhibits)} diff --git a/vuu-ui/tools/showcase-cli/src/ShowcaseStandalone.tsx b/vuu-ui/tools/showcase-cli/showcase-ui/ShowcaseStandalone.tsx similarity index 100% rename from vuu-ui/tools/showcase-cli/src/ShowcaseStandalone.tsx rename to vuu-ui/tools/showcase-cli/showcase-ui/ShowcaseStandalone.tsx diff --git a/vuu-ui/tools/showcase-cli/src/components/iframe/IFrame.tsx b/vuu-ui/tools/showcase-cli/showcase-ui/components/iframe/IFrame.tsx similarity index 100% rename from vuu-ui/tools/showcase-cli/src/components/iframe/IFrame.tsx rename to vuu-ui/tools/showcase-cli/showcase-ui/components/iframe/IFrame.tsx diff --git a/vuu-ui/tools/showcase-cli/src/components/iframe/IFrameContextProvider.tsx b/vuu-ui/tools/showcase-cli/showcase-ui/components/iframe/IFrameContextProvider.tsx similarity index 100% rename from vuu-ui/tools/showcase-cli/src/components/iframe/IFrameContextProvider.tsx rename to vuu-ui/tools/showcase-cli/showcase-ui/components/iframe/IFrameContextProvider.tsx diff --git a/vuu-ui/tools/showcase-cli/src/components/iframe/index.ts b/vuu-ui/tools/showcase-cli/showcase-ui/components/iframe/index.ts similarity index 100% rename from vuu-ui/tools/showcase-cli/src/components/iframe/index.ts rename to vuu-ui/tools/showcase-cli/showcase-ui/components/iframe/index.ts diff --git a/vuu-ui/tools/showcase-cli/src/components/index.ts b/vuu-ui/tools/showcase-cli/showcase-ui/components/index.ts similarity index 100% rename from vuu-ui/tools/showcase-cli/src/components/index.ts rename to vuu-ui/tools/showcase-cli/showcase-ui/components/index.ts diff --git a/vuu-ui/tools/showcase-cli/src/exhibit-utils.ts b/vuu-ui/tools/showcase-cli/showcase-ui/exhibit-utils.ts similarity index 100% rename from vuu-ui/tools/showcase-cli/src/exhibit-utils.ts rename to vuu-ui/tools/showcase-cli/showcase-ui/exhibit-utils.ts diff --git a/vuu-ui/tools/showcase-cli/src/index-main.tsx b/vuu-ui/tools/showcase-cli/showcase-ui/index-main.tsx similarity index 60% rename from vuu-ui/tools/showcase-cli/src/index-main.tsx rename to vuu-ui/tools/showcase-cli/showcase-ui/index-main.tsx index 052634561..66beb4a9f 100644 --- a/vuu-ui/tools/showcase-cli/src/index-main.tsx +++ b/vuu-ui/tools/showcase-cli/showcase-ui/index-main.tsx @@ -2,10 +2,14 @@ import ReactDOM from "react-dom"; import React from "react"; import { Showcase } from "./Showcase"; import { ExhibitsJson } from "./exhibit-utils"; +import { TreeSourceNode } from "@finos/vuu-utils"; -export default (exhibits: ExhibitsJson) => { +export default (exhibits: ExhibitsJson, treeSource: TreeSourceNode[]) => { const root = document.getElementById("root") as HTMLDivElement; // The full Showcase shell loads all examples in order to render the Navigation Tree. This can // be a bit slow in dev mode. - ReactDOM.render(, root); + ReactDOM.render( + , + root, + ); }; diff --git a/vuu-ui/tools/showcase-cli/src/index-standalone.tsx b/vuu-ui/tools/showcase-cli/showcase-ui/index-standalone.tsx similarity index 100% rename from vuu-ui/tools/showcase-cli/src/index-standalone.tsx rename to vuu-ui/tools/showcase-cli/showcase-ui/index-standalone.tsx diff --git a/vuu-ui/tools/showcase-cli/src/index.ts b/vuu-ui/tools/showcase-cli/showcase-ui/index.ts similarity index 100% rename from vuu-ui/tools/showcase-cli/src/index.ts rename to vuu-ui/tools/showcase-cli/showcase-ui/index.ts diff --git a/vuu-ui/tools/showcase-cli/src/main.ts b/vuu-ui/tools/showcase-cli/showcase-ui/main.ts similarity index 62% rename from vuu-ui/tools/showcase-cli/src/main.ts rename to vuu-ui/tools/showcase-cli/showcase-ui/main.ts index c18ba96db..c01f29b55 100644 --- a/vuu-ui/tools/showcase-cli/src/main.ts +++ b/vuu-ui/tools/showcase-cli/showcase-ui/main.ts @@ -1,7 +1,7 @@ -import { hasUrlParameter } from "@finos/vuu-utils"; +import { hasUrlParameter, TreeSourceNode } from "@finos/vuu-utils"; import { ExhibitsJson } from "./exhibit-utils"; -export default async (exhibits: ExhibitsJson) => { +export default async (exhibits: ExhibitsJson, treeSource: TreeSourceNode[]) => { console.log("Showcase start", { exhibits, }); @@ -10,6 +10,6 @@ export default async (exhibits: ExhibitsJson) => { start(exhibits); } else { const { default: start } = await import("./index-main"); - start(exhibits); + start(exhibits, treeSource); } }; diff --git a/vuu-ui/tools/showcase-cli/src/showcase-utils.ts b/vuu-ui/tools/showcase-cli/showcase-ui/showcase-utils.ts similarity index 90% rename from vuu-ui/tools/showcase-cli/src/showcase-utils.ts rename to vuu-ui/tools/showcase-cli/showcase-ui/showcase-utils.ts index 877ed2d8e..3a7903633 100644 --- a/vuu-ui/tools/showcase-cli/src/showcase-utils.ts +++ b/vuu-ui/tools/showcase-cli/showcase-ui/showcase-utils.ts @@ -35,6 +35,16 @@ export const byDisplaySequence = ([, f1]: VuuTuple, [, f2]: VuuTuple) => { } }; +export const pathFromKey = (key: string) => key.slice(5).split("|").join("/"); +export const keysFromPath = (path: string) => { + console.log(`path = ${path}`); + if (path === "/") { + return undefined; + } else { + return [`$root${path.split("/").join("|")}`]; + } +}; + export const pathToExample = (path: string): [string[], string] => { const endOfImportPath = path.lastIndexOf("/"); const importPath = diff --git a/vuu-ui/tools/showcase-cli/src/themes/vuu-theme.ts b/vuu-ui/tools/showcase-cli/showcase-ui/themes/vuu-theme.ts similarity index 100% rename from vuu-ui/tools/showcase-cli/src/themes/vuu-theme.ts rename to vuu-ui/tools/showcase-cli/showcase-ui/themes/vuu-theme.ts diff --git a/vuu-ui/tools/showcase-cli/showcase-ui/useShowcaseApp.ts b/vuu-ui/tools/showcase-cli/showcase-ui/useShowcaseApp.ts new file mode 100644 index 000000000..5bc6fd7a0 --- /dev/null +++ b/vuu-ui/tools/showcase-cli/showcase-ui/useShowcaseApp.ts @@ -0,0 +1,60 @@ +import type { TableRowSelectHandler } from "@finos/vuu-table-types"; +import type { TreeSourceNode } from "@finos/vuu-utils"; +import { useCallback, useMemo } from "react"; +import { useNavigate } from "react-router-dom"; +import type { AppProps } from "./App"; +import { ExhibitsJson } from "./exhibit-utils"; +import { pathFromKey } from "./showcase-utils"; + +const getTargetExhibit = (source: TreeSourceNode[], path: string) => { + const steps = path.split("/"); + const root = steps.slice(0, -1).join("/"); + + let node: string | ExhibitsJson = source; + let pathRoot: string[] = []; + while (steps.length) { + const step = steps.shift() as string; + node = node[step]; + } + if (typeof node === "string") { + return `${root}/${node}`; + } else { + throw Error(`unexpected leaf node ${JSON.stringify(node)}`); + } +}; + +export const useShowcaseApp = ({ treeSource }: AppProps) => { + const navigate = useNavigate(); + + const source = useMemo(() => treeSource, [treeSource]); + + const handleChange = async ([selected]: TreeSourceNode[]) => { + console.log(JSON.stringify(selected, null, 2)); + + // const sourceTarget = getTargetExhibit(treeSource, selected.id); + // if (sourceTarget?.endsWith(".tsx")) { + // console.log(`need to resolve ${sourceTarget}`); + // const module = await import( + // /* @vite-ignore */ + // `exhibits:src/examples/${sourceTarget}` + // ); + // console.log(module); + }; + // navigate(selected.id); + // }; + + const handleSelect: TableRowSelectHandler = useCallback(async (row) => { + if (row) { + const path = pathFromKey(row.key); + console.log(`selected Path ${path}`, { + row, + }); + //navigate(path); + } + }, []); + + return { + onSelect: handleSelect, + source, + }; +}; diff --git a/vuu-ui/tools/showcase-cli/src/useShowcaseApp.ts b/vuu-ui/tools/showcase-cli/src/useShowcaseApp.ts deleted file mode 100644 index f7a82f860..000000000 --- a/vuu-ui/tools/showcase-cli/src/useShowcaseApp.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { TreeSourceNode } from "@finos/vuu-ui-controls"; -import { useCallback, useMemo } from "react"; -import { useNavigate } from "react-router-dom"; -import { AppProps } from "./App"; -import { ExhibitsJson } from "./exhibit-utils"; - -const sourceFromImports = ( - exhibits: ExhibitsJson, - prefix = "", - icon = "folder", -): TreeSourceNode[] => - Object.entries(exhibits).map(([label, exhibits]) => { - const id = `${prefix}${label}`; - if (typeof exhibits === "string") { - return { - id, - icon: "rings", - label, - }; - } - return { - id, - icon, - label, - childNodes: sourceFromImports(exhibits, `${id}/`, "box"), - }; - }); - -const getTargetExhibit = (exhibits: ExhibitsJson, path: string) => { - const steps = path.split("/"); - const root = steps.slice(0, -1).join("/"); - - let node: string | ExhibitsJson = exhibits; - let pathRoot: string[] = []; - while (steps.length) { - const step = steps.shift() as string; - node = node[step]; - } - if (typeof node === "string") { - return `${root}/${node}`; - } else { - throw Error(`unexpected leaf node ${JSON.stringify(node)}`); - } -}; - -export const useShowcaseApp = ({ exhibits }: AppProps) => { - const navigate = useNavigate(); - - const source = useMemo(() => sourceFromImports(exhibits), [exhibits]); - - const handleChange = async ([selected]: TreeSourceNode[]) => { - console.log(JSON.stringify(selected, null, 2)); - - const sourceTarget = getTargetExhibit(exhibits, selected.id); - if (sourceTarget?.endsWith(".tsx")) { - const module = await import( - /* @vite-ignore */ - `exhibits:src/examples/${sourceTarget}` - ); - console.log(module); - } - // navigate(selected.id); - }; - - return { - onSelectionChange: handleChange, - source, - }; -}; diff --git a/vuu-ui/tools/showcase-cli/templates/index.html.ts b/vuu-ui/tools/showcase-cli/templates/index.html.ts index b03b28fcb..7e6831114 100644 --- a/vuu-ui/tools/showcase-cli/templates/index.html.ts +++ b/vuu-ui/tools/showcase-cli/templates/index.html.ts @@ -12,8 +12,9 @@ export default ` diff --git a/vuu-ui/tools/vuu-showcase/src/showcase-utils.ts b/vuu-ui/tools/vuu-showcase/src/showcase-utils.ts index 02560f567..7e555d1ed 100644 --- a/vuu-ui/tools/vuu-showcase/src/showcase-utils.ts +++ b/vuu-ui/tools/vuu-showcase/src/showcase-utils.ts @@ -36,8 +36,14 @@ export const byDisplaySequence = ([, f1]: VuuTuple, [, f2]: VuuTuple) => { }; export const pathFromKey = (key: string) => key.slice(5).split("|").join("/"); -export const keyFromPath = (path: string) => - `$root${path.split("/").join("|")}`; +export const keyFromPath = (path: string) => { + console.log(`path = ${path}`); + if (path === "/") { + return []; + } else { + return `$root${path.split("/").join("|")}`; + } +}; export const pathToExample = (path: string): [string[], string] => { const endOfImportPath = path.lastIndexOf("/");