1
0
Fork 0
mirror of synced 2024-09-18 18:28:33 +12:00

Add inline editing of options fields

This commit is contained in:
Andrew Kingston 2022-11-24 19:28:55 +00:00
parent b19a2a3d3a
commit 6471464971
2 changed files with 115 additions and 14 deletions

View file

@ -1,7 +1,12 @@
<script> <script>
import { Icon } from "@budibase/bbui"
export let value export let value
export let schema export let schema
export let selected = false
export let onChange
const options = schema?.constraints?.inclusion || []
const colors = [ const colors = [
"rgb(207, 223, 255)", "rgb(207, 223, 255)",
"rgb(208, 240, 253)", "rgb(208, 240, 253)",
@ -14,26 +19,116 @@
"rgb(237, 226, 254)", "rgb(237, 226, 254)",
] ]
$: idx = schema?.constraints?.inclusion?.indexOf(value) let open = false
$: color = value && idx === -1 ? null : colors[idx % colors.length]
$: color = getColor(value)
$: {
// Close when deselected
if (!selected) {
open = false
}
}
const getColor = value => {
const index = options.indexOf(value)
if (!value || index === -1) {
return null
}
return colors[index % colors.length]
}
const toggle = () => {
open = !open
}
</script> </script>
<div style="--color: {color}" class:valid={!!color}> <div
{value || ""} class="container"
class:selected
class:open
on:click={selected ? toggle : null}
>
{#if color}
<div class="badge text" style="--color: {color}">
{value}
</div>
{:else if value}
<div class="text">
{value}
</div>
{/if}
{#if selected}
<Icon name="ChevronDown" />
{/if}
{#if open}
<div class="options">
<div class="option">
<div class="badge text" style="--color: {color}">
{value}
</div>
<Icon name="Checkmark" color="var(--spectrum-global-color-blue-400)" />
</div>
{#each options.filter(x => x !== value) as option}
<div class="option" on:click={() => onChange(option)}>
<div class="badge text" style="--color: {getColor(option)}">
{option}
</div>
</div>
{/each}
</div>
{/if}
</div> </div>
<style> <style>
div { .container {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
padding: 0 8px; padding: 0 8px;
flex: 1 1 auto;
overflow: hidden;
gap: 4px;
}
.container.selected:hover {
cursor: pointer;
}
.text {
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
} }
div.valid { .badge {
margin: 0 8px;
padding: 2px 8px; padding: 2px 8px;
background: var(--color); background: var(--color);
border-radius: 8px; border-radius: 8px;
color: #333; color: #2c2c2c;
user-select: none;
}
.options {
min-width: 100%;
position: absolute;
top: 0;
left: 0;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: stretch;
box-shadow: 0 0 8px 4px rgba(0, 0, 0, 0.15);
border-radius: 4px;
max-height: 192px;
overflow-y: auto;
}
.option {
flex: 0 0 32px;
padding: 0 8px;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
background-color: var(--spectrum-global-color-gray-50);
}
.option:hover {
background-color: var(--spectrum-global-color-gray-100);
} }
</style> </style>

View file

@ -106,17 +106,18 @@
} }
const handleChange = async (rowId, field, value) => { const handleChange = async (rowId, field, value) => {
selectedCell = null
let row = $fetch.rows.find(x => x._id === rowId) let row = $fetch.rows.find(x => x._id === rowId)
if (!row) { if (!row) {
return return
} }
const newRow = { if (row[field] === value) {
...row, return
[field]: value,
} }
changeCache[rowId] = { [field]: value } changeCache[rowId] = { [field]: value }
await API.saveRow(newRow) await API.saveRow({
...row,
...changeCache[rowId],
})
await fetch.refresh() await fetch.refresh()
delete changeCache[rowId] delete changeCache[rowId]
} }
@ -237,6 +238,7 @@
justify-content: flex-start; justify-content: flex-start;
align-items: stretch; align-items: stretch;
border: 1px solid var(--spectrum-global-color-gray-400); border: 1px solid var(--spectrum-global-color-gray-400);
border-radius: 4px;
} }
.spreadsheet { .spreadsheet {
display: grid; display: grid;
@ -294,12 +296,13 @@
font-size: 14px; font-size: 14px;
gap: 4px; gap: 4px;
background: var(--spectrum-global-color-gray-50); background: var(--spectrum-global-color-gray-50);
position: relative;
} }
.cell.hovered { .cell.hovered {
background: var(--spectrum-global-color-gray-100); background: var(--spectrum-global-color-gray-100);
} }
.cell.selected { .cell.selected {
box-shadow: inset 0 0 0 2px rgb(89, 167, 246); box-shadow: inset 0 0 0 2px var(--spectrum-global-color-blue-400);
z-index: 1; z-index: 1;
} }
.cell:hover { .cell:hover {
@ -310,6 +313,9 @@
left: 50px; left: 50px;
z-index: 2; z-index: 2;
} }
.cell.sticky.selected {
z-index: 3;
}
.cell.row-selected { .cell.row-selected {
background-color: rgb(224, 242, 255); background-color: rgb(224, 242, 255);
} }