mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-18 11:56:01 +02:00
Add separate permission for AMS RFID re-read (Issue #204)
- Add new `printers:ams_rfid` permission for re-reading AMS RFID tags - Allows granting RFID re-read access without full printer control - Operators group includes this permission by default - Previously used `printers:control` which grants broader access - Permission available in Settings > Users > Group Editor Closes #204
This commit is contained in:
@@ -29,6 +29,11 @@ All notable changes to Bambuddy will be documented in this file.
|
|||||||
- Shows username on archive cards, library files, queue items, and printer cards (while printing)
|
- Shows username on archive cards, library files, queue items, and printer cards (while printing)
|
||||||
- Works when authentication is enabled; gracefully hidden when auth is disabled
|
- Works when authentication is enabled; gracefully hidden when auth is disabled
|
||||||
- Database migration adds `created_by_id` columns to `print_archives`, `library_files`, and `print_queue` tables
|
- Database migration adds `created_by_id` columns to `print_archives`, `library_files`, and `print_queue` tables
|
||||||
|
- **Separate AMS RFID Permission** (Issue #204):
|
||||||
|
- Added new `printers:ams_rfid` permission for re-reading AMS RFID tags
|
||||||
|
- Allows granting RFID re-read access without full printer control permissions
|
||||||
|
- Operators group includes this permission by default
|
||||||
|
- Available in Settings > Users > Group Editor as a toggleable permission
|
||||||
- **Schedule Button on Archive Cards** (Issue #208):
|
- **Schedule Button on Archive Cards** (Issue #208):
|
||||||
- Added "Schedule" button next to "Reprint" on archive cards for quick access to print scheduling
|
- Added "Schedule" button next to "Reprint" on archive cards for quick access to print scheduling
|
||||||
- Previously only available in the context menu (right-click)
|
- Previously only available in the context menu (right-click)
|
||||||
|
|||||||
@@ -1689,7 +1689,7 @@ async def refresh_ams_slot(
|
|||||||
printer_id: int,
|
printer_id: int,
|
||||||
ams_id: int,
|
ams_id: int,
|
||||||
slot_id: int,
|
slot_id: int,
|
||||||
_=RequirePermissionIfAuthEnabled(Permission.PRINTERS_CONTROL),
|
_=RequirePermissionIfAuthEnabled(Permission.PRINTERS_AMS_RFID),
|
||||||
db: AsyncSession = Depends(get_db),
|
db: AsyncSession = Depends(get_db),
|
||||||
):
|
):
|
||||||
"""Re-read RFID for an AMS slot (triggers filament info refresh)."""
|
"""Re-read RFID for an AMS slot (triggers filament info refresh)."""
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ class Permission(str, Enum):
|
|||||||
PRINTERS_DELETE = "printers:delete"
|
PRINTERS_DELETE = "printers:delete"
|
||||||
PRINTERS_CONTROL = "printers:control" # Start/stop/pause/resume prints
|
PRINTERS_CONTROL = "printers:control" # Start/stop/pause/resume prints
|
||||||
PRINTERS_FILES = "printers:files" # Send files to printer
|
PRINTERS_FILES = "printers:files" # Send files to printer
|
||||||
|
PRINTERS_AMS_RFID = "printers:ams_rfid" # Re-read AMS RFID tags
|
||||||
|
|
||||||
# Archives
|
# Archives
|
||||||
ARCHIVES_READ = "archives:read"
|
ARCHIVES_READ = "archives:read"
|
||||||
@@ -159,6 +160,7 @@ PERMISSION_CATEGORIES = {
|
|||||||
Permission.PRINTERS_DELETE,
|
Permission.PRINTERS_DELETE,
|
||||||
Permission.PRINTERS_CONTROL,
|
Permission.PRINTERS_CONTROL,
|
||||||
Permission.PRINTERS_FILES,
|
Permission.PRINTERS_FILES,
|
||||||
|
Permission.PRINTERS_AMS_RFID,
|
||||||
],
|
],
|
||||||
"Archives": [
|
"Archives": [
|
||||||
Permission.ARCHIVES_READ,
|
Permission.ARCHIVES_READ,
|
||||||
@@ -305,6 +307,7 @@ DEFAULT_GROUPS = {
|
|||||||
Permission.PRINTERS_DELETE.value,
|
Permission.PRINTERS_DELETE.value,
|
||||||
Permission.PRINTERS_CONTROL.value,
|
Permission.PRINTERS_CONTROL.value,
|
||||||
Permission.PRINTERS_FILES.value,
|
Permission.PRINTERS_FILES.value,
|
||||||
|
Permission.PRINTERS_AMS_RFID.value,
|
||||||
# Archives - own items only
|
# Archives - own items only
|
||||||
Permission.ARCHIVES_READ.value,
|
Permission.ARCHIVES_READ.value,
|
||||||
Permission.ARCHIVES_CREATE.value,
|
Permission.ARCHIVES_CREATE.value,
|
||||||
|
|||||||
@@ -1727,7 +1727,7 @@ export interface ExternalLinkUpdate {
|
|||||||
|
|
||||||
// Permission type - all available permissions
|
// Permission type - all available permissions
|
||||||
export type Permission =
|
export type Permission =
|
||||||
| 'printers:read' | 'printers:create' | 'printers:update' | 'printers:delete' | 'printers:control' | 'printers:files'
|
| 'printers:read' | 'printers:create' | 'printers:update' | 'printers:delete' | 'printers:control' | 'printers:files' | 'printers:ams_rfid'
|
||||||
| 'archives:read' | 'archives:create'
|
| 'archives:read' | 'archives:create'
|
||||||
| 'archives:update_own' | 'archives:update_all' | 'archives:delete_own' | 'archives:delete_all'
|
| 'archives:update_own' | 'archives:update_all' | 'archives:delete_own' | 'archives:delete_all'
|
||||||
| 'archives:reprint_own' | 'archives:reprint_all'
|
| 'archives:reprint_own' | 'archives:reprint_all'
|
||||||
|
|||||||
@@ -2291,18 +2291,18 @@ function PrinterCard({
|
|||||||
<div className="absolute top-full left-0 mt-1 z-50 bg-bambu-dark-secondary border border-bambu-dark-tertiary rounded-lg shadow-xl py-1 min-w-[120px]">
|
<div className="absolute top-full left-0 mt-1 z-50 bg-bambu-dark-secondary border border-bambu-dark-tertiary rounded-lg shadow-xl py-1 min-w-[120px]">
|
||||||
<button
|
<button
|
||||||
className={`w-full px-3 py-1.5 text-left text-xs flex items-center gap-2 ${
|
className={`w-full px-3 py-1.5 text-left text-xs flex items-center gap-2 ${
|
||||||
hasPermission('printers:control')
|
hasPermission('printers:ams_rfid')
|
||||||
? 'text-white hover:bg-bambu-dark-tertiary'
|
? 'text-white hover:bg-bambu-dark-tertiary'
|
||||||
: 'text-bambu-gray/50 cursor-not-allowed'
|
: 'text-bambu-gray/50 cursor-not-allowed'
|
||||||
}`}
|
}`}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
if (!hasPermission('printers:control')) return;
|
if (!hasPermission('printers:ams_rfid')) return;
|
||||||
refreshAmsSlotMutation.mutate({ amsId: ams.id, slotId: slotIdx });
|
refreshAmsSlotMutation.mutate({ amsId: ams.id, slotId: slotIdx });
|
||||||
setAmsSlotMenu(null);
|
setAmsSlotMenu(null);
|
||||||
}}
|
}}
|
||||||
disabled={isRefreshing || !hasPermission('printers:control')}
|
disabled={isRefreshing || !hasPermission('printers:ams_rfid')}
|
||||||
title={!hasPermission('printers:control') ? 'You do not have permission to control printers' : undefined}
|
title={!hasPermission('printers:ams_rfid') ? 'You do not have permission to re-read AMS RFID' : undefined}
|
||||||
>
|
>
|
||||||
<RefreshCw className={`w-3 h-3 ${isRefreshing ? 'animate-spin' : ''}`} />
|
<RefreshCw className={`w-3 h-3 ${isRefreshing ? 'animate-spin' : ''}`} />
|
||||||
Re-read RFID
|
Re-read RFID
|
||||||
@@ -2480,18 +2480,18 @@ function PrinterCard({
|
|||||||
<div className="absolute top-full left-0 mt-1 z-50 bg-bambu-dark-secondary border border-bambu-dark-tertiary rounded-lg shadow-xl py-1 min-w-[120px]">
|
<div className="absolute top-full left-0 mt-1 z-50 bg-bambu-dark-secondary border border-bambu-dark-tertiary rounded-lg shadow-xl py-1 min-w-[120px]">
|
||||||
<button
|
<button
|
||||||
className={`w-full px-3 py-1.5 text-left text-xs flex items-center gap-2 ${
|
className={`w-full px-3 py-1.5 text-left text-xs flex items-center gap-2 ${
|
||||||
hasPermission('printers:control')
|
hasPermission('printers:ams_rfid')
|
||||||
? 'text-white hover:bg-bambu-dark-tertiary'
|
? 'text-white hover:bg-bambu-dark-tertiary'
|
||||||
: 'text-bambu-gray/50 cursor-not-allowed'
|
: 'text-bambu-gray/50 cursor-not-allowed'
|
||||||
}`}
|
}`}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
if (!hasPermission('printers:control')) return;
|
if (!hasPermission('printers:ams_rfid')) return;
|
||||||
refreshAmsSlotMutation.mutate({ amsId: ams.id, slotId: htSlotId });
|
refreshAmsSlotMutation.mutate({ amsId: ams.id, slotId: htSlotId });
|
||||||
setAmsSlotMenu(null);
|
setAmsSlotMenu(null);
|
||||||
}}
|
}}
|
||||||
disabled={isHtRefreshing || !hasPermission('printers:control')}
|
disabled={isHtRefreshing || !hasPermission('printers:ams_rfid')}
|
||||||
title={!hasPermission('printers:control') ? 'You do not have permission to control printers' : undefined}
|
title={!hasPermission('printers:ams_rfid') ? 'You do not have permission to re-read AMS RFID' : undefined}
|
||||||
>
|
>
|
||||||
<RefreshCw className={`w-3 h-3 ${isHtRefreshing ? 'animate-spin' : ''}`} />
|
<RefreshCw className={`w-3 h-3 ${isHtRefreshing ? 'animate-spin' : ''}`} />
|
||||||
Re-read RFID
|
Re-read RFID
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
+1
-1
@@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
<!-- Splash screens for iOS -->
|
<!-- Splash screens for iOS -->
|
||||||
<link rel="apple-touch-startup-image" href="/img/android-chrome-512x512.png" />
|
<link rel="apple-touch-startup-image" href="/img/android-chrome-512x512.png" />
|
||||||
<script type="module" crossorigin src="/assets/index-D56fK0KZ.js"></script>
|
<script type="module" crossorigin src="/assets/index-1q7Yxq-H.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="/assets/index-CPqcJWwC.css">
|
<link rel="stylesheet" crossorigin href="/assets/index-CPqcJWwC.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
Reference in New Issue
Block a user