Skip to content

Issue 131 Tasks Forgot Your View

Ed Mozley edited this page Sep 3, 2026 · 1 revision

Tasks always reopened on the board (issue #131)

Reported by tjedelhauser Β· Fixed in #1459


1. What you saw

Switch Tasks to the list, or to All tasks, then reload the page. Both snap back: the board, showing only your own work. Every time.

Not a save that failed. There was no save at all.


2. What was actually wrong

Two lines of state in assets/js/tasks.js:

let currentFilter = 'my';
let currentView   = 'board';

switchView() and setFilter() changed those variables, repainted, and stopped. Nothing wrote them anywhere, and nothing read them back on load. So every page load started from the hardcoded defaults, exactly as reported.

The part that makes it a real complaint rather than a nitpick

It was the only thing on that page that forgot. Everything around it already remembered, per analyst:

Already saved Key
Task opens in the side panel or the large window tasks_detail_view
Large window: two columns or tabs (#1454) tasks_modal_layout
Which fields appear on a board card tasks_card_fields
Tasks calendar: subtask scope tasks_calendar_subtasks
Tasks calendar: span mode tasks_calendar_span_mode
Task table: columns and sort tasks_table_v1

And one tab away, the tickets calendar already saved the identical "my work vs everybody's" choice as tickets_calendar_scope. The board was the outlier.


3. Where it is stored, and why not in the browser

A user preference, in user_preferences, against the analyst - not localStorage.

Three reasons, in order of weight:

  1. Consistency. Every sibling control listed above is already a server-side preference. Storing this one locally would mean your panel choice follows you to another machine and your view choice does not, which is arbitrary and impossible to explain.
  2. It follows the person. Same doctrine as the recent trail in #1450: per analyst rather than per browser, so it survives signing out and reaches your other machine.
  3. No flash. tasks/index.php already reads a set of preference keys in one query and publishes them to the page, precisely so "tasks.js must not have to fetch a preference before it can open anything." Two more keys join that existing IN (...) list. Anything read client-side would paint the board and then swap it out.

That third point is why the panes' initial visibility and the buttons' active class are decided in PHP, not by tasks.js on load.


4. πŸ”‘ What is deliberately NOT remembered

Only board/list and my/all. The team dropdown, the analyst dropdown, the tag filter and the search box still clear on every visit.

The rule was already written down, in data-table.js for the saved table views (discussion #96):

A filter is how you like to look at things; a search is a question you asked once.

There is a sharper reason as well, and it is the one that decided the scope:

A narrow filter that survives the night is how somebody opens Tasks in the morning to an empty board and concludes their work has been deleted.

A stored analyst id can also outlive the analyst - the product already carries dozens of ticket rows pointing at deleted people, so this is not hypothetical. Board-or-list and mine-or-everyone's can do neither: neither can hide a task beyond the plain meaning of the button you pressed.

So setFilter() saves only the two coarse values, even though currentFilter can also hold 'team' and 'analyst':

if (filter === 'my' || filter === 'all') saveTaskPreference('tasks_filter', filter);

5. A small deliberate inconsistency

The save is fire-and-forget and silent on failure, matching the tasks calendar. The board has already redrawn the way you asked; a failed save costs you the choice next time and nothing now, and a toast about a view preference would be worse than quietly showing you the default tomorrow.

The detail-panel switch one screen away does toast on failure, and that stays. Moving a task into the large window is a considered choice you would want to know had not stuck. Flicking between board and list is not.


6. πŸ“ Files

File Change
tasks/index.php Reads tasks_view / tasks_filter in the existing preference query; renders the active buttons and the visible pane from them; publishes both to the page
assets/js/tasks.js Initial state taken from the published values; saveTaskPreference() helper; saves in switchView() and (guarded) setFilter(); cache-buster to v=39

No schema change - user_preferences already exists and is keyed on (analyst_id, preference_key).

Values are whitelisted on read, not trusted: the column is free text, and an unrecognised value must land on the default rather than on a view that does not exist and renders blank.


7. How it was verified

Driven in headless Chrome against the real page, clicking the actual buttons in a same-origin harness rather than posting to the endpoint by hand, on an analyst with no existing preference:

1 initial       activeView=board activeFilter=my   boardVisible=true  listVisible=false
  PASS starts on the board with My tasks
  PASS board pane visible, list hidden
2 clicked List  activeView=list  activeFilter=my   boardVisible=false listVisible=true
  PASS list is now active and visible
3 after reload  activeView=list  activeFilter=my   TASK_VIEW=list
  PASS LIST SURVIVED THE REFRESH
  PASS and the list pane is the one showing
  PASS server published TASK_VIEW=list (no flash of the board)
5 after reload  activeView=list  activeFilter=all  TASK_FILTER=all
  PASS ALL TASKS SURVIVED THE REFRESH
  PASS and the list view is still remembered too
6 after team    PASS a team filter is NOT remembered (still All)
7 after search  PASS a search is NOT remembered
DONE errors=0

Proved load-bearing by breaking it

With the single line saveTaskPreference('tasks_view', view) commented out, the harness reproduces the reported bug exactly and the checks fail:

3 after reload  activeView=board  boardVisible=true  listVisible=false
  FAIL LIST SURVIVED THE REFRESH
  FAIL and the list pane is the one showing
  FAIL server published TASK_VIEW=list (no flash of the board)
  PASS ALL TASKS SURVIVED THE REFRESH        <- the filter save was left in
DONE errors=4

The filter still passing while the view failed is the useful half: it shows the two are saved independently rather than one check covering both.


8. What this means for you

Nothing to configure. Pick the list, or All tasks, and Tasks opens that way next time - on any machine you sign in from.

To go back, pick the board again. There is no setting to find, because the buttons are the setting.


9. Related

FreeITSM

Getting Started

Modules

Multi-tenancy (planned)

Blue sky thinking

Bugs resolved

Links

Clone this wiki locally