diff --git a/packages/client/src/components/app/spreadsheet/Spreadsheet.svelte b/packages/client/src/components/app/spreadsheet/Spreadsheet.svelte index 5f6d01fa7a..72ce139e5e 100644 --- a/packages/client/src/components/app/spreadsheet/Spreadsheet.svelte +++ b/packages/client/src/components/app/spreadsheet/Spreadsheet.svelte @@ -13,13 +13,13 @@ const { styleable, API } = getContext("sdk") const component = getContext("component") - - // Config const limit = 100 const defaultWidth = 200 + let widths let hoveredRow let selectedCell + let selectedRows = {} let horizontallyScrolled = false $: query = LuceneUtils.buildLuceneQuery(filter) @@ -34,6 +34,8 @@ $: initWidths(fields) $: gridStyles = getGridStyles(widths) $: schema = $fetch.schema + $: rowCount = $fetch.rows?.length || 0 + $: selectedRowCount = Object.values(selectedRows).filter(x => !!x).length const createFetch = datasource => { return fetchData({ @@ -57,7 +59,7 @@ if (!widths?.length) { return "--grid: 1fr;" } - return `--grid: 60px ${widths.map(x => `${x}px`).join(" ")};` + return `--grid: 50px ${widths.map(x => `${x}px`).join(" ")};` } const handleScroll = e => { @@ -86,6 +88,21 @@ } return "Text" } + + const selectRow = idx => { + selectedRows[idx] = !selectedRows[idx] + } + + const selectAll = () => { + const allSelected = selectedRowCount === rowCount + if (allSelected) { + selectedRows = {} + } else { + for (let i = 0; i < rowCount; i++) { + selectedRows[i] = true + } + } + }
@@ -107,8 +124,12 @@
-
- + +
+
{#each fields as field, fieldIdx}
{/each} + + {#each $fetch.rows as row, rowIdx} -
- {rowIdx + 1} + {@const rowSelected = !!selectedRows[rowIdx]} + {@const rowHovered = hoveredRow === rowIdx} +
(hoveredRow = rowIdx)} + on:click={() => selectRow(rowIdx)} + > + {#if rowSelected || rowHovered} + + {:else} + + {rowIdx + 1} + + {/if}
{#each fields as field, fieldIdx} {@const cellIdx = rowIdx * fields.length + fieldIdx}
{/each} {/each} + + +
+ +
+ {#each fields as field, fieldIdx} +
+ {/each} +
+
@@ -170,6 +228,12 @@ overflow: auto; height: 800px; position: relative; + padding-bottom: 100px; + padding-right: 100px; + } + + .wrapper ::-webkit-scrollbar-track { + background: var(--spectrum-global-color-gray-50); } .controls { @@ -177,7 +241,7 @@ grid-template-columns: 1fr auto 1fr; align-items: center; height: 36px; - padding: 0 16px; + padding: 0 12px; background: var(--spectrum-global-color-gray-200); gap: 8px; border-bottom: 1px solid var(--spectrum-global-color-gray-400); @@ -207,29 +271,29 @@ flex-direction: row; justify-content: flex-start; align-items: center; - background: var(--spectrum-global-color-gray-50); color: var(--spectrum-global-color-gray-900); font-size: 14px; gap: 4px; - } - .cell:last-child { - border-right: none; + background: var(--spectrum-global-color-gray-50); } .cell.hovered { background: var(--spectrum-global-color-gray-100); } .cell.selected { - box-shadow: inset 0 0 0 2px var(--primaryColorHover); + box-shadow: inset 0 0 0 2px rgb(89, 167, 246); z-index: 1; } .cell:hover { - cursor: pointer; + cursor: default; } .cell.sticky { position: sticky; - left: 60px; + left: 50px; z-index: 2; } + .cell.row-selected { + background-color: rgba(20, 122, 243, 0.05); + } .header { background: var(--spectrum-global-color-gray-200); @@ -253,9 +317,8 @@ } .label { - padding: 0 16px; + padding: 0 12px; border-right: none; - color: var(--spectrum-global-color-gray-500); position: sticky; left: 0; z-index: 2; @@ -263,7 +326,25 @@ .label.header { z-index: 4; } - .label.header input { + .label span { + min-width: 14px; + text-align: center; + color: var(--spectrum-global-color-gray-500); + } + + input[type="checkbox"] { margin: 0; } + + .footer { + height: 32px; + width: 100%; + border-top: 1px solid var(--spectrum-global-color-gray-400); + padding: 0 12px; + display: flex; + flex-direction: row; + justify-content: flex-start; + align-items: center; + background: var(--spectrum-global-color-gray-50); + }