add ability to select rows from different tables and provide bindings

This commit is contained in:
Peter Clement 2022-02-22 15:18:08 +00:00
parent 87d001b66f
commit dffdcd882f
5 changed files with 86 additions and 44 deletions

View File

@ -30,6 +30,7 @@
export let customRenderers = [] export let customRenderers = []
export let disableSorting = false export let disableSorting = false
export let allowSelectAllRows = false export let allowSelectAllRows = false
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
// Config // Config
const rowHeight = 55 const rowHeight = 55
@ -43,6 +44,8 @@
// Table state // Table state
let height = 0 let height = 0
let loaded = false let loaded = false
let checkboxStatus = false
$: schema = fixSchema(schema) $: schema = fixSchema(schema)
$: if (!loading) loaded = true $: if (!loading) loaded = true
$: rows = data ?? [] $: rows = data ?? []
@ -52,6 +55,16 @@
$: fields = getFields(schema, showAutoColumns) $: fields = getFields(schema, showAutoColumns)
$: showEditColumn = allowEditRows || allowSelectRows $: showEditColumn = allowEditRows || allowSelectRows
// Deselect the "select all" checkbox whern the user navigates to a new page
$: {
let checkRowCount = rows.filter(o1 =>
selectedRows.some(o2 => o1._id === o2._id)
)
if (checkRowCount.length === 0) {
checkboxStatus = false
}
}
// Scrolling state // Scrolling state
let timeout let timeout
let nextScrollTop = 0 let nextScrollTop = 0
@ -207,10 +220,23 @@
if (!allowSelectAllRows) { if (!allowSelectAllRows) {
return return
} }
if (e.detail) { if (e.detail) {
selectedRows = rows let rowsToAdd = []
rows.map(x =>
selectedRows
.map(y => rows.map(x => x._id).indexOf(y._id))
.includes(true)
? null
: rowsToAdd.push(x)
)
selectedRows = [...selectedRows, ...rowsToAdd]
} else { } else {
selectedRows = [] //remove every object from selectedRows that is not in rows
let filtered = selectedRows.filter(el =>
rows.every(f => f._id !== el._id)
)
selectedRows = filtered
} }
} }
@ -219,9 +245,6 @@
return return
} }
if (selectedRows.some(selectedRow => selectedRow._id === row._id)) { if (selectedRows.some(selectedRow => selectedRow._id === row._id)) {
console.log("hello")
console.log(row)
selectedRows = selectedRows.filter( selectedRows = selectedRows.filter(
selectedRow => selectedRow._id !== row._id selectedRow => selectedRow._id !== row._id
) )
@ -250,7 +273,10 @@
<th class="spectrum-Table-headCell"> <th class="spectrum-Table-headCell">
<div class="spectrum-Table-headCell-content"> <div class="spectrum-Table-headCell-content">
{#if allowSelectAllRows} {#if allowSelectAllRows}
<Checkbox on:change={toggleSelectAll} /> <Checkbox
bind:value={checkboxStatus}
on:change={toggleSelectAll}
/>
{:else} {:else}
{editColumnTitle || ""} {editColumnTitle || ""}
{/if} {/if}

View File

@ -32,7 +32,7 @@ export const getBindableProperties = (asset, componentId) => {
const urlBindings = getUrlBindings(asset) const urlBindings = getUrlBindings(asset)
const deviceBindings = getDeviceBindings() const deviceBindings = getDeviceBindings()
const stateBindings = getStateBindings() const stateBindings = getStateBindings()
const rowBindings = getRowBindings() const rowBindings = getRowBindings(asset, componentId)
return [ return [
...contextBindings, ...contextBindings,
...urlBindings, ...urlBindings,
@ -321,16 +321,21 @@ const getDeviceBindings = () => {
* Gets all row bindings that are globally available. * Gets all row bindings that are globally available.
*/ */
const getRowBindings = () => { const getRowBindings = () => {
let tables = []
getAllAssets().forEach(asset => {
tables = findAllMatchingComponents(asset.props, component =>
component._component.endsWith("table")
)
})
let bindings = [] let bindings = []
if (get(store).clientFeatures?.rowSelection) { if (get(store).clientFeatures?.rowSelection) {
const safeState = makePropSafe("rowSelection") const safeState = makePropSafe("rowSelection")
bindings = [ bindings = tables.map(table => ({
{ type: "context",
type: "context", runtimeBinding: `${safeState}.${makePropSafe(table._id)}`,
runtimeBinding: `${safeState}`, readableBinding: `${table._instanceName}.Rows`,
readableBinding: "Row Selection.Rows", }))
},
]
} }
return bindings return bindings
} }
@ -340,8 +345,8 @@ const getRowBindings = () => {
*/ */
const getStateBindings = () => { const getStateBindings = () => {
let bindings = [] let bindings = []
if (get(store).clientFeatures?.rowSelection) { if (get(store).clientFeatures?.state) {
const safeState = makePropSafe("rowSelection") const safeState = makePropSafe("state")
bindings = getAllStateVariables().map(key => ({ bindings = getAllStateVariables().map(key => ({
type: "context", type: "context",
runtimeBinding: `${safeState}.${makePropSafe(key)}`, runtimeBinding: `${safeState}.${makePropSafe(key)}`,
@ -617,14 +622,9 @@ const buildFormSchema = component => {
* in the app. * in the app.
*/ */
export const getAllStateVariables = () => { export const getAllStateVariables = () => {
// Get all component containing assets
let allAssets = []
allAssets = allAssets.concat(get(store).layouts || [])
allAssets = allAssets.concat(get(store).screens || [])
// Find all button action settings in all components // Find all button action settings in all components
let eventSettings = [] let eventSettings = []
allAssets.forEach(asset => { getAllAssets().forEach(asset => {
findAllMatchingComponents(asset.props, component => { findAllMatchingComponents(asset.props, component => {
const settings = getComponentSettings(component._component) const settings = getComponentSettings(component._component)
settings settings
@ -655,6 +655,15 @@ export const getAllStateVariables = () => {
return Array.from(bindingSet) return Array.from(bindingSet)
} }
export const getAllAssets = () => {
// Get all component containing assets
let allAssets = []
allAssets = allAssets.concat(get(store).layouts || [])
allAssets = allAssets.concat(get(store).screens || [])
return allAssets
}
/** /**
* Recurses the input object to remove any instances of bindings. * Recurses the input object to remove any instances of bindings.
*/ */

View File

@ -11,8 +11,7 @@
export let limit export let limit
export let paginate export let paginate
const { styleable, Provider, ActionTypes, API, rowSelectionStore } = const { styleable, Provider, ActionTypes, API } = getContext("sdk")
getContext("sdk")
const component = getContext("component") const component = getContext("component")
// We need to manage our lucene query manually as we want to allow components // We need to manage our lucene query manually as we want to allow components
@ -140,19 +139,14 @@
<slot /> <slot />
{/if} {/if}
{#if paginate && $fetch.supportsPagination} {#if paginate && $fetch.supportsPagination}
<div class="footer"> <div class="pagination">
<div class="rowSelection"> <Pagination
{$rowSelectionStore.length} record(s) selected page={$fetch.pageNumber + 1}
</div> hasPrevPage={$fetch.hasPrevPage}
<div> hasNextPage={$fetch.hasNextPage}
<Pagination goToPrevPage={fetch.prevPage}
page={$fetch.pageNumber + 1} goToNextPage={fetch.nextPage}
hasPrevPage={$fetch.hasPrevPage} />
hasNextPage={$fetch.hasNextPage}
goToPrevPage={fetch.prevPage}
goToNextPage={fetch.nextPage}
/>
</div>
</div> </div>
{/if} {/if}
{/if} {/if}
@ -173,10 +167,10 @@
align-items: center; align-items: center;
height: 100px; height: 100px;
} }
.footer { .pagination {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: space-between; justify-content: flex-end;
align-items: center; align-items: center;
margin-top: var(--spacing-xl); margin-top: var(--spacing-xl);
} }

View File

@ -39,7 +39,10 @@
) )
$: { $: {
rowSelectionStore.actions.update(selectedRows) rowSelectionStore.actions.updateSelection(
$component.id,
selectedRows.map(row => row._id)
)
} }
const getFields = (schema, customColumns, showAutoColumns) => { const getFields = (schema, customColumns, showAutoColumns) => {
// Check for an invalid column selection // Check for an invalid column selection
@ -137,10 +140,18 @@
> >
<slot /> <slot />
</Table> </Table>
{#if allowSelectRows}
<div class="row-count">{selectedRows.length} record(s) selected</div>
{/if}
</div> </div>
<style> <style>
div { div {
background-color: var(--spectrum-alias-background-color-secondary); background-color: var(--spectrum-alias-background-color-secondary);
} }
.row-count {
margin-top: calc(1.4 * var(--spacing-xl));
position: absolute;
}
</style> </style>

View File

@ -1,18 +1,20 @@
import { writable } from "svelte/store" import { writable } from "svelte/store"
const createRowSelectionStore = () => { const createRowSelectionStore = () => {
const store = writable([]) const store = writable({})
function update(rows) { function updateSelection(componentId, selectedRows) {
store.update(state => { store.update(state => {
state = [...rows] state[componentId] = [...selectedRows]
return state return state
}) })
} }
return { return {
subscribe: store.subscribe, subscribe: store.subscribe,
set: store.set,
actions: { actions: {
update, updateSelection,
}, },
} }
} }