forked from tsai/budibase
32 changed files with 188 additions and 533 deletions
@ -0,0 +1,12 @@ |
|||||
|
import api from "./api" |
||||
|
|
||||
|
/** |
||||
|
* Uploads an attachment to the server. |
||||
|
*/ |
||||
|
export const uploadAttachment = async data => { |
||||
|
return await api.post({ |
||||
|
url: "/api/attachments/upload", |
||||
|
body: data, |
||||
|
json: false, |
||||
|
}) |
||||
|
} |
||||
@ -1,2 +1,7 @@ |
|||||
export * from "./rows" |
export * from "./rows" |
||||
export * from "./auth" |
export * from "./auth" |
||||
|
export * from "./datasources" |
||||
|
export * from "./tables" |
||||
|
export * from "./attachments" |
||||
|
export * from "./views" |
||||
|
export * from "./relationships" |
||||
|
|||||
@ -1,82 +0,0 @@ |
|||||
<script> |
|
||||
import { onMount } from "svelte" |
|
||||
|
|
||||
export let _bb |
|
||||
export let table |
|
||||
export let layout = "list" |
|
||||
|
|
||||
let headers = [] |
|
||||
let store = _bb.store |
|
||||
|
|
||||
async function fetchData() { |
|
||||
if (!table || !table.length) return |
|
||||
|
|
||||
const FETCH_ROWS_URL = `/api/views/all_${table}` |
|
||||
const response = await _bb.api.get(FETCH_ROWS_URL) |
|
||||
if (response.status === 200) { |
|
||||
const json = await response.json() |
|
||||
|
|
||||
store.update(state => { |
|
||||
state[table] = json |
|
||||
return state |
|
||||
}) |
|
||||
} else { |
|
||||
throw new Error("Failed to fetch rows.", response) |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
$: data = $store[table] || [] |
|
||||
$: if (table) fetchData() |
|
||||
|
|
||||
onMount(async () => { |
|
||||
await fetchData() |
|
||||
}) |
|
||||
</script> |
|
||||
|
|
||||
<section class:grid={layout === 'grid'} class:list={layout === 'list'}> |
|
||||
{#each data as data} |
|
||||
<div class="data-card"> |
|
||||
<ul> |
|
||||
{#each Object.keys(data) as key} |
|
||||
<li> |
|
||||
<span class="data-key">{key}:</span> |
|
||||
<span class="data-value">{data[key]}</span> |
|
||||
</li> |
|
||||
{/each} |
|
||||
</ul> |
|
||||
</div> |
|
||||
{/each} |
|
||||
</section> |
|
||||
|
|
||||
<style> |
|
||||
.list { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
font-family: Inter; |
|
||||
} |
|
||||
|
|
||||
.grid { |
|
||||
display: grid; |
|
||||
grid-template-columns: 1fr 1fr 1fr; |
|
||||
} |
|
||||
|
|
||||
ul { |
|
||||
list-style-type: none; |
|
||||
} |
|
||||
|
|
||||
li { |
|
||||
margin: 5px 0 5px 0; |
|
||||
} |
|
||||
|
|
||||
.data-card { |
|
||||
border: 1px solid #ccc; |
|
||||
border-radius: 5px; |
|
||||
padding: 10px; |
|
||||
} |
|
||||
|
|
||||
.data-key { |
|
||||
font-weight: bold; |
|
||||
font-size: 20px; |
|
||||
text-transform: capitalize; |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,15 +0,0 @@ |
|||||
<script> |
|
||||
export let _bb |
|
||||
export let table |
|
||||
|
|
||||
let searchValue = "" |
|
||||
|
|
||||
function search() { |
|
||||
const SEARCH_URL = _bb.api.get(``) |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<div> |
|
||||
<input type="text" bind:value={searchValue} /> |
|
||||
<button on:click={search}>Search</button> |
|
||||
</div> |
|
||||
@ -1,9 +0,0 @@ |
|||||
<script> |
|
||||
export let icon = "" |
|
||||
export let fontSize = "1em" |
|
||||
export let _bb |
|
||||
|
|
||||
$: style = { fontSize } |
|
||||
</script> |
|
||||
|
|
||||
<i class={icon} {style} /> |
|
||||
@ -1,116 +0,0 @@ |
|||||
<script> |
|
||||
import { cssVars } from "./helpers" |
|
||||
|
|
||||
export let navBarBackground = "" |
|
||||
export let navBarBorder = "" |
|
||||
export let navBarColor = "" |
|
||||
export let selectedItemBackground = "" |
|
||||
export let selectedItemColor = "" |
|
||||
export let selectedItemBorder = "" |
|
||||
export let itemHoverBackground = "" |
|
||||
export let itemHoverColor = "" |
|
||||
export let hideNavBar = false |
|
||||
export let selectedItem = "" |
|
||||
|
|
||||
export let _children |
|
||||
export let _bb |
|
||||
|
|
||||
let selectedIndex = -1 |
|
||||
let styleVars = {} |
|
||||
let components = {} |
|
||||
let componentElements = {} |
|
||||
|
|
||||
const hasComponentElements = () => |
|
||||
Object.getOwnPropertyNames(componentElements).length > 0 |
|
||||
|
|
||||
$: { |
|
||||
styleVars = { |
|
||||
navBarBackground, |
|
||||
navBarBorder, |
|
||||
navBarColor, |
|
||||
selectedItemBackground, |
|
||||
selectedItemColor, |
|
||||
selectedItemBorder, |
|
||||
itemHoverBackground, |
|
||||
itemHoverColor, |
|
||||
} |
|
||||
|
|
||||
if (_children && _children.length > 0 && hasComponentElements()) { |
|
||||
const currentSelectedItem = |
|
||||
selectedIndex > 0 ? _children[selectedIndex].title : "" |
|
||||
if (selectedItem && currentSelectedItem !== selectedItem) { |
|
||||
let i = 0 |
|
||||
for (let child of _children) { |
|
||||
if (child.title === selectedItem) { |
|
||||
onSelectItem(i)() |
|
||||
} |
|
||||
i++ |
|
||||
} |
|
||||
} else if (!currentSelectedItem) { |
|
||||
onSelectItem(0) |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
const onSelectItem = index => () => { |
|
||||
selectedIndex = index |
|
||||
if (!components[index]) { |
|
||||
const comp = _bb.attachChildren(componentElements[index]) |
|
||||
components[index] = comp |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<div class="root" use:cssVars={styleVars}> |
|
||||
{#if !hideNavBar} |
|
||||
<div class="navbar"> |
|
||||
{#each _children as navItem, index} |
|
||||
<div |
|
||||
class="navitem" |
|
||||
on:click={onSelectItem(index)} |
|
||||
class:selected={selectedIndex === index}> |
|
||||
{navItem.title} |
|
||||
</div> |
|
||||
{/each} |
|
||||
</div> |
|
||||
{/if} |
|
||||
{#each _children as navItem, index} |
|
||||
<div class="content" bind:this={componentElements[index]} /> |
|
||||
{/each} |
|
||||
</div> |
|
||||
|
|
||||
<style> |
|
||||
.root { |
|
||||
height: 100%; |
|
||||
width: 100%; |
|
||||
grid-template-columns: [navbar] auto [content] 1fr; |
|
||||
display: grid; |
|
||||
} |
|
||||
|
|
||||
.navbar { |
|
||||
grid-column: navbar; |
|
||||
background: var(--navBarBackground); |
|
||||
border: var(--navBarBorder); |
|
||||
color: var(--navBarColor); |
|
||||
} |
|
||||
|
|
||||
.navitem { |
|
||||
padding: 10px 17px; |
|
||||
cursor: pointer; |
|
||||
} |
|
||||
|
|
||||
.navitem:hover { |
|
||||
background: var(--itemHoverBackground); |
|
||||
color: var(--itemHoverColor); |
|
||||
} |
|
||||
|
|
||||
.navitem.selected { |
|
||||
background: var(--selectedItemBackground); |
|
||||
border: var(--selectedItemBorder); |
|
||||
color: var(--selectedItemColor); |
|
||||
} |
|
||||
|
|
||||
.content { |
|
||||
grid-column: content; |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,77 +0,0 @@ |
|||||
<script> |
|
||||
export let columns = [] |
|
||||
export let data = "" |
|
||||
export let tableClass = "" |
|
||||
export let theadClass = "" |
|
||||
export let tbodyClass = "" |
|
||||
export let trClass = "" |
|
||||
export let thClass = "" |
|
||||
export let onRowClick |
|
||||
|
|
||||
export let _bb |
|
||||
|
|
||||
const rowClickHandler = row => () => { |
|
||||
// call currently only accepts one argument, so passing row does nothing |
|
||||
// however, we do not expose this event anyway. I am leaving this |
|
||||
// in for the future, as can and probably should hande this |
|
||||
_bb.call("onRowClick", row) |
|
||||
} |
|
||||
|
|
||||
const cellValue = (colIndex, row) => { |
|
||||
const val = _bb.getStateOrValue(_bb.props.columns[colIndex].value, row) |
|
||||
return val |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<table class={tableClass}> |
|
||||
<thead class={theadClass}> |
|
||||
<tr class={trClass}> |
|
||||
{#each columns as col} |
|
||||
<th class={thClass}>{col.title}</th> |
|
||||
{/each} |
|
||||
</tr> |
|
||||
</thead> |
|
||||
<tbody class={tbodyClass}> |
|
||||
{#if data} |
|
||||
{#each data as row} |
|
||||
<tr class={trClass} on:click={rowClickHandler(row)}> |
|
||||
{#each columns as col, index} |
|
||||
<th class={thClass}>{cellValue(index, row)}</th> |
|
||||
{/each} |
|
||||
</tr> |
|
||||
{/each} |
|
||||
{/if} |
|
||||
</tbody> |
|
||||
</table> |
|
||||
|
|
||||
<style> |
|
||||
.table-default { |
|
||||
width: 100%; |
|
||||
margin-bottom: 1rem; |
|
||||
color: #212529; |
|
||||
border-collapse: collapse; |
|
||||
} |
|
||||
|
|
||||
.table-default .thead-default .th-default { |
|
||||
vertical-align: bottom; |
|
||||
border-bottom: 2px solid #dee2e6; |
|
||||
font-weight: bold; |
|
||||
} |
|
||||
|
|
||||
.table-default .th-default { |
|
||||
padding: 0.75rem; |
|
||||
vertical-align: top; |
|
||||
border-top: 1px solid #dee2e6; |
|
||||
font-weight: normal; |
|
||||
} |
|
||||
|
|
||||
.th-default { |
|
||||
text-align: inherit; |
|
||||
} |
|
||||
|
|
||||
.table-default .tbody-default .tr-default:hover { |
|
||||
color: #212529; |
|
||||
background-color: rgba(0, 0, 0, 0.075); |
|
||||
cursor: pointer; |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,10 +0,0 @@ |
|||||
<script> |
|
||||
export let className = "" |
|
||||
export let _bb |
|
||||
|
|
||||
let thead |
|
||||
|
|
||||
$: _bb.attachChildren(thead) |
|
||||
</script> |
|
||||
|
|
||||
<tbody bind:this={thead} class="className" /> |
|
||||
@ -1,10 +0,0 @@ |
|||||
<script> |
|
||||
export let className = "" |
|
||||
export let _bb |
|
||||
|
|
||||
let thead |
|
||||
|
|
||||
$: _bb.attachChildren(thead) |
|
||||
</script> |
|
||||
|
|
||||
<thead bind:this={thead} class="className" /> |
|
||||
@ -1,20 +0,0 @@ |
|||||
import api from "../../api" |
|
||||
|
|
||||
let cache = {} |
|
||||
|
|
||||
async function fetchTable(id) { |
|
||||
const FETCH_TABLE_URL = `/api/tables/${id}` |
|
||||
const response = await api.get(FETCH_TABLE_URL) |
|
||||
return await response.json() |
|
||||
} |
|
||||
|
|
||||
export async function getTable(tableId) { |
|
||||
if (!tableId) { |
|
||||
return null |
|
||||
} |
|
||||
if (!cache[tableId]) { |
|
||||
cache[tableId] = fetchTable(tableId) |
|
||||
cache[tableId] = await cache[tableId] |
|
||||
} |
|
||||
return await cache[tableId] |
|
||||
} |
|
||||
Loading…
Reference in new issue