more ag grid styling

This commit is contained in:
Martin McKeaveney 2020-10-23 17:38:10 +01:00
parent fdc944741c
commit 4714416e24
5 changed files with 67 additions and 252 deletions

View File

@ -2,19 +2,9 @@
import { goto, params } from "@sveltech/routify" import { goto, params } from "@sveltech/routify"
import { onMount } from "svelte" import { onMount } from "svelte"
import { fade } from "svelte/transition" import { fade } from "svelte/transition"
import fsort from "fast-sort"
import getOr from "lodash/fp/getOr"
import { store, backendUiStore } from "builderStore" import { store, backendUiStore } from "builderStore"
import api from "builderStore/api" import api from "builderStore/api"
import { Button, Icon } from "@budibase/bbui" 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" import Spinner from "components/common/Spinner.svelte"
// New // New
@ -28,7 +18,6 @@
export let allowEditing = false export let allowEditing = false
export let loading = false export let loading = false
// New stuff
export let theme = "alpine" export let theme = "alpine"
let columnDefs = [] let columnDefs = []
@ -93,21 +82,6 @@
// `/${$params.application}/data/table/${tableId}/relationship/${row._id}/${fieldName}` // `/${$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> </script>
<section> <section>
@ -159,4 +133,10 @@
margin-right: var(--spacing-m); margin-right: var(--spacing-m);
margin-bottom: var(--spacing-xl); margin-bottom: var(--spacing-xl);
} }
:global(.ag-header-cell-text) {
font-family: Inter;
font-weight: 600;
color: var(--ink);
}
</style> </style>

View File

@ -40,19 +40,6 @@
modal.show() 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(() => { onMount(() => {
column.addEventListener("sortChanged", () => { column.addEventListener("sortChanged", () => {
sortDirection = column.getSort() sortDirection = column.getSort()
@ -64,15 +51,15 @@
<div> <div>
<span>{field.name}</span> <span>{field.name}</span>
{#if enableSorting && sortDirection} {#if enableSorting && sortDirection}
<i class={SORT_ICON_MAP[sortDirection]} /> <i class={`${SORT_ICON_MAP[sortDirection]} sort-icon`} />
{/if} {/if}
</div> </div>
<Modal bind:this={modal}> <Modal bind:this={modal}>
<ModalContent <ModalContent
title={`Edit Column: ${field.name}`} showCancelButton={false}
confirmText={'Save Column'} showConfirmButton={false}
onConfirm={saveColumn}> title={`Edit Column: ${field.name}`}>
<CreateEditColumnPopover {field} /> <CreateEditColumnPopover onClosed={modal.hide} {field} />
</ModalContent> </ModalContent>
</Modal> </Modal>
<div> <div>
@ -88,10 +75,31 @@
<style> <style>
header { header {
font-family: Inter; font-family: Inter;
font-weight: 600;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
height: 100%; height: 100%;
width: 100%; width: 100%;
align-items: center; 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> </style>

View File

@ -20,9 +20,9 @@
</div> </div>
<Modal bind:this={modal}> <Modal bind:this={modal}>
<ModalContent <ModalContent
title={'Create Column'} showCancelButton={false}
confirmText={'Save Column'} showConfirmButton={false}
onConfirm={console.log}> title={'Create Column'}>
<CreateEditColumnPopover /> <CreateEditColumnPopover onClosed={modal.hide} />
</ModalContent> </ModalContent>
</Modal> </Modal>

View File

@ -20,6 +20,7 @@
import ActionButton from "components/common/ActionButton.svelte" import ActionButton from "components/common/ActionButton.svelte"
import DatePicker from "components/common/DatePicker.svelte" import DatePicker from "components/common/DatePicker.svelte"
import LinkedRowSelector from "components/common/LinkedRowSelector.svelte" import LinkedRowSelector from "components/common/LinkedRowSelector.svelte"
import ConfirmDialog from "components/common/ConfirmDialog.svelte"
import * as api from "../api" import * as api from "../api"
let fieldDefinitions = cloneDeep(FIELDS) let fieldDefinitions = cloneDeep(FIELDS)
@ -37,6 +38,8 @@
let primaryDisplay = let primaryDisplay =
$backendUiStore.selectedTable.primaryDisplay == null || $backendUiStore.selectedTable.primaryDisplay == null ||
$backendUiStore.selectedTable.primaryDisplay === field.name $backendUiStore.selectedTable.primaryDisplay === field.name
let confirmDeleteDialog
$: tableOptions = $backendUiStore.tables.filter( $: tableOptions = $backendUiStore.tables.filter(
table => table._id !== $backendUiStore.draftTable._id table => table._id !== $backendUiStore.draftTable._id
) )
@ -54,6 +57,17 @@
onClosed() 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) { function handleFieldConstraints(event) {
const { type, constraints } = fieldDefinitions[ const { type, constraints } = fieldDefinitions[
event.target.value.toUpperCase() event.target.value.toUpperCase()
@ -75,6 +89,11 @@
field.constraints.presence = { allowEmpty: false } field.constraints.presence = { allowEmpty: false }
} }
} }
function confirmDelete() {
onClosed()
confirmDeleteDialog.show()
}
</script> </script>
<div class="actions"> <div class="actions">
@ -147,11 +166,20 @@
thin thin
bind:value={field.fieldName} /> bind:value={field.fieldName} />
{/if} {/if}
<!-- <footer> <footer>
{#if originalName}
<Button secondary on:click={onClosed}>Cancel</Button> <Button secondary on:click={onClosed}>Cancel</Button>
{/if}
<Button red on:click={confirmDelete}>Delete Column</Button>
<Button primary on:click={saveColumn}>Save Column</Button> <Button primary on:click={saveColumn}>Save Column</Button>
</footer> --> </footer>
</div> </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> <style>
.actions { .actions {

View File

@ -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>