Merge pull request #11049 from Budibase/grid-block-notifications

Grid fixes
This commit is contained in:
Andrew Kingston 2023-06-30 11:30:34 +01:00 committed by GitHub
commit a1a8e74f43
12 changed files with 89 additions and 21 deletions

View File

@ -71,6 +71,7 @@
timeOnly,
enableTime,
time24hr,
disabled,
}
const handleChange = event => {

View File

@ -16,7 +16,7 @@
export let columns = null
const component = getContext("component")
const { styleable, API, builderStore } = getContext("sdk")
const { styleable, API, builderStore, notificationStore } = getContext("sdk")
$: columnWhitelist = columns?.map(col => col.name)
$: schemaOverrides = getSchemaOverrides(columns)
@ -52,6 +52,8 @@
showControls={false}
allowExpandRows={false}
allowSchemaChanges={false}
notifySuccess={notificationStore.actions.success}
notifyError={notificationStore.actions.error}
/>
</div>

View File

@ -1,7 +1,7 @@
<script>
import { onMount } from "svelte"
import { getContext } from "svelte"
import { Dropzone, notifications } from "@budibase/bbui"
import { Dropzone } from "@budibase/bbui"
export let value
export let focused = false
@ -11,7 +11,7 @@
export let invertX = false
export let invertY = false
const { API } = getContext("grid")
const { API, notifications } = getContext("grid")
const imageExtensions = ["png", "tiff", "gif", "raw", "jpg", "jpeg"]
let isOpen = false
@ -40,7 +40,7 @@
}
const handleFileTooLarge = fileSizeLimit => {
notifications.error(
$notifications.error(
`Files cannot exceed ${
fileSizeLimit / 1000000
}MB. Please try again with smaller files.`
@ -55,7 +55,7 @@
try {
return await API.uploadBuilderAttachment(data)
} catch (error) {
notifications.error("Failed to upload attachment")
$notifications.error("Failed to upload attachment")
return []
}
}

View File

@ -1,8 +1,8 @@
<script>
import { Modal, ModalContent, notifications } from "@budibase/bbui"
import { Modal, ModalContent } from "@budibase/bbui"
import { getContext, onMount } from "svelte"
const { selectedRows, rows, subscribe } = getContext("grid")
const { selectedRows, rows, subscribe, notifications } = getContext("grid")
let modal
@ -15,7 +15,7 @@
const performDeletion = async () => {
const count = rowsToDelete.length
await rows.actions.deleteRows(rowsToDelete)
notifications.success(`Deleted ${count} row${count === 1 ? "" : "s"}`)
$notifications.success(`Deleted ${count} row${count === 1 ? "" : "s"}`)
}
onMount(() => subscribe("request-bulk-delete", () => modal?.show()))

View File

@ -44,6 +44,8 @@
export let initialSortColumn = null
export let initialSortOrder = null
export let initialRowHeight = null
export let notifySuccess = null
export let notifyError = null
// Unique identifier for DOM nodes inside this instance
const rand = Math.random()
@ -89,6 +91,8 @@
initialSortColumn,
initialSortOrder,
initialRowHeight,
notifySuccess,
notifyError,
})
// Set context for children to consume

View File

@ -78,6 +78,11 @@
}
const startAdding = async () => {
// Attempt to submit if already adding a row
if (visible && !isAdding) {
await addRow()
return
}
if (visible || !firstColumn) {
return
}

View File

@ -1,11 +1,5 @@
<script>
import {
clickOutside,
Menu,
MenuItem,
Helpers,
notifications,
} from "@budibase/bbui"
import { clickOutside, Menu, MenuItem, Helpers } from "@budibase/bbui"
import { getContext } from "svelte"
import { NewRowID } from "../lib/constants"
@ -22,6 +16,7 @@
dispatch,
focusedCellAPI,
focusedRowId,
notifications,
} = getContext("grid")
$: style = makeStyle($menu)
@ -34,7 +29,7 @@
const deleteRow = () => {
rows.actions.deleteRows([$focusedRow])
menu.actions.close()
notifications.success("Deleted 1 row")
$notifications.success("Deleted 1 row")
}
const duplicate = async () => {
@ -48,7 +43,7 @@
const copyToClipboard = async value => {
await Helpers.copyToClipboard(value)
notifications.success("Copied to clipboard")
$notifications.success("Copied to clipboard")
}
</script>

View File

@ -35,10 +35,20 @@ export const createStores = () => {
[]
)
// Checks if we have a certain column by name
const hasColumn = column => {
const $columns = get(columns)
const $sticky = get(stickyColumn)
return $columns.some(col => col.name === column) || $sticky?.name === column
}
return {
columns: {
...columns,
subscribe: enrichedColumns.subscribe,
actions: {
hasColumn,
},
},
stickyColumn,
visibleColumns,
@ -121,6 +131,7 @@ export const deriveStores = context => {
columns: {
...columns,
actions: {
...columns.actions,
saveChanges,
saveTable,
changePrimaryDisplay,

View File

@ -13,6 +13,8 @@ export const createStores = context => {
const initialRowHeight = getProp("initialRowHeight")
const schemaOverrides = getProp("schemaOverrides")
const columnWhitelist = getProp("columnWhitelist")
const notifySuccess = getProp("notifySuccess")
const notifyError = getProp("notifyError")
return {
config,
@ -23,5 +25,7 @@ export const createStores = context => {
initialRowHeight,
schemaOverrides,
columnWhitelist,
notifySuccess,
notifyError,
}
}

View File

@ -14,9 +14,11 @@ import * as Clipboard from "./clipboard"
import * as Config from "./config"
import * as Sort from "./sort"
import * as Filter from "./filter"
import * as Notifications from "./notifications"
const DependencyOrderedStores = [
Config,
Notifications,
Sort,
Filter,
Bounds,

View File

@ -0,0 +1,23 @@
import { notifications as BBUINotifications } from "@budibase/bbui"
import { derived } from "svelte/store"
export const createStores = context => {
const { notifySuccess, notifyError } = context
// Normally we would not derive a store in "createStores" as it should be
// dependency free, but in this case it's safe as we only depend on grid props
// which are guaranteed to be first in the dependency chain
const notifications = derived(
[notifySuccess, notifyError],
([$notifySuccess, $notifyError]) => {
return {
success: $notifySuccess || BBUINotifications.success,
error: $notifyError || BBUINotifications.error,
}
}
)
return {
notifications,
}
}

View File

@ -1,6 +1,5 @@
import { writable, derived, get } from "svelte/store"
import { fetchData } from "../../../fetch/fetchData"
import { notifications } from "@budibase/bbui"
import { NewRowID, RowPageSize } from "../lib/constants"
import { tick } from "svelte"
@ -71,6 +70,7 @@ export const deriveStores = context => {
previousFocusedRowId,
hasNextPage,
error,
notifications,
} = context
const instanceLoaded = writable(false)
const fetch = writable(null)
@ -203,10 +203,23 @@ export const deriveStores = context => {
// state, storing error messages against relevant cells
const handleValidationError = (rowId, error) => {
if (error?.json?.validationErrors) {
// Normal validation error
// Normal validation errors
const keys = Object.keys(error.json.validationErrors)
const $columns = get(columns)
// Filter out missing columns from columns that we have
let erroredColumns = []
let missingColumns = []
for (let column of keys) {
if (columns.actions.hasColumn(column)) {
erroredColumns.push(column)
} else {
missingColumns.push(column)
}
}
// Process errors for columns that we have
for (let column of erroredColumns) {
validation.actions.setError(
`${rowId}-${column}`,
`${column} ${error.json.validationErrors[column]}`
@ -221,8 +234,16 @@ export const deriveStores = context => {
})
}
}
// Notify about missing columns
for (let column of missingColumns) {
get(notifications).error(`${column} is required but is missing`)
}
// Focus the first cell with an error
focusedCellId.set(`${rowId}-${keys[0]}`)
if (erroredColumns.length) {
focusedCellId.set(`${rowId}-${erroredColumns[0]}`)
}
} else {
// Some other error - just update the current cell
validation.actions.setError(get(focusedCellId), error?.message || "Error")
@ -250,7 +271,7 @@ export const deriveStores = context => {
}
// Refresh row to ensure data is in the correct format
notifications.success("Row created successfully")
get(notifications).success("Row created successfully")
return newRow
} catch (error) {
if (bubble) {