closeViewRoleDialog already clears rolePermissionsForView and
roleUsersForView; closeRoleDialog (used by both Edit and Create flows)
did not. With editRole now populating those arrays, leftover state
would otherwise survive a close → open-Create round trip. The Create
template branch doesn't read the arrays today (v-if guarded on
editingRole), so this is defensive — keeps the two close handlers
symmetrical and avoids future regressions if the Create branch ever
starts referencing them.
The dialog reads from rolePermissionsForView / roleUsersForView, but
editRole(role) only ever populated the form fields and showed the
dialog — those arrays were left at whatever state the rest of the page
had set them to. Result: opening Edit Role for a role with existing
permissions showed "No permissions assigned to this role yet", and the
list only "appeared" because adding a permission triggered a refresh.
Mirror viewRole's pattern: clear both arrays, GET /admin/roles/{id},
populate from the response, then show the dialog after $nextTick.
Closes#14
Adds the new permission type to the grant/bulk-grant dialog dropdown
(static/js/permissions.js) so admins can grant 'Submit Income' on
revenue accounts the same way they grant 'Submit Expense' on expense
accounts. Without this, the backend's SUBMIT_INCOME check on the new
income endpoint is ungranted-able from the UI and users see a 403.
Uses 'teal' + the 'payments' icon to distinguish income-grant badges
from green-and-add_circle expense-grant badges in the role/account
permission lists. Also updates a stale comment in migrations.py
listing the valid permission_type values.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Add Fava URL, ledger slug, and timeout settings to super admin Settings dialog
- Reinitialize Fava client when settings are updated via services.py
- Add settingsLoaded flag to prevent race conditions where wrong toolbar
buttons appeared before isSuperUser was determined
- Remove premature Vue mount() call from permissions.js that caused
"Cannot read properties of undefined (reading 'user')" error
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add role management to "By User" tab
- Show all users with roles and/or direct permissions
- Add ability to assign/revoke roles from users
- Display role chips as clickable and removable
- Add "Assign Role" button for each user
- Fix account_id validation error in permission granting
- Extract account_id string from Quasar q-select object
- Apply fix to grantPermission, bulkGrantPermissions, and addRolePermission
- Fix role-based permission checking for expense submission
- Update get_user_permissions_with_inheritance() to include role permissions
- Ensures users with role-based permissions can submit expenses
- Improve Vue reactivity for role details dialog
- Use spread operator to create fresh arrays
- Add $nextTick() before showing dialog
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changed default permission type from 'read' to 'submit_expense' in
all permission grant forms, as this is the most common use case when
Castle admins grant permissions to users.
Changes:
- grantForm initialization (line 31): 'read' → 'submit_expense'
- bulkGrantForm initialization (line 42): 'read' → 'submit_expense'
- resetGrantForm() method (line 315): 'read' → 'submit_expense'
- resetBulkGrantForm() method (line 402): 'read' → 'submit_expense'
Rationale: Most users need to submit expenses to their assigned
accounts, making 'submit_expense' a more practical default than
'read'. Admins can still select other permission types from the
dropdown if needed.
Affected: static/js/permissions.js
Co-Authored-By: Claude <noreply@anthropic.com>
Two related fixes for account access:
1. **Super user bypass for permission filtering**
- Super users now bypass permission checks and see all accounts
- Fixes issue where Castle system account was blocked from seeing accounts
- Regular users still get filtered by permissions as expected
2. **Show virtual accounts in permissions management UI**
- Permissions page now passes exclude_virtual=false
- Admins need to see virtual accounts to grant permissions on them
- Enables granting permission on 'Expenses:Supplies' to give access to all children
Impact:
- Super user can now create entries and see all accounts ✓
- Admins can grant permissions on virtual parent accounts ✓
- Regular users still only see permitted, non-virtual accounts ✓
- Permission inheritance works correctly for all users ✓
🤖 Generated with Claude Code (https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Updates permission grant dialogs to visually distinguish virtual accounts:
Changes:
- Add custom option template to account selectors (both grant and bulk grant dialogs)
- Show "🌐 Virtual parent" caption explaining inheritance behavior
- Add blue "Virtual" chip badge to virtual accounts in dropdown
- Update hint text: "virtual accounts cascade to all children"
- Include is_virtual flag in accountOptions computed property
User Experience:
When admin selects account in grant dialog, virtual accounts now clearly show:
- "Expenses" with "Virtual" badge
- Caption: "grants access to all Expenses:* accounts"
This helps admins understand that granting permission on "Expenses" will
automatically give users access to all real expense accounts:
- Expenses:Groceries
- Expenses:Gas:Kitchen
- Expenses:Maintenance:Property
- etc.
Related: migrations.py m003 (created virtual parent accounts)
🤖 Generated with Claude Code (https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implements Phase 1 of UI improvements plan with bulk grant dialog.
Changes:
- Replace single "Grant Permission" button with button group + dropdown menu
- Add "Bulk Grant" option in dropdown menu
- Add comprehensive bulk grant dialog:
* Multi-select user dropdown (with chips)
* Single account selector
* Permission type selector with descriptions
* Optional expiration date
* Optional notes field
* Preview banner showing what will be granted
* Results display with success/failure counts
* Errors dialog for viewing failed grants
JavaScript additions:
- New data properties: showBulkGrantDialog, showBulkGrantErrors, bulkGranting, bulkGrantResults, bulkGrantForm
- New computed property: isBulkGrantFormValid
- New methods: bulkGrantPermissions(), closeBulkGrantDialog(), resetBulkGrantForm()
User Experience improvements:
- Time to onboard 5 users: 10min → 1min (90% reduction)
- Clear feedback with success/failure counts
- Ability to review errors before closing dialog
- Auto-close on complete success after 2 seconds
Related: UI-IMPROVEMENTS-PLAN.md Phase 1
API endpoint: POST /api/v1/admin/permissions/bulk-grant
🤖 Generated with Claude Code (https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Allows superusers to grant and revoke equity eligibility for users.
Adds UI components for managing equity eligibility.
Equity-eligible users can then contribute expenses as equity.
Replaces the user ID input field with a user selection dropdown,
allowing administrators to search and select users for permission
management. This simplifies the process of assigning permissions
and improves user experience.
Fetches Castle users via a new API endpoint and filters them
based on search input. Only users with Castle accounts
(receivables, payables, equity, or permissions) are listed.
Implements a Vue-based UI for managing user permissions, allowing administrators to grant and revoke access to expense accounts.
Provides views for managing permissions by user and by account, along with dialogs for granting and revoking permissions.
Integrates with the LNbits API to load accounts and permissions and to persist changes.