diff --git a/packages/builder/src/components/backend/DataTable/buttons/grid/GridRowActionsButton.svelte b/packages/builder/src/components/backend/DataTable/buttons/grid/GridRowActionsButton.svelte
index 9adbca7603..5bd2b757e4 100644
--- a/packages/builder/src/components/backend/DataTable/buttons/grid/GridRowActionsButton.svelte
+++ b/packages/builder/src/components/backend/DataTable/buttons/grid/GridRowActionsButton.svelte
@@ -9,21 +9,20 @@
} from "@budibase/bbui"
import DetailPopover from "components/common/DetailPopover.svelte"
import { getContext } from "svelte"
- import { appStore, automationStore } from "stores/builder"
+ import { appStore, rowActions } from "stores/builder"
import { API } from "api"
import { goto, url } from "@roxi/routify"
import { derived } from "svelte/store"
- import { getSequentialName } from "helpers/duplicate"
const { datasource } = getContext("grid")
- let rowActions = []
-
$: ds = $datasource
$: tableId = ds?.tableId
+ $: viewId = ds?.id
$: isView = ds?.type === "viewV2"
- $: fetchRowActions(ds)
- $: actionCount = rowActions.filter(action => !isView || action.enabled).length
+ $: tableRowActions = $rowActions[tableId] || []
+ $: viewRowActions = $rowActions[viewId] || []
+ $: actionCount = isView ? viewRowActions.length : tableRowActions.length
const rowActionUrl = derived([url, appStore], ([$url, $appStore]) => {
return ({ automationId }) => {
@@ -31,30 +30,11 @@
}
})
- const fetchRowActions = async datasource => {
- if (!datasource?.tableId) {
- rowActions = []
- return
- }
- const res = await API.rowActions.fetch(datasource.tableId)
- rowActions = Object.values(res || {}).map(action => ({
- ...action,
- enabled: !isView || action.allowedViews?.includes(ds.id),
- }))
- }
-
const createRowAction = async () => {
try {
- const name = getSequentialName(rowActions, "New row action ", {
- getName: x => x.name,
- })
- const res = await API.rowActions.create({
- name,
- tableId,
- })
- await automationStore.actions.fetch()
+ const newRowAction = await rowActions.createRowAction(tableId, viewId)
notifications.success("Row action created successfully")
- $goto($rowActionUrl(res))
+ // $goto($rowActionUrl(newRowAction))
} catch (error) {
console.error(error)
notifications.error("Error creating row action")
@@ -62,19 +42,10 @@
}
const toggleAction = async (action, enabled) => {
- console.log(action, enabled)
if (enabled) {
- await API.rowActions.enableView({
- tableId,
- rowActionId: action.id,
- viewId: ds.id,
- })
+ await rowActions.enableView(tableId, viewId, action.id)
} else {
- await API.rowActions.disableView({
- tableId,
- rowActionId: action.id,
- viewId: ds.id,
- })
+ await rowActions.disableView(tableId, viewId, action.id)
}
}
@@ -96,18 +67,18 @@
Use the toggle to enable/disable row actions for this view.
{/if}
- {#if !rowActions.length}
+ {#if !tableRowActions.length}
You haven't created any row actions.
{:else}
- {#each rowActions as action}
+ {#each tableRowActions as action}
{#if isView}
toggleAction(action, e.detail)}
/>
diff --git a/packages/builder/src/pages/builder/app/[application]/data/table/[tableId]/[viewId]/index.svelte b/packages/builder/src/pages/builder/app/[application]/data/table/[tableId]/[viewId]/index.svelte
index e3020394df..3596f1b832 100644
--- a/packages/builder/src/pages/builder/app/[application]/data/table/[tableId]/[viewId]/index.svelte
+++ b/packages/builder/src/pages/builder/app/[application]/data/table/[tableId]/[viewId]/index.svelte
@@ -1,5 +1,5 @@
{#if $tables?.selected?.name}
diff --git a/packages/builder/src/stores/BudiStore.js b/packages/builder/src/stores/BudiStore.js
index 1acf299921..e7be02f283 100644
--- a/packages/builder/src/stores/BudiStore.js
+++ b/packages/builder/src/stores/BudiStore.js
@@ -2,9 +2,8 @@ import { writable } from "svelte/store"
export default class BudiStore {
constructor(init, opts) {
- const store = writable({
- ...init,
- })
+ this.initialState = init
+ const store = writable({ ...init })
/**
* Internal Svelte store
@@ -23,6 +22,7 @@ export default class BudiStore {
* *Store modification should be kept to a minimum
*/
this.update = this.store.update
+ this.set = this.store.set
/**
* Optional debug mode to output the store updates to console
@@ -33,4 +33,8 @@ export default class BudiStore {
})
}
}
+
+ reset = () => {
+ this.store.set({ ...this.initialState })
+ }
}
diff --git a/packages/builder/src/stores/builder/index.js b/packages/builder/src/stores/builder/index.js
index aa0062dd7d..dbde739951 100644
--- a/packages/builder/src/stores/builder/index.js
+++ b/packages/builder/src/stores/builder/index.js
@@ -29,6 +29,7 @@ import { integrations } from "./integrations"
import { sortedIntegrations } from "./sortedIntegrations"
import { queries } from "./queries"
import { flags } from "./flags"
+import { rowActions } from "./rowActions"
import componentTreeNodesStore from "./componentTreeNodes"
export {
@@ -65,6 +66,7 @@ export {
flags,
hoverStore,
snippets,
+ rowActions,
}
export const reset = () => {
@@ -74,6 +76,7 @@ export const reset = () => {
componentStore.reset()
layoutStore.reset()
navigationStore.reset()
+ rowActions.reset()
}
const refreshBuilderData = async () => {
diff --git a/packages/builder/src/stores/builder/rowActions.js b/packages/builder/src/stores/builder/rowActions.js
new file mode 100644
index 0000000000..0255e4726c
--- /dev/null
+++ b/packages/builder/src/stores/builder/rowActions.js
@@ -0,0 +1,114 @@
+import { get, derived } from "svelte/store"
+import BudiStore from "stores/BudiStore"
+import { tables } from "./tables"
+import { viewsV2 } from "./viewsV2"
+import { automationStore } from "./automations"
+import { API } from "api"
+import { getSequentialName } from "helpers/duplicate"
+
+const initialState = {}
+
+export class RowActionStore extends BudiStore {
+ constructor() {
+ super(initialState)
+ }
+
+ refreshRowActions = async sourceId => {
+ if (!sourceId) {
+ return
+ }
+
+ // Get the underlying table ID for this source ID
+ let tableId = get(tables).list.find(table => table._id === sourceId)?._id
+ if (!tableId) {
+ const view = get(viewsV2).list.find(view => view.id === sourceId)
+ tableId = view?.tableId
+ }
+ if (!tableId) {
+ return
+ }
+
+ // Fetch row actions for this table
+ const res = await API.rowActions.fetch(tableId)
+ const actions = Object.values(res || {})
+ this.update(state => ({
+ ...state,
+ [tableId]: actions,
+ }))
+ }
+
+ createRowAction = async (tableId, viewId) => {
+ if (!tableId) {
+ return
+ }
+
+ // Get a unique name for this action
+ const existingRowActions = get(this.store)[tableId] || []
+ const name = getSequentialName(existingRowActions, "New row action ", {
+ getName: x => x.name,
+ })
+
+ // Create the action and update state
+ const res = await API.rowActions.create({
+ name,
+ tableId,
+ })
+ this.update(state => ({
+ ...state,
+ [tableId]: [...(state[tableId] || []), res],
+ }))
+
+ // If adding to a view, enable on this view
+ if (viewId) {
+ await this.enableView(tableId, viewId, res.id)
+ }
+
+ // Refresh automations so we have this new row action automation
+ await automationStore.actions.fetch()
+
+ return res
+ }
+
+ enableView = async (tableId, viewId, rowActionId) => {
+ await API.rowActions.enableView({
+ tableId,
+ viewId,
+ rowActionId,
+ })
+ await this.refreshRowActions(tableId)
+ }
+
+ disableView = async (tableId, viewId, rowActionId) => {
+ await API.rowActions.disableView({
+ tableId,
+ viewId,
+ rowActionId,
+ })
+ await this.refreshRowActions(tableId)
+ }
+}
+
+const store = new RowActionStore()
+const derivedStore = derived(store, $store => {
+ let map = {}
+
+ // Generate an entry for every view as well
+ Object.keys($store || {}).forEach(tableId => {
+ map[tableId] = $store[tableId]
+ for (let action of $store[tableId]) {
+ for (let viewId of action.allowedViews || []) {
+ if (!map[viewId]) {
+ map[viewId] = []
+ }
+ map[viewId].push(action)
+ }
+ }
+ })
+
+ return map
+})
+
+export const rowActions = {
+ ...store,
+ subscribe: derivedStore.subscribe,
+}
diff --git a/packages/builder/src/stores/portal/licensing.js b/packages/builder/src/stores/portal/licensing.js
index dd9747aa09..0e44650479 100644
--- a/packages/builder/src/stores/portal/licensing.js
+++ b/packages/builder/src/stores/portal/licensing.js
@@ -104,7 +104,6 @@ export const createLicensingStore = () => {
const isBusinessPlan = planType === Constants.PlanType.BUSINESS
const isEnterpriseTrial =
planType === Constants.PlanType.ENTERPRISE_BASIC_TRIAL
- console.log(license)
const groupsEnabled = license.features.includes(
Constants.Features.USER_GROUPS
)
@@ -143,8 +142,6 @@ export const createLicensingStore = () => {
Constants.Features.VIEW_READONLY_COLUMNS
)
- console.log(isViewReadonlyColumnsEnabled)
-
store.update(state => {
return {
...state,
diff --git a/packages/frontend-core/src/components/grid/layout/ButtonColumn.svelte b/packages/frontend-core/src/components/grid/layout/ButtonColumn.svelte
index a086972941..03f5f4644e 100644
--- a/packages/frontend-core/src/components/grid/layout/ButtonColumn.svelte
+++ b/packages/frontend-core/src/components/grid/layout/ButtonColumn.svelte
@@ -25,7 +25,7 @@
let container
- $: buttons = $props.buttons?.slice(0, 3) || []
+ $: buttons = getButtons($props)
$: columnsWidth = $scrollableColumns.reduce(
(total, col) => (total += col.width),
0
@@ -34,6 +34,14 @@
$: gridEnd = $width - $buttonColumnWidth - 1
$: left = Math.min(columnEnd, gridEnd)
+ const getButtons = ({ buttons, buttonsCollapsed }) => {
+ let gridButtons = buttons || []
+ if (!buttonsCollapsed) {
+ return gridButtons.slice(0, 3)
+ }
+ return gridButtons
+ }
+
const handleClick = async (button, row) => {
await button.onClick?.(rows.actions.cleanRow(row))
await rows.actions.refreshRow(row._id)