-
- {{ roleForm.isGlobal ? 'Global' : 'App-specific' }}
-
{{ roleForm.isActive ? 'Active' : 'Inactive' }}
diff --git a/pages/users/create.vue b/pages/users/create.vue
index 978681e..1a5c324 100644
--- a/pages/users/create.vue
+++ b/pages/users/create.vue
@@ -12,61 +12,58 @@ definePageMeta({
import { ref, reactive, computed, onMounted } from 'vue'
-// Form state
+// Form state - SIMPLIFIED
const userForm = reactive({
+ // Basic Information
firstName: '',
lastName: '',
email: '',
username: '',
password: '',
confirmPassword: '',
- groups: [],
- roles: [],
- isActive: true,
- // Profile
- phone: '',
- department: '',
- jobTitle: '',
- employeeId: '',
+ // Application Assignment (ESSENTIAL)
+ application: '',
+
+ // Group Assignment (Groups contain roles)
+ groups: [],
+
+ // Direct Role Assignment (optional - for specific cases)
+ additionalRoles: [],
// Account Settings
- emailVerified: false,
+ isActive: true,
mustChangePassword: true,
-
- // Notification Settings
sendInvitation: true
})
// Available options
+const availableApplications = ref([
+ { id: '1', name: 'Main Application', description: 'Primary business application' },
+ { id: '2', name: 'HR System', description: 'Human Resources Management' },
+ { id: '3', name: 'Finance System', description: 'Financial Management' }
+])
+
const availableGroups = ref([
- { id: '1', name: 'IT Department', authentikUUID: 'uuid-1', description: 'Information Technology Department' },
- { id: '2', name: 'HR Department', authentikUUID: 'uuid-2', description: 'Human Resources Department' },
- { id: '3', name: 'Finance Department', authentikUUID: 'uuid-3', description: 'Finance and Accounting Department' },
- { id: '4', name: 'Management', authentikUUID: 'uuid-4', description: 'Executive Management' }
+ { id: '1', name: 'IT Department', application: '1', description: 'Information Technology Department' },
+ { id: '2', name: 'HR Department', application: '2', description: 'Human Resources Department' },
+ { id: '3', name: 'Finance Department', application: '3', description: 'Finance and Accounting Department' },
+ { id: '4', name: 'Development Team', application: '1', description: 'Software Development Team' },
+ { id: '5', name: 'Support Team', application: '1', description: 'Customer Support Team' }
])
const availableRoles = ref([
- { id: '1', name: 'Administrator', description: 'Full system access' },
- { id: '2', name: 'Manager', description: 'Department management access' },
- { id: '3', name: 'Editor', description: 'Content editing access' },
- { id: '4', name: 'Viewer', description: 'Read-only access' }
-])
-
-const departments = ref([
- 'Information Technology',
- 'Human Resources',
- 'Finance',
- 'Marketing',
- 'Operations',
- 'Legal',
- 'Executive'
+ { id: '1', name: 'Administrator', application: '1', description: 'Full system access' },
+ { id: '2', name: 'Manager', application: '1', description: 'Department management access' },
+ { id: '3', name: 'Editor', application: '1', description: 'Content editing access' },
+ { id: '4', name: 'Viewer', application: '1', description: 'Read-only access' },
+ { id: '5', name: 'HR Admin', application: '2', description: 'HR system administrator' },
+ { id: '6', name: 'Finance Admin', application: '3', description: 'Finance system administrator' }
])
// Validation state
const errors = ref({})
const isLoading = ref(false)
-const showPassword = ref(false)
// Computed
const isFormValid = computed(() => {
@@ -76,7 +73,8 @@ const isFormValid = computed(() => {
userForm.lastName &&
userForm.password &&
userForm.password === userForm.confirmPassword &&
- userForm.password.length >= 8
+ userForm.password.length >= 8 &&
+ userForm.application
})
const passwordStrength = computed(() => {
@@ -100,6 +98,25 @@ const passwordStrength = computed(() => {
}
})
+const applicationOptions = computed(() =>
+ availableApplications.value.map(app => ({
+ label: app.name,
+ value: app.id
+ }))
+)
+
+// Groups filtered by selected application
+const filteredGroups = computed(() => {
+ if (!userForm.application) return []
+ return availableGroups.value.filter(group => group.application === userForm.application)
+})
+
+// Roles filtered by selected application (for additional roles)
+const filteredRoles = computed(() => {
+ if (!userForm.application) return []
+ return availableRoles.value.filter(role => role.application === userForm.application)
+})
+
// Methods
const validateForm = () => {
errors.value = {}
@@ -131,6 +148,10 @@ const validateForm = () => {
if (userForm.password !== userForm.confirmPassword) {
errors.value.confirmPassword = 'Passwords do not match'
}
+
+ if (!userForm.application) {
+ errors.value.application = 'Application is required'
+ }
return Object.keys(errors.value).length === 0
}
@@ -145,6 +166,12 @@ const generateRandomPassword = () => {
userForm.confirmPassword = password
}
+// Clear groups and roles when application changes
+const onApplicationChange = () => {
+ userForm.groups = []
+ userForm.additionalRoles = []
+}
+
const createUser = async () => {
if (!validateForm()) {
return
@@ -153,22 +180,18 @@ const createUser = async () => {
isLoading.value = true
try {
- // Prepare user data
+ // Prepare user data - SIMPLIFIED
const userData = {
username: userForm.username,
email: userForm.email,
firstName: userForm.firstName,
lastName: userForm.lastName,
password: userForm.password,
- phone: userForm.phone,
- department: userForm.department,
- jobTitle: userForm.jobTitle,
- employeeId: userForm.employeeId,
- isActive: userForm.isActive,
- emailVerified: userForm.emailVerified,
- mustChangePassword: userForm.mustChangePassword,
+ application: userForm.application,
groups: userForm.groups,
- roles: userForm.roles,
+ additionalRoles: userForm.additionalRoles,
+ isActive: userForm.isActive,
+ mustChangePassword: userForm.mustChangePassword,
sendInvitation: userForm.sendInvitation
}
@@ -179,13 +202,11 @@ const createUser = async () => {
})
if (response.success) {
- // Show success message
await navigateTo('/users')
}
} catch (error) {
console.error('Failed to create user:', error)
- // Handle error
} finally {
isLoading.value = false
}
@@ -199,46 +220,16 @@ const resetForm = () => {
username: '',
password: '',
confirmPassword: '',
- phone: '',
- department: '',
- jobTitle: '',
- employeeId: '',
- isActive: true,
- emailVerified: false,
- mustChangePassword: true,
+ application: '',
groups: [],
- roles: [],
+ additionalRoles: [],
+ isActive: true,
+ mustChangePassword: true,
sendInvitation: true
})
errors.value = {}
}
-const handleSubmit = (data) => {
- console.log('Creating user:', {
- ...data
- })
-
- // Reset form
- Object.assign(userForm, {
- firstName: '',
- lastName: '',
- email: '',
- username: '',
- password: '',
- confirmPassword: '',
- groups: [],
- roles: [],
- isActive: true,
- phone: '',
- department: '',
- jobTitle: '',
- employeeId: '',
- emailVerified: false,
- mustChangePassword: true,
- sendInvitation: true
- })
-}
-
// Initialize
onMounted(() => {
// Load additional data if needed
@@ -254,7 +245,7 @@ onMounted(() => {
Add New User
-
Create a new user account with roles and permissions
+
Users get permissions through groups (collections of roles)
@@ -269,7 +260,7 @@ onMounted(() => {
-
+
@@ -280,41 +271,73 @@ onMounted(() => {
Basic Information
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
@@ -341,6 +364,7 @@ onMounted(() => {
validation="required|length:8"
validation-visibility="dirty"
:validation-messages="{
+ required: 'Password is required',
length: 'Password must be at least 8 characters'
}"
/>
@@ -353,6 +377,7 @@ onMounted(() => {
validation="required|confirm:password"
validation-visibility="dirty"
:validation-messages="{
+ required: 'Confirm password is required',
confirm: 'Passwords do not match'
}"
/>
@@ -375,45 +400,6 @@ onMounted(() => {
-
-
-
- Profile Information
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -428,83 +414,13 @@ onMounted(() => {
help="User can log in when active"
/>
-
-
-
-
-
-
-
-
-
-
-
-
- Groups
-
-
-
-
-
-
-
-
-
-
-
- Roles
-
-
-
-
-
-
-
-
-
-
-
- Notification Settings
-
-
-
+
{
+
+
+
+
+
+
+
+
Groups
+ Primary
+
+
+
+
+
+ Groups contain roles. Users inherit all roles from their groups.
+
+
+
+
+ Select an application first to see available groups.
+
+
+
+
+
+ No groups available for the selected application.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Additional Roles
+ Optional
+
+
+
+
+
+ Extra roles for specific permissions beyond group roles.
+
+
+
+
+ Select an application first to see available roles.
+
+
+
+
+
+ No additional roles available for the selected application.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Preview
+
+
+
+
+
Name:
+
+ {{ userForm.firstName && userForm.lastName ? `${userForm.firstName} ${userForm.lastName}` : 'Not set' }}
+
+
+
+
+
Application:
+
+ {{ availableApplications.find(a => a.id === userForm.application)?.name || 'Not selected' }}
+
+
+
+
+
Groups:
+
+ {{ userForm.groups.length }} group(s) selected
+
+
+
+
+
Additional Roles:
+
+ {{ userForm.additionalRoles.length }} additional role(s)
+
+
+
+
+
+ {{ userForm.isActive ? 'Active' : 'Inactive' }}
+
+
+
+
+
+
\ No newline at end of file