Skip to content

✨ Add home page section preferences - #1392

Open
devy1540 wants to merge 8 commits into
stumpapp:nightlyfrom
devy1540:feat/home-arrangement
Open

devy1540 wants to merge 8 commits into
stumpapp:nightlyfrom
devy1540:feat/home-arrangement

Conversation

@devy1540

@devy1540 devy1540 commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Description

Home page sections currently have a fixed order and cannot be hidden. This adds an editor under Preferences → Home page to show or hide the four existing sections, reorder them by dragging or keyboard, and save the layout per user. Reset restores the default order and visibility. When every section is hidden, the home page provides a link back to preferences.

This implements the home-section portion of #245.

  • Match the navigation arrangement editor's styling, with eye-icon visibility controls and small Reset, Cancel, and Save buttons in the header. Save keeps its label while pending; failures use a short toast title and the error message as its description.
  • Add updateHomeArrangement and apply the same normalization when reading saved home sections: keep the first supported occurrence of each section, preserve its order and visibility, and append missing sections as hidden.
  • Use ordinary tagged Serde serialization. Unreadable arrangement JSON falls back to the corresponding default configuration; the next save writes the current format. Decoding happens at the arrangement-field boundary so a bad configuration does not prevent loading the user's preferences.
  • Remove unused links fields from the built-in home section configurations.
  • Render and prefetch enabled sections in the saved order. Successful saves update the query cache and cancel older in-flight reads; failed saves retain the draft for retry.

The shared server API can support a future mobile implementation. This PR adds the web editor and updates its documentation.

LLM tooling assisted with this contribution.

Validation

  • Browser tests: 274 passed, including keyboard ordering, visibility, reset and invalid-configuration recovery, save failure/retry, rendering, prefetching, and stale-read handling.
  • Model tests: 78 passed, including tagged JSON round trips and section normalization.
  • Server integration tests: 60 passed. Home-specific cases cover saved order/visibility, normalization on reads and writes, and unreadable-config fallback followed by a successful save.
  • Browser TypeScript checks, production web build, Rust formatting, Clippy for models and graphql, GraphQL schema consistency, and client generation passed.
  • Browser ESLint: 0 errors; 17 warnings remain in existing files outside this change.
  • Revalidated in Chrome using a temporary local database and empty library: keyboard reordering, visibility, cancellation, saving and reload, all-hidden recovery, and Reset. Stopping the test server confirmed the error toast and draft retention; restarting it allowed the same draft to be saved.
  • Rechecked after merging nightly: aligned the home test with react-router and added explicit hook return types to fix declaration generation.

Ready?

  • I read the contributing guidelines
  • I searched for existing issues or pull requests that may be related to my contribution
  • This PR targets nightly and not main
  • I added tests and documentation for my changes
  • I disclosed the use of LLMs in this PR

Stump Contributor License Agreement

By contributing to Stump, you agree that your contributions will be licensed under the following licenses (where applicable):

@aaronleopold aaronleopold left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for working on this, I reviewed the changes this morning and have some feedback

Comment thread apps/server/tests/graphql/home_arrangement.rs Outdated
Comment thread crates/graphql/src/mutation/user.rs Outdated
Comment thread crates/models/src/shared/arrangement.rs Outdated
Comment thread crates/models/src/shared/arrangement.rs Outdated
Comment thread crates/models/src/shared/arrangement.rs Outdated
Comment on lines +185 to +186
#[graphql(default)]
links: Vec<FilterableArrangementEntityLink>,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OnDeck does not need links, there are a few others that make similar mistake (e.g., preexisting InProgressBooks). I do recall, although it was really some time ago, adding them for a future where there is a See all button but I think until that point it is simpler to remove until needed

.home_arrangement
.clone()
.unwrap_or(Arrangement::default_home())
.with_missing_home_sections()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mentioned removing this earlier, so perhaps all existing ones still need to flow through new() or something in case they need cleaning

Comment thread apps/server/tests/graphql/home_arrangement.rs Outdated
Comment thread apps/server/tests/graphql/home_arrangement.rs Outdated
Comment thread apps/server/tests/graphql/home_arrangement.rs Outdated
Comment thread apps/server/tests/graphql/home_arrangement.rs Outdated
@codecov

codecov Bot commented Sep 6, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 91.06145% with 16 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
crates/models/src/shared/arrangement.rs 90.41% 14 Missing ⚠️
crates/graphql/src/input/user.rs 0.00% 1 Missing ⚠️
crates/models/src/entity/user.rs 0.00% 1 Missing ⚠️
Files with missing lines Coverage Δ
crates/graphql/src/mutation/user.rs 14.58% <100.00%> (+14.58%) ⬆️
crates/graphql/src/object/user_preferences.rs 75.00% <ø> (+75.00%) ⬆️
crates/models/src/entity/user_preferences.rs 50.00% <100.00%> (+31.81%) ⬆️
crates/graphql/src/input/user.rs 0.00% <0.00%> (ø)
crates/models/src/entity/user.rs 45.16% <0.00%> (+0.48%) ⬆️
crates/models/src/shared/arrangement.rs 90.95% <90.41%> (+87.00%) ⬆️

... and 3 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@devy1540

devy1540 commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the detailed review, @aaronleopold! I've pushed updates addressing your feedback and merged the latest nightly changes. Whenever you have a chance, I'd appreciate another look. Happy to make any further adjustments!

@aaronleopold aaronleopold left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for making those updates! I have one remaining point, but otherwise I think this looks good

Comment on lines +56 to +60
pub navigation_arrangement: Option<Json>,
#[sea_orm(column_type = "Json", nullable)]
#[graphql(skip)]
#[serde(default = "Model::default_home_arrangement")]
pub home_arrangement: Option<Arrangement>,
pub home_arrangement: Option<Json>,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I like this one, instead we could maybe manually implement FromJsonQueryResult with a safer parse? Otherwise this cuts a bit from a dx-perspective. I think a lot of the changes in this file go away if we do that, as well

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the suggestion! Addressed in 9274ad7.

Both fields are back to Option<Arrangement>. The manual SeaORM JSON conversion treats unreadable stored configurations as absent, allowing home and navigation to use their respective defaults without losing other preferences. This removes the explicit JSON conversions from callers while preserving home section normalization.

SQLite tests cover valid and invalid configurations, preservation of other preferences, and recovery on the next save without modifying stored data during reads. Model, GraphQL, and server tests passed, along with formatting and schema checks.

The broader all-target Clippy check reports four existing lint errors on local Rust 1.98; I confirmed the same errors on the unchanged PR head.

devy1540 and others added 2 commits September 14, 2026 15:27
설정 필드를 Option<Arrangement>로 복원하고 저장 JSON의 구조 오류를 DB 조회 단계에서 None으로 처리한다.

홈과 탐색 설정, 인증 사용자 경로의 수동 JSON 변환을 제거하고 각 기본값과 홈 섹션 정규화를 유지한다. SQLite 회귀 테스트로 설정 보존과 조회 후 저장 복구를 확인한다.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants