Skip to content

Commit

Permalink
feat: add ComponentList component, ensure correct status behavior
Browse files Browse the repository at this point in the history
  • Loading branch information
chriswhong committed Jul 29, 2019
1 parent 77782e9 commit 288d05e
Show file tree
Hide file tree
Showing 6 changed files with 178 additions and 150 deletions.
10 changes: 8 additions & 2 deletions app/actions/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,14 @@ export function fetchCommitStatus (): ApiActionThunk {
name: selections.name,
path: commit
},
map: (data: Record<string, string>): Dataset => {
return data as Dataset
map: (data: Array<Record<string, string>>): ComponentStatus[] => {
return data.map((d) => {
return {
filepath: d.sourceFile,
component: d.component,
status: d.type as ComponentState
}
})
}
}
})
Expand Down
48 changes: 18 additions & 30 deletions app/components/CommitDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ import * as React from 'react'
import moment from 'moment'
import { Resizable } from '../components/resizable'
import { Action } from 'redux'
import { FileRow } from '../components/DatasetSidebar'
import ComponentList from '../components/ComponentList'
import MetadataContainer from '../containers/MetadataContainer'
import BodyContainer from '../containers/BodyContainer'
import SchemaContainer from '../containers/SchemaContainer'

import { ApiAction } from '../store/api'
import { Commit } from '../models/dataset'
import { CommitDetails as ICommitDetails } from '../models/Store'
import { CommitDetails as ICommitDetails, ComponentType, DatasetStatus } from '../models/Store'

import { defaultSidebarWidth } from '../reducers/ui'

Expand All @@ -23,6 +23,14 @@ interface CommitDetailsProps {
commitDetails: ICommitDetails
}

const isEmpty = (status: DatasetStatus) => {
const { body, meta, schema } = status
if (body) return false
if (meta) return false
if (schema) return false
return true
}

export default class CommitDetails extends React.Component<CommitDetailsProps> {
state = { commit: '' }

Expand All @@ -42,7 +50,6 @@ export default class CommitDetails extends React.Component<CommitDetailsProps> {

render () {
const { selectedComponent } = this.props
const components = [ 'body', 'meta', 'schema' ]

let mainContent

Expand All @@ -58,8 +65,9 @@ export default class CommitDetails extends React.Component<CommitDetailsProps> {
break
}

if (this.props.commit && this.props.commitDetails) {
if (this.props.commit && !isEmpty(this.props.commitDetails.status)) {
const { commit, sidebarWidth, setSidebarWidth, setSelectedListItem, commitDetails } = this.props
const { status } = commitDetails
const { title, timestamp } = commit
const timeMessage = moment(timestamp).fromNow()
return (
Expand All @@ -81,32 +89,12 @@ export default class CommitDetails extends React.Component<CommitDetailsProps> {
onReset={() => { setSidebarWidth('commit', defaultSidebarWidth) }}
maximumWidth={348}
>
{
components.map((component) => {
const activeComponents = Object.keys(commitDetails.status)
if (activeComponents.includes(component)) {
return (
<FileRow
key={component}
name={component}
displayName={component}
selected={selectedComponent === component}
selectionType={'commitComponent'}
onClick={setSelectedListItem}
/>
)
} else {
return (
<FileRow
key={component}
name={component}
displayName={component}
disabled
/>
)
}
})
}
<ComponentList
status={status}
selectedComponent={selectedComponent}
selectionType={'commitComponent' as ComponentType}
onComponentClick={setSelectedListItem}
/>
</Resizable>
<div className='content-wrapper'>
{mainContent}
Expand Down
134 changes: 134 additions & 0 deletions app/components/ComponentList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import * as React from 'react'
import { Action } from 'redux'
import classNames from 'classnames'
import { DatasetStatus, ComponentType } from '../models/store'

interface FileRowProps {
name: string
displayName: string
filename?: string
selected?: boolean
status?: string
selectionType?: ComponentType
disabled?: boolean
onClick?: (type: ComponentType, activeTab: string) => Action
}

export const FileRow: React.FunctionComponent<FileRowProps> = (props) => {
let statusColor
switch (props.status) {
case 'modified':
statusColor = '#cab081'
break
case 'add':
statusColor = '#83d683'
break
case 'removed':
statusColor = '#e04f4f'
break
default:
statusColor = 'transparent'
}

return (
<div
className={classNames('sidebar-list-item', 'sidebar-list-item-text', {
'selected': props.selected,
'disabled': props.disabled
})}
onClick={() => {
if (props.onClick && props.selectionType && props.name) {
props.onClick(props.selectionType, props.name)
}
}}
>
<div className='text-column'>
<div className='text'>{props.displayName}</div>
<div className='subtext'>{props.filename}</div>
</div>
<div className='status-column'>
<span className='dot' style={{ backgroundColor: statusColor }}></span>
</div>
</div>
)
}

FileRow.displayName = 'FileRow'

interface ComponentListProps {
status: DatasetStatus
selectedComponent: string
onComponentClick: (type: ComponentType, activeTab: string) => Action
selectionType: ComponentType
isLinked?: boolean
}

const components = [
{
name: 'meta',
displayName: 'Meta'
},
{
name: 'body',
displayName: 'Body'
},
{
name: 'schema',
displayName: 'Schema'
}
]

const ComponentList: React.FunctionComponent<ComponentListProps> = (props: ComponentListProps) => {
const {
status,
selectedComponent,
onComponentClick,
selectionType,
isLinked
} = props

return (
<div>
<div className='sidebar-list-item sidebar-list-item-text sidebar-list-header'>
Dataset Components
</div>
{
components.map(({ name, displayName }) => {
if (status[name]) {
const { filepath, status: fileStatus } = status[name]
let filename
if (filepath === 'repo') {
filename = ''
} else {
filename = filepath.substring((filepath.lastIndexOf('/') + 1))
}

return (
<FileRow
key={name}
displayName={displayName}
name={name}
filename={isLinked ? filename : ''}
status={fileStatus}
selected={selectedComponent === name}
selectionType={selectionType}
onClick={onComponentClick}
/>
)
} else {
return (
<FileRow
key={name}
displayName={displayName}
name={displayName}
disabled={true}
/>
)
}
})
}
</div>
)
}

export default ComponentList
123 changes: 11 additions & 112 deletions app/components/DatasetSidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,62 +1,10 @@
import * as React from 'react'
import { Action } from 'redux'
import classNames from 'classnames'
import moment from 'moment'
import SaveFormContainer from '../containers/SaveFormContainer'
import ComponentList from './ComponentList'

import { WorkingDataset } from '../models/store'

interface FileRowProps {
name: string
displayName: string
filename?: string
selected?: boolean
status?: string
selectionType?: string
disabled?: boolean
onClick?: (type: string, selectedListItem: string) => Action
}

export const FileRow: React.FunctionComponent<FileRowProps> = (props) => {
let statusColor
switch (props.status) {
case 'modified':
statusColor = '#cab081'
break
case 'add':
statusColor = '#83d683'
break
case 'removed':
statusColor = '#e04f4f'
break
default:
statusColor = 'transparent'
}

return (
<div
className={classNames('sidebar-list-item', 'sidebar-list-item-text', {
'selected': props.selected,
'disabled': props.disabled
})}
onClick={() => {
if (props.onClick && props.selectionType && props.name) {
props.onClick(props.selectionType, props.name)
}
}}
>
<div className='text-column'>
<div className='text'>{props.displayName}</div>
<div className='subtext'>{props.filename}</div>
</div>
<div className='status-column'>
<span className='dot' style={{ backgroundColor: statusColor }}></span>
</div>
</div>
)
}

FileRow.displayName = 'FileRow'
import { WorkingDataset, ComponentType } from '../models/store'

interface HistoryListItemProps {
path: string
Expand Down Expand Up @@ -86,8 +34,6 @@ const HistoryListItem: React.FunctionComponent<HistoryListItemProps> = (props) =
)
}

type componentType = 'component' | 'commit'

interface DatasetSidebarProps {
activeTab: string
selectedComponent: string
Expand All @@ -96,24 +42,9 @@ interface DatasetSidebarProps {
status: WorkingDataset['status']
isLinked: boolean
onTabClick: (activeTab: string) => Action
onListItemClick: (type: componentType, activeTab: string) => Action
onListItemClick: (type: ComponentType, activeTab: string) => Action
}

const components = [
{
name: 'meta',
displayName: 'Meta'
},
{
name: 'body',
displayName: 'Body'
},
{
name: 'schema',
displayName: 'Schema'
}
]

const DatasetSidebar: React.FunctionComponent<DatasetSidebarProps> = (props: DatasetSidebarProps) => {
const {
activeTab,
Expand All @@ -137,46 +68,14 @@ const DatasetSidebar: React.FunctionComponent<DatasetSidebarProps> = (props: Dat
</div>
<div id='content'>
<div id='status-content' className='sidebar-content' hidden = {activeTab !== 'status'}>
<div className='sidebar-list-item'>
<div className='changes'>
Changes
</div>
</div>
{
statusLoaded && components.map(({ name, displayName }) => {
if (status[name]) {
const { filepath, status: fileStatus } = status[name]
let filename
if (filepath === 'repo') {
filename = ''
} else {
filename = filepath.substring((filepath.lastIndexOf('/') + 1))
}

return (
<FileRow
key={name}
displayName={displayName}
name={name}
filename={filename}
status={fileStatus}
selected={selectedComponent === name}
selectionType={'component'}
onClick={onListItemClick}
/>
)
} else {
return (
<FileRow
key={name}
displayName={displayName}
name={displayName}
disabled={true}
/>
)
}
})
}
{ statusLoaded &&
<ComponentList
status={status}
selectedComponent={selectedComponent}
onComponentClick={onListItemClick}
selectionType={'component' as ComponentType}
isLinked={isLinked}
/>}
</div>
{
historyLoaded && (
Expand Down
Loading

0 comments on commit 288d05e

Please sign in to comment.