Skip to content

Commit

Permalink
direct modal management
Browse files Browse the repository at this point in the history
  • Loading branch information
thoughtspile committed Jun 6, 2024
1 parent ba2b61b commit 5598455
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 87 deletions.
21 changes: 6 additions & 15 deletions src/app/Analysis/AnalysisPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Index, Show, createSignal } from "solid-js";
import { FaSolidMagnifyingGlass, FaSolidXmark } from "solid-icons/fa";
import { Fab } from "../ui/Fab";
import { Index, Show } from "solid-js";
import { FaSolidXmark } from "solid-icons/fa";
import { Modal } from "../ui/Modal";
import { FilterLayer } from "./FilterLayer";
import { AggregationLayer } from "./AggregationLayer";
Expand All @@ -16,12 +15,13 @@ import type { Pipeline } from "../../data/pipeline";
import { ComputeLayer } from "./ComputeLayer";

interface AnalysisPanelProps {
visible: boolean;
onClose: () => void;
pipeline: Pipeline;
update: (f: Pipeline) => void;
}

export function AnalysisPanel(props: AnalysisPanelProps) {
const [visible, setVisible] = createSignal(false);
const staging = () => props.pipeline.flow.filter((s) => s.mode !== "order");
function addStep(mode: FlowStep["mode"]) {
setStaging(flowActions.addStep(staging(), mode));
Expand All @@ -31,17 +31,8 @@ export function AnalysisPanel(props: AnalysisPanelProps) {
}

return (
<Show
when={visible()}
fallback={
<Fab
primary
onClick={() => setVisible(true)}
icon={<FaSolidMagnifyingGlass />}
/>
}
>
<Modal close={() => setVisible(false)}>
<Show when={props.visible}>
<Modal close={props.onClose}>
<div class={styles.Form}>
<Index each={staging().filter((s) => s.mode !== "order")}>
{(s, i) => (
Expand Down
41 changes: 19 additions & 22 deletions src/app/Charts/ChartsPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { For, Show, createSignal } from "solid-js";
import { FaSolidChartSimple, FaSolidPlus } from "solid-icons/fa";
import { FaSolidPlus } from "solid-icons/fa";
import type ColumnTable from "arquero/dist/types/table/column-table";
import { Fab } from "../ui/Fab";
import { Modal } from "../ui/Modal";
import { FormButton } from "../ui/Form";
import { chartConfig, type ChartConfig } from "./chartConfig";
Expand All @@ -10,10 +9,11 @@ import styles from "./ChartsPanel.module.css";

interface ChartsPanelProps {
table: ColumnTable;
visible: boolean;
onClose: () => void;
}

export function ChartsPanel(props: ChartsPanelProps) {
const [visible, setVisible] = createSignal(false);
const [charts, setCharts] = createSignal<ChartConfig[]>([chartConfig()]);
function addChart() {
setCharts([...charts(), chartConfig()]);
Expand All @@ -23,24 +23,21 @@ export function ChartsPanel(props: ChartsPanelProps) {
}

return (
<>
<Show when={visible()}>
<Modal close={() => setVisible(false)} class={styles.ChartsPanel}>
<For each={charts()}>
{(config) => (
<ChartItem
config={config}
table={props.table}
onChange={updateChart}
/>
)}
</For>
<FormButton onClick={addChart}>
<FaSolidPlus /> Add chart
</FormButton>
</Modal>
</Show>
<Fab onClick={() => setVisible(true)} icon={<FaSolidChartSimple />} />
</>
<Show when={props.visible}>
<Modal close={props.onClose} class={styles.ChartsPanel}>
<For each={charts()}>
{(config) => (
<ChartItem
config={config}
table={props.table}
onChange={updateChart}
/>
)}
</For>
<FormButton onClick={addChart}>
<FaSolidPlus /> Add chart
</FormButton>
</Modal>
</Show>
);
}
4 changes: 2 additions & 2 deletions src/app/Dashboard.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Show, createResource, createSignal, onMount } from "solid-js";
import { parseCsv } from "../data/data";
import { Table } from "./Table";
import { Welcome } from "./Welcome";
import { accessSource, persistSource } from "./fs";
import { Workspace } from "./Workspace";

export function Dashboard() {
const [initializing, setInitializing] = createSignal(true);
Expand All @@ -22,7 +22,7 @@ export function Dashboard() {
when={table()}
fallback={<Welcome onSubmit={persistSource} loading={loading()} />}
>
<Table table={table()} />
<Workspace table={table()} />
</Show>
);
}
27 changes: 2 additions & 25 deletions src/app/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,37 +20,14 @@ import { ImportFab } from "./ImportFab";
import { GitHubLogo } from "./GitHubLogo";
import { GH_REPO } from "../constants";

export function Table(props: { table: ColumnTable }) {
const [pipeline, setPipeline] = createSignal(createPipeline(props.table));

return (
<>
<TableView
table={pipeline().output}
orderBy={(col) => setPipeline(pipeline().orderBy(col))}
order={pipeline().order}
/>
<Fab
icon={<GitHubLogo />}
onClick={() => window.open(GH_REPO, "_blank")}
/>
<ImportFab />
<Export table={pipeline().output} />
<ChartsPanel table={pipeline().output} />
<AnalysisPanel pipeline={pipeline()} update={setPipeline} />
<FabContainer />
</>
);
}

const rowHeight = 19;

type TableViewProps = {
type TableProps = {
table: ColumnTable;
order: Order;
orderBy: (c: string) => void;
};
function TableView(props: TableViewProps) {
export function Table(props: TableProps) {
const [colWidths, setColWidths] = createSignal(new Map<string, number>());
const cols = () => props.table.columnNames();

Expand Down
64 changes: 64 additions & 0 deletions src/app/Workspace.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { createSignal } from "solid-js";
import "./Table.css";
import type ColumnTable from "arquero/dist/types/table/column-table";
import { AnalysisPanel } from "./Analysis";
import { Fab, FabContainer } from "./ui/Fab";
import { createPipeline } from "../data/pipeline";
import { Export } from "./Export";
import { ChartsPanel } from "./Charts";
import { ImportFab } from "./ImportFab";
import { GitHubLogo } from "./GitHubLogo";
import { GH_REPO } from "../constants";
import { Table } from "./Table";
import { FaSolidChartSimple, FaSolidMagnifyingGlass } from "solid-icons/fa";

type Modals = "analysis" | "charts";

export function Workspace(props: { table: ColumnTable }) {
const [modalStack, setModalStack] = createSignal<Modals[]>([]);
const openModal = (m: Modals) =>
setModalStack(
modalStack().includes(m) ? modalStack() : [...modalStack(), m],
);
const closeModal = (m: Modals) =>
setModalStack(modalStack().filter((t) => t !== m));
const [pipeline, setPipeline] = createSignal(createPipeline(props.table));

return (
<>
<Table
table={pipeline().output}
orderBy={(col) => setPipeline(pipeline().orderBy(col))}
order={pipeline().order}
/>
<FabContainer>
<Fab
icon={<GitHubLogo />}
onClick={() => window.open(GH_REPO, "_blank")}
/>
<ImportFab />
<Export table={pipeline().output} />
<Fab
onClick={() => openModal("charts")}
icon={<FaSolidChartSimple />}
/>
<Fab
primary
onClick={() => openModal("analysis")}
icon={<FaSolidMagnifyingGlass />}
/>
</FabContainer>
<AnalysisPanel
pipeline={pipeline()}
update={setPipeline}
onClose={() => closeModal("analysis")}
visible={modalStack().includes("analysis")}
/>
<ChartsPanel
table={pipeline().output}
visible={modalStack().includes("charts")}
onClose={() => closeModal("charts")}
/>
</>
);
}
39 changes: 16 additions & 23 deletions src/app/ui/Fab.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,18 @@
import type { JSX } from "solid-js/jsx-runtime";
import styles from "./Fab.module.css";
import { Portal } from "solid-js/web";

const containerId = "fab-container";

export function Fab(props: {
onClick: () => void;
icon: JSX.Element;
primary?: boolean;
}) {
return (
<Portal mount={document.getElementById(containerId)}>
<button
onClick={props.onClick}
classList={{ [styles.Fab]: true, [styles.primary]: props.primary }}
>
{props.icon}
</button>
</Portal>
<button
onClick={props.onClick}
classList={{ [styles.Fab]: true, [styles.primary]: props.primary }}
>
{props.icon}
</button>
);
}

Expand All @@ -27,19 +22,17 @@ export function FabUpload(props: {
accept: string;
}) {
return (
<Portal mount={document.getElementById(containerId)}>
<label class={styles.Fab}>
{props.icon}
<input
type="file"
accept={props.accept}
onInput={(e) => props.onUpload(e.currentTarget.files[0])}
/>
</label>
</Portal>
<label class={styles.Fab}>
{props.icon}
<input
type="file"
accept={props.accept}
onInput={(e) => props.onUpload(e.currentTarget.files[0])}
/>
</label>
);
}

export function FabContainer() {
return <div class={styles.FabContainer} id={containerId} />;
export function FabContainer(props: { children: JSX.Element[] }) {
return <div class={styles.FabContainer} {...props} />;
}

0 comments on commit 5598455

Please sign in to comment.