Skip to content

Commit

Permalink
Storybook examples + tests
Browse files Browse the repository at this point in the history
  • Loading branch information
PatrikMatiasko committed Jul 5, 2024
1 parent be4655b commit ebb14fe
Show file tree
Hide file tree
Showing 53 changed files with 407 additions and 25 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"plgd"
],
"scripts": {
":pretest": "npm-run-all test :lint",
":pretest": "npm-run-all test lint",
"test": "jest -c ./config/jest.config.js",
"test:watch": "jest -c ./config/jest.config.js --watchAll",
"build": "npm-run-all prebuild build:legacy build:modern build:node build:stable build:copy-files",
Expand All @@ -32,7 +32,7 @@
":generate:theme": "npm-run-all :generate:theme:build :generate:theme:clean",
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build",
"test:storybook": "npx playwright test",
"test:storybook": "npx playwright test --update-snapshots",
"test:storybook:ui": "npx playwright test --ui",
"test:storybook:debug": "npx playwright test --debug",
"test:storybook:report": "npx playwright show-report"
Expand Down
4 changes: 0 additions & 4 deletions src/components/Atomic/Tag/__snapshots__/Tag.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,6 @@ exports[`<Tag> render correctly - snapshot 1`] = `
display: flex;
}
.emotion-3 {
margin: 2px;
}
.emotion-4 {
display: -webkit-inline-box;
display: -webkit-inline-flex;
Expand Down
6 changes: 2 additions & 4 deletions src/components/Atomic/TagGroup/TagGroup.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,18 @@ export const parent = css`
`

export const tagGroup = css`
margin: -2px;
display: flex;
justify-content: flex-start;
align-items: center;
flex-wrap: wrap;
gap: 4px;
`

export const justifyEnd = css`
justify-content: end;
`

export const tag = css`
margin: 2px;
`
export const tag = css``

export const test = css`
position: absolute;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,6 @@ exports[`TagGroup Component renders children when there is enough space 1`] = `
display: flex;
}
.emotion-3 {
margin: 2px;
}
.emotion-4 {
display: -webkit-inline-box;
display: -webkit-inline-flex;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import isEmpty from 'lodash/isEmpty'
import isFunction from 'lodash/isFunction'
import { pick } from 'lodash'

import { Props, ResourceContentType, ResourceStatusType } from './ResourceToggleCreator.types'
import { Props, ResourceContentType, ResourceStatusType, ResourceType } from './ResourceToggleCreator.types'
import IconArrowDownNoPadding from '../../Atomic/Icon/components/IconArrowDownNoPadding'
import IconTrash from '../../Atomic/Icon/components/IconTrash'
import { convertSize } from '../../Atomic/Icon'
Expand All @@ -23,6 +23,37 @@ import IconEdit from '../../Atomic/Icon/components/IconEdit'
import TimeoutControl from '../../Atomic/TimeoutControl'
import IconArrowDetail from '../../Atomic/Icon/components/IconArrowDetail'
import Tooltip from '../../Atomic/Tooltip'
import StatusTag from '../../Atomic/StatusTag'
import { tagVariants as statusTagVariants } from '../../Atomic/StatusTag/constants'

export const getResourceStatus = (resource: ResourceType) => {
if (resource.status && ['PENDING', 'TIMEOUT'].includes(resource.status)) {
return resource.status
}

return resource.resourceUpdated?.status
}

export const getResourceStatusTag = (resource: ResourceType) => {
switch (resource.status) {
case 'PENDING':
return <StatusTag variant={statusTagVariants.WARNING}>{resource.status}</StatusTag>
case 'TIMEOUT':
return <StatusTag variant={statusTagVariants.ERROR}>{resource.status}</StatusTag>
case 'DONE':
default:
switch (resource.resourceUpdated?.status) {
case 'OK':
return <StatusTag variant={statusTagVariants.SUCCESS}>{resource.resourceUpdated?.status}</StatusTag>
case 'CANCELED':
return <StatusTag variant={statusTagVariants.WARNING}>{resource.resourceUpdated?.status}</StatusTag>
case 'ERROR':
default: {
return <StatusTag variant={statusTagVariants.ERROR}>{resource.resourceUpdated?.status}</StatusTag>
}
}
}
}

const ResourceToggleCreator: FC<Props> = (props) => {
const { className, dataTestId, defaultOpen, i18n, readOnly, id, resourceData, onCancelPending, onUpdate, responsive, statusTag } = props
Expand Down Expand Up @@ -79,21 +110,21 @@ const ResourceToggleCreator: FC<Props> = (props) => {
}, [show])

const getButtonIcon = useCallback((hasContent: boolean, hasUpdateContent: boolean, status?: ResourceStatusType) => {
if (hasContent) {
return <IconEdit />
} else if (hasUpdateContent || status === 'PENDING') {
if (hasUpdateContent || status) {
return <IconArrowDetail />
} else if (hasContent) {
return <IconEdit />
} else {
return <IconPlus />
}
}, [])

const getButtonText = useCallback(
(hasContent: boolean, hasUpdateContent: boolean, status?: ResourceStatusType) => {
if (hasContent) {
return i18n.edit
} else if (hasUpdateContent || status === 'PENDING') {
if (hasUpdateContent || status) {
return i18n.view
} else if (hasContent) {
return i18n.edit
} else {
return i18n.add
}
Expand Down Expand Up @@ -291,7 +322,7 @@ const ResourceToggleCreator: FC<Props> = (props) => {
<Spacer style={{ flex: '1 1 auto' }} type='pt-6'>
<Editor
dataTestId={dataTestId?.concat('-editor')}
disabled={disabled}
disabled={disabled || readOnly}
editorRef={(node: any) => {
editor.current = node
}}
Expand Down
203 changes: 203 additions & 0 deletions src/stories/Organism/ConditionFilter.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
import ConditionFilter from '../../components/Organisms/ConditionFilter'
import { Meta, StoryObj } from '@storybook/react'
import React, { useMemo, useState } from 'react'
import StatusTag from '../../components/Atomic/StatusTag'
import FormGroup from '../../components/Atomic/FormGroup'
import FormLabel from '../../components/Atomic/FormLabel'
import FormSelect from '../../components/Atomic/FormSelect'
import { OptionType } from '../../components/Atomic/FormSelect/FormSelect.types'
import FormInput from '../../components/Atomic/FormInput'
import Button from '../../components/Atomic/Button'
import IconPlus from '../../components/Atomic/Icon/components/IconPlus'

export default {
argTypes: {},
component: ConditionFilter,
title: 'Organism/ConditionFilter',
} as Meta<typeof ConditionFilter>

type Story = StoryObj<typeof ConditionFilter>

const FormSelectConditionFilter = () => {
const [items, setItems] = useState<string[]>([])

const [options, setOptions] = useState<OptionType[]>([
{ value: 'device-1', label: 'Device 1' },
{ value: 'device-2', label: 'Device 2' },
{ value: 'device-3', label: 'Device 3' },
{ value: 'device-4', label: 'Device 4' },
{ value: 'device-5', label: 'Device 5' },
])

const value = useMemo(() => items.map((id: string) => options?.find((o) => o.value === id) || { value: id, label: id }), [items, options])

return (
<ConditionFilter
listName='List of Selected Item'
listOfItems={items.map((id) => options?.find((o) => o.value === id)?.label || id)}
onItemDelete={(key) => {
const newItems = items.filter((_, i) => i !== key)
setItems(newItems)
}}
status={
<StatusTag lowercase={false} variant={items.length > 0 ? 'success' : 'normal'}>
{items.length > 0 ? 'Set up' : 'Not set'}
</StatusTag>
}
title='FormSelect'
>
<FormGroup id='items'>
<FormLabel text='Select Item' />
<FormSelect
checkboxOptions
creatable
isMulti
footerLinksLeft={[
{
title: 'Reset',
onClick: () => {
setItems([])
},
},
{
title: 'Done',
variant: 'primary',
onClick: (values: OptionType[]) => {
const rawValue = values.map((v) => v.value.toString())
setItems(rawValue)
},
},
]}
i18n={{
itemSelected: 'Item selected',
itemsSelected: 'Items selected',
}}
menuPortalTarget={document.body}
menuZIndex={100}
name='items'
onChange={(values: OptionType[]) => {
const rawValue = values.map((v) => v.value.toString())
setItems(rawValue)
}}
onCreateOption={(value: string | number) => {
setOptions((prev) => [...prev, { value: value.toString(), label: value.toString() }])
}}
options={options}
placeholder='Select or Create'
value={value}
/>
</FormGroup>
</ConditionFilter>
)
}

const FormInputConditionFilter = () => {
const [items, setItems] = useState<string[]>([])
const [value, setValue] = useState<string>('')

return (
<ConditionFilter
listName='List of selected Items'
listOfItems={items}
onItemDelete={(key) => {
const newVal = items?.filter((_, i) => i !== key)
setItems(newVal)
}}
status={
<StatusTag lowercase={false} variant={items?.length > 0 ? 'success' : 'normal'}>
{items?.length > 0 ? 'Set up' : 'Not set'}
</StatusTag>
}
title='FormInput'
>
<div style={{ display: 'flex', alignItems: 'flex-end', gap: '8px' }}>
<FormGroup id='resourceTypeFilter' marginBottom={false} style={{ flex: '1 1 auto' }}>
<FormLabel text='Add manual data' />
<FormInput
compactFormComponentsView={false}
onChange={(e) => setValue(e.target.value)}
onKeyPress={(e) => {
if (e.key === 'Enter' && e.target.value !== '') {
e.preventDefault()
const newVal = [...items, e.target.value]
setItems(newVal)
setValue('')
}
}}
value={value}
/>
</FormGroup>
<Button
disabled={value === ''}
icon={<IconPlus />}
onClick={() => {
const newVal = [...items, value]
setItems(newVal)
setValue('')
}}
size='small'
style={{
position: 'relative',
bottom: '2px',
}}
variant='secondary'
>
Add
</Button>
</div>
</ConditionFilter>
)
}

const FormInputSingleConditionFilter = () => {
const [value, setValue] = useState('')
return (
<ConditionFilter
listName='Selected'
status={
<StatusTag lowercase={false} variant={value !== '' ? 'success' : 'normal'}>
{value !== '' ? 'Set up' : 'Not set'}
</StatusTag>
}
title='FormInput single'
>
<FormGroup id='jqExpressionFilter'>
<FormLabel text='Add manual data' />
<FormInput
compactFormComponentsView={false}
onChange={(e) => {
setValue(e.target.value)
}}
onKeyPress={(e) => {
if (e.key === 'Enter') {
e.preventDefault()
setValue(e.target.value)
}
}}
value={value}
/>
</FormGroup>
</ConditionFilter>
)
}

export const Default: Story = {
args: {},
parameters: {
layout: 'fullscreen',
},
render: (args) => (
<div
style={{
margin: '50px',
display: 'flex',
flexDirection: 'column',
gap: '20px',
}}
>
<FormSelectConditionFilter />
<FormInputConditionFilter />
<FormInputSingleConditionFilter />
</div>
),
}
Loading

0 comments on commit ebb14fe

Please sign in to comment.