Enable renaming row actions and improve row actions in grids
This commit is contained in:
parent
7d5e884a8f
commit
789df301cb
|
@ -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}>
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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>
|
|
@ -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>
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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 />
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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 },
|
||||||
|
|
Loading…
Reference in New Issue