formue-crud
v0.2.17
Published
1. [Overview](#overview) 2. [Installation & Setup](#installation--setup) 3. [Core Components](#core-components) 4. [Architecture](#architecture) 5. [API Reference](#api-reference) 6. [Usage Examples](#usage-examples) 7. [Advanced Features](#advanced-featu
Downloads
598
Readme
Formue CRUD - Complete Documentation
Table of Contents
- Overview
- Installation & Setup
- Core Components
- Architecture
- API Reference
- Usage Examples
- Advanced Features
- Customization
- Best Practices
- Troubleshooting
Overview
Formue CRUD is a comprehensive Vue.js 3 framework designed for building data-driven applications with advanced CRUD operations. It provides a complete solution for managing data tables, forms, filtering, sorting, pagination, and user permissions.
Key Features
- Dynamic Data Tables: Tabulator.js integration with advanced sorting and filtering
- Form Management: Vueform integration for dynamic form generation
- Permission System: Role-based access control for CRUD operations
- Advanced Filtering: Multi-field filtering with save/load functionality
- Export Capabilities: Excel export with customizable data
- Responsive Design: Mobile-friendly interface with Tailwind CSS
- State Management: Pinia-based reactive state management
- Real-time Updates: Event-driven architecture for live data updates
Dependencies
{
"@vueform/vueform": "^1.5.3",
"@vueuse/core": "^10.4.0",
"axios": "^1.6.2",
"lodash": "^4.17.21",
"mitt": "^3.0.1",
"pinia": "^2.1.6",
"qs": "^6.11.2",
"tabulator-tables": "^6.2.1",
"vue": "^3.3.4"
}Installation & Setup
1. Install the Package
npm install formue-crud2. Import and Configure
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import FormueCrud from 'formue-crud'
const app = createApp(App)
app.use(createPinia())
app.use(FormueCrud)3. Basic Setup
<template>
<MCrud
:fields="fields"
:options="options"
:route="route"
:hidden-actions="hiddenActions"
@mounted="onMounted"
/>
</template>
<script setup>
import { MCrud } from 'formue-crud'
const fields = {
name: {
type: 'text',
title: 'Name',
placeholder: 'Enter name'
},
email: {
type: 'email',
title: 'Email',
placeholder: 'Enter email'
}
}
const options = {
formMode: 'dialog' // or 'tab'
}
const route = {
index: '/api/users',
create: '/api/users',
update: '/api/users',
delete: '/api/users'
}
const hiddenActions = [] // ['create', 'update', 'delete', 'show']
</script>Core Components
MCrud (Main Component)
The primary component that orchestrates all CRUD operations.
Props:
fields: Object defining form fields and table columnsoptions: Configuration object for behavior customizationstructure: Additional form structure configurationhiddenActions: Array of actions to hide from UItableOptions: Tabulator-specific optionsroute: API endpoints configurationdir: Text direction ('ltr' or 'rtl')
Events:
mounted: Emitted when component is fully initialized
MTable
Advanced data table component with sorting, filtering, and pagination.
Features:
- Column sorting with visual indicators
- Row selection with batch operations
- Custom column visibility
- Loading states and empty data handling
- Responsive design
MFilter
Dynamic filtering system with save/load functionality.
Features:
- Field-specific filter types (text, date, select)
- Multiple filter combinations
- Save/load filter presets
- Real-time filter application
FormCore
Dynamic form generation component using Vueform.
Features:
- Auto-generated forms from field definitions
- Validation integration
- Conditional field display
- Multi-step form support
MButtonBox
Action toolbar with permissions-based button visibility.
Features:
- Create, export, reload, column selection buttons
- Permission-based visibility
- Batch operation support
- Search integration
Architecture
State Management (Pinia Store)
The framework uses a dynamic store system for managing application state:
// Store Structure
{
mainKey: '', // Current data model key
form: {}, // Current form data
items: {}, // Data collections by key
query: '', // Additional query parameters
routes: {}, // API endpoints
fields: [], // Field definitions
options: [], // Configuration options
filters: [], // Active filters
loadings: {}, // Loading states
dialog: false, // Dialog visibility
structure: {}, // Form structure
paginations: {}, // Pagination data
searchParam: '', // Search query
isEditing: false, // Edit mode flag
selected: new Set([]) // Selected items
}Event System
Uses mitt.js for event communication between components:
import { emitter } from '@/helpers/emitter'
// Listen to events
emitter.listen('saveForm', () => {
// Handle form save
})
// Emit events
emitter.event('alert', { text: 'Success!', color: 'green' })Permission System
Role-based access control for UI elements:
import { usePermission } from '@/composables/usePermission'
const { can } = usePermission()
// Check permissions
if (can('create')) {
// Show create button
}API Reference
Field Types
Text Field
{
type: 'text',
title: 'Field Name',
placeholder: 'Enter value',
required: true,
validation: 'required|min:3'
}Select Field
{
type: 'select',
title: 'Category',
items: [
{ value: 1, text: 'Option 1' },
{ value: 2, text: 'Option 2' }
],
'label-prop': 'text',
'value-prop': 'value',
search: true
}Date Field
{
type: 'date',
title: 'Date',
placeholder: 'Select date',
format: 'YYYY-MM-DD'
}Store Actions
Data Operations
// Load items
store.loadItems(key, page)
// Add new item
store.addItem(data)
// Edit existing item
store.editItem(data)
// Remove item
store.remove(id)
// Reload data
store.reloadData()Filtering
// Apply filters
store.loadItems()
// Clear all filters
store.filters = []
// Generate filter query
store.convertToFilterForm()Composables
useDynamicStore
import { useDynamicStore } from '@/composables/useDynamicStore'
const store = useDynamicStore('MyStore')usePermission
import { usePermission } from '@/composables/usePermission'
const { can, setPermissions } = usePermission()
setPermissions(['create', 'update', 'delete'])useFetch
import { useFetch } from '@/composables/useFetch'
const { get, post, patch, remove } = useFetch()
const response = await get('/api/users')Usage Examples
Basic CRUD Setup
<template>
<MCrud :fields="userFields" :route="userRoutes" :options="{ formMode: 'dialog' }" />
</template>
<script setup>
const userFields = {
name: {
type: 'text',
title: 'Full Name',
required: true,
showIn: ['create', 'edit', 'list']
},
email: {
type: 'email',
title: 'Email Address',
required: true
},
role: {
type: 'select',
title: 'Role',
items: [
{ value: 'admin', text: 'Administrator' },
{ value: 'user', text: 'Regular User' }
]
},
created_at: {
type: 'date',
title: 'Created Date',
showIn: ['list']
}
}
const userRoutes = {
index: '/api/users',
create: '/api/users',
update: '/api/users',
delete: '/api/users'
}
</script>Custom Field with API Integration
const productFields = {
category_id: {
type: 'select',
title: 'Category',
items: async (search) => {
const response = await axios.get(`/api/categories?search=${search}`)
return response.data.data
},
'label-prop': 'name',
'value-prop': 'id',
search: true
}
}Advanced Filtering Setup
const advancedFields = {
status: {
type: 'select',
title: 'Status',
items: [
{ value: 'active', text: 'Active' },
{ value: 'inactive', text: 'Inactive' }
],
filterItems: [
{ value: 'active', text: 'Active Only' },
{ value: 'inactive', text: 'Inactive Only' }
]
},
created_at: {
type: 'date',
title: 'Created Date',
filterable: true
}
}Custom Actions
<template>
<MCrud :fields="fields" :route="route" @mounted="setupCustomActions">
<template #extra>
<CustomActionButtons />
</template>
</MCrud>
</template>
<script setup>
import { emitter } from '@/helpers/emitter'
const setupCustomActions = () => {
emitter.listen('customAction', (data) => {
// Handle custom action
console.log('Custom action triggered:', data)
})
}
</script>Advanced Features
Batch Operations
// Select multiple items
store.selected.add(itemId)
// Batch delete
const selectedIds = Array.from(store.selected)
store.remove(selectedIds)
// Custom batch operation
emitter.listen('batchUpdate', (data) => {
const selectedItems = store.mainItems.filter((item) => store.selected.has(item.id))
// Process selected items
})Export Functionality
// Export filtered data
function exportData() {
const exportUrl = store.generateQuery() + '/export'
window.open(exportUrl)
}
// Custom export format
function exportCustom() {
const selectedData = store.mainItems.filter((item) => store.selected.has(item.id))
// Process and export selected data
}Custom Column Rendering
const customFields = {
avatar: {
type: 'image',
title: 'Avatar',
formatter: (value) => {
return `<img src="${value}" alt="Avatar" class="w-8 h-8 rounded-full">`
}
},
status: {
type: 'select',
title: 'Status',
formatter: (value) => {
const color = value === 'active' ? 'green' : 'red'
return `<span class="px-2 py-1 text-xs rounded bg-${color}-100 text-${color}-800">${value}</span>`
}
}
}Conditional Field Display
const conditionalFields = {
type: {
type: 'select',
title: 'User Type',
items: [
{ value: 'individual', text: 'Individual' },
{ value: 'company', text: 'Company' }
],
onChange: (value, formData) => {
// Show/hide fields based on selection
if (value === 'company') {
// Show company-specific fields
}
}
},
company_name: {
type: 'text',
title: 'Company Name',
showIf: (formData) => formData.type === 'company'
}
}Customization
Styling
The framework uses Tailwind CSS for styling. You can customize the appearance by:
- Override CSS Classes:
.fc-header-icon-btn {
@apply bg-blue-500 hover:bg-blue-600 text-white;
}
.fc-table-row:hover {
@apply bg-blue-50;
}- Custom Themes:
const customOptions = {
theme: {
primary: 'blue',
secondary: 'gray',
success: 'green',
danger: 'red'
}
}Custom Components
<!-- CustomField.vue -->
<template>
<div class="custom-field">
<label>{{ field.title }}</label>
<input v-model="modelValue" :type="field.type" :placeholder="field.placeholder" />
</div>
</template>
<script setup>
import { registerFields } from 'formue-crud'
registerFields({
'custom-field': CustomField
})
</script>API Response Format
Expected API response format:
{
"data": [
{
"id": 1,
"name": "John Doe",
"email": "[email protected]"
}
],
"current_page": 1,
"last_page": 5,
"total": 50,
"per_page": 10
}Best Practices
1. Field Organization
// Group related fields
const userFields = {
// Personal Information
first_name: { type: 'text', title: 'First Name', group: 'personal' },
last_name: { type: 'text', title: 'Last Name', group: 'personal' },
// Contact Information
email: { type: 'email', title: 'Email', group: 'contact' },
phone: { type: 'tel', title: 'Phone', group: 'contact' }
}2. Performance Optimization
// Use lazy loading for large datasets
const lazyFields = {
category: {
type: 'select',
items: async (search) => {
// Only load when needed
if (search.length < 2) return []
return await fetchCategories(search)
}
}
}3. Error Handling
// Global error handling
emitter.listen('error', (error) => {
console.error('CRUD Error:', error)
// Show user-friendly message
showNotification(error.message, 'error')
})4. Validation
const validatedFields = {
email: {
type: 'email',
title: 'Email',
rules: ['required', 'email'],
messages: {
required: 'Email is required',
email: 'Please enter a valid email'
}
}
}Troubleshooting
Common Issues
1. Data Not Loading
// Check API endpoint
console.log('API URL:', store.generateRoute())
// Verify response format
axios.get('/api/users').then((response) => {
console.log('Response structure:', response.data)
})2. Form Validation Errors
// Debug form validation
emitter.listen('validation-error', (errors) => {
console.log('Validation errors:', errors)
})3. Permission Issues
// Check permission setup
const { permissions } = usePermission()
console.log('Available permissions:', permissions.value)4. Filter Not Working
// Debug filter generation
console.log('Filter query:', store.convertToFilterForm())Debug Mode
Enable debug mode for detailed logging:
const debugOptions = {
debug: true,
logging: {
api: true,
events: true,
state: true
}
}Performance Monitoring
// Monitor API calls
axios.interceptors.request.use((request) => {
console.time(`API: ${request.url}`)
return request
})
axios.interceptors.response.use((response) => {
console.timeEnd(`API: ${response.config.url}`)
return response
})Migration Guide
From Version 0.1.x to 0.2.x
- Update field definitions:
// Old format
const fields = [{ field: 'name', type: 'text', title: 'Name' }]
// New format
const fields = {
name: { type: 'text', title: 'Name' }
}- Update event listeners:
// Old format
this.$emit('update', data)
// New format
emitter.event('update', data)Contributing
Development Setup
git clone https://github.com/your-repo/formue-crud
cd formue-crud
npm install
npm run devBuild Process
npm run build
npm run type-check
npm run lintTesting
npm run test
npm run test:unit
npm run test:e2eVersion: 0.1.77
Last Updated: 2024
License: MIT
For more information, visit the GitHub repository or contact the maintainers.
