Feature/uxp e03 portfolios empty - #522
Closed
David-Tenni wants to merge 1884 commits into
Closed
Conversation
Co-authored-by: Cursor <cursoragent@cursor.com>
…s page Completes IN-05. Web PR #28 added bulk actions to the header dropdown only, and the dropdown is hidden at the xs breakpoint, so on a phone there was no way to clear or delete a notification at all. Adds a Mark all read control, a per-row delete behind a confirmation dialog, and screen reader labels naming the notification being deleted. The delete button is a sibling of the row rather than nested inside it, because a button inside a button is not valid html and the browser unnests them. Also handles the cases that only show up in use: marking all read is not offered when nothing is unread, a failed delete keeps the row, deleting the last row on the last page pulls the reader back a page, and a list read still in flight is dropped when either action fires so a stale response cannot overwrite the list or strand a spinner. Tests: 15 new cases, taking the notifications page spec Full web suite 64 files, 227 tests, 0 failures. Built against doubtfire-web feature/notifications f5c4b5b, doubtfire-api feature/notifications d3be7c79f, and doubt 11.0.x 5d2c8b409.
11.0.x split doubtfire-constants.ts into loadPublicSettings(), which runs pre-auth through HttpBackend, and applyAuthenticatedSettings(), which authentication.service.ts calls once a token exists. IsPushEnabled and VapidPublicKey move into applyAuthenticatedSettings. They used to be read at bootstrap from the unauthenticated /settings, and GET /settings is authenticated on 11.0.x, so leaving them at bootstrap would have left push permanently off with nothing on screen to explain why. The two fields are optional on AuthenticatedSettingsResponseFormat so the web can run against an API that has not taken the api-side change yet, and so doubtfire-constants.spec.ts still type checks. Built against doubtfire-web feature/notifications f5c4b5b merged with 11.0.x 6b82a61, doubtfire-api feature/notifications d3be7c79f, and doubtfire-deploy 11.0.x 5d2c8b409.
…rd (CPD-Q06) * docs: add privacy-safe screenshot checklist for Cross-Project Dashboard (CPD-Q06) (cherry picked from commit df15f62) * docs: strengthen screenshot redaction guidance (CPD-Q06) --------- Co-authored-by: jmirchh75 <jmirch@live.com>
* Add GitHub Actions workflow to notify Teams on PRs * fix(ci): gate the Teams notifier and harden its payload Adds a job guard so the webhook is unreachable from anonymous fork pull requests on these public repositories, and so the file is inert if it ever travels to thoth-tech or doubtfire-lms. Adds reopened and ready_for_review, which is the transition a reviewer alert exists to catch, and varies the headline per action so it stays accurate. Strips Markdown link and code syntax from the title, author and head label before they reach the channel. Joins on a double newline, which is what Teams renders as a break. Reports the real HTTP status instead of asserting a delivery the workflow never checked. --------- Co-authored-by: Clupai8o0 <clupaio4@gmail.com>
Refactor Teams notification to use Adaptive Card
Bumps and [brace-expansion](https://github.com/juliangruber/brace-expansion). These dependencies needed to be updated together. Updates `brace-expansion` from 5.0.6 to 5.0.9 - [Release notes](https://github.com/juliangruber/brace-expansion/releases) - [Commits](juliangruber/brace-expansion@v5.0.6...v5.0.9) Updates `brace-expansion` from 5.0.7 to 5.0.9 - [Release notes](https://github.com/juliangruber/brace-expansion/releases) - [Commits](juliangruber/brace-expansion@v5.0.6...v5.0.9) Updates `brace-expansion` from 2.1.1 to 2.1.4 - [Release notes](https://github.com/juliangruber/brace-expansion/releases) - [Commits](juliangruber/brace-expansion@v5.0.6...v5.0.9) --- updated-dependencies: - dependency-name: brace-expansion dependency-version: 5.0.9 dependency-type: indirect - dependency-name: brace-expansion dependency-version: 5.0.9 dependency-type: indirect - dependency-name: brace-expansion dependency-version: 2.1.4 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com>
Bumps [ip-address](https://github.com/beaugunderson/ip-address) from 10.2.0 to 10.5.0. - [Release notes](https://github.com/beaugunderson/ip-address/releases) - [Commits](beaugunderson/ip-address@v10.2.0...v10.5.0) --- updated-dependencies: - dependency-name: ip-address dependency-version: 10.5.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com>
Simplified the conditional check for PR notifications.
…n-click feat(notifications): navigate on push notification click
…anage focus Mark all read had no success handler, so the only feedback was rows losing their bold and a dot going grey. It now announces through AlertService. The button also moved from @if to disabled, but a native disabled attribute does not solve the focus problem it was meant to: a natively disabled button cannot hold focus either, so the browser drops it to the body just the same. disabledInteractive is Material's input for exactly this, buttons that become disabled when activated. It announces via aria-disabled and stays focusable, so markAllRead re-checks hasUnread rather than trusting the binding. The block stays inside an @if on the list length so a greyed control never sits over the loading, failed or empty states. The confirmation dialog closes as soon as it is agreed to and the row is not dropped until the response lands, so the same delete could be confirmed twice and the second request 404s. Ids with a request in the air are held and the button marked disabled, with disabledInteractive again so MatDialog can still restore focus to it. Focus after a removal now lands on the row that took the deleted one's place, clamped to what is on screen so a page collapse does not jump to the top, and only when focus actually went to the body, so a slow delete cannot take it back from wherever the reader moved to. The dialog also now names the notification, which the button's aria-label already did and the modal covering the list dropped.
…x/pr44-fix-20260823 # Conflicts: # src/app/common/notifications-page/notifications-page.component.ts
…coverage fix(routes): apply the role guard to every staff route
…key-events fix(a11y): give hover reveals a focus path and enable the lint rule
…-unsaved-guard fix(unit-tasks): stop an unsaved task definition being discarded without asking
…-route-param fix(task-viewer): follow taskAbbreviation changes in the route
…empty-body fix(http): handle an error response with an empty body
…ft-user-scope fix(comments): scope comment drafts to the signed in user and clear them on sign out
# Conflicts: # src/app/units/states/tasks/inbox/directives/staff-task-list/staff-task-list.component.spec.ts
…follows-navigation fix(units): follow the route when the unit changes
…board-followup-20260828 fix(dashboard): complete mobile navigation and feedback routing
…-url-20260828 fix(auth): restore notification destination after sign in
…ns page (UXP-E01)
…d-tasks list (UXP-L01)
…-skeleton Jira ticket: UXP-L01 Summary: Adds a small reusable f-skeleton-loader standalone component (shape and repeat-count inputs) that wraps the already-installed ngx-skeleton-loader, and applies it to the loading state of the portfolio included-tasks list, replacing the bare spinner with row-shaped placeholders. Target branch: feature/ui-polish Testing: npx tsc --noEmit passes against src/tsconfig.app.json and src/tsconfig.spec.json. Added skeleton-loader.component.spec.ts (defaults to 3 row placeholders, renders the configured count, renders none for a count of zero, a discriminating test that row and card shapes render different placeholder heights, and that the placeholder group is aria-hidden). Added portfolio-included-tasks.component.spec.ts, which did not exist before (skeleton renders with shape row and count 4 while the load is pending, is replaced by the real list once the load resolves, and gives way to the existing "No tasks found" state when the load resolves empty). Build and test:ci run in CI, since the dev container mounts a different checkout than this branch. Security and privacy: No data model or API change. Presentational component only. No student data involved. Evidence: An after screenshot of the skeleton loading state will be attached. fixed these One thing blocks merge: lint (22) is red on prettier import ordering, and the job runs --max-warnings 0. I reproduced both against .prettierrc (the @trivago sort-imports plugin). Two one-line moves fix it: skeleton-loader.component.ts: unmatched third-party imports sort before the @angular group, so put the ngx-skeleton-loader line above the @angular/core line. portfolio-included-tasks.component.spec.ts: within the src/app group the entries must be alphabetical, so move the AlertService import (common/services/alert.service) above the SkeletonLoaderComponent import (common/skeleton-loader/...), since "se" sorts before "sk". Easiest is to run npx prettier --write on those two files, which produces exactly those two changes and nothing else. Once lint is green this is good to merge. Not blocking: ChangeDetectionStrategy.Eager is valid in Angular 22 (it is the renamed Default and matches the sibling component), so no change needed there.
…UXP-E01-empty-state # Conflicts: # src/app/doubtfire-angular.module.ts
…-empty-state feat(ui): add reusable empty-state component and apply to notificatio…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Jira ticket
UXP-E03
Summary
Replaces the bare "No students found" cell in the portfolios list table with the shared f-empty-state component in a full-width colspan cell, matching the pattern from UXP-E01.
Target branch
feature/ui-polish
Testing
tsc --noEmit, prettier --check, and eslint all pass on the changed files. Added a discriminating spec that asserts f-empty-state renders when the list is empty and disappears once rows are present. Build and full test suite run in CI.
Built and tested against:
Security and privacy
No known security or privacy impact. Presentational component only; no data model or API change, no student data.
Evidence
After screenshot of the portfolios-list empty state attached below.
Checklist