Add ability to add new rows

This commit is contained in:
Andrew Kingston 2022-11-25 08:34:44 +00:00
parent fafb8ec938
commit 152d157aaa
2 changed files with 51 additions and 18 deletions

View File

@ -52,9 +52,9 @@
<div class="badge text" style="--color: {color}"> <div class="badge text" style="--color: {color}">
{value} {value}
</div> </div>
{:else if value} {:else}
<div class="text"> <div class="text">
{value} {value || ""}
</div> </div>
{/if} {/if}
{#if selected} {#if selected}
@ -62,12 +62,17 @@
{/if} {/if}
{#if open} {#if open}
<div class="options"> <div class="options">
{#if value}
<div class="option"> <div class="option">
<div class="badge text" style="--color: {color}"> <div class="badge text" style="--color: {color}">
{value} {value}
</div> </div>
<Icon name="Checkmark" color="var(--spectrum-global-color-blue-400)" /> <Icon
name="Checkmark"
color="var(--spectrum-global-color-blue-400)"
/>
</div> </div>
{/if}
{#each options.filter(x => x !== value) as option} {#each options.filter(x => x !== value) as option}
<div class="option" on:click={() => onChange(option)}> <div class="option" on:click={() => onChange(option)}>
<div class="badge text" style="--color: {getColor(option)}"> <div class="badge text" style="--color: {getColor(option)}">

View File

@ -23,6 +23,7 @@
let selectedRows = {} let selectedRows = {}
let horizontallyScrolled = false let horizontallyScrolled = false
let changeCache = {} let changeCache = {}
let newRows = []
$: query = LuceneUtils.buildLuceneQuery(filter) $: query = LuceneUtils.buildLuceneQuery(filter)
$: fetch = createFetch(table) $: fetch = createFetch(table)
@ -38,6 +39,7 @@
$: schema = $fetch.schema $: schema = $fetch.schema
$: rowCount = $fetch.rows?.length || 0 $: rowCount = $fetch.rows?.length || 0
$: selectedRowCount = Object.values(selectedRows).filter(x => !!x).length $: selectedRowCount = Object.values(selectedRows).filter(x => !!x).length
$: rows = getSortedRows($fetch.rows, newRows)
const createFetch = datasource => { const createFetch = datasource => {
return fetchData({ return fetchData({
@ -100,14 +102,14 @@
if (allSelected) { if (allSelected) {
selectedRows = {} selectedRows = {}
} else { } else {
$fetch.rows.forEach(row => { rows.forEach(row => {
selectedRows[row._id] = true selectedRows[row._id] = true
}) })
} }
} }
const handleChange = async (rowId, field, value) => { const handleChange = async (rowId, field, value) => {
let row = $fetch.rows.find(x => x._id === rowId) let row = rows.find(x => x._id === rowId)
if (!row) { if (!row) {
return return
} }
@ -125,10 +127,10 @@
const deleteRows = () => { const deleteRows = () => {
// Fetch full row objects to be deleted // Fetch full row objects to be deleted
const rows = Object.entries(selectedRows) const rowsToDelete = Object.entries(selectedRows)
.map(entry => { .map(entry => {
if (entry[1] === true) { if (entry[1] === true) {
return $fetch.rows.find(x => x._id === entry[0]) return rows.find(x => x._id === entry[0])
} else { } else {
return null return null
} }
@ -139,7 +141,7 @@
const performDeletion = async () => { const performDeletion = async () => {
await API.deleteRows({ await API.deleteRows({
tableId: table.tableId, tableId: table.tableId,
rows, rows: rowsToDelete,
}) })
await fetch.refresh() await fetch.refresh()
notificationStore.actions.success( notificationStore.actions.success(
@ -163,6 +165,23 @@
performDeletion performDeletion
) )
} }
const addRow = async field => {
const res = await API.saveRow({ tableId: table.tableId })
selectedCell = `${res._id}-${field}`
newRows.push(res._id)
await fetch.refresh()
}
const getSortedRows = (rows, newRows) => {
let sortedRows = rows.slice()
sortedRows.sort((a, b) => {
const aIndex = newRows.indexOf(a._id)
const bIndex = newRows.indexOf(b._id)
return aIndex < bIndex ? -1 : 1
})
return sortedRows
}
</script> </script>
<div use:styleable={$component.styles}> <div use:styleable={$component.styles}>
@ -185,7 +204,12 @@
{/if} {/if}
</div> </div>
</div> </div>
<div class="spreadsheet" on:scroll={handleScroll} style={gridStyles}> <div
class="spreadsheet"
on:scroll={handleScroll}
style={gridStyles}
on:click|self={() => (selectedCell = null)}
>
<!-- Field headers --> <!-- Field headers -->
<div class="header cell label" on:click={selectAll}> <div class="header cell label" on:click={selectAll}>
<input <input
@ -209,7 +233,7 @@
{/each} {/each}
<!-- All real rows --> <!-- All real rows -->
{#each $fetch.rows as row, rowIdx (row._id)} {#each rows as row, rowIdx (row._id)}
{@const rowSelected = !!selectedRows[row._id]} {@const rowSelected = !!selectedRows[row._id]}
{@const rowHovered = hoveredRow === row._id} {@const rowHovered = hoveredRow === row._id}
{@const data = { ...row, ...changeCache[row._id] }} {@const data = { ...row, ...changeCache[row._id] }}
@ -254,14 +278,15 @@
{/each} {/each}
<!-- New row placeholder --> <!-- New row placeholder -->
<div class="cell label"> <div class="cell label new" on:click={addRow}>
<Icon hoverable name="Add" /> <Icon hoverable name="Add" />
</div> </div>
{#each fields as field, fieldIdx} {#each fields as field, fieldIdx}
<div <div
class="cell" class="cell new"
class:sticky={fieldIdx === 0} class:sticky={fieldIdx === 0}
class:shadow={horizontallyScrolled} class:shadow={horizontallyScrolled}
on:click={() => addRow(field)}
/> />
{/each} {/each}
</div> </div>
@ -284,9 +309,9 @@
justify-content: flex-start; justify-content: flex-start;
align-items: stretch; align-items: stretch;
overflow: auto; overflow: auto;
max-height: 800px; max-height: 1014px;
position: relative; position: relative;
padding-bottom: 80px; padding-bottom: 180px;
padding-right: 100px; padding-right: 100px;
} }
@ -363,6 +388,9 @@
.cell.row-selected { .cell.row-selected {
background-color: rgb(224, 242, 255); background-color: rgb(224, 242, 255);
} }
.cell.new:hover {
cursor: pointer;
}
.header { .header {
background: var(--spectrum-global-color-gray-200); background: var(--spectrum-global-color-gray-200);