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 disableSorting = false
export let allowSelectAllRows = false
const dispatch = createEventDispatcher()
// Config
const rowHeight = 55
@ -43,6 +44,8 @@
// Table state
let height = 0
let loaded = false
let checkboxStatus = false
$: schema = fixSchema(schema)
$: if (!loading) loaded = true
$: rows = data ?? []
@ -52,6 +55,16 @@
$: fields = getFields(schema, showAutoColumns)
$: 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
let timeout
let nextScrollTop = 0
@ -207,10 +220,23 @@
if (!allowSelectAllRows) {
return
}
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 {
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
}
if (selectedRows.some(selectedRow => selectedRow._id === row._id)) {
console.log("hello")
console.log(row)
selectedRows = selectedRows.filter(
selectedRow => selectedRow._id !== row._id
)
@ -250,7 +273,10 @@
<th class="spectrum-Table-headCell">
<div class="spectrum-Table-headCell-content">
{#if allowSelectAllRows}
<Checkbox on:change={toggleSelectAll} />
<Checkbox
bind:value={checkboxStatus}
on:change={toggleSelectAll}
/>
{:else}
{editColumnTitle || ""}
{/if}

View File

@ -32,7 +32,7 @@ export const getBindableProperties = (asset, componentId) => {
const urlBindings = getUrlBindings(asset)
const deviceBindings = getDeviceBindings()
const stateBindings = getStateBindings()
const rowBindings = getRowBindings()
const rowBindings = getRowBindings(asset, componentId)
return [
...contextBindings,
...urlBindings,
@ -321,16 +321,21 @@ const getDeviceBindings = () => {
* Gets all row bindings that are globally available.
*/
const getRowBindings = () => {
let tables = []
getAllAssets().forEach(asset => {
tables = findAllMatchingComponents(asset.props, component =>
component._component.endsWith("table")
)
})
let bindings = []
if (get(store).clientFeatures?.rowSelection) {
const safeState = makePropSafe("rowSelection")
bindings = [
{
type: "context",
runtimeBinding: `${safeState}`,
readableBinding: "Row Selection.Rows",
},
]
bindings = tables.map(table => ({
type: "context",
runtimeBinding: `${safeState}.${makePropSafe(table._id)}`,
readableBinding: `${table._instanceName}.Rows`,
}))
}
return bindings
}
@ -340,8 +345,8 @@ const getRowBindings = () => {
*/
const getStateBindings = () => {
let bindings = []
if (get(store).clientFeatures?.rowSelection) {
const safeState = makePropSafe("rowSelection")
if (get(store).clientFeatures?.state) {
const safeState = makePropSafe("state")
bindings = getAllStateVariables().map(key => ({
type: "context",
runtimeBinding: `${safeState}.${makePropSafe(key)}`,
@ -617,14 +622,9 @@ const buildFormSchema = component => {
* in the app.
*/
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
let eventSettings = []
allAssets.forEach(asset => {
getAllAssets().forEach(asset => {
findAllMatchingComponents(asset.props, component => {
const settings = getComponentSettings(component._component)
settings
@ -655,6 +655,15 @@ export const getAllStateVariables = () => {
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.
*/

View File

@ -11,8 +11,7 @@
export let limit
export let paginate
const { styleable, Provider, ActionTypes, API, rowSelectionStore } =
getContext("sdk")
const { styleable, Provider, ActionTypes, API } = getContext("sdk")
const component = getContext("component")
// We need to manage our lucene query manually as we want to allow components
@ -140,19 +139,14 @@
<slot />
{/if}
{#if paginate && $fetch.supportsPagination}
<div class="footer">
<div class="rowSelection">
{$rowSelectionStore.length} record(s) selected
</div>
<div>
<Pagination
page={$fetch.pageNumber + 1}
hasPrevPage={$fetch.hasPrevPage}
hasNextPage={$fetch.hasNextPage}
goToPrevPage={fetch.prevPage}
goToNextPage={fetch.nextPage}
/>
</div>
<div class="pagination">
<Pagination
page={$fetch.pageNumber + 1}
hasPrevPage={$fetch.hasPrevPage}
hasNextPage={$fetch.hasNextPage}
goToPrevPage={fetch.prevPage}
goToNextPage={fetch.nextPage}
/>
</div>
{/if}
{/if}
@ -173,10 +167,10 @@
align-items: center;
height: 100px;
}
.footer {
.pagination {
display: flex;
flex-direction: row;
justify-content: space-between;
justify-content: flex-end;
align-items: center;
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) => {
// Check for an invalid column selection
@ -137,10 +140,18 @@
>
<slot />
</Table>
{#if allowSelectRows}
<div class="row-count">{selectedRows.length} record(s) selected</div>
{/if}
</div>
<style>
div {
background-color: var(--spectrum-alias-background-color-secondary);
}
.row-count {
margin-top: calc(1.4 * var(--spacing-xl));
position: absolute;
}
</style>

View File

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