web: add status monitor for background tasks#2909
Merged
Conversation
Since src/App.tsx wraps the layout for all protected routes, consuming application state directly from there caused unnecessary layout re-renders with noticeable side effects, such as menus or other floating UI elements closing unexpectedly. The problem happened because the internal guard and flow-control logic lived inside the component, which was also retrieving the application data directly. With both concerns mixed together, any state update forced the entire layout tree to re-render. The fix separates these responsibilities: the new App component now only sets up the global listeners, while the new Content component handles state consumption and redirect logic. This keeps layout updates stable and prevents UI elements from closing unexpectedly. This is slightly related to [1], since internal <Content /> was already a component, but was previously defined inside App, causing React to treat it as “a different component at the same position” and reset state unnecessarily. [1] https://react.dev/learn/preserving-and-resetting-state#different-components-at-the-same-position-reset-state
This adds a simple status monitor to track and display background activity. The design and placement will evolve as more insights are gathered on optimal UI integration.
jreidinger
reviewed
Nov 25, 2025
jreidinger
reviewed
Nov 25, 2025
jreidinger
reviewed
Nov 25, 2025
jreidinger
reviewed
Nov 25, 2025
jreidinger
reviewed
Nov 25, 2025
jreidinger
approved these changes
Nov 25, 2025
Restore default behavior where the popover is hidden when its trigger element is hidden, instead of remaining open with irrelevant information.
jreidinger
approved these changes
Nov 25, 2025
dgdavid
added a commit
that referenced
this pull request
Dec 17, 2025
A few weeks ago, in #2909, a small, non-blocking component was introduced to subtly inform users when actions are in progress . This PR introduces its _blocking counterpart_, allowing Agama pages to subscribe to specific progress signals and block user interactions until those progress events are complete. The changes in this PR ended up being more complex than initially expected due to an edge case that caused an undesirable flickering effect: the progress indicator would disappear almost simultaneously, or even slightly before, certain proposal queries were invalidated and refetched. This led to a transition from the progress state to an outdated UI, which was not ideal. To address this, a new hook has been implemented to subscribe to the TanStack Query cache, notifying when specific queries are considered fully refetched after a certain point. This is then used in conjunction with `useProposalChanges` query invalidation. As a result, it now emits a custom event once proposal-related queries are fully refetched, allowing the Page component to subscribe to this event and unmount the blocking overlay just before React performs the UI redraw. Please, note that using something like `const { isFetching } = useProposalChanges()` wasn't suitable for this scenario. For further details, please refer to the code and commit messages. ### Additional notes * Using query.state.fetchStatus, query.isStale, or similar properties to directly check in the hook if a query is in a refetching state could end up making things more complex for this scenario. The hook would need to track multiple statuses transitions (e.g., from stale/invalidated to fetching, and then to success), which increases the complexity. Instead, working with the dataUpdatedAt timestamp looks simpler and enough for this use case right now. It can be changed if race conditions or other issues related with timing are found. * Currently, only the software pages (all of them) and the storage proposal page are subscribed to their respective progress scopes. The only pages missing at the moment are the network pages, but since the progress for network is not yet ready, TypeScript raises an error when trying to include these pages in this PR, as it doesn't recognize "network" as a valid scope. * It would be nice to allow pages to conditionally discard the blocking state based on the number of progress steps. This idea originated with the assumption that one-step progress (like for storage proposals) would be fast, though it might not be for certain users or stacks. It's difficult to predict since other factors such as connection speed, whether the page is remote or localhost, etc can have a significant impact. These factors could be explored further to refine the behavior, if/when time permits. * Another possibility, which is fully outside the scope of this PR for now because there is no current use case, is to allow pages to subscribe to multiple progress scopes, rather than just one.
imobachgs
added a commit
that referenced
this pull request
Jan 10, 2026
Merge the new HTTP API. Each PR has been already reviewed, so it should be safe to merge it. * #1829 * #2508 * #2772 * #2826 * #2848 * #2860 * #2863 * #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 * #2938 * #2939 * #2942 * #2943 * #2944 * #2945 * #2946 * #2947 * #2948 * #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 * #2982 * #2983 * #2984 * #2988 * #2989 * #2991 * #2992 * #2993 * #2994 * #2995 * #2996 * #2997 * #2999
Merged
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
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.
This PR introduces a lightweight status monitor for background tasks (aka progresses), allowing users to track ongoing activity in the app. Please, note that the design and placement of this feature are expected to evolve as we gain further insights into optimal UI integration. Proposed one is just an simple starting point.
Additionally, the PR refactors the state logic in App.tsx to reduce unnecessary layout re-renders, which were causing unexpected UI issues such as menus and floating elements closing unexpectedly. This change separates concerns by moving state management and redirect logic to an internal component defined outside the main one, improving the overall stability of the layout.
To make everything work, a new hook for listening to and update progress changes has been added.