diff --git a/package.json b/package.json index b2f572d202..7429805b11 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "clean": "lerna clean", "kill-port": "kill-port 4001", "dev": "yarn run kill-port && lerna link && lerna run --parallel dev:builder --concurrency 1", - "dev:noserver": "lerna link && lerna run --parallel dev:builder --concurrency 1 --ignore @budibase/server", + "dev:noserver": "lerna link && lerna run --parallel dev:builder --concurrency 1 --ignore @budibase/server", "test": "lerna run test", "lint": "eslint packages", "lint:fix": "eslint --fix packages", @@ -38,5 +38,8 @@ "test:e2e:ci": "lerna run cy:ci", "build:docker": "cd hosting/scripts/linux/ && ./release-to-docker-hub.sh && cd -", "build:docker:staging": "cd hosting/scripts/linux/ && ./release-to-docker-hub.sh staging && cd -" + }, + "dependencies": { + "@spectrum-css/toast": "^3.0.1" } } diff --git a/packages/bbui/src/Notification/NotificationDisplay.svelte b/packages/bbui/src/Notification/NotificationDisplay.svelte new file mode 100644 index 0000000000..161d31ec6c --- /dev/null +++ b/packages/bbui/src/Notification/NotificationDisplay.svelte @@ -0,0 +1,44 @@ + + + +
+ {#each $notifications as {type, icon, message, id} (id)} +
+ {#if icon} + + {/if} +
+
{message}
+
+
+ {/each} +
+
+ + \ No newline at end of file diff --git a/packages/bbui/src/Stores/Notifications.svench.svx b/packages/bbui/src/Stores/Notifications.svench.svx index 2c54a91c8c..c776ee2422 100644 --- a/packages/bbui/src/Stores/Notifications.svench.svx +++ b/packages/bbui/src/Stores/Notifications.svench.svx @@ -19,7 +19,7 @@ This custom can be used to display toast messages. It has 5 different methods: ` - + diff --git a/packages/bbui/src/Stores/notifications.js b/packages/bbui/src/Stores/notifications.js index 520e5c97b2..761d8531ec 100644 --- a/packages/bbui/src/Stores/notifications.js +++ b/packages/bbui/src/Stores/notifications.js @@ -1,40 +1,51 @@ -import { writable, derived } from "svelte/store" +import { writable } from "svelte/store" const NOTIFICATION_TIMEOUT = 3000 -const createNotificationStore = () => { - const _notifications = writable([]) - - const send = (message, type = "default") => { - _notifications.update(state => { - return [...state, { id: id(), type, message }] - }) - } - - const notifications = derived(_notifications, ($_notifications, set) => { - set($_notifications) - if ($_notifications.length > 0) { - const timeout = setTimeout(() => { - _notifications.update(state => { - state.shift() - return state - }) - set($_notifications) - }, NOTIFICATION_TIMEOUT) - return () => { - clearTimeout(timeout) - } +export const createNotificationStore = () => { + const timeoutIds = new Set() + const _notifications = writable([], () => { + return () => { + // clear all the timers + timeoutIds.forEach(timeoutId => { + clearTimeout(timeoutId) + }) + _notifications.set([]) } }) - const { subscribe } = notifications + let block = false + + const blockNotifications = (timeout = 1000) => { + block = true + setTimeout(() => (block = false), timeout) + } + + const send = (message, type = "default", icon = "") => { + if (block) { + return + } + let _id = id() + _notifications.update(state => { + return [...state, { id: _id, type, message, icon }] + }) + const timeoutId = setTimeout(() => { + _notifications.update(state => { + return state.filter(({ id }) => id !== _id) + }) + }, NOTIFICATION_TIMEOUT) + timeoutIds.add(timeoutId) + } + + const { subscribe } = _notifications return { subscribe, send, - danger: msg => send(msg, "danger"), - warning: msg => send(msg, "warning"), - info: msg => send(msg, "info"), - success: msg => send(msg, "success"), + info: msg => send(msg, "info", "Info"), + error: msg => send(msg, "error", "Alert"), + warning: msg => send(msg, "warning", "Alert"), + success: msg => send(msg, "success", "CheckmarkCircle"), + blockNotifications, } } diff --git a/packages/bbui/src/index.js b/packages/bbui/src/index.js index 1a156697c9..6e8db956b0 100644 --- a/packages/bbui/src/index.js +++ b/packages/bbui/src/index.js @@ -25,6 +25,7 @@ export { default as Label } from "./Styleguide/Label.svelte" export { default as Close } from "./Button/Close.svelte" export { default as Modal } from "./Modal/Modal.svelte" export { default as ModalContent } from "./Modal/ModalContent.svelte" +export { default as NotificationDisplay } from "./Notification/NotificationDisplay.svelte" export { default as Spacer } from "./Spacer/Spacer.svelte" export { default as DatePicker } from "./DatePicker/DatePicker.svelte" export { default as Multiselect } from "./Form/Multiselect.svelte" @@ -37,4 +38,4 @@ export { default as positionDropdown } from "./Actions/position_dropdown" export { default as clickOutside } from "./Actions/click_outside" // Stores -export { notifications } from "./Stores/notifications" +export { notifications, createNotificationStore } from "./Stores/notifications" diff --git a/packages/builder/src/App.svelte b/packages/builder/src/App.svelte index 5c87ebbc7d..507eaaa5de 100644 --- a/packages/builder/src/App.svelte +++ b/packages/builder/src/App.svelte @@ -3,8 +3,8 @@ import { Router } from "@roxi/routify" import { routes } from "../.routify/routes" import { initialise } from "builderStore" - import NotificationDisplay from "components/common/Notification/NotificationDisplay.svelte" - + import { NotificationDisplay } from "@budibase/bbui" + onMount(async () => { await initialise() }) diff --git a/packages/builder/src/components/automation/AutomationPanel/CreateAutomationModal.svelte b/packages/builder/src/components/automation/AutomationPanel/CreateAutomationModal.svelte index ebc0d5955e..9768915a54 100644 --- a/packages/builder/src/components/automation/AutomationPanel/CreateAutomationModal.svelte +++ b/packages/builder/src/components/automation/AutomationPanel/CreateAutomationModal.svelte @@ -2,7 +2,7 @@ import { goto } from "@roxi/routify" import { database } from "stores/backend" import { automationStore } from "builderStore" - import { notifier } from "builderStore/store/notifications" + import { notifications } from "@budibase/bbui" import { Input, ModalContent } from "@budibase/bbui" import analytics from "analytics" @@ -16,7 +16,7 @@ name, instanceId, }) - notifier.success(`Automation ${name} created.`) + notifications.success(`Automation ${name} created.`) $goto(`./${$automationStore.selectedAutomation.automation._id}`) analytics.captureEvent("Automation Created", { name }) } diff --git a/packages/builder/src/components/automation/AutomationPanel/EditAutomationPopover.svelte b/packages/builder/src/components/automation/AutomationPanel/EditAutomationPopover.svelte index 0924fa3a44..e41fc59e3b 100644 --- a/packages/builder/src/components/automation/AutomationPanel/EditAutomationPopover.svelte +++ b/packages/builder/src/components/automation/AutomationPanel/EditAutomationPopover.svelte @@ -2,7 +2,7 @@ import { goto } from "@roxi/routify" import { automationStore } from "builderStore" import { database } from "stores/backend" - import { notifier } from "builderStore/store/notifications" + import { notifications } from "@budibase/bbui" import { DropdownMenu } from "@budibase/bbui" import { DropdownContainer, DropdownItem } from "components/common/Dropdowns" import ConfirmDialog from "components/common/ConfirmDialog.svelte" @@ -24,7 +24,7 @@ instanceId, automation, }) - notifier.success("Automation deleted.") + notifications.success("Automation deleted.") $goto("../automate") } diff --git a/packages/builder/src/components/automation/SetupPanel/SetupPanel.svelte b/packages/builder/src/components/automation/SetupPanel/SetupPanel.svelte index ed4ea54964..ad3eccf9c3 100644 --- a/packages/builder/src/components/automation/SetupPanel/SetupPanel.svelte +++ b/packages/builder/src/components/automation/SetupPanel/SetupPanel.svelte @@ -1,7 +1,7 @@ diff --git a/packages/builder/src/components/automation/Shared/WebhookDisplay.svelte b/packages/builder/src/components/automation/Shared/WebhookDisplay.svelte index dc908a9571..5a2984f961 100644 --- a/packages/builder/src/components/automation/Shared/WebhookDisplay.svelte +++ b/packages/builder/src/components/automation/Shared/WebhookDisplay.svelte @@ -1,5 +1,5 @@ diff --git a/packages/builder/src/components/backend/DataTable/Table.svelte b/packages/builder/src/components/backend/DataTable/Table.svelte index d1bee34a2a..8f460e34eb 100644 --- a/packages/builder/src/components/backend/DataTable/Table.svelte +++ b/packages/builder/src/components/backend/DataTable/Table.svelte @@ -4,7 +4,7 @@ import AgGrid from "@budibase/svelte-ag-grid" import api from "builderStore/api" - import { notifier } from "builderStore/store/notifications" + import { notifications } from "@budibase/bbui" import Spinner from "components/common/Spinner.svelte" import DeleteRowsButton from "./buttons/DeleteRowsButton.svelte" import { @@ -142,7 +142,7 @@ type: "delete", }) data = data.filter(row => !selectedRows.includes(row)) - notifier.success(`Successfully deleted ${selectedRows.length} rows`) + notifications.success(`Successfully deleted ${selectedRows.length} rows`) selectedRows = [] } diff --git a/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte b/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte index 19b8d15911..392909d3ef 100644 --- a/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte +++ b/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte @@ -17,7 +17,7 @@ RelationshipTypes, } from "constants/backend" import { getAutoColumnInformation, buildAutoColumn } from "builderStore/utils" - import { notifier } from "builderStore/store/notifications" + import { notifications } from "@budibase/bbui" import ValuesList from "components/common/ValuesList.svelte" import DatePicker from "components/common/DatePicker.svelte" import ConfirmDialog from "components/common/ConfirmDialog.svelte" @@ -82,10 +82,10 @@ function deleteColumn() { if (field.name === $tables.selected.primaryDisplay) { - notifier.danger("You cannot delete the display column") + notifications.error("You cannot delete the display column") } else { tables.deleteField(field) - notifier.success(`Column ${field.name} deleted.`) + notifications.success(`Column ${field.name} deleted.`) onClosed() } } diff --git a/packages/builder/src/components/backend/DataTable/modals/CreateEditRow.svelte b/packages/builder/src/components/backend/DataTable/modals/CreateEditRow.svelte index b50c12bc1f..98b858836f 100644 --- a/packages/builder/src/components/backend/DataTable/modals/CreateEditRow.svelte +++ b/packages/builder/src/components/backend/DataTable/modals/CreateEditRow.svelte @@ -1,6 +1,6 @@ diff --git a/packages/builder/src/components/backend/DataTable/modals/CreateEditUser.svelte b/packages/builder/src/components/backend/DataTable/modals/CreateEditUser.svelte index 56935a9c7b..1d3e771309 100644 --- a/packages/builder/src/components/backend/DataTable/modals/CreateEditUser.svelte +++ b/packages/builder/src/components/backend/DataTable/modals/CreateEditUser.svelte @@ -1,7 +1,7 @@ diff --git a/packages/builder/src/components/backend/DataTable/modals/DeleteRow.svelte b/packages/builder/src/components/backend/DataTable/modals/DeleteRow.svelte index 6620b57f61..99ba1022a1 100644 --- a/packages/builder/src/components/backend/DataTable/modals/DeleteRow.svelte +++ b/packages/builder/src/components/backend/DataTable/modals/DeleteRow.svelte @@ -1,7 +1,7 @@ diff --git a/packages/builder/src/components/backend/DataTable/modals/EditRoles.svelte b/packages/builder/src/components/backend/DataTable/modals/EditRoles.svelte index 0984c94e0c..7ee70efe21 100644 --- a/packages/builder/src/components/backend/DataTable/modals/EditRoles.svelte +++ b/packages/builder/src/components/backend/DataTable/modals/EditRoles.svelte @@ -2,7 +2,7 @@ import { ModalContent, Select, Input, Button } from "@budibase/bbui" import { onMount } from "svelte" import api from "builderStore/api" - import { notifier } from "builderStore/store/notifications" + import { notifications } from "@budibase/bbui" import ErrorsBox from "components/common/ErrorsBox.svelte" import { roles } from "stores/backend" @@ -61,9 +61,9 @@ // Save/create the role const response = await roles.save(selectedRole) if (response.status === 200) { - notifier.success("Role saved successfully.") + notifications.success("Role saved successfully.") } else { - notifier.danger("Error saving role.") + notifications.error("Error saving role.") return false } } @@ -73,9 +73,9 @@ const response = await roles.delete(selectedRole) if (response.status === 200) { changeRole() - notifier.success("Role deleted successfully.") + notifications.success("Role deleted successfully.") } else { - notifier.danger("Error deleting role.") + notifications.error("Error deleting role.") } } diff --git a/packages/builder/src/components/backend/DataTable/popovers/CalculatePopover.svelte b/packages/builder/src/components/backend/DataTable/popovers/CalculatePopover.svelte index cbfe4a29da..a28cc523c5 100644 --- a/packages/builder/src/components/backend/DataTable/popovers/CalculatePopover.svelte +++ b/packages/builder/src/components/backend/DataTable/popovers/CalculatePopover.svelte @@ -2,7 +2,7 @@ import { Button, Select } from "@budibase/bbui" import { tables, views } from "stores/backend" - import { notifier } from "builderStore/store/notifications" + import { notifications } from "@budibase/bbui" import analytics from "analytics" const CALCULATIONS = [ @@ -36,7 +36,7 @@ function saveView() { views.save(view) - notifier.success(`View ${view.name} saved.`) + notifications.success(`View ${view.name} saved.`) onClosed() analytics.captureEvent("Added View Calculate", { field: view.field }) } diff --git a/packages/builder/src/components/backend/DataTable/popovers/CreateViewPopover.svelte b/packages/builder/src/components/backend/DataTable/popovers/CreateViewPopover.svelte index 93ca7bb211..da36ab6635 100644 --- a/packages/builder/src/components/backend/DataTable/popovers/CreateViewPopover.svelte +++ b/packages/builder/src/components/backend/DataTable/popovers/CreateViewPopover.svelte @@ -3,7 +3,7 @@ import { goto } from "@roxi/routify" import { views as viewsStore } from "stores/backend" import { tables } from "stores/backend" - import { notifier } from "builderStore/store/notifications" + import { notifications } from "@budibase/bbui" import analytics from "analytics" export let onClosed @@ -15,7 +15,7 @@ function saveView() { if (views.includes(name)) { - notifier.danger(`View exists with name ${name}.`) + notifications.error(`View exists with name ${name}.`) return } viewsStore.save({ @@ -23,7 +23,7 @@ tableId: $tables.selected._id, field, }) - notifier.success(`View ${name} created`) + notifications.success(`View ${name} created`) onClosed() analytics.captureEvent("View Created", { name }) $goto(`../../view/${name}`) diff --git a/packages/builder/src/components/backend/DataTable/popovers/FilterPopover.svelte b/packages/builder/src/components/backend/DataTable/popovers/FilterPopover.svelte index d32a9866b6..825644b908 100644 --- a/packages/builder/src/components/backend/DataTable/popovers/FilterPopover.svelte +++ b/packages/builder/src/components/backend/DataTable/popovers/FilterPopover.svelte @@ -1,7 +1,7 @@ diff --git a/packages/builder/src/components/backend/DataTable/popovers/ManageAccessPopover.svelte b/packages/builder/src/components/backend/DataTable/popovers/ManageAccessPopover.svelte index a3fc4fc355..bcd3fa1b15 100644 --- a/packages/builder/src/components/backend/DataTable/popovers/ManageAccessPopover.svelte +++ b/packages/builder/src/components/backend/DataTable/popovers/ManageAccessPopover.svelte @@ -1,6 +1,6 @@ diff --git a/packages/builder/src/components/backend/TableNavigator/TableDataImport.svelte b/packages/builder/src/components/backend/TableNavigator/TableDataImport.svelte index 293f52b487..397113dab2 100644 --- a/packages/builder/src/components/backend/TableNavigator/TableDataImport.svelte +++ b/packages/builder/src/components/backend/TableNavigator/TableDataImport.svelte @@ -1,6 +1,6 @@ diff --git a/packages/builder/src/components/common/Dropzone.svelte b/packages/builder/src/components/common/Dropzone.svelte index 0b98f2b256..5d4d3f0124 100644 --- a/packages/builder/src/components/common/Dropzone.svelte +++ b/packages/builder/src/components/common/Dropzone.svelte @@ -1,5 +1,5 @@ - -
- {#each $notificationStore.notifications as notification (notification.id)} -
-
{notification.message}
- {#if notification.icon}{/if} -
- {/each} -
- - diff --git a/packages/builder/src/components/deploy/DeploymentHistory.svelte b/packages/builder/src/components/deploy/DeploymentHistory.svelte index 0933b1a676..d84f6b7f49 100644 --- a/packages/builder/src/components/deploy/DeploymentHistory.svelte +++ b/packages/builder/src/components/deploy/DeploymentHistory.svelte @@ -4,7 +4,7 @@ import { slide } from "svelte/transition" import { Heading, Body, Button, Modal, ModalContent } from "@budibase/bbui" import api from "builderStore/api" - import { notifier } from "builderStore/store/notifications" + import { notifications } from "@budibase/bbui" import CreateWebhookDeploymentModal from "./CreateWebhookDeploymentModal.svelte" import { store, hostingStore } from "builderStore" @@ -75,7 +75,7 @@ } catch (err) { console.error(err) clearInterval(poll) - notifier.danger("Error fetching deployment history. Please try again.") + notifications.error("Error fetching deployment history. Please try again.") } } diff --git a/packages/builder/src/components/design/NavigationPanel/ComponentNavigationTree/LayoutDropdownMenu.svelte b/packages/builder/src/components/design/NavigationPanel/ComponentNavigationTree/LayoutDropdownMenu.svelte index 602e46b35b..dfd24deb4a 100644 --- a/packages/builder/src/components/design/NavigationPanel/ComponentNavigationTree/LayoutDropdownMenu.svelte +++ b/packages/builder/src/components/design/NavigationPanel/ComponentNavigationTree/LayoutDropdownMenu.svelte @@ -1,7 +1,7 @@ diff --git a/packages/builder/src/components/design/NavigationPanel/ComponentNavigationTree/ScreenDropdownMenu.svelte b/packages/builder/src/components/design/NavigationPanel/ComponentNavigationTree/ScreenDropdownMenu.svelte index 54b1e96799..54096d1faf 100644 --- a/packages/builder/src/components/design/NavigationPanel/ComponentNavigationTree/ScreenDropdownMenu.svelte +++ b/packages/builder/src/components/design/NavigationPanel/ComponentNavigationTree/ScreenDropdownMenu.svelte @@ -1,7 +1,7 @@ diff --git a/packages/builder/src/components/design/NavigationPanel/NewLayoutModal.svelte b/packages/builder/src/components/design/NavigationPanel/NewLayoutModal.svelte index 2ef467c755..14c6c5ab31 100644 --- a/packages/builder/src/components/design/NavigationPanel/NewLayoutModal.svelte +++ b/packages/builder/src/components/design/NavigationPanel/NewLayoutModal.svelte @@ -1,6 +1,6 @@ diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/DataSourceSelect.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/DataSourceSelect.svelte index 7a4ab4c754..85ccf000b9 100644 --- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/DataSourceSelect.svelte +++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/DataSourceSelect.svelte @@ -15,7 +15,7 @@ queries as queriesStore, } from "stores/backend" import { datasources, integrations } from "stores/backend" - import { notifier } from "builderStore/store/notifications" + import { notifications } from "@budibase/bbui" import ParameterBuilder from "components/integration/QueryParameterBuilder.svelte" import IntegrationQueryEditor from "components/integration/index.svelte" @@ -108,7 +108,7 @@ blue thin on:click={() => { - notifier.success('Query parameters saved.') + notifications.success('Query parameters saved.') handleSelected(value) drawer.hide() }}> diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/EventPropertyControl.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/EventPropertyControl.svelte index 9a239a4e1b..8c0ab62807 100644 --- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/EventPropertyControl.svelte +++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/EventPropertyControl.svelte @@ -1,7 +1,7 @@ diff --git a/packages/builder/src/components/settings/tabs/APIKeys.svelte b/packages/builder/src/components/settings/tabs/APIKeys.svelte index 45dedf0041..729f464fd6 100644 --- a/packages/builder/src/components/settings/tabs/APIKeys.svelte +++ b/packages/builder/src/components/settings/tabs/APIKeys.svelte @@ -1,7 +1,7 @@ diff --git a/yarn.lock b/yarn.lock index f27c37ebf1..5f0162a7e0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -824,6 +824,11 @@ estree-walker "^1.0.1" micromatch "^4.0.2" +"@spectrum-css/toast@^3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@spectrum-css/toast/-/toast-3.0.1.tgz#36f62ea05302761e59b9d53e05f6c04423861796" + integrity sha512-jov++S358BrN2tmMfaoYk1N6u9HojgeuQk61keXrK2m3VE5/n94x7Lg3kIPeSWO0odyDfBlMqT9jacbRey3QTg== + "@types/estree@0.0.39": version "0.0.39" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f"