Appearance
Management Modules
Overview
The Management Modules system provides a comprehensive framework for organizing and managing different functional areas within the Admin Frontend application. Each module represents a distinct business domain with its own pages, components, permissions, and workflows.
Architecture
Module Structure
Each management module follows a consistent structure:
module-name/
├── pages/ # Module-specific pages
├── components/ # Module-specific components
├── store/ # Vuex store module
├── middleware/ # Route protection middleware
├── mixins/ # Module-specific mixins
└── utils/ # Module utilitiesCore Modules
1. Digital Asset Management (DAM) Module
Purpose: Manage digital assets, folders, collages, and related operations.
Key Features:
- Asset upload and management
- Folder organization
- Collage creation and management
- Search and filtering
- Sharing and permissions
Module Configuration:
javascript
{
name: 'dam',
displayName: 'Digital Asset Management',
icon: 'FolderIcon', // Custom SVG icon component from @/components/svg
route: '/:workspace_id/dam',
enabled: true,
permissions: {
view: 'can-view-dam',
create: 'can-create-assets',
edit: 'can-edit-assets',
delete: 'can-delete-assets',
share: 'can-share-assets'
},
pages: [
{
path: 'dashboard',
component: 'pages/_workspace_id/dam/dashboard/index.vue',
middleware: ['authCheck', 'checkWorkspace', 'can-access-dam-module']
},
{
path: 'folders',
component: 'pages/_workspace_id/dam/folders/index.vue',
middleware: ['authCheck', 'checkWorkspace', 'can-access-dam-module']
},
{
path: 'collages',
component: 'pages/_workspace_id/dam/collage/index.vue',
middleware: ['authCheck', 'checkWorkspace', 'can-access-dam-module']
}
]
}Middleware: can-access-dam-module
Store Module: store/dam.js
2. Workspace Settings Module
Purpose: Manage workspace configuration, users, and settings.
Key Features:
- User management
- Workspace configuration
- Subscription and billing
- Module enablement
Module Configuration:
javascript
{
name: 'workspace-settings',
displayName: 'Workspace Settings',
icon: 'SettingsIcon', // Custom SVG icon component from @/components/svg
route: '/:workspace_id/workspace-settings',
enabled: true,
permissions: {
view: 'can-view-settings',
edit: 'can-edit-settings',
manageUsers: 'can-manage-users'
}
}Module Registration
Frontend Registration
Modules are registered in the application configuration. Note: The application uses custom SVG icon components from @/components/svg instead of Material Design Icons (MDI). Icons should be imported as Vue components.
javascript
// plugins/modules.js
import FolderIcon from '@/components/svg/FolderIcon.vue'
import SettingsIcon from '@/components/svg/SettingsIcon.vue'
export default ({ app, store, router }) => {
const modules = [
{
id: 'dam',
name: 'Digital Asset Management',
icon: 'FolderIcon', // Custom SVG icon component from @/components/svg
route: '/:workspace_id/dam',
enabled: true,
permissions: ['can-access-dam-module']
},
{
id: 'workspace-settings',
name: 'Workspace Settings',
icon: 'SettingsIcon', // Custom SVG icon component from @/components/svg
route: '/:workspace_id/workspace-settings',
enabled: true,
permissions: ['can-view-settings']
}
]
// Register modules in store
store.commit('modules/registerModules', modules)
}Module Store
javascript
// store/modules.js
export const state = () => ({
modules: [],
activeModule: null,
modulePermissions: {}
})
export const mutations = {
registerModules(state, modules) {
state.modules = modules
},
setActiveModule(state, module) {
state.activeModule = module
},
setModulePermissions(state, { moduleId, permissions }) {
state.modulePermissions[moduleId] = permissions
}
}
export const getters = {
enabledModules: (state) => {
return state.modules.filter(m => m.enabled)
},
accessibleModules: (state, getters, rootState) => {
const userPermissions = rootState.auth.user?.permissions || []
return state.modules.filter(module => {
if (!module.enabled) return false
if (!module.permissions || module.permissions.length === 0) return true
return module.permissions.some(perm => userPermissions.includes(perm))
})
},
hasModuleAccess: (state) => (moduleId) => {
const module = state.modules.find(m => m.id === moduleId)
if (!module || !module.enabled) return false
return true
}
}Module Navigation
Navigation Component
vue
<template>
<v-navigation-drawer v-model="drawer" app>
<v-list>
<v-list-item
v-for="module in accessibleModules"
:key="module.id"
:to="getModuleRoute(module)"
:disabled="!hasModuleAccess(module.id)"
>
<v-list-item-icon>
<v-icon>{{ module.icon }}</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title>{{ module.name }}</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
</v-navigation-drawer>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
computed: {
...mapGetters('modules', ['accessibleModules', 'hasModuleAccess']),
drawer: {
get() {
return this.$store.state.ui.drawer
},
set(value) {
this.$store.commit('ui/setDrawer', value)
}
}
},
methods: {
getModuleRoute(module) {
const workspaceId = this.$route.params.workspace_id
return module.route.replace(':workspace_id', workspaceId)
}
}
}
</script>Module Access Control
Middleware Implementation
javascript
// middleware/can-access-module.js
export default async function ({ route, store, redirect, $auth }) {
const moduleId = route.meta?.moduleId
if (!moduleId) return
// Check if module exists and is enabled
const hasAccess = store.getters['modules/hasModuleAccess'](moduleId)
if (!hasAccess) {
return redirect('/')
}
// Check user permissions
const module = store.getters['modules/enabledModules'].find(m => m.id === moduleId)
if (module && module.permissions) {
const userPermissions = $auth.user?.permissions || []
const hasPermission = module.permissions.some(perm =>
userPermissions.includes(perm)
)
if (!hasPermission) {
return redirect('/')
}
}
}Page-Level Usage
javascript
// pages/_workspace_id/dam/dashboard/index.vue
export default {
middleware: [
'authCheck',
'checkWorkspace',
'can-access-dam-module'
],
meta: {
moduleId: 'dam'
}
}Module API
Backend Module Configuration
javascript
// API: GET /api/workspaces/:workspace_id/modules
{
"modules": [
{
"id": "dam",
"name": "Digital Asset Management",
"enabled": true,
"subscription_required": true,
"permissions": {
"view": "can-view-dam",
"create": "can-create-assets",
"edit": "can-edit-assets",
"delete": "can-delete-assets"
}
},
]
}Enable/Disable Module
javascript
// API: PUT /api/workspaces/:workspace_id/modules/:module_id
{
"enabled": true
}Workflow
Module Access Flow
1. User navigates to module route
↓
2. Middleware checks module access
↓
3. Verify module is enabled for workspace
↓
4. Check user has required permissions
↓
5. Load module-specific store
↓
6. Render module pages/components
↓
7. Apply module-specific middlewareModule Initialization Flow
1. Application starts
↓
2. Fetch workspace modules from API
↓
3. Register modules in Vuex store
↓
4. Filter modules by user permissions
↓
5. Build navigation menu
↓
6. Set active module on route changeSample Data
Module Configuration Object
javascript
{
id: "dam",
name: "Digital Asset Management",
displayName: "DAM",
description: "Manage digital assets, folders, and collages",
icon: "FolderIcon", // Custom SVG icon component from @/components/svg
route: "/:workspace_id/dam",
enabled: true,
subscription_required: true,
subscription_tier: "professional",
permissions: [
"can-access-dam-module",
"can-view-dam",
"can-create-assets",
"can-edit-assets",
"can-delete-assets",
"can-share-assets"
],
features: [
"asset-upload",
"folder-management",
"collage-creation",
"advanced-search",
"sharing"
],
limits: {
max_assets: 10000,
max_storage_gb: 100,
max_users: 50
},
pages: [
{
path: "dashboard",
name: "Dashboard",
component: "Dashboard",
middleware: ["authCheck", "can-access-dam-module"]
},
{
path: "folders",
name: "Folders",
component: "Folders",
middleware: ["authCheck", "can-access-dam-module"]
}
]
}Related Documentation
- Role-Based Access Matrix - Permission system
- Middleware Documentation - Route protection
- Pages Documentation - Page structure