Commit Graph

696 Commits

Author SHA1 Message Date
REDCODE
d1f545bb59 fix(ui): restore progress bar visibility on job rows
d-none d-sm-flex hides the progress bar but also changes its
display from inline to flex on desktop, breaking visibility.
Remove the hide-class — the progress bar is always shown.
2026-07-09 03:31:49 +02:00
REDCODE
584e24d751 fix(ui): replace inline save indicator with Bootstrap toast notification
SettingBox base now uses JS interop to call showToast() which
renders a Bootstrap Toast at the bottom-right corner. Removed
all SaveIndicator RenderFragments and IsSaving/IsSaved state
from the four child components. Toast auto-hides after 2s.
2026-07-09 02:58:01 +02:00
REDCODE
ea25eca9fa fix(ui): right-align number inputs, let them grow to fill card width
Replace w-auto with text-end+flex-grow-1 so the number input
right-aligns its value text and adapts its width on narrow
setting cards.
2026-07-09 02:55:03 +02:00
REDCODE
b8f0eea848 fix(ui): stack setting card body vertically — description above, control + indicator below
Remove d-flex justify-content-between from all card bodies.
Description always sits above the input/control row, and the save
indicator sits inline on the same row as the control. Removed
mobile-specific stacking workaround and save-indicator CSS class
since layout shift is impossible with this structure.
2026-07-09 02:44:10 +02:00
REDCODE
b417f37780 fix(ui): prevent save indicator from shifting adjacent controls
Always render the save indicator container with a fixed 5rem min-width,
only toggle the inner text/color. Previously the conditional Rendering
caused the element to appear-disappear-resize, shifting nearby inputs.
2026-07-09 02:39:39 +02:00
REDCODE
f52b684722 fix(ui): prevent layout shift from save indicator width change
Add .save-indicator CSS class with fixed min-width (4rem) and
text-align:right. Apply to all four setting box types so
'Saving...'→'Saved' text change doesn't shift adjacent
controls.
2026-07-09 02:27:00 +02:00
REDCODE
5c15f89f59 fix(ui): stack setting card description and control vertically on mobile
On ≤576px viewports, switch card body from side-by-side to
stacked layout: description text on top, input/slider
control below. Prevents text clipping and control overflow.
2026-07-09 02:26:24 +02:00
REDCODE
f2e2997988 fix(ui): reduce password input width on AdminUsers to prevent cell overflow
Tighten password inline-edit input from 80-120px to 60-100px
so it fits alongside confirm/cancel buttons in narrow
mobile table cells.
2026-07-09 02:26:04 +02:00
REDCODE
1589c7fe29 fix(ui): change AdminUsers mobile actions dropdown from dropup to dropdown
dropup opens upward and clips off-screen for the first table rows.
Use standard dropdown (downward) which works correctly for
all row positions.
2026-07-09 02:25:42 +02:00
REDCODE
5e23180c7c fix(ui): prevent JobRow horizontal overflow on mobile portrait
Hide non-essential columns (child summary, dates/progress bar,
elapsed time) on mobile using d-none d-sm-inline/d-sm-flex.
Add flex-wrap to main row for overflow safety on very
narrow viewports.
2026-07-09 02:25:24 +02:00
MrFastwind
f8eafed093 fix(milkystream): Fix sorted masonry for albums 2026-07-09 02:08:35 +02:00
MrFastwind
debd0dd4af Revert "refactor: replace custom masonry JS with Bootstrap grid + Masonry.js approach"
This reverts commit 04d425b88d.
2026-07-09 02:07:16 +02:00
REDCODE
04d425b88d refactor: replace custom masonry JS with Bootstrap grid + Masonry.js approach
Use Bootstrap's recommended pattern: .row.g-2 container with col-* grid
classes for item widths, Masonry.js with percentPosition:true for
vertical positioning. Extracted infinite scroll observers into separate
infiniteScroll.js. Removed custom column-width JS, imagesLoaded CDN,
and the old masonryObserver.js.
2026-07-09 01:51:38 +02:00
REDCODE
ca21dc3dd9 fix(frontend): removed faulty d-flex tag on main object 2026-07-09 00:57:58 +02:00
f4d4b6a75a Merge branch 'develop' into fix/mobile-ui-responsive-fixes 2026-07-08 21:33:43 +00:00
REDCODE
4ff3b24df8 Merge remote-tracking branch 'gitea/develop' into develop 2026-07-08 23:33:05 +02:00
REDCODE
1da7236d5d fix(frontend): sorts setting by alphabetical 2026-07-08 23:32:46 +02:00
MrFastwind
df14b8b227 fix (lactose): remove check from authentication endpoint
ref: #36
2026-07-08 23:04:51 +02:00
MrFastwind
15508013a3 Merge remote-tracking branch 'origin/develop' into develop
# Conflicts:
#	Lactose/Controllers/UserController.cs
2026-07-08 22:39:20 +02:00
MrFastwind
cb47336230 fix(Lactose): Change to use UtcNow, even if alredy working without timeline 2026-07-08 22:38:05 +02:00
76cabe058b fix(ui): collapse AdminUsers table columns and actions on mobile (#48)
- Hide Email and Created columns below md breakpoint (d-none d-md-table-cell)
- Hide Last Login below lg breakpoint (d-none d-lg-table-cell)
- Replace action btn-group with dropdown menu on mobile (d-sm-none)
- Reduces table from 7 visible columns to 4 on mobile
2026-07-08 19:51:48 +02:00
33175ffdcb fix(ui): responsive layout fixes for mobile portrait mode (closes #48)
- Settings: stack sidebar vertically on mobile, fix grid minmax 380->280px, use dvh
- AlbumDetail: add mobile breakpoints for grid, restructure header actions
- ImagePreview: switch info bar to column layout on mobile
- User profile: fix col-2/col-2 to responsive col-5/col-7 breakpoints
- AdminUsers: wrap inline editing controls with flex-wrap on mobile
- Jobs: collapse 8 action buttons into dropdown on mobile
- Albums: add flex-wrap to header, hide 'New Album' text on mobile
- NavMenu: responsive authenticated area (column on mobile, btn-group-sm)
- Empty-state messages: m-5 -> m-2 m-sm-5
- Footer: hide on mobile (d-none d-sm-flex)
- Login: remove orphaned 'Remember me' checkbox
2026-07-08 19:49:11 +02:00
54cf5eff2b feat(stats): add percentage and stale counters to completeness cards
- Show percentage of total assets on missing metadata/thumbnail/preview/phash cards
- Add stale counts for thumbnails and previews (generated at wrong resolution vs current settings)
- Add h-100 to all completeness cards for consistent row heights
2026-07-08 19:45:09 +02:00
94bba45f45 Merge branch 'feature/admin-users-page' into develop
Admin user management page (#45)
2026-07-08 19:18:29 +02:00
23ef7e3ded fix(auth): detect banned/deleted user on page load via InitializeAsync
- LoginService.InitializeAsync: after fetching LoggedUser, check IsBanned
  and DeletedAt. If banned/disabled, set ForceLogoutReason, call Logout
  to clear state, and return false
- App.razor: after InitializeAsync completes, check ForceLogoutReason
  and navigate to /login if set. This handles the timing issue where
  MainLayout isnt created yet when the event fires on page load

Refs #45
2026-07-08 19:15:49 +02:00
a84d93882d fix(auth): show ban/disabled message on login and force-logout on refresh
- AuthController: fix HTTP 100 Continue → 403 Forbidden for banned/disabled
  users in both Login and RefreshToken endpoints
- LoginService.Login: return error message from AuthResultDto on failure
  instead of a generic message
- LoginService.Reauthenticate: parse AuthResultDto on refresh failure;
  if "User is banned" or "User is disabled", trigger force logout via
  new ForceLogout event, setting ForceLogoutReason property
- MainLayout: subscribe to ForceLogout event, redirect to /login
- Login.razor: display specific error messages (ban reason, force-logout
  reason) instead of generic "Login failed"

Refs #45
2026-07-08 19:10:53 +02:00
0ec6888809 fix(admin): show inline errors instead of replacing entire page
- Moved error/success alerts inside the main content block (else branch)
  so validation errors (empty email, username, etc.) do not hide the table
- Added dismissible error alert with ClearError method
- Added clearError method to code-behind
- Fixed broken @if(_showCreateForm) guard for create form

Refs #45
2026-07-08 19:00:08 +02:00
977d2325fa feat(admin): add inline editing for username, email, and password
- Username and email columns now have pencil-to-edit with confirm/cancel
- Actions column gains a key button to change password inline
- Validation: empty username/email/password rejected with error message
- Unified CancelFieldEdit clears all edit modes at once

Refs #45
2026-07-08 18:56:52 +02:00
20975a2872 fix(ui): remove broken onfocusout handler from role edit dropdown
- onfocusout on the wrapper span was firing when focus moved to child buttons,
  cancelling the edit before the button onclick handlers ran
- Confirm/cancel now works via explicit button clicks only
- Starting a new edit on a different row implicitly cancels the previous one

Refs #45
2026-07-08 18:54:49 +02:00
61cf886174 fix(user): hash password in Create endpoint instead of storing raw
- UserController.Create was assigning userCreateDto.Password directly without
  hashing via IPasswordHasher, unlike the Update method and AuthController
- Moved duplicate email/username checks before User object instantiation

Refs #45
2026-07-08 18:53:46 +02:00
bf638ca995 fix(admin): add confirm/cancel for role change and prevent admin self-demotion
- Role dropdown now uses explicit confirm (checkmark) / cancel (X) buttons
  instead of auto-committing on selection
- Clicking outside the dropdown cancels the edit (onfocusout)
- Selecting the same role as current is a no-op
- Admins cannot demote themselves below Admin level

Refs #45
2026-07-08 18:52:27 +02:00
a599648d87 feat(admin): add user management page for admins
- Add AdminUsers.razor page at /Users with user listing, ban/unban toggle,
  access level change, delete, and create user functionality
- Extend UserService with GetAllUsersAsync, GetUserByIdAsync,
  UpdateUserAsync, DeleteUserAsync, CreateUserAsync methods
- Add Users link to NavMenu dropdown for admin users
- Fix ban/unban bug in UserController where BannedAt was only updated
  if the user had been previously banned

Closes #45
2026-07-08 18:47:01 +02:00
e5fc1a017e chore: remove debug auth logging middleware from Program.cs 2026-07-08 18:08:48 +02:00
44394daebf fix(AlbumController): exclude deleted assets from search visibility for #11
Album search for User role used asset.IsPubliclyShared and
SharedWith checks without filtering soft-deleted assets. A deleted
public asset would cause its album to appear in search results.

Added asset.DeletedAt == null checks to both filter paths.

Refs: #11
2026-07-08 17:49:08 +02:00
ac76aab168 fix(AssetController): correct search visibility filter for #11
The User-role asset search filter had two bugs:
1. DeletedAt != null was negated — shared non-deleted assets were
   excluded, while shared deleted assets passed the filter.
2. DeletedAt check was applied only to the shared leg — public
   deleted assets leaked through the filter.

Corrected to: not-deleted AND (public OR shared), matching the
logic used by GET /api/asset/{id}.

Refs: #11
2026-07-08 17:47:43 +02:00
4f56acb320 fix(controllers): tighten asset visibility and media access checks
- AlbumController GET {id}: exclude soft-deleted assets for User role
  (public/owned and shared paths) and Curator role (viewed all assets)
- AssetController GET: add explicit parentheses to DeletedAt operator
  grouping in search filter to match intent
- MediaController: deny Curators direct file access to deleted assets;
  extract CanAccessAssetDirectly helper method

Refs: #11
2026-07-08 17:44:03 +02:00
70fe586fc6 fix: force square aspect-ratio in grid mode over inline style
- Inline style aspect-ratio:W/H overrides CSS aspect-ratio:1
- !important needed to force square crop in grid tiles
2026-07-08 16:44:40 +02:00
58bd4ee766 fix: override masonry inline styles with !important for grid mode
- JS masonry sets position/width/left/top/height as inline styles on tiles
- Grid CSS uses !important to override inline styles for proper layout
- Force StateHasChanged on mode switch to ensure re-render
2026-07-08 16:36:46 +02:00
3d789d68e7 refactor: remove list view, add grid/masonry toggle to album detail
- Albums page: drop list mode, keep masonry and grid
- AlbumDetail page: add masonry/grid toggle in header
- Masonry mode uses JS masonryLayout, grid mode uses CSS grid with square tiles
2026-07-08 16:32:30 +02:00
9327a739f8 feat: view mode selector for albums page (masonry/grid/list)
- Button group in header: masonry (columns), grid (square tiles), list (rows)
- CSS-driven mode switching via album-grid.masonry/.grid/.list classes
- List mode: horizontal card with thumbnail left, info right
2026-07-08 16:19:47 +02:00
de731095cc fix: use CSS columns for albums page, keep JS masonry only for album detail
- Albums page: remove masonryLayout JS call, use column-count CSS (reliable, no ordering needed)
- AlbumDetail: keeps JS masonryLayout for left-to-right alphabetical ordering with varying heights
2026-07-08 16:18:03 +02:00
696ea613de revert: switch album detail back to masonry layout 2026-07-08 14:52:38 +02:00
9b17b6b231 fix: faulty migration that could cause lactose crash on migration apply 2026-07-08 14:47:54 +02:00
b1d5356220 feat: justified gallery layout for album detail page
- New justifiedLayout.apply JS function: uniform row heights, automatic widths
- Reads aspect-ratio from tile inline style, fills each row to container width
- AlbumDetail calls justifiedLayout in OnAfterRenderAsync
- Albums page stays on masonryLayout
2026-07-08 14:19:19 +02:00
37dad0d1d7 fix: JS-based masonry for left-to-right item flow with varying heights
- Add masonryLayout.apply JS function using shortest-column-next algorithm
- Both Albums and AlbumDetail call masonryLayout on each render
- Items flow left-to-right in alphabetical order, each keeping its own aspect-ratio height
- Remove CSS column-count in favor of absolute positioning by JS
2026-07-08 14:10:51 +02:00
c5e41f2c05 fix: unlock body scroll on navigation, reorder masonry for left-to-right flow
- Home.DisposeAsync now unlocks body scroll so navigation to other pages works
- Albums and AlbumDetail unlock body scroll on init as defense
- Reorder items with column-major index mapping so CSS columns display left-to-right
- Switch both pages back to column-count CSS for reliable masonry
- Add pageLayout.columnCount JS helper matching media query breakpoints
2026-07-08 14:05:31 +02:00
d45a915ba9 fix: use flexbox with align-items:flex-start for album detail grid
- CSS Grid forces uniform row heights, cropped landscape images next to portraits
- Flexbox with align-items:flex-start preserves each tile's own aspect-ratio height
- align-content:flex-start ensures container height grows for scrolling
2026-07-08 13:58:37 +02:00
b7d1912fc6 fix: switch album detail grid from flexbox to CSS Grid
- Flexbox was collapsing with aspect-ratio tiles, preventing scroll
- CSS Grid with repeat(N, 1fr) fills left-to-right with proper row heights
2026-07-08 13:54:20 +02:00
d51efe8b3c fix: remove content-visibility and contain-intrinsic-size from album detail tiles
- These properties overrode aspect-ratio in flexbox layout, causing all tiles to render at 200px regardless of actual dimensions
2026-07-08 13:52:56 +02:00
48a97beb74 fix: remove preventDefault from album links so they actually navigate
- @onclick:preventDefault was canceling the browser's link navigation
- @onclick:stopPropagation alone suffices to prevent tile click
2026-07-08 13:51:33 +02:00