Repository: mathesar-foundation/mathesar

Issue:
Explorations should not auto-save
New Explorations are currently persistent, any change made immediately saves the exploration. This behaviour is not preferred since we'd like the user to be able to run and discard queries.

[Mail thread containing related discussion](https://groups.google.com/a/mathesar.org/g/mathesar-developers/c/RQJSiDQu1Tg/m/uLHj30yFAgAJ).

New behaviour proposed:

* New Exploration: Auto-save is not preferred
  - User opens Data Explorer
  - User joins tables, does any number of operations
  - This should not get saved automatically
  - It should get saved when user manually clicks Save button

* Editing existing Exploration: ~~Auto-save is preferred~~ Auto save is not preferred (Refer https://github.com/centerofci/mathesar/issues/1590#issuecomment-1238204655)
  - Users edits an existing exploration in the Data Explorer
  - User makes changes to it
  - ~~The changes are auto-saved~~ User has to click the Save button or Ctrl+s to save the changes
  - We have undo-redo to improve the user's editing experience
Implement Exploration Page functionality
This is a placeholder issue to implement a page to view a single exploration.


Discussion:
Looks good to me. How persistent do we need undo-redo to be? Is this something that you're planning to cache in the front end, or does this imply back end work at this point?
> How persistent do we need undo-redo to be? Is this something that you're planning to cache in the front end, or does this imply back end work at this point

We already have it implemented on the frontend where each change is cached in the query history. We do not need any backend work for it.
I'm imagine that in _some_ cases, auto-saving edits to an existing exploration would be best for the user. But my inclination would be to only save them manually. Here are a couple use-cases to consider.

- I predict that we'll eventually use explorations to power other workflows within Mathesar, such as custom widgets on the Record Page, publicly available reports, and other things too. If I'm using Mathesar with other people who are relying on those workflows, and I want to make some improvements to a specific exploration, I would want to make sure that my modifications are made atomically, without leaving the exploration in a non-functional state while I'm continuing to work on it. I want to work on it, make sure it's done, _then_ save it.

- I might want to play with an existing exploration (very much in the spirit of "exploring") without necessarily committing to the changes I make. If I want to rollback my changes to the last-saved version, it's not necessarily clear how to do that. For example, before I read Pavish's comment above, I didn't know whether the undo history was persisting locally or persisting on the server. Now that I know it's only local, I know that I can click "undo" over and over until the button is disabled. But even so, that's still not very convenient.

I use the [Svelte REPL](https://svelte.dev/repl/hello-world?version=3.50.0) a lot, and I really like its UX around saving. You can load a saved REPL and modify it, but your modifications won't be automatically saved. Instead, the UI makes it clear that you have unsaved changes, and if you try to close your tab with unsaved changes, then it throws up a modal dialog warning. This is the UX that I imagine would be best for the Data Explorer.
I find myself convinced by @seancolsen's reasoning. I assume we can still have undo/redo, but it just wouldn't get saved to the server.
Sounds good. I find @seancolsen's comments convincing as well. I've updated the issue description to reflect this.


Resolving patch:
diff --git a/mathesar/views.py b/mathesar/views.py
--- a/mathesar/views.py
+++ b/mathesar/views.py
@@ -42,7 +42,7 @@ def get_queries_list(request, schema):
     if schema is None:
         return []
     query_serializer = QuerySerializer(
-        UIQuery.objects.all(),
+        UIQuery.objects.filter(base_table__schema=schema),
         many=True,
         context={'request': request}
     )


Test patch: