import { PureComponent } from 'react'
import { createRoot } from 'react-dom/client'
import { imgb64 } from '../lib/helpers/tests'
import SmartDataTable from '../lib'
import '../lib/css/basic.css'
const sematicUI = {
change: 'ui labeled secondary icon button',
changeIcon: 'exchange icon',
checkbox: 'ui toggle checkbox',
deleteIcon: 'trash red icon',
input: 'ui input',
iconInput: 'ui icon input',
labeledInput: 'ui right labeled input',
loader: 'ui active text loader',
message: 'ui message',
refresh: 'ui labeled primary icon button',
refreshIcon: 'sync alternate icon',
rowsIcon: 'numbered list icon',
searchIcon: 'search icon',
segment: 'ui segment',
select: 'ui dropdown',
table: 'ui compact selectable table',
}
const generateData = async (numResults = 0) => {
const { faker } = await import('@faker-js/faker')
let total = numResults || 0
if (typeof numResults === 'string') {
total = parseInt(numResults, 10)
}
const data = []
for (let i = 0; i < total; i += 1) {
const row = {
_id: i,
address: {
city: faker.location.city(),
state: faker.location.state(),
country: faker.location.country(),
},
url: faker.internet.url(),
isMarried: faker.datatype.boolean(),
actions: null,
avatar: imgb64,
fullName: faker.person.fullName(),
_username: faker.internet.username(),
password_: faker.internet.password(),
'email.address': faker.internet.email(),
phone_number: faker.phone.number(),
}
// Add random attributes to random rows (after the first)
if (i > 0 && faker.datatype.boolean()) {
const column = faker.database.column()
if (!row[column]) {
row[column] = faker.number.int()
}
}
data.push(row)
}
return data
}
const emptyTable = (
There is no data available to display.
)
const loader = Loading...
// rowIndex is zero-based, so the 1st row (index 0) is odd
const rowClassName = (_row, idx) => (idx % 2 === 0 ? 'odd-row' : 'even-row')
const DeleteButton = ({ handleDelete }) => (
)
class AppDemo extends PureComponent {
constructor(props) {
super(props)
this.state = {
useApi: false,
apiUrl: 'https://randomuser.me/api/?results=100',
apiUrlNew: 'https://randomuser.me/api/?results=100',
dataKey: 'results',
numResults: 10,
data: [],
dataSampling: 0,
filterValue: '',
perPage: 0,
showOnRowClick: true,
changeOrder: false,
orderedHeaders: [
'_id',
'avatar',
'fullName',
'_username',
'password_',
'email.address',
'phone_number',
'address.city',
'address.state',
'address.country',
'url',
'isMarried',
'actions',
],
hideUnordered: false,
}
this.changeData = this.changeData.bind(this)
this.handleCheckboxChange = this.handleCheckboxChange.bind(this)
this.handleNewApiUrl = this.handleNewApiUrl.bind(this)
this.handleOnChange = this.handleOnChange.bind(this)
this.handleOnChangeOrder = this.handleOnChangeOrder.bind(this)
this.handleOnPerPage = this.handleOnPerPage.bind(this)
this.onRowClick = this.onRowClick.bind(this)
this.setNewData = this.setNewData.bind(this)
}
componentDidMount() {
this.setNewData()
}
async setNewData() {
const { numResults } = this.state
const data = await generateData(numResults)
this.setState({ data })
}
handleNewApiUrl() {
const { apiUrlNew } = this.state
this.setState({ apiUrl: apiUrlNew })
}
handleDelete(event, _idx, row) {
event.preventDefault()
event.stopPropagation()
this.setState((prevState) => ({
data: prevState.data.filter((r) => r._id !== row._id),
}))
}
getHeaders() {
return {
_id: {
text: 'Identifier',
invisible: true,
filterable: false,
transform: (value) => `Row #${value + 1}`,
},
avatar: {
text: 'Profile Pic',
sortable: false,
filterable: false,
},
_username: {
invisible: true,
},
password_: {
invisible: true,
},
fullName: {
sortable: (a, b) => a.fullName.localeCompare(b.fullName),
},
phone_number: {
sortable: false,
},
'address.city': {
text: 'City',
},
'address.state': {
text: 'State',
},
'address.country': {
text: 'Country',
},
url: {
text: 'Web Page',
sortable: (a, b) =>
a.url
.replace(/^https?:\/\//, '')
.localeCompare(b.url.replace(/^https?:\/\//, '')),
},
actions: {
text: 'Actions',
sortable: false,
filterable: false,
transform: (value, idx, row) => (
this.handleDelete(e, idx, row)} />
),
},
}
}
handleOnChange({ target: { name, value } }) {
this.setState({ [name]: value }, () => {
if (name === 'numResults') this.setNewData()
})
}
handleOnChangeOrder(now, next) {
const { orderedHeaders } = this.state
const N = orderedHeaders.length
let nextPos = next
if (next < 0) {
nextPos = N
}
if (next >= N) {
nextPos = 0
}
const newOrderedHeaders = [...orderedHeaders]
const mvElement = newOrderedHeaders.splice(now, 1)[0]
newOrderedHeaders.splice(nextPos, 0, mvElement)
this.setState({ orderedHeaders: newOrderedHeaders })
}
handleOnPerPage({ target: { name, value } }) {
this.setState({ [name]: parseInt(value, 10) })
}
changeData() {
const { useApi } = this.state
this.setState({
useApi: !useApi,
filterValue: '',
perPage: 0,
})
}
handleCheckboxChange({ target: { name, checked } }) {
this.setState({ [name]: checked })
}
onRowClick(event, { rowData, rowIndex, tableData }) {
const { showOnRowClick } = this.state
if (showOnRowClick) {
const { fullName, name, id } = rowData
let value = fullName || name || id
if (!value) {
const [key] = Object.keys(rowData)
value = `${key}: ${rowData[key]}`
}
window.alert(`You clicked ${value}'s row !`)
} else {
// The following results should be identical
console.log(rowData, tableData[rowIndex])
}
}
render() {
const {
apiUrl,
apiUrlNew,
changeOrder,
data,
dataKey,
dataSampling,
filterValue,
hideUnordered,
numResults,
orderedHeaders,
perPage,
showOnRowClick,
useApi,
} = this.state
const divider =
const headers = this.getHeaders()
return (
<>
{useApi && (
)}
{changeOrder && (
{orderedHeaders.map((header, idx) => (
))}
)}
{useApi
? 'While using async data, the state is controlled internally by the table'
: `Total rows in the table: ${data.length}`}
{useApi && (
)}
{!useApi && (
)}
>
)
}
}
const container = document.getElementById('app')
const root = createRoot(container)
root.render()