Split examples into individual stories

This commit is contained in:
Nathan Evans 2022-09-20 15:59:07 -07:00
Родитель cb266b5a1b
Коммит b8d9fb00bd
27 изменённых файлов: 144 добавлений и 221 удалений

Просмотреть файл

@ -9,7 +9,7 @@
"error",
[
{
"expectedExtensions": [".js", ".css"]
"expectedExtensions": [".js", ".css", ".json"]
}
]
],

Просмотреть файл

@ -1,62 +0,0 @@
/*!
* Copyright (c) Microsoft. All rights reserved.
* Licensed under the MIT license. See LICENSE file in the project.
*/
import type { TableContainer } from '@datashaper/tables'
import type { Workflow } from '@datashaper/workflow'
import { memo, useState } from 'react'
import { useWorkflow } from '../../../hooks/common.js'
import { useHandleStepOutputChanged } from '../../../hooks/useHandleStepOutputChanged.js'
import { useHandleStepSave } from '../../../hooks/useHandleStepSave.js'
import { useStepOutputs } from '../../../hooks/useStepOutputs.js'
import { useWorkflowSteps } from '../../../hooks/useWorkflowSteps.js'
import { ExamplesDropdown } from './components/ExamplesDropdown.js'
import { StepOutput } from './components/StepOutput.js'
import { useInputTables } from './Examples.hooks.js'
import {
Container,
Description,
Dropdown,
Header,
Output,
} from './Examples.styles.js'
export interface ExamplesProps {
inputs: TableContainer[]
}
export const Examples: React.FC<ExamplesProps> = memo(function Examples({
inputs,
}) {
const tables = useInputTables(inputs)
const [workflow, setWorkflow] = useState<Workflow | undefined>(undefined)
const wf = useWorkflow(workflow, tables)
const steps = useWorkflowSteps(wf)
const outputs = useStepOutputs(wf, (idx: number) => `step-${idx}`) as string[]
const onStepSave = useHandleStepSave(wf)
const onStepOutputChange = useHandleStepOutputChanged(wf)
return (
<Container>
<Header>
<Dropdown>
<ExamplesDropdown onChange={setWorkflow} />
</Dropdown>
<Description>{workflow?.description || ''}</Description>
</Header>
<Output>
{steps.map((step, index) => (
<StepOutput
step={step}
index={index}
key={step.id}
workflow={wf}
output={outputs[index]!}
onStepChange={onStepSave}
onStepOutputChange={onStepOutputChange}
/>
))}
</Output>
</Container>
)
})

Просмотреть файл

@ -1,62 +0,0 @@
/*!
* Copyright (c) Microsoft. All rights reserved.
* Licensed under the MIT license. See LICENSE file in the project.
*/
import type { WorkflowSchema } from '@datashaper/schema'
import { Workflow } from '@datashaper/workflow'
import type { IDropdownOption } from '@fluentui/react'
import { useCallback, useMemo } from 'react'
import aggregatedLookup from '../../specs/aggregated-lookup.json'
import binning from '../../specs/binning.json'
import categorical from '../../specs/categorical.json'
import dropdown from '../../specs/dropdown.json'
import everyOperation from '../../specs/every-operation.json'
import groupby from '../../specs/groupby.json'
import multistepBinarize from '../../specs/multistep-binarize.json'
import onehotunhot from '../../specs/onehot-unhot.json'
import sparkbar from '../../specs/sparkbar.json'
import sparkline from '../../specs/sparkline.json'
import spreadhot from '../../specs/spreadhot.json'
import type { ExamplesDropdownProps } from './ExamplesDropdown.types.js'
const specs: Array<WorkflowSchema> = [
aggregatedLookup as unknown as WorkflowSchema,
binning as unknown as WorkflowSchema,
everyOperation as unknown as WorkflowSchema,
multistepBinarize as unknown as WorkflowSchema,
sparkbar as unknown as WorkflowSchema,
sparkline as unknown as WorkflowSchema,
categorical as unknown as WorkflowSchema,
dropdown as unknown as WorkflowSchema,
groupby as unknown as WorkflowSchema,
spreadhot as unknown as WorkflowSchema,
onehotunhot as unknown as WorkflowSchema,
]
export function useExampleOptions(): IDropdownOption[] {
return useMemo(
() =>
specs.map(spec => ({
key: `${spec.name}`,
text: `${spec.name}`,
})),
[],
)
}
export function useOnSelectOption(
onChange: ExamplesDropdownProps['onChange'],
): (key: string) => void {
return useCallback(
(key: string) => {
if (onChange) {
const found = specs.find(s => s.name === key)
if (found) {
onChange(new Workflow(found))
}
}
},
[onChange],
)
}

Просмотреть файл

@ -1,39 +0,0 @@
/*!
* Copyright (c) Microsoft. All rights reserved.
* Licensed under the MIT license. See LICENSE file in the project.
*/
import type { IDropdownOption } from '@fluentui/react'
import { Dropdown } from '@fluentui/react'
import { memo, useCallback, useState } from 'react'
import {
useExampleOptions,
useOnSelectOption,
} from './ExamplesDropdown.hooks.js'
import type { ExamplesDropdownProps } from './ExamplesDropdown.types.js'
export const ExamplesDropdown: React.FC<ExamplesDropdownProps> = memo(
function ExamplesDropdown({ onChange }) {
const options = useExampleOptions()
const [currentOption, setCurrentOption] = useState<string | undefined>()
const handleOptionSelected = useOnSelectOption(onChange)
const handleDropdownChange = useCallback(
(_e: any, opt: IDropdownOption<any> | undefined) => {
if (opt) {
setCurrentOption(opt.key as string)
handleOptionSelected(opt.key as string)
}
},
[setCurrentOption, handleOptionSelected],
)
return (
<Dropdown
placeholder={'Select example workflow'}
options={options}
selectedKey={currentOption}
onChange={handleDropdownChange}
/>
)
},
)

Просмотреть файл

@ -1,9 +0,0 @@
/*!
* Copyright (c) Microsoft. All rights reserved.
* Licensed under the MIT license. See LICENSE file in the project.
*/
import type { Workflow } from '@datashaper/workflow'
export interface ExamplesDropdownProps {
onChange?: (spec: Workflow | undefined) => void
}

Просмотреть файл

@ -7,6 +7,11 @@ import type { ComponentStory } from '@storybook/react'
import type { InputTablesProps } from './InputTables.js'
import { InputTables } from './InputTables.js'
const storyMetadata = {
title: 'Workflows',
}
export default storyMetadata
export const InputTablesStory: ComponentStory<typeof InputTables> = (
_args: InputTablesProps,
{ loaded: { companies, companies2, products, stocks } }: any,

Просмотреть файл

@ -4,14 +4,15 @@
*/
import type { ComponentStory } from '@storybook/react'
import type { ExamplesProps } from './Examples.js'
import { Examples } from './Examples.js'
import type { WorkflowExampleProps } from './WorkflowExample.js'
import { WorkflowExample } from './WorkflowExample.js'
export const ExamplesStory: ComponentStory<typeof Examples> = (
_args: ExamplesProps,
export const WorkflowExampleStory: ComponentStory<typeof WorkflowExample> = (
args: WorkflowExampleProps,
{ loaded: { companies, companies2, products, stocks } }: any,
): JSX.Element => (
<Examples
<WorkflowExample
{...args}
inputs={[
{
id: 'companies',
@ -32,4 +33,3 @@ export const ExamplesStory: ComponentStory<typeof Examples> = (
]}
/>
)
ExamplesStory.storyName = 'Example Workflows'

Просмотреть файл

@ -8,19 +8,6 @@ export const Container = styled.div`
margin-top: 12px;
`
export const Header = styled.div`
display: flex;
align-items: center;
gap: 20px;
margin-bottom: 20px;
`
export const Dropdown = styled.div`
width: 200px;
`
export const Description = styled.p`
margin: 0;
`
export const Description = styled.p``
export const Output = styled.div``

Просмотреть файл

@ -0,0 +1,55 @@
/*!
* Copyright (c) Microsoft. All rights reserved.
* Licensed under the MIT license. See LICENSE file in the project.
*/
import type { WorkflowSchema } from '@datashaper/schema'
import type { TableContainer } from '@datashaper/tables'
import { Workflow } from '@datashaper/workflow'
import { memo, useMemo } from 'react'
import { useWorkflow } from '../../../hooks/common.js'
import { useHandleStepOutputChanged } from '../../../hooks/useHandleStepOutputChanged.js'
import { useHandleStepSave } from '../../../hooks/useHandleStepSave.js'
import { useStepOutputs } from '../../../hooks/useStepOutputs.js'
import { useWorkflowSteps } from '../../../hooks/useWorkflowSteps.js'
import { StepOutput } from './components/StepOutput.js'
import { useInputTables } from './WorkflowExample.hooks.js'
import { Container, Description, Output } from './WorkflowExample.styles.js'
export interface WorkflowExampleProps {
schema: WorkflowSchema
inputs: TableContainer[]
}
export const WorkflowExample: React.FC<WorkflowExampleProps> = memo(
function Examples({ schema, inputs }) {
const tables = useInputTables(inputs)
const workflow = useMemo(() => new Workflow(schema), [schema])
const wf = useWorkflow(workflow, tables)
const steps = useWorkflowSteps(wf)
const outputs = useStepOutputs(
wf,
(idx: number) => `step-${idx}`,
) as string[]
const onStepSave = useHandleStepSave(wf)
const onStepOutputChange = useHandleStepOutputChanged(wf)
return (
<Container>
<Description>{workflow?.description || ''}</Description>
<Output>
{steps.map((step, index) => (
<StepOutput
step={step}
index={index}
key={step.id}
workflow={wf}
output={outputs[index]!}
onStepChange={onStepSave}
onStepOutputChange={onStepOutputChange}
/>
))}
</Output>
</Container>
)
},
)

Просмотреть файл

@ -3,7 +3,8 @@
* Licensed under the MIT license. See LICENSE file in the project.
*/
import { StepComponent, StepDescription, useDataTable } from '@datashaper/react'
import { memo } from 'react'
import { introspect } from '@datashaper/tables'
import { memo, useMemo } from 'react'
import { Section } from './Section.js'
import {
@ -26,6 +27,7 @@ export const StepOutput: React.FC<StepOutputProps> = memo(function StepOutput({
onStepOutputChange,
}) {
const table = useDataTable(output, workflow)
const metadata = useMemo(() => table && introspect(table, true), [table])
return (
<StepBlock className="step-block">
<Section title={`Step ${index + 1}`} subtitle={step.verb}>
@ -50,6 +52,7 @@ export const StepOutput: React.FC<StepOutputProps> = memo(function StepOutput({
<Table
name={output}
table={table}
metadata={metadata}
compact
features={{ smartHeaders: true, smartCells: true }}
/>

Просмотреть файл

@ -2,12 +2,73 @@
* Copyright (c) Microsoft. All rights reserved.
* Licensed under the MIT license. See LICENSE file in the project.
*/
import { ExamplesStory } from './Examples/Examples.story.js'
import { InputTablesStory } from './InputTables/InputTables.story.js'
import type { WorkflowSchema } from '@datashaper/schema'
import aggregatedLookup from './specs/aggregated-lookup.json'
import binning from './specs/binning.json'
import categorical from './specs/categorical.json'
import dropdown from './specs/dropdown.json'
import everyOperation from './specs/every-operation.json'
import multistepBinarize from './specs/multistep-binarize.json'
import onehotunhot from './specs/onehot-unhot.json'
import sparkbar from './specs/sparkbar.json'
import sparkline from './specs/sparkline.json'
import spreadhot from './specs/spreadhot.json'
import { WorkflowExampleStory } from './WorkflowExample/WorkflowExample.story.js'
const storyMetadata = {
title: 'Workflows',
title: 'Workflows/Examples',
}
export default storyMetadata
export const InputTables = InputTablesStory
export const Examples = ExamplesStory
export const EveryOperation = WorkflowExampleStory.bind({})
EveryOperation.args = {
schema: everyOperation as WorkflowSchema,
}
export const AggregatedLookup = WorkflowExampleStory.bind({})
AggregatedLookup.args = {
schema: aggregatedLookup as WorkflowSchema,
}
export const Binning = WorkflowExampleStory.bind({})
Binning.args = {
schema: binning as WorkflowSchema,
}
export const DropdownCells = WorkflowExampleStory.bind({})
DropdownCells.args = {
schema: dropdown as WorkflowSchema,
}
export const MultistepBinarize = WorkflowExampleStory.bind({})
MultistepBinarize.args = {
schema: multistepBinarize as WorkflowSchema,
}
export const OnehotUnhot = WorkflowExampleStory.bind({})
OnehotUnhot.args = {
schema: onehotunhot as WorkflowSchema,
}
OnehotUnhot.storyName = 'Onehot/Unhot'
export const Sparkbar = WorkflowExampleStory.bind({})
Sparkbar.args = {
schema: sparkbar as WorkflowSchema,
}
export const SparkbarCategorical = WorkflowExampleStory.bind({})
SparkbarCategorical.args = {
schema: categorical as WorkflowSchema,
}
SparkbarCategorical.storyName = 'Sparkbar: Categorical'
export const Sparkline = WorkflowExampleStory.bind({})
Sparkline.args = {
schema: sparkline as WorkflowSchema,
}
export const Spreadhot = WorkflowExampleStory.bind({})
Spreadhot.args = {
schema: spreadhot as WorkflowSchema,
}

Просмотреть файл

@ -1,6 +1,6 @@
{
"$schema": "../../../../../../schema/workflow.json",
"name": "Categorical sparkbar",
"name": "Sparkbar: Categorical",
"description": "Aggregates months into an array to demonstrate categorical Sparkbar cells",
"steps": [
{

Просмотреть файл

@ -389,6 +389,7 @@
"filter-1",
"fold-1",
"groupby-1",
"intersect-1",
"impute-1",
"join-1",
"lookup-1",

Просмотреть файл

@ -1,17 +0,0 @@
{
"$schema": "../../../../../../schema/workflow.json",
"name": "Group by",
"description": "",
"steps": [
{
"id": "groupby",
"verb": "groupby",
"input": { "source": "stocks" },
"args": {
"columns": ["Symbol", "Month"]
}
}
],
"input": ["stocks"],
"output": ["groupby"]
}

Просмотреть файл

@ -1,7 +1,7 @@
{
"$schema": "../../../../../../schema/workflow.json",
"name": "Onehot-unhot",
"description": "",
"description": "Performs a onehot then unhot to demonstrate reversing the encoding.",
"steps": [
{
"id": "onehot",
@ -21,5 +21,5 @@
}
],
"input": ["companies2"],
"output": ["unhot"]
"output": ["onehot", "unhot"]
}

Просмотреть файл

@ -1,7 +1,7 @@
{
"$schema": "../../../../../../schema/workflow.json",
"name": "Spread with onehot",
"description": "",
"description": "Demonstrates the spread verb with a onehot flag to encode as binary columns.",
"steps": [
{
"id": "spreadhot",

Просмотреть файл

@ -42,7 +42,7 @@ export function columnTypes(table: ColumnTable, columns?: string[]): Record<stri
// Warning: (ae-missing-release-tag) "container" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export function container(id: string, table?: ColumnTable): TableContainer;
export function container(id: string, table?: ColumnTable, metadata?: TableMetadata): TableContainer;
// Warning: (ae-missing-release-tag) "determineType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//