mirror of https://github.com/Budibase/budibase.git
5 changed files with 67 additions and 252 deletions
@ -1,201 +0,0 @@ |
|||||
<script> |
|
||||
import { onMount } from "svelte" |
|
||||
import { cssVars } from "./cssVars" |
|
||||
import ArrowUp from "./icons/ArrowUp.svelte" |
|
||||
import ArrowDown from "./icons/ArrowDown.svelte" |
|
||||
import fsort from "fast-sort" |
|
||||
import fetchData from "./fetchData.js" |
|
||||
import { isEmpty } from "lodash/fp" |
|
||||
import AttachmentList from "./attachments/AttachmentList.svelte" |
|
||||
|
|
||||
export let backgroundColor |
|
||||
export let color |
|
||||
export let stripeColor |
|
||||
export let borderColor |
|
||||
export let datasource |
|
||||
export let _bb |
|
||||
|
|
||||
let data = [] |
|
||||
let headers = [] |
|
||||
let sort = {} |
|
||||
let sorted = [] |
|
||||
let schema = {} |
|
||||
let store = _bb.store |
|
||||
|
|
||||
$: cssVariables = { |
|
||||
backgroundColor, |
|
||||
color, |
|
||||
stripeColor, |
|
||||
borderColor, |
|
||||
} |
|
||||
|
|
||||
$: sorted = sort.direction ? fsort(data)[sort.direction](sort.column) : data |
|
||||
|
|
||||
async function fetchTable(tableId) { |
|
||||
const FETCH_TABLE_URL = `/api/tables/${tableId}` |
|
||||
const response = await _bb.api.get(FETCH_TABLE_URL) |
|
||||
const table = await response.json() |
|
||||
return table.schema |
|
||||
} |
|
||||
|
|
||||
onMount(async () => { |
|
||||
if (!isEmpty(datasource)) { |
|
||||
data = await fetchData(datasource, $store) |
|
||||
|
|
||||
// Get schema for datasource |
|
||||
// Views with "Calculate" applied provide their own schema. |
|
||||
// For everything else, use the tableId property to pull to table schema |
|
||||
if (datasource.schema) { |
|
||||
schema = datasource.schema |
|
||||
headers = Object.keys(schema).filter(shouldDisplayField) |
|
||||
} else { |
|
||||
schema = await fetchTable(datasource.tableId) |
|
||||
headers = Object.keys(schema).filter(shouldDisplayField) |
|
||||
} |
|
||||
} |
|
||||
}) |
|
||||
|
|
||||
const shouldDisplayField = name => { |
|
||||
if (name.startsWith("_")) return false |
|
||||
// always 'row' |
|
||||
if (name === "type") return false |
|
||||
// tables are always tied to a single tableId, this is irrelevant |
|
||||
if (name === "tableId") return false |
|
||||
return true |
|
||||
} |
|
||||
|
|
||||
function sortColumn(column) { |
|
||||
if (column === sort.column) { |
|
||||
sort = { |
|
||||
direction: sort.direction === "asc" ? "desc" : null, |
|
||||
column: sort.direction === "asc" ? sort.column : null, |
|
||||
} |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
sort = { |
|
||||
column, |
|
||||
direction: "asc", |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<table use:cssVars={cssVariables}> |
|
||||
<thead> |
|
||||
<tr> |
|
||||
{#each headers as header} |
|
||||
<th on:click={() => sortColumn(header)}> |
|
||||
<span> |
|
||||
{header} |
|
||||
{#if sort.column === header} |
|
||||
<svelte:component |
|
||||
this={sort.direction === 'asc' ? ArrowDown : ArrowUp} |
|
||||
style="height: 1em;" /> |
|
||||
{/if} |
|
||||
</span> |
|
||||
</th> |
|
||||
{/each} |
|
||||
</tr> |
|
||||
</thead> |
|
||||
<tbody> |
|
||||
{#each sorted as row (row._id)} |
|
||||
<tr> |
|
||||
{#each headers as header} |
|
||||
{#if schema[header] !== undefined} |
|
||||
<!-- Rudimentary solution for attachments on array given this entire table will be replaced by AG Grid --> |
|
||||
{#if schema[header] && schema[header].type === 'attachment'} |
|
||||
<AttachmentList files={row[header]} /> |
|
||||
{:else if schema[header] && schema[header].type === 'link'} |
|
||||
<td>{row[header] ? row[header].length : 0} related row(s)</td> |
|
||||
{:else} |
|
||||
<td>{row[header] == null ? '' : row[header]}</td> |
|
||||
{/if} |
|
||||
{/if} |
|
||||
{/each} |
|
||||
</tr> |
|
||||
{/each} |
|
||||
</tbody> |
|
||||
</table> |
|
||||
|
|
||||
<style> |
|
||||
table { |
|
||||
width: 100%; |
|
||||
border-collapse: collapse; |
|
||||
overflow: scroll; /* Scrollbar are always visible */ |
|
||||
overflow: auto; /* Scrollbar is displayed as it's needed */ |
|
||||
} |
|
||||
|
|
||||
/* Zebra striping */ |
|
||||
tr:nth-of-type(odd) { |
|
||||
background: var(--stripeColor); |
|
||||
} |
|
||||
|
|
||||
th { |
|
||||
background-color: var(--backgroundColor); |
|
||||
color: var(--color); |
|
||||
font-weight: bold; |
|
||||
text-transform: capitalize; |
|
||||
cursor: pointer; |
|
||||
} |
|
||||
|
|
||||
th span { |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
} |
|
||||
|
|
||||
td, |
|
||||
th { |
|
||||
padding: 16px; |
|
||||
border: 1px solid var(--borderColor); |
|
||||
text-align: left; |
|
||||
} |
|
||||
|
|
||||
@media only screen and (max-width: 760px), |
|
||||
(min-device-width: 768px) and (max-device-width: 1024px) { |
|
||||
table { |
|
||||
width: 100%; |
|
||||
} |
|
||||
|
|
||||
/* Force table to not be like tables anymore */ |
|
||||
table, |
|
||||
thead, |
|
||||
tbody, |
|
||||
th, |
|
||||
td, |
|
||||
tr { |
|
||||
display: block; |
|
||||
} |
|
||||
|
|
||||
/* Hide table headers (but not display: none;, for accessibility) */ |
|
||||
thead tr { |
|
||||
position: absolute; |
|
||||
top: -9999px; |
|
||||
left: -9999px; |
|
||||
} |
|
||||
|
|
||||
tr { |
|
||||
border: 1px solid var(--borderColor); |
|
||||
} |
|
||||
|
|
||||
td { |
|
||||
/* Behave like a "row" */ |
|
||||
border: none; |
|
||||
border-bottom: 1px solid #eee; |
|
||||
position: relative; |
|
||||
padding-left: 10%; |
|
||||
} |
|
||||
|
|
||||
td:before { |
|
||||
/* Now like a table header */ |
|
||||
position: absolute; |
|
||||
/* Top/left values mimic padding */ |
|
||||
top: 6px; |
|
||||
left: 6px; |
|
||||
width: 45%; |
|
||||
padding-right: 10px; |
|
||||
white-space: nowrap; |
|
||||
/* Label the data */ |
|
||||
content: attr(data-column); |
|
||||
} |
|
||||
} |
|
||||
</style> |
|
||||
Loading…
Reference in new issue