more ag grid styling
This commit is contained in:
parent
be407ece71
commit
eb1192ebc0
|
@ -2,19 +2,9 @@
|
|||
import { goto, params } from "@sveltech/routify"
|
||||
import { onMount } from "svelte"
|
||||
import { fade } from "svelte/transition"
|
||||
import fsort from "fast-sort"
|
||||
import getOr from "lodash/fp/getOr"
|
||||
import { store, backendUiStore } from "builderStore"
|
||||
import api from "builderStore/api"
|
||||
import { Button, Icon } from "@budibase/bbui"
|
||||
import ActionButton from "components/common/ActionButton.svelte"
|
||||
import CreateEditRowModal from "./modals/CreateEditRowModal.svelte"
|
||||
import RowPopover from "./buttons/CreateRowButton.svelte"
|
||||
import ColumnPopover from "./buttons/CreateColumnButton.svelte"
|
||||
import ViewPopover from "./buttons/CreateViewButton.svelte"
|
||||
import ColumnHeaderPopover from "./popovers/ColumnPopover.svelte"
|
||||
import EditRowPopover from "./popovers/RowPopover.svelte"
|
||||
import CalculationPopover from "./buttons/CalculateButton.svelte"
|
||||
import Spinner from "components/common/Spinner.svelte"
|
||||
|
||||
// New
|
||||
|
@ -28,7 +18,6 @@
|
|||
export let allowEditing = false
|
||||
export let loading = false
|
||||
|
||||
// New stuff
|
||||
export let theme = "alpine"
|
||||
|
||||
let columnDefs = []
|
||||
|
@ -93,21 +82,6 @@
|
|||
// `/${$params.application}/data/table/${tableId}/relationship/${row._id}/${fieldName}`
|
||||
// )
|
||||
// }
|
||||
|
||||
// New stuff
|
||||
// const deleteRows = async () => {
|
||||
// const response = await api.post(`/api/${tableId}/rows`, {
|
||||
// rows: selectedRows,
|
||||
// type: "delete",
|
||||
// })
|
||||
// data = data.filter(row => !selectedRows.includes(row))
|
||||
// selectedRows = []
|
||||
// }
|
||||
|
||||
// const handleUpdate = ({ detail }) => {
|
||||
// data[detail.row] = detail.data
|
||||
// updateRow(detail.data)
|
||||
// }
|
||||
</script>
|
||||
|
||||
<section>
|
||||
|
@ -159,4 +133,10 @@
|
|||
margin-right: var(--spacing-m);
|
||||
margin-bottom: var(--spacing-xl);
|
||||
}
|
||||
|
||||
:global(.ag-header-cell-text) {
|
||||
font-family: Inter;
|
||||
font-weight: 600;
|
||||
color: var(--ink);
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -40,19 +40,6 @@
|
|||
modal.show()
|
||||
}
|
||||
|
||||
async function saveColumn() {
|
||||
backendUiStore.update(state => {
|
||||
backendUiStore.actions.tables.saveField({
|
||||
originalName,
|
||||
field,
|
||||
primaryDisplay,
|
||||
})
|
||||
return state
|
||||
})
|
||||
notifier.success(`Column ${field.name} saved successfully.`)
|
||||
modal.hide()
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
column.addEventListener("sortChanged", () => {
|
||||
sortDirection = column.getSort()
|
||||
|
@ -64,15 +51,15 @@
|
|||
<div>
|
||||
<span>{field.name}</span>
|
||||
{#if enableSorting && sortDirection}
|
||||
<i class={SORT_ICON_MAP[sortDirection]} />
|
||||
<i class={`${SORT_ICON_MAP[sortDirection]} sort-icon`} />
|
||||
{/if}
|
||||
</div>
|
||||
<Modal bind:this={modal}>
|
||||
<ModalContent
|
||||
title={`Edit Column: ${field.name}`}
|
||||
confirmText={'Save Column'}
|
||||
onConfirm={saveColumn}>
|
||||
<CreateEditColumnPopover {field} />
|
||||
showCancelButton={false}
|
||||
showConfirmButton={false}
|
||||
title={`Edit Column: ${field.name}`}>
|
||||
<CreateEditColumnPopover onClosed={modal.hide} {field} />
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
<div>
|
||||
|
@ -88,10 +75,31 @@
|
|||
<style>
|
||||
header {
|
||||
font-family: Inter;
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
color: var(--ink);
|
||||
}
|
||||
|
||||
.sort-icon {
|
||||
position: relative;
|
||||
top: 2px;
|
||||
}
|
||||
|
||||
i {
|
||||
transition: 0.2s all;
|
||||
font-size: var(--font-size-m);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
i:hover {
|
||||
color: var(--blue);
|
||||
}
|
||||
|
||||
i:active {
|
||||
color: var(--blue);
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -20,9 +20,9 @@
|
|||
</div>
|
||||
<Modal bind:this={modal}>
|
||||
<ModalContent
|
||||
title={'Create Column'}
|
||||
confirmText={'Save Column'}
|
||||
onConfirm={console.log}>
|
||||
<CreateEditColumnPopover />
|
||||
showCancelButton={false}
|
||||
showConfirmButton={false}
|
||||
title={'Create Column'}>
|
||||
<CreateEditColumnPopover onClosed={modal.hide} />
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
import ActionButton from "components/common/ActionButton.svelte"
|
||||
import DatePicker from "components/common/DatePicker.svelte"
|
||||
import LinkedRowSelector from "components/common/LinkedRowSelector.svelte"
|
||||
import ConfirmDialog from "components/common/ConfirmDialog.svelte"
|
||||
import * as api from "../api"
|
||||
|
||||
let fieldDefinitions = cloneDeep(FIELDS)
|
||||
|
@ -37,6 +38,8 @@
|
|||
let primaryDisplay =
|
||||
$backendUiStore.selectedTable.primaryDisplay == null ||
|
||||
$backendUiStore.selectedTable.primaryDisplay === field.name
|
||||
let confirmDeleteDialog
|
||||
|
||||
$: tableOptions = $backendUiStore.tables.filter(
|
||||
table => table._id !== $backendUiStore.draftTable._id
|
||||
)
|
||||
|
@ -54,6 +57,17 @@
|
|||
onClosed()
|
||||
}
|
||||
|
||||
function deleteColumn() {
|
||||
if (field.name === $backendUiStore.selectedTable.primaryDisplay) {
|
||||
notifier.danger("You cannot delete the display column")
|
||||
} else {
|
||||
backendUiStore.actions.tables.deleteField(field)
|
||||
notifier.success("Column deleted")
|
||||
}
|
||||
onClosed()
|
||||
}
|
||||
|
||||
|
||||
function handleFieldConstraints(event) {
|
||||
const { type, constraints } = fieldDefinitions[
|
||||
event.target.value.toUpperCase()
|
||||
|
@ -75,6 +89,11 @@
|
|||
field.constraints.presence = { allowEmpty: false }
|
||||
}
|
||||
}
|
||||
|
||||
function confirmDelete() {
|
||||
onClosed()
|
||||
confirmDeleteDialog.show()
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="actions">
|
||||
|
@ -147,11 +166,20 @@
|
|||
thin
|
||||
bind:value={field.fieldName} />
|
||||
{/if}
|
||||
<!-- <footer>
|
||||
<Button secondary on:click={onClosed}>Cancel</Button>
|
||||
<footer>
|
||||
{#if originalName}
|
||||
<Button secondary on:click={onClosed}>Cancel</Button>
|
||||
{/if}
|
||||
<Button red on:click={confirmDelete}>Delete Column</Button>
|
||||
<Button primary on:click={saveColumn}>Save Column</Button>
|
||||
</footer> -->
|
||||
</footer>
|
||||
</div>
|
||||
<ConfirmDialog
|
||||
bind:this={confirmDeleteDialog}
|
||||
body={`Are you sure you wish to delete this column? Your data will be deleted and this action cannot be undone.`}
|
||||
okText="Delete Column"
|
||||
onOk={deleteColumn}
|
||||
title="Confirm Delete" />
|
||||
|
||||
<style>
|
||||
.actions {
|
||||
|
|
|
@ -1,201 +0,0 @@
|
|||
<script>
|
||||
import { onMount } from "svelte"
|
||||
import { cssVars } from "./cssVars"
|
||||
import ArrowUp from "./icons/ArrowUp.svelte"
|
||||
import ArrowDown from "./icons/ArrowDown.svelte"
|
||||
import fsort from "fast-sort"
|
||||
import fetchData from "./fetchData.js"
|
||||
import { isEmpty } from "lodash/fp"
|
||||
import AttachmentList from "./attachments/AttachmentList.svelte"
|
||||
|
||||
export let backgroundColor
|
||||
export let color
|
||||
export let stripeColor
|
||||
export let borderColor
|
||||
export let datasource
|
||||
export let _bb
|
||||
|
||||
let data = []
|
||||
let headers = []
|
||||
let sort = {}
|
||||
let sorted = []
|
||||
let schema = {}
|
||||
let store = _bb.store
|
||||
|
||||
$: cssVariables = {
|
||||
backgroundColor,
|
||||
color,
|
||||
stripeColor,
|
||||
borderColor,
|
||||
}
|
||||
|
||||
$: sorted = sort.direction ? fsort(data)[sort.direction](sort.column) : data
|
||||
|
||||
async function fetchTable(tableId) {
|
||||
const FETCH_TABLE_URL = `/api/tables/${tableId}`
|
||||
const response = await _bb.api.get(FETCH_TABLE_URL)
|
||||
const table = await response.json()
|
||||
return table.schema
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
if (!isEmpty(datasource)) {
|
||||
data = await fetchData(datasource, $store)
|
||||
|
||||
// Get schema for datasource
|
||||
// Views with "Calculate" applied provide their own schema.
|
||||
// For everything else, use the tableId property to pull to table schema
|
||||
if (datasource.schema) {
|
||||
schema = datasource.schema
|
||||
headers = Object.keys(schema).filter(shouldDisplayField)
|
||||
} else {
|
||||
schema = await fetchTable(datasource.tableId)
|
||||
headers = Object.keys(schema).filter(shouldDisplayField)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const shouldDisplayField = name => {
|
||||
if (name.startsWith("_")) return false
|
||||
// always 'row'
|
||||
if (name === "type") return false
|
||||
// tables are always tied to a single tableId, this is irrelevant
|
||||
if (name === "tableId") return false
|
||||
return true
|
||||
}
|
||||
|
||||
function sortColumn(column) {
|
||||
if (column === sort.column) {
|
||||
sort = {
|
||||
direction: sort.direction === "asc" ? "desc" : null,
|
||||
column: sort.direction === "asc" ? sort.column : null,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
sort = {
|
||||
column,
|
||||
direction: "asc",
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<table use:cssVars={cssVariables}>
|
||||
<thead>
|
||||
<tr>
|
||||
{#each headers as header}
|
||||
<th on:click={() => sortColumn(header)}>
|
||||
<span>
|
||||
{header}
|
||||
{#if sort.column === header}
|
||||
<svelte:component
|
||||
this={sort.direction === 'asc' ? ArrowDown : ArrowUp}
|
||||
style="height: 1em;" />
|
||||
{/if}
|
||||
</span>
|
||||
</th>
|
||||
{/each}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each sorted as row (row._id)}
|
||||
<tr>
|
||||
{#each headers as header}
|
||||
{#if schema[header] !== undefined}
|
||||
<!-- Rudimentary solution for attachments on array given this entire table will be replaced by AG Grid -->
|
||||
{#if schema[header] && schema[header].type === 'attachment'}
|
||||
<AttachmentList files={row[header]} />
|
||||
{:else if schema[header] && schema[header].type === 'link'}
|
||||
<td>{row[header] ? row[header].length : 0} related row(s)</td>
|
||||
{:else}
|
||||
<td>{row[header] == null ? '' : row[header]}</td>
|
||||
{/if}
|
||||
{/if}
|
||||
{/each}
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<style>
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
overflow: scroll; /* Scrollbar are always visible */
|
||||
overflow: auto; /* Scrollbar is displayed as it's needed */
|
||||
}
|
||||
|
||||
/* Zebra striping */
|
||||
tr:nth-of-type(odd) {
|
||||
background: var(--stripeColor);
|
||||
}
|
||||
|
||||
th {
|
||||
background-color: var(--backgroundColor);
|
||||
color: var(--color);
|
||||
font-weight: bold;
|
||||
text-transform: capitalize;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
th span {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
td,
|
||||
th {
|
||||
padding: 16px;
|
||||
border: 1px solid var(--borderColor);
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 760px),
|
||||
(min-device-width: 768px) and (max-device-width: 1024px) {
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Force table to not be like tables anymore */
|
||||
table,
|
||||
thead,
|
||||
tbody,
|
||||
th,
|
||||
td,
|
||||
tr {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Hide table headers (but not display: none;, for accessibility) */
|
||||
thead tr {
|
||||
position: absolute;
|
||||
top: -9999px;
|
||||
left: -9999px;
|
||||
}
|
||||
|
||||
tr {
|
||||
border: 1px solid var(--borderColor);
|
||||
}
|
||||
|
||||
td {
|
||||
/* Behave like a "row" */
|
||||
border: none;
|
||||
border-bottom: 1px solid #eee;
|
||||
position: relative;
|
||||
padding-left: 10%;
|
||||
}
|
||||
|
||||
td:before {
|
||||
/* Now like a table header */
|
||||
position: absolute;
|
||||
/* Top/left values mimic padding */
|
||||
top: 6px;
|
||||
left: 6px;
|
||||
width: 45%;
|
||||
padding-right: 10px;
|
||||
white-space: nowrap;
|
||||
/* Label the data */
|
||||
content: attr(data-column);
|
||||
}
|
||||
}
|
||||
</style>
|
Loading…
Reference in New Issue