generated from corrad-software/corrad-af-2024
791 lines
23 KiB
JavaScript
791 lines
23 KiB
JavaScript
import { defineStore } from 'pinia';
|
|
|
|
export const useDmsStore = defineStore('dms', {
|
|
state: () => ({
|
|
// Navigation state
|
|
currentPath: '/',
|
|
pathHistory: ['/'],
|
|
historyIndex: 0,
|
|
|
|
// User information
|
|
currentUser: {
|
|
id: 'user1',
|
|
name: 'Aiman Fakhrullah',
|
|
email: 'aiman@example.com',
|
|
role: 'engineer', // engineer, admin, manager, etc.
|
|
department: 'JKR Bahagian Kejuruteraan Awam Cawangan Kota Bharu'
|
|
},
|
|
|
|
// Cabinet access types
|
|
cabinetAccessTypes: [
|
|
{ id: 'public', name: 'Public Access', icon: 'check-circle', color: 'green' },
|
|
{ id: 'personal', name: 'Personal Access', icon: 'circle-check', color: 'orange' },
|
|
{ id: 'private', name: 'Private Access', icon: 'lock', color: 'red' }
|
|
],
|
|
|
|
// Access request statuses
|
|
accessRequestStatuses: [
|
|
{ id: 'pending', name: 'Pending', color: 'orange' },
|
|
{ id: 'approved', name: 'Approved', color: 'green' },
|
|
{ id: 'rejected', name: 'Rejected', color: 'red' }
|
|
],
|
|
|
|
// Items state - in production this would be loaded from API
|
|
cabinets: [
|
|
{
|
|
id: 'public-cabinet',
|
|
name: 'Public Cabinet',
|
|
type: 'cabinet',
|
|
accessType: 'public',
|
|
children: [
|
|
{
|
|
id: 'public-cabinet-1',
|
|
name: 'Public Cabinet',
|
|
type: 'cabinet',
|
|
accessType: 'public',
|
|
parentId: 'public-cabinet'
|
|
}
|
|
]
|
|
},
|
|
{
|
|
id: 'my-cabinets',
|
|
name: 'My Cabinets',
|
|
type: 'cabinet-group',
|
|
accessType: 'personal',
|
|
children: [
|
|
{
|
|
id: 'jkr-tebedu',
|
|
name: 'JKR Cawangan Tebedu, Sarawak',
|
|
type: 'cabinet',
|
|
accessType: 'personal',
|
|
parentId: 'my-cabinets',
|
|
hasAccess: true
|
|
},
|
|
{
|
|
id: 'jkr-kota-bharu',
|
|
name: 'JKR Cawangan Kota Bharu, Kelantan',
|
|
type: 'cabinet',
|
|
accessType: 'personal',
|
|
parentId: 'my-cabinets',
|
|
hasAccess: true,
|
|
children: [
|
|
{
|
|
id: 'jkr-kewangan-kb',
|
|
name: 'JKR Bahagian Kewangan Cawangan Kota Bharu',
|
|
type: 'cabinet',
|
|
accessType: 'personal',
|
|
parentId: 'jkr-kota-bharu',
|
|
hasAccess: true
|
|
},
|
|
{
|
|
id: 'jkr-kejuruteraan-kb',
|
|
name: 'JKR Bahagian Kejuruteraan Awam Cawangan Kota Bharu',
|
|
type: 'cabinet',
|
|
accessType: 'personal',
|
|
parentId: 'jkr-kota-bharu',
|
|
hasAccess: true,
|
|
children: [
|
|
{
|
|
id: 'pembinaan-jambatan-kb',
|
|
name: 'Pembinaan Jambatan Kota Bharu',
|
|
type: 'cabinet',
|
|
accessType: 'personal',
|
|
parentId: 'jkr-kejuruteraan-kb',
|
|
hasAccess: true,
|
|
children: [
|
|
{
|
|
id: 'kewangan-tag',
|
|
name: 'Kewangan',
|
|
type: 'tag',
|
|
color: 'purple',
|
|
parentId: 'pembinaan-jambatan-kb'
|
|
},
|
|
{
|
|
id: 'kejuruteraan-awam-tag',
|
|
name: 'Kejuruteraan Awam',
|
|
type: 'tag',
|
|
color: 'purple',
|
|
parentId: 'pembinaan-jambatan-kb'
|
|
},
|
|
{
|
|
id: 'teknologi-maklumat-tag',
|
|
name: 'Teknologi Maklumat',
|
|
type: 'tag',
|
|
color: 'purple',
|
|
parentId: 'pembinaan-jambatan-kb'
|
|
}
|
|
]
|
|
},
|
|
{
|
|
id: 'projek-jalan-raya-kb',
|
|
name: 'Projek Jalan Raya Kota Bharu',
|
|
type: 'cabinet',
|
|
accessType: 'personal',
|
|
parentId: 'jkr-kejuruteraan-kb',
|
|
hasAccess: true
|
|
}
|
|
]
|
|
},
|
|
{
|
|
id: 'jkr-teknologi-kb',
|
|
name: 'JKR Bahagian Teknologi Maklumat Cawangan Kota Bharu',
|
|
type: 'cabinet',
|
|
accessType: 'personal',
|
|
parentId: 'jkr-kota-bharu',
|
|
hasAccess: true
|
|
}
|
|
]
|
|
},
|
|
{
|
|
id: 'jkr-ipoh',
|
|
name: 'JKR Cawangan Ipoh, Perak',
|
|
type: 'cabinet',
|
|
accessType: 'personal',
|
|
parentId: 'my-cabinets',
|
|
hasAccess: true
|
|
}
|
|
]
|
|
},
|
|
{
|
|
id: 'private-cabinets',
|
|
name: 'Private Cabinets',
|
|
type: 'cabinet-group',
|
|
accessType: 'private',
|
|
children: [
|
|
{
|
|
id: 'jkr-batu-kawan',
|
|
name: 'JKR Cawangan Batu Kawan, Penang',
|
|
type: 'cabinet',
|
|
accessType: 'private',
|
|
parentId: 'private-cabinets',
|
|
hasAccess: false,
|
|
accessRequestStatus: 'pending'
|
|
},
|
|
{
|
|
id: 'jkr-kuala-terengganu',
|
|
name: 'JKR Cawangan Kuala Terengganu, Terengganu',
|
|
type: 'cabinet',
|
|
accessType: 'private',
|
|
parentId: 'private-cabinets',
|
|
hasAccess: false,
|
|
accessRequestStatus: 'pending'
|
|
},
|
|
{
|
|
id: 'jkr-arkitek',
|
|
name: 'JKR Cawangan Arkitek',
|
|
type: 'cabinet',
|
|
accessType: 'private',
|
|
parentId: 'private-cabinets',
|
|
hasAccess: false,
|
|
accessRequestStatus: 'pending'
|
|
},
|
|
{
|
|
id: 'jkr-putrajaya',
|
|
name: 'JKR Cawangan Putrajaya',
|
|
type: 'cabinet',
|
|
accessType: 'private',
|
|
parentId: 'private-cabinets',
|
|
hasAccess: false,
|
|
accessRequestStatus: 'rejected',
|
|
isLocked: true
|
|
}
|
|
]
|
|
}
|
|
],
|
|
|
|
// Files within cabinets
|
|
items: [
|
|
{
|
|
id: 'file1',
|
|
name: 'Pembangunan_Sistem_IT_2021.pdf',
|
|
type: 'file',
|
|
extension: 'pdf',
|
|
size: '4MB',
|
|
modified: '2021-05-20',
|
|
cabinetId: 'jkr-kota-bharu',
|
|
accessType: 'personal',
|
|
status: 'locked',
|
|
info: {
|
|
title: 'Projek Pembangunan Sistem IT',
|
|
subject: 'Dokumen spesifikasi sistem',
|
|
state: 'Kelantan',
|
|
date: '2021-05-20',
|
|
user: 'Mohd Faizal bin Abdullah',
|
|
storeDate: '2021-05-25'
|
|
}
|
|
},
|
|
{
|
|
id: 'file2',
|
|
name: 'Projek_Jalan_Raya_Kota_Bharu.pdf',
|
|
type: 'file',
|
|
extension: 'pdf',
|
|
size: '5MB',
|
|
modified: '2021-06-15',
|
|
cabinetId: 'jkr-kejuruteraan-kb',
|
|
accessType: 'personal',
|
|
status: 'unlocked'
|
|
},
|
|
{
|
|
id: 'file3',
|
|
name: 'Anggaran_Kos_Projek_MRT3.xlsx',
|
|
type: 'file',
|
|
extension: 'xlsx',
|
|
size: '3MB',
|
|
modified: '2021-07-10',
|
|
cabinetId: 'pembinaan-jambatan-kb',
|
|
accessType: 'personal',
|
|
status: 'locked'
|
|
},
|
|
{
|
|
id: 'file4',
|
|
name: 'EIA_Empangan_Nenggiri.pdf',
|
|
type: 'file',
|
|
extension: 'pdf',
|
|
size: '15MB',
|
|
modified: '2021-04-18',
|
|
cabinetId: 'jkr-ipoh',
|
|
accessType: 'personal',
|
|
status: 'locked'
|
|
},
|
|
{
|
|
id: 'file5',
|
|
name: 'Borang_Maklumabalas.xlsx',
|
|
type: 'file',
|
|
extension: 'xlsx',
|
|
size: '34.1 KB',
|
|
modified: '2025-01-27',
|
|
cabinetId: 'public-cabinet-1',
|
|
accessType: 'public',
|
|
createdBy: 'aimantasan',
|
|
status: 'unlocked',
|
|
info: {
|
|
authors: 'aimantasan',
|
|
lastSavedBy: 'aimantasan',
|
|
dateAccessed: '2025-05-28',
|
|
dateModified: '2025-01-27',
|
|
contentCreated: '2025-01-27'
|
|
}
|
|
}
|
|
],
|
|
|
|
// Access requests
|
|
accessRequests: [
|
|
{
|
|
id: 'req1',
|
|
userId: 'user1',
|
|
userName: 'Aiman Fakhrullah',
|
|
cabinetId: 'jkr-batu-kawan',
|
|
cabinetName: 'JKR Cawangan Batu Kawan, Penang',
|
|
requestDate: '2023-06-15',
|
|
status: 'pending',
|
|
reason: 'Need access for project collaboration'
|
|
},
|
|
{
|
|
id: 'req2',
|
|
userId: 'user1',
|
|
userName: 'Aiman Fakhrullah',
|
|
cabinetId: 'jkr-kuala-terengganu',
|
|
cabinetName: 'JKR Cawangan Kuala Terengganu, Terengganu',
|
|
requestDate: '2023-06-16',
|
|
status: 'pending',
|
|
reason: 'Required for cross-department coordination'
|
|
},
|
|
{
|
|
id: 'req3',
|
|
userId: 'user1',
|
|
userName: 'Aiman Fakhrullah',
|
|
cabinetId: 'jkr-arkitek',
|
|
cabinetName: 'JKR Cawangan Arkitek',
|
|
requestDate: '2023-06-17',
|
|
status: 'pending',
|
|
reason: 'Need architectural plans for current project'
|
|
},
|
|
{
|
|
id: 'req4',
|
|
userId: 'user1',
|
|
userName: 'Aiman Fakhrullah',
|
|
cabinetId: 'jkr-putrajaya',
|
|
cabinetName: 'JKR Cawangan Putrajaya',
|
|
requestDate: '2023-06-01',
|
|
status: 'rejected',
|
|
reason: 'Need access to headquarters documents',
|
|
rejectionReason: 'Access restricted to headquarters staff only'
|
|
}
|
|
],
|
|
|
|
// Selected item
|
|
selectedItem: null,
|
|
|
|
// View settings
|
|
viewMode: 'list', // list, grid, details
|
|
sortBy: 'name',
|
|
sortDirection: 'asc',
|
|
|
|
// User permissions - would be loaded from auth service
|
|
userPermissions: {
|
|
canCreate: true,
|
|
canEdit: true,
|
|
canDelete: true,
|
|
canManageAccess: true
|
|
},
|
|
|
|
// Flags
|
|
isLoading: false,
|
|
showFileViewer: false,
|
|
viewerDocument: null,
|
|
searchQuery: '',
|
|
searchResults: []
|
|
}),
|
|
|
|
getters: {
|
|
// Get items at the current cabinet
|
|
currentCabinetItems: (state) => {
|
|
const currentCabinetId = state.currentPath.split('/').filter(Boolean).pop();
|
|
return state.items.filter(item => item.cabinetId === currentCabinetId);
|
|
},
|
|
|
|
// Get breadcrumbs for current path
|
|
breadcrumbs: (state) => {
|
|
if (state.currentPath === '/') return [{ name: 'Home', path: '/' }];
|
|
|
|
const paths = state.currentPath.split('/').filter(Boolean);
|
|
let breadcrumbPath = '';
|
|
|
|
return [
|
|
{ name: 'Home', path: '/' },
|
|
...paths.map(segment => {
|
|
breadcrumbPath += `/${segment}`;
|
|
|
|
// Find the actual cabinet name
|
|
const findCabinetName = (cabinets, id) => {
|
|
for (const cabinet of cabinets) {
|
|
if (cabinet.id === id) return cabinet.name;
|
|
if (cabinet.children) {
|
|
const name = findCabinetName(cabinet.children, id);
|
|
if (name) return name;
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
|
|
const name = findCabinetName(state.cabinets, segment) || segment;
|
|
|
|
return {
|
|
name: name,
|
|
path: breadcrumbPath
|
|
};
|
|
})
|
|
];
|
|
},
|
|
|
|
// Get public cabinets
|
|
publicCabinets: (state) => {
|
|
return state.cabinets.filter(cabinet => cabinet.accessType === 'public');
|
|
},
|
|
|
|
// Get personal cabinets (ones the user has access to)
|
|
personalCabinets: (state) => {
|
|
return state.cabinets.find(cabinet => cabinet.id === 'my-cabinets') || null;
|
|
},
|
|
|
|
// Get private cabinets
|
|
privateCabinets: (state) => {
|
|
return state.cabinets.find(cabinet => cabinet.id === 'private-cabinets') || null;
|
|
},
|
|
|
|
// Check if we can navigate back
|
|
canGoBack: (state) => {
|
|
return state.historyIndex > 0;
|
|
},
|
|
|
|
// Check if we can navigate forward
|
|
canGoForward: (state) => {
|
|
return state.historyIndex < state.pathHistory.length - 1;
|
|
},
|
|
|
|
// Filter items by access level
|
|
publicDocuments: (state) => {
|
|
return state.items.filter(item => item.accessType === 'public');
|
|
},
|
|
|
|
personalDocuments: (state) => {
|
|
return state.items.filter(item => item.accessType === 'personal');
|
|
},
|
|
|
|
privateDocuments: (state) => {
|
|
return state.items.filter(item => item.accessType === 'private');
|
|
},
|
|
|
|
// Get pending access requests
|
|
pendingAccessRequests: (state) => {
|
|
return state.accessRequests.filter(req => req.status === 'pending');
|
|
}
|
|
},
|
|
|
|
actions: {
|
|
// Navigation actions
|
|
navigateTo(path) {
|
|
// Add to history if it's a new path
|
|
if (path !== this.currentPath) {
|
|
// If we navigated back and then to a new path, truncate the forward history
|
|
if (this.historyIndex < this.pathHistory.length - 1) {
|
|
this.pathHistory = this.pathHistory.slice(0, this.historyIndex + 1);
|
|
}
|
|
|
|
this.pathHistory.push(path);
|
|
this.historyIndex = this.pathHistory.length - 1;
|
|
}
|
|
|
|
this.currentPath = path;
|
|
this.selectedItem = null;
|
|
},
|
|
|
|
navigateBack() {
|
|
if (this.canGoBack) {
|
|
this.historyIndex--;
|
|
this.currentPath = this.pathHistory[this.historyIndex];
|
|
this.selectedItem = null;
|
|
}
|
|
},
|
|
|
|
navigateForward() {
|
|
if (this.canGoForward) {
|
|
this.historyIndex++;
|
|
this.currentPath = this.pathHistory[this.historyIndex];
|
|
this.selectedItem = null;
|
|
}
|
|
},
|
|
|
|
selectItem(item) {
|
|
this.selectedItem = item;
|
|
},
|
|
|
|
// View actions
|
|
setViewMode(mode) {
|
|
this.viewMode = mode;
|
|
},
|
|
|
|
setSortBy(field) {
|
|
if (this.sortBy === field) {
|
|
// Toggle direction if clicking the same field
|
|
this.sortDirection = this.sortDirection === 'asc' ? 'desc' : 'asc';
|
|
} else {
|
|
this.sortBy = field;
|
|
this.sortDirection = 'asc';
|
|
}
|
|
},
|
|
|
|
// File viewer actions
|
|
openFileViewer(document) {
|
|
this.viewerDocument = document;
|
|
this.showFileViewer = true;
|
|
},
|
|
|
|
closeFileViewer() {
|
|
this.showFileViewer = false;
|
|
this.viewerDocument = null;
|
|
},
|
|
|
|
// Cabinet access actions
|
|
async requestCabinetAccess(cabinetId, reason) {
|
|
this.isLoading = true;
|
|
|
|
try {
|
|
// Find the cabinet
|
|
let cabinetName = '';
|
|
const findCabinet = (cabinets, id) => {
|
|
for (const cabinet of cabinets) {
|
|
if (cabinet.id === id) {
|
|
cabinetName = cabinet.name;
|
|
return cabinet;
|
|
}
|
|
if (cabinet.children) {
|
|
const result = findCabinet(cabinet.children, id);
|
|
if (result) return result;
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
|
|
const cabinet = findCabinet(this.cabinets, cabinetId);
|
|
if (!cabinet) throw new Error('Cabinet not found');
|
|
|
|
// Mock API delay
|
|
await new Promise(resolve => setTimeout(resolve, 500));
|
|
|
|
// Create new access request
|
|
const newRequest = {
|
|
id: `req${Date.now()}`,
|
|
userId: this.currentUser.id,
|
|
userName: this.currentUser.name,
|
|
cabinetId: cabinetId,
|
|
cabinetName: cabinetName,
|
|
requestDate: new Date().toISOString().split('T')[0],
|
|
status: 'pending',
|
|
reason: reason
|
|
};
|
|
|
|
// Add to access requests
|
|
this.accessRequests.push(newRequest);
|
|
|
|
// Update cabinet request status
|
|
cabinet.accessRequestStatus = 'pending';
|
|
|
|
return newRequest;
|
|
} catch (error) {
|
|
console.error('Failed to request access:', error);
|
|
throw error;
|
|
} finally {
|
|
this.isLoading = false;
|
|
}
|
|
},
|
|
|
|
async approveAccessRequest(requestId) {
|
|
this.isLoading = true;
|
|
|
|
try {
|
|
// Mock API delay
|
|
await new Promise(resolve => setTimeout(resolve, 500));
|
|
|
|
// Find the request
|
|
const request = this.accessRequests.find(req => req.id === requestId);
|
|
if (!request) throw new Error('Request not found');
|
|
|
|
// Update request status
|
|
request.status = 'approved';
|
|
|
|
// Find the cabinet and update access
|
|
const updateCabinetAccess = (cabinets, id) => {
|
|
for (const cabinet of cabinets) {
|
|
if (cabinet.id === id) {
|
|
cabinet.hasAccess = true;
|
|
cabinet.accessRequestStatus = 'approved';
|
|
return true;
|
|
}
|
|
if (cabinet.children) {
|
|
if (updateCabinetAccess(cabinet.children, id)) return true;
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
|
|
updateCabinetAccess(this.cabinets, request.cabinetId);
|
|
|
|
return request;
|
|
} catch (error) {
|
|
console.error('Failed to approve access request:', error);
|
|
throw error;
|
|
} finally {
|
|
this.isLoading = false;
|
|
}
|
|
},
|
|
|
|
async rejectAccessRequest(requestId, reason) {
|
|
this.isLoading = true;
|
|
|
|
try {
|
|
// Mock API delay
|
|
await new Promise(resolve => setTimeout(resolve, 500));
|
|
|
|
// Find the request
|
|
const request = this.accessRequests.find(req => req.id === requestId);
|
|
if (!request) throw new Error('Request not found');
|
|
|
|
// Update request status
|
|
request.status = 'rejected';
|
|
request.rejectionReason = reason;
|
|
|
|
// Find the cabinet and update access
|
|
const updateCabinetAccess = (cabinets, id) => {
|
|
for (const cabinet of cabinets) {
|
|
if (cabinet.id === id) {
|
|
cabinet.hasAccess = false;
|
|
cabinet.accessRequestStatus = 'rejected';
|
|
return true;
|
|
}
|
|
if (cabinet.children) {
|
|
if (updateCabinetAccess(cabinet.children, id)) return true;
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
|
|
updateCabinetAccess(this.cabinets, request.cabinetId);
|
|
|
|
return request;
|
|
} catch (error) {
|
|
console.error('Failed to reject access request:', error);
|
|
throw error;
|
|
} finally {
|
|
this.isLoading = false;
|
|
}
|
|
},
|
|
|
|
// CRUD operations
|
|
async createItem(item) {
|
|
this.isLoading = true;
|
|
|
|
try {
|
|
// Mock API delay
|
|
await new Promise(resolve => setTimeout(resolve, 500));
|
|
|
|
// Get current cabinet id
|
|
const currentCabinetId = this.currentPath.split('/').filter(Boolean).pop();
|
|
|
|
// Generate a unique ID
|
|
const newItem = {
|
|
...item,
|
|
id: `${item.type}${Date.now()}`,
|
|
cabinetId: currentCabinetId,
|
|
modified: new Date().toISOString().split('T')[0],
|
|
createdBy: this.currentUser.name
|
|
};
|
|
|
|
// Add to items
|
|
this.items.push(newItem);
|
|
|
|
return newItem;
|
|
} catch (error) {
|
|
console.error('Failed to create item:', error);
|
|
throw error;
|
|
} finally {
|
|
this.isLoading = false;
|
|
}
|
|
},
|
|
|
|
async updateItem(id, updates) {
|
|
this.isLoading = true;
|
|
|
|
try {
|
|
// Mock API delay
|
|
await new Promise(resolve => setTimeout(resolve, 500));
|
|
|
|
// Find the item
|
|
const itemIndex = this.items.findIndex(item => item.id === id);
|
|
if (itemIndex === -1) throw new Error('Item not found');
|
|
|
|
// Update the item
|
|
const updatedItem = {
|
|
...this.items[itemIndex],
|
|
...updates,
|
|
modified: new Date().toISOString().split('T')[0]
|
|
};
|
|
|
|
this.items.splice(itemIndex, 1, updatedItem);
|
|
|
|
return updatedItem;
|
|
} catch (error) {
|
|
console.error('Failed to update item:', error);
|
|
throw error;
|
|
} finally {
|
|
this.isLoading = false;
|
|
}
|
|
},
|
|
|
|
async deleteItem(id) {
|
|
this.isLoading = true;
|
|
|
|
try {
|
|
// Mock API delay
|
|
await new Promise(resolve => setTimeout(resolve, 500));
|
|
|
|
// Find the item
|
|
const itemIndex = this.items.findIndex(item => item.id === id);
|
|
if (itemIndex === -1) throw new Error('Item not found');
|
|
|
|
// Remove the item
|
|
const deletedItem = this.items.splice(itemIndex, 1)[0];
|
|
|
|
return deletedItem;
|
|
} catch (error) {
|
|
console.error('Failed to delete item:', error);
|
|
throw error;
|
|
} finally {
|
|
this.isLoading = false;
|
|
}
|
|
},
|
|
|
|
// Search functionality
|
|
async searchDocuments(query) {
|
|
this.isLoading = true;
|
|
this.searchQuery = query;
|
|
|
|
try {
|
|
// Mock API delay
|
|
await new Promise(resolve => setTimeout(resolve, 500));
|
|
|
|
// Simple search implementation - in production would be more sophisticated
|
|
const results = this.items.filter(item =>
|
|
item.type === 'file' &&
|
|
(item.name.toLowerCase().includes(query.toLowerCase()) ||
|
|
(item.info?.title && item.info.title.toLowerCase().includes(query.toLowerCase())) ||
|
|
(item.info?.subject && item.info.subject.toLowerCase().includes(query.toLowerCase())))
|
|
);
|
|
|
|
this.searchResults = results;
|
|
return results;
|
|
} catch (error) {
|
|
console.error('Failed to search documents:', error);
|
|
throw error;
|
|
} finally {
|
|
this.isLoading = false;
|
|
}
|
|
},
|
|
|
|
clearSearch() {
|
|
this.searchQuery = '';
|
|
this.searchResults = [];
|
|
},
|
|
|
|
// Access request functionality
|
|
async requestAccess(itemId, accessLevel, justification, duration = '7 days') {
|
|
this.isLoading = true;
|
|
|
|
try {
|
|
// Mock API delay
|
|
await new Promise(resolve => setTimeout(resolve, 500));
|
|
|
|
// Generate a unique request ID
|
|
const requestId = `req${Date.now()}`;
|
|
|
|
// Create new access request
|
|
const newRequest = {
|
|
id: requestId,
|
|
userId: 'current-user-id', // Would come from auth store
|
|
userName: 'Current User', // Would come from auth store
|
|
itemId: itemId,
|
|
accessLevel: accessLevel,
|
|
justification: justification,
|
|
duration: duration,
|
|
requestDate: new Date().toISOString().split('T')[0],
|
|
status: 'pending'
|
|
};
|
|
|
|
// Add to access requests
|
|
this.accessRequests.push(newRequest);
|
|
|
|
// Update the item's access request status (for mock data)
|
|
// In production, this would be handled server-side
|
|
const updateItemStatus = (items, id) => {
|
|
for (const item of items) {
|
|
if (item.id === id) {
|
|
item.accessRequestStatus = 'pending';
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
|
|
// Try to find and update the item in the mock data arrays
|
|
// This is a simplified approach for demo purposes
|
|
|
|
return newRequest;
|
|
} catch (error) {
|
|
console.error('Failed to submit access request:', error);
|
|
throw error;
|
|
} finally {
|
|
this.isLoading = false;
|
|
}
|
|
}
|
|
}
|
|
});
|