1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
import React, { Component } from 'react'
import { Link } from 'react-router-dom'
import { connect } from 'react-redux'
import { formatDateTime } from '../util'
import { Loader, Swatch, Dot } from '../common'
/*
<TableIndex
title="Collections"
actions={actions.collection}
data={data.collection.index}
fields={[
{ name: 'title', type: 'title', link: row => '/collection/' + row.id + '/show/' },
{ name: 'username', type: 'string' },
{ name: 'date', type: 'date' },
{ name: 'notes', type: 'text' },
]}
/>
*/
export default class TableIndex extends Component {
componentDidMount() {
this.props.actions && this.props.actions.index()
}
render() {
const { data, els, title, fields, noHeadings, notFoundMessage } = this.props
if (data.loading) {
return <Loader />
}
if (!els && (!data.lookup || !data.order.length)) {
return (
<div>
<h1>{title}</h1>
<p className='gray'>
{notFoundMessage || ("No " + title)}
</p>
</div>
)
}
return (
<div className='tableIndex'>
<h1>{title}</h1>
<div className='rows'>
{!noHeadings && <RowHeadings fields={fields} />}
{els
? els.map(el => <Row key={el.id} row={el} fields={fields} />)
: data.order.map(id => <Row key={id} row={data.lookup[id]} fields={fields} />)
}
</div>
</div>
)
}
}
const RowHeadings = ({fields}) => {
return (
<div className='row heading'>
{fields.map(field => {
if (field.type === 'gallery') return
let css = {}
if (field.width) {
css = { width: field.width, maxWidth: 'none', flex: 'none', }
}
if (field.flex) {
css.flex = field.flex
}
return <div key={field.name} className={field.type} style={css}>{(field.title || field.name).replace(/_/g, ' ')}</div>
})}
</div>
)
}
const Row = ({ row, fields }) => {
return (
<div className='row tableRow'>
{fields.map(field => {
let value = field.valueFn ? field.valueFn(row) : row[field.name]
let css = {}
if (field.type === 'date' && (row.updated_at || row.created_at || value)) {
// value = (value || "").split('.')[0]
value = formatDateTime(row.updated_at || row.created_at || value)
} else if (field.type === 'text') {
value = String(value || "").trim().split('\n')[0].replace(/^#+/, '').substr(0, 100)
} else if (field.type === 'color') {
value = <Swatch color={value} />
} else if (field.type === 'bool') {
value = <Dot color={value ? '#11f' : '#fff'} />
} else if (field.type === 'str') {
value = String(value || "").replace(/_/g, ' ')
} else if (field.type === 'gallery') {
return <GalleryRow key={field.name} media={value} />
}
if (field.width) {
css = { width: field.width, maxWidth: 'none', flex: 'none', }
}
if (field.flex) {
css.flex = field.flex
}
let className
if (field.style) {
className = field.type + ' ' + field.style
} else {
className = field.type
}
value = <div title={value} key={field.name} className={className} style={css}>{value}</div>
if (field.link) {
return <Link key={field.name} to={field.link(row)}>{value}</Link>
}
return value
})}
</div>
)
}
const GalleryRow = ({ media }) => {
return (
<div className='galleryRow'>
<div>
{media.map(img => (
<Link to={"/media/id/" + img.id + "/"} key={img.url}>
<img src={img.url} className='thumbnail' />
</Link>
))}
</div>
</div>
)
}
|