Enhance Sidebar and Object Models with List Action Integration

- Added a 'list' action to various object models, including AppPassword, AuditLog, Client, and more, to standardize access to list views across the application.
- Updated the ObjectModels.js to include a new label for the 'list' action, improving clarity in the permission matrix.
- Refactored Sidebar.js to incorporate user profile permissions for sidebar item visibility, enhancing user experience based on access rights.
- Introduced utility functions for normalizing paths and filtering sidebar items based on user permissions, streamlining sidebar management.
- Improved the overall structure and readability of the Sidebar and ObjectModels components.
This commit is contained in:
Tom Butcher 2026-08-20 20:14:57 +01:00
parent 8ac04ac0bc
commit 5ed086cf8b
51 changed files with 501 additions and 16 deletions

View File

@ -250,7 +250,12 @@ export function getPermissionMatrixActions() {
seen.set(action.name, {
name: action.name,
type: action.type,
label: action.name === 'new' ? 'New' : action.label || action.name
label:
action.name === 'new'
? 'New'
: action.name === 'list'
? 'List'
: action.label || action.name
})
}
})

View File

@ -4,6 +4,8 @@ import salesSidebarItems from './sidebars/sales'
import financeSidebarItems from './sidebars/finance'
import managementSidebarItems from './sidebars/management'
import developerSidebarItems from './sidebars/developer'
import { objectModels } from './ObjectModels'
import { hasActionPermission } from './permissions'
const SIDEBARS = {
production: {
@ -49,6 +51,48 @@ const SIDEBARS = {
const splitPath = (path) => path.split('/').filter(Boolean)
const normalizePath = (path) =>
typeof path === 'string' ? path.split('?')[0].replace(/\/+$/, '') : ''
export const getSidebarItemModel = (item) => {
const itemPath = normalizePath(item?.path)
if (!itemPath) return null
return (
objectModels.find(
(model) =>
typeof model.url === 'string' && normalizePath(model.url) === itemPath
) || null
)
}
const isSidebarItemAllowed = (item, userProfile) => {
if (!userProfile) return true
const model = getSidebarItemModel(item)
if (!model) return true
return hasActionPermission(userProfile, model, 'list')
}
const cleanSidebarDividers = (items = []) => {
const cleaned = []
for (const item of items) {
if (!item) continue
if (item.type === 'divider') {
if (cleaned.length === 0) continue
if (cleaned[cleaned.length - 1]?.type === 'divider') continue
cleaned.push(item)
continue
}
cleaned.push(item)
}
if (cleaned[cleaned.length - 1]?.type === 'divider') {
cleaned.pop()
}
return cleaned
}
const isPathPrefixMatch = (candidatePath, pathname) => {
const candidateParts = splitPath(candidatePath)
const pathParts = splitPath(pathname)
@ -59,15 +103,32 @@ const isPathPrefixMatch = (candidatePath, pathname) => {
return true
}
const getFilteredItems = (items = [], includeDev = false) =>
items
.filter((item) => item?.devOnly !== true || includeDev)
.map((item) => {
if (item?.children && Array.isArray(item.children)) {
return { ...item, children: getFilteredItems(item.children, includeDev) }
}
return { ...item }
})
const getFilteredItems = (items = [], includeDev = false, userProfile) =>
cleanSidebarDividers(
items
.filter((item) => item?.devOnly !== true || includeDev)
.map((item) => {
if (item?.type === 'divider') return item
if (item?.children && Array.isArray(item.children)) {
const children = getFilteredItems(
item.children,
includeDev,
userProfile
)
if (children.length === 0 && !item.path) return null
return { ...item, children }
}
return { ...item }
})
.filter((item) => {
if (!item) return false
if (item.type === 'divider') return true
return isSidebarItemAllowed(item, userProfile)
})
)
export const filterSidebarItemsByListPermission = (items = [], userProfile) =>
getFilteredItems(items, true, userProfile)
const flattenPathEntries = (items = [], acc = []) => {
items.forEach((item) => {
@ -120,8 +181,31 @@ export const getSidebar = (sidebarKey) => SIDEBARS[sidebarKey] || null
export const getSidebarItems = (sidebarKey, options = {}) => {
const sidebar = getSidebar(sidebarKey)
if (!sidebar) return []
const { includeDev = false } = options
return getFilteredItems(sidebar.items, includeDev)
const { includeDev = false, userProfile } = options
return getFilteredItems(sidebar.items, includeDev, userProfile)
}
const collectSidebarModelItems = (items = [], acc = []) => {
items.forEach((item) => {
if (!item || item.type === 'divider') return
const model = getSidebarItemModel(item)
if (model) acc.push(model)
if (item.children?.length) collectSidebarModelItems(item.children, acc)
})
return acc
}
export const isSidebarSectionVisible = (sidebarKey, options = {}) => {
const { includeDev = false, userProfile } = options
const sidebar = getSidebar(sidebarKey)
if (!sidebar) return false
const items = getFilteredItems(sidebar.items, includeDev)
const models = collectSidebarModelItems(items)
if (!userProfile) return flattenPathEntries(items).length > 0
if (models.length === 0) return flattenPathEntries(items).length > 0
return models.some((model) => hasActionPermission(userProfile, model, 'list'))
}
export const getSidebarSelectedKey = (sidebarKey, pathname, options = {}) => {
@ -142,14 +226,20 @@ export const getSidebarSelectedKey = (sidebarKey, pathname, options = {}) => {
}
export const getSidebarMenuSections = (options = {}) => {
const { includeDev = false } = options
const { includeDev = false, userProfile } = options
return Object.values(SIDEBARS)
.filter((sidebar) => includeDev || sidebar.key !== 'developer')
.filter(
(sidebar) =>
!userProfile || isSidebarSectionVisible(sidebar.key, options)
)
.map((sidebar) => ({
key: sidebar.key,
label: sidebar.label,
iconKey: sidebar.iconKey,
items: toMenuItems(getSidebarItems(sidebar.key, { includeDev }))
items: toMenuItems(
getSidebarItems(sidebar.key, { includeDev, userProfile })
)
}))
}

View File

@ -18,6 +18,7 @@ import EditIcon from '../../components/Icons/EditIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import LockIcon from '../../components/Icons/LockIcon'
import ListIcon from '../../components/Icons/ListIcon'
export const AppPassword = {
name: 'appPassword',
@ -38,6 +39,13 @@ export const AppPassword = {
return createElement(NewAppPassword, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -1,4 +1,5 @@
import AuditLogIcon from '../../components/Icons/AuditLogIcon'
import ListIcon from '../../components/Icons/ListIcon'
export const AuditLog = {
name: 'auditLog',
@ -7,7 +8,15 @@ export const AuditLog = {
url: '/dashboard/management/auditlogs',
prefix: 'ADL',
icon: AuditLogIcon,
actions: [],
actions: [
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
}
],
columns: [
'_reference',
'owner',

View File

@ -13,6 +13,7 @@ import EditIcon from '../../components/Icons/EditIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import BinIcon from '../../components/Icons/BinIcon'
import ListIcon from '../../components/Icons/ListIcon'
export const Client = {
name: 'client',
@ -33,6 +34,13 @@ export const Client = {
return createElement(NewClient, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -13,6 +13,7 @@ import EditIcon from '../../components/Icons/EditIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import BinIcon from '../../components/Icons/BinIcon'
import ListIcon from '../../components/Icons/ListIcon'
export const Courier = {
name: 'courier',
@ -33,6 +34,13 @@ export const Courier = {
return createElement(NewCourier, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -13,6 +13,7 @@ import EditIcon from '../../components/Icons/EditIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import BinIcon from '../../components/Icons/BinIcon'
import ListIcon from '../../components/Icons/ListIcon'
export const CourierService = {
name: 'courierService',
@ -33,6 +34,13 @@ export const CourierService = {
return createElement(NewCourierService, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -13,6 +13,7 @@ import CheckIcon from '../../components/Icons/CheckIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import DocumentJobIcon from '../../components/Icons/DocumentJobIcon'
import dayjs from 'dayjs'
import ListIcon from '../../components/Icons/ListIcon'
export const DocumentJob = {
name: 'documentJob',
@ -33,6 +34,13 @@ export const DocumentJob = {
return createElement(NewDocumentJob, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -12,6 +12,7 @@ import EditIcon from '../../components/Icons/EditIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import DocumentPrinterIcon from '../../components/Icons/DocumentPrinterIcon'
import ListIcon from '../../components/Icons/ListIcon'
export const DocumentPrinter = {
name: 'documentPrinter',
@ -32,6 +33,13 @@ export const DocumentPrinter = {
return createElement(NewDocumentPrinter, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -12,6 +12,7 @@ import EditIcon from '../../components/Icons/EditIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import DocumentSizeIcon from '../../components/Icons/DocumentSizeIcon'
import ListIcon from '../../components/Icons/ListIcon'
export const DocumentSize = {
name: 'documentSize',
@ -32,6 +33,13 @@ export const DocumentSize = {
return createElement(NewDocumentSize, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -14,6 +14,7 @@ import CheckIcon from '../../components/Icons/CheckIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import DesignIcon from '../../components/Icons/DesignIcon'
import DocumentTemplateIcon from '../../components/Icons/DocumentTemplateIcon'
import ListIcon from '../../components/Icons/ListIcon'
export const DocumentTemplate = {
name: 'documentTemplate',
@ -34,6 +35,13 @@ export const DocumentTemplate = {
return createElement(NewDocumentTemplate, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'design',
label: 'Design',

View File

@ -13,6 +13,7 @@ import XMarkIcon from '../../components/Icons/XMarkIcon'
import FilamentIcon from '../../components/Icons/FilamentIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import BinIcon from '../../components/Icons/BinIcon'
import ListIcon from '../../components/Icons/ListIcon'
export const Filament = {
name: 'filament',
@ -33,6 +34,13 @@ export const Filament = {
return createElement(NewFilament, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -14,6 +14,7 @@ import EditIcon from '../../components/Icons/EditIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import BinIcon from '../../components/Icons/BinIcon'
import ListIcon from '../../components/Icons/ListIcon'
export const FilamentProfile = {
name: 'filamentProfile',
@ -34,6 +35,13 @@ export const FilamentProfile = {
return createElement(NewFilamentProfile, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -13,6 +13,7 @@ import EditIcon from '../../components/Icons/EditIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import BinIcon from '../../components/Icons/BinIcon'
import ListIcon from '../../components/Icons/ListIcon'
export const FilamentSku = {
name: 'filamentSku',
@ -33,6 +34,13 @@ export const FilamentSku = {
return createElement(NewFilamentSku, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -10,6 +10,7 @@ const NewFilamentStock = lazy(
import FilamentStockIcon from '../../components/Icons/FilamentStockIcon'
import PlusIcon from '../../components/Icons/PlusIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import ListIcon from '../../components/Icons/ListIcon'
export const FilamentStock = {
name: 'filamentStock',
@ -31,6 +32,13 @@ export const FilamentStock = {
return createElement(NewFilamentStock, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -10,6 +10,7 @@ import EditIcon from '../../components/Icons/EditIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import BinIcon from '../../components/Icons/BinIcon'
import ListIcon from '../../components/Icons/ListIcon'
export const File = {
name: 'file',
@ -19,6 +20,13 @@ export const File = {
prefix: 'FLE',
icon: FileIcon,
actions: [
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -14,6 +14,7 @@ import XMarkIcon from '../../components/Icons/XMarkIcon'
import GCodeFileIcon from '../../components/Icons/GCodeFileIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import EyeIcon from '../../components/Icons/EyeIcon'
import ListIcon from '../../components/Icons/ListIcon'
export const GCodeFile = {
name: 'gcodeFile',
@ -34,6 +35,13 @@ export const GCodeFile = {
return createElement(NewGCodeFile, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'preview',
label: 'Preview',

View File

@ -17,6 +17,7 @@ import CheckIcon from '../../components/Icons/CheckIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import BinIcon from '../../components/Icons/BinIcon'
import OTPIcon from '../../components/Icons/OTPIcon'
import ListIcon from '../../components/Icons/ListIcon'
export const Host = {
name: 'host',
@ -37,6 +38,13 @@ export const Host = {
return createElement(NewHost, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -19,6 +19,7 @@ import CheckIcon from '../../components/Icons/CheckIcon'
import EditIcon from '../../components/Icons/EditIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import BinIcon from '../../components/Icons/BinIcon'
import ListIcon from '../../components/Icons/ListIcon'
export const Invoice = {
name: 'invoice',
@ -39,6 +40,13 @@ export const Invoice = {
return createElement(NewInvoice, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -17,6 +17,7 @@ import XMarkIcon from '../../components/Icons/XMarkIcon'
import EditIcon from '../../components/Icons/EditIcon'
import BinIcon from '../../components/Icons/BinIcon'
import dayjs from 'dayjs'
import ListIcon from '../../components/Icons/ListIcon'
export const Job = {
name: 'job',
@ -37,6 +38,13 @@ export const Job = {
return createElement(NewJob, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -19,6 +19,7 @@ import EditIcon from '../../components/Icons/EditIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import BinIcon from '../../components/Icons/BinIcon'
import ListIcon from '../../components/Icons/ListIcon'
export const Listing = {
name: 'listing',
@ -39,6 +40,13 @@ export const Listing = {
return createElement(NewListing, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -19,6 +19,7 @@ import EditIcon from '../../components/Icons/EditIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import BinIcon from '../../components/Icons/BinIcon'
import ListIcon from '../../components/Icons/ListIcon'
export const ListingVarient = {
name: 'listingVarient',
@ -39,6 +40,13 @@ export const ListingVarient = {
return createElement(NewListingVarient, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -21,6 +21,7 @@ import XMarkIcon from '../../components/Icons/XMarkIcon'
import ReloadIcon from '../../components/Icons/ReloadIcon'
import LinkIcon from '../../components/Icons/LinkIcon'
import BinIcon from '../../components/Icons/BinIcon'
import ListIcon from '../../components/Icons/ListIcon'
export const Marketplace = {
name: 'marketplace',
@ -41,6 +42,13 @@ export const Marketplace = {
return createElement(NewMarketplace, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -13,6 +13,7 @@ import EditIcon from '../../components/Icons/EditIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import BinIcon from '../../components/Icons/BinIcon'
import ListIcon from '../../components/Icons/ListIcon'
export const Material = {
name: 'material',
@ -33,6 +34,13 @@ export const Material = {
return createElement(NewMaterial, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -12,6 +12,7 @@ import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import EditIcon from '../../components/Icons/EditIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import ListIcon from '../../components/Icons/ListIcon'
export const NoteType = {
name: 'noteType',
@ -32,6 +33,13 @@ export const NoteType = {
return createElement(NewNoteType, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -13,6 +13,7 @@ import EditIcon from '../../components/Icons/EditIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import BinIcon from '../../components/Icons/BinIcon'
import ListIcon from '../../components/Icons/ListIcon'
export const OrderItem = {
name: 'orderItem',
@ -33,6 +34,13 @@ export const OrderItem = {
return createElement(NewOrderItem, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -12,6 +12,7 @@ import CheckIcon from '../../components/Icons/CheckIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import PartIcon from '../../components/Icons/PartIcon'
import ListIcon from '../../components/Icons/ListIcon'
export const Part = {
name: 'part',
@ -32,6 +33,13 @@ export const Part = {
return createElement(NewPart, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -13,6 +13,7 @@ import EditIcon from '../../components/Icons/EditIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import BinIcon from '../../components/Icons/BinIcon'
import ListIcon from '../../components/Icons/ListIcon'
export const PartSku = {
name: 'partSku',
@ -33,6 +34,13 @@ export const PartSku = {
return createElement(NewPartSku, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -9,6 +9,7 @@ const NewPartStock = lazy(
import PartStockIcon from '../../components/Icons/PartStockIcon'
import PlusIcon from '../../components/Icons/PlusIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import ListIcon from '../../components/Icons/ListIcon'
export const PartStock = {
name: 'partStock',
@ -30,6 +31,13 @@ export const PartStock = {
return createElement(NewPartStock, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -25,6 +25,7 @@ import CheckIcon from '../../components/Icons/CheckIcon'
import EditIcon from '../../components/Icons/EditIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import BinIcon from '../../components/Icons/BinIcon'
import ListIcon from '../../components/Icons/ListIcon'
export const Payment = {
name: 'payment',
@ -45,6 +46,13 @@ export const Payment = {
return createElement(NewPayment, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -14,6 +14,7 @@ import EditIcon from '../../components/Icons/EditIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import BinIcon from '../../components/Icons/BinIcon'
import ListIcon from '../../components/Icons/ListIcon'
export const PermissionSetting = {
name: 'permissionSetting',
@ -35,6 +36,13 @@ export const PermissionSetting = {
return createElement(NewPermissionSetting, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -38,6 +38,7 @@ import StopCircleIcon from '../../components/Icons/StopCircleIcon'
import FilamentStockIcon from '../../components/Icons/FilamentStockIcon'
import ControlIcon from '../../components/Icons/ControlIcon'
import JobIcon from '../../components/Icons/JobIcon'
import ListIcon from '../../components/Icons/ListIcon'
export const Printer = {
name: 'printer',
@ -58,6 +59,13 @@ export const Printer = {
return createElement(NewPrinter, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -13,6 +13,7 @@ import EditIcon from '../../components/Icons/EditIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import BinIcon from '../../components/Icons/BinIcon'
import ListIcon from '../../components/Icons/ListIcon'
const THUMBNAIL_PROPERTIES = [
{
@ -298,6 +299,13 @@ export const PrinterProfile = {
return createElement(NewPrinterProfile, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -12,6 +12,7 @@ import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import EditIcon from '../../components/Icons/EditIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import ListIcon from '../../components/Icons/ListIcon'
export const Product = {
name: 'product',
@ -32,6 +33,13 @@ export const Product = {
return createElement(NewProduct, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -13,6 +13,7 @@ import EditIcon from '../../components/Icons/EditIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import BinIcon from '../../components/Icons/BinIcon'
import ListIcon from '../../components/Icons/ListIcon'
export const ProductCategory = {
name: 'productCategory',
@ -34,6 +35,13 @@ export const ProductCategory = {
return createElement(NewProductCategory, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -13,6 +13,7 @@ import EditIcon from '../../components/Icons/EditIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import BinIcon from '../../components/Icons/BinIcon'
import ListIcon from '../../components/Icons/ListIcon'
export const ProductSku = {
name: 'productSku',
@ -33,6 +34,13 @@ export const ProductSku = {
return createElement(NewProductSku, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -17,6 +17,7 @@ import EditIcon from '../../components/Icons/EditIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import BinIcon from '../../components/Icons/BinIcon'
import ListIcon from '../../components/Icons/ListIcon'
export const ProductStock = {
name: 'productStock',
@ -37,6 +38,13 @@ export const ProductStock = {
return createElement(NewProductStock, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -22,6 +22,7 @@ import CheckIcon from '../../components/Icons/CheckIcon'
import EditIcon from '../../components/Icons/EditIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import BinIcon from '../../components/Icons/BinIcon'
import ListIcon from '../../components/Icons/ListIcon'
export const PurchaseOrder = {
name: 'purchaseOrder',
@ -42,6 +43,13 @@ export const PurchaseOrder = {
return createElement(NewPurchaseOrder, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -22,6 +22,7 @@ import CheckIcon from '../../components/Icons/CheckIcon'
import EditIcon from '../../components/Icons/EditIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import BinIcon from '../../components/Icons/BinIcon'
import ListIcon from '../../components/Icons/ListIcon'
export const SalesOrder = {
name: 'salesOrder',
@ -42,6 +43,13 @@ export const SalesOrder = {
return createElement(NewSalesOrder, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -22,6 +22,7 @@ import EditIcon from '../../components/Icons/EditIcon'
import BinIcon from '../../components/Icons/BinIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import ListIcon from '../../components/Icons/ListIcon'
export const Shipment = {
name: 'shipment',
@ -42,6 +43,13 @@ export const Shipment = {
return createElement(NewShipment, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -12,6 +12,7 @@ import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import EditIcon from '../../components/Icons/EditIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import ListIcon from '../../components/Icons/ListIcon'
export const StockAudit = {
name: 'stockAudit',
@ -32,6 +33,13 @@ export const StockAudit = {
return createElement(NewStockAudit, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -1,4 +1,5 @@
import StockEventIcon from '../../components/Icons/StockEventIcon'
import ListIcon from '../../components/Icons/ListIcon'
export const StockEvent = {
name: 'stockEvent',
@ -7,7 +8,15 @@ export const StockEvent = {
url: '/dashboard/inventory/stockevents',
prefix: 'SEV',
icon: StockEventIcon,
actions: [],
actions: [
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
}
],
columns: ['_reference', 'owner', 'parent', 'value', 'createdAt', 'updatedAt'],
filters: ['owner', 'parent', 'createdAt', 'updatedAt', '_reference'],
sorters: ['createdAt', 'updatedAt'],

View File

@ -12,6 +12,7 @@ import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import EditIcon from '../../components/Icons/EditIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import ListIcon from '../../components/Icons/ListIcon'
export const StockLocation = {
name: 'stockLocation',
@ -32,6 +33,13 @@ export const StockLocation = {
return createElement(NewStockLocation, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -16,6 +16,7 @@ import EditIcon from '../../components/Icons/EditIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import BinIcon from '../../components/Icons/BinIcon'
import ListIcon from '../../components/Icons/ListIcon'
export const StockTransfer = {
name: 'stockTransfer',
@ -36,6 +37,13 @@ export const StockTransfer = {
return createElement(NewStockTransfer, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -7,6 +7,7 @@ import SubJobIcon from '../../components/Icons/SubJobIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import dayjs from 'dayjs'
import ListIcon from '../../components/Icons/ListIcon'
export const SubJob = {
name: 'subJob',
@ -16,6 +17,13 @@ export const SubJob = {
prefix: 'SJB',
icon: SubJobIcon,
actions: [
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -13,6 +13,7 @@ import EditIcon from '../../components/Icons/EditIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import BinIcon from '../../components/Icons/BinIcon'
import ListIcon from '../../components/Icons/ListIcon'
export const TaxRate = {
name: 'taxRate',
@ -33,6 +34,13 @@ export const TaxRate = {
return createElement(NewTaxRate, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -13,6 +13,7 @@ import EditIcon from '../../components/Icons/EditIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import BinIcon from '../../components/Icons/BinIcon'
import ListIcon from '../../components/Icons/ListIcon'
export const TaxRecord = {
name: 'taxRecord',
@ -33,6 +34,13 @@ export const TaxRecord = {
return createElement(NewTaxRecord, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -9,6 +9,7 @@ import EditIcon from '../../components/Icons/EditIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import { calculateUserPermissions } from '../permissions.js'
import ListIcon from '../../components/Icons/ListIcon'
export const User = {
name: 'user',
@ -18,6 +19,13 @@ export const User = {
prefix: 'USR',
icon: PersonIcon,
actions: [
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -14,6 +14,7 @@ import CheckIcon from '../../components/Icons/CheckIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import BinIcon from '../../components/Icons/BinIcon'
import { calculateUserGroupPermissions } from '../permissions.js'
import ListIcon from '../../components/Icons/ListIcon'
export const UserGroup = {
name: 'userGroup',
@ -34,6 +35,13 @@ export const UserGroup = {
return createElement(NewUserGroup, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -13,6 +13,7 @@ import EditIcon from '../../components/Icons/EditIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import BinIcon from '../../components/Icons/BinIcon'
import ListIcon from '../../components/Icons/ListIcon'
export const Vendor = {
name: 'vendor',
@ -33,6 +34,13 @@ export const Vendor = {
return createElement(NewVendor, { defaultValues: objectData, onOk, reset: true })
}
},
{
name: 'list',
type: 'page',
pageName: 'list',
label: 'List',
icon: ListIcon
},
{
name: 'info',
type: 'page',

View File

@ -14,6 +14,7 @@ export function actionVisibleOnPage(action, pageName) {
return action.pageName === pageName
}
if (action.name === 'new') return pageName === 'list'
if (action.name === 'list') return pageName !== 'list'
return pageName !== 'list'
}
@ -67,6 +68,9 @@ export function buildActionUrl(model, action, objectId, pathname, search = '') {
const pageName = action.pageName || action.name
if (action.type === 'page') {
if (action.name === 'list' || pageName === 'list') {
return model.url
}
const params = new URLSearchParams()
params.set(idParam, objectId)
if (action.name !== pageName) {