summaryrefslogtreecommitdiff
path: root/frontend/app/common/tableIndex.component.js
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/app/common/tableIndex.component.js')
-rw-r--r--frontend/app/common/tableIndex.component.js129
1 files changed, 129 insertions, 0 deletions
diff --git a/frontend/app/common/tableIndex.component.js b/frontend/app/common/tableIndex.component.js
new file mode 100644
index 0000000..c58fc35
--- /dev/null
+++ b/frontend/app/common/tableIndex.component.js
@@ -0,0 +1,129 @@
+import React, { Component } from 'react'
+import { Link } from 'react-router-dom'
+import { connect } from 'react-redux'
+
+import { formatDateTime } from 'app/utils'
+import { Loader, Swatch, Dot } from 'app/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>
+ )
+}