Skip to content

refactor(web): restore interface for managing DASD from web client#3143

Merged
joseivanlopez merged 51 commits intoagama-project:masterfrom
joseivanlopez:dasd-ui-api-v2
Feb 27, 2026
Merged

refactor(web): restore interface for managing DASD from web client#3143
joseivanlopez merged 51 commits intoagama-project:masterfrom
joseivanlopez:dasd-ui-api-v2

Conversation

@joseivanlopez
Copy link
Copy Markdown
Contributor

@joseivanlopez joseivanlopez commented Feb 11, 2026

Bring back the DASD user interface fully adapted to the HTTP v2 API and to the latest web client look&feel (https://trello.com/c/xdvueNDg/, private link)

Warning

The format progress has not been adapted as part of this PR and will be addressed in a follow up one.

@joseivanlopez joseivanlopez force-pushed the dasd-ui-api-v2 branch 2 times, most recently from a66d780 to 3a239fd Compare February 11, 2026 16:24
@coveralls
Copy link
Copy Markdown

coveralls commented Feb 11, 2026

Coverage Status

coverage: 74.814% (-0.2%) from 74.989%
when pulling aead77c on joseivanlopez:dasd-ui-api-v2
into 5db0028 on agama-project:master.

- It makes easier to generate the types for the UI.
Apply only the minimal required changes (including commenting out
lines) to satisfy linters and the test suite, providing a clean
baseline for adapting the DASD web UI to the new API.

Upcoming work will likely require updating the DASDTable component
to support two modes: config and system, and to handle both device
types accordingly.
Add tests for useAddDevice and useRemoveDevice while eliminating
duplicate helper functions that simply wrapped model/config/dasd calls.

Hooks now call model/config/dasd#addDevice and removeDevice directly
instead of maintaining wrapper functions.

The separation between model/config/dasd and hooks/model/config/dasd is
worth to be re-evaluated, since consolidating them might help to reduce
indirection and ease testing, as the hooks already provide the primary
interface..

Commit also adds test-utils/tanstack-query for query-key-based mocking
when hooks share modules with their dependencies.
And also add some more for dasd#useConfig hook based on the ones added
for useSystem.
Needed for merging information from both hooks at dasd, useConfig and
useSystem.

There was a "mergeSources" utils added previously in the iSCSI context
that it's not valid for what is needed now. Most probably, iSCSI would
move in the DASD behavior direction and mergeSource deprecated or drop.
Previously, extendCollection returned only items from the base
collection extended with data from the extension collection. Now returns
an object with both extended and unmatched items, enabling use cases
like:
  - Identifying which extension items have no match in the base collection
  - Validation and reporting without additional filtering
  - Single source of truth for both intersection and difference

Before:
  const result = extendCollection(config, { with: system, matching: 'id' })

After:
  const { extended } = extendCollection(config, { with: system, matching: 'id' })
Drop the in-table empty state approach (Bullseye inside a colSpan Td) in
favor of an early return.

Rendering the empty state outside and instead of the table is a better
approach since it avoids visual noise from sortable column headers that
would be rendered but serve no purpose with no data to sort.

Also fix a typo in the documentation ("single" -> "none").
And write pending tests, although one of them has to be skipped until
the code will be refactored to satisfy it.
Still pending some refactorizations and, more important, the call to the
setConfig request when an action is performed. Also, worth reviewing
when an action is shown and when not.
dgdavid and others added 2 commits February 23, 2026 13:19
Accepts an optional filter predicate to exclude entries from the result.
Useful when building filter selectors from translated option maps.
dgdavid and others added 10 commits February 25, 2026 17:42
Partial rollback of changes done in commit
b83d94b.

Row actions are always available and act only on their own device, while
the bulk toolbar acts on the current selection.

Previously, row actions were hidden when devices were selected in order
to avoid confusion between single-device and bulk actions. However, this
would cause accessibility issues for keyboard and screen reader users
who would lose their interaction point mid-navigation with no clear
guidance on where actions had moved.

Alternatives were explored but discarded:

  - Disabling the toggle: while keyboard navigation is preserved, the
    "more" icon (three horizontal dots) is already rendered in a muted
    gray style making it practically indistinguishable from its disabled
    state. Combined with PatternFly's Tooltip not triggering on disabled
    elements, sighted keyboard users would have no visual feedback about why
    the toggle is inactive and where to go instead.

  - Visually hiding the toggle: sighted keyboard users would tab onto an
    invisible element with no feedback.

  - Per-row skip links: semantically wrong and fatiguing for screen
    reader users. A hidden "Skip to bulk actions" link per row would be
    announced on every row, adding repetitive noise. Skip links should be
    stable, always-present, and bypass navigation blocks instead of replace
    contextual controls. Replacing per-row action toggles with a skip link
    conflates navigation with action and increases cognitive load.

  - Split interaction models for sighted vs screen reader users:
    rejected on principle. Accessibility best practice is "same model,
    different presentation", not different interaction models per user type.
    Creating AT-only affordances or hidden interaction paths is not
    accessibility — it is a hidden compensation for unstable UI.

The core a11y principle at play is: don't remove contextual affordances
when context changes, clarify the context instead. Keeping both row
actions and bulk toolbar always available is the safest baseline that
respects this principle.

Further iterations will explore a smoother solution that works for all
users without altering the DOM abruptly when selection changes.
Add an aria-live="polite" region to BulkActionsToolbar so that selection
state changes are announced as they happen. Two sets of strings are
used: concise visual text for sighted users and more descriptive sr-only
text providing fuller context. The visual text is marked aria-hidden to
prevent double announcements.
Created in the context of adding labeled action menus to DASDTable rows

Add SimpleDropdown, a plain dropdown menu with a "more actions" toggle
and a labeled group header. Intended as a tiny replacement for
PatternFly's ActionsColumn when a group label is needed to provide
context about which row the actions apply to. The label is shown both as
the aria-label of the toggle button and as the visible group header
inside the open menu, improving accessibility for screen reader users
navigating action menus in tables.

Add `itemActionsComponent` prop to SelectableDataTable to allow callers
to provide a custom component for rendering the actions cell, falling
back to PatternFly's ActionsColumn when not provided.

Last but not least, use SimpleDropdown in DASDTable making the channel
identifier shown as a group label when the actions menu is open, making
it clear which device the actions belong to.
Copy link
Copy Markdown
Contributor Author

@joseivanlopez joseivanlopez left a comment

Choose a reason for hiding this comment

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

LGTM. Only changelog is missing.

Comment on lines +41 to +45
*
* FIXME: Read todo note below.
* @todo Consider returning an empty object ({}) instead of undefined to simplify
* consuming code and eliminate the need for fallback checks throughout the codebase.
*/
Copy link
Copy Markdown
Contributor

@dgdavid dgdavid Feb 26, 2026

Choose a reason for hiding this comment

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

We discussed this in a meeting and while we haven't reached a final conclusion but different point of view, the direction we're leaning toward is using null to represent "nothing found", aligning with language intent despite its well-known typeof quirk (see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/null#description). Alongside this, we'd rely on explicit "defaults" (imported from a shared utility module) to reconstruct the expected shape from scratch when needed.

Not defaulting to an empty or default object does make destructuring slightly more harder to write and follow, but beyond small drawbacks the final solution should focus providing a consistent, predictable pattern as key benefits, as well as avoids mixing null and undefined return types, which can silently become the root cause of unexpected crashes when accessing properties down the render chain (e.g., null passing through a something !== undefined check and then causing a property access to blow up).

For now, I'm removing these comments to keep the PR diff clean. We'll revisit and document the agreed pattern once the team lands on it.

@dgdavid dgdavid changed the title Adapt DASD UI to API v2 refactor(web): restore interface for managing DASD from web client Feb 26, 2026
@dgdavid dgdavid marked this pull request as ready for review February 26, 2026 16:32
@dgdavid dgdavid requested review from ancorgs and teclator February 26, 2026 17:11
Copy link
Copy Markdown
Contributor

@ancorgs ancorgs left a comment

Choose a reason for hiding this comment

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

This was already cross-reviewed and tested by @joseivanlopez and @dgdavid. So I'm approving it based on my trust on them (to make it mergeable at Github).

@joseivanlopez joseivanlopez merged commit 2d72883 into agama-project:master Feb 27, 2026
11 of 17 checks passed
dgdavid added a commit that referenced this pull request Mar 3, 2026
Agama tables lacked any visual feedback when users hovered with mouse or
navigated rows with the keyboard, making it hard to track which row user
is on. PF's built-in solution (isClickable on Tr) was intentionally
avoided since it provides the hover highlight out of the box but also
adds a pointer cursor and implies the row is clickable, which is not the
common use case for Agama tables at this moment (check slightly related
commit ae2d3a2 in which the usage of
isClickable was discarded).

Thus, a custom CSS rule has been added for covering three interaction
cases:

* Mouse hover, standard `:hover`
* Keyboard navigation, `:focus-within`, intentionally broad to cover all
focusable elements including checkboxes. This ensures keyboard users
always know which row they are on. The (small) tradeoff is a residual
highlight after checkbox selection that persists until focus moves
elsewhere. Since it's not expected mouse users stop suddenly
interacting, this is an acceptable edge case where the benefit for
keyboard users outweighs the minor annoyance (for a brief amount of
time) for mouse users.
* Action menu open, `:has(.pf-v6-c-menu-toggle[aria-expanded="true"])`,
which required fixing a missing `isExpanded` prop on `SimpleDropdown` as
part of this PR.

The highlight color reuses the same value used for button and menu
option hover states for consistency across interactive elements.
Defining another color for these elements or a dedicated token for row
highlighting is left as a future improvement, though it is not a
priority for the team in the mid-term given the amount of other ongoing
work.


<img width="2048" height="1536" alt="localhost_8080_ (10)"
src="https://github.com/user-attachments/assets/3752b712-3a0e-4398-8afa-2a3fc45c73a4"
/>
<img width="2048" height="1536" alt="localhost_8080_ (9)"
src="https://github.com/user-attachments/assets/9696544e-0d93-4a7a-8cec-6d7774ce2d7a"
/>


---

Related to 

 * #3143
 * #3092
 * #2459
joseivanlopez added a commit that referenced this pull request Mar 3, 2026
)

As a follow up of #3143,
restores the DASD format progress by adapting `DASDFormatProgress` to
the new API v2 event model, using `DASDFormatChanged` websocket events
to drive progress state and only rendering when formatting is actually
active.

To support injecting the per-device progress details into the existing
backdrop overlay, `ProgressBackdrop` was extended with an `extraContent`
prop, which can be used by pages to inject any extra content of their
convenience to the progress overlay.

This PR was also taken as an opportunity to improve the readability of
the progress overlay, on hold since
#2947, by wrapping its
content in a Card layout, which provides a clear visual container,
structured spacing, and scrollable content for long step messages.

A `waitingLabel` prop was added as another minor improvement to let
consumers override the default `"Refreshing data..."` message shown
while queries finish refetching.
bmwiedemann pushed a commit to bmwiedemann/openSUSE that referenced this pull request Mar 11, 2026
… 38 via SR 1337998

https://build.opensuse.org/request/show/1337998
by user IGonzalezSosa + anag_factory
- Do not automatically update issues con language change. When to
  update them is handled by agama-web-server (gh#agama-project/agama#3262).

- Allow to reuse LVM volume groups, volumes and thin pools
  (jsc#PED-15104, bsc#1254718 and gh#agama-project/agama#3171).

- Provide new D-Bus API for zFCP (gh#agama-project/agama#3184).

- Replace D-Bus methods by attributes in order to allow caching
  data (related to bsc#1258466).

- Allow reactivating a DASD if enabling DIAG failed
  (gh#agama-project/agama#3143).
bmwiedemann pushed a commit to bmwiedemann/openSUSE that referenced this pull request Mar 11, 2026
https://build.opensuse.org/request/show/1338003
by user IGonzalezSosa + anag_factory
- Remove code to deal with the old HTTP API
  (gh#agama-project/agama#3258).

- Allow downloading the user config (jsc#PED-15453).

- Improve registration and software issues reporting (related to bsc#1258034).

- Drop vulnerable dev dependency no longer needed (bsc#1259117).

- Restores DASD format progress with API v2 event model
  (gh#agama-project/agama#3143).
- Improves progress backdrop layout and readbility
  (gh#agama-project/agama#2947).

- Add visual feedback on table row hover and focus
  (gh#agama-project/agama#3233).

- Update web dependencies to their latest available versions
  as of 2026-03-02 (gh#agama-project/agama#3232).

- Do not reset the configuration on product selection (bsc#1258032).

- Do not show empty software page (related to bsc#1258922).

- Restore the interfa
@imobachgs imobachgs mentioned this pull request Mar 17, 2026
imobachgs added a commit that referenced this pull request Mar 17, 2026
Prepare to release version 19.

* #1829
* #2508
* #2772
* #2818
* #2826
* #2848
* #2860
* #2863
* #2864
* #2866
* #2867
* #2869
* #2870
* #2871
* #2872
* #2873
* #2874
* #2875
* #2876
* #2877
* #2880
* #2881
* #2882
* #2884
* #2885
* #2886
* #2891
* #2892
* #2893
* #2894
* #2895
* #2896
* #2897
* #2898
* #2899
* #2900
* #2901
* #2902
* #2903
* #2904
* #2908
* #2909
* #2910
* #2912
* #2913
* #2914
* #2915
* #2916
* #2917
* #2918
* #2920
* #2921
* #2923
* #2924
* #2926
* #2928
* #2929
* #2930
* #2933
* #2934
* #2935
* #2936
* #2937
* #2938
* #2939
* #2942
* #2943
* #2944
* #2945
* #2946
* #2947
* #2948
* #2949
* #2950
* #2951
* #2952
* #2954
* #2955
* #2956
* #2957
* #2958
* #2959
* #2960
* #2961
* #2963
* #2964
* #2965
* #2967
* #2968
* #2969
* #2970
* #2971
* #2972
* #2974
* #2975
* #2977
* #2978
* #2980
* #2981
* #2982
* #2983
* #2984
* #2988
* #2989
* #2990
* #2991
* #2992
* #2993
* #2994
* #2995
* #2996
* #2997
* #2998
* #2999
* #3000
* #3001
* #3002
* #3004
* #3005
* #3006
* #3007
* #3008
* #3009
* #3011
* #3012
* #3013
* #3014
* #3015
* #3016
* #3018
* #3019
* #3020
* #3021
* #3022
* #3023
* #3024
* #3025
* #3026
* #3027
* #3028
* #3029
* #3030
* #3031
* #3033
* #3034
* #3035
* #3036
* #3037
* #3039
* #3040
* #3041
* #3042
* #3043
* #3044
* #3045
* #3046
* #3047
* #3048
* #3049
* #3050
* #3051
* #3052
* #3053
* #3054
* #3055
* #3056
* #3057
* #3058
* #3060
* #3061
* #3062
* #3063
* #3064
* #3065
* #3066
* #3067
* #3068
* #3069
* #3070
* #3071
* #3072
* #3073
* #3074
* #3075
* #3076
* #3077
* #3078
* #3079
* #3086
* #3087
* #3088
* #3089
* #3090
* #3091
* #3092
* #3093
* #3094
* #3095
* #3096
* #3097
* #3098
* #3099
* #3100
* #3101
* #3102
* #3103
* #3104
* #3105
* #3106
* #3107
* #3108
* #3109
* #3110
* #3112
* #3113
* #3114
* #3115
* #3116
* #3117
* #3118
* #3119
* #3120
* #3122
* #3123
* #3124
* #3127
* #3128
* #3129
* #3130
* #3131
* #3133
* #3134
* #3135
* #3136
* #3137
* #3138
* #3139
* #3140
* #3141
* #3142
* #3143
* #3144
* #3145
* #3146
* #3147
* #3148
* #3149
* #3150
* #3151
* #3152
* #3153
* #3154
* #3155
* #3157
* #3158
* #3159
* #3160
* #3161
* #3162
* #3163
* #3164
* #3165
* #3166
* #3167
* #3168
* #3169
* #3170
* #3174
* #3175
* #3176
* #3177
* #3178
* #3179
* #3181
* #3182
* #3184
* #3185
* #3186
* #3188
* #3189
* #3190
* #3191
* #3192
* #3194
* #3195
* #3196
* #3197
* #3198
* #3199
* #3200
* #3201
* #3202
* #3203
* #3205
* #3206
* #3208
* #3209
* #3210
* #3213
* #3214
* #3215
* #3216
* #3217
* #3218
* #3219
* #3220
* #3222
* #3223
* #3224
* #3225
* #3226
* #3227
* #3228
* #3229
* #3230
* #3231
* #3232
* #3233
* #3234
* #3235
* #3236
* #3237
* #3238
* #3239
* #3240
* #3241
* #3242
* #3243
* #3244
* #3246
* #3247
* #3248
* #3250
* #3251
* #3252
* #3253
* #3254
* #3255
* #3256
* #3257
* #3258
* #3259
* #3260
* #3261
* #3262
* #3263
* #3265
* #3266
* #3267
* #3268
* #3269
* #3270
* #3271
* #3272
* #3273
* #3274
* #3275
* #3276
* #3277
* #3278
* #3279
* #3280
* #3281
* #3282
* #3283
* #3284
* #3285
* #3286
* #3287
* #3288
* #3289
* #3290
* #3291
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.

4 participants