Allow expanding rows using existing edit row modal
This commit is contained in:
parent
5640b2fa89
commit
7570c52879
8 changed files with 109 additions and 71 deletions
|
@ -23,9 +23,9 @@
|
|||
async function saveRow() {
|
||||
errors = []
|
||||
try {
|
||||
await API.saveRow({ ...row, tableId: table._id })
|
||||
const res = await API.saveRow({ ...row, tableId: table._id })
|
||||
notifications.success("Row saved successfully")
|
||||
dispatch("updaterows")
|
||||
dispatch("updaterows", res._id)
|
||||
} catch (error) {
|
||||
if (error.handled) {
|
||||
const response = error.json
|
||||
|
|
|
@ -2,13 +2,27 @@
|
|||
import CreateEditRow from "../../modals/CreateEditRow.svelte"
|
||||
import { getContext, onMount } from "svelte"
|
||||
import { Modal } from "@budibase/bbui"
|
||||
import { cloneDeep } from "lodash/fp"
|
||||
|
||||
const { subscribe } = getContext("sheet")
|
||||
const { subscribe, rows } = getContext("sheet")
|
||||
|
||||
let modal
|
||||
onMount(() => subscribe("add-row", modal.show))
|
||||
let row
|
||||
|
||||
onMount(() =>
|
||||
subscribe("add-row", () => {
|
||||
row = {}
|
||||
modal.show()
|
||||
})
|
||||
)
|
||||
onMount(() =>
|
||||
subscribe("edit-row", rowToEdit => {
|
||||
row = cloneDeep(rowToEdit)
|
||||
modal.show()
|
||||
})
|
||||
)
|
||||
</script>
|
||||
|
||||
<Modal bind:this={modal}>
|
||||
<CreateEditRow />
|
||||
<CreateEditRow {row} on:updaterows={e => rows.actions.refreshRow(e.detail)} />
|
||||
</Modal>
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
import { clickOutside } from "@budibase/bbui"
|
||||
import AddRowButton from "../controls/AddRowButton.svelte"
|
||||
import SheetControls from "./SheetControls.svelte"
|
||||
import SidePanel from "./SidePanel.svelte"
|
||||
|
||||
export let API
|
||||
export let tableId
|
||||
|
@ -35,19 +34,21 @@
|
|||
export let allowSelectRows = true
|
||||
export let allowAddColumns = true
|
||||
export let allowEditColumns = true
|
||||
export let allowExpandRows = true
|
||||
|
||||
// Sheet constants
|
||||
const cellHeight = 36
|
||||
const gutterWidth = 80
|
||||
const gutterWidth = 72
|
||||
const rand = Math.random()
|
||||
|
||||
// State stores
|
||||
const tableIdStore = writable(tableId)
|
||||
const config = writable({
|
||||
tableId,
|
||||
allowAddRows,
|
||||
allowSelectRows,
|
||||
allowAddColumns,
|
||||
allowEditColumns,
|
||||
allowExpandRows,
|
||||
})
|
||||
|
||||
// Build up spreadsheet context
|
||||
|
@ -58,6 +59,7 @@
|
|||
cellHeight,
|
||||
gutterWidth,
|
||||
config,
|
||||
tableId: tableIdStore,
|
||||
}
|
||||
context = { ...context, ...createEventManagers() }
|
||||
context = { ...context, ...createBoundsStores(context) }
|
||||
|
@ -76,13 +78,14 @@
|
|||
// Reference some stores for local use
|
||||
const { isResizing, isReordering, ui, loaded } = context
|
||||
|
||||
// Keep config store up to date
|
||||
// Keep stores up to date
|
||||
$: tableIdStore.set(tableId)
|
||||
$: config.set({
|
||||
tableId,
|
||||
allowAddRows,
|
||||
allowSelectRows,
|
||||
allowAddColumns,
|
||||
allowEditColumns,
|
||||
allowExpandRows,
|
||||
})
|
||||
|
||||
// Set context for children to consume
|
||||
|
@ -127,7 +130,6 @@
|
|||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
<SidePanel />
|
||||
<KeyboardManager />
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
<script>
|
||||
import { getContext } from "svelte"
|
||||
|
||||
const { sidePanelRowId } = getContext("sheet")
|
||||
|
||||
$: visible = $sidePanelRowId != null
|
||||
</script>
|
||||
|
||||
<div class="side-panel" class:visible>some content</div>
|
||||
|
||||
<style>
|
||||
.side-panel {
|
||||
width: 320px;
|
||||
transform: translateX(100%);
|
||||
transition: transform 130ms ease-out;
|
||||
}
|
||||
.side-panel.visible {
|
||||
transform: translateX(0);
|
||||
}
|
||||
</style>
|
|
@ -1,6 +1,6 @@
|
|||
<script>
|
||||
import { getContext } from "svelte"
|
||||
import { Checkbox } from "@budibase/bbui"
|
||||
import { Checkbox, Icon } from "@budibase/bbui"
|
||||
import SheetCell from "../cells/SheetCell.svelte"
|
||||
import DataCell from "../cells/DataCell.svelte"
|
||||
import SheetScrollWrapper from "./SheetScrollWrapper.svelte"
|
||||
|
@ -19,6 +19,7 @@
|
|||
selectedCellMap,
|
||||
selectedCellRow,
|
||||
gutterWidth,
|
||||
dispatch,
|
||||
} = getContext("sheet")
|
||||
|
||||
$: scrollLeft = $scroll.left
|
||||
|
@ -59,17 +60,24 @@
|
|||
class:scrolled={scrollLeft > 0}
|
||||
>
|
||||
<div class="header row">
|
||||
<SheetCell
|
||||
width={gutterWidth}
|
||||
on:click={$config.allowSelectRows && selectAll}
|
||||
center
|
||||
>
|
||||
{#if $config.allowSelectRows}
|
||||
<Checkbox
|
||||
value={rowCount && selectedRowCount === rowCount}
|
||||
disabled={!$renderedRows.length}
|
||||
/>
|
||||
{/if}
|
||||
<SheetCell width={gutterWidth}>
|
||||
<div class="gutter">
|
||||
<div class="checkbox visible">
|
||||
{#if $config.allowSelectRows}
|
||||
<div on:click={$config.allowSelectRows && selectAll}>
|
||||
<Checkbox
|
||||
value={rowCount && selectedRowCount === rowCount}
|
||||
disabled={!$renderedRows.length}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{#if $config.allowExpandRows}
|
||||
<div class="expand">
|
||||
<Icon name="Maximize" size="S" />
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</SheetCell>
|
||||
|
||||
{#if $stickyColumn}
|
||||
|
@ -89,25 +97,41 @@
|
|||
on:mouseleave={() => ($hoveredRowId = null)}
|
||||
>
|
||||
<SheetCell
|
||||
width={gutterWidth}
|
||||
rowSelected={rowSelected || containsSelectedRow}
|
||||
{rowHovered}
|
||||
width={gutterWidth}
|
||||
center
|
||||
>
|
||||
<div
|
||||
on:click={() => selectRow(row._id)}
|
||||
class="checkbox"
|
||||
class:visible={$config.allowSelectRows &&
|
||||
(rowSelected || rowHovered)}
|
||||
>
|
||||
<Checkbox value={rowSelected} />
|
||||
</div>
|
||||
<div
|
||||
class="number"
|
||||
class:visible={!$config.allowSelectRows ||
|
||||
!(rowSelected || rowHovered)}
|
||||
>
|
||||
{row.__idx + 1}
|
||||
<div class="gutter">
|
||||
<div
|
||||
on:click={() => selectRow(row._id)}
|
||||
class="checkbox"
|
||||
class:visible={$config.allowSelectRows &&
|
||||
(rowSelected || rowHovered || containsSelectedRow)}
|
||||
>
|
||||
<Checkbox value={rowSelected} />
|
||||
</div>
|
||||
<div
|
||||
class="number"
|
||||
class:visible={!$config.allowSelectRows ||
|
||||
!(rowSelected || rowHovered || containsSelectedRow)}
|
||||
>
|
||||
{row.__idx + 1}
|
||||
</div>
|
||||
{#if $config.allowExpandRows}
|
||||
<div
|
||||
class="expand"
|
||||
class:visible={containsSelectedRow || rowHovered}
|
||||
>
|
||||
<Icon
|
||||
name="Maximize"
|
||||
hoverable
|
||||
size="S"
|
||||
on:click={() => {
|
||||
dispatch("edit-row", row)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</SheetCell>
|
||||
|
||||
|
@ -172,20 +196,35 @@
|
|||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
/* Styles for label cell */
|
||||
/* Styles for gutter */
|
||||
.gutter {
|
||||
flex: 1 1 auto;
|
||||
display: grid;
|
||||
align-items: center;
|
||||
padding: var(--cell-padding);
|
||||
grid-template-columns: 1fr auto;
|
||||
gap: var(--cell-spacing);
|
||||
}
|
||||
.checkbox,
|
||||
.number {
|
||||
padding: 0 var(--cell-padding);
|
||||
}
|
||||
.checkbox {
|
||||
display: none;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.number {
|
||||
display: none;
|
||||
color: var(--spectrum-global-color-gray-500);
|
||||
}
|
||||
.checkbox.visible,
|
||||
.number.visible {
|
||||
display: flex;
|
||||
}
|
||||
.expand {
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
.expand.visible {
|
||||
opacity: 1;
|
||||
pointer-events: all;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import { derived, get } from "svelte/store"
|
||||
import { get } from "svelte/store"
|
||||
import { io } from "socket.io-client"
|
||||
|
||||
export const createWebsocket = context => {
|
||||
const { rows, config, users, userId, selectedCellId } = context
|
||||
const tableId = derived(config, $config => $config.tableId)
|
||||
const { rows, tableId, users, userId, selectedCellId } = context
|
||||
|
||||
// Determine connection info
|
||||
const tls = location.protocol === "https:"
|
||||
|
|
|
@ -3,8 +3,7 @@ import { fetchData } from "../../../fetch/fetchData"
|
|||
import { notifications } from "@budibase/bbui"
|
||||
|
||||
export const createRowsStore = context => {
|
||||
const { config, API, scroll } = context
|
||||
const tableId = derived(config, $config => $config.tableId)
|
||||
const { tableId, API, scroll } = context
|
||||
const rows = writable([])
|
||||
const table = writable(null)
|
||||
const filter = writable([])
|
||||
|
@ -115,6 +114,12 @@ export const createRowsStore = context => {
|
|||
})
|
||||
})
|
||||
|
||||
// Gets a row by ID
|
||||
const getRow = id => {
|
||||
const index = get(rowLookupMap)[id]
|
||||
return index >= 0 ? get(enrichedRows)[index] : null
|
||||
}
|
||||
|
||||
// Adds a new empty row
|
||||
const addRow = async (row, idx) => {
|
||||
try {
|
||||
|
@ -281,6 +286,7 @@ export const createRowsStore = context => {
|
|||
subscribe: enrichedRows.subscribe,
|
||||
actions: {
|
||||
addRow,
|
||||
getRow,
|
||||
updateRow,
|
||||
deleteRows,
|
||||
hasRow,
|
||||
|
|
|
@ -6,7 +6,6 @@ export const createUIStores = context => {
|
|||
const selectedRows = writable({})
|
||||
const hoveredRowId = writable(null)
|
||||
const selectedCellAPI = writable(null)
|
||||
const sidePanelRowId = writable(null)
|
||||
|
||||
// Derive the row that contains the selected cell.
|
||||
const selectedCellRow = derived(
|
||||
|
@ -93,7 +92,6 @@ export const createUIStores = context => {
|
|||
hoveredRowId,
|
||||
selectedCellRow,
|
||||
selectedCellAPI,
|
||||
sidePanelRowId,
|
||||
ui: {
|
||||
actions: {
|
||||
blur,
|
||||
|
|
Loading…
Reference in a new issue