Enable renaming row actions and improve row actions in grids

This commit is contained in:
Andrew Kingston 2024-09-03 15:05:13 +01:00
parent 7d5e884a8f
commit 789df301cb
No known key found for this signature in database
11 changed files with 131 additions and 16 deletions

View File

@ -9,6 +9,7 @@
export let size = "M" export let size = "M"
export let align = "left" export let align = "left"
export let offset export let offset
export let animate
let anchor let anchor
let popover let popover
@ -28,7 +29,14 @@
> >
{text || "Action"} {text || "Action"}
</Button> </Button>
<Popover bind:this={popover} {align} {anchor} {offset} resizable={false}> <Popover
bind:this={popover}
{align}
{anchor}
{offset}
{animate}
resizable={false}
>
<Menu> <Menu>
{#each buttons as button} {#each buttons as button}
<MenuItem on:click={() => handleClick(button)} disabled={button.disabled}> <MenuItem on:click={() => handleClick(button)} disabled={button.disabled}>

View File

@ -190,7 +190,7 @@
{#if isTrigger && triggerInfo} {#if isTrigger && triggerInfo}
<InlineAlert <InlineAlert
header={triggerInfo.type} header={triggerInfo.type}
message={`This trigger is tied to the row action ${triggerInfo.rowAction.name} on your ${triggerInfo.table.name} table`} message={`This trigger is tied to the "${triggerInfo.rowAction.name}" row action in your ${triggerInfo.table.name} table`}
/> />
{/if} {/if}
{#if lastStep} {#if lastStep}

View File

@ -9,6 +9,7 @@
import { sdk } from "@budibase/shared-core" import { sdk } from "@budibase/shared-core"
import ConfirmDialog from "components/common/ConfirmDialog.svelte" import ConfirmDialog from "components/common/ConfirmDialog.svelte"
import UpdateAutomationModal from "components/automation/AutomationPanel/UpdateAutomationModal.svelte" import UpdateAutomationModal from "components/automation/AutomationPanel/UpdateAutomationModal.svelte"
import UpdateRowActionModal from "components/automation/AutomationPanel/UpdateRowActionModal.svelte"
import NavItem from "components/common/NavItem.svelte" import NavItem from "components/common/NavItem.svelte"
export let automation export let automation
@ -16,6 +17,9 @@
let confirmDeleteDialog let confirmDeleteDialog
let updateAutomationDialog let updateAutomationDialog
let updateRowActionDialog
$: isRowAction = sdk.automations.isRowAction(automation)
async function deleteAutomation() { async function deleteAutomation() {
try { try {
@ -37,7 +41,6 @@
} }
const getContextMenuItems = () => { const getContextMenuItems = () => {
const isRowAction = sdk.automations.isRowAction(automation)
const pause = { const pause = {
icon: automation.disabled ? "CheckmarkCircle" : "Cancel", icon: automation.disabled ? "CheckmarkCircle" : "Cancel",
name: automation.disabled ? "Activate" : "Pause", name: automation.disabled ? "Activate" : "Pause",
@ -83,7 +86,16 @@
del, del,
] ]
} else { } else {
return [del] return [
{
icon: "Edit",
name: "Edit",
keyBind: null,
visible: true,
callback: updateRowActionDialog.show,
},
del,
]
} }
} }
@ -122,4 +134,9 @@
<i>{automation.name}?</i> <i>{automation.name}?</i>
This action cannot be undone. This action cannot be undone.
</ConfirmDialog> </ConfirmDialog>
<UpdateAutomationModal {automation} bind:this={updateAutomationDialog} />
{#if isRowAction}
<UpdateRowActionModal {automation} bind:this={updateRowActionDialog} />
{:else}
<UpdateAutomationModal {automation} bind:this={updateAutomationDialog} />
{/if}

View File

@ -0,0 +1,85 @@
<script>
import { automationStore } from "stores/builder"
import {
notifications,
Icon,
Input,
ModalContent,
Modal,
} from "@budibase/bbui"
import { API } from "api"
export let automation
export let onCancel = undefined
let name
let error = ""
let modal
export const show = () => {
name = automation?.displayName
modal.show()
}
export const hide = () => {
modal.hide()
}
async function saveAutomation() {
try {
await API.rowActions.update({
rowActionId: automation.definition.trigger.inputs.rowActionId,
tableId: automation.definition.trigger.inputs.tableId,
name,
})
await automationStore.actions.fetch()
notifications.success(`Row action updated successfully`)
hide()
} catch (error) {
notifications.error("Error saving row action")
}
}
function checkValid(evt) {
name = evt.target.value
if (!name) {
error = "Name is required"
return
}
error = ""
}
</script>
<Modal bind:this={modal} on:hide={onCancel}>
<ModalContent
title="Edit Row Action"
confirmText="Save"
size="L"
onConfirm={saveAutomation}
disabled={error}
>
<Input bind:value={name} label="Name" on:input={checkValid} {error} />
<a
slot="footer"
target="_blank"
href="https://docs.budibase.com/docs/automation-steps"
>
<Icon name="InfoOutline" />
<span>Learn about automations</span>
</a>
</ModalContent>
</Modal>
<style>
a {
color: var(--ink);
font-size: 14px;
vertical-align: middle;
display: flex;
align-items: center;
text-decoration: none;
}
a span {
text-decoration: underline;
margin-left: var(--spectrum-alias-item-padding-s);
}
</style>

View File

@ -2,8 +2,7 @@
import { getContext } from "svelte" import { getContext } from "svelte"
import { ActionButton, Popover } from "@budibase/bbui" import { ActionButton, Popover } from "@budibase/bbui"
import ColumnsSettingContent from "./ColumnsSettingContent.svelte" import ColumnsSettingContent from "./ColumnsSettingContent.svelte"
import { licensing } from "stores/portal"
export let allowViewReadonlyColumns = false
const { columns } = getContext("grid") const { columns } = getContext("grid")
@ -29,5 +28,8 @@
</div> </div>
<Popover bind:open {anchor} align="left"> <Popover bind:open {anchor} align="left">
<ColumnsSettingContent columns={$columns} {allowViewReadonlyColumns} /> <ColumnsSettingContent
columns={$columns}
allowViewReadonlyColumns={$licensing.isViewReadonlyColumnsEnabled}
/>
</Popover> </Popover>

View File

@ -22,7 +22,7 @@
$: ds = $datasource $: ds = $datasource
$: tableId = ds?.tableId $: tableId = ds?.tableId
$: isView = ds?.type === "viewV2" $: isView = ds?.type === "viewV2"
$: fetchRowActions(tableId) $: fetchRowActions(ds)
$: actionCount = rowActions.filter(action => !isView || action.enabled).length $: actionCount = rowActions.filter(action => !isView || action.enabled).length
const rowActionUrl = derived([url, appStore], ([$url, $appStore]) => { const rowActionUrl = derived([url, appStore], ([$url, $appStore]) => {
@ -31,12 +31,12 @@
} }
}) })
const fetchRowActions = async tableId => { const fetchRowActions = async datasource => {
if (!tableId) { if (!datasource?.tableId) {
rowActions = [] rowActions = []
return return
} }
const res = await API.rowActions.fetch(tableId) const res = await API.rowActions.fetch(datasource.tableId)
rowActions = Object.values(res || {}).map(action => ({ rowActions = Object.values(res || {}).map(action => ({
...action, ...action,
enabled: !isView || action.allowedViews?.includes(ds.id), enabled: !isView || action.allowedViews?.includes(ds.id),

View File

@ -1,6 +1,6 @@
<script> <script>
import { viewsV2 } from "stores/builder" import { viewsV2 } from "stores/builder"
import { admin, licensing } from "stores/portal" import { admin } from "stores/portal"
import { Grid } from "@budibase/frontend-core" import { Grid } from "@budibase/frontend-core"
import { API } from "api" import { API } from "api"
import GridCreateEditRowModal from "components/backend/DataTable/modals/grid/GridCreateEditRowModal.svelte" import GridCreateEditRowModal from "components/backend/DataTable/modals/grid/GridCreateEditRowModal.svelte"
@ -35,7 +35,6 @@
showAvatars={false} showAvatars={false}
on:updatedatasource={handleGridViewUpdate} on:updatedatasource={handleGridViewUpdate}
isCloud={$admin.cloud} isCloud={$admin.cloud}
allowViewReadonlyColumns={$licensing.isViewReadonlyColumnsEnabled}
> >
<svelte:fragment slot="controls"> <svelte:fragment slot="controls">
<GridFilterButton /> <GridFilterButton />

View File

@ -104,6 +104,7 @@ export const createLicensingStore = () => {
const isBusinessPlan = planType === Constants.PlanType.BUSINESS const isBusinessPlan = planType === Constants.PlanType.BUSINESS
const isEnterpriseTrial = const isEnterpriseTrial =
planType === Constants.PlanType.ENTERPRISE_BASIC_TRIAL planType === Constants.PlanType.ENTERPRISE_BASIC_TRIAL
console.log(license)
const groupsEnabled = license.features.includes( const groupsEnabled = license.features.includes(
Constants.Features.USER_GROUPS Constants.Features.USER_GROUPS
) )
@ -142,6 +143,8 @@ export const createLicensingStore = () => {
Constants.Features.VIEW_READONLY_COLUMNS Constants.Features.VIEW_READONLY_COLUMNS
) )
console.log(isViewReadonlyColumnsEnabled)
store.update(state => { store.update(state => {
return { return {
...state, ...state,

View File

@ -31,7 +31,7 @@ export const buildRowActionEndpoints = API => ({
* @param rowActionId the ID of the row action to update * @param rowActionId the ID of the row action to update
*/ */
update: async ({ tableId, rowActionId, name }) => { update: async ({ tableId, rowActionId, name }) => {
return await API.post({ return await API.put({
url: `/api/tables/${tableId}/actions/${rowActionId}`, url: `/api/tables/${tableId}/actions/${rowActionId}`,
body: { body: {
name, name,

View File

@ -91,6 +91,7 @@
align="right" align="right"
offset={5} offset={5}
size="S" size="S"
animate={false}
/> />
{:else} {:else}
{#each buttons as button} {#each buttons as button}

View File

@ -52,7 +52,7 @@ export async function getBuilderData(
const rowActionName = await getRowActionName(tableId, rowActionId) const rowActionName = await getRowActionName(tableId, rowActionId)
result[automation._id!] = { result[automation._id!] = {
displayName: `${tableName}: ${automation.name}`, displayName: rowActionName,
triggerInfo: { triggerInfo: {
type: "Automation trigger", type: "Automation trigger",
table: { id: tableId, name: tableName }, table: { id: tableId, name: tableName },