mirror of https://github.com/Budibase/budibase.git
62 changed files with 2363 additions and 786 deletions
@ -0,0 +1,152 @@ |
|||
static_resources: |
|||
listeners: |
|||
- name: main_listener |
|||
address: |
|||
socket_address: { address: 0.0.0.0, port_value: 10000 } |
|||
filter_chains: |
|||
- filters: |
|||
- name: envoy.filters.network.http_connection_manager |
|||
typed_config: |
|||
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager |
|||
stat_prefix: ingress |
|||
codec_type: auto |
|||
route_config: |
|||
name: local_route |
|||
virtual_hosts: |
|||
- name: local_services |
|||
domains: ["*"] |
|||
routes: |
|||
- match: { prefix: "/app/" } |
|||
route: |
|||
cluster: app-service |
|||
prefix_rewrite: "/" |
|||
|
|||
- match: { path: "/v1/update" } |
|||
route: |
|||
cluster: watchtower-service |
|||
|
|||
- match: { prefix: "/builder/" } |
|||
route: |
|||
cluster: app-service |
|||
|
|||
- match: { prefix: "/builder" } |
|||
route: |
|||
cluster: app-service |
|||
|
|||
- match: { prefix: "/app_" } |
|||
route: |
|||
cluster: app-service |
|||
|
|||
# special cases for worker admin (deprecated), global and system API |
|||
- match: { prefix: "/api/global/" } |
|||
route: |
|||
cluster: worker-service |
|||
|
|||
- match: { prefix: "/api/admin/" } |
|||
route: |
|||
cluster: worker-service |
|||
|
|||
- match: { prefix: "/api/system/" } |
|||
route: |
|||
cluster: worker-service |
|||
|
|||
- match: { path: "/" } |
|||
route: |
|||
cluster: app-service |
|||
|
|||
# special case for when API requests are made, can just forward, not to minio |
|||
- match: { prefix: "/api/" } |
|||
route: |
|||
cluster: app-service |
|||
timeout: 120s |
|||
|
|||
- match: { prefix: "/worker/" } |
|||
route: |
|||
cluster: worker-service |
|||
prefix_rewrite: "/" |
|||
|
|||
- match: { prefix: "/db/" } |
|||
route: |
|||
cluster: couchdb-service |
|||
prefix_rewrite: "/" |
|||
|
|||
# minio is on the default route because this works |
|||
# best, minio + AWS SDK doesn't handle path proxy |
|||
- match: { prefix: "/" } |
|||
route: |
|||
cluster: minio-service |
|||
|
|||
http_filters: |
|||
- name: envoy.filters.http.router |
|||
|
|||
clusters: |
|||
- name: app-service |
|||
connect_timeout: 0.25s |
|||
type: strict_dns |
|||
lb_policy: round_robin |
|||
load_assignment: |
|||
cluster_name: app-service |
|||
endpoints: |
|||
- lb_endpoints: |
|||
- endpoint: |
|||
address: |
|||
socket_address: |
|||
address: app-service |
|||
port_value: 4002 |
|||
|
|||
- name: minio-service |
|||
connect_timeout: 0.25s |
|||
type: strict_dns |
|||
lb_policy: round_robin |
|||
load_assignment: |
|||
cluster_name: minio-service |
|||
endpoints: |
|||
- lb_endpoints: |
|||
- endpoint: |
|||
address: |
|||
socket_address: |
|||
address: minio-service |
|||
port_value: 9000 |
|||
|
|||
- name: worker-service |
|||
connect_timeout: 0.25s |
|||
type: strict_dns |
|||
lb_policy: round_robin |
|||
load_assignment: |
|||
cluster_name: worker-service |
|||
endpoints: |
|||
- lb_endpoints: |
|||
- endpoint: |
|||
address: |
|||
socket_address: |
|||
address: worker-service |
|||
port_value: 4003 |
|||
|
|||
- name: couchdb-service |
|||
connect_timeout: 0.25s |
|||
type: strict_dns |
|||
lb_policy: round_robin |
|||
load_assignment: |
|||
cluster_name: couchdb-service |
|||
endpoints: |
|||
- lb_endpoints: |
|||
- endpoint: |
|||
address: |
|||
socket_address: |
|||
address: couchdb-service |
|||
port_value: 5984 |
|||
|
|||
- name: watchtower-service |
|||
connect_timeout: 0.25s |
|||
type: strict_dns |
|||
lb_policy: round_robin |
|||
load_assignment: |
|||
cluster_name: watchtower-service |
|||
endpoints: |
|||
- lb_endpoints: |
|||
- endpoint: |
|||
address: |
|||
socket_address: |
|||
address: watchtower-service |
|||
port_value: 8080 |
|||
|
|||
@ -0,0 +1,178 @@ |
|||
<script> |
|||
import { |
|||
Button, |
|||
Icon, |
|||
DrawerContent, |
|||
Layout, |
|||
Input, |
|||
Select, |
|||
Label, |
|||
Body, |
|||
} from "@budibase/bbui" |
|||
import { flip } from "svelte/animate" |
|||
import { dndzone } from "svelte-dnd-action" |
|||
import { generate } from "shortid" |
|||
|
|||
export let columns = [] |
|||
export let options = [] |
|||
|
|||
const flipDurationMs = 150 |
|||
let dragDisabled = true |
|||
|
|||
$: unselectedColumns = getUnselectedColumns(options, columns) |
|||
$: columns.forEach(column => { |
|||
if (!column.id) { |
|||
column.id = generate() |
|||
} |
|||
}) |
|||
|
|||
const getUnselectedColumns = (allColumns, selectedColumns) => { |
|||
let optionsObj = {} |
|||
allColumns.forEach(option => { |
|||
optionsObj[option] = true |
|||
}) |
|||
selectedColumns?.forEach(column => { |
|||
delete optionsObj[column.name] |
|||
}) |
|||
return Object.keys(optionsObj) |
|||
} |
|||
|
|||
const getRemainingColumnOptions = selectedColumn => { |
|||
if (!selectedColumn || unselectedColumns.includes(selectedColumn)) { |
|||
return unselectedColumns |
|||
} |
|||
return [selectedColumn, ...unselectedColumns] |
|||
} |
|||
|
|||
const addColumn = () => { |
|||
columns = [...columns, {}] |
|||
} |
|||
|
|||
const removeColumn = id => { |
|||
columns = columns.filter(column => column.id !== id) |
|||
} |
|||
|
|||
const updateColumnOrder = e => { |
|||
columns = e.detail.items |
|||
} |
|||
|
|||
const handleFinalize = e => { |
|||
updateColumnOrder(e) |
|||
dragDisabled = true |
|||
} |
|||
|
|||
const reset = () => { |
|||
columns = options.map(col => ({ |
|||
name: col, |
|||
displayName: col, |
|||
})) |
|||
} |
|||
</script> |
|||
|
|||
<DrawerContent> |
|||
<div class="container"> |
|||
<Layout noPadding gap="S"> |
|||
{#if columns?.length} |
|||
<Layout noPadding gap="XS"> |
|||
<div class="column"> |
|||
<div /> |
|||
<Label size="L">Column</Label> |
|||
<Label size="L">Label</Label> |
|||
<div /> |
|||
</div> |
|||
<div |
|||
class="columns" |
|||
use:dndzone={{ |
|||
items: columns, |
|||
flipDurationMs, |
|||
dropTargetStyle: { outline: "none" }, |
|||
dragDisabled, |
|||
}} |
|||
on:finalize={handleFinalize} |
|||
on:consider={updateColumnOrder} |
|||
> |
|||
{#each columns as column (column.id)} |
|||
<div class="column" animate:flip={{ duration: flipDurationMs }}> |
|||
<div |
|||
class="handle" |
|||
aria-label="drag-handle" |
|||
style={dragDisabled ? "cursor: grab" : "cursor: grabbing"} |
|||
on:mousedown={() => (dragDisabled = false)} |
|||
> |
|||
<Icon name="DragHandle" size="XL" /> |
|||
</div> |
|||
<Select |
|||
bind:value={column.name} |
|||
placeholder="Column" |
|||
options={getRemainingColumnOptions(column.name)} |
|||
on:change={e => (column.displayName = e.detail)} |
|||
/> |
|||
<Input bind:value={column.displayName} placeholder="Label" /> |
|||
<Icon |
|||
name="Close" |
|||
hoverable |
|||
size="S" |
|||
on:click={() => removeColumn(column.id)} |
|||
disabled={columns.length === 1} |
|||
/> |
|||
</div> |
|||
{/each} |
|||
</div> |
|||
</Layout> |
|||
{:else} |
|||
<div class="column"> |
|||
<div /> |
|||
<Body size="S">Add the first column to your table.</Body> |
|||
</div> |
|||
{/if} |
|||
<div class="columns"> |
|||
<div class="column"> |
|||
<div /> |
|||
<div class="buttons"> |
|||
<Button secondary icon="Add" on:click={addColumn}> |
|||
Add column |
|||
</Button> |
|||
<Button secondary quiet on:click={reset}>Reset columns</Button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</Layout> |
|||
</div> |
|||
</DrawerContent> |
|||
|
|||
<style> |
|||
.container { |
|||
width: 100%; |
|||
max-width: 600px; |
|||
margin: 0 auto; |
|||
} |
|||
.columns { |
|||
display: flex; |
|||
flex-direction: column; |
|||
justify-content: flex-start; |
|||
align-items: stretch; |
|||
gap: var(--spacing-m); |
|||
} |
|||
.column { |
|||
gap: var(--spacing-l); |
|||
display: grid; |
|||
grid-template-columns: 20px 1fr 1fr 20px; |
|||
align-items: center; |
|||
border-radius: var(--border-radius-s); |
|||
transition: background-color ease-in-out 130ms; |
|||
} |
|||
.column:hover { |
|||
background-color: var(--spectrum-global-color-gray-100); |
|||
} |
|||
.handle { |
|||
display: grid; |
|||
place-items: center; |
|||
} |
|||
.buttons { |
|||
display: flex; |
|||
flex-direction: row; |
|||
justify-content: flex-start; |
|||
align-items: center; |
|||
gap: var(--spacing-m); |
|||
} |
|||
</style> |
|||
@ -0,0 +1,64 @@ |
|||
<script> |
|||
import { Button, ActionButton, Drawer } from "@budibase/bbui" |
|||
import { createEventDispatcher } from "svelte" |
|||
import ColumnDrawer from "./ColumnDrawer.svelte" |
|||
import { cloneDeep } from "lodash/fp" |
|||
import { |
|||
getDatasourceForProvider, |
|||
getSchemaForDatasource, |
|||
} from "builderStore/dataBinding" |
|||
import { currentAsset } from "builderStore" |
|||
|
|||
export let componentInstance |
|||
export let value = [] |
|||
|
|||
const dispatch = createEventDispatcher() |
|||
|
|||
let drawer |
|||
let boundValue |
|||
|
|||
$: datasource = getDatasourceForProvider($currentAsset, componentInstance) |
|||
$: schema = getSchemaForDatasource($currentAsset, datasource).schema |
|||
$: options = Object.keys(schema || {}) |
|||
$: sanitisedValue = getValidColumns(value, options) |
|||
$: updateBoundValue(sanitisedValue) |
|||
|
|||
const updateBoundValue = value => { |
|||
boundValue = cloneDeep(value) |
|||
} |
|||
|
|||
const getValidColumns = (columns, options) => { |
|||
// If no columns then default to all columns |
|||
if (!Array.isArray(columns) || !columns.length) { |
|||
return options.map(col => ({ |
|||
name: col, |
|||
displayName: col, |
|||
})) |
|||
} |
|||
// We need to account for legacy configs which would just be an array |
|||
// of strings |
|||
if (typeof columns[0] === "string") { |
|||
columns = columns.map(col => ({ |
|||
name: col, |
|||
displayName: col, |
|||
})) |
|||
} |
|||
return columns.filter(column => { |
|||
return options.includes(column.name) |
|||
}) |
|||
} |
|||
|
|||
const save = () => { |
|||
dispatch("change", getValidColumns(boundValue, options)) |
|||
drawer.hide() |
|||
} |
|||
</script> |
|||
|
|||
<ActionButton on:click={drawer.show}>Configure columns</ActionButton> |
|||
<Drawer bind:this={drawer} title="Table Columns"> |
|||
<svelte:fragment slot="description"> |
|||
Configure the columns in your table. |
|||
</svelte:fragment> |
|||
<Button cta slot="buttons" on:click={save}>Save</Button> |
|||
<ColumnDrawer slot="body" bind:columns={boundValue} {options} /> |
|||
</Drawer> |
|||
File diff suppressed because it is too large
@ -1,2 +1,3 @@ |
|||
dist/ |
|||
node_modules/ |
|||
stats.html |
|||
Loading…
Reference in new issue