Budibase is an open-source low-code platform for creating internal apps in minutes. Supports PostgreSQL, MySQL, MSSQL, MongoDB, Rest API, Docker, K8s 🚀
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

140 lines
3.4 KiB

<script>
import {
Icon,
ActionButton,
Input,
Label,
Toggle,
Select,
} from "@budibase/bbui"
import { createEventDispatcher } from "svelte"
import { lowercase } from "helpers"
let dispatch = createEventDispatcher()
export let defaults
export let object = defaults || {}
export let activity = {}
export let readOnly
export let noAddButton
export let name
export let headings = false
export let options
export let toggle
export let keyPlaceholder = "Key"
export let valuePlaceholder = "Value"
export let tooltip
let fields = Object.entries(object).map(([name, value]) => ({ name, value }))
let fieldActivity = []
$: object = fields.reduce(
(acc, next) => ({ ...acc, [next.name]: next.value }),
{}
)
$: fieldActivity = buildFieldActivity(activity)
function buildFieldActivity(obj) {
if (!obj || typeof obj !== "object") {
return []
}
const array = Array(fields.length)
for (let [key, value] of Object.entries(obj)) {
const field = fields.find(el => el.name === key)
const idx = fields.indexOf(field)
if (idx !== -1) {
array[idx] = value
}
}
return array
}
export function addEntry() {
fields = [...fields, { name: "", value: "" }]
fieldActivity = [...fieldActivity, true]
changed()
}
function deleteEntry(idx) {
fields.splice(idx, 1)
fieldActivity.splice(idx, 1)
changed()
}
function changed() {
fields = fields
const newActivity = {}
for (let idx = 0; idx < fields.length; idx++) {
const fieldName = fields[idx].name
if (fieldName) {
newActivity[fieldName] = fieldActivity[idx]
}
}
activity = newActivity
dispatch("change", fields)
}
</script>
<!-- Builds Objects with Key Value Pairs. Useful for building things like Request Headers. -->
{#if Object.keys(object || {}).length > 0}
{#if headings}
<div class="container" class:container-active={toggle}>
<Label {tooltip}>{keyPlaceholder}</Label>
<Label>{valuePlaceholder}</Label>
{#if toggle}
<Label>Active</Label>
{/if}
</div>
{/if}
<div class="container" class:container-active={toggle} class:readOnly>
{#each fields as field, idx}
<Input
placeholder={keyPlaceholder}
bind:value={field.name}
on:change={changed}
/>
{#if options}
<Select bind:value={field.value} on:change={changed} {options} />
{:else}
<Input
placeholder={valuePlaceholder}
bind:value={field.value}
on:change={changed}
/>
{/if}
{#if toggle}
<Toggle
bind:value={fieldActivity[idx]}
on:change={changed}
default={true}
/>
{/if}
{#if !readOnly}
<Icon hoverable name="Close" on:click={() => deleteEntry(idx)} />
{/if}
{/each}
</div>
{/if}
{#if !readOnly && !noAddButton}
<div>
<ActionButton icon="Add" secondary thin outline on:click={addEntry}
>Add{name ? ` ${lowercase(name)}` : ""}</ActionButton
>
</div>
{/if}
<style>
.container {
display: grid;
grid-template-columns: 1fr 1fr 20px;
grid-gap: var(--spacing-m);
align-items: center;
margin-bottom: var(--spacing-m);
}
.container-active {
grid-template-columns: 1fr 1fr 50px 20px;
}
.readOnly {
grid-template-columns: 1fr 1fr;
}
</style>