Compare commits

..

No commits in common. "d0a4736a2a6b2221c7ac869ba742f5462cd5c6a3" and "27e7b748bc6c8a247ab77f5c8954f88f4a73a399" have entirely different histories.

7 changed files with 209 additions and 491 deletions

View File

@ -13,7 +13,7 @@ const props = defineProps({
} }
}); });
const emit = defineEmits(['close', 'upload', 'update:visible']); const emit = defineEmits(['close', 'upload']);
// Store // Store
const dmsStore = useDmsStore(); const dmsStore = useDmsStore();
@ -45,15 +45,14 @@ const customFields = computed(() => {
// Get tag suggestions // Get tag suggestions
const tagSuggestions = ref([]); const tagSuggestions = ref([]);
// Add a ref for the file input
const fileInput = ref(null);
// Methods // Methods
const openFileDialog = () => { const openFileDialog = () => {
// Use the ref instead of creating a new input element const input = document.createElement('input');
if (fileInput.value) { input.type = 'file';
fileInput.value.click(); input.multiple = true;
} input.accept = dmsStore.systemSettings.upload.allowedFileTypes.map(ext => `.${ext}`).join(',');
input.onchange = (e) => handleFiles(Array.from(e.target.files));
input.click();
}; };
const handleFiles = (files) => { const handleFiles = (files) => {
@ -70,8 +69,7 @@ const handleFiles = (files) => {
fileMetadata.value[file.name] = { fileMetadata.value[file.name] = {
...template, ...template,
title: file.name.split('.')[0], title: file.name.split('.')[0],
author: dmsStore.currentUser.name || 'Current User', author: 'Current User' // Get from auth store
tags: [] // Ensure tags is always initialized as an array
}; };
} else { } else {
errors[file.name] = validation.errors; errors[file.name] = validation.errors;
@ -118,11 +116,6 @@ const uploadFiles = async () => {
const file = selectedFiles.value[i]; const file = selectedFiles.value[i];
const metadata = fileMetadata.value[file.name]; const metadata = fileMetadata.value[file.name];
// Ensure all required fields are present
if (!metadata.tags) metadata.tags = [];
if (!metadata.author) metadata.author = dmsStore.currentUser.name || 'Current User';
if (!metadata.department) metadata.department = dmsStore.currentUser.department || '';
// Upload with enhanced metadata // Upload with enhanced metadata
await dmsStore.uploadFileWithMetadata(file, metadata, props.currentPath); await dmsStore.uploadFileWithMetadata(file, metadata, props.currentPath);
@ -133,7 +126,7 @@ const uploadFiles = async () => {
closeDialog(); closeDialog();
} catch (error) { } catch (error) {
console.error('Upload failed:', error); console.error('Upload failed:', error);
alert(`Upload failed: ${error.message || 'Unknown error'}`); // Show error to user
} finally { } finally {
isUploading.value = false; isUploading.value = false;
} }
@ -144,7 +137,6 @@ const closeDialog = () => {
fileMetadata.value = {}; fileMetadata.value = {};
validationErrors.value = {}; validationErrors.value = {};
uploadProgress.value = 0; uploadProgress.value = 0;
emit('update:visible', false);
emit('close'); emit('close');
}; };
@ -186,25 +178,14 @@ const handleTagInput = (fileName, input) => {
}; };
const addTag = (fileName, tag) => { const addTag = (fileName, tag) => {
if (!tag || tag.trim() === '') return; if (!fileMetadata.value[fileName].tags.includes(tag)) {
fileMetadata.value[fileName].tags.push(tag);
// Initialize tags array if it doesn't exist
if (!fileMetadata.value[fileName].tags) {
fileMetadata.value[fileName].tags = [];
} }
// Only add if tag isn't empty and not already in the array
if (!fileMetadata.value[fileName].tags.includes(tag.trim())) {
fileMetadata.value[fileName].tags.push(tag.trim());
}
tagSuggestions.value = []; tagSuggestions.value = [];
}; };
const removeTag = (fileName, tagIndex) => { const removeTag = (fileName, tagIndex) => {
if (fileMetadata.value[fileName]?.tags) { fileMetadata.value[fileName].tags.splice(tagIndex, 1);
fileMetadata.value[fileName].tags.splice(tagIndex, 1);
}
}; };
// Watch for template changes // Watch for template changes
@ -241,35 +222,10 @@ const getFieldComponent = (fieldType) => {
return 'text'; return 'text';
} }
}; };
onMounted(() => {
// Ensure fileMetadata is initialized correctly for each selected file
selectedFiles.value.forEach(file => {
if (!fileMetadata.value[file.name]) {
const template = dmsStore.metadataTemplates[metadataTemplate.value];
fileMetadata.value[file.name] = {
...template,
title: file.name.split('.')[0],
tags: [],
author: dmsStore.currentUser.name || 'Current User'
};
}
});
});
</script> </script>
<template> <template>
<rs-modal :visible="visible" @close="closeDialog" size="4xl"> <rs-modal :visible="visible" @close="closeDialog" size="4xl">
<!-- Hidden file input for better browser compatibility -->
<input
type="file"
ref="fileInput"
@change="(e) => handleFiles(Array.from(e.target.files))"
multiple
class="hidden"
:accept="dmsStore.systemSettings.upload.allowedFileTypes.map(ext => `.${ext}`).join(',')"
/>
<template #header> <template #header>
<div class="flex items-center space-x-2"> <div class="flex items-center space-x-2">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
@ -445,7 +401,7 @@ onMounted(() => {
</div> </div>
<!-- Selected Tags --> <!-- Selected Tags -->
<div v-if="fileMetadata[file.name]?.tags && fileMetadata[file.name].tags.length > 0" <div v-if="fileMetadata[file.name].tags && fileMetadata[file.name].tags.length > 0"
class="flex flex-wrap gap-2"> class="flex flex-wrap gap-2">
<span v-for="(tag, tagIndex) in fileMetadata[file.name].tags" :key="tagIndex" <span v-for="(tag, tagIndex) in fileMetadata[file.name].tags" :key="tagIndex"
class="inline-flex items-center px-2 py-1 text-xs bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-300 rounded-full"> class="inline-flex items-center px-2 py-1 text-xs bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-300 rounded-full">

View File

@ -40,7 +40,6 @@ const accessRequestItem = ref(null);
const isRequestingAccess = ref(false); const isRequestingAccess = ref(false);
const requestSuccess = ref(false); const requestSuccess = ref(false);
const requestError = ref(null); const requestError = ref(null);
const parentType = ref('root'); // root, cabinet, drawer, folder
// Navigation history for back/forward functionality // Navigation history for back/forward functionality
const navigationHistory = ref([props.initialPath]); const navigationHistory = ref([props.initialPath]);
@ -307,47 +306,25 @@ const goForward = () => {
const navigateTo = (path) => { const navigateTo = (path) => {
if (path !== currentPath.value) { if (path !== currentPath.value) {
// Add current path to history if not navigating with back/forward buttons // Remove any forward history if we're navigating to a new path
if (historyIndex.value === navigationHistory.value.length - 1) { if (historyIndex.value < navigationHistory.value.length - 1) {
navigationHistory.value.push(path);
historyIndex.value++;
} else {
// If navigating from a back/forward position, truncate history
navigationHistory.value = navigationHistory.value.slice(0, historyIndex.value + 1); navigationHistory.value = navigationHistory.value.slice(0, historyIndex.value + 1);
navigationHistory.value.push(path);
historyIndex.value++;
} }
// Add new path to history
navigationHistory.value.push(path);
historyIndex.value = navigationHistory.value.length - 1;
currentPath.value = path; currentPath.value = path;
// Auto-expand tree to show current path
autoExpandTreeForPath(path);
emit('pathChanged', path); emit('pathChanged', path);
// Update parent type based on the path
updateParentType(path);
// Refresh items for the new path
loadItems();
}
};
// Update parent type based on the current path
const updateParentType = (path) => {
if (path === '/') {
parentType.value = 'root';
} else {
// Find the last container in the path
const pathParts = path.split('/').filter(Boolean);
if (pathParts.length === 0) {
parentType.value = 'root';
} else if (pathParts.length === 1) {
parentType.value = 'cabinet';
} else if (pathParts.length === 2) {
parentType.value = 'drawer';
} else {
parentType.value = 'folder';
}
} }
}; };
// Auto-expand tree items to show the current path
const autoExpandTreeForPath = (path) => { const autoExpandTreeForPath = (path) => {
const segments = path.split('/').filter(Boolean); const segments = path.split('/').filter(Boolean);
segments.forEach((segment, index) => { segments.forEach((segment, index) => {
@ -532,18 +509,10 @@ const getAccessTypeCount = (accessType) => {
}; };
// Lifecycle hooks // Lifecycle hooks
onMounted(async () => { onMounted(() => {
// Load items loadItems();
await loadItems();
// Set initial parent type
updateParentType(currentPath.value);
// Auto-expand tree for initial path // Auto-expand tree for initial path
autoExpandTreeForPath(currentPath.value); autoExpandTreeForPath(currentPath.value);
// Mark as loaded
isLoading.value = false;
}); });
const getTabClasses = (tab) => { const getTabClasses = (tab) => {
@ -769,9 +738,14 @@ const breadcrumbs = computed(() => {
return breadcrumbItems; return breadcrumbItems;
}); });
const getCurrentContainerType = () => { const parentType = computed(() => {
return parentType.value; const pathParts = currentPath.value.split('/').filter(Boolean);
}; if (pathParts.length === 0) return 'root';
if (pathParts.length === 1) return 'cabinet';
if (pathParts.length === 2) return 'drawer';
if (pathParts.length === 3) return 'folder';
return 'subfolder';
});
</script> </script>
<template> <template>
@ -1437,9 +1411,7 @@ const getCurrentContainerType = () => {
<!-- Create New Dialog --> <!-- Create New Dialog -->
<DMSCreateNewDialog <DMSCreateNewDialog
v-model:visible="showCreateDialog" v-if="showCreateDialog"
:current-path="currentPath"
:parent-type="getCurrentContainerType()"
@close="showCreateDialog = false" @close="showCreateDialog = false"
@create="handleCreateNew" @create="handleCreateNew"
/> />

View File

@ -21,7 +21,7 @@ The Document Management System (DMS) Settings provides administrators with compl
## Access & Navigation ## Access & Navigation
### Prerequisites ### Prerequisites
- **Administrative Privileges**: Only users with Superadmin or Admin roles can access DMS settings - **Administrative Privileges**: Only users with admin roles can access DMS settings
- **Browser Requirements**: Modern browser with JavaScript enabled - **Browser Requirements**: Modern browser with JavaScript enabled
- **Network Access**: Stable connection to the EDMS server - **Network Access**: Stable connection to the EDMS server
@ -37,7 +37,7 @@ The Document Management System (DMS) Settings provides administrators with compl
- **Action Buttons**: Save, Export, Import, and Reset options in the header - **Action Buttons**: Save, Export, Import, and Reset options in the header
3. **Permission Verification**: 3. **Permission Verification**:
- System automatically verifies Superadmin/Admin permissions - System automatically verifies admin permissions
- Unauthorized users are redirected to main DMS interface - Unauthorized users are redirected to main DMS interface
- Error messages displayed for access issues - Error messages displayed for access issues
@ -85,52 +85,25 @@ The DMS settings are organized into six main categories, each with a distinct ic
### User Roles Configuration ### User Roles Configuration
#### Default System Roles #### Default Roles
The system comes with three default user roles: The system comes with four default user roles:
- **Superadmin**: Full system access with all administrative privileges - **Admin**: Full system access and administrative privileges
- **Admin**: Administrative access to manage documents, access requests, and some settings - **Editor**: Create, edit, and manage documents with approval capabilities
- **User**: Standard access for viewing, uploading, and managing personal documents - **Viewer**: Read-only access to assigned documents
- **Uploader**: Upload documents with basic editing capabilities
#### Role Capabilities #### Adding Custom Roles
1. **Navigate to User Roles section**
2. **Click "Add Role" button**
3. **Enter role name** in the prompt dialog
4. **Role automatically added** to the list
5. **Save settings** to persist changes
##### Superadmin Role #### Removing Roles
- **Color Scheme**: Purple 1. **Locate role** in the roles list
- **Description**: Full system access with ability to manage all settings, users, and content 2. **Click delete button** (trash icon) next to role name
- **Key Capabilities**: 3. **Confirm deletion** (role removed from all users)
- User and role management through Authentik integration 4. **Save settings** to persist changes
- Full system settings configuration
- Complete document management
- Access to all system areas including Pentadbiran
- Role management authority
- System monitoring and maintenance
##### Admin Role
- **Color Scheme**: Blue
- **Description**: Administrative access to manage content and some system settings
- **Key Capabilities**:
- Document management and organization
- Access request processing
- View KPI dashboard and metrics
- Some system configuration access
- Cannot access Pentadbiran section
- Cannot manage user roles
##### User Role
- **Color Scheme**: Green
- **Description**: Standard user access for viewing and interacting with content based on permissions
- **Key Capabilities**:
- View permitted documents
- Upload personal documents
- Request access to restricted content
- Manage personal documents
- No administrative access
#### Role Switching
The system includes a role switching capability for testing and administrative purposes:
1. Navigate to **Switch Role** in the DMS menu
2. Select the desired role from the available options
3. Apply the temporary role change
4. Return to original role when finished
### Permission Configuration ### Permission Configuration
@ -143,40 +116,50 @@ Configure specific permissions for different user levels:
- **Impact**: Controls document visibility - **Impact**: Controls document visibility
- **Edit Documents**: - **Edit Documents**:
- **Default**: Enabled for all roles - **Default**: Enabled for Admin/Editor roles
- **Purpose**: Modify document content and metadata - **Purpose**: Modify document content and metadata
- **Impact**: Affects document modification capabilities - **Impact**: Affects document modification capabilities
- **Delete Documents**: - **Delete Documents**:
- **Default**: Enabled for Superadmin and Admin roles only - **Default**: Disabled (Admin only)
- **Purpose**: Remove documents from system - **Purpose**: Remove documents from system
- **Impact**: Permanent document removal access - **Impact**: Permanent document removal access
- **Download Documents**: - **Download Documents**:
- **Default**: Enabled for all roles - **Default**: Enabled for most roles
- **Purpose**: Save documents locally - **Purpose**: Save documents locally
- **Impact**: Controls offline document access - **Impact**: Controls offline document access
- **Share Documents**: - **Share Documents**:
- **Default**: Enabled for all roles - **Default**: Enabled for Admin/Editor roles
- **Purpose**: Share documents with other users - **Purpose**: Share documents with other users
- **Impact**: Affects collaboration capabilities - **Impact**: Affects collaboration capabilities
- **Approve Access Requests**:
- **Default**: Enabled for Superadmin and Admin roles only
- **Purpose**: Process access request workflows
- **Impact**: Controls access approval workflow
### Authentication Configuration ### Authentication Configuration
#### Authentik Integration #### Single Sign-On (SSO)
- **Purpose**: Centralized identity and access management - **Purpose**: Integrate with organizational authentication systems
- **Configuration**: - **Supported Providers**: LDAP, Active Directory, OAuth providers
- Enable/disable Authentik integration - **Configuration**: Enable/disable SSO functionality
- Configure connection parameters - **Impact**: Streamlines user authentication process
- Map Authentik groups to system roles
- **User Experience**: Single sign-on with role-based permissions #### Multi-Factor Authentication (MFA)
- **Management**: User account provisioning and deprovisioning - **Purpose**: Enhanced security for sensitive environments
- **Methods**: SMS, email, authenticator apps
- **Configuration**: Require MFA for all users or specific roles
- **Impact**: Significantly improves account security
#### LDAP Integration
- **Purpose**: Synchronize with enterprise directory services
- **Features**: User import, group synchronization, automatic provisioning
- **Configuration**: Enable/disable LDAP authentication
- **Impact**: Centralizes user management
#### Session Management
- **Session Timeout**: Configure automatic logout (1-24 hours)
- **Default**: 8 hours
- **Security Impact**: Balances security with user convenience
- **Compliance**: Helps meet organizational security policies
## Document & Folder Settings ## Document & Folder Settings

View File

@ -49,7 +49,7 @@ Site settings affect the entire application including:
- **Backup & Restore**: Export/import configuration for backup and migration - **Backup & Restore**: Export/import configuration for backup and migration
### Administrative Features ### Administrative Features
- **Role-Based Access**: Only Superadmin users can modify site settings - **Role-Based Access**: Only administrators can modify site settings
- **Validation System**: Comprehensive validation for all settings - **Validation System**: Comprehensive validation for all settings
- **File Upload Management**: Secure file upload for logos and assets - **File Upload Management**: Secure file upload for logos and assets
- **Version Control**: Track changes and maintain configuration history - **Version Control**: Track changes and maintain configuration history
@ -58,7 +58,7 @@ Site settings affect the entire application including:
## Accessing Site Settings ## Accessing Site Settings
### Prerequisites ### Prerequisites
- **Administrative Privileges**: User must have Superadmin role - **Administrative Privileges**: User must have admin role
- **Modern Browser**: Chrome 70+, Firefox 65+, Safari 12+, Edge 79+ - **Modern Browser**: Chrome 70+, Firefox 65+, Safari 12+, Edge 79+
- **JavaScript Enabled**: Required for interactive functionality - **JavaScript Enabled**: Required for interactive functionality
- **Network Access**: Stable connection for file uploads and saves - **Network Access**: Stable connection for file uploads and saves
@ -69,12 +69,6 @@ Site settings affect the entire application including:
3. **Site Settings**: Choose **Site Settings** from the submenu 3. **Site Settings**: Choose **Site Settings** from the submenu
4. **Alternative Access**: Direct URL navigation to `/admin/site-settings` 4. **Alternative Access**: Direct URL navigation to `/admin/site-settings`
### Permission Requirements
- **Available to**: Superadmin role only
- **Admin users**: Cannot access Site Settings (limited to DMS Settings)
- **Regular users**: No access to any settings pages
- **Access control**: Implemented through navigation meta tags and server-side verification
### Interface Layout ### Interface Layout
- **Tabbed Interface**: Basic Info, Branding, SEO, Advanced settings - **Tabbed Interface**: Basic Info, Branding, SEO, Advanced settings
- **Live Preview Panel**: Real-time preview of changes - **Live Preview Panel**: Real-time preview of changes

View File

@ -26,7 +26,7 @@ The Electronic Document Management System (EDMS) is a modern web application bui
- **Database**: Prisma ORM with MySQL support and comprehensive schema - **Database**: Prisma ORM with MySQL support and comprehensive schema
- **Styling**: TailwindCSS with custom Rs component system - **Styling**: TailwindCSS with custom Rs component system
- **State Management**: Pinia for reactive state management with persistence - **State Management**: Pinia for reactive state management with persistence
- **Authentication**: Flexible authentication with Authentik integration and role-based access control - **Authentication**: Flexible authentication with JWT tokens and RBAC
- **File Management**: Server-side file handling with metadata and versioning - **File Management**: Server-side file handling with metadata and versioning
- **Real-time Features**: Vue reactivity for live updates and notifications - **Real-time Features**: Vue reactivity for live updates and notifications
- **Responsive Design**: Mobile-first approach with adaptive layouts - **Responsive Design**: Mobile-first approach with adaptive layouts
@ -398,67 +398,45 @@ npm run dev
## Component Structure ## Component Structure
### Core Components ### Frontend Architecture
```
pages/
├── dms/
│ ├── index.vue # Main DMS interface with access level tabs
│ ├── settings.vue # Comprehensive DMS settings management
│ └── erd.vue # Entity Relationship Diagram viewer
├── index.vue # Dashboard/landing page
└── [...other pages]
The EDMS is organized into several key component directories: components/
├── dms/
│ └── explorer/
│ └── DMSExplorer.vue # Document management interface
├── Rs/ # Reusable component system
│ ├── RsButton.vue
│ ├── RsCard.vue
│ ├── RsInput.vue
│ └── [...other components]
└── layouts/
└── Breadcrumb.vue # Navigation breadcrumb component
#### DMS Explorer Components composables/
- **`components/dms/explorer/`**: Main document exploration interface ├── useDmsSettings.js # DMS settings state management
- `DMSExplorer.vue`: Main document explorer component with folder navigation and document viewing ├── useSiteSettings.js # Site configuration management
- `DMSFileViewer.vue`: Document preview and viewing component └── [...other composables]
- `DMSNavigation.vue`: Navigation tree and breadcrumbs
- `DMSSearchBar.vue`: Advanced search component
#### Dialog Components stores/
- **`components/dms/dialogs/`**: Modal dialogs for user interactions ├── dms.js # DMS-specific Pinia store
- `DMSUploadDialog.vue`: File upload with metadata tagging and validation └── [...other stores]
- `DMSCreateNewDialog.vue`: Create new cabinets, drawers, folders and subfolders ```
- `DMSAccessRequestDialog.vue`: Request access to restricted content
- `DMSAccessApprovalDialog.vue`: Approve/reject access requests with notes
#### Access Management Components ### Rs Component System
- **`components/dms/workflows/`**: Access control and workflows The EDMS uses a custom component library (Rs components) for consistent UI:
- `DMSAccessRequestTracker.vue`: KPI tracking for access requests with metrics visualization - **RsButton**: Standardized button component with variants
- `DMSApprovalQueue.vue`: Access request approval management interface - **RsCard**: Card container with header/body/footer slots
- `DMSRoleManager.vue`: Role management interface with Authentik integration - **RsInput**: Form input components with validation
- **RsModal**: Modal dialog components
#### Admin Components - **RsTable**: Data table components with sorting/filtering
- **`components/dms/admin/`**: Administrative interfaces
- `DMSAdminDashboard.vue`: KPI metrics and system overview with performance charts
- `DMSAccessManagement.vue`: Comprehensive access management for documents
- `DMSSystemSettings.vue`: System configuration interface
### Page Components
The system includes several key page components:
#### Main DMS Pages
- **`pages/dms/index.vue`**: Main document explorer page
- **`pages/dms/admin-dashboard.vue`**: Administrative dashboard with KPIs
- **`pages/dms/access-management.vue`**: Access request management interface
- **`pages/dms/role-management.vue`**: Role-based access control management
- **`pages/dms/switch-roles.vue`**: Role switching for testing and administrative purposes
- **`pages/dms/settings.vue`**: DMS settings configuration
### Store Implementation
State management is handled through Pinia stores:
#### DMS Store
- **`stores/dms.js`**: Core DMS functionality and state management
- User information and authentication
- Document and cabinet management
- Role-based access control
- Access request workflows
- System settings and configuration
- File uploads and metadata management
#### Global Store
- **`stores/global.js`**: Application-wide state management
- Theme and UI preferences
- Global notifications
- Application state
- User session management
## API & Data Management ## API & Data Management
@ -745,113 +723,27 @@ Site settings are integrated throughout the application:
## Security & Authentication ## Security & Authentication
### Authentication System ### Authentication Methods
- **Local Authentication**: Username/password with bcrypt hashing
- **JWT Tokens**: Secure token-based authentication
- **Session Management**: Configurable session timeouts
- **Multi-Factor Authentication**: Optional MFA support
- **LDAP Integration**: Enterprise directory integration
- **SSO Support**: Single Sign-On capabilities
The EDMS implements a comprehensive authentication and authorization system using Authentik integration for identity management and a three-tier role-based access control model. ### Authorization & RBAC
- **Role-Based Access Control**: Granular permission system
- **Dynamic Permissions**: Configurable permission sets
- **Resource-Level Security**: Document-level access control
- **Access Request Workflow**: Formal access request process
- **Audit Trail**: Comprehensive activity logging
#### Authentik Integration ### Data Security
- **Input Validation**: Server-side validation for all inputs
Authentik is used as the identity provider with the following implementation: - **SQL Injection Prevention**: Prisma ORM parameter binding
- **XSS Protection**: Content Security Policy and input sanitization
```javascript - **File Upload Security**: File type validation and virus scanning
// Authentication integration in stores/dms.js - **Encryption**: Data encryption at rest and in transit
async authenticateWithAuthentik(username, password) {
// In production, this connects to the Authentik API
// The implementation here is a placeholder for demonstration
// Authenticate and receive user profile with role information
// Returns user object with role (superadmin, admin, or user)
}
```
#### User Roles and Permissions
The system implements three core roles with distinct permission levels:
```javascript
// Role definitions in stores/dms.js
systemRoles: [
{
id: 'superadmin',
name: 'Super Administrator',
description: 'Full system access with ability to manage all settings, users, and content',
color: 'purple'
},
{
id: 'admin',
name: 'Administrator',
description: 'Administrative access to manage content and some system settings',
color: 'blue'
},
{
id: 'user',
name: 'User',
description: 'Standard user access for viewing and interacting with content based on permissions',
color: 'green'
}
]
```
Role-based permissions are implemented through the `getRbacPermissions` method:
```javascript
// RBAC permissions implementation
async getRbacPermissions(userId) {
// In production, this fetches permissions from Authentik
// Returns permission object with granular access controls
return {
roles: ['superadmin' | 'admin' | 'user'],
permissions: {
documents: { view, edit, delete, approve, reject, download },
cabinets: { view, create, edit, delete },
accessRequests: { approve, reject, viewAll },
systemSettings: { manage },
users: { manage },
roles: { manage }
}
};
}
```
### Navigation Authorization
The navigation system enforces role-based access through meta tags:
```javascript
// Role-based navigation in navigation/index.js
{
"title": "Admin Dashboard",
"path": "/dms/admin-dashboard",
"icon": "material-symbols:dashboard",
"meta": {
"auth": {
"role": ["admin", "superadmin"] // Only these roles can access
}
}
}
```
### Role Switching
For testing and administrative purposes, the system includes a role switching component:
```vue
// Role switching implementation in pages/dms/switch-roles.vue
<script setup>
// Component for switching between Superadmin, Admin, and User roles
// Preserves the original role for restoration
</script>
```
### Secure Storage
User credentials and sensitive information are handled securely:
1. **Token Storage**: JWT tokens stored in HTTP-only cookies
2. **Password Handling**: Passwords never stored in the browser
3. **Session Management**: Auto-logout after configurable inactivity period
4. **Credential Transmission**: All authentication requests over HTTPS
## Deployment ## Deployment

View File

@ -5,7 +5,7 @@
2. [Getting Started](#getting-started) 2. [Getting Started](#getting-started)
3. [Navigation](#navigation) 3. [Navigation](#navigation)
4. [DMS Interface](#dms-interface) 4. [DMS Interface](#dms-interface)
5. [Role-Based Access Control](#role-based-access-control) 5. [Access Level System](#access-level-system)
6. [Document Organization](#document-organization) 6. [Document Organization](#document-organization)
7. [Working with Documents](#working-with-documents) 7. [Working with Documents](#working-with-documents)
8. [DMS Settings (Administrators)](#dms-settings-administrators) 8. [DMS Settings (Administrators)](#dms-settings-administrators)
@ -21,7 +21,6 @@ The Electronic Document Management System (EDMS) is a modern web-based platform
- **Access Level Organization**: Documents categorized as All, Public, Private, and Personal with color-coded tabs - **Access Level Organization**: Documents categorized as All, Public, Private, and Personal with color-coded tabs
- **Hierarchical Structure**: Documents organized in a Cabinet → Drawer → Folder → Subfolder structure - **Hierarchical Structure**: Documents organized in a Cabinet → Drawer → Folder → Subfolder structure
- **Multiple View Modes**: List, Grid, and Details views for browsing documents - **Multiple View Modes**: List, Grid, and Details views for browsing documents
- **Role-Based Access Control**: Three-tier role system (Superadmin, Admin, User) with granular permissions
- **Advanced Settings Management**: Comprehensive configuration system for administrators - **Advanced Settings Management**: Comprehensive configuration system for administrators
- **Document Viewer**: Built-in viewer supporting multiple file formats (PDF, images, text files, spreadsheets) - **Document Viewer**: Built-in viewer supporting multiple file formats (PDF, images, text files, spreadsheets)
- **Search Functionality**: Advanced search across document titles, descriptions, and metadata - **Search Functionality**: Advanced search across document titles, descriptions, and metadata
@ -129,71 +128,46 @@ The main DMS interface features a modern tabbed design for easy navigation betwe
- **Loading States**: Visual feedback during system operations - **Loading States**: Visual feedback during system operations
- **Error Handling**: Clear error messages with retry options - **Error Handling**: Clear error messages with retry options
## Role-Based Access Control ## Access Level System
### Understanding System Roles ### Understanding Access Levels
The EDMS implements a three-tier role system to manage access to system features and functionality: #### Public Documents
- **Accessibility**: Visible and accessible to all system users
- **Visual Indicator**: Green color theme with unlock icon
- **Permissions**: No special permissions or approvals required
- **Best For**:
- Company policies and procedures
- Public announcements
- Shared templates and forms
- General information documents
#### Superadmin Role #### Private Documents
- **Access Level**: Complete system access with no restrictions - **Accessibility**: Restricted access requiring specific permissions
- **Visual Indicator**: Purple color theme in the interface - **Visual Indicator**: Red color theme with lock icon
- **Capabilities**: - **Permissions**: May require access request and approval workflow
- Full system administration and configuration - **Best For**:
- User and role management - Confidential business information
- Complete access to all documents and folders - HR records and sensitive data
- System settings management - Financial documents
- Access to Pentadbiran (administration) section - Executive communications
- Ability to create, modify, and delete any content - Legal documents
- Approval/rejection of access requests
- Role management through Authentik integration
#### Admin Role #### Personal Documents
- **Access Level**: Administrative access with some restrictions - **Accessibility**: Documents owned and controlled by individual users
- **Visual Indicator**: Blue color theme in the interface - **Visual Indicator**: Purple color theme with user icon
- **Capabilities**: - **Permissions**: Full control over sharing and access
- Document management and organization - **Best For**:
- Access to Admin Dashboard with KPI metrics - Individual workspace documents
- View and process access requests - Draft documents before publication
- Create and manage content - Personal notes and references
- Access management for users - Work-in-progress files
- Some system settings configuration
- Cannot manage user roles or access the Pentadbiran section
#### User Role ### Access Level Switching
- **Access Level**: Standard user access with basic permissions - Click any access level tab to filter documents by that category
- **Visual Indicator**: Green color theme in the interface - Visual feedback shows which tab is currently active
- **Capabilities**: - Document count may vary between tabs based on your permissions
- View documents based on permissions - Some tabs may be empty if no documents exist in that category
- Upload and edit documents (own documents)
- Request access to restricted content
- Basic search and navigation
- Personal document management
- Cannot access administrative features
### Role Switching
For testing and administrative purposes, the system includes a role switching feature:
1. **Access the Role Switcher**:
- Navigate to "Switch Role" in the DMS menu
- Current role is displayed at the top of the page
2. **Temporary Role Change**:
- Select the desired role (Superadmin, Admin, or User)
- Click "Switch to Selected Role"
- A temporary session with the new role permissions is created
3. **Returning to Original Role**:
- Click "Revert to Original Role" to return to your assigned permissions
- The system will restore your original access level
### Permission Inheritance
Permissions in the system follow a hierarchical inheritance pattern:
- Superadmin permissions include all Admin and User permissions
- Admin permissions include all User permissions
- Each higher role level has additional specialized capabilities
## Document Organization ## Document Organization
@ -224,57 +198,25 @@ The system uses color coding and icons to indicate access levels:
### Uploading Documents ### Uploading Documents
The system provides a comprehensive document upload interface with metadata tagging: #### Single File Upload
1. Navigate to the desired location in the hierarchy
2. Click the "Upload" button or use the dedicated upload interface
3. Select file(s) using the file picker or drag-and-drop interface
4. Fill in comprehensive document metadata:
- Document title and description
- Keywords for enhanced searchability
- Category and current status
- Access level and specific permissions
- Department or responsible party
- Retention period and compliance information
5. Review and click "Upload" to save the document
1. **Access the Upload Dialog**: #### Bulk Upload
- Click the "Upload" button in the document explorer toolbar 1. Select multiple files using Ctrl+Click (Windows) or Cmd+Click (Mac)
- The upload dialog appears with drag-and-drop functionality 2. Assign metadata to individual files or apply common metadata to all
3. Set default properties for batch processing efficiency
2. **Select Files**: 4. Monitor upload progress with real-time status updates
- Drag files into the upload area, or 5. Review and confirm successful uploads
- Click "browse" to select files from your device
- Multiple files can be selected simultaneously
3. **Metadata Assignment**:
- For each uploaded file, complete the metadata form
- Select a document template (Standard, Contract, Report)
- Add required fields like Department, Project Code
- Add a description to help with search and context
- Add tags by typing and pressing Enter (or select from suggestions)
4. **Validation**:
- The system automatically validates file types and sizes
- Required metadata fields are marked with asterisks
- Validation errors appear if requirements aren't met
5. **Complete Upload**:
- Click "Upload" button to process files
- Progress bar shows upload status
- System provides confirmation when complete
### Creating New Items
To create new containers in the document hierarchy:
1. **Access Create Dialog**:
- Click the "Create New" button in the toolbar
- Select the desired item type from the dropdown
2. **Available Item Types**:
- Cabinet: Top-level organizational unit
- Drawer: Mid-level category container
- Folder: Specific topic container
- Subfolder: Detailed organizational unit
3. **Set Properties**:
- Enter a name for the new item
- Select an access type (Public, Private, Personal)
- Add a description (optional but recommended)
4. **Create Item**:
- Click "Create" to add the item to the current location
- New item appears in the document explorer
- Navigate into the new container by clicking on it
### Document Metadata ### Document Metadata
For each document, you can specify comprehensive metadata based on system configuration: For each document, you can specify comprehensive metadata based on system configuration:

View File

@ -120,41 +120,17 @@ const showAdminDashboard = computed(() => {
return ['admin', 'superadmin'].includes(store.currentUser?.role); return ['admin', 'superadmin'].includes(store.currentUser?.role);
}); });
// Event handlers for DMSExplorer component interactions // Event handlers (placeholder functions for when components load)
const handleItemSelected = (item) => { const handleItemSelected = (item) => {
if (DMSExplorer && item) { console.log('Item selected:', item);
// The explorer component already handles file opening and navigation
console.log('Item selected:', item);
}
}; };
const handleViewModeChanged = (mode) => { const handleViewModeChanged = (mode) => {
if (DMSExplorer) { console.log('View mode changed to:', mode);
console.log('View mode changed to:', mode);
}
}; };
const handlePathChanged = (path) => { const handlePathChanged = (path) => {
if (DMSExplorer) { console.log('Path changed to:', path);
console.log('Path changed to:', path);
}
};
// Handle uploaded files
const handleUploadCompleted = (files) => {
console.log('Files uploaded:', files);
// The explorer component already handles refreshing the view
};
// Handle create new item
const handleItemCreated = (item) => {
console.log('New item created:', item);
// The explorer component already handles refreshing the view
};
// Handle access request submitted
const handleAccessRequestSubmitted = (request) => {
console.log('Access request submitted:', request);
}; };
// Lifecycle hooks // Lifecycle hooks
@ -250,6 +226,17 @@ onMounted(() => {
</svg> </svg>
Admin Dashboard Admin Dashboard
</NuxtLink> </NuxtLink>
<!-- Switch Role Button -->
<NuxtLink
to="/dms/switch-roles"
class="inline-flex items-center px-3 py-1.5 border border-indigo-300 dark:border-indigo-600 rounded-md text-sm font-medium text-indigo-700 dark:text-indigo-300 bg-white dark:bg-gray-800 hover:bg-indigo-50 dark:hover:bg-indigo-900/10 transition-colors"
>
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-1.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" />
</svg>
Switch Role
</NuxtLink>
</div> </div>
</div> </div>
</div> </div>
@ -320,16 +307,11 @@ onMounted(() => {
<!-- Action Buttons --> <!-- Action Buttons -->
<div class="px-6 py-3 bg-white dark:bg-gray-900/10 border-b border-gray-200 dark:border-gray-700 flex items-center justify-between"> <div class="px-6 py-3 bg-white dark:bg-gray-900/10 border-b border-gray-200 dark:border-gray-700 flex items-center justify-between">
<div class="flex space-x-2"> <div class="flex space-x-2">
<h2 class="text-lg font-medium text-gray-800 dark:text-gray-200"> <!-- Placeholder for future actions -->
{{ activeTab === 'all' ? 'All Documents' :
activeTab === 'public' ? 'Public Documents' :
activeTab === 'private' ? 'Private Documents' :
'Personal Documents' }}
</h2>
</div> </div>
<div class="flex space-x-2"> <div class="flex space-x-2">
<!-- View toggles and other action buttons will be handled by the DMSExplorer component --> <!-- Role Management button has been removed -->
</div> </div>
</div> </div>
@ -343,9 +325,6 @@ onMounted(() => {
@item-selected="handleItemSelected" @item-selected="handleItemSelected"
@view-mode-changed="handleViewModeChanged" @view-mode-changed="handleViewModeChanged"
@path-changed="handlePathChanged" @path-changed="handlePathChanged"
@upload-completed="handleUploadCompleted"
@item-created="handleItemCreated"
@access-request-submitted="handleAccessRequestSubmitted"
/> />
<!-- Fallback Content --> <!-- Fallback Content -->